CS50 Introduction To Python Programming


The CS50's Introduction to Programming with Python is a course offered by Harvard University, focusing on teaching Python programming.
This course, led by Harvard Professor David J. Malan, is designed for students with or without prior programming experience who want to learn Python specifically.
It covers topics such as functions, variables, conditionals, loops, exceptions, libraries, unit tests, file I/O, regular expressions, and object-oriented programming.
The course provides hands-on practice opportunities with exercises inspired by real-world programming problems. It can be taken independently or as a precursor to the more general CS50x course,
which covers computer science and programming with C, Python, SQL, and JavaScript.
The CS50's Introduction to Programming with Python course is available online through platforms like Harvard Online, edX, and YouTube, offering a comprehensive introduction to Python programming


Problem Set 7 Solutions




NUMB3RS

In a file called numb3rs.py, implement a function called validate that expects an IPv4 address as input as a str and then returns True or False, respectively, if that input is a valid IPv4 address or not.
Structure numb3rs.py as follows, wherein you're welcome to modify main and/or implement other functions as you see fit, but you may not import any other libraries. You're welcome, but not required, to use re and/or sys.

            import re
            import sys


            def main():
                print(validate(input("IPv4 Address: ")))


            def validate(ip):
                ...


            ...


            if __name__ == "__main__":
                main()

Either before or after you implement validate in numb3rs.py, additionally implement, in a file called test_numb3rs.py, two or more functions that collectively test your implementation of validate thoroughly, each of whose names should begin with test_ so that you can execute your tests with:
pytest test_numb3rs.py

Source Code

        

NUMB3RS.PY

   import re


        def main():
            print(validate(input("IPv4 Address: ")))


        def validate(ip):
            regex = "([0-1]?([0-9]?){2}|2[0-4]?[0-9]?|25[0-5]?)"
            match = re.search(r"^" + regex + "\." + regex + "\." + regex + "\." + regex + "$", ip)
            if match:
                return True
            else:
                return False


        if __name__ == "__main__":
            main()

test_numb3rs.py

        from numb3rs import validate


        def test_validate():
            assert validate("127.0.0.1") == True
            assert validate("255.255.255.255") == True
            assert validate("512.512.512.512") == False
            assert validate("1.2.3.1000") == False
            assert validate("cat") == False
            assert validate("1.2.3.4") == True
            assert validate("11.99.22.88") == True
            assert validate("199.911.288.882") == False
            assert validate("249.249.249.249") == True
        

Watch on Youtube

In a file called watch.py, implement a function called parse that expects a str of HTML as input, extracts any YouTube URL thatd's the value of a src attribute of an iframe element therein, and returns its shorter, shareable youtu.be equivalent as a str. Expect that any such URL will be in one of the formats below. Assume that the value of src will be surrounded by double quotes. And assume that the input will contain no more than one such URL. If the input does not contain any such URL at all, return None.
Structure watch.py as follows, wherein youd're welcome to modify main and/or implement other functions as you see fit, but you may not import any other libraries. Youd're welcome, but not required, to use re and/or sys.

        import re
        import sys
        
        
        def main():
            print(parse(input("HTML: ")))
        
        
        def parse(s):
            ...
        
        
        ...
        
        
        if __name__ == "__main__":
            main()

