PROBLEM SET 7: WORKING 9 TO 5 | SOLUTION (CS50 PYTHON)

preview_player
Показать описание


––– DISCLAIMER –––

The following videos are for educational purposes only. Cheating or any other activities are highly discouraged!! Using another person’s code breaks the academic honesty guidelines. This solution is for those who have finished the problem sets and want to watch for educational purposes, learning experience, and exploring alternative ways to approach problems and is NOT meant for those actively doing the problem sets. All problem sets presented in this video are owned by Harvard University.

–––
Рекомендации по теме
Комментарии
Автор

These videos are keeping me going with course. LIFE SAVER!! Seems like I need a little something here or there. With this problem set, I didn't understand how to run the if statement for if there was no value for minutes. Had my program running fine except for that. Also, I forgotten how to raise ValueError. Thanks so much!!!

If I didn't have these videos, I think I would've given up a long time ago. THANKS!!!

kwadjoglenn
Автор

Hi Giovanna, I'm not sure if you will see this but I want to say thank you for putting so much effort into your videos, especially the editing when explaining a function.

floppa.floa
Автор

Thanks you so much for awesome video. I have stuck for a little thing and got the idea to resolve the issue. I have been breaking my head to resolve the problem. What a time saver!!! It is refreshing to see how the other folks have been trying to resolve the same issue with a different technique.

alo
Автор

For those having the same error as me: When you raise the value the ValueError you dont catch it when you call the function. Just let the terminal show all the errors.

danielperry
Автор

Thanks for the videos. I've seen some really different ways to do the same problems that I have and it's interesting and cool to know that's an option.

The assignments got so much easier after this one lol. I hated regex initially but I don't mind it now.

ProfShibe
Автор

My code is super long, but Im glad i did it in a few hours. Still needs a lot of reworking.
My Code:

import re
import sys

the_finale_list = list()

time_table_PM = {"1":"13:00", "2":"14:00", "3":"15:00", "4":"16:00", "5":"17:00", "6":"18:00", "7":"19:00", "8":"20:00", "9":"21:00", "10":"22:00", "11":"23:00", "12":"12:00"}
time_table_PM2 = {"1":"13", "2":"14", "3":"15", "4":"16", "5":"17", "6":"18", "7":"19", "8":"20", "9":"21", "10":"22", "11":"23", "12":"12"}
time_table_AM = {"12":"00:00", "2":"02:00", "3":"03:00", "4":"04:00", "5":"05:00", "6":"06:00", "7":"07:00", "8":"08:00", "9":"09:00", "10":"10:00", "11":"11:00", "00":"12:00"}
time_table_AM2 = {"12":"00", "2":"02", "3":"03", "4":"04", "5":"05", "6":"06", "7":"07", "8":"08", "9":"09", "10":"10", "11":"11", "0":"12"}
def main():
print(convert(input("Hours: ")))


def convert(s):
time = re.findall('([\d]+.*).*to.(.*[\d]+.*)', s)
if not time:
raise ValueError
for a, b in time:
newa = ("".join(a)).strip()
newb = ("".join(b)).strip()

if "AM" in newa:
if ":" in newa:
the_time = newa.split(" ")
h_and_m = the_time[0].split(":")
hours = h_and_m[0]
minutes = h_and_m[1]
if int(minutes) > 59:
raise ValueError
elif " " not in newa:
raise ValueError
elif minutes != "00":

else:


if ":" not in newa:
if " " not in newa:
raise ValueError
the_time = newa.split(" ")
if the_time[0] in time_table_PM:

elif "AM" not in newa and "PM" not in newa:
raise ValueError

if "PM" in newa:
if ":" in newa:
the_time = newa.split(" ")
h_and_m = the_time[0].split(":")
hours = h_and_m[0]
minutes = h_and_m[1]
if int(minutes) > 59:
raise ValueError
elif minutes != "00":

else:


if ":" not in newa:
if " " not in newa:
raise ValueError
the_time = newa.split(" ")
if the_time[0] in time_table_PM:

elif "AM" not in newa and "PM" not in newa:
raise ValueError

if "AM" in newb:
if ":" in newb:
the_time = newb.split(" ")
h_and_m = the_time[0].split(":")
hours = h_and_m[0]
minutes = h_and_m[1]
if int(minutes) > 59:
raise ValueError
elif " " not in newa:
raise ValueError
elif minutes != "00":


else:


if ":" not in newb:
if " " not in newb:
raise ValueError
the_time = newb.split(" ")
if the_time[0] in time_table_PM:

elif "AM" not in newa and "PM" not in newa:
raise ValueError

