IT 116: Introduction to Scripting
Class 8
Today's Topics
Tips and Examples
Review
New Material
Reading Assignment
You should read Chapter 4, Repetition Structures, from our
textbook, Starting Out with Python, before next week's class.
Homework 4
I have posted homework 4 here.
It is due this coming Sunday at 11:59 PM.
Tips and Examples
Use Tabs in a Code Block
- A code block is a group of statements that are only executed under certain conditions
- All control structures
use code blocks
- There are two ways to indent a code block
- You should always use Tabs to indent code blocks
- Why?
- The reason is you must consistently use either Spaces or Tabs within a single code block
- You cannot mix them
- If you do you will get an IndentationError
- Look at the following code
num = int(input('Number: '))
if num % 2 == 0:
print(num)
print('This number is even')
- It looks fine but when I run it I get
$ python3 indent_test.py
File "indent_test.py", line 5
print('This number is even')
^
IndentationError: unindent does not match any outer indentation level
- What went wrong?
- It looks like the both lines are indented the same amount
- But not really
- I used Spaces to indent the first line in the code block
- But I used Tabs in the second
- It looks good to our eyes
- But not to the Python interpreter
- The first line indents with 4 space characters
- Space characters have the Unicode number 32
>>> ord(" ")
32
- While Tabs are Unicode 9
>>> ord("\t")
9
- As far as Python is concerned, these are two different indentations
- This problem is very difficult to detect
- We only see the whitespace before the statement
- We do not see the actual whitespace characters used
- To avoid this problem you need to be consistent
- You can indent with one Tab character
- Or you can indent with many spaces
- It is simpler to use Tabs
Misleading Error Messages
- If your code violates the rules of Python you will get an error message
- Errors of this type are called
syntax errors
- The interpreter is good at spotting these errors
- But it isn't always good at telling you what the problem is
- The most important thing an error message tells you is that your code does not work
- Interpreters run through your code expecting certain things
- When the interpreter sees a " at the beginning of a
string literal,
it expects to see another " at the end
- When the interpreter sees a (, it expects a following
)
- If it does not see the character on one line, it looks at the next
- This means that the error message sometimes give you the wrong line number
- The error occurs on one line where you are missing a " or )
- But the interpreter does not realize it until it gets to the next line
- A while ago a student emailed me with a problem he was having with a homework script
- This is what happened when I ran the code
$ python3 hw4.py
File "hw4.py", line 4
print("Your score is ", score)
^
- Line 4 of the code reads
print("Your score is ", score)
- There is nothing wrong with this code
- But there is with the line above
score = int(input("What is your score? ")
- If you look carefully you will see that there are two left parentheses,
(
- but only one right parenthesis, )
- If you can't see the error on one line, look at the line above
- Unclosed parentheses are often a problem
- For every ( there should be a )
- There is a trick for spotting this
- You count the number of parentheses in a special way
- Start with 0
- Every time you come across a ( add 1
- Every time you come across a ) subtract 1
- Should should end up with 0
Review
Control Structures
- Python, like most computer languages, has
control structures
- Control structures allow the interpreter to take different paths through the code
- The order in which the statements of a script are executed is called
path of execution
- Or the flow of control
- Without control structures the interpreter would start at the top
- And go directly to the bottom
if
Statements
Boolean Expression
Relational Operators
- Boolean expressions are often created using
relational operators
- Relational operators compare two values
- And return true or false depending on their relationship
- Here are the relational operators
Operator | Meaning |
> |
Greater than |
< |
Less than |
>= |
Greater than or equal to |
<= |
Less than or equal to |
== |
Equal to |
!= |
Not equal to |
- Notice that we test for equality using == not =
- This is a common mistake that you will probably make many times
Precedence of Relational Operators
- All the relational operators have lower precedence than the arithmetic operators
- The order of precedence is
** |
Exponentiation |
*
/
//
%
|
Multiplication, division and remainder |
+
-
|
Addition and subtraction |
>
<
>=
<=
==
!=
|
Relational Operators |
if
-else
Statements
Indentation in the if
-else
Statement
Comparing Strings
Nested if
Statements
Testing a Series of Conditions
- Sometimes you have test more than one condition
- For example if you need to turn a score into a grade you need many comparisons
- Here is code that will do that
$ cat grade.py
# this programs turns a score into a letter grade
# it demonstrates using nested if statements
# to test for many possible conditions
score = int(input("What is your score? "))
print("Grade", end=" ")
if score >= 90:
print("A")
else:
if score >= 80:
print("B")
else:
if score >= 70:
print("C")
else:
if score >= 60:
print("D")
else:
print("F")
$ python3 grade.py
What is your score? 80
Grade B
$ python3 grade.py
What is your score? 60
Grade D
if
-elif
Statements
- The code above will work but it is a little hard to read
- Notice how the code keeps shifting to the right of the page
- Python provides a different kind of
if
statement
- It is the
if
-elif
-else
statement ...
- which has the following format
if BOOLEAN_EXPRESSION_1:
STATEMENT
...
elif BOOLEAN_EXPRESSION_2:
STATEMENT
...
elif BOOLEAN_EXPRESSION_3
STATEMENT
...
...
[else:
STATEMENT
...]
- The [ ] around the
else
clause indicates that it is optional
- The keyword
elif
is short for "else if"
- Notice that all the conditions line up vertically
- This is good because it makes is clear that each condition has the same level of importance
- Here is the grade program rewritten to use the
if
-elif
-else
statement
$ cat grade2.py
# this program turns a score into a letter grade
# it demonstrates the if-elif-else statement
score = int(input("What is your score? "))
print("Grade", end=" ")
if score >= 90:
print("A")
elif score >= 80:
print("B")
elif score >= 70:
print("C")
elif score >= 60:
print("D")
else:
print("F")
$ python3 grade2.py
What is your score? 50
Grade F
New Material
Logical Operators
Data Types with Logical Operators
- Different operators work on values of different data types
- The arithmetic operators work on numbers
>>> 8 / 4
2.0
- But not strings
>>> 'eight' / 'four'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for /: 'str' and 'str')
- The relational operators work on both numbers
>>> 6 > 5
True
- And strings
>>> "small" < "smaller"
True
- And even booleans
>>> True > False
True
- The relational operators will work on any data type where the values have a natural order
- The logical operators are very flexible too
- They will work on expressions of any of the data types we have studied
- Integers
- Floats
- Strings
- Booleans
- But the way they do this is a little weird
>>> 5 and 6
6
>>> 6 and 5
5
>>> 5 and 0
0
>>> 0 and 5
0
- Similar weirdness happens with strings
>>> "a" and "b"
'b'
>>> "a" and ""
''
- And with values of different types
>>> "a" and 5
5
>>> 0 and "b"
0
- I'm not sure why Python works this way, but we don't have to worry about it
- When Python needs a boolean but you give it another data type, Python runs
bool
it
- It will do this automatically
bool
will convert any number that is not 0 to True
- 0 becomes
False
>>> bool(5)
True
>>> bool(-5)
True
>>> bool(0)
False
- and any string that is not the
empty string
becomes
True
>>> bool(5)
True
>>> bool(0)
False
>>> bool("a")
True
>>> bool("")
False
- All the scripting languages I know do the same
Short-Circuit Evaluation
Checking Numeric Ranges with Logical Operators
- One of the most input ideas in programming is something called
data validation
- The idea is to check the data type and range of data before you use it in a program
- For example, a program might need to know a person's age in order to calculate retirement benefits
- The user should enter something like
35
- not
thirty-five
since the later is a string, not a number
- Similarly, the age could not be 3 or 200
- The program should look for mistakes like these
- And ask the user to reenter their age
- In this case, we might want to make sure that the values were between 18 and 65
- When we need to determine whether a value is inside a range we use the
and
operator
if age >= 18 and age <= 65:
print("The age entered is a reasonable value")
- If we wanted to determine whether a value is outside a range we use the
or
operator
if age < 18 or age > 65
print("Please enter your age again")
- Python allows us to write the first condition in a much shorter way
>>> age = 25
>>> if 18 <= age <= 65:
... print("Your age is in the right range")
... else:
... print("Your age is in the wrong range")
...
Your age is in the right range
- The boolean expression
18 <= age <= 65
is the same as writing
18 <= age and age <= 65
- In other words the
and
operator is implicit
Precedence of Logical Operators
- When we write an expression like
a + b > c and c * d < a
there are three different kind of operators
- Arithmetic - +, *
- Relational - >, <
- Logical - and
- operator precedence
determines which operators are used before other operators
- The logical operators are and, or and not
- They have lower precedence than arithmetic operators
- They also have lower precedence than the relational operators
- The order of precedence is
** |
Exponentiation |
*
/
//
%
|
Multiplication, division and remainder |
+
-
|
Addition and subtraction |
>
<
>=
<=
==
!=
|
Relational Operators |
and
or
not
|
Logical Operators |
Boolean Variables
- A variable is a name that represents a value in the computer's memory
- If the value it holds is
True
or False
it is a boolean variable
- Boolean variables are often used as
flags
to indicate whether a certain condition in the program is true
- Flags can make a program much more readable
- For example a program to compute the price of a ticket might use the following code
if age < 18:
minor = True
else:
minor = False
if age >= 65:
senior = True
else:
senior = False
- You could then use these flags later in your program to calculate the ticket price
- Actually there is a shorter way to achieve the same results
minor = age < 18
senior = age >= 65
- The expressions on the right are both boolean expressions
- Normally you would set a flag if you wanted to check a condition more than once
- But even if you only use the value of a flag once it will make the code more readable
- Compare these two versions of the a script that calculates ticket prices
$ cat tickets_1.py
# this program calculates ticket prices
age = int(input("What is your age? "))
if age < 18:
print("Your ticket will cost $10")
elif age >= 65:
print("Your ticket will cost $15")
else:
print("Your ticket will cost $25")
$ cat tickets_2.py
# this program calculates ticket prices
age = int(input("What is your age? "))
minor = age < 18
senior = age >= 65
if minor:
print("Your ticket will cost $10")
elif senior:
print("Your ticket will cost $15")
else:
print("Your ticket will cost $25")
Keep Your Code Short
- If you read any book on how to write better they will always say that is that shorter is better longer
- That's because people's attention is a resource
- If you make your sentences longer than they need to be people will stop paying attention
- The same is true with code
- Look at the ticket script above
- Notice that each
if
clause has the string "Your ticket will cost"
if minor:
print("Your ticket will cost $10")
elif senior:
print("Your ticket will cost $15")
else:
print("Your ticket will cost $25")
- If you think about it, the real work of the
if
statement
is to set ticket price
- Printing the message is a different task
- We can make the code shorter by having it set a variable ...
- which is used in a single
print
statement
age = int(input("What is your age? "))
minor = age < 18
senior = age >= 65
if minor:
price = 10
elif senior:
price = 15
else:
price = 25
print("Your ticket will cost $" + str(price))
- Why did I use concatenation
in the
print
statement
instead of giving print
two arguments?
- With two arguments there would have been a space in the output ...
- between $ and the price
Attendance
Class Quiz