Source Code

            import re


            def main():
                print(parse(input("HTML: ")))
            
            
            def parse(s):
                if link := re.search(r")
                    return f"https://youtu.be/{link.group(2)}"
                else:
                    return None
            
            
            if __name__ == "__main__":
                main()

Working 9 to 5

In a file called working.py, implement a function called convert that expects a str in either of the 12-hour formats below and returns the corresponding str in 24-hour format (i.e., 9:00 to 17:00). Expect that AM and PM will be capitalized (with no periods therein) and that there will be a space before each. Assume that these times are representative of actual times, not necessarily 9:00 AM and 5:00 PM specifically.
9:00 AM to 5:00 PM
9 AM to 5 PM
Raise a ValueError instead if the input to convert is not in either of those formats or if either time is invalid (e.g., 12:60 AM, 13:00 PM, etc.).
But do not assume that someone's hours will start ante meridiem and end post meridiem; someone might work late and even long hours (e.g., 5:00 PM to 9:00 AM).
Structure working.py as follows, wherein you're welcome to modify main and/or implement other functions as you see fit, but you may not import any other libraries. You're welcome, but not required, to use re and/or sys.

            import re
            import sys
            
            
            def main():
                print(convert(input("Hours: ")))
            
            
            def convert(s):
                ...
            
            
            ...
            
            
            if __name__ == "__main__":
                main()

Either before or after you implement convert in working.py, additionally implement, in a file called test_working.py, three or more functions that collectively test your implementation of convert thoroughly, each of whose names should begin with test_ so that you can execute your tests with:
pytest test_working.py


Source Code

                

working.py

import re def main(): print(convert(input("Hours: "))) def convert(s): regex = "(0?[1-9]|1[0-2]):?\.?([0-5][0-9])? (AM|PM)" match = re.search(r"^" + regex + " to " + regex + "$", s) if match: from_time = standardize(match.group(1), match.group(2), match.group(3)) time = standardize(match.group(4), match.group(5), match.group(6)) return f"{from_time} to {time}" else: raise ValueError def standardize(hr, min, x): if hr == "12": if x == "AM": hour = "00" else: hour = "12" else: if x == "AM": hour = f"{int(hr):02}" else: hour = f"{int(hr)+12}" if min == None: minute = "00" else: minute = f"{int(min):02}" return f"{hour}:{minute}" if __name__ == "__main__": main()

test_working.py

        import pytest
        from working import convert


        def test_convert():
            assert convert("9 AM to 5 PM") == "09:00 to 17:00"
            assert convert("9:00 AM to 5:00 PM") == "09:00 to 17:00"
            assert convert("10 PM to 8 AM") == "22:00 to 08:00"
            assert convert("10:30 PM to 8:50 AM") == "22:30 to 08:50"

        def test_value_error():
            with pytest.raises(ValueError):
                convert("9AM - 5PM")
            with pytest.raises(ValueError):
                convert("09:00 to 17:00")
            with pytest.raises(ValueError):
                convert("15:00 AM to 25:00 PM")
            with pytest.raises(ValueError):
                convert("9:60 AM to 5:60 PM")
            

Regular, um, Expressions

In a file called um.py, implement a function called count that expects a line of text as input as a str and returns, as an int, the number of times that “um” appears in that text, case-insensitively, as a word unto itself, not as a substring of some other word. For instance, given text like hello, um, world, the function should return
1. Given text like yummy, though, the function should return 0.
Structure um.py as follows, wherein you're welcome to modify main and/or implement other functions as you see fit, but you may not import any other libraries. You're welcome, but not required, to use re and/or sys.

            import re
            import sys
            
            
            def main():
                print(count(input("Text: ")))
            
            
            def count(s):
                ...
            
            
            ...
            
            
            if __name__ == "__main__":
                main()

Either before or after you implement count in um.py, additionally implement, in a file called test_um.py, three or more functions that collectively test your implementation of count thoroughly, each of whose names should begin with test_ so that you can execute your tests with:
pytest test_um.py

Source Code

                

um.py

import re def main(): print(count(input("Text: "))) def count(s): # Match if "um" is in the beginning (^) or end ($) of a string input # Match if the character before and after "um" is not alphanumeric (punctuation / space is ok) regex = "(^|\W)um($|\W)" match = re.findall(regex, s, re.IGNORECASE) if match: return(len(match)) if __name__ == "__main__": main()

test_um.py

import pytest from um import count def test_input(): assert count("Um, thanks for the album.") == 1 assert count("um") == 1 assert count("Um, thanks, um...") == 2 assert count("Um?") == 1

Response Validation

In a file called response.py, using either validator-collection or validators from PyPI, implement a program that prompts the user for an email address via input and then prints Valid or Invalid, respectively, if the input is a syntatically valid email address. You may not use re. And do not validate whether the email address's domain name actually exists.


Source Code

                import validators


                def main():
                    print(validate(input("What's your email address? ")))
                
                
                def validate(s):
                    if validators.email(s) == True:
                        return f"Valid"
                    else:
                        return f"Invalid"
                
                
                if __name__ == "__main__":
                    main()