if "PM" in newb:
if ":" in newb:
the_time = newb.split(" ")
h_and_m = the_time[0].split(":")
hours = h_and_m[0]
minutes = h_and_m[1]
if int(minutes) > 59:
raise ValueError
elif minutes != "00":

else:

if ":" not in newb:
if " " not in newb:
raise ValueError
the_time = newb.split(" ")
if the_time[0] in time_table_PM:

elif "AM" not in newa and "PM" not in newa:
raise ValueError

the_list = " to ".join(the_finale_list)
return the_list

if __name__ == "__main__":
main()

niva
Автор

Does any of the code versions offered here address not raising an error when the user types smth like 122 AM to 233 PM? Since the : is optional, the code returns 01:22 to 2:33 where it should be a ValueError. The task does not offer to assume the user will always put the : when inputting times...

victorialauri
Автор

Initially I thought that my code is ugly and overcomplicated, but looking at comments.... Writing this code took me like 30 mins and it is very simple (code itself and the problem if u take approach like me). It could be re written by implementing second function, so it looks nice, but I just wanted to share a very very simple approach to this problem


import re


def main():
print(convert(input("Hours: ")))


def convert(s):
matches = re.search(
r"^(\d[1-2]?):?([0-5][0-9])? (AM|PM) to (\d[1-2]?):?([0-5][0-9])? (AM|PM)$", s
)
if matches:
groups = matches.groups()
if groups[2] == "PM":
hours1 = int(groups[0]) + 12
else:
if int(groups[0]) <= 9:
hours1 = f"0{groups[0]}"
else:
hours1 = f"{groups[0]}"
if groups[5] == "PM":
hours2 = int(groups[3]) + 12
else:
if int(groups[3]) <= 9:
hours2 = f"0{groups[3]}"
else:
hours2 = f"{groups[3]}"
if groups[1] == None:
minutes1 = "00"
else:
minutes1 = groups[1]
if groups[4] == None:
minutes2 = "00"
else:
minutes2 = groups[4]
if groups[0] == "12":
if groups[2] == "AM":
hours1 = "00"
else:
hours1 = "12"
if groups[3] == "12":
if groups[5] == "AM":
hours2 = "00"
else:
hours2 = "12"

return f"{hours1}:{minutes1} to {hours2}:{minutes2}"
else:
raise ValueError("Wrong")


if __name__ == "__main__":
main()

nostalgiez
Автор

Your help lubricates things when check50 feels like a pain in the ass :)

raccess
Автор

Here is how I solved this, hope it helps:

import re

# MAIN FUNCTION #

def main():
print(convert(input("Hours: ")))


# CONVERT HOURS #


def convert_hours(h, am_pm):
# return (h+12) if it is "PM" and but not 12 PM:
if am_pm == "PM" and int(h) != 12:
return (int(h) + 12)

# return 0 if it is 12 AM:
elif am_pm == "AM" and int(h) == 12:
return 0

# otherwise if it is not PM, or not 12 AM or PM, return 'h' as it is:
return h


# CONVERT FUNCTION #


def convert(s):
# find matches to the pattern, "?P<h1>" represents the capture group which is quantity of hour of first time:
matches = re.search(r"^(?P<h1>\d{1, 2})(:| )(?P<m1>\d{2})? ?(?P<am_pm1>\w{2}) to (?P<h2>\d{1, 2})(:| )(?P<m2>\d{2})? ?(?P<am_pm2>\w{2})", s)

# detect early and raise ValueError if there is no matches:
if matches is None:
raise ValueError

h1 = matches.group("h1")
h2 = matches.group("h2")
m1 = matches.group("m1")
m2 = matches.group("m2")
am_pm1 = matches.group("am_pm1")
am_pm2 = matches.group("am_pm2")

try:
# check if both hours are valid, else raise Value Error:
if 1 <= int(h1) <= 12 and 1 <= int(h2) <= 12:

# check if AM or PM are present, else raise Value Error:
if am_pm1 and am_pm2 in ["AM", "PM"]:

# if both minute values exist, check that they are in range (between 0 & 59) if they both exist (e.g. 9:"30" AM, 12:"45" PM)
if m1 != None and m2 != None and 0 <= int(m1) <= 59 and 0 <= int(m2) <= 59:

# pass h1 and h2 to the function created before:
h1 = convert_hours(h1, am_pm1)
h2 = convert_hours(h2, am_pm2)

return f"{int(h1):02}:{m1:02} to {int(h2):02}:{m2:02}"

# if m1 doesn't exist and m2 does, check if m2 is in range (e.g. 9 AM to 5:30 PM):
elif m1 == None and m2 != None and 0 <= int(m2) <= 59:
h1 = convert_hours(h1, am_pm1)
h2 = convert_hours(h2, am_pm2)
return f"{int(h1):02}:00 to {int(h2):02}:{m2:02}"

