Winter 2024 Quiz 3

← return to practice.dsc10.com


This quiz was administered in-person. It was closed-book and closed-note; students were not allowed to use the DSC 10 Reference Sheet. Students had 20 minutes to work on the quiz.

This quiz covered Lectures 8-11 of the Winter 2024 offering of DSC 10.

⚠️ PDF version available here .


The DataFrame flights contains information about recent flights, with each row representing a specific flight and the following columns:


Problem 1

Lecture 8

Suppose the function first_two takes as input a string and returns a string with the first two characters only. For example first_two("panda") is "pa". Using this function, write an expression that evaluates to a Series containing the two-character airline designator for each flight in flights.

Answer: flights.get("flight_num").apply(first_two)

flights.get("flight_num") selects the "flight_num" column as a Series, with values like "UA1989". Calling .apply(first_two) runs the first_two function on every value in that Series, replacing each flight number with just its first two characters — the airline designator.


Difficulty: ⭐️⭐️

The average score on this problem was 78%.


Problem 2

Lecture 9


Problem 2.1

Fill in the blanks below so that grouped is a DataFrame showing how many flights on each airline departed from each airport.

    grouped = flights.groupby(___(x)___).___(y)___.get(["flight_num"])

Answer (x): ["departure", "airline"] or ["airline", "departure"]

“How many flights on each airline departed from each airport” asks for a count for every combination of departure airport and airline. Grouping by a list of both columns creates one group — one row in the output — for each distinct (departure, airline) pair that appears in flights. The order of the two columns in the list doesn’t change which pairs exist, only how the resulting index is arranged.


Difficulty: ⭐️⭐️

The average score on this problem was 82%.

Answer (y): count()

.count() counts the number of flights that fall into each group. .get(["flight_num"]) then keeps just the "flight_num" column (wrapped in a list so the result stays a DataFrame), which holds that count for every (departure, airline) pair.


Difficulty: ⭐️⭐️

The average score on this problem was 89%.


Problem 2.2

Suppose the expression grouped.shape[0] == flights.shape[0] evaluates to True. Select all true statements below.

Answer: Option 3 and Option 4

grouped has one row per distinct (departure, airline) pair, and grouped.shape[0] == flights.shape[0] means there are exactly as many such pairs as there are flights. Since no row can be grouped twice, this means every flight has a unique (departure, airline) pair — no two flights share both the same departure airport and the same airline.

Option 1: False. This would mean every flight is on a different airline, which is much stronger than what we’re told. Two flights can share an airline, as long as they don’t also share a departure airport.

Option 2: False. Arrival airport isn’t one of the columns we grouped by, so this condition doesn’t follow from grouped.shape[0] == flights.shape[0] at all.

Option 3: True. If two flights were on the same airline and had the same departure airport, they’d share the same (departure, airline) pair, which we just said can’t happen. So within a single airline, every flight departs from a different airport.

Option 4: True. This is the same fact, viewed the other way: if two flights departed from the same airport and were on the same airline, they’d again share a pair. So among flights from the same airport, every flight is on a different airline.


Difficulty: ⭐️⭐️

The average score on this problem was 80%.



Problem 3

Lecture 9

Suppose we have another DataFrame more_flights which contains the same columns as flights, but different rows. Define merged as follows.

        merged = flights.merge(more_flights, on = "airline")

Suppose that in merged, there are 108 flights where the airline is "United", and in more_flights, there are 12 flights where the airline is "United". If flights has 15 rows in total, how many of these rows are not for "United" flights? Give your answer as an integer.

Answer: 6

When we merge on "airline", every "United" row in flights is paired with every "United" row in more_flights. So the number of "United" rows in merged is

