Difference between revisions of "CSC111 Lab 9 2011"
(→Working with Functions) |
(→Homework) |
||
(23 intermediate revisions by the same user not shown) | |||
Line 11: | Line 11: | ||
<source lang="python"> | <source lang="python"> | ||
def boxIt( string ): | def boxIt( string ): | ||
− | noChars = len( | + | noChars = len( string ) |
− | print( " | + | print( "-" * ( 2 + noChars + 2 ) ) |
print( "| " + string + " |" ) | print( "| " + string + " |" ) | ||
− | print( " | + | print( "-" * ( 2 + noChars + 2 ) ) |
def main(): | def main(): | ||
Line 28: | Line 28: | ||
* 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) | * 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: | ||
+ | <br /> | ||
+ | <source lang="python"> | ||
+ | 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() | ||
+ | |||
+ | </source> | ||
+ | |||
+ | <br /> | ||
+ | * 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: | ||
+ | |||
+ | <br /> | ||
+ | <source lang='python'> | ||
+ | |||
+ | L = [ 1, 10, 2, 3, 30, 40, 50 ] | ||
+ | ss = secondSmallest( L ) | ||
+ | print( ss ) # prints out 2 | ||
+ | |||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | * 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. | ||
+ | |||
+ | <br /> | ||
+ | <source lang="python"> | ||
+ | |||
+ | user = makeUserName( "Alex Andra" ) | ||
+ | print( user ) | ||
+ | # will print aandra | ||
+ | |||
+ | print( makeUserName( "Mini Driver" ) ) | ||
+ | # will print mdriver | ||
+ | |||
+ | print( makeUserName( "Alan J. Smith" ) ) | ||
+ | # will print asmith | ||
+ | </source> | ||
+ | <br /> | ||
+ | |||
+ | * make sure the name returned is all lower-case. | ||
+ | |||
+ | =Graphics with Functions= | ||
+ | |||
+ | ===IsInside() === | ||
+ | <br /> | ||
+ | <source lang="python"> | ||
+ | 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() | ||
+ | |||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | * 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: | ||
+ | <br /> | ||
+ | <source lang="python"> | ||
+ | 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 | ||
+ | |||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | |||
+ | ===IsInside() with objects=== | ||
+ | |||
+ | * Same idea, but this time change isInside so that it takes as parameters the circle and the rectangle: | ||
+ | |||
+ | <source lang="python"> | ||
+ | |||
+ | |||
+ | 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 | ||
+ | |||
+ | </source> | ||
+ | |||
+ | ===Add another rectangle=== | ||
+ | |||
+ | * Add a second rectangle to your program, and make the ball become <font color="blue">'''blue'''</font> 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'''. | ||
+ | |||
+ | <br /> | ||
+ | <source lang="python"> | ||
+ | if isInside( c, r )== 1: | ||
+ | # center inside rectangle | ||
+ | c.setFill( "red" ) | ||
+ | elif isInside( c, r2 )==1: | ||
+ | ... | ||
+ | else: | ||
+ | ... | ||
+ | </source> | ||
<br /><br /><br /> | <br /><br /><br /> | ||
+ | =Exercises= | ||
+ | * Pick from the exercises we did this morning one or two that were the most challenging for you and code them. | ||
+ | |||
+ | =Homework= | ||
+ | * Feel free to move on to [[CSC111 Homework 6 2011| Homework 6]], or [[CSC111 Homework 7 2011| Homework 7]]... | ||
+ | <br /><br /><br /> | ||
+ | <br /><br /><br /> | ||
+ | <br /><br /><br /> | ||
+ | <br /><br /><br /> | ||
+ | <font size="-1">[[CSC111 Lab 9 Solutions 2011 | solution programs]]</font> | ||
[[Category:CSC111]][[Category:Python]][[Category:Labs]] | [[Category:CSC111]][[Category:Python]][[Category:Labs]] |
Latest revision as of 12:00, 3 November 2011
--D. Thiebaut 13:15, 2 November 2011 (EDT)
Contents
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
- Feel free to move on to Homework 6, or Homework 7...