lab02 : Coffee Shop

num ready? description assigned due
lab02 true Coffee Shop Sun 04/16 11:59PM Sun 04/23 11:59PM

In this lab, we’ll utilize inheritance functionality and define various Beverage objects and its properties. You’ll have the opportunity to practice:

Note: In general, it is always important to work on labs and reading early so you can gain the proper context and utilize our office hours to seek assistance / ask clarifying questions during the weekdays before the deadline if needed!

It may be a good idea to read up on some concepts we’ll be using in this lab before you get started, specifically Chapter 1.4.6.2 (Inheritance).

In this lab, we will create a Beverage base class as well as defining specific classes for a couple types of Beverages (Coffee and FruitJuice). The DrinkOrder class will organize Beverages and will provide a summary of a specific drink order.

In addition to defining classes for various Beverages and a Drink Order, you will test your code for correctness by unit testing various scenarios using pytest.

Instructions

You will need to create five files:

There will be no starter code for this assignment, but rather the class descriptions and required methods are defined in the specification below.

It’s recommended that you organize your lab work in its own directory. This way all files for a lab are located in a single folder. Also, this will be easy to import various files into your code using the import / from technique shown in lecture.

Beverage class

The Beverage.py file will contain the class definition of what a general beverage is.

We will define this class’ attributes as follows:

You should write a constructor that passes in values for all the fields. You may assume calls to the constructor will always contain a positive int representing the beverage’s ounces and a positive float representing the beverage’s price.

In addition to your constructor, your class definition should also support “setter” and “getter” methods that can update and retrieve the state of the Beverage objects:

Each Beverage object should be able to call a method getInfo(self) that you will implement, which returns a str with the current beverage’s ounces and price. Since there are many beverages, the following output represents what will be returned if we call the getInfo method after constructing a Beverage object:

b1 = Beverage(16, 20.5)
print(b1.getInfo())

Output:

16 oz, $20.50

Note: The b1.getInfo() return value in the example above does not contain a newline character (\n) at the end.

Tip: Note that the return string will contain a price with two decimal places (as traditionally used when displaying prices). Consider using the string’s format method have floating point values contain 2 decimal places. For example:

>>> price = 1.5
>>> "{:.2f}".format(price)
'1.50'

You can refer to CS 8 lecture notes on string formatting if you would like a review https://ucsb-cs8.github.io/m19-wang/lectures/lect11/

Coffee class

The Coffee.py file will contain the class definition of what a coffee beverage will have. Since a coffee IS-A beverage, we will inherit the values we defined in the Beverage class.

Your Coffee class definition should support the following constructor and method:

>>> c1 = Coffee(8, 3.0, "Espresso")
>>> c1.getInfo()
'Espresso Coffee, 8 oz, $3.00'

Note: The c1.getInfo() return value in the example above does not contain a newline character (\n) at the end.

FruitJuice class

The FruitJuice.py file will contain the class definition of what a fruit juice beverage will have. Since a fruit juice IS-A beverage, we will inherit the values we defined in the Beverage class.

Your FruitJuice class definition should support the following constructor and method:

>>> juice = FruitJuice(16, 4.5, ["Apple", "Guava"])
>>> juice.getInfo()
'Apple/Guava Juice, 16 oz, $4.50'

Note: The juice.getInfo() return value in the example above does not contain a newline character (\n) at the end.

DrinkOrder class

The DrinkOrder.py file will contain the class definition of what a customer’s drink order will contain along with the total price of all beverages in the drink order.

Your DrinkOrder class definition should support the following constructor and methods:

c1 = Coffee(8, 3.0, "Espresso")
juice = FruitJuice(16, 4.5, ["Apple", "Guava"])
order = DrinkOrder()
order.addBeverage(c1)
order.addBeverage(juice)
print(order.getTotalOrder())

Output:

Order Items:
* Espresso Coffee, 8 oz, $3.00
* Apple/Guava Juice, 16 oz, $4.50
Total Price: $7.50

An example of what the return string format of the getTotalOrder method when there are no beverages in the Drink Order is shown below:

Order Items:
Total Price: $0.00

Note: The order.getTotalOrder() return value in the examples above do not contain a newline character (\n) at the end.

testFile.py pytests

This file will contain unit tests using pytest to test if your functionality is correct. You should create your own tests different than the examples given in this writeup. Think of various scenarios and method calls to be certain that the state of your objects and return values are correct (provide enough tests such that all method calls in Beverage, Coffee, and FruitJuice and DrinkOrder are covered). Even though Gradescope will not use this file when running the automated tests, it is important to provide this file with various test cases (testing is important!!). We will manually grade your testFile.py to make sure your unit tests cover the defined methods in Beverage, Coffee, and FruitJuice and DrinkOrder. There are many ways to organize your test functions - my recommendation is writing a test for each class, and calling various methods to make sure the functionality and state of the objects are correct.

Pytest will need to be installed on your computer since it does not come with Python by default. Some links for you to use when installing pytest are:

In order to run your pytests, you can navigate to your folder where your lab02 code is located with the command line interface, and run:

On Mac:

python3 -m pytest testFile.py

On Windows:

python -m pytest testFile.py

Submission

Once you’re done with writing your class definition and tests, Submit your Beverage.py, Coffee.py, FruitJuice.py, DrinkOrder.py, and testFile.py files to the Lab02 assignment on Gradescope. There will be various unit tests Gradescope will run to ensure your code is working correctly based on the specifications given in this lab.

Note on grading for labs with testing component: For this lab assignment (and all lab assignments requiring a testFile.py), we will only manually grade the tests you write. In general, your lab score will be based on the autograder’s score (out of 100 points).

If Gradescope’s tests don’t pass, you may get some error message that may or may not be obvious. Don’t worry - if the tests didn’t pass, take a minute to think about what may have caused the error. Try to think of your pytests and see if you can write a test to help you debug the error (if you haven’t already). If you’re still not sure why you’re getting the error, feel free to ask your TAs or Learning Assistants.