(\text{\# United rows in } \texttt{flights}) \times (\text{\# United rows in } \texttt{more\_flights}).

We’re told this product is 108, and that more_flights has 12 "United" rows, so

(\text{\# United rows in } \texttt{flights}) \times 12 = 108 \implies \text{\# United rows in } \texttt{flights} = 9.

Since flights has 15 rows in total, the number that are not "United" flights is

15 - 9 = \boxed{6}.


Difficulty: ⭐️⭐️⭐️

The average score on this problem was 64%.


Problem 4

Lecture 11


Problem 4.1

Fill in the blanks below so that prob evaluates to the probability that a randomly selected flight from the flights DataFrame arrives at "SAN" given that it departs from "LAX".

san = flights.get("arrival") == "SAN"
lax = flights.get("departure") == "LAX"
prob = flights[san___(x)___lax].shape[0] / ___(y)___

Answer (x): &

The probability of arriving at "SAN" given departure from "LAX" is the fraction of LAX departures that go to SAN — that is, flights where both san and lax are True. Since san and lax are Boolean Series, we combine them element-wise with & to find flights satisfying both conditions at once.


Difficulty: ⭐️⭐️⭐️

The average score on this problem was 66%.

Answer (y): flights[lax].shape[0]

A conditional probability is (# satisfying both conditions) / (# satisfying the condition we’re given). The numerator, flights[san & lax].shape[0], counts flights that both depart from LAX and arrive at SAN. The denominator should be the number of flights departing from LAX — the event we’re conditioning on — which is flights[lax].shape[0].


Difficulty: ⭐️⭐️⭐️

The average score on this problem was 62%.


Problem 4.2

Write an expression that evaluates to the probability that a randomly selected flight from the flights DataFrame is not on the airline "Delta".

Answer: 1 - flights[flights.get("airline") == "Delta"].shape[0] / flights.shape[0] or flights[flights.get("airline") != "Delta"].shape[0] / flights.shape[0] or (flights.get("airline") != "Delta").mean()

flights[flights.get("airline") == "Delta"].shape[0] / flights.shape[0] is the probability that a random flight is on Delta. By the complement rule, the probability it’s not on Delta is 1 minus that.

Alternatively, we can count the “not Delta” flights directly: flights.get("airline") != "Delta" is a Boolean Series that’s True for every non-Delta flight, so flights[flights.get("airline") != "Delta"].shape[0] / flights.shape[0] divides that count by the total number of flights.

The last expression uses a shortcut: taking .mean() of a Boolean Series gives the proportion of True values (since True and False act as 1 and 0), which here is exactly the proportion of flights that are not on Delta.


Difficulty: ⭐️⭐️

The average score on this problem was 76%.



Problem 5

Lecture 10

Use the function defined below to answer the questions on the right.

def discount(duration, price):
    if duration > 6:
        price = price * 0.9
    if duration > 4:
        price = price * 0.95 
    elif duration > 3:
        price = price * 0.98
    else:
        price = price * 0.99 
    price = price - 5 
    return price


Problem 5.1

What is the output of discount(7, 100)?

Answer: Option 2

discount has two separate conditional blocks, not one long chain — the second if/elif/else is independent of the first if. Calling discount(7, 100) runs both blocks:

  • First block: duration > 6 is 7 > 6, which is True, so price = 100 * 0.9.
  • Second block: duration > 4 is 7 > 4, which is True, so this branch runs (and the elif/else are skipped): price = (100 * 0.9) * 0.95.
  • Finally, price = price - 5.

So the output is 100 * 0.9 * 0.95 - 5, which is Option 2.


Difficulty: ⭐️⭐️⭐️

The average score on this problem was 72%.



Problem 5.2

Find x and y such that discount(x, y) evaluates to 97 * 0.98 - 5.

Answer (x): anything greater than 3 and less than or equal to 4

The target expression 97 * 0.98 - 5 only has one multiplier, 0.98, before the - 5. That 0.98 only comes from the elif duration > 3 branch of the second block, so the first if duration > 6 block must not have multiplied price by anything — meaning it didn’t run, so duration must be 6 or less. The elif duration > 3 branch running (instead of the if duration > 4 branch before it, or the else) means duration is greater than 3 but not greater than 4. Together, that’s 3 < duration <= 4.


Difficulty: ⭐️

The average score on this problem was 95%.

Answer (y): 97

Since the first block never runs, price enters the second block unchanged, so the 0.98 multiplies the original input price directly: price * 0.98 - 5 must equal 97 * 0.98 - 5, so price = 97.


Difficulty: ⭐️

The average score on this problem was 95%.



👋 Feedback: Find an error? Still confused? Have a suggestion? Let us know here.