How Do I Enter Something Again in Method
3.3.i. Simple while
Loops¶
Other than the trick with using a return
statement inside of a for
loop, all of the loops so far have gone all the manner through a specified list. In whatever instance the for
loop has required the employ of a specific list. This is often too restrictive. A Python while
loop behaves quite similarly to common English usage. If I say
While your tea is also hot, add a chip of ice.
Presumably you lot would test your tea. If it were too hot, you would add a little water ice. If you test again and it is even so also hot, yous would add ice again. As long as yous tested and constitute it was true that your tea was too hot, you would go back and add more than ice. Python has a like syntax:
while
condition:
- indentedBlock
Setting up the English example in a similar format would be:
- while your tea is besides hot :
- add together a fleck of ice
To make things concrete and numerical, suppose the following: The tea starts at 115 degrees Fahrenheit. You want information technology at 112 degrees. A chip of ice turns out to lower the temperature i degree each time. Yous examination the temperature each time, and as well print out the temperature before reducing the temperature. In Python you could write and run the lawmaking below, saved in instance program cool.py:
temperature = 115 while temperature > 112 : # showtime while loop code print ( temperature ) temperature = temperature - 1 print ( 'The tea is cool enough.' ) |
I added a last line after the while loop to remind you lot that execution follows sequentially after a loop completes.
If you play computer and follow the path of execution, yous could generate the following table. Think, that each time you reach the cease of the indented block later the while
heading, execution returns to the while
heading for another test:
Line | temperature | Comment |
---|---|---|
1 | 115 | |
2 | 115 > 112 is true, do loop | |
3 | prints 115 | |
4 | 114 | 115 - 1 is 114, loop back |
two | 114 > 112 is true, do loop | |
3 | prints 114 | |
4 | 113 | 114 - i is 113, loop back |
2 | 113 > 112 is true, do loop | |
iii | prints 113 | |
iv | 112 | 113 - 1 is 112, loop back |
2 | 112 > 112 is fake, skip loop | |
six | prints that the tea is cool |
Each time the stop of the indented loop torso is reached, execution returns to the while
loop heading for some other test. When the test is finally simulated, execution jumps past the indented trunk of the while
loop to the next sequential argument.
A while
loop more often than not follows the pattern of the successive modification loop introduced with for
-each loops:
initialization
while
continuationCondition:
do principal action to exist repeated
prepare variables for the next time through the loop
Test yourself: Following the code. Effigy out what is printed. :
i = 4 while i < 9 : print ( i ) i = i + 2
Check yourself by running the example program testWhile.py
.
Note
In Python, while
is non used quite like in English. In English you could mean to stop as soon as the condition you want to test becomes false. In Python the test is simply made when execution for the loop starts (or starts once more), non in the centre of the loop.
Predict what will happen with this slight variation on the previous example, switching the order in the loop trunk. Follow it carefully, one pace at a fourth dimension.
i = iv # variation on testWhile.py while ( i < 9 ): i = i + 2 print ( i ) |
Check yourself by running the example program testWhile2.py
.
The sequence order is of import. The variable i
is increased before information technology is printed, so the first number printed is 6. Another mutual mistake is to presume that x will not be printed, since 10 is by 9, but the test that may stop the loop is not fabricated in the eye of the loop. Once the torso of the loop is started, information technology continues to the end, fifty-fifty when i
becomes 10.
Line | i | Annotate |
---|---|---|
1 | 4 | |
2 | 4 < 9 is true, practise loop | |
3 | half dozen | four+2=half-dozen |
4 | impress 6 | |
2 | 6 < nine is truthful, practise loop | |
three | 8 | half-dozen+2= eight |
4 | impress 8 | |
2 | eight < nine is true, do loop | |
three | 10 | 8+2=ten No exam here |
four | print 10 | |
2 | 10 < 9 is false, skip loop |
Predict what happens in this related little program:
nums = list () i = 4 while ( i < ix ): nums . append ( i ) i = i + 2 print ( nums )
Check yourself past running the case programme testWhile3.py
.
3.3.ii. The Most Full general range
Function¶
There is actually a much simpler manner to generate the previous sequences like in testWhile3.py
, using a further variation of the range
function. Enter these lines separately in the Shell. As in the simpler applications of range
, the values are but generated one at a time, equally needed. To encounter the entire sequence at once, convert the sequence to a listing earlier printing:
nums = range ( 4 , 9 , two ) print ( list ( nums ))
The third parameter for the range function is the step size. It is needed when the pace size from ane element to the next is non one.
The most general syntax is
range(
start,
pastEnd,
step)
The value of the second parameter is always past the last element of the list. Each element after the first in the listing is step more than the previous i. Predict and try in the Beat:
Actually the range function is even more sophisticated than indicated by the while
loop to a higher place. The step size can be negative. Attempt in the Shell:
Exercise you see how 0 is past the end of the list?
Endeavor it: Make up a range
function call to generate the list of temperatures printed in the tea example, 115, 114, 113
. Test it in the Vanquish.
These ranges, like the simpler ranges that nosotros used earlier, are most frequently used as the sequence in a for
loop heading:
for i in range ( x , 0 , - ane ): # countdown... print ( i ) print ( 'Blastoff!' )
3.3.3. Interactive while
Loops¶
The earlier examples of while loops were chosen for their simplicity. Obviously they could take been rewritten with range function calls. Now lets effort a more than interesting example. Suppose you lot want to permit a user enter a sequence of lines of text, and want to remember each line in a listing. This could hands be done with a simple repeat loop if yous knew the number of lines to enter. For case, in readLines0.py
, the user is prompted for the exact number of lines to be entered:
lines = list () n = int ( input ( 'How many lines practise you want to enter? ' )) for i in range ( n ): line = input ( 'Next line: ' ) lines . append ( line ) print ( 'Your lines were:' ) # bank check now for line in lines : print ( line )
The user may want to enter a bunch of lines and not count them all alee of time. This means the number of repetitions would not be known alee of time. A while
loop is appropriate here. There is still the question of how to examination whether the user wants to continue. An obvious but verbose way to do this is to ask before every line if the user wants to continue, as shown beneath and in the example file readLines1.py
. Read it and and then run information technology:
lines = list () testAnswer = input ( 'Press y if you want to enter more lines: ' ) while testAnswer == 'y' : line = input ( 'Next line: ' ) lines . append ( line ) testAnswer = input ( 'Printing y if you want to enter more lines: ' ) print ( 'Your lines were:' ) for line in lines : print ( line )
See the two statements setting testAnswer
: one before the while
loop and ane at the lesser of the loop body.
Note
The information must be initialized earlier the loop, in guild for the first test of the while condition to work. Also the test must work when you loop dorsum from the stop of the loop trunk. This means the data for the test must as well be prepare up a 2d fourth dimension, in the loop body (unremarkably as the activity in the last line of the loop). It is like shooting fish in a barrel to forget the second time!
The readLines1.py
code works, but information technology may exist more annoying than counting ahead! Two lines must be entered for every one you actually want! A practical alternative is to use a sentinel: a piece of data that would not make sense in the regular sequence, and which is used to betoken the end of the input. Y'all could hold to use the line DONE!
Even simpler: if you assume all the real lines of data will really have some text on them, use an empty line as a sentinel. (If yous remember near information technology, the Python Crush uses this approach when you lot enter a argument with an indented body.) This style yous only need to enter i extra (very unproblematic) line, no affair how many lines of real data yous have.
What should the while status be now? Since the sentinel is an empty line, you might retrieve line == ''
, simply that is the termination condition, non the continuation status: You need the contrary condition. To negate a condition in Python, you may apply not
, similar in English language,
Of course in this situation there is a shorter style,
Run the example program readLines2.py
, shown below:
lines = list () print ( 'Enter lines of text.' ) print ( 'Enter an empty line to quit.' ) line = input ( 'Adjacent line: ' ) # initalize earlier the loop while line != '' : # while Not the termination status lines . append ( line ) line = input ( 'Adjacent line: ' ) # !! reset value at terminate of loop! impress ( 'Your lines were:' ) for line in lines : print ( line )
Once more the information for the test in the while loop heading must be initialized before the start time the while
statement is executed and the examination data must too be fabricated set inside the loop for the test after the torso has executed. Hence y'all meet the statements setting the variable line
both before the loop and at the finish of the loop body. Information technology is easy to forget the second identify within the loop!
After reading the rest of this paragraph, comment the final line of the loop out, and run it over again: Information technology will never cease! The variable line
volition forever have the initial value you lot gave it! You lot actually can stop the plan past entering Ctrl-C
. That ways concord the Ctrl
key and press c
.
Note
As you finish coding a while
loop, information technology is good practice to ever double-check: Did I make a change to the variables, within the loop, that will somewhen brand the loop condition False
?
The earliest while
loop examples had numerical tests and the lawmaking to get fix for the next loop merely incremented a numerical variable by a stock-still amount. Those were unproblematic examples only while
loops are much more general! In the interactive loop nosotros accept seen a continuation condition with a cord exam, and getting prepare for the next time through the loop involves input from the user.
Some of the exercises that follow involve interactive while loops. Others were delayed until here just considering they take a wider variety of continuation status tests and means to ready for the next time through the loop. What is consistent is the general steps to recall of and questions to ask yourself. They keep on applying! Keep these in mind!
- the need to see whether there is a kind of repetition, even without a stock-still drove of values to work through
- to recall from the specific situation and figure out the continuation condition that makes sense for your loop
- to think what specific processing or results you desire each fourth dimension through the loop, using the same code
- to figure out what supporting code you lot need to make you gear up for the adjacent time through the loop: how to make the same results lawmaking take new data values to process each fourth dimension through, and eventually achieve a stopping point.
Detecting the need for while
statements: Like with planning programs needing``for`` or if
statements, you want to be able to translate English descriptions of problems that would naturally include while
statements. What are some words or phrases or ideas that suggest the apply of these statements? Think of your own then compare to a few I gave: [1]
iii.three.3.1. Interactive Sum Exercise¶
Write a plan sumAll.py
that prompts the user to enter numbers, one per line, ending with a line containing only 0, and proceed a running sum of the numbers. Simply impress out the sum after all the numbers are entered (at least in your last version). Do not create a listing! Each time you read in a number, you can immediately use information technology for your sum, and and so exist done with the number just entered.
3.3.iii.2. Rubber Number Input Practice¶
* In that location is an event with reading in numbers with the input argument. If you lot brand a typo and enter something that cannot exist converted from a string to the correct kind of number, a naive programme will flop. This is avoidable if y'all test the string and repeat if the string is illegal. In this do write rubber utility role replacements for the input function that piece of work to read in a whole number, an integer or a decimal number.
All parts refer to the previous Is Number String Exercise. Part a. refers to the introduction in the previous practise. Parts b. and c. refer to functions in the solution, isNumberStr.py
, of the previous practice. Brand sure you look back at these first.
Salve the example safeNumberInputStub.py
as safeNumberInput.py
, and complete it. It contains headings and documentation strings for the functions in each role of this do.
- This office considers the simplest case, where yous are trying to enter a whole number. Complete the definition of the function
safeWholeNumber
. - Complete the role
safeInt
. This hands parallels office a. if you copy in and use the function (not method)isIntegerStr
. - Complete the part
safeDecimal
. This hands parallels office b. if you copy in and use the functionisDecimalStr
.
3.three.three.3. Savings Exercise¶
The thought here is to see how many years information technology will take a banking concern account to abound to at least a given value, bold a fixed annual interest. Write a programme savings.py
. Prompt the user for three numbers: an initial balance, the annual pct for interest every bit a decimal, like .04 for 4%, and the final residual desired.
All the budgetary amounts that yous print should exist rounded to exactly ii decimal places. Starting time by printing the initial balance this way. For instance, if the initial balance was entered as 123.v, information technology should be reprinted by your program as 123.50. Likewise print the balance each year until the desired amount is reached or passed. The first residuum at or past the target should exist the final i printed.
The math: The amount next year is the amount now times (1 + interest fraction), and so if I accept $500 now and the interest rate is .04, I have $500*(1.04) = $520 subsequently one year and afterward 2 years I take, $520*(one.04) = $540.lxxx....
For example, if I respond to the prompts, and enter into the program a $500 starting residue, .04 interest rate and a target of $550, the program prints:
500.00 520.00 540.fourscore 562.43
iii.3.iii.4. Strange Sequence Exercise¶
* Remember Strange Part Exercise and its jumpFunc.py
which contains the function jump
: For whatsoever integer n, jump(n) is n//2 if n is even, and iii*northward+1 if n is odd.
Yous can kickoff with one number, say north = three, and keep applying the jump office to the terminal number given, and come across how the numbers jump effectually!
leap ( three ) = 3 * 3 + 1 = x ; jump ( ten ) = 10 // 2 = 5 ; bound ( 5 ) = three * 5 + i = 16 ; spring ( xvi ) = 16 // 2 = 8 ; jump ( 8 ) = 8 // ii = 4 ; jump ( 4 ) = four // 2 = two ; jump ( ii ) = 2 // two = 1
This process of repeatedly applying the same part to the most recent result is called function iteration. In this instance you see that iterating the jump part, starting from n=3, eventually reaches the value 1.
It is an open research question whether iterating the spring role from an integer n will eventually reach i, for every starting integer n greater than i. Researchers have only found examples of due north where it is truthful. Still, no general argument has been fabricated to employ to the infinite number of possible starting integers.
In this exercise you iterate the jump function for specific starting values due north, until the result is 1.
-
Relieve case
jumpSeqStub.py
equallyjumpSeq.py
and complete the missing role bodies. If you lot coded the functionjump
earlier injumpFunc.py
, y'all can copy it. You can complete eitherprintJumps
orlistJumps
first, and test before completing the other. Hint [two] -
Later you have finished and saved
jumpSeq.py
copy it and salvage the file asjumpSeqLengths.py
.Kickoff modify the main method so it prompts the user for a value of n, and then prints just the length of the iterative sequence from listJumps(north). Hint [3]
Then elaborate the program so it prompts the user for two integers: a lowest starting value of northward and a highest starting value of due north. For all integers n in the range from the lowest start through the highest start, including the highest, print a sentence giving the starting value of north and the length of the list from
listJumps(n)
. An example run:Enter lowest start: 3
Enter highest get-go: 6
Starting from 3, jump sequence length 8.
Starting from 4, jump sequence length iii.
Starting from v, jump sequence length 6.
Starting from six, jump sequence length 9.
3.3.iv. Graphical Applications¶
Another place where a while
loop could be useful is in interactive graphics. Suppose you desire the user to exist able to create a Polygon by clicking on vertices they cull interactively, but y'all do non desire them to have to count the number of vertices ahead of time. A while
loop is suggested for such a repetitive process. Every bit with entering lines of text interactively, there is the question of how to bespeak that you are done (or how to indicate to continue). If you make simply a certain region be immune for the Polygon, then the sentinel can be a mouse click outside the region. The earlier interactive color choice example already has a method to check if a mouse click is inside a Rectangle, so that method tin can be copied and reused.
Creating a polygon is a unified activity with a articulate result, so let'southward define a function. It involves a boundary rectangle and mouse clicks in a GraphWin, and may every bit well render the Polygon constructed. Read the following start:
def polyHere ( rect , win ): ''' Draw a polygon interactively in Rectangle rect, in GraphWin win. Collect mouse clicks inside rect into the vertices of a Polygon, and always draw the Polygon created so far. When a click goes outside rect, end and return the last polygon. The Polygon ends up drawn. The method draws and undraws rect. '''
It is useful to get-go by thinking of the objects needed, and give them names.
- A Polygon is needed. Call it
poly
. - A list of vertices is needed. Call information technology
vertices
. I need to append to this listing. Information technology must exist initialized first. - The latest mouse click signal is needed. Call it
pt
.
Certainly the overall process volition be repetitious, choosing point subsequently bespeak. However information technology may not be at all articulate how to make an effective Python loop. In challenging situations like this it is often useful to imagine a concrete situation with a express number of steps, so each step tin be written in sequence without worrying near a loop.
For instance to get up to a triangle (3 vertices in our list and a fourth mouse click for the sentinel), y'all might imagine the following sequence, undrawing each old polygon before the next is displayed with the latest mouse click included:
rect . setOutline ( 'cherry' ) rect . draw ( win ) vertices = list () pt = win . getMouse () vertices . append ( pt ) poly = Polygon ( vertices ) poly . draw ( win ) # with one signal pt = win . getMouse () poly . undraw () # missing latest signal vertices . append ( pt ) poly = Polygon ( vertices ) poly . draw ( win ) # with 2 points pt = win . getMouse () poly . undraw () # missing latest point vertices . append ( pt ) poly = Polygon ( vertices ) poly . draw ( win ) # with 3 points pt = win . getMouse () # presume exterior the region rect . undraw () return poly
There is a fine point here that I missed the first time. The vertices of an existing Polygon practise not get mutated in this organization. A new Polygon gets created each time with the new vertex listing. The old Polygon does non go away automatically, and extraneous lines appear in the pic if the old polygon is not explicitly undrawn each time before a new version is redrawn with an extra vertex. The last Polygon you draw should be visible at the stop, so in the example above where I was assuming the 3rd click was the concluding for the triangle, I did not undraw
the Polygon.
The timing for each undraw
needs to be after the next mouse click and presumably before the revised Polygon is created, so information technology could exist earlier or afterward the line vertices.suspend(pt)
. I arbitrarily chose for it to go before the vertices list is changed. The remainder of the order of the lines is pretty well fixed by the basic logic.
If you lot think of the repetitions through a large number of loops, the procedure is essentially circular (equally suggested past the word 'loop'). The body of a loop in Python, nevertheless, is written as a linear sequence: ane with a first line and a last line, a beginning and an end. We can cutting a circular loop anywhere to get a piece with a beginning and an cease. In practice, the place you cut the loop for Python has 1 master constraint: The processing in Python from the end of i fourth dimension through the loop to the beginning of the side by side loop is separated by the test of the condition in the heading. The continuation condition in the while
heading must brand sense where you lot cut the loop.
It tin can help to look at a concrete example sequence, similar the steps listed in a higher place for creating a triangle, only now bold we do not know how many vertices volition be chosen. The continuation status is for pt
to be in the rectangle, so using the previously written function isInside
, the loop heading volition be
while isInside ( pt , rect ):
With this condition in listen, look for where to split up to loop. Information technology needs to exist after a new pt
is clicked (then it tin be tested) and before the next Polygon is created (so it does not include the picket point by error). In item, with the sequence higher up, await and encounter that the divide could become before or after the poly.undraw()
line. Exercise Moving Undraw considers the example where the split goes earlier this line. I will proceed with the selection of splitting into a Python loop after the undraw
line. This makes the loop be
while isInside ( pt , rect ): vertices . append ( pt ) poly = Polygon ( vertices ) poly . draw ( win ) pt = win . getMouse () poly . undraw ()
If you follow the total sequence of required steps above for making the concrete triangle, yous run into that this total sequence for the loop is only repeated twice. The final time there is no poly.undraw()
pace. I could redo the loop moving the undraw line to the meridian, which caused different issues (Exercise Moving Undraw below). Instead think how to get in piece of work at the end of the terminal fourth dimension through the loop....
In that location are several possible approaches. Yous want the undraw
line every fourth dimension except for the final time. Hence it is a argument you want sometimes and non others. That suggests an if
statement. The times you want the undraw
are when the loop volition echo again. This is the same as the continuation condition for the loop, and you take just read the next value for pt
! Y'all could just add a condition in front of the last line of the loop:
if isInside ( pt , rect ): poly . undraw ()
I find this pick unaesthetic: information technology means duplicating the continuation test twice in every loop.
Instead of avoiding the undraw
equally you go out the loop, another pick in this case is to undo it: just redraw the polygon one terminal time across the loop. This only needs to be done in one case, non repeatedly in the loop. Then the repetitious lines collapse neatly into the loop.
If you lot look at the overall concrete sequence for the triangle, non all the lines are in the loop. You must advisedly include the lines both that come earlier the loop and those that come after the loop. Make sure these lines are not put in the loop, but before or afterwards, as indicated by the concrete sequence in the case. In the end the entire office is:
def polyHere ( rect , win ): ''' Draw a polygon interactively in Rectangle rect, in GraphWin win. Collect mouse clicks inside rect into the vertices of a Polygon, and ever draw the Polygon created so far. When a click goes exterior rect, stop and return the final polygon. The Polygon ends up drawn. The method draws and undraws rect. ''' rect . setOutline ( "red" ) rect . describe ( win ) vertices = list () pt = win . getMouse () while isInside ( pt , rect ): vertices . append ( pt ) poly = Polygon ( vertices ) poly . draw ( win ) pt = win . getMouse () poly . undraw () poly . draw ( win ) rect . undraw () render poly
Make certain yous understand: Follow this code through, imagining three mouse clicks inside rect and then one click outside of rect. Compare the steps to the ones in the concrete sequence written out above and encounter that the match (aside from the last canceling undraw
and draw
of poly
).
This part is illustrated in the example plan makePoly.py
. Other than standard graphics example code, the main program contains:
rect1 = Rectangle ( Point ( v , 55 ), Indicate ( 200 , 120 )) poly1 = polyHere ( rect1 , win ) poly1 . setFill ( 'greenish' ) rect2 = Rectangle ( Point ( 210 , l ), Point ( 350 , 350 )) poly2 = polyHere ( rect2 , win ) poly2 . setOutline ( 'orange' )
As you can meet, the returned polygons are used to make color changes, just equally an analogy.
In earlier blitheness examples a while
loop would too have been useful. Rather than continuing the animation a fixed number of times, it would be overnice for the user to indicate by a mouse click when she has watched long enough. Thus far the only mode to use the mouse has been with getMouse()
. This is not going to work in an blitheness, considering the computer stops and waits for a click with getMouse()
, whereas the animation should continue until the click.
In total-fledged graphical systems that respond to events, this is no problem. Zelle's graphics is congenital on top of a capable effect-driven system, and in fact, all mouse clicks are registered, even exterior calls to getMouse()
.
Equally an example, run example program randomCirclesWhile.py
. Be sure to follow the prompt saying to click to start and to terminate.
Aside from the prompts, the difference from the previous randomCircles.py
program is the replacement of the original unproblematic repeat loop heading
past the following initialization and while loop heading:
while win . checkMouse () == None : #NEW*
The graphics module remembers the last mouse click, whether or non it occurred during a call to getMouse()
. A fashion to check if the mouse has been clicked since the last call to getMouse()
is checkMouse()
. It does non expect for the mouse as in getMouse()
. Instead it returns the remembered mouse click - the virtually recent mouse click in the past, unless in that location has been no mouse click since the last call to getMouse or checkMouse. In that example checkMouse()
returns None (the special object used to indicate the lack of a regular object).
The checkMouse
method allows for a loop that does not stop while waiting for a mouse click, merely goes on until the heading test detects that the mouse was clicked.
A similar elaboration can be made for the other examples of animation, like bounce1.py
. In bounceWhile.py
I modified bounce1.py
to have a while loop in identify of the for-loop repeating 600 times. Run it. The only slight added modification hither was that win
was not originally a parameter to bounceInBox
, so I included it. Await at the source lawmaking for bounceWhile.py
, with the few changes marked NEW.
In bounce2.py
I besides made a more interesting modify to the initialization, so the initial direction and speed of the mouse are determined graphically past the user, with a mouse click. Try example program bounce2.py
.
The program includes a new utility function to help decide the initial (dx, dy) for the blitheness. This is done by computing the move necessary to go from i betoken (where the ball is in this program) to another (specified by a user's mouse click in this program). :
def getShift ( point1 , point2 ): # NEW utility function '''Returns a tuple (dx, dy) which is the shift from point1 to point2.''' dx = point2 . getX () - point1 . getX () dy = point2 . getY () - point1 . getY () render ( dx , dy )
Since the role calculates both a change in x and y, it returns a tuple
.
A straightforward interactive method, getUserShift
, is wrapped around this function to get the user'due south option, which ultimately returns the same tuple:
def getUserShift ( betoken , prompt , win ): #NEW direction selection '''Return the change in position from the indicate to a mouse click in win. Commencement display the prompt string under point.''' text = Text ( Indicate ( point . getX (), 60 ), prompt ) text . draw ( win ) userPt = win . getMouse () text . undraw () return getShift ( point , userPt )
In the new version of the master driver, bounceBall
, excerpted below, this interactive setting of (dx, dy) is used. Note the multiple assignment statement to both dx and dy, set from the tuple returned from getUserShift
. This shift would generally be much too much for a single blitheness footstep, so the actual values passed to bounceBall are scaled fashion down past a factor calibration
.
center = Point ( win . getWidth () / 2 , win . getHeight () / 2 ) #NEW central starting point ball = makeDisk ( heart , radius , win ) #NEW interactive direction and speed setting prompt = ''' Click to betoken the direction and speed of the brawl: The farther you click from the ball, the faster it starts.''' ( dx , dy ) = getUserShift ( center , prompt , win ) scale = 0.01 # to reduce the size of animation steps bounceInBox ( ball , dx * scale , dy * scale , xLow , xHigh , yLow , yHigh , win )
The bounceInBox
method has the same modify to the loop as in the randomCircles.py instance. The method then requires the GraphWin
, win
, as a further parameter, since checkMouse
is a GraphWin
method.
Y'all can look in Idle at the full source lawmaking for bounce2.py
if y'all similar. The changes from bounce1.py
are all marked with a annotate starting with #NEW
, and all the major changes have been described to a higher place.
In the examples so far of the use of checkMouse()
, nosotros take only used the fact that a signal was clicked, not which point. The side by side example version, bounce3.py
, does apply the location of mouse clicks that are read with checkMouse()
to change the direction and speed of the brawl. Endeavor information technology.
This version only slightly modifies the cardinal animation part, bounceInBox
, but wraps it in another looping function that makes the direction and speed of the ball change on each mouse click. Hence the mouse clicks detected in bounceInBox
need to be remembered so returned after the master animation loop finishes. That requires a proper name, pt
, to be given to the concluding mouse click, and then information technology can exist remembered. This means modifying the main blitheness loop to initialize the variable pt
before the loop and reset it at the end of the loop, much as in the utilise of getMouse() for the interactive polygon creation. That explains the first three NEW lines and the last two NEW lines in the revised bounceInBox
:
def bounceInBox ( shape , dx , dy , xLow , xHigh , yLow , yHigh , win ): ''' Animate a shape moving in jumps (dx, dy), bouncing when its center reaches the low and high 10 and y coordinates. The animation stops when the mouse is clicked, and the last mouse click is returned.''' filibuster = . 001 pt = None #NEW while pt == None : #NEW shape . move ( dx , dy ) center = shape . getCenter () x = eye . getX () y = middle . getY () isInside = True #NEW if 10 < xLow or x > xHigh : dx = - dx isInside = Faux #NEW if y < yLow or y > yHigh : dy = - dy isInside = Imitation #NEW fourth dimension . sleep ( filibuster ) if isInside : # NEW don't mess with dx, dy when outside pt = win . checkMouse () #NEW return pt #NEW def moveInBox ( shape , stopHeight , xLow , xHigh , yLow , yHigh , win ): #NEW '''Shape bounces in win so its center stays within the low and high x and y coordinates, and changes management based on mouse clicks, terminating when there is a click in a higher place stopHeight.''' calibration = 0.01 pt = shape . getCenter () # starts motionless while pt . getY () < stopHeight : ( dx , dy ) = getShift ( shape . getCenter (), pt ) pt = bounceInBox ( shape , dx * scale , dy * scale , xLow , xHigh , yLow , yHigh , win ) def makeDisk ( heart , radius , win ): '''Return a carmine disk that is drawn in win with given heart and radius.''' disk = Circle ( center , radius ) disk . setOutline ( "cherry" ) disk . setFill ( "red" ) disk . draw ( win ) return disk def getShift ( point1 , point2 ): '''Returns a tuple (dx, dy) which is the shift from point1 to point2.''' dx = point2 . getX () - point1 . getX () dy = point2 . getY () - point1 . getY () return ( dx , dy ) def bounceBall (): '''Make a ball bounce around the screen, and react to mouse clicks.''' win = GraphWin ( 'Ball Bounce 3' , 290 , 290 ) win . yUp () #NEW to mark and label the area where a click stops the plan lineHeight = win . getHeight () - 40 textHeight = win . getHeight () - 20 Line ( Point ( 0 , lineHeight ), Point ( win . getWidth (), lineHeight )) . draw ( win ) prompt = 'Click to a higher place the line to finish \northward or below to motion toward the click.' Text ( Signal ( win . getWidth () / ii , textHeight ), prompt ) . draw ( win ) radius = 10 xLow = radius # middle is separated from the wall by the radius at a bounciness xHigh = win . getWidth () - radius yLow = radius yHigh = lineHeight - radius #NEW lower height to billowy limits middle = Point ( win . getWidth () / 2 , lineHeight / 2 ) ball = makeDisk ( center , radius , win ) moveInBox ( ball , lineHeight , xLow , xHigh , yLow , yHigh , win ) #NEW win . close () bounceBall ()
I initially made just the changes discussed then far (not the ones involving the new variable isInside
). The variable isInside
was in response to a bug that I volition discuss afterward introducing the unproblematic function that wraps around bounceInBox
:
Each fourth dimension the mouse is clicked, the ball is to switch direction and move toward the terminal click, until the stopping condition occurs, when in that location is a click above the stop line. This is clearly repetitive and needs a while loop. The status is but to test the y coordinate of the mouse click against the the height of the stop line. The body of the loop is very short, since nosotros already take the utility part getShift
, to figure out (dx, dy) values.
def moveInBox ( shape , stopHeight , xLow , xHigh , yLow , yHigh , win ): #NEW '''Shape bounces in win so its eye stays within the low and high 10 and y coordinates, and changes direction based on mouse clicks, terminating when in that location is a click above stopHeight.''' scale = 0.01 pt = shape . getCenter () # starts motionless while pt . getY () < stopHeight : ( dx , dy ) = getShift ( shape . getCenter (), pt ) pt = bounceInBox ( shape , dx * scale , dy * calibration , xLow , xHigh , yLow , yHigh , win )
The variable pt
for the last mouse click needed to be initialized some way. I chose to make the value exist the same equally the initial position of the ball, so both dx and dy are initially 0, and the ball does not start in motility. (Alternatives are in Random Start Practise below.)
I occasionally detected a issues when using the program. The ball would become stuck but outside the purlieus and stay there. The fact that information technology was slightly beyond the boundary was a clue: For simplicity I had cheated, and allowed the ball to go merely one animation pace beyond the intended boundary. With the speed and pocket-sized step size this works visually. The original code was sure to make an reverse spring back inside at the next step.
Subsequently some thought, I noticed that the initial version of the bounce3.py code for bounceInBox
broke that supposition. When the ball was where a bounce-dorsum is required, a mouse click could change (dx, dy) and mess up the bounce. The idea for a gear up is not to let the user alter the direction in the moment when the brawl needs to bounce back.
Neither of the original purlieus-checking if
statements, by itself, always determines if the ball is in the region where it needs to opposite direction. I dealt with this state of affairs by introducing a Boolean variable isInside
. It is initially set as True
, and so either of the if
statements can correct it to False. Then, at the end of the loop, isInside
is used to brand sure the brawl is safely within the proper region when there is a check for a new mouse click and a possible user adjustment to (dx, dy).
3.3.4.i. Exercise Moving Undraw¶
** As discussed higher up at Where to dissever the loop, the basic loop logic works whether the poly.undraw()
phone call is at the beginning or end of the loop. Write a variation makePoly2.py
that makes the code work the other fashion, with the poly.undraw()
at the beginning of the loop. Exercise non alter or movement any other statement in the loop. The new identify to cut the loop does affect the code before and later on the loop. In particular, the actress argument drawing poly
is not needed subsequently the loop is completed. Make other changes to the surrounding code to make this piece of work. Hints: [iv]
3.iii.4.2. Brand Path Practise¶
** Write a program that is outwardly very like to makePoly.py
, and call it makePath.py
, with a office pathHere
. The just outward difference between polyHere
and pathHere
is that while the first creates a closed polygon, and returns it, and the new one creates a polygonal path, without the final point being automatically continued to the first point, and a list of the lines in the path is returned. Internally the functions are quite different. The change simplifies some things: no need to undraw annihilation in the chief loop - just draw the latest segment each time going from the previous signal to the just clicked bespeak. There are complications withal: You do need deal especially with the get-go bespeak. It has no previous point to connect to. I suggest y'all handle this before the main loop: If the signal is within the rectangle, draw the point and so it is a visible guide for the next point. Before returning, undraw this initial point. (The place on the screen will still be visible if an initial segment is drawn. If no more points were added, the screen is left bare, which is the way information technology should be, and an empty listing of lines should be returned.) You also demand to recall the previous point each time through the main loop. I advise you think individually about what should happen if y'all stop the cartoon when the get-go, 2nd or third point is outside the rectangle. Too test each of those cases after the programme is written.
In your principal program, call the makePath
office two times. Utilize the list of lines returned to loop through and change the color of all the lines in one path and the width of the lines in the other path. A portion of a sample image from this program is shown below.
iii.3.4.iii. Random Start Exercise¶
* (Optional) I chose to take the brawl start motionless, by making the initial value of pt
(which determines the initial (dx, dy) ) be the center of the ball. Write a variation startRandom.py
so pt
is randomly chosen. As well make the initial location of the ball be random. You lot can copy the function getRandomPoint
from bounce1.py.
3.3.4.4. Mad Lib While Exercise¶
** Write a programme madlib4.py
that modifies the getKeys
method of madlib2.py
to use a while
loop. (This is not an animation plan, but this department is where you have had the most experience with while loops!)
Hints: This is really the most natural approach. I avoided while
loops initially, when merely for
loops had been discussed. In the original approach, withal, it is redundant to find every instance of '{'
to count the number of repetitions and and then observe them all again when extracting the cue keys. A more natural fashion to command the loop is a while
loop stopping when there are no further occurrences of '{'
to notice
. This involves some further adjustments. You must cutting the loop in a different place (to end later searching for '{'
). Every bit discussed before, cutting a loop in a different place may require changes before and afterward the loop, too.
3.3.four.5. Find Pigsty Game Do¶
** Write a graphical game program, findHole.py
, "Find the Hole". The programme should use a random number generator to determine a round "hole", selecting a signal and a perhaps the radius around that point. These make up one's mind the target and are non revealed to the thespian initially. The user is then prompted to click around on the screen to "notice the hidden pigsty". You should prove the points the user has tried. One time the user selects a point that is within the chosen radius of the mystery point, the mystery circle should appear. There should be a bulletin announcing how many steps information technology took, and the game should end.
Hint: you lot have already seen the code to determine the displacement (dx, dy) betwixt 2 points: utilize the getShift
function in bounce2.py
. Once yous have the deportation (dx, dy) between the hidden center and the latest mouse click, the altitude betwixt the points is (dx*dx + dy*dy)**0.v
, using the Pythagorean Theorem of geometry. If this distance is no more than the radius that you lot have chosen for the mystery circle, then the user has constitute the circumvolve! You lot can utilize getShift
every bit written, or alter it into a function getDistance
that directly returns the distance betwixt two points.
Many elaborations on this game are possible! Have fun with information technology!
3.3.5. Fancier Blitheness Loop Logic (Optional)¶
The terminal variation is the example program bounce4.py
, which has the aforementioned outward behavior every bit bounce3.py, but it illustrates a different internal design determination. The bounce3.py version has ii levels of while loop in two methods, moveInBox
for mouse clicks and bounceInBox
for bouncing. The bounce4.py version puts all the code for irresolute direction inside the main animation loop in the erstwhile outer function, moveInBox
. There are at present three reasons to adjust (dx, dy): billowy off the sides, bouncing off the top or lesser, or a mouse click. That is a simplification and unification of the logic in ane sense. The complication at present is that the logic for determining when to quit is buried deep inside the if
- else
logic, not at the heading of the loop. The exam for mouse clicks is inside the while
loop and further inside some other if
argument. The test of the mouse click may merely lead to a alter in (dx, dy), or is a signal to quit. Here is the revised code, with a give-and-take afterward of the return statement:
def moveInBox ( shape , stopHeight , xLow , xHigh , yLow , yHigh , win ): ''' Animate a shape moving toward any mouse click below stopHeight and billowy when its eye reaches the depression or high x or y coordinates. The animation stops when the mouse is clicked at stopHeight or above.''' scale = 0.01 delay = . 001 dx = 0 #NEW dx and dy are no longer parameters dy = 0 #NEW while True : #NEW exit loop at return statement centre = shape . getCenter () x = center . getX () y = center . getY () isInside = Truthful if x < xLow or 10 > xHigh : dx = - dx isInside = Imitation if y < yLow or y > yHigh : dy = - dy isInside = False if isInside : pt = win . checkMouse () if pt != None : #NEW dealing with mouse click now here if pt . getY () < stopHeight : # switch direction ( dx , dy ) = getShift ( center , pt ) ( dx , dy ) = ( dx * scale , dy * scale ) else : #NEW exit from depths of the loop return #NEW shape . move ( dx , dy ) fourth dimension . sleep ( delay )
Call back that a return
statement immediately terminates function execution. In this instance the function returns no value, simply a blank render
is legal to forcefulness the exit. Since the testing is not done in the normal while
condition, the while
condition is set up as permanently Truthful
. This is not the nearly common while
loop pattern! It obscures the loop exit. The selection between the approach of bounce3.py
and bounce4.py
is a thing of taste in the given situation.
[1] | "while ___", "do ___ while", "repeat while", "repeat until", "as long equally ___, do", "keep doing ___ every bit long as" |
[2] | Yous volition need a loop. You tin impress/append almost all the numbers in the loop. Yous are likely to omit one number with just this code, just after looking at what you lot produce, it is easy to separately include the remaining number. There are several ways to do this. |
[three] | Call up the built-in len office! It applies to lists. |
[4] | The basic effect is similar to the old version: the undraw is not e'er needed – at the beginning in this case. In this identify information technology is not needed the first time through the loop. The ii bones approaches considered for the previous version nonetheless work here: make an extra compensating activity outside the loop or break into cases inside the loop. Further hint: It is legal to describe a polygon with an empty vertex list - nothing appears on the screen. |
sawyerbrigingening.blogspot.com
Source: http://anh.cs.luc.edu/handsonPythonTutorial/whilestatements.html
0 Response to "How Do I Enter Something Again in Method"
Post a Comment