Winter 2024 Quiz 1

← 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 1-4 of the Winter 2024 offering of DSC 10.

⚠️ PDF version available here .


Problem 1

Lecture 2

Select all the true statements below.

Answer: Option 1 and Option 3

Option 1: True. When an arithmetic expression mixes an int and a float, Python converts the int to a float so that no information after the decimal point is lost. The result is therefore always a float.

Option 2: False. Dividing with / always produces a float, even when there is no remainder. For example, 4 / 2 evaluates to 2.0, not 2.

Option 3: True. Every value can be written out as text, so str() works on any float.

Option 4: False. float() only works on strings that look like a number. For example, float('hello') raises a ValueError because there’s no number to convert.


Difficulty: ⭐️⭐️

The average score on this problem was 87%.


Problem 2

Lecture 3

Consider the assignment statement below.

pear = [6, 10.1, "pear", 13]

What does the expression np.array(pear) evaluate to?

Answer: array(["6", "10.1", "pear", "13"])

Every element of an array must have the same type. When np.array() receives a list with mixed types, (if possible) it converts all of the elements to a single type that can represent every one of them. A number can always be written as a string, but not every string can be written as a number, so every element in this array is converted to a string.

Option 1: array([6, 10.1, "pear", 13]). Incorrect. This keeps the original types of the elements, so the array would hold numbers and strings together

Option 2: array([6, 10.1, pear, 13]). Incorrect. Without quotes, pear refers to the variable (the whole list), not the string "pear", which still mixes types

Option 3: array(["6", "10.1", "pear", "13"]). Correct. All four elements become strings, so the array has a single type

Option 4: array(["pear"]). Incorrect. np.array() doesn’t throw away elements whose type doesn’t match. All four elements are kept

Option 5: array([pear]). Incorrect. This would be an array containing the variable pear itself, rather than the elements of the list. This nests the list pear within another list, ultimately resulting in array([['6', '10.1', 'pear', '13']]).

Option 6: This expression errors. Incorrect. NumPy converts every element to a common type, which in this problem is a string.


Difficulty: ⭐️⭐️⭐️

The average score on this problem was 50%.


Problem 3

Lecture 3

Suppose x and y are both ints that have been previously defined, with x < y. Now, define:

peach = np.arange(x, y, 2)

Say that the spread of peach is the difference between the largest and smallest values in peach. The spread should be a non-negative integer.


Problem 3.1

Using array methods, write an expression that evaluates to the spread of peach.

Answer: peach.max() - peach.min()

The spread is the largest value minus the smallest value. Arrays have the methods .max() and .min(), which return the largest and smallest elements of the array.

  • Order matters. The largest value has to come first
  • Methods vs. functions. max(peach) and np.max(peach) also find the largest value, but they are functions, note the array goes inside the parentheses. A method is called on the array with a dot, like peach.max()
  • Don’t forget the parentheses. peach.max without () refers to the method itself and doesn’t call it, so peach.max - peach.min errors.

Difficulty: ⭐️⭐️⭐️

The average score on this problem was 62%.


Problem 3.2

Without using any methods or functions, write an expression that evaluates to the spread of peach.
Hint: Use [ ].

Answer: peach[len(peach) - 1] - peach[0] or peach[-1] - peach[0]

The key is that np.arange(x, y, 2) produces values in increasing order. That means:

  • The smallest value is the first element, peach[0].
  • The largest value is the last element, peach[-1]. A negative index counts from the end of the array, so -1 is the last element.

Common mistakes:

  • peach[len(peach)] - peach[0] errors. Indexing starts at 0, so the index of the last element is len(peach) - 1, not len(peach).
  • y - x or peach[y] - peach[x]. y is never in peach because np.arange stops before y. Also, x and y are values in the array, not positions in it.

Difficulty: ⭐️⭐️⭐️⭐️

The average score on this problem was 36%.


Problem 3.3

Choose the correct way to fill in the blank in this sentence:

The spread of peach is ______ the value of y - x.

Answer: always less than

The smallest value in peach is x. Because np.arange excludes the stop value, the largest value in peach is always strictly less than y. It’s either y - 1 or y - 2, depending on whether y - x is odd or even. So the spread is (largest value) − x, which is strictly less than y - x.

Why the other options are wrong:

  • “sometimes less than and sometimes equal to” / “always equal to”: the spread could only equal y - x if y were in the array. np.arange never includes the stop value, so equality never happens.
  • “always greater than” / “sometimes greater than and sometimes equal to”: every value in peach lies between x and y, and x is the smallest, so the spread can’t exceed y - x.

Difficulty: ⭐️⭐️⭐️⭐️

The average score on this problem was 48%.



Problem 4

Lecture 4

