What are the three statements in python?

3.1.1. Simple Conditions¶

The statements introduced in this chapter will involve tests or conditions. More syntax for conditions will be introduced later, but for now consider simple arithmetic comparisons that directly translate from math into Python. Try each line separately in the Shell

2  7
x = 11
x > 10
2 * x  50:
        print["There is a $25 charge for luggage that heavy."]
    print["Thank you for your business."]

The middle two line are an if statement. It reads pretty much like English. If it is true that the weight is greater than 50, then print the statement about an extra charge. If it is not true that the weight is greater than 50, then don’t do the indented part: skip printing the extra luggage charge. In any event, when you have finished with the if statement [whether it actually does anything or not], go on to the next statement that is not indented under the if. In this case that is the statement printing “Thank you”.

The general Python syntax for a simple if statement is

If the condition is true, then do the indented statements. If the condition is not true, then skip the indented statements.

Another fragment as an example:

if balance  70:
        print['Wear shorts.']
    else:
        print['Wear long pants.']
    print['Get some exercise outside.']

The middle four lines are an if-else statement. Again it is close to English, though you might say “otherwise” instead of “else” [but else is shorter!]. There are two indented blocks: One, like in the simple if statement, comes right after the if heading and is executed when the condition in the if heading is true. In the if-else form this is followed by an else: line, followed by another indented block that is only executed when the original condition is false. In an if-else statement exactly one of two possible indented blocks is executed.

A line is also shown dedented next, removing indentation, about getting exercise. Since it is dedented, it is not a part of the if-else statement: Since its amount of indentation matches the if heading, it is always executed in the normal forward flow of statements, after the if-else statement [whichever block is selected].

The general Python if-else syntax is

if condition :

indentedStatementBlockForTrueCondition

else:

indentedStatementBlockForFalseCondition

These statement blocks can have any number of statements, and can include about any kind of statement.

See Graduate Exercise

3.1.4. More Conditional Expressions¶

All the usual arithmetic comparisons may be made, but many do not use standard mathematical symbolism, mostly for lack of proper keys on a standard keyboard.

MeaningMath SymbolPython Symbols
Less than < >
Less than or equal =
Equals = ==
Not equal !=

There should not be space between the two-symbol Python substitutes.

Notice that the obvious choice for equals, a single equal sign, is not used to check for equality. An annoying second equal sign is required. This is because the single equal sign is already used for assignment in Python, so it is not available for tests.

Warning

It is a common error to use only one equal sign when you mean to test for equality, and not make an assignment!

Tests for equality do not make an assignment, and they do not require a variable on the left. Any expressions can be tested for equality or inequality [!=]. They do not need to be numbers! Predict the results and try each line in the Shell:

x = 5
x
x == 5
x == 6
x
x != 6
x = 6
6 == x
6 != x
'hi' == 'h' + 'i'
'HI' != 'hi'
[1, 2] != [2, 1]

An equality check does not make an assignment. Strings are case sensitive. Order matters in a list.

Try in the Shell:

When the comparison does not make sense, an Exception is caused. [1]

Following up on the discussion of the inexactness of float arithmetic in String Formats for Float Precision, confirm that Python does not consider .1 + .2 to be equal to .3: Write a simple condition into the Shell to test.

Here is another example: Pay with Overtime. Given a person’s work hours for the week and regular hourly wage, calculate the total pay for the week, taking into account overtime. Hours worked over 40 are overtime, paid at 1.5 times the normal rate. This is a natural place for a function enclosing the calculation.

Read the setup for the function:

def calcWeeklyWages[totalHours, hourlyWage]:
    '''Return the total weekly wages for a worker working totalHours,
    with a given regular hourlyWage.  Include overtime for hours over 40.
    '''

The problem clearly indicates two cases: when no more than 40 hours are worked or when more than 40 hours are worked. In case more than 40 hours are worked, it is convenient to introduce a variable overtimeHours. You are encouraged to think about a solution before going on and examining mine.

You can try running my complete example program, wages.py, also shown below. The format operation at the end of the main function uses the floating point format [String Formats for Float Precision] to show two decimal places for the cents in the answer:

