How to Use the Input Value Again After 1 Time for Loop Python
3.3.1. 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 style through a specified listing. In any case the for
loop has required the use of a specific listing. This is frequently as well restrictive. A Python while
loop behaves quite similarly to common English usage. If I say
While your tea is too hot, add a chip of water ice.
Presumably yous would test your tea. If it were likewise hot, y'all would add a trivial ice. If you test again and it is still too hot, you would add ice again. As long as you lot tested and plant it was true that your tea was too hot, you would go back and add more ice. Python has a similar syntax:
while
condition:
- indentedBlock
Setting upwardly the English example in a similar format would exist:
- while your tea is too hot :
- add together a chip of ice
To brand things concrete and numerical, suppose the following: The tea starts at 115 degrees Fahrenheit. You want it at 112 degrees. A chip of water ice turns out to lower the temperature one degree each time. You exam the temperature each fourth dimension, and also print out the temperature before reducing the temperature. In Python you could write and run the lawmaking below, saved in case program cool.py:
temperature = 115 while temperature > 112 : # starting time while loop code print ( temperature ) temperature = temperature - 1 print ( 'The tea is cool plenty.' ) |
I added a terminal line after the while loop to remind y'all that execution follows sequentially after a loop completes.
If you play computer and follow the path of execution, yous could generate the following tabular array. Remember, that each time you lot attain the end of the indented cake after the while
heading, execution returns to the while
heading for another examination:
Line | temperature | Comment |
---|---|---|
1 | 115 | |
ii | 115 > 112 is truthful, practice loop | |
3 | prints 115 | |
four | 114 | 115 - 1 is 114, loop dorsum |
2 | 114 > 112 is true, do loop | |
three | prints 114 | |
4 | 113 | 114 - one is 113, loop back |
2 | 113 > 112 is true, do loop | |
3 | prints 113 | |
iv | 112 | 113 - i is 112, loop dorsum |
2 | 112 > 112 is false, skip loop | |
6 | prints that the tea is cool |
Each fourth dimension the end of the indented loop torso is reached, execution returns to the while
loop heading for another test. When the exam is finally false, execution jumps past the indented trunk of the while
loop to the adjacent sequential statement.
A while
loop generally follows the pattern of the successive modification loop introduced with for
-each loops:
initialization
while
continuationCondition:
do master activeness to be repeated
ready variables for the next time through the loop
Test yourself: Post-obit the code. Effigy out what is printed. :
i = 4 while i < 9 : print ( i ) i = i + two
Check yourself by running the example program testWhile.py
.
Notation
In Python, while
is non used quite similar in English. In English y'all could mean to end as shortly as the condition y'all want to examination becomes false. In Python the test is only made when execution for the loop starts (or starts again), not in the middle of the loop.
Predict what volition happen with this slight variation on the previous example, switching the gild in the loop body. Follow it carefully, i step at a time.
i = 4 # variation on testWhile.py while ( i < 9 ): i = i + 2 print ( i ) |
Cheque yourself past running the example program testWhile2.py
.
The sequence order is important. The variable i
is increased before it is printed, so the first number printed is 6. Another common fault is to assume that ten will not be printed, since 10 is by ix, merely the test that may stop the loop is not fabricated in the eye of the loop. One time the trunk of the loop is started, information technology continues to the end, even when i
becomes x.
Line | i | Annotate |
---|---|---|
1 | 4 | |
2 | iv < 9 is true, do loop | |
3 | 6 | four+ii=6 |
4 | print 6 | |
2 | 6 < 9 is true, do loop | |
3 | 8 | 6+2= 8 |
iv | print eight | |
2 | viii < ix is true, exercise loop | |
3 | 10 | 8+two=ten No test here |
4 | print x | |
ii | ten < 9 is false, skip loop |
Predict what happens in this related little program:
nums = listing () i = 4 while ( i < 9 ): nums . append ( i ) i = i + 2 impress ( nums )
Bank check yourself by running the example plan testWhile3.py
.
3.iii.2. The Most General range
Function¶
There is actually a much simpler way to generate the previous sequences like in testWhile3.py
, using a further variation of the range
part. Enter these lines separately in the Shell. As in the simpler applications of range
, the values are only generated one at a time, as needed. To see the entire sequence at once, convert the sequence to a list before printing:
nums = range ( four , 9 , 2 ) print ( list ( nums ))
The 3rd parameter for the range function is the footstep size. It is needed when the step size from i element to the next is non 1.
The most full general syntax is
range(
get-go,
pastEnd,
footstep)
The value of the 2nd parameter is ever past the last element of the list. Each chemical element after the first in the listing is step more than the previous one. Predict and try in the Shell:
Actually the range function is fifty-fifty more sophisticated than indicated by the while
loop higher up. The step size can be negative. Endeavour in the Shell:
Do you see how 0 is past the end of the list?
Try it: Brand up a range
office phone call to generate the list of temperatures printed in the tea instance, 115, 114, 113
. Examination it in the Crush.
These ranges, similar the simpler ranges that we used earlier, are most often used as the sequence in a for
loop heading:
for i in range ( 10 , 0 , - i ): # countdown... print ( i ) print ( 'Blastoff!' )
three.3.3. Interactive while
Loops¶
The before examples of while loops were chosen for their simplicity. Apparently they could have been rewritten with range part calls. At present lets endeavor a more than interesting instance. Suppose yous desire to let a user enter a sequence of lines of text, and want to think each line in a list. This could easily be done with a uncomplicated repeat loop if you knew the number of lines to enter. For example, in readLines0.py
, the user is prompted for the verbal number of lines to exist entered:
lines = list () northward = int ( input ( 'How many lines practice y'all want to enter? ' )) for i in range ( due north ): line = input ( 'Next line: ' ) lines . append ( line ) print ( 'Your lines were:' ) # check now for line in lines : print ( line )
The user may want to enter a bunch of lines and not count them all ahead of fourth dimension. This means the number of repetitions would not be known ahead of fourth dimension. A while
loop is advisable here. In that location is still the question of how to test whether the user wants to continue. An obvious but verbose way to do this is to enquire before every line if the user wants to proceed, as shown below and in the example file readLines1.py
. Read it and then run it:
lines = listing () testAnswer = input ( 'Press y if yous want to enter more lines: ' ) while testAnswer == 'y' : line = input ( 'Next line: ' ) lines . append ( line ) testAnswer = input ( 'Printing y if yous desire to enter more lines: ' ) impress ( 'Your lines were:' ) for line in lines : print ( line )
Run across the two statements setting testAnswer
: i earlier the while
loop and i at the bottom of the loop body.
Note
The data must exist initialized before the loop, in order for the first test of the while condition to work. Also the test must work when yous loop back from the cease of the loop trunk. This means the data for the test must also be set up a second time, in the loop body (commonly as the action in the terminal line of the loop). It is easy to forget the second time!
The readLines1.py
code works, but information technology may be more abrasive than counting alee! Ii lines must be entered for every one you actually want! A practical alternative is to utilise a sentry: a piece of information that would not brand sense in the regular sequence, and which is used to indicate the end of the input. You could concur to employ the line DONE!
Even simpler: if you assume all the real lines of information will actually have some text on them, utilize an empty line as a sentinel. (If you recollect about it, the Python Beat out uses this approach when yous enter a statement with an indented torso.) This way you just need to enter one extra (very simple) line, no thing how many lines of real information you have.
What should the while condition be now? Since the sentinel is an empty line, y'all might think line == ''
, just that is the termination status, not the continuation condition: Yous need the opposite condition. To negate a condition in Python, you lot may use not
, like in English,
Of course in this state of affairs 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 ( 'Next line: ' ) # initalize before the loop while line != '' : # while NOT the termination condition lines . append ( line ) line = input ( 'Next line: ' ) # !! reset value at cease of loop! print ( 'Your lines were:' ) for line in lines : print ( line )
Once more the data for the examination in the while loop heading must be initialized earlier the starting time time the while
statement is executed and the test information must too be made prepare inside the loop for the test after the trunk has executed. Hence y'all see the statements setting the variable line
both before the loop and at the stop of the loop body. It is like shooting fish in a barrel to forget the 2d place inside the loop!
Subsequently reading the rest of this paragraph, annotate the concluding line of the loop out, and run information technology over again: It will never finish! The variable line
volition forever have the initial value yous gave it! Yous actually can stop the program past entering Ctrl-C
. That means agree the Ctrl
cardinal and press c
.
Annotation
As you lot finish coding a while
loop, it is skilful practice to always double-check: Did I make a change to the variables, inside the loop, that will somewhen make the loop condition Simulated
?
The earliest while
loop examples had numerical tests and the lawmaking to get ready for the next loop only incremented a numerical variable past a fixed amount. Those were unproblematic examples but while
loops are much more general! In the interactive loop nosotros have seen a continuation condition with a string test, and getting prepare for the next fourth dimension through the loop involves input from the user.
Some of the exercises that follow involve interactive while loops. Others were delayed until here just because they have a wider variety of continuation condition tests and ways to fix for the next fourth dimension through the loop. What is consistent is the full general steps to think of and questions to ask yourself. They proceed on applying! Keep these in mind!
- the need to meet whether there is a kind of repetition, fifty-fifty without a fixed collection of values to work through
- to think from the specific situation and figure out the continuation condition that makes sense for your loop
- to retrieve what specific processing or results you want each time through the loop, using the aforementioned lawmaking
- to figure out what supporting code yous need to make y'all set for the next time through the loop: how to make the aforementioned results code have new data values to procedure each time through, and somewhen accomplish a stopping indicate.
Detecting the need for while
statements: Similar with planning programs needing``for`` or if
statements, you lot want to be able to translate English descriptions of issues that would naturally include while
statements. What are some words or phrases or ideas that suggest the use of these statements? Think of your own and then compare to a few I gave: [ane]
3.iii.3.1. Interactive Sum Exercise¶
Write a program sumAll.py
that prompts the user to enter numbers, one per line, catastrophe with a line containing just 0, and keep a running sum of the numbers. Only print out the sum after all the numbers are entered (at to the lowest degree in your last version). Practice not create a list! Each time you read in a number, you can immediately employ it for your sum, and and then be done with the number just entered.
3.3.three.2. Safety Number Input Exercise¶
* There is an issue with reading in numbers with the input statement. If you make a typo and enter something that cannot be converted from a string to the correct kind of number, a naive plan will bomb. This is avoidable if y'all test the string and repeat if the string is illegal. In this exercise write safe utility function replacements for the input part that 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 do. Parts b. and c. refer to functions in the solution, isNumberStr.py
, of the previous practice. Brand sure yous look back at these first.
Save the example safeNumberInputStub.py
as safeNumberInput.py
, and complete it. It contains headings and documentation strings for the functions in each role of this practice.
- This part considers the simplest example, where you are trying to enter a whole number. Complete the definition of the function
safeWholeNumber
. - Complete the function
safeInt
. This easily parallels part a. if you lot copy in and use the office (not method)isIntegerStr
. - Complete the function
safeDecimal
. This easily parallels part b. if you re-create in and use the roleisDecimalStr
.
3.iii.three.3. Savings Practice¶
The idea here is to come across how many years it will accept a bank account to grow to at least a given value, bold a stock-still annual interest. Write a program savings.py
. Prompt the user for 3 numbers: an initial balance, the annual percent for interest every bit a decimal, like .04 for 4%, and the final balance desired.
All the budgetary amounts that y'all print should be rounded to exactly two decimal places. Start by printing the initial balance this mode. For case, if the initial balance was entered as 123.v, information technology should be reprinted by your programme as 123.l. As well print the residuum each twelvemonth until the desired amount is reached or passed. The start balance at or past the target should exist the last 1 printed.
The math: The corporeality next year is the corporeality at present times (i + involvement fraction), so if I have $500 at present and the interest charge per unit is .04, I take $500*(one.04) = $520 after i year and afterwards two years I take, $520*(ane.04) = $540.80....
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.80 562.43
3.3.3.4. Strange Sequence Exercise¶
* Recollect Strange Function Exercise and its jumpFunc.py
which contains the function bound
: For any integer n, leap(n) is due north//2 if due north is even, and 3*n+1 if due north is odd.
You can first with one number, say n = 3, and keep applying the jump function to the terminal number given, and see how the numbers jump around!
jump ( 3 ) = 3 * three + 1 = x ; leap ( x ) = x // 2 = 5 ; jump ( 5 ) = iii * 5 + 1 = 16 ; jump ( xvi ) = 16 // 2 = 8 ; bound ( 8 ) = 8 // 2 = 4 ; jump ( 4 ) = 4 // 2 = 2 ; jump ( ii ) = 2 // 2 = 1
This process of repeatedly applying the same role to the nearly recent result is called role iteration. In this instance y'all see that iterating the jump part, starting from due north=3, eventually reaches the value ane.
It is an open up research question whether iterating the jump function from an integer n will eventually achieve 1, for every starting integer n greater than 1. Researchers take only found examples of north where it is true. Still, no general argument has been made to apply to the infinite number of possible starting integers.
In this exercise you iterate the bound role for specific starting values north, until the effect is one.
-
Save instance
jumpSeqStub.py
asjumpSeq.py
and complete the missing part bodies. If yous coded the functionjump
before injumpFunc.py
, y'all tin re-create information technology. Y'all can consummate eitherprintJumps
orlistJumps
first, and examination earlier completing the other. Hint [ii] -
After you have finished and saved
jumpSeq.py
re-create it and save the file asjumpSeqLengths.py
.First modify the main method then information technology prompts the user for a value of northward, so prints just the length of the iterative sequence from listJumps(north). Hint [3]
So elaborate the program and so it prompts the user for two integers: a lowest starting value of north and a highest starting value of northward. For all integers due north in the range from the lowest showtime through the highest get-go, including the highest, impress a judgement giving the starting value of north and the length of the list from
listJumps(northward)
. An case run:Enter lowest get-go: 3
Enter highest start: vi
Starting from 3, jump sequence length 8.
Starting from 4, jump sequence length 3.
Starting from 5, jump sequence length six.
Starting from half dozen, jump sequence length nine.
3.3.four. Graphical Applications¶
Some other identify where a while
loop could exist useful is in interactive graphics. Suppose you lot want the user to exist able to create a Polygon by clicking on vertices they choose interactively, but you do not want them to have to count the number of vertices alee of time. A while
loop is suggested for such a repetitive process. Equally with entering lines of text interactively, in that location is the question of how to indicate that you are washed (or how to point to go along). If you make only a sure region be allowed for the Polygon, then the lookout tin be a mouse click outside the region. The before interactive color choice example already has a method to check if a mouse click is within a Rectangle, so that method can be copied and reused.
Creating a polygon is a unified activity with a articulate result, and so let'south define a function. It involves a boundary rectangle and mouse clicks in a GraphWin, and may every bit well return the Polygon constructed. Read the following start:
def polyHere ( rect , win ): ''' Depict 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 and then far. When a click goes outside rect, stop and return the last polygon. The Polygon ends upwardly drawn. The method draws and undraws rect. '''
Information technology is useful to offset past thinking of the objects needed, and give them names.
- A Polygon is needed. Telephone call it
poly
. - A list of vertices is needed. Call it
vertices
. I need to suspend to this listing. Information technology must be initialized get-go. - The latest mouse click bespeak is needed. Telephone call it
pt
.
Certainly the overall process volition be repetitious, choosing bespeak after point. Still it may not exist at all clear how to brand an constructive 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 can be written in sequence without worrying nigh a loop.
For instance to get up to a triangle (3 vertices in our listing and a quaternary mouse click for the sentinel), you might imagine the following sequence, undrawing each onetime polygon before the next is displayed with the latest mouse click included:
rect . setOutline ( 'red' ) rect . draw ( win ) vertices = list () pt = win . getMouse () vertices . append ( pt ) poly = Polygon ( vertices ) poly . draw ( win ) # with 1 point pt = win . getMouse () poly . undraw () # missing latest point vertices . suspend ( pt ) poly = Polygon ( vertices ) poly . draw ( win ) # with two points pt = win . getMouse () poly . undraw () # missing latest point vertices . append ( pt ) poly = Polygon ( vertices ) poly . draw ( win ) # with three points pt = win . getMouse () # assume outside the region rect . undraw () render poly
There is a fine point here that I missed the first fourth dimension. The vertices of an existing Polygon do non go mutated in this system. A new Polygon gets created each time with the new vertex list. The old Polygon does not become away automatically, and extraneous lines appear in the picture if the old polygon is not explicitly undrawn each time before a new version is redrawn with an extra vertex. The last Polygon yous describe should be visible at the terminate, so in the case above where I was bold the 3rd click was the last for the triangle, I did non undraw
the Polygon.
The timing for each undraw
needs to be after the next mouse click and presumably earlier the revised Polygon is created, so it could be earlier or after the line vertices.suspend(pt)
. I arbitrarily chose for information technology to go earlier the vertices list is inverse. The rest of the lodge of the lines is pretty well fixed by the basic logic.
If yous think of the repetitions through a large number of loops, the process is essentially circular (equally suggested by the give-and-take 'loop'). The body of a loop in Python, yet, is written as a linear sequence: one with a first line and a concluding line, a beginning and an finish. We can cut a circular loop anywhere to get a piece with a beginning and an end. In practice, the place you cut the loop for Python has one main constraint: The processing in Python from the end of one fourth dimension through the loop to the first of the next loop is separated by the test of the condition in the heading. The continuation condition in the while
heading must make sense where you lot cut the loop.
It can help to look at a physical example sequence, like the steps listed above for creating a triangle, but at present bold we do non know how many vertices volition exist chosen. The continuation condition is for pt
to be in the rectangle, so using the previously written role isInside
, the loop heading will exist
while isInside ( pt , rect ):
With this status in mind, look for where to divide to loop. It needs to be after a new pt
is clicked (and so it can exist tested) and before the adjacent Polygon is created (so it does non include the sentry indicate past fault). In particular, with the sequence above, look and run across that the dissever could get earlier or afterward the poly.undraw()
line. Practise Moving Undraw considers the case where the split goes before this line. I will proceed with the pick of splitting into a Python loop after the undraw
line. This makes the loop exist
while isInside ( pt , rect ): vertices . append ( pt ) poly = Polygon ( vertices ) poly . describe ( win ) pt = win . getMouse () poly . undraw ()
If yous follow the full sequence of required steps higher up for making the concrete triangle, you encounter that this full sequence for the loop is just repeated twice. The concluding time at that place is no poly.undraw()
stride. I could redo the loop moving the undraw line to the top, which acquired different issues (Exercise Moving Undraw below). Instead think how to make it work at the end of the final time through the loop....
There are several possible approaches. Y'all want the undraw
line every time except for the last time. Hence it is a statement you want sometimes and not others. That suggests an if
statement. The times yous desire the undraw
are when the loop will repeat again. This is the same as the continuation condition for the loop, and yous have just read the next value for pt
! You lot could just add a condition in front of the last line of the loop:
if isInside ( pt , rect ): poly . undraw ()
I discover this option unaesthetic: it means duplicating the continuation test twice in every loop.
Instead of fugitive the undraw
as you exit the loop, another choice in this case is to undo it: merely redraw the polygon one final time beyond the loop. This only needs to be done once, non repeatedly in the loop. And so the repetitious lines collapse neatly into the loop.
If y'all look at the overall physical sequence for the triangle, not all the lines are in the loop. You must carefully 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, merely earlier or later, as indicated by the physical sequence in the instance. In the terminate the entire function 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 always draw the Polygon created so far. When a click goes exterior rect, stop and return the terminal polygon. The Polygon ends up fatigued. The method draws and undraws rect. ''' rect . setOutline ( "reddish" ) 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 () return poly
Make sure you sympathize: Follow this lawmaking through, imagining three mouse clicks inside rect and and so one click outside of rect. Compare the steps to the ones in the concrete sequence written out above and come across that the match (aside from the last canceling undraw
and draw
of poly
).
This function is illustrated in the example plan makePoly.py
. Other than standard graphics example code, the main plan contains:
rect1 = Rectangle ( Point ( 5 , 55 ), Point ( 200 , 120 )) poly1 = polyHere ( rect1 , win ) poly1 . setFill ( 'green' ) rect2 = Rectangle ( Point ( 210 , 50 ), Signal ( 350 , 350 )) poly2 = polyHere ( rect2 , win ) poly2 . setOutline ( 'orange' )
As you can run across, the returned polygons are used to brand color changes, but every bit an illustration.
In earlier animation examples a while
loop would also take been useful. Rather than continuing the animation a fixed number of times, it would be nice for the user to indicate by a mouse click when she has watched long enough. Thus far the only way to use the mouse has been with getMouse()
. This is not going to work in an animation, because the computer stops and waits for a click with getMouse()
, whereas the animation should continue until the click.
In full-fledged graphical systems that respond to events, this is no problem. Zelle's graphics is built on top of a capable event-driven system, and in fact, all mouse clicks are registered, even outside calls to getMouse()
.
Every bit an example, run example program randomCirclesWhile.py
. Be certain to follow the prompt saying to click to first and to end.
Aside from the prompts, the difference from the previous randomCircles.py
program is the replacement of the original simple repeat loop heading
by 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 way to check if the mouse has been clicked since the last telephone call to getMouse()
is checkMouse()
. Information technology does not wait for the mouse as in getMouse()
. Instead it returns the remembered mouse click - the nearly recent mouse click in the past, unless there has been no mouse click since the last phone call to getMouse or checkMouse. In that example checkMouse()
returns None (the special object used to point the lack of a regular object).
The checkMouse
method allows for a loop that does non stop while waiting for a mouse click, just goes on until the heading exam detects that the mouse was clicked.
A similar elaboration can be made for the other examples of blitheness, similar bounce1.py
. In bounceWhile.py
I modified bounce1.py
to take a while loop in place of the for-loop repeating 600 times. Run it. The but slight added modification here was that win
was not originally a parameter to bounceInBox
, so I included information technology. Look at the source code for bounceWhile.py
, with the few changes marked NEW.
In bounce2.py
I besides fabricated a more interesting change to the initialization, then the initial management and speed of the mouse are determined graphically past the user, with a mouse click. Endeavor example program bounce2.py
.
The programme includes a new utility function to help determine the initial (dx, dy) for the animation. This is done past calculating the movement necessary to go from one indicate (where the ball is in this programme) to another (specified by a user'due south 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 function calculates both a change in x and y, it returns a tuple
.
A straightforward interactive method, getUserShift
, is wrapped around this role to go the user's choice, which ultimately returns the same tuple:
def getUserShift ( point , prompt , win ): #NEW direction selection '''Return the alter in position from the betoken to a mouse click in win. Starting time display the prompt string nether bespeak.''' text = Text ( Point ( signal . getX (), 60 ), prompt ) text . describe ( win ) userPt = win . getMouse () text . undraw () render getShift ( point , userPt )
In the new version of the principal driver, bounceBall
, excerpted below, this interactive setting of (dx, dy) is used. Annotation the multiple assignment statement to both dx and dy, set from the tuple returned from getUserShift
. This shift would by and large be much too much for a single animation step, so the actual values passed to bounceBall are scaled style down by a factor scale
.
centre = Point ( win . getWidth () / two , win . getHeight () / two ) #NEW key starting signal ball = makeDisk ( center , radius , win ) #NEW interactive management and speed setting prompt = ''' Click to indicate the direction and speed of the ball: The further you click from the ball, the faster information technology starts.''' ( dx , dy ) = getUserShift ( middle , prompt , win ) scale = 0.01 # to reduce the size of blitheness steps bounceInBox ( brawl , dx * scale , dy * scale , xLow , xHigh , yLow , yHigh , win )
The bounceInBox
method has the same modify to the loop as in the randomCircles.py example. The method then requires the GraphWin
, win
, as a farther parameter, since checkMouse
is a GraphWin
method.
You lot can expect in Idle at the full source code for bounce2.py
if yous like. The changes from bounce1.py
are all marked with a comment starting with #NEW
, and all the major changes have been described above.
In the examples and then far of the use of checkMouse()
, we have merely used the fact that a indicate was clicked, not which point. The next example version, bounce3.py
, does use the location of mouse clicks that are read with checkMouse()
to change the direction and speed of the ball. Endeavour information technology.
This version only slightly modifies the central animation function, bounceInBox
, but wraps it in another looping role that makes the management and speed of the ball change on each mouse click. Hence the mouse clicks detected in bounceInBox
need to be remembered and then returned after the primary blitheness loop finishes. That requires a name, pt
, to exist given to the last mouse click, then it can exist remembered. This means modifying the chief animation loop to initialize the variable pt
earlier the loop and reset it at the end of the loop, much every bit in the use of getMouse() for the interactive polygon creation. That explains the get-go 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 heart reaches the low and loftier x and y coordinates. The animation stops when the mouse is clicked, and the last mouse click is returned.''' delay = . 001 pt = None #NEW while pt == None : #NEW shape . move ( dx , dy ) center = shape . getCenter () x = center . getX () y = center . getY () isInside = Truthful #NEW if ten < xLow or x > xHigh : dx = - dx isInside = False #NEW if y < yLow or y > yHigh : dy = - dy isInside = False #NEW time . slumber ( delay ) if isInside : # NEW don't mess with dx, dy when exterior pt = win . checkMouse () #NEW return pt #NEW def moveInBox ( shape , stopHeight , xLow , xHigh , yLow , yHigh , win ): #NEW '''Shape bounces in win and so its center stays within the depression and loftier x and y coordinates, and changes direction based on mouse clicks, terminating when there 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 ) def makeDisk ( middle , radius , win ): '''Render a red deejay that is fatigued in win with given center and radius.''' disk = Circumvolve ( center , radius ) disk . setOutline ( "red" ) 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 () render ( dx , dy ) def bounceBall (): '''Brand a brawl bounciness around the screen, and react to mouse clicks.''' win = GraphWin ( 'Ball Bounciness 3' , 290 , 290 ) win . yUp () #NEW to mark and label the area where a click stops the program lineHeight = win . getHeight () - 40 textHeight = win . getHeight () - 20 Line ( Signal ( 0 , lineHeight ), Betoken ( win . getWidth (), lineHeight )) . draw ( win ) prompt = 'Click above the line to stop \n or below to move toward the click.' Text ( Bespeak ( win . getWidth () / ii , textHeight ), prompt ) . describe ( win ) radius = 10 xLow = radius # center is separated from the wall by the radius at a bounciness xHigh = win . getWidth () - radius yLow = radius yHigh = lineHeight - radius #NEW lower pinnacle to bouncing limits center = Point ( win . getWidth () / 2 , lineHeight / 2 ) brawl = makeDisk ( center , radius , win ) moveInBox ( ball , lineHeight , xLow , xHigh , yLow , yHigh , win ) #NEW win . shut () bounceBall ()
I initially made only the changes discussed so far (not the ones involving the new variable isInside
). The variable isInside
was in response to a bug that I volition discuss after introducing the simple function that wraps around bounceInBox
:
Each fourth dimension the mouse is clicked, the ball is to switch management and movement toward the last click, until the stopping status occurs, when there is a click above the stop line. This is conspicuously repetitive and needs a while loop. The status is but to test the y coordinate of the mouse click against the the elevation of the cease line. The torso of the loop is very short, since we already have the utility function getShift
, to figure out (dx, dy) values.
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 direction based on mouse clicks, terminating when there 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 * scale , xLow , xHigh , yLow , yHigh , win )
The variable pt
for the last mouse click needed to be initialized some mode. I chose to make the value be the same as the initial position of the ball, then both dx and dy are initially 0, and the ball does non start in motility. (Alternatives are in Random Commencement Practice below.)
I occasionally detected a issues when using the plan. The brawl would get stuck but exterior the purlieus and stay in that location. The fact that it was slightly across the boundary was a inkling: For simplicity I had cheated, and allowed the ball to go just 1 animation stride across the intended purlieus. With the speed and small step size this works visually. The original code was sure to make an opposite bound back inside at the next stride.
Afterward some thought, I noticed that the initial version of the bounce3.py code for bounceInBox
broke that assumption. 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 non to let the user change the direction in the moment when the brawl needs to bounciness back.
Neither of the original boundary-checking if
statements, by itself, always determines if the ball is in the region where it needs to reverse direction. I dealt with this state of affairs by introducing a Boolean variable isInside
. It is initially gear up as True
, and then either of the if
statements can correct it to False. Then, at the terminate of the loop, isInside
is used to make sure the ball is safely within the proper region when at that place is a check for a new mouse click and a possible user adjustment to (dx, dy).
3.iii.4.i. Do Moving Undraw¶
** Every bit discussed to a higher place at Where to split the loop, the basic loop logic works whether the poly.undraw()
call is at the first or stop of the loop. Write a variation makePoly2.py
that makes the code work the other mode, with the poly.undraw()
at the get-go of the loop. Do not change or move any other statement in the loop. The new place to cut the loop does affect the code before and after the loop. In item, the extra statement drawing poly
is not needed after the loop is completed. Make other changes to the surrounding code to brand this piece of work. Hints: [4]
3.3.4.2. Brand Path Exercise¶
** Write a program that is outwardly very like to makePoly.py
, and call it makePath.py
, with a function pathHere
. The only outward difference betwixt 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 last bespeak being automatically connected to the starting time 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 anything in the main loop - just draw the latest segment each fourth dimension going from the previous signal to the just clicked point. At that place are complications however: You practice need deal specially with the first indicate. It has no previous betoken to connect to. I suggest you handle this before the principal loop: If the point is inside the rectangle, draw the point and then it is a visible guide for the next indicate. Earlier returning, undraw this initial signal. (The place on the screen will still be visible if an initial segment is fatigued. If no more points were added, the screen is left blank, which is the way information technology should be, and an empty list of lines should exist returned.) Y'all also need to remember the previous point each time through the principal loop. I suggest you retrieve individually about what should happen if you stop the cartoon when the first, second or third point is outside the rectangle. Likewise test each of those cases afterward the program is written.
In your main program, call the makePath
office two times. Use the list of lines returned to loop through and change the color of all the lines in i path and the width of the lines in the other path. A portion of a sample paradigm from this programme is shown below.
3.three.4.3. Random Start Exercise¶
* (Optional) I chose to have the ball kickoff motionless, past making the initial value of pt
(which determines the initial (dx, dy) ) be the center of the brawl. Write a variation startRandom.py
and so pt
is randomly called. Also make the initial location of the ball be random. You can copy the function getRandomPoint
from bounce1.py.
iii.3.iv.4. Mad Lib While Exercise¶
** Write a program madlib4.py
that modifies the getKeys
method of madlib2.py
to utilise a while
loop. (This is not an animation program, but this section is where you take had the near feel with while loops!)
Hints: This is actually the virtually natural approach. I avoided while
loops initially, when only for
loops had been discussed. In the original approach, nonetheless, it is redundant to find every instance of '{'
to count the number of repetitions and then find them all again when extracting the cue keys. A more natural way to control the loop is a while
loop stopping when in that location are no further occurrences of '{'
to detect
. This involves some further adjustments. Y'all must cut the loop in a different place (to terminate after searching for '{'
). As discussed earlier, cutting a loop in a dissimilar place may require changes before and afterward the loop, too.
three.3.4.five. Detect Hole Game Exercise¶
** Write a graphical game program, findHole.py
, "Detect the Pigsty". The plan should utilize a random number generator to decide a circular "hole", selecting a point and a perchance the radius around that point. These determine the target and are not revealed to the player initially. The user is then prompted to click around on the screen to "find the hidden hole". Y'all should testify the points the user has tried. Once the user selects a bespeak that is within the chosen radius of the mystery point, the mystery circle should appear. There should be a message announcing how many steps it took, and the game should end.
Hint: you have already seen the code to make up one's mind the displacement (dx, dy) between two points: use the getShift
function in bounce2.py
. In one case you accept the deportation (dx, dy) between the hidden center and the latest mouse click, the distance betwixt the points is (dx*dx + dy*dy)**0.5
, using the Pythagorean Theorem of geometry. If this distance is no more than than the radius that you have chosen for the mystery circle, and so the user has found the circumvolve! You can use getShift
as written, or change information technology into a part getDistance
that directly returns the distance between 2 points.
Many elaborations on this game are possible! Accept fun with it!
3.three.v. Fancier Animation Loop Logic (Optional)¶
The final variation is the case program bounce4.py
, which has the aforementioned outward behavior as bounce3.py, but it illustrates a different internal pattern decision. The bounce3.py version has ii levels of while loop in two methods, moveInBox
for mouse clicks and bounceInBox
for billowy. The bounce4.py version puts all the code for changing direction inside the main animation loop in the old outer function, moveInBox
. There are now 3 reasons to adapt (dx, dy): bouncing off the sides, bouncing off the top or bottom, or a mouse click. That is a simplification and unification of the logic in 1 sense. The complication now 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 test for mouse clicks is inside the while
loop and further inside another if
argument. The test of the mouse click may merely atomic number 82 to a modify in (dx, dy), or is a indicate to quit. Here is the revised code, with a discussion afterward of the return statement:
def moveInBox ( shape , stopHeight , xLow , xHigh , yLow , yHigh , win ): ''' Animate a shape moving toward any mouse click beneath stopHeight and bouncing when its center reaches the low or high ten or y coordinates. The blitheness 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 center = shape . getCenter () x = centre . getX () y = heart . getY () isInside = Truthful if x < xLow or x > xHigh : dx = - dx isInside = False 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 management ( dx , dy ) = getShift ( center , pt ) ( dx , dy ) = ( dx * scale , dy * scale ) else : #NEW leave from depths of the loop return #NEW shape . move ( dx , dy ) time . sleep ( filibuster )
Recall that a render
statement immediately terminates function execution. In this instance the function returns no value, but a blank render
is legal to force the leave. Since the testing is not done in the normal while
condition, the while
condition is set as permanently True
. This is not the most common while
loop pattern! Information technology obscures the loop exit. The pick between the arroyo of bounce3.py
and bounce4.py
is a matter of gustation in the given situation.
[1] | "while ___", "do ___ while", "echo while", "repeat until", "every bit long as ___, practise", "continue doing ___ as long as" |
[ii] | You will demand a loop. You can print/append almost all the numbers in the loop. You lot are likely to omit i number with just this code, but afterwards looking at what you produce, information technology is easy to separately include the remaining number. There are several means to do this. |
[iii] | Recall the built-in len function! It applies to lists. |
[4] | The basic event is similar to the old version: the undraw is non always needed – at the beginning in this instance. In this place it is not needed the first time through the loop. The 2 basic approaches considered for the previous version all the same piece of work here: brand an extra compensating action outside the loop or break into cases inside the loop. Further hint: It is legal to draw a polygon with an empty vertex list - nothing appears on the screen. |
Source: http://anh.cs.luc.edu/handsonPythonTutorial/whilestatements.html
0 Response to "How to Use the Input Value Again After 1 Time for Loop Python"
Post a Comment