DEV Community

Cover image for Solving the Problem Sets of CS50's Introduction to Programming with Python — One at a Time: Problem Set 3

Solving the Problem Sets of CS50's Introduction to Programming with Python — One at a Time: Problem Set 3

Eda on April 26, 2022

Read the original blog post here. On this week's problem set on Exceptions, we are given four problems this time, instead of five. Th...
Collapse
 
heyandre profile image
Andre Castro

That's really cool and helpful what you are doing. I'm now actually stuck in the Fuel gauge from PSET3

Collapse
 
rivea0 profile image
Eda

Thank you!
Fuel Gauge is an interesting one indeed. You can take a similar approach as the example given in the lecture. The whole try...except block can be put inside an infinite loop, and once you split the input and got the two numbers as integers, the result is simply x * (100 / y). After getting the result, we want to check if that result is more than 99 or less than 1 as long as x is less than or equal to y. If it is more than 99, we return with F, and if it is less than 1 we return with E. (Or, if you did not use a function, just break out of the loop). If none of these conditions are true, and you don't even need an else here, just return the result as a formatted string. And we can just handle the exceptions with pass. Hope this helps!

Collapse
 
heyandre profile image
Andre Castro

Thats exactly how i have done... I wrapped try...except in a while True loop and inside that after input I did an if statement and everything returns fine except that the loop keeps asking, never stops asking... Im using break after if, after elif after else...Also 4 of the checks is not passing as green

I get the following errors when checking...