# if m1 exists and m2 doesn't, check if m1 is in range (e.g. 9:30 AM to 5 PM):
elif m1 != None and m2 == None and 0 <= int(m1) <= 59:
h1 = convert_hours(h1, am_pm1)
h2 = convert_hours(h2, am_pm2)
return f"{int(h1):02}:{m1:02} to {int(h2):02}:00"

# if m1 and m2 don't exist (e.g. 9 AM to 5 PM):
elif m1 == None and m2 == None:
h1 = convert_hours(h1, am_pm1)
h2 = convert_hours(h2, am_pm2)
return f"{int(h1):02}:00 to {int(h2):02}:00"

else:
raise ValueError

else:
raise ValueError

else:
raise ValueError

except:
raise ValueError


# CALL MAIN #

if __name__ == "__main__":
main()

# END #

mukulparashar
Автор

thx a lot. A quick tip, do not import functions like new_format in the test_working.py

yangsong
Автор

in Your code You should change the regex for hour count to -- > : (([\d][\d]?) - in this case it accept hours from 0 to 99 and than the piece of code where you check whether the time is less than 12 is useful - otherwise you can delete it

and
Автор

My solution of using a dictionary to capture the data:
...

import re
import sys


def main():
print(convert(input("Hours: ")))


#9 AM to 5 P | 9:00 AM to 5:00 PM
#12 AM to 12 PM >> 00:00 to 12:00
def convert(s):
if matches_short := re.search(r"^(\d+) (AM|PM) to (\d+) (PM|AM)", s):
hours_from, p_from, hours_to, p_to = matches_short.groups()

return format24(hours_from, hours_to, p_from, p_to)

elif matches_full := re.search(r"^(\d+):(\d+) (AM|PM) to (\d+):(\d+) (PM|AM)", s):
hours_from, minutes_from, p_from, hours_to, minutes_to, p_to = matches_full.groups()

return format24(hours_from, hours_to, p_from, p_to, minutes_from, minutes_to)
else:
raise ValueError
#sys.exit("Unmatched")

def format24(hoursF, hoursT, partF, partT, minF="00", minT="00"):
#hours format
if int(hoursF) and int(hoursT) not in list(range(13)):
raise ValueError
elif int(minF) and int(minT) not in list(range(60)):
raise ValueError

#create a dictionary
set_dict = {
"daytime" : partF,
"hours" : hoursF,
"minutes" : minF}, {
"daytime": partT,
"hours": hoursT,
"minutes": minT
}
#print(set_dict)

for set in set_dict:
#convert 12 to 24
if set["daytime"] == "PM" and set["hours"] != "12":
set["hours"] = int(set["hours"]) + 12

#exception
if set["daytime"] == "AM" and set["hours"] == "12":
set["hours"] = "0"

#print(set_dict)

hours_from = str(set_dict[0]["hours"])
hours_to = str(set_dict[1]["hours"])

return to {hours_to.zfill(2)}:{minT}"


if __name__ == "__main__":
main()

kyrylldmytrenko
Автор

One of the hardest exercises no doubt. Finally did it. Here's my solution:
import re
import sys


def main():
print(convert(input("Hours: ")))


def convert(s):
if matches := (AM|PM) to (AM|PM)$", s):
start_hour = int(matches.group(1))
start_minutes = matches.group(2)
start_meridiem = matches.group(3)
finish_hour= int(matches.group(4))
finish_minutes = matches.group(5)
finish_meridiem = matches.group(6)

if start_meridiem == "PM" and start_hour !=12:
start_hour = int(start_hour)+12
if start_meridiem == "AM" and start_hour==12:
start_hour="00"
if finish_meridiem == "PM" and finish_hour!=12:
finish_hour = int(finish_hour)+12
if finish_meridiem == "AM" and finish_hour==12:
finish_hour=str(0)
if start_minutes:
return to
else:
return (f"{start_hour:02}:00 to {finish_hour:02}:00")

else:
raise ValueError


if __name__ == "__main__":
main()

alanmunoz
Автор

I HAVE FINALLY DONE IT AFTER TWO DAYS


import re
import sys

def main():
print(convert(input("Hours: ")))

def convert(s):
if match := (AM|PM)) to (AM|PM))", s):
start = match.group(1)
end = match.group(6)

# Start time
if "AM" in start:
if int(match.group(2)) == 12:
hour1 = int(match.group(2)) - 12
else:
hour1 = int(match.group(2))
else:
if int(match.group(2)) == 12:
hour1 = int(match.group(2))
else:
hour1 = int(match.group(2)) + 12
if match.group(3):
time1 =
else:
time1 = f"{hour1:02}:00"

