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!