👨💻 Learn How to Code with Private Classes - www.dorscodingschool.com/coachingplans ❓Having a hard time with CS50, FreeCodeCamp or Odin Project? Practice with our exclusive free coding platform: www.codingdors.com/ 🎯 Are You A Coding Expert? Take Our Free Quiz and Find Out - www.dorscodingschool.com/quiz
@Pnigro2 жыл бұрын
No need to use regular expressions. Date comes with a fromisoformat() method.
@Alex431984 ай бұрын
from isoformat method allows date formats either than YYYY-MM-DD
@ismailhossain9643 ай бұрын
Exactly my point. We should ignore re whenever its possible.
@codegarden8765 Жыл бұрын
I really wanted to use classes for this assignment since that is what the lecture was about. I commented out the body of my functions, so here's the bare-bones structure of my solution. Both the solution and the test file passed btw. As for testing stuff, I found pytest's @pytest.fixture decorator for setting up, monkeypatch for mocking user input action, and with pytest.raises(SystemExit) for raising specific exceptions useful. from datetime import date, datetime import inflect import sys import re p = inflect.engine() class Time: def __init__(self, target_date): self.target_date = target_date def __str__(self): # prints out the output at the end # operator overload def __sub__(self, other): # perform the subtraction and return the result @staticmethod def validate_date(target_date): # use regex to validate the proper format # return boolean (true if the match is found, false otherwise) @classmethod def get(cls): # prompt the user for input # validate the input by calling the static method validate_date and pass the user's input # if valid, pass in that user input the cls, otherwise exit using sys.exit() with an error message # Remember datetime.strptime allows you to turn a string into a DateTime object to make it easier for math operations def main(): then = Time.get() # gets the current date so no need to ask the user now = Time(date.today()) print(now - then) if __name__ == "__main__": main()
@mostafaboras Жыл бұрын
how did you do this!!!
@avnimahajan2266 Жыл бұрын
Can you please share the test code you wrote for this?
@getstart9811 ай бұрын
I already submitted mine without classes but your one looks well organized. like this class approach
@ismailhossain9643 ай бұрын
Omg. So clever.
@kyrylldmytrenko89962 жыл бұрын
Thank you for sharing. Here is one alternative solution: ... If I understood the mechanics behind the date class correctly the function called .fromisoformat does exactly the match and gives year, month, day attributes or raises ValueError it simplifies the code a little bit, with more straight-forward logic > basically in 3 main lines also another one called _total seconds combines all in seconds (also using timedelta as sc50 suggests) - which then should be divided by 60 ofc from datetime import date, timedelta import inflect import sys p = inflect.engine() def main(): birthday = input("Date of Birth: ") minutes = sub_date(birthday) print(convert_totext(minutes)) def sub_date(birth): #take input date try: b = date.fromisoformat(birth) except ValueError: sys.exit("Invalid date type") else: #take current date today = date.today() #substract one from another sub = today - b total = sub.total_seconds() / 60 return round(total) def convert_totext(num): return f"{p.number_to_words(num, andword='')} minutes" if __name__ == "__main__": main()
@WontuNein2 жыл бұрын
I have a solution similar to this, however I have two functions to test in the test file. how would you make a test file if yours all on main? thanks for reading.
@kyrylldmytrenko89962 жыл бұрын
@@WontuNein Main function does not matter in this case (also because it is called by the last lines of __name...) I test only these 2 functions in my test file, they both have return values so it should be ok
@edwincondor469 Жыл бұрын
Thank you very much. I spend hours trying to figure out it. Besides, I have problems to test with pytest, but I saw that someone suggested to use "with pytest.raises(SystemExit): conv_date("January 15, 1980")". I really apreciate all your help.
@cuchum Жыл бұрын
@@edwincondor469 i had the same problems with exceptinon. but i had solved it with your comment.
@sum1asty Жыл бұрын
Just by ur comment i found out that inflect takes andword="" arg. Helped me finish this, didnt notice diffrence in sentence at cs50 check.
@sweetiepiedpiperr6 ай бұрын
Thank you, Giovanna! I also spent too much time on this problem! 😂😂😅
@NepsComsci2 ай бұрын
What?! You didn’t solve it using the OOP concept? Meanwhile, I’m over here struggling to solve it with Classes and Objects! Isn’t that what Lecture 8 / Problem Set 8 is all about?
@JairCPaulo8 күн бұрын
I thought the same thing, but in the end for me it was not making sense to use OOP
@sarahcruz7352 Жыл бұрын
For those of you running into an error, you have to include the following line at the top along with the libraries you're importing: p = inflect.engine()
@alvarobarboza57304 ай бұрын
Thank you Giovanna!
@giannisfilippou74602 жыл бұрын
this is my solution with the use of Classes import sys import re from datetime import datetime, date import inflect p = inflect.engine() class Born: def __init__(self,date,dif): self.date = date def __str__(self): return f"{self.date}" @classmethod def get(cls): birth = input("Birth date: ") check = birth if check := re.search(r"^([0-9]{4})\-([0-9]{2})\-([0-9]{2})$",check): year = int(check.group(1)) month = int(check.group(2)) day = int(check.group(3)) if month
@avnimahajan2266 Жыл бұрын
Can you please share the test case you wrote for this?
@rohith6255 Жыл бұрын
the check50 for me is giving some nonsensetical problems: like it is asking the ouput between random to days not the today's date and birthday date , its giving varied "today's date", why
@desanduwanniarachchi78188 ай бұрын
Yes!!! , It happens to me too, but it's not happening in this videos tests
@srijan57346 ай бұрын
@@desanduwanniarachchi7818 same did u find a solution?
@LuisGaruzBernabeu5 ай бұрын
@@desanduwanniarachchi7818 How did you solved it?
@desanduwanniarachchi78185 ай бұрын
@@LuisGaruzBernabeu unfortunately I didn’t man, I asked it from the discord community of cs50 too. Didn’t get a solution
@PaloumaAlmos4 ай бұрын
@@desanduwanniarachchi7818 any update?
@junivensaavedra8822 жыл бұрын
Superb! thanks for sharing, here's how I did it. :) import sys import inflect from typing import Optional from datetime import datetime, date, timedelta def days_diff(start: date, end: date) -> int: return int((end - start) / timedelta(minutes=1)) def validate_date(date: str) -> Optional[date|bool]: try: return datetime.strptime(date, '%Y-%m-%d').date() except ValueError: return False def number_to_word(days: int) -> str: inf = inflect.engine() return inf.number_to_words(days, andword="") def main() -> None: today = date.today() if date_of_birth := validate_date(input("Date of Birth: ")): print(f"{number_to_word(days_diff(date_of_birth, today)).capitalize()} minutes") else: sys.exit("Invalid date") if __name__ == "__main__": main()
@krishnateja507 ай бұрын
Thank you!
@Samuelson-ts1bz Жыл бұрын
Great, thank you
@acronproject2 жыл бұрын
this is so useful for me. thank you💯
@DorsCodingSchool2 жыл бұрын
You're welcome!
@burakemrepolat7041 Жыл бұрын
I used num2words library and my cs50 check didn't work, but when I used inflect library it worked. Does anyone know why?
@HungryTv13 Жыл бұрын
Because its a third party library and not built into python itself as you need to install it manually. In this lesson it specifies that you can use other libraries but only that are built in python it self.
@hahahaha-bm9xs Жыл бұрын
@@HungryTv13 Inflect is also a third party library which I have to install via pip3. The reason why inflect works is that it is included in the "Hint" section. "You’re welcome to import other (built-in) libraries, or any that are specified in the below hints." I tried to do it without the hint, figured num2words would not work and wasted two hours trying to convert the number into words🗿
@ismailhossain9643 ай бұрын
Probably you did not flag "and" word in the function.
@federicoelevazo36222 жыл бұрын
How about trying to input an invalid date? There is not code to catch those error in your code tho it passes check50. I had them catched by if statements a while back but im not passing the pytest. I even imported calendar module to get the number of days of the specific month.
@DorsCodingSchool2 жыл бұрын
I'm checking this by calling the function check_birthday
@user-sq9wp2ge4h2 жыл бұрын
can be simpler: from datetime import date import sys from datetime import timedelta import inflect bday = input("Date of Birth: ") p=inflect.engine() def main(): try: x,y,z= bday.split("-") birth=date(int(x),int(y),int(z)) except: sys.exit("Invalid date") dif=date.today()-birth letters=p.number_to_words(int(dif.total_seconds()/60), andword="") print(f'{letters.capitalize()} minutes') if __name__=="__main__": main()
@DorsCodingSchool2 жыл бұрын
Great job!
@michaelnunezmd367 Жыл бұрын
@user-sq9wp2ge4h How did you test your code in test_seasons.py?
@jasperlee47502 жыл бұрын
i just ignored my andword="" parameter... no wonder i received few unhappy face in check50 Tks a lot :)
@DorsCodingSchool2 жыл бұрын
Great job!
@dykoyaa39372 жыл бұрын
how did u pass the check50 without using round
@DorsCodingSchool2 жыл бұрын
There are multiple ways of solving this problem :)
@davidparra65732 жыл бұрын
Good help. Although, the code doesn't work if I write for instance "2022-02-31" as the birth date, does it?
@DorsCodingSchool2 жыл бұрын
We’d love to help you more. Did you know you can join our Free Discord Group and get help from me and from people around the world that are also learning how to code? dorscodingschool.com/discord
@cruseder2 Жыл бұрын
Making the test-code took longer than making the actual main-code lol. Here is my solution: --- MAIN CODE --- from datetime import date import sys import inflect def main(): seasons_of_love = calculate_words(input("Date of Birth: ")) print(seasons_of_love.capitalize(), "minutes") def calculate_words(n): try: year, month, day = n.split("-") year = int(year) month = int(month) day = int(day) birthday = date(year, month, day) today = date.today() time_to_birthday = abs(birthday - today) days = time_to_birthday.days minutes = days * 24 * 60 p = inflect.engine() words = p.number_to_words(minutes, andword="") return words except ValueError: sys.exit("Invalid date") if __name__ == "__main__": main() --- TEST CODE --- import pytest from course import calculate_words def test_input(): with pytest.raises(SystemExit): calculate_words("January 1, 1999") assert calculate_words("1999-01-01") == "thirteen million, one hundred sixty-five thousand, nine hundred twenty" with pytest.raises(SystemExit): calculate_words("1999.01.01") with pytest.raises(SystemExit): calculate_words("1999-10-99") with pytest.raises(SystemExit): calculate_words("cat")
@sujayshah4541 Жыл бұрын
I think there is a slight mistake in the regular expression used in this video. instead of [0-9]{4} ------> [0-9]{1,4}
@tsujimasen9 ай бұрын
I don't think Y is a valid format, it has to be YYYY.
@kenardsilva392610 ай бұрын
my solution: from sys import exit from datetime import date import inflect p = inflect.engine() def main(): input_date = input("Date of Birth: ") print(validate_date(input_date).capitalize() + " minutes") def validate_date(input_date): try: birth_date = date.fromisoformat(input_date) today = date.today() diff = today-birth_date total_minutes = p.number_to_words(diff.days*24*60, andword='') return(total_minutes) except ValueError: exit('Invalid date') if __name__ == "__main__": main()
@razagovani38510 ай бұрын
Here's my solution: from datetime import date import inflect import operator import sys p = inflect.engine() def main(): birthdate = input("Date of birth: ") output = calc_diff(birthdate) print(output) def calc_diff(d): try: difference = operator.sub(date.today(), date.fromisoformat(d)) return calc_mins(difference.days) except ValueError: sys.exit("Invalid date") def calc_mins(diff): mins = (diff) * 24 * 60 return f"{(p.number_to_words(mins, andword="")).capitalize()} minutes" if __name__ == "__main__": main()
@tsujimasen9 ай бұрын
I like the invocation of the fromisoformat method, but as a matter of saving keystrokes, - would also work instead of operator.sub. In that case, you also wouldn't need to import operator.
@omarhamid4462 жыл бұрын
I think your regular expression accepts date like 1998-55-88
@DorsCodingSchool2 жыл бұрын
We will take a look!
@massimotarsitani4434 Жыл бұрын
yeah, I think it too, there aren't the checks in the check_birthday function. Should call the date class inside the function since it has all the needed checks in it.
@inigocuervo Жыл бұрын
Exactly, to use regular expressions better to use something similar to (is for MM/DD/YYYY): match = re.match(r"([0[1-9]|1[0-2])/(3[01]|[12][0-9]|[1-9])/(\d{4})", date) #and take advantage of the groups if match: month, day, year = match.groups()
@MaggieMaTransforminie7 ай бұрын
has anyone run into problems with CS50 check? my testing file verifies my original file, but im not passing cs50 check... For example, the expected answer for a year ago from today is "Five hundred twenty-five thousand, six hundred minutes". but i'm getting "Five hundred twenty-seven thousand forty minutes." I've also tried some of your codes here, getting the same errors.
@pokytv58937 ай бұрын
Same here. been stuck for weeks
@pokytv58937 ай бұрын
@DorsCodingSchool
@pokytv58937 ай бұрын
i actually just figured it out. i think its because 2024 is a leap year so it doesn't get the exact result. it adds an extra day. But it actually works for other years from datetime import date import sys import inflect p = inflect.engine() def main(): date = input("Date of birth: ") print(validate(date)) def validate(d): try: birth = date.fromisoformat(d) except ValueError: sys.exit("Invalid Format") today = date.today() difference = today - birth time = difference.days * 24 * 60 words = p.number_to_words(time,andword="").capitalize() return f"{words} minutes" if __name__ == "__main__": main() test file: import pytest import sys from seasons import validate def test_format(): assert validate("2005-05-12") == "Ten million, forty-six thousand, eight hundred eighty minutes" assert validate("2003-12-12") == "Ten million, seven hundred ninety-one thousand, three hundred sixty minutes" assert validate("20190812") == "Two million, five hundred fifty-one thousand, six hundred eighty minutes" def test_error(): with pytest.raises(SystemExit): assert validate("January 12, 1995") == "Invalid Date" assert validate("friday the 13th, 2020") == "Invalid Date" assert validate("2004/12/05") == "Invalid Date" assert validate("2005-13-40") == "Invalid Date" assert validate("02-01-09") == "Invalid Date"
@randomtech_tv2 жыл бұрын
To write pytest for SysExit, use something like this def test_sysexit(): with pytest.raises(SystemExit, match='Invalid date') as error: your_birthday_function("January 1, 1999") assert error.type == SystemExit
@gameforggjarmenia2023 Жыл бұрын
or simpler def test_sysexit(): with pytest.raises(SystemExit): date_to_words("January 1, 1999")
@NomadLovesUs Жыл бұрын
You don't need to add the last line or even the match value. Just need to know the function is raising a SystemExit
@Ithicuss Жыл бұрын
Thanks for your explanation. For some reason I get an error stating that pytest cannot find my class so my test_seasons.py fails. But I got marks for all the other tests which run fine with my OOP solution I think is mostly in line with this class, so I called it a day after 1 hour of getting frustrated with pytest. import sys from datetime import date from datetime import datetime import inflect def main(): class MyDate: def __init__(self, birthday): self.birthday = birthday self.today = date.today() @classmethod def get_birthday(cls): try: return cls(date.fromisoformat(input("Birthday: "))) except ValueError: sys.exit("Wrong Date Format") @property def birthday(self): return self._birthday @birthday.setter def birthday(self, birthday): try: self._birthday = birthday except: sys.exit("Invalid date") def calcDifference(self): result = (self.today - self.birthday) difference_in_minutes = round((result.total_seconds()) / 60) p = inflect.engine() return f"{p.number_to_words(difference_in_minutes, andword="").capitalize()} minutes" laurens = MyDate.get_birthday() print(laurens.calcDifference()) if __name__ == "__main__": main()
@Nepallium Жыл бұрын
try putting your MyDate class outside of the main function maybe?
@carlosleter2 жыл бұрын
You should use class.
@javierdemendonca2572 жыл бұрын
Actually doesn't say that anywhere on the problem set.
@kellzbaker8 ай бұрын
dont follow this code were supposed to implement classes here .
@JenniferA.Moreno8 ай бұрын
Is your check50 failing most test in 2024!?? Please help your the most recent comment
@srijan57346 ай бұрын
@@JenniferA.Moreno yeah
@ProfShibe5 ай бұрын
it doesn't say anything about using classes for this on the assignment
@theophaneallany679 Жыл бұрын
this is how i solved the problem from datetime import date import re import sys import inflect p = inflect.engine() import operator def main(): user_input = input("Date of Birth: ") final_minutes = get_minute(user_input) print(final_minutes + " minutes") def get_minute(word): matches = re.search(r"^(\d{4})-(\d{2})-(\d{2})$",word) if matches: year,month,day = map(int, matches.groups()) today = date.today() my_date = date(int(year),int(month),int(day)) result = operator.__sub__(today, my_date) minutes = round(int(result.days * 1440)) words = p.number_to_words(minutes, andword="") words = words.capitalize() return words else: sys.exit("Invalid date") if __name__ == "__main__": main()
@СергейНиденталь Жыл бұрын
That's my way of decision: import sys import inflect p = inflect.engine() from datetime import date def main(): try: birth_date = get_date(input('Day of birth: ')) print(birth_date) except ValueError: sys.exit('Invalid date') def get_date(n): days = (date.today() - date.fromisoformat(n)).days minutes = p.number_to_words(days*24*60) return minutes if __name__ == "__main__": main()
@NomadLovesUs Жыл бұрын
from datetime import date import inflect, re, sys def main(): print(conv_to_words(conv_to_mins(input('Date of Birth: ')))) def conv_to_mins(s): try: year, month, day = s.split('-') days = str(date.today() - date(int(year), int(month), int(day))).split() return int(days[0])*24*60 except ValueError: sys.exit('Invalid date') def conv_to_words(mins): p = inflect.engine() return f'{p.number_to_words(mins, andword="")} minutes'.capitalize() if __name__ == "__main__": main()
@sethschuler192 Жыл бұрын
one more highly simplified from datetime import date import inflect import re p = inflect.engine() def main(): days_between = date.today() - check_date() print (f"{p.number_to_words(days_between.days *24 * 60)}, minutes") def check_date(): while True: birth_date = input("Enter birthdate: ").strip() if re.search(r"(\d{4})-([0-1]\d)-([0-3]\d)$", birth_date): return date.fromisoformat(birth_date) else: print("Invalid Date") if __name__ == "__main__": main()
@christophervirgo837 Жыл бұрын
i def think fromsioformat is the way to go. def main(): try: print(convert_date(get_birthday())) except ValueError: sys.exit(1) def get_birthday(): return date.fromisoformat(input("Date of Birth?")) def convert_date(birthday): time_passed = date.today() - birthday delta = int(timedelta.total_seconds(time_passed) / 60) return(f"{p.number_to_words(delta, andword='')} minutes").capitalize() if __name__ == "__main__": main()