Exam 2 Review#

Open In Colab

[ad] Food Insecurity Survey

Q&A

Q: are we going to use the terminals for the final ~project~ exam?
A: Technically, you can do the final without using the terminal, but 1) you will need to know the provided bash commands for E2 and 2) being comfortable at the terminal will make doing your exam easier

Q: can you explain how to open a terminal in prairielearn again please?
A: Yes - I will demo this again, but briefly here, if you’re on PL and you open a workspace: File > New > Terminal will open it

Q: what is the point of an f string instead of just normal ‘’ strings?
A: Concatenating strings with + and using an fstring accomplish the same thing…but the spaces are more intuitive with f-strings. You can use either!

Q: will file paths be on the exam?
A: Yup - you’ll need to understand relative and absolute paths

Q: Will we have to create a project? (Maybe for the final we can have a choice to create a project)
A: Historically, COGS 18 has had a project. Because of all the changes, I did remove it this quarter and everyone will do the exam. However, the exam will be a mini project….I’ll just guide you rather than you doing a project independently. Apologies if you were excited to do a project!

Course Announcements

Due this week:

  • VQ12 due Wed night <- this is your last VQ!

  • CL7 due Friday

  • Take E2: 5/23-5/30

Notes:

  • Practice E2 is available on PL - take multiple instances!

  • This week’s oral exam focuses on classes

  • Sign up for a second oral exam if you haven’t yet

Day of Exam:#

What to Bring:

  • An ID

  • Your Brain

  • A writing utensil

Reminders:

  • You will put your belongings in a locker; leave time for this

  • You are not allowed to bring in water/coffee

  • They will provide scratch paper & a calculator

  • You’ll need to sign into your PL

Location: TTC-CBTF - Applied Physics & Mathematics (AP&M) B349 (basement)

Exam Window: 5/23-5/30 (Fri-Fri); 45min

Exam 2 Plan#

Exam (15 Qs): (there were 25 on E1)

  • Q1 - blank jupyter notebook (no credit)

  • Q2-8 Multiple Choice (7)

  • Q9-13 “Short Answer” (line of code, matching, drop-down, parsons) (5)

  • Q14-16 Code Reading & Debugging (3)

