CSC111 Lab 9 2011

From dftwiki3
Jump to: navigation, search

--D. Thiebaut 13:15, 2 November 2011 (EDT)


Working with Functions

  • For this part, work in Idle or emacs and create the various functions this lab presents you, and test them in main().
  • For example, if you are asked to write a function that receives a string as parameter and prints it with a box around it, you could write something like this:



def boxIt( string ):
    noChars = len( string )
    print( "-" * ( 2 + noChars  + 2 ) )
    print( "| " + string + " |" )
    print( "-" * ( 2 + noChars + 2 ) )

def main():
    boxIt( "hello!" )
    boxIt( "This is a very long string!" )
    boxIt( "" ) # empty string 

main()



  • No need to add documentation for the code in this lab (or just in spots where you think you need to add markers for yourself)

Box

  • Go ahead and create the boxIt() function above.
  • Test it. Notice that I tested it with 3 different strings, one of them the empty string. It is important to test for "strange" conditions. An empty string is a totally valid string, and if our program is supposed to work with strings, it should work with empty strings as well without crashing.

Triple Boxes

  • Add a new function called BoxIt3( s1, s2, s3), that receives 3 strings and prints each string in its own box.
  • If you call your function in main() like this BoxIt3( "Hello", "There", "Smith College" ), it will print
---------
| Hello |
---------

---------
| There |
---------

-----------------
| Smith College |
-----------------

  • Go ahead and test your new function. Test it with different strings.
  • If your solution does not use the function BoxIt() created earlier, modify BoxIt3() so that it calls BoxIt() 3 times.

Multiple Boxes

  • Add a new function called multipleBoxes( L ) that receives a list of strings and prints each string in the list with BoxIt().


  • Here is are different possible ways one could test your function:


multipleBoxes( [ "Doc", "Grumpy",  "Happy", "Sleepy", "Bashful", "Sneezy", "Dopey" ] )

multipleBoxes( [ "Hello", "", "", "There!" ] )

multipleBoxes( "Hello Smith College!" . split() )

Intelligent BoxIt()

  • Make BoxIt() not print anything if the string it is given is empty.


Functions Returning Values

Median of 3

  • write a function that returns the median of 3 numbers.
  • For example:


def median3( a, b, c ):
    # could it be b?
    if a <= b and b <= c:
          return b

    # if we're here, it's not b.  Could it be a?
    if b <= a and a <= c:
          return a

    # if we're here it's not b and not a.  It has to be c!
    return c


def main():
     print( median3( 10, 10, 20 ) )
     print( median3( 1, 2, 3 ) )
     print( median3( 6, 5, 7 ) )
     print( median3( 8, 10, 9 ) )

main()


  • Modify the code above and make it simpler by remembering that you can put a, b, and c in a list, sort the list, and return the element at Index 1.

Second Smallest

  • Write a function that receives a list of numbers (or strings), and that returns the second smallest of them.
  • For example:


 L = [ 1, 10, 2, 3, 30, 40, 50 ]
 ss = secondSmallest( L ) 
 print( ss )                 # prints out 2


  • Make sure your function works even if the list is empty or contains just one element!

Testing Second Smallest

  • Test the function you have just written, and print the contents of the List of numbers (or strings) before you call secondSmallest() and after you call it.
  • You will likely see that your list has changed. (if not, then skip to the next problem)
  • If it has changed it is because you are sorting the list inside your function, and the list is passed by reference to the function.
  • Modify your function so that the list does not get modified by the function when it is passed.

Make User Name

  • This one should make sense just by looking at what it returns.


  user = makeUserName( "Alex Andra" )
  print( user )
  # will print aandra
 
  print( makeUserName( "Mini Driver" ) )
  # will print mdriver

  print( makeUserName( "Alan J. Smith" ) )
  # will print asmith


  • make sure the name returned is all lower-case.

Graphics with Functions

IsInside()


from graphics import *


def isInside( xc, yc, x1, y1, x2, y2 ):
    #
    # add your code here!
    #
    return 0

def main():
    w = 600
    h = 400
    x1 = 20
    y1 = 30
    x2 = w // 3
    y2 = h - y1
    win = GraphWin( "Click me to stop!", w, h )


    c = Circle( Point( w//2, h//4 ), 20 )
    c.setFill( "yellow" )
    c.draw( win )

    r = Rectangle( Point( x1, y1 ), Point( x2, y2 ) )
    r.setWidth(3)
    r.draw( win )

    dirX = 5
    dirY = 3
    
    while True:
        c.move( dirX, dirY )
        xc = c.getCenter().getX()
        yc = c.getCenter().getY()
        if not ( 0 <= xc <= w ): dirX = -dirX
        if not ( 0 <= yc <= h ): dirY = -dirY
        
        if isInside( xc, yc, x1, y1, x2, y2 )== 1:
            # center inside rectangle
            c.setFill( "red" )
        else:
            # center outside rectangle
            c.setFill( "yellow" )

        if win.checkMouse() != None:
            break

    win.close()

main()


  • write the body of the function isInside( ) above. This function gets the coordinates of the center of the circle, and the coordinates of the points defining a rectangle, and it returns 1 when the center is inside the rectangle, and returns 0 when it is not.
Basically, the body of the function should be the python translation of this algorithm:
 if xc is between x1 and x2, and if yc is between y1 and y2,
       then return 1
  else return 0


  • Once your function works, the circle should move freely around the graphics window, bouncing off the edges, and should change color as soon as its center enters the rectangle.

IsInside with Points

  • Change the definition of isInside() so that it works with points instead of coordinates. This will make the code a bit easier to read:


    P1 = Point( x1, y1 )
    P2 = Point( x2, y2 )
    while True:
        c.move( dirX, dirY )
        xc = c.getCenter().getX()
        yc = c.getCenter().getY()
        if not ( 0 <= xc <= w ): dirX = -dirX
        if not ( 0 <= yc <= h ): dirY = -dirY
        
        if isInside( c.getCenter(), P1, P2 )== 1:
            # center inside rectangle
            c.setFill( "red" )
        else:
            # center outside rectangle
            c.setFill( "yellow" )

        if win.checkMouse() != None:
            break


IsInside() with objects

  • Same idea, but this time change isInside so that it takes as parameters the circle and the rectangle:
    while True:
        c.move( dirX, dirY )
        xc = c.getCenter().getX()
        yc = c.getCenter().getY()
        if not ( 0 <= xc <= w ): dirX = -dirX
        if not ( 0 <= yc <= h ): dirY = -dirY
        
        if isInside( c, r )== 1:
            # center inside rectangle
            c.setFill( "red" )
        else:
            # center outside rectangle
            c.setFill( "yellow" )

        if win.checkMouse() != None:
            break

Add another rectangle

  • Add a second rectangle to your program, and make the ball become blue inside the second rectangle. You should use the new function you have created for testing if c is inside Rectangle r or inside new Rectangle r2.


        if isInside( c, r )== 1:
            # center inside rectangle
            c.setFill( "red" )
        elif isInside( c, r2 )==1:
            ...
        else:
            ...




Exercises

  • Pick from the exercises we did this morning one or two that were the most challenging for you and code them.

Homework













solution programs