# End time
if "AM" in end:
if int(match.group(7)) == 12:
hour2 = int(match.group(7)) - 12
else:
hour2 = int(match.group(7))
else:
if int(match.group(7)) == 12:
hour2 = int(match.group(7))
else:
hour2 = int(match.group(7)) + 12
if match.group(8):
time2 =
else:
time2 = f"{hour2:02}:00"
return f"{time1} to {time2}"
else:
raise ValueError

if __name__ == "__main__":
main()

shirshxk
Автор

when i submit, the other file test_working isnot sumit . Is it normal?

aureladissin
Автор

After writing my code I thought my code was maybe excessively lengthy but after checking a lot of comments here, I think it's pretty fine after taking around an hour for it. Here's my code:
def convert(s):
if matches := (AM|PM) to ([0-9]+):?([0-5][0-9])? (AM|PM)$", s):
hour = []
minutes = []
for i in [0, 3]:
if int(matches.group(i+1)) <=12:
if matches.group(i+3) == "PM":
if int(matches.group(i+1)) <= 11:
n_hour = int(matches.group(i+1)) + 12
else:
n_hour = int(matches.group(i+1))
else:
if int(matches.group(i+1)) == 12:
n_hour = int(matches.group(i+1)) - 12
else:
n_hour = int(matches.group(i+1))
hour.append(n_hour)
if matches.group(i+2) == None:
n_min = int(0)
else:
n_min = int(matches.group(i+2))
minutes.append(n_min)
else:
raise ValueError
vakt = to
return vakt
else:
raise ValueError

sakethreddyburugu
Автор

I wrote this problem so that convert() received an already split string. so instead of "12 AM to 5PM" convert was receiving "12 AM" and "5 PM" separately. The program is fully functional, but check 50 HATES it. first half all green, but second half not. So I have to rewrite. Sad because I felt so confident writing the whole program and tests, only for check50 to not accept it. Hopefully this helps someone suffering a similar problem!

jaedonthompson
Автор

My code looks damn messy!
here it is....


import re
import sys

def main():
print(convert(input("Hours: ")))

def convert(s):
try:
if matches := re.search(r"(\d+):?(\d+)? (AM|PM) to (\d+):?(\d+)? (AM|PM)", s):
a, b, c = matches.group(1, 2, 3)
x, y, z = matches.group(4, 5, 6)
if int(a) <= 12 and c == "AM":
if int(a) == 12:
if b == None:
time1 = f"{0:02}:{0:02}"
elif int(b) < 60:
time1 = f"{0:02}:{b}"
else:
raise ValueError
elif int(a) != 12:
if b == None:
if int(a) < 10:
time1 = f"0{a}:{0:02}"
else:
time1 = f"{a}:{0:02}"
elif int(b) < 60:
if int(a) < 10:
time1 = f"0{a}:{b}"
else:
time1 = f"{a}:{b}"
else:
raise ValueError
elif int(a) <= 12 and c == "PM":
if int(a) == 12:
if b == None:
time1 = f"{a}:{0:02}"
elif int(b) < 60:
time1 = f"{a}:{b}"
else:
raise ValueError
elif int(a) != 12:
if b == None:
if int(a) < 10:
time1 = f"0{a}:{0:02}"
else:
time1 = f"{a}:{0:02}"
elif int(b) < 60:
if int(a) < 10:
time1 = f"0{a}:{b}"
else:
time1 = f"{a}:{b}"
else:
raise ValueError

if int(x) <= 12 and z == "AM":
if int(x) == 12:
if y == None:
time2 = f"{0:02}:{0:02}"
elif int(y) < 60:
time2 = f"{0:02}:{y}"
else:
raise ValueError
elif int(x) != 12:
if y == None:
if int(x) < 10:
time1 = f"0{x}:{0:02}"
else:
time1 = f"{x}:{0:02}"
elif int(y) < 60:
if int(x) < 10:
time1 = f"0{x}:{y}"
else:
time1 = f"{x}:{y}"
else:
raise ValueError

elif int(x) <= 12 and z == "PM":
if int(x) == 12:
if y == None:
time2 = f"{x}:{0:02}"
elif int(y) < 60:
time2 = f"{x}:{y}"
else:
raise ValueError
elif int(x) != 12:
if y == None:
x = int(x) + 12
time2 = f"{x}:{0:02}"
elif int(y) < 60:
x = int(x) + 12
time2 = f"{x}:{y}"
else:
raise ValueError

return f"{time1} to {time2} "
else:
raise ValueError

else:
raise ValueError

except ValueError:
sys.exit("ValueError")

if __name__ == "__main__":
main()

brannstrom
Автор

Doing this ex I realized 12:00 AM is midnight and not 12:00 PM 🙄

massimotarsitani