Topics Focused on (#Qs):

  1. Loops (5 | 1MC; 3 SA; 1 Debug)

  2. Methods (4 | 3 MC; 1 SA)

  3. Classes (4 | 1 MC; 1 SA; 2 Debug)

  4. Command Line, File Paths & Imports (2 | 2 MC)

Note: This is the expected layout. Small changes to this could be made after the staff proofread/test-drive the exam.

Topics from E1 (can’t forget)#

  • Variables

  • Operators

  • Functions

  • Conditionals

E2 Topics#

Loops#

Types:

  • for and while

  • range, break, continue

Methods#

  • list, string, and dictionary methods (need to know .append(); others will be explained)

  • in place vs not in place

  • in place: when you use the method, directly changes the variable it is operating on

  • not in place: when you use the method, the variable it is operating on remains UNchanged

# append  - operates IN PLACE
my_list = ['a', 'b']
my_list.append('c')
my_list
['a', 'b', 'c']
# operate NOT IN PLACE
my_string = 'hi'
my_string.upper()
'HI'
my_string
'hi'

Classes#

  • class

  • class & instance attributes

  • methods

  • self

  • instance

  • accessing attributes

  • executing methods

Command Line, File Paths & Imports#

  • shell commands: pwd, ls, mkdir, touch, cd, mv

  • absolute and relative file paths

  • import (from and as)

Questions#

What questions do you have!?

Practice#

These practice questions are NOT representative of the typical question on the exam, but are representative of the more difficult questions on the exam. Many students are feeling pretty good about MC & matching questions (and you’ve done lots of those on PL so far) and less confident when there’s less structure. So, I figured if we did these together…we’d get everyone feeling a bit more confident!

The form we’ll use for today (we’ll just keep using the same one….): https://forms.gle/wf1dayq5fw8VNMPR9

Q1#

Q1. Fix the StudyTracker class below, so that it accomplishes the following:

  • by default sets hours_studied at 0, but allows the user to specify a different value when initializing an instance

  • has a method add_hours that increases the number of hours in the hours attribute by the input to the method

  • has a method study_feedback that returns a different string if you’ve studied less than 1 hour, less than 3 hours, or 3 hours or more. (Note: the strings do not need to be changed, but the conditional logic may)

#original
class StudyTracker:
    def __init__(self):
        hours = 0

    def add_hours(additional_hours):
        hours -= additional_hours

    def study_feedback():
        if hours > 1:
            return "Getting started is the hardest part—keep going!"
        elif hours > 3:
            return "Nice! You're building solid study habits."
        else:
            return "Awesome dedication! You're setting yourself up for success!"
#fixed
class StudyTracker:
    def __init__(self, hours_studied=0):
        self.hours = hours_studied

    def add_hours(self, additional_hours):
        self.hours += additional_hours

    def study_feedback(self):
        if self.hours < 1:
            return "Getting started is the hardest part—keep going!"
        elif self.hours < 3:
            return "Nice! You're building solid study habits."
        else:
            return "Awesome dedication! You're setting yourself up for success!"
# TEST IT OUT HERE
st = StudyTracker()
st.hours
0
st.add_hours(2)
st.hours
2
st.add_hours(2)
st.study_feedback()
"Awesome dedication! You're setting yourself up for success!"

Concepts in Q1:

  • classes

  • debugging

Note to self: demo how to make similar questions on ChatGPT

Q2#

Q2. Below is an attempt at implementing a CoffeeTracker class. Its instance attributes are all working as intended…but buy_coffee is not quite there. Fix the buy_coffee method so that when it takes in a list of prices, it will update the total_spent attribute to:

  • include the sum of all prices in prices

  • update total_coffees attribute to count how many drinks were in the prices list

  • If the number of total_coffees is more than zero, the average_price attribute will be updated, calculating the value in the total_spent attribute divided by the value in the total_coffees attribute. The print statements at the end do NOT need to be changed.

# original
class CoffeeTracker:
    def __init__(self, name):
        self.name = name
        self.total_spent = 0.0
        self.total_coffees = 0
        self.average_price = 0.0

    def buy_coffee(prices):
        total_spent = price
        total_coffees = 1
        
        if total_coffees > 0:
            average_price = total_spent / total_coffees
        
        print(f"{self.name} bought {self.total_coffees} coffees.")
        print(f"Average price per coffee: ${self.average_price:.2f}")
len([5, 10])
2
sum([5, 10])
15
#debugged
class CoffeeTracker:
    def __init__(self, name):
        self.name = name
        self.total_spent = 0.0
        self.total_coffees = 0
        self.average_price = 0.0

    def buy_coffee(self, prices):
        # for price in prices:
        #     self.total_spent += price
        #     self.total_coffees += 1

        self.total_spent = sum(prices)
        self.total_coffees = len(prices)
        
        if self.total_coffees > 0:
            self.average_price = self.total_spent / self.total_coffees
        
        print(f"{self.name} bought {self.total_coffees} coffees.")
        print(f"Average price per coffee: ${self.average_price:.2f}")
ct = CoffeeTracker('Shannon')
ct.name
'Shannon'
ct.total_spent
0.0
ct.buy_coffee([5, 10])
Shannon bought 2 coffees.
Average price per coffee: $7.50
ct.total_spent
15
ct.total_coffees
2

Concepts in Q2:

  • Classes

  • Debugging

  • loops

  • conditionals

Q3#

Q3a. Assume a fictitious class Exam2 has been defined. It contains:

  • a class attribute course which stores the string ‘COGS 18’

  • two instance attributes storing the name of a student and the score that they earned

  • a single method calculate_percentage that calculates the student’s percentage out of 100 by dividng score by 12.5

How would you create an instance my_exam2 of this object? How would you access the name attribute? How would you execute the calculate_percentage method?

# YOUR ANSWER HERE
my_exam2 = Exam2('Shannon', 12.25)
my_exam2.name
my_exam2.calculate_percentage()

Q3b Time permitting: Try to write the code for the class described above. Note: You will NOT have to write a whole class from scratch on the exam.

## YOUR CODE HERE
class Exam2():
    course = 'COGS 18'

    def __init__(self, name, score):
        self.name = name
        self.score = score

    def calculate_percentage(self):
        percentage =  self.score/12.5 * 100
        return f"{self.name} earned a {percentage}% on the second exam in {self.course}"
my_exam2 = Exam2('Shannon', 12.25)
my_exam2.name
'Shannon'
my_exam2.calculate_percentage()
'Shannon earned a 98.0% on the second exam in COGS 18'