def calcWeeklyWages[totalHours, hourlyWage]:
    '''Return the total weekly wages for a worker working totalHours,
    with a given regular hourlyWage.  Include overtime for hours over 40.
    '''
    if totalHours > vals = ['this', 'is', 'it]
>>> 'is' in vals
True
>>> 'was' in vals
False

It can also be used with not, as not in, to mean the opposite:

>>> vals = ['this', 'is', 'it]
>>> 'is' not in vals
False
>>> 'was' not in vals
True

In general the two versions are:

item in sequence

item not in sequence

Detecting the need for if statements: Like with planning programs needing``for`` statements, you want to be able to translate English descriptions of problems that would naturally include if or if-else 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: [2]

3.1.4.1. Graduate Exercise¶

Write a program, graduate.py, that prompts students for how many credits they have. Print whether of not they have enough credits for graduation. [At Loyola University Chicago 120 credits are needed for graduation.]

3.1.4.2. Head or Tails Exercise¶

Write a program headstails.py. It should include a function flip[], that simulates a single flip of a coin: It randomly prints either Heads or Tails. Accomplish this by choosing 0 or 1 arbitrarily with random.randrange[2], and use an if-else statement to print Heads when the result is 0, and Tails otherwise.

In your main program have a simple repeat loop that calls flip[] 10 times to test it, so you generate a random sequence of 10 Heads and Tails.

3.1.4.3. Strange Function Exercise¶

Save the example program jumpFuncStub.py as jumpFunc.py, and complete the definitions of functions jump and main as described in the function documentation strings in the program. In the jump function definition use an if-else statement [hint [3]]. In the main function definition use a for-each loop, the range function, and the jump function.

The jump function is introduced for use in Strange Sequence Exercise, and others after that.

3.1.5. Multiple Tests and if-elif Statements¶

Often you want to distinguish between more than two distinct cases, but conditions only have two possible results, True or False, so the only direct choice is between two options. As anyone who has played “20 Questions” knows, you can distinguish more cases by further questions. If there are more than two choices, a single test may only reduce the possibilities, but further tests can reduce the possibilities further and further. Since most any kind of statement can be placed in an indented statement block, one choice is a further if statement. For instance consider a function to convert a numerical grade to a letter grade, ‘A’, ‘B’, ‘C’, ‘D’ or ‘F’, where the cutoffs for ‘A’, ‘B’, ‘C’, and ‘D’ are 90, 80, 70, and 60 respectively. One way to write the function would be test for one grade at a time, and resolve all the remaining possibilities inside the next else clause:

def letterGrade[score]:
    if score >= 90:
        letter = 'A'
    else:   # grade must be B, C, D or F
        if score >= 80:
            letter = 'B'
        else:  # grade must be C, D or F
            if score >= 70:
                letter = 'C'
            else:    # grade must D or F
                if score >= 60:
                    letter = 'D'
                else:
                    letter = 'F'
    return letter

This repeatedly increasing indentation with an if statement as the else block can be annoying and distracting. A preferred alternative in this situation, that avoids all this indentation, is to combine each else and if block into an elif block:

def letterGrade[score]:
    if score >= 90:
        letter = 'A'
    elif score >= 80:
        letter = 'B'
    elif score >= 70:
        letter = 'C'
    elif score >= 60:
        letter = 'D'
    else:
        letter = 'F'
    return letter

The most elaborate syntax for an if-elif-else statement is indicated in general below:

if condition1 :

indentedStatementBlockForTrueCondition1

elif condition2 :

indentedStatementBlockForFirstTrueCondition2

elif condition3 :

indentedStatementBlockForFirstTrueCondition3

elif condition4 :

indentedStatementBlockForFirstTrueCondition4

else:

indentedStatementBlockForEachConditionFalse

The if, each elif, and the final else lines are all aligned. There can be any number of elif lines, each followed by an indented block. [Three happen to be illustrated above.] With this construction exactly one of the indented blocks is executed. It is the one corresponding to the first True condition, or, if all conditions are False, it is the block after the final else line.

Be careful of the strange Python contraction. It is elif, not elseif. A program testing the letterGrade function is in example program grade1.py.

See Grade Exercise.

A final alternative for if statements: if-elif-.... with no else. This would mean changing the syntax for if-elif-else above so the final else: and the block after it would be omitted. It is similar to the basic if statement without an else, in that it is possible for no indented block to be executed. This happens if none of the conditions in the tests are true.

With an else included, exactly one of the indented blocks is executed. Without an else, at most one of the indented blocks is executed.

if weight > 120:
    print['Sorry, we can not take a suitcase that heavy.']
elif weight > 50:
    print['There is a $25 charge for luggage that heavy.']

This if-elif statement only prints a line if there is a problem with the weight of the suitcase.

3.1.5.1. Sign Exercise¶

Write a program sign.py to ask the user for a number. Print out which category the number is in: 'positive', 'negative', or 'zero'.

3.1.5.2. Grade Exercise¶

In Idle, load grade1.py and save it as grade2.py Modify grade2.py so it has an equivalent version of the letterGrade function that tests in the opposite order, first for F, then D, C, .... Hint: How many tests do you need to do? [4]

Be sure to run your new version and test with different inputs that test all the different paths through the program. Be careful to test around cut-off points. What does a grade of 79.6 imply? What about exactly 80?

3.1.5.3. Wages Exercise¶

* Modify the wages.py or the wages1.py example to create a program wages2.py that assumes people are paid double time for hours over 60. Hence they get paid for at most 20 hours overtime at 1.5 times the normal rate. For example, a person working 65 hours with a regular wage of $10 per hour would work at $10 per hour for 40 hours, at 1.5 * $10 for 20 hours of overtime, and 2 * $10 for 5 hours of double time, for a total of

10*40 + 1.5*10*20 + 2*10*5 = $800.

You may find wages1.py easier to adapt than wages.py.

Be sure to test all paths through the program! Your program is likely to be a modification of a program where some choices worked before, but once you change things, retest for all the cases! Changes can mess up things that worked before.

3.1.6. Nesting Control-Flow Statements¶

The power of a language like Python comes largely from the variety of ways basic statements can be combined. In particular, for and if statements can be nested inside each other’s indented blocks. For example, suppose you want to print only the positive

numbers from an arbitrary list of numbers in a function with the following heading. Read the pieces for now.

def printAllPositive[numberList]:
    '''Print only the positive numbers in numberList.'''

For example, suppose numberList is [3, -5, 2, -1, 0, 7]. You want to process a list, so that suggests a for-each loop,

but a for-each loop runs the same code body for each element of the list, and we only want

for some of them. That seems like a major obstacle, but think closer at what needs to happen concretely. As a human, who has eyes of amazing capacity, you are drawn immediately to the actual correct numbers, 3, 2, and 7, but clearly a computer doing this systematically will have to check every number. In fact, there is a consistent action required: Every number must be tested to see if it should be printed. This suggests an if statement, with the condition num > 0. Try loading into Idle and running the example program onlyPositive.py, whose code is shown below. It ends with a line testing the function:

def printAllPositive[numberList]:
    '''Print only the positive numbers in numberList.'''
    for num in numberList:
        if num > 0:
            print[num]

printAllPositive[[3, -5, 2, -1, 0, 7]]

This idea of nesting if statements enormously expands the possibilities with loops. Now different things can be done at different times in loops, as long as there is a consistent test to allow a choice between the alternatives. Shortly, while loops will also be introduced, and you will see if statements nested inside of them, too.

The rest of this section deals with graphical examples.

Run example program bounce1.py. It has a red ball moving and bouncing obliquely off the edges. If you watch several times, you should see that it starts from random locations. Also you can repeat the program from the Shell prompt after you have run the script. For instance, right after running the program, try in the Shell

The parameters give the amount the shape moves in each animation step. You can try other values in the Shell, preferably with magnitudes less than 10.

For the remainder of the description of this example, read the extracted text pieces.

The animations before this were totally scripted, saying exactly how many moves in which direction, but in this case the direction of motion changes with every bounce. The program has a graphic object shape and the central animation step is

but in this case, dx and dy have to change when the ball gets to a boundary. For instance, imagine the ball getting to the left side as it is moving to the left and up. The bounce obviously alters the horizontal part of the motion, in fact reversing it, but the ball would still continue up. The reversal of the horizontal part of the motion means that the horizontal shift changes direction and therefore its sign:

but dy does not need to change. This switch does not happen at each animation step, but only when the ball reaches the edge of the window. It happens only some of the time - suggesting an if statement. Still the condition must be determined. Suppose the center of the ball has coordinates [x, y]. When x reaches some particular x coordinate, call it xLow, the ball should bounce.

The edge of the window is at coordinate 0, but xLow should not be 0, or the ball would be half way off the screen before bouncing! For the edge of the ball to hit the edge of the screen, the x coordinate of the center must be the length of the radius away, so actually xLow is the radius of the ball.

Animation goes quickly in small steps, so I cheat. I allow the ball to take one [small, quick] step past where it really should go [xLow], and then we reverse it so it comes back to where it belongs. In particular

There are similar bounding variables xHigh, yLow and yHigh, all the radius away from the actual edge coordinates, and similar conditions to test for a bounce off each possible edge. Note that whichever edge is hit, one coordinate, either dx or dy, reverses. One way the collection of tests could be written is

if x  xHigh:
    dx = -dx
if y  yHigh:
    dy = -dy

This approach would cause there to be some extra testing: If it is true that x xHigh, so we do not need both tests together. We avoid unnecessary tests with an elif clause [for both x and y]:

        if x  xHigh:
            dx = -dx
        if y  yHigh:
            dy = -dy            

Note that the middle if is not changed to an elif, because it is possible for the ball to reach a corner, and need both dx and dy reversed.

The program also uses several methods to read part of the state of graphics objects that we have not used in examples yet. Various graphics objects, like the circle we are using as the shape, know their center point, and it can be accessed with the getCenter[] method. [Actually a clone of the point is returned.] Also each coordinate of a Point can be accessed with the getX[] and getY[] methods.

This explains the new features in the central function defined for bouncing around in a box, bounceInBox. The animation arbitrarily goes on in a simple repeat loop for 600 steps. [A later example will improve this behavior.]

def bounceInBox[shape, dx, dy, xLow, xHigh, yLow, yHigh]:
    ''' Animate a shape moving in jumps [dx, dy], bouncing when
    its center reaches the low and high x and y coordinates.
    '''  
    delay = .005
    for i in range[600]:
        shape.move[dx, dy]
        center = shape.getCenter[]
        x = center.getX[]
        y = center.getY[]
        if x  xHigh:
            dx = -dx
        if y  yHigh:
            dy = -dy            
        time.sleep[delay]

The program starts the ball from an arbitrary point inside the allowable rectangular bounds. This is encapsulated in a utility function included in the program, getRandomPoint. The getRandomPoint function uses the randrange function from the module random. Note that in parameters for both the functions range and randrange, the end stated is past the last value actually desired:

def getRandomPoint[xLow, xHigh, yLow, yHigh]:
    '''Return a random Point with coordinates in the range specified.'''
    x = random.randrange[xLow, xHigh+1]
    y = random.randrange[yLow, yHigh+1]
    return Point[x, y]   

The full program is listed below, repeating bounceInBox and getRandomPoint for completeness. Several parts that may be useful later, or are easiest to follow as a unit, are separated out as functions. Make sure you see how it all hangs together or ask questions!

'''
Show a ball bouncing off the sides of the window.
'''

from graphics import *
import time, random

def bounceInBox[shape, dx, dy, xLow, xHigh, yLow, yHigh]:
    ''' Animate a shape moving in jumps [dx, dy], bouncing when
    its center reaches the low and high x and y coordinates.
    '''  
    delay = .005
    for i in range[600]:
        shape.move[dx, dy]
        center = shape.getCenter[]
        x = center.getX[]
        y = center.getY[]
        if x  xHigh:
            dx = -dx
        if y  yHigh:
            dy = -dy            
        time.sleep[delay]

def getRandomPoint[xLow, xHigh, yLow, yHigh]:
    '''Return a random Point with coordinates in the range specified.'''
    x = random.randrange[xLow, xHigh+1]
    y = random.randrange[yLow, yHigh+1]
    return Point[x, y]   

def makeDisk[center, radius, win]:
    '''return a red disk that is drawn in win with given center and radius.'''
    disk = Circle[center, radius]
    disk.setOutline["red"]
    disk.setFill["red"]
    disk.draw[win]
    return disk

def bounceBall[dx, dy]:
    '''Make a ball bounce around the screen, initially moving by [dx, dy]
    at each jump.'''    
    win = GraphWin['Ball Bounce', 290, 290]
    win.yUp[]

    radius = 10
    xLow = radius # center is separated from the wall by the radius at a bounce
    xHigh = win.getWidth[] - radius
    yLow = radius
    yHigh = win.getHeight[] - radius

    center = getRandomPoint[xLow, xHigh, yLow, yHigh]
    ball = makeDisk[center, radius, win]
    
    bounceInBox[ball, dx, dy, xLow, xHigh, yLow, yHigh]    
    win.close[]
    
bounceBall[3, 5]

3.1.6.1. Short String Exercise¶

Write a program short.py with a function printShort with heading:

def printShort[strings]:
    '''Given a list of strings,
    print the ones with at most three characters.
    >>> printShort[['a', 'long', one']]
    a
    one
    '''

In your main program, test the function, calling it several times with different lists of strings. Hint: Find the length of each string with the len function.

The function documentation here models a common approach: illustrating the behavior of the function with a Python Shell interaction. This part begins with a line starting with >>>. Other exercises and examples will also document behavior in the Shell.

3.1.6.2. Even Print Exercise¶

Write a program even1.py with a function printEven with heading:

def printEven[nums]:
    '''Given a list of integers nums,
    print the even ones.

    >>> printEven[[4, 1, 3, 2, 7]]
    4
    2
    '''

In your main program, test the function, calling it several times with different lists of integers. Hint: A number is even if its remainder, when dividing by 2, is 0.

3.1.6.3. Even List Exercise¶

Write a program even2.py with a function chooseEven with heading:

def chooseEven[nums]:
    '''Given a list of integers, nums,
    return a list containing only the even ones.

    >>> chooseEven[[4, 1, 3, 2, 7]]
    [4, 2]
    '''

In your main program, test the function, calling it several times with different lists of integers and printing the results in the main program. [The documentation string illustrates the function call in the Python shell, where the return value is automatically printed. Remember, that in a program, you only print what you explicitly say to print.] Hint: In the function, create a new list, and append the appropriate numbers to it, before returning the result.

3.1.6.4. Unique List Exercise¶

* The madlib2.py program has its getKeys function, which first generates a list of each occurrence of a cue in the story format. This gives the cues in order, but likely includes repetitions. The original version of getKeys uses a quick method to remove duplicates, forming a set from the list. There is a disadvantage in the conversion, though: Sets are not ordered, so when you iterate through the resulting set, the order of the cues will likely bear no resemblance to the order they first appeared in the list. That issue motivates this problem:

Copy madlib2.py to madlib2a.py, and add a function with this heading:

def uniqueList[aList]:
    ''' Return a new list that includes the first occurrence of each value
    in aList, and omits later repeats.  The returned list should include
    the first occurrences of values in aList in their original order.

    >>> vals = ['cat', 'dog', 'cat', 'bug', 'dog', 'ant', 'dog', 'bug']
    >>> uniqueList[vals]
    ['cat', 'dog', 'bug', 'ant']
    '''

Hint: Process aList in order. Use the in syntax to only append elements to a new list that are not already in the new list.

After perfecting the uniqueList function, replace the last line of getKeys, so it uses uniqueList to remove duplicates in keyList.

Check that your madlib2a.py prompts you for cue values in the order that the cues first appear in the madlib format string.

3.1.7. Compound Boolean Expressions¶

To be eligible to graduate from Loyola University Chicago, you must have 120 credits and a GPA of at least 2.0. This translates directly into Python as a compound condition:

credits >= 120 and GPA >=2.0

This is true if both credits >= 120 is true and GPA >= 2.0 is true. A short example program using this would be:

credits = float[input['How many units of credit do you have? ']]
GPA = float[input['What is your GPA? ']]
if credits >= 120 and GPA >=2.0:
    print['You are eligible to graduate!']
else:
    print['You are not eligible to graduate.']

The new Python syntax is for the operator and:

condition1 and condition2

The compound condition is true if both of the component conditions are true. It is false if at least one of the conditions is false.

See Congress Exercise.

In the last example in the previous section, there was an if-elif statement where both tests had the same block to be done if the condition was true:

if x  xHigh:
    dx = -dx

There is a simpler way to state this in a sentence: If x < xLow or x > xHigh, switch the sign of dx. That translates directly into Python:

if x  xHigh:
    dx = -dx

The word or makes another compound condition:

condition1 or condition2

is true if at least one of the conditions is true. It is false if both conditions are false. This corresponds to one way the word “or” is used in English. Other times in English “or” is used to mean exactly one alternative is true.

Warning

When translating a problem stated in English using “or”, be careful to determine whether the meaning matches Python’s or.

It is often convenient to encapsulate complicated tests inside a function. Think how to complete the function starting:

def isInside[rect, point]:
    '''Return True if the point is inside the Rectangle rect.'''
    pt1 = rect.getP1[]
    pt2 = rect.getP2[]

Recall that a Rectangle is specified in its constructor by two diagonally oppose Points. This example gives the first use in the tutorials of the Rectangle methods that recover those two corner points, getP1 and getP2. The program calls the points obtained this way pt1 and pt2. The x and y coordinates of pt1, pt2, and point can be recovered with the methods of the Point type, getX[] and getY[].

Suppose that I introduce variables for the x coordinates of pt1, point, and pt2, calling these x-coordinates end1, val, and end2, respectively. On first try you might decide that the needed mathematical relationship to test is

Unfortunately, this is not enough: The only requirement for the two corner points is that they be diagonally opposite, not that the coordinates of the second point are higher than the corresponding coordinates of the first point. It could be that end1 is 200; end2 is 100, and val is 120. In this latter case val is between end1 and end2, but substituting into the expression above

is False. The 100 and 200 need to be reversed in this case. This makes a complicated situation. Also this is an issue which must be revisited for both the x and y coordinates. I introduce an auxiliary function isBetween to deal with one coordinate at a time. It starts:

def isBetween[val, end1, end2]:
    '''Return True if val is between the ends.
    The ends do not need to be in increasing order.'''

Clearly this is true if the original expression, end1

Chủ Đề