:( input of 3/4 yields output of 75%
Did not find "75%" in "75%\r\nFractio..."
:( input of 503/1000 yields output of 50%
timed out while waiting for program to exit
:( input of three/four results in reprompt
expected program to reject input, but it did not
:( input of 1.5/4 results in reprompt
expected program to reject input, but it did not
:( input of 3/5.5 results in reprompt
expected program to reject input, but it did not
:( input of 5-10 results in reprompt
expected program to reject input, but it did not

Thread Thread
 
heyandre profile image
Andre Castro

I just fixed it...Passed all checks...I realised my input was before try: and after while True....I had to put inside try:

Thread Thread
 
heyandre profile image
Andre Castro

I just wanted to ask something if I may... For the input initially I wasn't sure how I could input 2 numbers and make it work like a division...so I researched and came across this method:

a, b = [int(a) for a in input("Fraction: ").split('/')]

I get most part of it...

a and b are variables where the input is stored...

int(a) converts the input to a number ... but how about b?

for a in input .... not quite sure about this part?

.split('/') splits the string in 2 string values

[ ] I guess by using these brackets we want to store it as a dictionary but for what? for the loop to work?

If you could clarify my questions I would really appreciate...
Many thanks

Thread Thread
 
rivea0 profile image
Eda • Edited

int(a) converts the input to a number ... but how about b?

This piece of code (a, b = [int(a) for a in input("Fraction: ").split('/')]) is actually a list comprehension — one of my favorites of Python. It is just a more elegant, and "pythonic" way to write for loops. Here, it asks for an input, and splits it with /, then it puts the values (converted to integers) inside a list. Then it unpacks the list with assigning the two values into variables a and b. Literally the same as this:

values = []
for a in input('Fraction: ').split('/'):
    values.append(int(a))
a = values[0]
b = values[1]
Enter fullscreen mode Exit fullscreen mode

So, the a inside the list is different from a the variable that the first value is assigned to. Giving them the same name is not a good practice in my opinion. You can change that name and it does not matter, for example, a, b = [int(x) for x in input("Fraction: ").split('/')] gives the same output.

W3Schools has a basic explanation on how list comprehensions work. You can also read about them from the official docs.

Glad you passed the tests. The whole aim of the infinite loop is just to keep getting input, but using that list comprehension example inside an infinite loop would continue asking for an input forever and keep adding the results into a list, so it wouldn't work. I think it's better to convert the values after you got the input, but it really depends on how you would like to implement it.

Thread Thread
 
heyandre profile image
Andre Castro

Thanks a lot for the clear explanation...

Collapse
 
heyandre profile image
Andre Castro • Edited

Now Im nearly done with the taqueria, but it gives me 1 error... saying input of burger leads to reprompt and is expected to reject

the structure of my code is...

variable to count the total

try statement...

inside try is the dictionary

then is the while True followed by a for loop
with break just before the except statement

except statement...
with pass inside

Collapse
 
heyandre profile image
Andre Castro

Nevermind... I actually fixed it... was due to the except statements... I was putting both errors under one except statement and check50 expects different behaviours for each error...so i just separated by having 2 except statements, one with pass and other with break

Collapse
 
rivea0 profile image
Eda

I have just seen your comment, glad you fixed it! I've also come across timeout errors with the new problem set, I guess it happens when try...except block or a loop is suffocated with many things at once and cannot exit the program properly.

Thread Thread
 
heyandre profile image
Andre Castro

Now, I'm nearly done with the grocery problem, but I just need to for example, if i input Apple Orange at the same time to print in separate lines...It prints in separate lines if I type Apple then enter, Orange then enter... but if I type Apple Orange then enter prints one next to the other...

Thread Thread
 
rivea0 profile image
Eda

Not sure if I understand it correctly, but shouldn't you enter each item separately anyway? Like the example I give in this article, Accio, Lumos, etc. all inputted one by one. So if you put two items as one input, it is going to be stored as such.

Thread Thread
 
heyandre profile image
Andre Castro • Edited

If i input one by one my code works correctly although I only get 2 green checks that the file exists and the one handling the EO error... the other errors are all the same:

:( input of "apple" and "banana" yields "1 APPLE 1 BANANA"
expected "1 APPLE\n1 BAN...", not "Input: 1 APPLE..."
:( input of "strawberry" and "strawberry" yields "2 STRAWBERRY"
expected "2 STRAWBERRY", not "Input: 1 STRAW..."
:( input of "mango", "sugar", and "mango" yields "2 MANGO 1 SUGAR"
expected "2 MANGO\n1 SUG...", not "Input: 1 MANGO..."
:( input of "tortilla" and "sweet potato" yields "1 SWEET POTATO 1 TORTILLA"
expected "1 SWEET POTATO...", not "Input: 1 TORTI..."

below is a example of my logic...

dictionary = {} 

while True:
     user_input = input("Input: ")

     dictionary[user_input] = dictionary.get(user_input, 0) + 1

     for key, value in sorted(dictionary.items()):
          print(f"{value} {key.upper()}", end=" ")
          print("\n")
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
rivea0 profile image
Eda

I implemented it with the same logic as well. But, you need to wrap everything inside a try...except block. Like, you can try to get the input and put it inside the dictionary; and only inside except EOFError you can do the for loop and printing. Also, I don't think you need to specify end inside the first print function and then print a newline. Just print(f"{value} {key.upper()})" will be going to provide a new line after each time by default, so you do not need to do anything else.

Thread Thread
 
heyandre profile image
Andre Castro

Ye I have everything wrapped inside try...except block, just didnt include that in the code I wrote here...

Thread Thread
 
heyandre profile image
Andre Castro • Edited

Amazing! I fixed it! Thanks a lot for the tip...I was around and around trying new ways and would never have guessed that the for loop should be inside the except. I even tried import sys and use sys.stdin.read().split("\n") and was working as expected, but couldn't get green checks, only yellow checks ...anyway, now looking through the code and thinking about the logic makes perfect sense...Thanks a lot! Onto the next one :)

Thread Thread
 
rivea0 profile image
Eda

Congrats! We only need to print everything after the user hits control-d (resulting in EOFError), so it makes sense to put it inside the except. It's absolutely great to see that helped!

Collapse
 
aristhera profile image
Gebhard • Edited

Hi @ all, I just started with outdated. I was wondering how to catch an out of range error for DD > 31 or MM > 12. I thought first splitting the user input into variables like a, b, c = input.split('/') like we're told in the hints, then converting to integers by using the modulus operator, e.g.
a, b, c = int(a) % 12, int(b) % 31, int(c). Is that alright or am I obliged to raise an exception?

Collapse
 
rivea0 profile image
Eda

Hello Gebhard,

It seems that dev.to has an issue with notifications for comments on original content, I haven't seen yours until I have just encountered it, I really apologize for the inconvenience of the delay.

You've probably already had an answer to your question by now, but I still wanted to reply.

I don't think there is any need to convert the variables to integers while splitting. A simple conditional was enough in my solution to check if the values were not out of range, and since the output was going to be a string, you could just
convert them to integers for the conditional, with something like if 0 < int(day) < 32 and 0 < int(month) < 13. I don't think it would require raising an exception here, we could just raise a ValueError for the input itself if it was faulty.

Again, I apologize for the long-delayed response, hope you're doing well.

Collapse
 
aristhera profile image
Gebhard

Hi Eda, yes I know that, happens to me all the time (overlooking messages). Don't worry about it, hope you're doing well, too

Collapse
 
aturysbekova profile image
aturysbekova

can you guys share "outdated" code please?