total = 0Chapter 4: Working With Variables
Notes
Variables in Python
- Variables let us add memory to python
- Can be viewed as an alias for a storage location
- Variables in python are created by defining a name, and providing a value, e.g. the below defines a variable
totaland assigns it the value \(0\)
block-beta
columns 3
space
title["Anatomy of Variable Assignment"]
space
block:variable
columns 1
varName["total"]
variablebody["variable"]
variableDescr["(thing to which value assigned)"]
end
block:equals
columns 1
equalsSymbol["="]
equalsName["equals"]
equalsDescr["(means assign)"]
end
block:argumentblock
columns 1
zero["0"]
zeroName["expression"]
zeroDescr["(value to assign)"]
end
classDef BG stroke:transparent, fill:transparent
class title BG
class variablebody BG
class variableDescr BG
class equalsName BG
class equalsDescr BG
class zeroName BG
class zeroDescr BG
- The above diagrammatically breaks down variable assignment. On the left we have the variable, then
=which means assignment, followed by the expression to assign - The assignment expression does not need to be made of simple primitives, e.g.
total = us_sales + world_wide_salesdefines the variabletotalto be equal to the sum of the variablesus_salesandworld_wide_sales
Make Something Happen: Working with Variables
Start up a python interpreter, then run the following commands in sequence
total = 0total = 0- No output is generated, the assignment is performed silently
totaltotal00outputtotalhas been assigned0, putting the variable name into the terminal returns the value associated with this value
total = total + 10total = total + 10- No output
- Like with the first statement, variable assignment generates no output
- Here we assign
totalthe value given by the current value oftotalplus \(10\)
totaltotal1010output- The new value of
totalis printed
Python Names
- Variables require names
- Python variable names must obey a number of rules
- Must start with a letter or _
- Can contain letters, numbers or _ characters
- Some valid names are
totalxyzt0tal
- Some invalid names are
2_be_or_not_to_be- Starts with a number which is not allowed
tot@l@is not a valid character for a variable name
- Python names are case sensitive, i.e.
FREDandfredare distinct variables
Create Meaningful Names
Don’t use silly or meaningless names like hello_mom. Use meaningful names that convey information about what they represent like length or length_in_centimetres. The PEP8 style guide, sets out how to write and format python programs. This includes a section on naming conventions
Some languages recommend using camel case for variable naming. In this format words in a variable are distinguished by capital letters, but the first letter of the variable is lower case, e.g. lengthInCentimetres. Camel case is called this because the capital letters look like the humps of a camel. Either standard works, but when writing python it is best to stick to the python style guides
- Python does not limit the length of variable names
- There should be no performance cost associated with long variable names
- Longer names can be hard to read
- Names should be no longer than they need to convey clear meaning
Code Analysis: Typing Errors and Testing
You’ve already seen that python can generate errors when it is unable to interpret an input. Answer the following questions to investigate how errors can arise in using variables. Assume that total has already been defined
Can you identify an error in the statement below, which is supposed to add \(10\) to the variable
total?# clearing saved variables in the notebook %resettotal = 0 Total = total + 10- Variable names are case-sensitive. Therefore
Totalandtotalare distinct variables. So this declares a new variableTotaland assigns it the value oftotal + 10. The value oftotalitself is unchanged. - This is a logic error, it is a legal statement in python that generates the wrong behaviour
- Logic errors are some of the hardest errors to deal with since they (typically) don’t stop a program running, they just produce incorrect behaviour
- Python typically cannot warn you about them ahead of time
- This variable mis-assignment is why python style guides recommend the use of all lowercase letters for variable names
NoteIdentifying Errors
Other languages with more strict type systems and variable declarations, may be able to identify logic errors like the one above.
- Variable names are case-sensitive. Therefore
How do we prevent logic errors?
- Testing
- i.e checking that the actual behaviour of a program matches the expected behaviour
- Run a program with input that will generate a known output when running correctly
- Verify the program generates this output
- Testing doesn’t guarantee a program is correct
- Typically hard to check all inputs and use cases
- Does however give confidence and can provide that a program isn’t correct
- Typically tests should be written as the program is created or if using test-driven development the tests are written before the program itself is written
- Testing
The statement below also contains a misspelling of the variable
total. However, this time the name on the right-hand side of the equals is misspelled. What will happen when this program runs?# Again clear the notebook variables %resettotal = 0 total = Total + 10--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[9], line 2 1 total = 0 ----> 2 total = Total + 10 NameError: name 'Total' is not defined
- In this case,
Totalis not defined as a variable, so there is no meaningful way to interpret a value. Hence we would expect an error. Since the error is thatTotaldoesn’t exist, we see aNameError.
- In this case,
Make Something Happen: Self-Timer Party Game
Consider the Nerves of Steel exercise from Chapter 3. In the game, players must remain standing right up to the moment before they think a random timer will expire
One suggestion is that the game might provide more skill if the program told the players how long they had to stand. The game now functions as a “Self-Timer”, the winner is now arguably the person who can best keep track of the time
The “game” sequence is
- Set the time to remain standing to a random number
- Display time to remain standing
- Sleep for the time to remain standing
- Display a message for the winner
Observe that the time is required to be used in two places, displaying the time remaining and then sleeping for that period of time. This means we need to use a variable to store the value of the time remaining
# Example 4.1: Self Timer
#
# Extends the Nerves of Steel Game from Chapter 3, by adding a skill element
# with the players being informed of how long they have to stand for
import random
import time
print("Welcome to Self Timer")
print() # just prints a newline
print("Everybody stand up")
print("Stay standing until you think the time has ended")
print("Then sit down")
print("Anyone still standing when the time expires loses")
print("The last person to sit down before the time ended will win")
stand_time = random.randint(5, 20) # generate the time to stand for
print("Stay standing for", stand_time, "seconds.") # display standing time
time.sleep(stand_time) # sleep for the standing time
print("****TIMES UP, LAST TO SIT WINS!****")Welcome to Self Timer
Everybody stand up
Stay standing until you think the time has ended
Then sit down
Anyone still standing when the time expires loses
The last person to sit down before the time ended will win
Stay standing for 18 seconds.
****TIMES UP, LAST TO SIT WINS!****
Most of the code is just text, but the key takeaway is the line stand_time = random.randint(5, 20) which assigns stand_time the result of random.randint(5, 20), i.e a random number from 5 to 20 inclusive. We then call stand_time is our call to print to display the time, and then sleep for the same amount of time. Observe we couldn’t just write the number into both functions explicitly since it’s randomly generated, we would need to know ahead of time what the value will be
Working with Text
- Variables can also hold text, e.g.
customer_name = 'fred'assigns the string'fred'tocustomer_name - Can use a string variable anywhere we would use a string literal, e.g.
message = 'the name is ' + customer_nameperforms the string concatenation of'the name is'and the value ofcustomer_nameand assigns the result tomessage, which we can confirm below,
customer_name = "fred"
message = "the name is " + customer_name
print(message)the name is fred
Make Something Happen: Text and Numeric Variables
Python tracks the contents of each variable and only allows operations that make sense. Using the python interpreter experiment with the following combinations of string and number variables.
customer_age_in_years = 25
customer_name = 'fred'After entering the above two lines in the interpreter, run the following line
customer_age_in_years + customer_name--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[13], line 1 ----> 1 customer_age_in_years + customer_name TypeError: unsupported operand type(s) for +: 'int' and 'str'
Here we are trying to add a number and a string, which we saw previously shouldn’t work. The terminal should provide some error output like the below
Now try the below line
customer_age_in_years = 'Fred'One might expect the above to generate an error, after all we assign text to a variable that was just storing a number. Instead python simply discards the old numeric value of the variable, and now stores text in customer_age_in_years. You should generally avoid doing this, being able to reason about the type of a variable is typically an important part of safe and effective programming, and the weak typing of python is typically disliked outside of quick prototyping
Weak vs Strong Typing
The above behaviour is an example of python as a what’s called a weakly typed language. Types are a quite developed part of programming theory that can be discussed later. In some languages, types are enforced to greater degrees of strictness. In some languages (like C) you can assign variables compatible types, i.e. ones that can be converted to the variable’s innate type. In other stricter languages a variable can only hold the exact specified type
The more strictly a language enforces its typing system typically the harder it is to generate errors at runtime, however they are often correspondingly more painful to actually write the code in the first place
Marking the Start and End of Strings
- Python lets you use either single-quotes (’) or double-quotes (“)
- Lets us include ’ or ” in a string, by using the alternate delimiter
- For example, compare the two quote snippets,
print("It's a trap")It's a trap
- Whereas if we tried to just use single quotes,
print('It's a trap')Cell In[16], line 1 print('It's a trap') ^ SyntaxError: unterminated string literal (detected at line 1)
- The single quote in
It'sends the string, and we get a syntax error detecting what should be the closing single quote as opening a new string literal - How do we handle the case where we have mixed quotes in a string?
- We use triple quotes, a series of three single or double quotes in a row, see the example below
print('''...and then Luke said "It's a trap"''')...and then Luke said "It's a trap"
- Triple quoted strings have the added advantage of capturing newlines. To see this, we could rewrite the intro string in Nerves of Steel as
print('''Welcome to Nerves of Steel
Everybody stand up
Stay standing as long as you dare.
Sit down just before you think the time will end. ''')Welcome to Nerves of Steel
Everybody stand up
Stay standing as long as you dare.
Sit down just before you think the time will end.
String Delimiters must Match
You must using matching delimiters, if we try to mix them we’ll get an error
print('hello")Cell In[19], line 1 print('hello") ^ SyntaxError: unterminated string literal (detected at line 1)
Escape Characters in Text
- Escape sequences are another way to include quote characters
- Extends to other symbols with meaning other than their literal character glyph in a string
- Denoted by the
\character
| Escape Sequence | Meaning | Effect |
|---|---|---|
\\ |
Backslash character (\) |
Enter a backslash into a string |
\' |
Single Quote (') |
Enter a single quote into the string |
\" |
Double Quote (") |
Enter a double quote into the string |
\n |
ASCII Line Feed/New Line | End this line and take a new one |
\t |
ASCII Tab | Move to the right to the next tab stop |
\r |
ASCII Carriage Return | Return the printing position to the start of the line |
\a |
ASCII Bell | Sound the bell on the terminal |
ASCII
ASCII (short for American Standard Code for Information Interchange) is an old format for character encoding that covers a small range of symbols including the latin alphabet and digits.
ASCII itself is less used today since it only covers around \(100\) characters, which is nowhere near enough to cover all modern languages, before you start adding in characters like emojis. However modern text encoding like unicode are typically backwards compatible with ASCII.
Not all ASCII escape sequences may work on a modern computer. \a was designed to ring a mechanical bell on old computers. Some modern computers may play a beep while others may do nothing. Similarly \r is supposed to return the print head of a computer back to the start of the line. This has very limited use cases, and may not be implemented on all systems.
The most common escape characters are newline \n and escaping quotes
Newline in Python
Python uses \n as the newline character. Technically this is known as a line feed and means “go to the next line”. In Linux and similar operating systems this is equivalent to starting a new line, but in windows going to the start of a new line is achieved via \r\n, i.e. return to the start of the line, and then feed to the next. Luckily python handles the conversion between the conventions automatically and we can just use \n regardless of the operating system we are actually running on
Code Analysis: Investigating Escape Sequences
Start a python interpreter and answer the following questions
What do you think the following quote would print?
print('hello\nworld')- We would expect this print
helloon one line, thenworldon the next
hello world- We would expect this print
What do you think the following would print?
print('Item\tSales\ncar\t50\nboat\t10')- We can see this prints a series of tab separated lines. So this is essentially a tab separated table (a similar format to the more familiar comma-separated table)
Item Sales car 50 boat 10- The exact spacing of tab characters can depend on the computer system, and it is quite common for text editors to convert tabs to spaces, so this format isn’t the best. We’ll see other ways to format strings later
How could I use Python escape sequences to print out this message?
and then Luke said “It’s a trap”
- We saw how to do this with triple-delimited strings before. Instead we just have to remember to instead use a single-delimiter string and then escape the quotes that actually form the string contents. See,
print('and then Luke said "It\'s a trap"')and then Luke said "It's a trap"
- Since the string is delimited by single quotes we only have to delimit the one single quote in
It'srather than the two double quotes
Read in Text using the input Function
- We’ve seen how to output data with
print - We can also input data with the appropriately named
input - The code snippet below, takes input from the user and stores it in
name
name = input()- The program will pause until the user supplies the input, (Try it yourself in the interpreter!)
- We can add a display prompt to the input statement
name = input('Enter your name please: ')- The above should output something like the below when run
Enter your name please:
- As mentioned
inputpasses what it receives into the receiving variable.- If we just immediately press enter this is the empty string i.e. a string containing no characters
inputis another technique for delaying the end of a program, e.g. the below prints a prompt and then holds the program until some input is received
input('Press enter to continue...')Make Something Happen: Use input to make a “greeter” Program
Use python to create a simple program that will issue a personalised greeting. Create a new program (greeter.py) with the following contents
name = input('Enter your name please: ')
print('Hello', name)Save the program and execute it to see the output. For me the program would output,
Enter your name please: Felix
Hello Felix
I’ve used colour to emphases what is my input, versus the program’s output
Working with Numbers
Convert Strings into Integer Values
inputreturns a string- Fine if we want that, but what if we want to handle numbers?
- e.g. if we wanted to have a user-specified egg timer
intis a function that converts the argument to a whole number e.g.
time_text = input('Enter the cooking time in seconds: ') #receive time in seconds
time_int = int(time_next) #perform conversion to numberExample: Configurable Egg Timer
The complete program would then look like,
# Example 4.3: Configurable Egg Timer # # Reads in a user specified time to set the timer for import time time_text = input("Enter the cooking time in seconds: ") time_int = int(time_text) print("Put the egg in boiling water now") input("Press enter to continue once the egg is in...") time.sleep(time_int) print("Take the egg out now")This basic pattern works just as well for an alarm as it does for a configurable timer
Code Analysis: Reading Numbers
Consider the previous example, and answer the following questions
How many variables are used in the program above?
- two, the first
time_textstores the initial text input, while the secondtime_intcontains the converted numeric representation
- two, the first
Could you write the program without the time_text variable?
- Yes, we could immediately pass the input result to
int, e.g.
time_int = int(input('Enter the cooking time in seconds: '))- It’s an open debate which format is clearer. In the second there’s more to grok on one line, but the whole workflow is there
- Yes, we could immediately pass the input result to
What do you think will happen if the user enters something other than a number?
- Let us find out,
x = int('kaboom')--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Cell In[25], line 1 ----> 1 x = int('kaboom') ValueError: invalid literal for int() with base 10: 'kaboom'
- We get an error,
inttries to convert the string'kaboom'to an integer, which it clearly cant - The art of programming to handle invalid input like the above is called error-handling, we’ll see that later
Whole Numbers and Real Numbers
- There are two types of numbers
- Whole numbers or integers
- Are always held accurately by the computer
- Real numbers (or representations of) or floating point
- Contain a fractional component
- Must be truncated to be stored in memory, so cannot always be stored accurately
- Whole numbers or integers
Code Analysis: Whole Numbers vs Real Numbers
Learn about the differences between whole numbers and real numbers through the following questions
I’m building a device that can count the number of hairs on your head. Should this be stored as a whole or real number?
- Integer, we generally wouldn’t count fractions of a hair
- Alternatively, given how many hairs there are, and that we might not care about being precise, we might instead want to use a real number to store the approximate magnitude
I want to use my hair-counting machine on \(100\) people and determine the average number of hairs on all their heads. Should I use this value as a whole or real number?
- We expect that the average will not be a whole number, so we should store it as a real number
- Alternatively, we may not care about getting the number exact down to the fraction, so we could use a whole number to round to the nearest number
I want to keep track of the price of a product in my program. Should I use whole numbers or real numbers?
- Naively we would a real number, however as we mentioned real numbers have some uncertainty stored in them
- When dealing with financial values we need to maintain that precision
- Instead we might then use whole cents
- Works straightforward if we only care about the total
- If we care about averages, or fractions of a total then we might have to reconsider
- There are techniques used to control the error in a real number calculation
- Instead we might then use whole cents
- As you can see the argument of what numerical type to use, requires understanding both the nature of the value itself, and what you want to do with it. You can then consider the properties of the numeric representation and choose the most appropriate one
The way you store a variable depends on what you want to do with it
As the discussion above highlights, sometimes the answer to how we want to store data is not the immediate first answer. It’s important to consider not just what the natural representation of a value is, but what it’s purpose in the code is.
For example as we discussed above, money is naturally expressed as real numbers. However due to the it’s use case, which requires high precision and also generally a limited range (values of even a trillion are rare, and we typically only consider down to whole cents) compared to the full range of a floating point number we might want to look at alternative representations
Real Numbers and Floating Point
- Real numbers have a fractional part
- Their representation may not align 1:1 with what was originally input
- The most common way to store real numbers is called floating point
- The floating means that the decimal point moves around in the representation, as opposed to a fixed point representation which has a set number of digits after the decimal point
- Using more memory to store a float lets us store it with greater precision, but we can never accurately represent all floating point numbers
- Real numbers can be defined by range and precision
- Precision governs how precisely a number is stored e.g. a float may be able to store \(123456789.0\) or \(0.123456789\) but not \(123456789.987654321\) because the precision required is too great
- Range determines how much we can slide the decimal point to represent large or small numbers e.g. we could store \(123456700\) or \(0.0001234567\)
- In Python floats have \(15-16\) digits of precision and can range from \(10^{308}\) and \(10^{-324}\)
- A quirk of floating point is that some apparently simple numbers like \(0.1\) can’t be stored exactly
Code Analysis: Floating Point Variables and Errors
Conduct the following experiments in the python shell to learn about floating points
What happens if we try to store a value that can’t be held accurately as a floating-point value?
0.10.1- Above we said that \(0.1\) couldn’t be exactly represented, but that doesn’t match with what we just saw. The answer is because the error in the representation is very small, and
printrounds off the answer
- Above we said that \(0.1\) couldn’t be exactly represented, but that doesn’t match with what we just saw. The answer is because the error in the representation is very small, and
Does the rounding really happen? Run the following and comment on the result
0.1 + 0.20.30000000000000004- We expected the answer to be \(0.3\) but instead we see a slight error. This is because there is an error accumulation from adding \(0.1\) to \(0.2\) and the underlying floating point representations
- These issues are not python specific. They are an innate challenge of trying to represent real numbers on hardware. Modern floating-point numbers are also an internationally recognised standard which lets different programs and hardware talk to each other.
- Python differs from some languages in only providing a single floating point type that is \(8\) bytes. In many languages this is referred to as a double-precision floating point or just a double and is one of several floating point types
Don’t confuse precision with accuracy
Numbers don’t become more accurate when they are stored with more precision. Scientists often measure values with a measure of uncertainty which captures how sure they are in the accuracy of their number. There is no point storing a value to \(15\) decimal places of precision, if the accuracy of a measurement is only to \(1-2\) places, e.g. if we measure with a ruler
Using higher precision can result in slower programs that use more memory
- Python automatically creates variables for use in programs
- The type of a variable is determined by what is stored in it
name = 'Rob'
age = 25- The above creates two variables
- One
nameis astringtype - The other
ageis anintor integer type
- One
Code Analysis: Working with Floating Point Variables
Work through the following following questions to understand how floating-point variables work?
How do you create a floating point variable?
- You can create a floating point variable by assigning a floating point number e.g. the below creates a variable*
x*and assigns it the floating point value \(1.5\)
x = 1.5 x1.5- You can create a floating point variable by assigning a floating point number e.g. the below creates a variable*
What happens if you assign an integer to a floating point variable?
- The below assigns the integer value \(1.0\) to a variable
y - If we print the value back we can see it keeps the decimal, indicating it is a floating point value
y = 1.0 y1.0- i.e. by writing the decimal point we coerce the type of
yto be floating point
- The below assigns the integer value \(1.0\) to a variable
What happens when we mix floating point and integers in calculations?
- If we compare the two additions below, we can see that when we add floating points, the addition stays a floating point even if the result is integral
2 + 242.0 + 2.04.0- If we mix a floating point and integer type we can also see that the result is returned as a floating point (even when the final result is integral)
2 + 2.04.0- Lastly what happens if we divide two coprime integers?
- We see that the result gives the appropriate floating point fraction
1/20.5
Integer Division
While the last point about division behaviour may seem obvious if you haven’t programmed before you would do well to be careful. In many common languages, division of two integers is treated as integer division. In this case the result is always an integer with the result being rounded according to some scheme. Three common schemes are towards zero, in which the result is always rounded towards the number \(0\); towards the nearest, where the result is rounded to the nearest whole number and floored division in which the number is rounded towards negative infinity.
| Division | Example | Interpretation |
|---|---|---|
| towards zero | \(-1/2 = 0\) | Discard decimal digits |
| towards nearest | \(3.2/2 = 2\) | Minimise the difference between “true” division and result |
| floored division | \(-1/2 = -1\) | Round “down” |
Python lets you perform integer division using floored division behaviour with the // operator e.g.
-1//2-1
Converting string into float values
- Converting
stringto float, works identically to as forintbut we usefloatinstead- e.g. We could rewrite the configurable egg timer with floats as,
time_text = input('Enter the cooking time in seconds: ')
time_float = float(time_text)Example: Ultra-Precise Egg Timer
- The complete program would then look like
# Example 4.4 Ultra-Precise Egg Timer
#
# A version of the Configurable Egg Timer using floating point for the input time
import time
time_text = input("Enter the cooking time in seconds: ")
time_float = float(time_text)
print("Put the egg in boiling water now")
input("Press enter to continue once the egg is in...")
time.sleep(time_float)
print("Take the egg out now")- The code is the same except we make the substitution
int\(\to\)float
Perform Calculations
- As mentioned before python is an expression evaluator
- An expression consists of operators and operands
- Python evaluates an expression left to right, and carries out operations according to their order of operations
- Analogous to mathematical order of operations (and includes them) but must extend for programming specific syntax
- As in maths, parentheses are used to enforce an evaluation order
| Operator | Use case |
|---|---|
- |
Unary minus, denotes a negative number |
* |
Multiplication (in-lieu of \(\times\)) |
/ |
Division |
+ |
Addition |
- |
binary minus or subtraction |
- Basic operators and their precedence
Code Analysis: Work out the Results
See if you can work out the values of a, b and c when the following statements are evaluated,
a = 1
b = 2
c = a + b
c = c * (a + b)
b = a + b + cThe first three lines give a = \(1\), b = \(2\) and c = \(3\). Substituting those into the second evaluation for c,
a = 1
b = 2
c = a + b
c = 3 * (1 + 2)
c9
So c is assigned \(9\). We then repeat for the second assignment to b to get,
b = 1 + 2 + 9So the final values are, a = \(1\), b = \(12\), c = \(9\). If we execute the original cell we can confirm this
a = 1
b = 2
c = a + b
c = c * (a + b)
b = a + b + c
print('a: ', a)
print('b: ', b)
print('c: ', c)a: 1
b: 12
c: 9
Dumb Calculations
Python won’t try and stop you if you do something that mathematically makes no sense like dividing a number by zero, instead an error is raised, but this won’t occur until your program runs! Therefore when using division you should always take care to make sure you either handling division by zero cases appropriately or preventing them from occurring
1/0--------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) Cell In[38], line 1 ----> 1 1/0 ZeroDivisionError: division by zero
When using other languages, they may not raise and error, instead unexpected behaviour may occur including your program crashing.
Convert Between float and int
- We saw
floatcan be used to convert astringto a float.- It can also be used to convert an integer value to a floating point value, e.g.
z = float(1)
z1.0
- If we want to go the other way we can use
intto convert afloatto anint.- The number is rounded towards zero, i.e. fractional components are truncated (see the callout-box above about integer division)
i = int(2.9)
i2
Make Something Happen: Calculating a Pizza Order
Consider the following program which is designed to calculate the number of pizzas needed for a hackathon with \(x\) number of participants using the heuristic that \(1\) pizza can satisfy \(1.5\) people
# Example 4.5: Pizza Order Calculator
#
# A basic pizza order calculator based on the heuristic that 1 pizza = 1.5 people fed
students_int = int(
input("How many students are attending? ")
) # read in string, convert to int and store
pizza_count = students_int / 1.5 # perform division int -> float
print("You will need", pizza_count, "pizzas")Note, that I’ve modified the code to directly pass the input to int and then to a variable, to demonstrate that it’s possible.
The above program has the problem that for any number not divisible by \(1.5\), the program recommends ordering a fractional number of pizzas. This is generally not possible, so we need to convert the output to an integer.
Modify the program to return an
intby callingintdirectly during the calculation ofpizza_count. What potential problems does this solution have?# Exercise 4.1.1: Pizza Order Calculator # # A basic pizza order calculator based on the heuristic that 1 pizza = 1.5 people fed students_int = int( input("How many students are attending? ") ) # read in string, convert to int and store pizza_count = students_int / 1.5 # perform division int -> float print("You will need", pizza_count, "pizzas")- This method has the disadvantage that it will tend to underestimate the number of pizzas needed.
- For example if we needed to feed \(40\) people, the program would give us \(26\), which can satisfy, \(39\) people, meaning someone goes hungry
Modify the program to return an
intby callingintto convert the division to anintthen adding \(1\). Explain how this changes the behaviour# Exercise 4.1.2: Pizza Order Calculator # # A basic pizza order calculator based on the heuristic that 1 pizza = 1.5 people fed # Converts the result to an integer using int on pizza_count then adding one # has the disadvantage it will tend to overestimate the number of pizzas needed students_int = int( input("How many students are attending? ") ) # read in string, convert to int and store pizza_count = int(students_int / 1.5) + 1 # perform division int -> float print("You will need", pizza_count, "pizzas")- This method will tend to add an additional spare pizza or overestimate the number of pizzas needed.
- Since it’s generally better for there to be a little left over than someone go hungry, this behaviour is probably preferred.
Never assume you know what a program is supposed to do
When faced with a choice like the above for the pizza order calculator for a product being made by a client, you should not decide what the expected behaviour is yourself. For example, in the above the customer may prefer to round down the number of pizzas to reduce cost.
Never assume you know what the program should do, ask the client
Make Something Happen: Converting Between Fahrenheit and Centigrade
Write a program to convert from Fahrenheit to Centigrade. The formula for this is
\[ \begin{align} \text{Centigrade} &= \frac{\text{Fahrenheit} - 32}{1.8} \end{align} \]
Our solution is very similar to the Pizza Calculator, but with some of the text changed. The other major difference is that we want to be able to accept a float value, and output a float value.
# Exercise 4.2: Fahrenheit to Celsius
#
# Converts Fahrenheit to Celsius
temperature_fahrenheit = float(
input("Enter a temperature in Fahrenheit: ")
) # read in string, convert to float
temperature_centigrade = (temperature_fahrenheit - 32) / 1.8
print("The temperature is", temperature_centigrade, "degrees Celsius")A sample output may look like,
Enter a temperature in Fahrenheit: 0
The temperature is -17.77777777777778 degrees Celsius
- Later we’ll see how we can format the output to be a bit more presentable
Weather Snaps
- Snaps contains a function
get_weather_tempfor to return the temperature of a location in the United States- Data is scraped from the US National Weather Service website
- Function takes the latitude and longitude as an argument
Example: Seattle Temperature
The following program can be used to get the current temperature reading from Seattle using
snaps# Example 4.6: Seattle Temperature # # Get the current temperature in Seattle import snaps temp = snaps.get_weather_temp(latitude=47.61, longitude=-122.33) print("The temperature in Seattle is:", temp)pygame 2.6.1 (SDL 2.28.4, Python 3.12.3) Hello from the pygame community. https://www.pygame.org/contribute.html The temperature in Seattle is: 37
Example: Seattle Weather
We can also use
snapsto get a short description of the current weather# Example 4.7: Seattle Weather # # Uses snaps to get a description of the weather in Seattle import snaps desc = snaps.get_weather_description(latitude=47.61, longitude=-122.33) print("The conditions are:", desc)--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Cell In[43], line 7 1 # Example 4.7: Seattle Weather 2 # 3 # Uses snaps to get a description of the weather in Seattle 5 import snaps ----> 7 desc = snaps.get_weather_description(latitude=47.61, longitude=-122.33) 8 print("The conditions are:", desc) AttributeError: module 'snaps' has no attribute 'get_weather_description'
Make Something Happen: Weather Display Program
Write a program that displays the current weather conditions. If you use the display_text function from snaps, your program can display the current weather and description
Our solution is written below,
# Exercise 4.3: Weather Display
#
# Displays the Weather in Seattle
import snaps
temperature_fahrenheit = snaps.get_weather_temp(latitude=47.61, longitude=-122.33)
temperature_string = "The temperature in Seattle is: " + str(temperature_fahrenheit)
weather_descr = snaps.get_weather_description(latitude=47.61, longitude=-122.33)
weather_descr_string = "The conditions are: " + str(weather_descr)
weather_string = temperature_string + "\n" + weather_descr_string
snaps.display_message(weather_string, size=100)
input("Press enter to continue...")As we can see most the actual getting of the temperature and weather data is the same as for the Seattle Temperature and Weather programs. The rest of the work is done to construct the appropriate strings and merge them together so they can be passed to the display_message function for output
Summary
- Variables can be created
- Variables are effectively named regions of memory
- Variables must start with a letter or underscore and can only consist of alphanumeric characters or underscores
- Data can be viewed as two fundamental types, text or numeric
stringis a type for holding textinputcan be used to get strings from the userintandfloatcan convert a string to an integer or floating point number respectively
- Numeric values have two forms
intfor whole numbers with no fractional partfloatfor real numbers with a fractional partfloatonly approximate real numbers and can be subject to some errors
Questions and Answers
- What happens if I “overwrite” a variable of one type with a value of another type?
- Python replaces the old variable with a new one of the same name but the new type
- Does using a long variable name slow the program down?
- If it does it is insignificant, it’s much more important to use a name that clearly conveys meaning
- Can we write all our programs using floating point numbers?
- You could, but you should use
intwhere appropriate becausefloatrepresentation is inexact and subject to errors- These errors mean that it is often hard to compare for exact equality e.g.
1.0might actually have the representation1.0000...4
- These errors mean that it is often hard to compare for exact equality e.g.
- You could, but you should use
- Can I stop my program from crashing if someone types in an invalid input?
- Yes, this is called error handling. This will be covered later in Chapter 6