4/27/2020
Agenda:
-
None
-
Exercise: vendingmachine.py
-
help/dir
-
magic methods
Notes:
vendingmachine.py
from snack import Snack
class VendingMachine:
def __init__(self):
"""
Constructor. Initializes a list of available snacks (empty to start) and
calls a function to load the default file of snack information
"""
self.foods = []
self.loadSnacks("snacks.txt")
def loadSnacks(self, filename):
"""
Loads snack information from a file. Clears the old snacks from the
machine. Param filename (string): the file to load Returns: none
"""
ifile = open(filename, "r")
for line in ifile:
tokens = line.strip().split(",")
print(tokens)
name = tokens[0]
quantity = int(tokens[1])
cost = int(tokens[2])
desc = tokens[3]
snack = Snack(name, quantity, cost, desc)
self.foods.append(snack)
def listSnacks(self):
"""
Pretty prints the snacks in the vending machine.
Hint: Use the following string formatting to match the sample output
"%d) %-20s %d left\t$%d\t%s"
Params: none
Returns: none
"""
print()
print("="*30, "Vending Machine", "="*30)
for i in range(len(self.foods)):
print(i, self.foods[i])
print("="*75)
def buy(self, snack, money):
"""
Buy a snack from the vending machine.
Prints "Cannot find food" if the snack is not a valid (e.g. None)
Prints "None left!" if the named snack is unavailable
Prints "You can't afford it" if the snack costs too much
Prints "You bought a snack!" if successful and decrements the snack qty
Param snack (Snack): the snack to buy (might be None)
Param money (int): the available amount of money
Returns: True is successful; False otherwise
"""
if snack is None:
print("Cannot find food!")
return False
elif snack.getQuantity() == 0:
print("None left!")
return False
elif snack.getCost() > money:
print("You can't afford it")
return False
else:
print("You bought a snack!")
quantity = snack.getQuantity()
snack.setQuantity(quantity-1)
return True
def findSnack(self, name):
"""
Searches for a snack matching name in the list of snacks
Param name (string): the snack name to search
Returns: found snack (type Snack) if found; None otherwise
"""
# for every snack in our list of list of snack
# if the snack's name == name: return the snack
for i in range(len(self.foods)):
snack = self.foods[i]
if snack.getName() == name:
return snack
return None # not found!
def getSnack(self, idx):
"""
Returns the snack at marker idx in the list of snacks
Param idx (int): the snack id
Returns: snack (type Snack) if found; None otherwise
"""
if idx < 0 or idx >= len(self.foods):
return None # not valid, not found
return self.foods[idx]
def getNumSnacks(self):
"""
Returns the number of snacks in the vending machine
Params: none
Returns (int): the number of snacks
"""
return len(self.foods)
if __name__ == '__main__':
playerMoney = 10
machine = VendingMachine()
print("You have $%d dollars to spend at the snack vending machine"%playerMoney)
print("What would you like to buy?")
machine.listSnacks()
print()
numSnacks = machine.getNumSnacks()
snack = machine.findSnack("Slurm")
#print("Snack Test1: ", snack) # for debugging
snack = machine.findSnack("Cheetos")
#print("Snack Test2: ", snack) # for debugging
snackIdx = int(input("Enter a choice from 0 to %d: "%(numSnacks-1)))
snack = machine.getSnack(snackIdx)
#print("The user choose: ", snack) # for debugging
if machine.buy(snack, playerMoney):
playerMoney = playerMoney - snack.getCost()
print("You now have $%d left"%playerMoney)
point.py
dir
and help
Use dir
to list all the functions/classes in a module or all the methods in a class.
Use help
to see the interface for a module or class. If the clas has documentation
strings for each function, the user will see them too!
Magic methods
str
is an example of a magic method. Classes automatically inherit
this method by default. When we define an implementation for it, we customize
its behavior.
Magic methods allow our classes to "plug in" to convenient Python features.
In the example below, we override add
to give Point the ability to
add with the plus operator!
class Point:
"""
Class for representing 2D coordinates
"""
def __init__(self, x, y):
"""
Constructor
Parameters:
x (float) - coordinate along x axis
y (float) - coordinate along y axis
Return (Point) - implicitly returns a new object with type Point
"""
self.x = x
self.y = y
def scale(self, factor):
"""
Scales this point by factor
Parameters:
factor (float) - scale factor
Return: None
Side effects: changes x,y values of this Point
"""
self.x = factor * self.x
self.y = factor * self.y
def setX(self, x):
"""
Mutator/Setter
Parameters (numeric): x
Return (None)
Side effects: None
"""
self.x = x
def setY(self, y):
"""
Mutator/Setter
Parameters (numeric): y
Return (None)
Side effects: None
"""
self.y = y
def getX(self):
"""
Accessor/Getter
Parameters: None
Return (float): the x coordinate
Side effects: None
"""
return self.x
def getY(self):
"""
Accessor/Getter
Parameters: None
Return (float): the y coordinate
Side effects: None
"""
return self.y
def __str__(self):
return "%f,%f"%(self.getX(), self.getY())
def __add__(self, other):
"""
override + behavior, e.g. implement p = p1+p2
"""
x = self.x + other.x
y = self.y + other.y
return Point(x,y)
if __name__ == '__main__':
p = Point(5, -3) # call __init__
print("The point is", p)
p.scale(10)
print("The point is", p)
p.setX(-4)
p.setY(-8)
print("The point is", p) # call __str__
p1 = Point(10,10)
p2 = Point(0,5)
p = p1 + p2 # call __add__
print(p1, "+", p2, "=", p)
4/29/2020
Agenda:
-
Data structures
-
Dictionary
-
Example: vehicle speeds
Data structures
Data structure is the term we give to containers which allow us to organize data. So far, our primary data structure has been lists, which are great for storing data that we primarily want to access sequentially or by index.
However, lists are incovenient (and slow) when we want to look up data by an attribute such as its name. Using lists, our best solution is to keep the list sorted by name so we can lookup items using binary search. An easier data structure to use in this case is a Dictionary.
Dictionaries organize data in terms of key:value pairs. Using the key, we can easily get the corresponding value.
Dictionary practice
The data type name for dictionaries in Python 3 is dict.
Digression: During class today, I forgot the syntax for checking whether a key is in a dictionary. To find the answer, I looked at the examples in the following tutorials by searching for "python3 dictionary". In general, if you ever forget the syntax for a Python feature, you can always search in this way. For an open book quiz, you can also prepare code snippets ahead of time!
Resources:
"""
Dictionary practice
"""
def main():
names2ages = {} # creates an empty dictionary
print(names2ages)
# suppose our pairs are str:int
names2ages = { "marie": 65, "shane":45, "cat":38, "briana":28}
ages2names = { 65:"marie", 45:"shane"}
print(names2ages)
# L[0], e.g. L[<index>]
print(names2ages["marie"]) # syntax: dict[<key>]
# if the key is not in the dictionary, we get an KeyError!
# checking if a key is in a dictionary
if "bill" in names2ages:
print(names2ages["bill"]) # dictionary[<key>], throws error if bill not a key
else:
print("bill not in dictionary")
print(names2ages.keys()) # returns all keys
print(names2ages.values()) # returns all values
# append to add items to a list
names2ages["bill"] = 10 # add a key/value pair for bill:10
print(names2ages["bill"])
names2ages["bill"] = 15 # replace value of 10 to 15 for key "bill"
print(names2ages["bill"])
# safe method of getting values for keys
age = names2ages.get("sally", -1)
print("sally", age)
age = names2ages.get("shane", -1)
print("shane", age)
print("-"*30)
for key in names2ages.keys():
# key can be used to lookup the value
print(key, names2ages[key])
print("-"*30)
for key,value in names2ages.items():
# item is a key,value tuple
print(key,value)
main()
vehicle-dictionary.py
"""
Write a program that let's the user ask for the maximum speed of a vehicle
Load the vehicles/speeds from the file "speeds.csv" and store the results
in a dictionary
$ python3 vehicle-dictionary.py
Enter a vehicle (Type nothing to quit): plane
The speed of plane is 2193.000000 mph
Enter a vehicle (Type nothing to quit): bicycle
Sorry. I don't know the speed for bicycle
Enter a vehicle (Type nothing to quit):
"""
def load(filename):
data = {}
ifile = open(filename, "r")
for line in ifile:
tokens = line.strip().split(",")
name = tokens[0]
speed = float(tokens[1])
data[name] = speed
return data
def main():
vehicles2speed = load("speeds.csv")
done = False
while not done:
query = input("Enter a vehicle (Type nothing to quit): ")
if query == "":
done = True
else:
speed = vehicles2speed.get(query, -1)
if speed != -1:
print(f"The speed of {query} is {speed}")
else:
print(f"Sorry. I don't know the speed for {query}")
main()
5/1/2020
Agenda:
-
Reflections
-
Next steps
Reflections
What concepts were most confusing?
Your thoughts:
-
recursion
-
^ yes
-
TDD
-
And classes too
-
Recursion
-
classes
-
Classes and files
-
that Wheel of Fortune lab
-
^
-
recursion
What concepts were most intuitive?
Your thoughts:
-
graphics
-
Nothing, but that’s okay!
-
print("hello world")
-
For loops
-
Print statements
-
if statements
-
Else/if
-
while loops were fun once u understood for loops
Were there aspects of programming that you found surprising or interesting?
Your thoughts:
-
How code turns into graphics
-
I think seeing the different functions within each program was neat
-
blobilism lab was the best
-
If debugging is the process of fixing bugs, then programming is the process of writing them - some quotable programmer out there
-
Surprised by how many cases you have to prepare for! Can’t just say do this also have to say if this happens, do this, etc.
Next steps
Free online resources for practicing python
-
www.hackerrank.com
-
open.kattis.com
Is it Halloween?
def checkHalloween(line):
tokens = line.strip().split(" ")
month = tokens[0]
day = tokens[1]
if month == "OCT" and day == "31":
print("yup")
elif month == "DEC" and day == "25":
print("yup")
else:
print("nope")
# The input will be fed into this program
# Thus, we don't provide a prompt, which only makes sense
# for a human user
userText = input()
checkHalloween(userText)
To run the program outside the website, put the input into a file and then "pipe" it into Python 3.
$ cat input1.txt
DEC 10
$ cat input1.txt | python3 halloween.py
nope
You can also enter the input manually. The program will sit and wait for you to enter input
$ python3 halloween.py
DEC 10
nope
Oddities
n = int(input())
for i in range(n):
x = int(input())
if x % 2 == 0:
print(x,"is even")
else:
print(x,"is odd")
If you like solving programming puzzles, try these ones next!