Suppose fruits is a DataFrame of the fruits Ashley bought at the grocery store, where:


Problem 4.1

Fill in the blanks below to add a new column to fruits called "price_per_ounce" that contains the price per ounce of each of the fruits in fruits. There are 16 ounces in a pound.

    fruits = fruits.__(x)__(price_per_ounce = __(y)__ / __(z)__)

Answer (x): assign

We know that we must create a new column called price_per_ounce, and .assign() is the DataFrame method that adds a new column. The name before the = (price_per_ounce) becomes the column’s name, and the value after the = becomes its values. Notice that .assign() doesn’t change the original DataFrame. It returns a new one, which is why the result is saved back into fruits with fruits = ....


Difficulty: ⭐️⭐️⭐️

The average score on this problem was 71%.

Answer (y): fruits.get("price")

To compute the price per ounce, we start with the total price paid for each fruit. fruits.get("price") gives the "price" column as a Series. Because we do arithmetic on the whole Series at once, the calculation happens for every fruit (every row) in one step.

A common mistake is to write just "price". That’s a string, not the column, so dividing it by a number errors.


Difficulty: ⭐️⭐️⭐️

The average score on this problem was 67%.

Answer (z): (fruits.get("pounds") * 16)

Price per ounce = (total price) / (number of ounces). The "pounds" column is in pounds, so we convert to ounces by multiplying by 16, since each pound is 16 ounces.

Common mistakes:

  • Forgetting the parentheses. Python does division and multiplication from left to right, so fruits.get("price") / fruits.get("pounds") * 16 computes (price / pounds) × 16. That’s 16 times the price per pound, the opposite of what we want. The parentheses make Python find the number of ounces first.
  • Dividing by 16 instead of multiplying. fruits.get("pounds") / 16 converts in the wrong direction.

Difficulty: ⭐️⭐️⭐️⭐️

The average score on this problem was 43%.


Problem 4.2

Write a line of code that evaluates to the amount of money, in dollars, that Ashley spent on fruit at the grocery store.

Answer: fruits.get("price").sum() or sum(fruits.get("price"))

Each row’s "price" is the amount Ashley spent on that fruit, so her total spending is the sum of the "price" column. First get the column with fruits.get("price"), then add up its values, either with the .sum() method or the sum() function.

Common mistakes:

  • Using "price_per_ounce". Summing prices per ounce doesn’t give a total amount of money, because each fruit was bought in a different quantity. "price" is already the total spent on each fruit.
  • Using .count() instead of .sum(). .count() gives the number of fruits, not the total price.
  • Writing fruits.sum(). This sums every column of the DataFrame, not just "price", so it doesn’t evaluate to a single number.

Difficulty: ⭐️⭐️⭐️

The average score on this problem was 62%.


Problem 4.3

Fill in the blanks so that the expression below evaluates to the name of the fruit with the highest price per ounce.

    (fruits.sort_values(by = "price_per_ounce", ascending = __(x)__)
           .get(__(y)__).iloc[0])

Answer (x): False

The expression ends with .iloc[0], which takes the first element. For the fruit with the highest price per ounce to come first, we need to sort from largest to smallest, which is ascending = False.

Using .iloc[0] gives the fruit with the lowest price per ounce.


Difficulty: ⭐️⭐️

The average score on this problem was 87%.

Answer (y): "fruit"

The question asks for the fruit’s name, which is in the "fruit" column. After sorting, .get("fruit") takes that column, and .iloc[0] takes the name in the first row.

Common mistakes:

  • .get("price_per_ounce") gives the highest price per ounce value, not the name of the fruit.

Difficulty: ⭐️⭐️⭐️

The average score on this problem was 65%.


Problem 4.4

Assuming that "mango" is one of the fruits Ashley bought, fill in the blanks so that the expression below evaluates to the price per ounce of "mango".

    fruits.__(x)__("fruit").get("price_per_ounce").__(y)__["mango"]

Answer (x): set_index

To look up a row by the fruit’s name, the fruit names need to be the index (the row labels). .set_index("fruit") moves the "fruit" column into the index, so each row is labeled by its fruit name instead of a number. This works because the problem says all values in "fruit" are distinct, so each label refers to exactly one row.

A common mistake is to try sort_values or get here. Neither of these changes the row labels, so you still can’t look rows up by name afterward.


Difficulty: ⭐️⭐️⭐️⭐️

The average score on this problem was 41%.

Answer (y): loc

After .get("price_per_ounce"), we have a Series of prices per ounce whose index is the fruit names. .loc["mango"] looks up the value whose label is "mango".

The common mistake is using .iloc instead. .iloc looks up by integer position (0, 1, 2, …), so .iloc["mango"] errors.


Difficulty: ⭐️⭐️

The average score on this problem was 83%.



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