Practice problems about dictionaries and frequency tables for mission 5 from Python for Data Science Fundamentals course

I got stock with this practice problem, I understand what is required from the question, but I do not understand the steps taken to solve the problem. Please it need it explained thoroughly to better grasp what the lines of code in the solution mean.

Screen Link: https://app.dataquest.io/m/1011/python-fundamentals-practice-problems/12/laptop-purchase

Solution Code: <–>

from csv import reader
file = open('laptops.csv')
read_file = reader(file)

rows = list(read_file)[1:]

# create the dictionary mapping the prices to the laptop names
price_to_name = {}

for row in rows:
    price = int(row[2])
    name = row[1]
    if price in price_to_name:
        price_to_name[price].append(name)
    else:
        price_to_name[price] = [name]

# intitialize the two laptops in the answer to None
laptop1 = None
laptop2 = None
# look for a solution
for row in rows:
    price = int(row[2])
    # this laptop's cost is price, so if there is a laptop that costs 5000, then their total price is exactly 5000
    if price == 2500 and len(price_to_name[2500]) >= 2:
        laptop1 = price_to_name[2500][0]
        laptop2 = price_to_name[2500][1]
    elif 5000 - price in price_to_name:
        laptop1 = price_to_name[price][0]
        laptop2 = price_to_name[5000 - price][0]
        print(price)
#print the solution
print(laptop1)
print(laptop2)

Instead of explaining to you what it does, I want you to spend time trying to understanding the code yourself.

Go through each line of code, and understand what it does.

rows = list(read_file)[1:]
  • Print out rows and see what it contains
  • Ignore everything else, except based on what you saw from printing rows, see what row should contain.

  • After you have an answer for the above, print out row in that loop, and see what you get for that print statement.

  • From the above, check what row[2] and row[1] would be for each row in rows. If you are unsure, print those out.

  • By now, you should know what price and name contain.

  • Think about what if price in price_to_name: statement is about.

    • If you are confused about this, then go back to the Missions which cover if and dictionaries in Python.
    • Make sure you understand what this statement does before moving on. You should be absolutely sure of what it’s checking for. Specifically the price in price_to_name part.
  • price_to_name[price].append(name)

    • To understand this, you should know how dictionaries in Python work. If you are not clear on that, you should go back to the Missions that teach dictionaries.
    • Print out price_to_name[price] and see what it contains. Focus on what it is. Hint: Is the output of this print statement an integer? A string? Anything else?
    • Think about what you have studied so far in Python that can use append(). Take your time with this. If you can’t figure it out. Just google “python append” and see what comes up.
    • Put the pieces from the above steps together. What does price_to_name[price].append(name) do?
    • At this stage, print out price_to_name[price] again. See what changes before and after the append
  • Think about the else statement in comparison to the if statement. What did that if statement do? So, what will that else statement do now? Make sure you understand this step before moving on.

  • Knowing what else is about, knowing how dictionaries work, think about what price_to_name[price] = [name] will do.

    • Just like before, think about what price_to_name[price] should contain.
    • Based on the above, think about what name contains.
    • Based on the above two, think about why name is being put into a list, that is, why we are doing [name] here.

The above is a LOT of steps and might feel overwhelming. But the point is, if you don’t break the above down like I have tried to, you might continue to struggle with understanding what every piece of code you come across does. It’s easy to ask someone to explain this to you. It’s difficult but important to get into the habit of understanding it yourself.

Reading, understanding, debugging code is important. So, start with the above.

  1. When you add print statements, you might see a LOT of output. So, narrow down the problem. In your for loop, instead of iterating over all the rows, you can iterate over a very small number of them. Use indexing and slicing to your advantage -
for row in rows[0:5]:

Because of the rows[0:5], you will only loop through 5 rows. Makes it simpler to understand what’s happening when you print things out. Lower or increase that number (5) as it suits you.

  1. If after following the above steps you get confused and stuck AND if you have gone through the Missions that explain those concepts again, then ask specific questions about where you got stuck.

Once you have done the above, we will move on to the next part of the solution.

4 Likes

Thank you for taking the time to help break the parts down. Putting the name in the list really got me confused but I’ll look deeply into this to better understand it and all the other areas that are foggy. I’ll return with a feedback. Thanks.

1 Like

So, I’ve understood what the first part of the program does.
First part (first for loop)
In order to create the frequency table (price_to_name) that maps prices to the names of laptops.

  1. A for loop is created, prices and names are extracted.
  2. in the else statement, price is mapped to name (name is put in a list) because, more than one laptop can have the same price, with a list in place, additional laptops names can be added to the list and that is the role of the if statement - it basically appends/adds the laptops that have the same price to the existing list.
    So, the first for loops basically creates the frequency table which is useful in the second for loop .
    Second part (second for loop)
  3. Loop through the dataset and get the prices.
  4. if the laptops that cost 2500 are 2 or more in number, assign them to laptop1 and laptop2 then buy both.
    Questions:
  5. In the second for loop. Do all the rows in the data set run in the if statement before they begin to run in the elif statement? or does the row instances run in the if statement then if the condition is not met, moves to the elif statement?
  6. I did not understand the logic behind the elif statement.
    Observations:
  7. The program runs fine without assigning None to laptop1 and laptop 2, then why include it?
  8. In the if statement, price == 2500, the program runs well without that part, why include it?
if condition1:
    do_something_1
elif condition2:
    do_something_2

If condition1 is True, then do_something_1 will run. If condition1 is False, then we check if condition2 is true or not.

elif only runs if the previous if (or elif) condition was False.

For elif in general or for the following code?

elif 5000 - price in price_to_name:

In this particular case, it’s not required.

Because of the problem statement itself.

We want to find laptops whose price sum is 5000$. There are two ways to do this -

  1. We look for laptops which are exactly 2500 in price. So, 2 of those laptops will have a total price of 5000$. This is the first if statement.
  2. We need the total cost to be 5000. So, we check for the keys in the dictionary that are (5000 - the current laptop’s price). This way we will get the laptops we need. This is the elif.

The if works when you remove price == 2500 because the dataset itself does not have any prices for laptops that add up to 5000 exactly except the ones whose price is 2500.

So, when you remove price == 2500, you are left with len(price_to_name[2500]) >= 2. That’s the values in the dictionary which store the laptop names in a list, where the number of laptop names in each list is greater than or equal to 2. len(price_to_name[2500]) >= 2 will return a lot of such lists.

Out of all those lists, they specifically get the names corresponding to the price 2500.

laptop1 = price_to_name[2500][0]
laptop2 = price_to_name[2500][1]

So, that’s why it runs without issue. The dataset is sort of “limited” given the task. Their code is suitable for a more general approach to solve that task, but it can be slightly improved upon as well, as per me.

1 Like

Thanks for your help.