From 5f7d0f5ccd950b3e8b415540c00c81cdd9ad9302 Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Wed, 15 Feb 2023 12:08:58 -0500 Subject: [PATCH 01/23] complete Hello World exercise --- Ch2 - Basics/helloworld_start.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Ch2 - Basics/helloworld_start.py b/Ch2 - Basics/helloworld_start.py index 7d6b753..c9d3957 100644 --- a/Ch2 - Basics/helloworld_start.py +++ b/Ch2 - Basics/helloworld_start.py @@ -3,4 +3,12 @@ # LinkedIn Learning Python course by Joe Marini # +def main(): + print("Hello, world!") + name = input("What is your name? ") + name = name.capitalize() + print(f"Nice to meet you, {name}!") +# run main() if file executed as a program +if __name__ == "__main__": + main() \ No newline at end of file From 3416f43e439acf0e7165c829c807270130533864 Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Wed, 15 Feb 2023 12:18:29 -0500 Subject: [PATCH 02/23] complete variables exercise --- Ch2 - Basics/variables_start.py | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/Ch2 - Basics/variables_start.py b/Ch2 - Basics/variables_start.py index b2756cc..7593c88 100644 --- a/Ch2 - Basics/variables_start.py +++ b/Ch2 - Basics/variables_start.py @@ -13,25 +13,44 @@ mytuple = (0, 1, 2) mydict = {"one" : 1, "two" : 2} -print(myint) -print(myfloat) -print(mystr) -print(mybool) -print(mylist) -print(mytuple) -print(mydict) +# print(myint) +# print(myfloat) +# print(mystr) +# print(mybool) +# print(mylist) +# print(mytuple) +# print(mydict) # re-declaring a variable works +myint = "abc" +print(myint) # to access a member of a sequence type, use [] +print(mylist[2]) +print(mytuple[1]) # use slices to get parts of a sequence +print(mylist[1:5]) +print(mylist[1:5:2]) # you can use slices to reverse a sequence +print(mylist[::-1]) # dictionaries are accessed via keys +print(mydict["one"]) # ERROR: variables of different types cannot be combined +# print("string type" + 123) +print("string type" + str(123)) # Global vs. local variables in functions +def someFunction(): + global mystr + mystr = "def" + print(mystr) + +someFunction() +print(mystr) # => is still set to value from line 10, not line 48, unless global declared inside someFunction() +del mystr +print(mystr) \ No newline at end of file From 241df38a0c87d66225732fdf7ef58efdc35e64a3 Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Wed, 15 Feb 2023 12:26:23 -0500 Subject: [PATCH 03/23] complete functions exercise --- Ch2 - Basics/functions_start.py | 34 +++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/Ch2 - Basics/functions_start.py b/Ch2 - Basics/functions_start.py index 56cb247..e88dc0c 100644 --- a/Ch2 - Basics/functions_start.py +++ b/Ch2 - Basics/functions_start.py @@ -5,17 +5,51 @@ # TODO: define a basic function +def func1(): + print("I am a function.") # TODO: function that takes arguments +def func2(arg1, arg2): + print(arg1, " ", arg2) # TODO: function that returns a value +def cube(x): + return x * x * x # TODO: function with default value for an argument +def power(num, x = 1): + result = 1 + for i in range(x): + result = result * num + return result # TODO: function with variable number of arguments +def multi_add(*args): + result = 0 + for x in args: + result = result + x + return result + + +func1() +print(func1()) +print(func1) + +func2(10, 20) +print(func2(10, 20)) +print(func2) + +print(cube(3)) + +print(power(2)) +print(power(2, 3)) +print(power(x=3, num=2)) + +print(multi_add(4, 5, 10, 4)) +print(multi_add(4, 5, 10, 4, 10)) \ No newline at end of file From c42aa88aeec3e5caaebb5128288e3a66096ac0e1 Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Thu, 16 Feb 2023 11:53:07 -0500 Subject: [PATCH 04/23] complete conditionals exercise --- Ch2 - Basics/conditionals_start.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/Ch2 - Basics/conditionals_start.py b/Ch2 - Basics/conditionals_start.py index f6b58d6..0e5df80 100644 --- a/Ch2 - Basics/conditionals_start.py +++ b/Ch2 - Basics/conditionals_start.py @@ -9,11 +9,31 @@ def main(): x, y = 10, 100 # conditional flow uses if, elif, else + if x < y: + result = "x is less than y" + elif x > y: + result = "x is greater than y" + else: + result = "x is equal to y" + + print(result) # conditional statements let you use "a if C else b" + result = "x is less than y" if x < y else "x is greater than or equal to y" + print(result) # match-case makes it easy to compare multiple values - value = "one" + value = "fds" + match value: + case "one": + result = 1 + case "two": + result = 2 + case "three" | "four": + result = (3, 4) + case _: + result = -1 + print(result) if __name__ == "__main__": main() From 69c835096984cf450fae6c5f10528a95024bd090 Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Thu, 16 Feb 2023 12:13:28 -0500 Subject: [PATCH 05/23] complete loops exercise --- Ch2 - Basics/loops_start.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Ch2 - Basics/loops_start.py b/Ch2 - Basics/loops_start.py index f7d2e75..f6799c7 100644 --- a/Ch2 - Basics/loops_start.py +++ b/Ch2 - Basics/loops_start.py @@ -8,19 +8,37 @@ def main(): x = 0 # TODO: define a while loop + while(x < 5): + print(x) + x += 1 # TODO: define a for loop + for i in range(x): + print(i) # TODO: use a for loop over a collection days = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"] + for day in days: + print(day) # TODO: use the break and continue statements + for x in range(5, 10): + if x == 7: + break + print(x) + + for x in range(5, 10): + if x % 2 == 0: + continue + print(x) # TODO: using the enumerate() function to get index + for index, day in enumerate(days): + print(index, day) if __name__ == "__main__": From 6b8ba4fb416838dc04dc2e1254b0e8412359a2d9 Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Thu, 16 Feb 2023 12:21:48 -0500 Subject: [PATCH 06/23] complete classes exercise --- Ch2 - Basics/classes_start.py | 45 +++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/Ch2 - Basics/classes_start.py b/Ch2 - Basics/classes_start.py index de3226d..5176020 100644 --- a/Ch2 - Basics/classes_start.py +++ b/Ch2 - Basics/classes_start.py @@ -3,3 +3,48 @@ # LinkedIn Learning Python course by Joe Marini # +class Vehicle(): + def __init__(self, body_style): + self.body_style = body_style + + def drive(self, speed): + self.mode = "driving" + self.speed = speed + +class Car(Vehicle): + def __init__(self, engine_type): + super().__init__("Car") # creates Vehicle with body_style of car + self.wheels = 4 + self.doors = 4 + self.engine_type = engine_type + + def drive(self, speed): + super().drive(speed) + print("Driving my", self.engine_type, "car at", self.speed) + +class Motorcycle(Vehicle): + def __init__(self, engine_type, has_side_car): + super().__init__("Motorcycle") # creates Vehicle with body_style of Motorcycle + if (has_side_car): + self.wheels = 3 + else: + self.wheels = 2 + self.doors = 0 + self.engine_type = engine_type + + def drive(self, speed): + super().drive(speed) + print("Driving my", self.engine_type, "motorcycle at", self.speed) + + +car1 = Car("gas") +car2 = Car("electric") +moto1 = Motorcycle("gas", True) + +print(moto1.wheels) +print(car1.engine_type) +print(car2.doors) + +car1.drive(30) +car2.drive(40) +moto1.drive(50) \ No newline at end of file From 07287639d54b267ce1488274a8133e627f8920fb Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Thu, 16 Feb 2023 12:26:38 -0500 Subject: [PATCH 07/23] complete modules exercise --- Ch2 - Basics/modules_start.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Ch2 - Basics/modules_start.py b/Ch2 - Basics/modules_start.py index 8c8bf6c..822b9b4 100644 --- a/Ch2 - Basics/modules_start.py +++ b/Ch2 - Basics/modules_start.py @@ -3,12 +3,19 @@ # TODO: import the math module, which contains features for working with mathematics +import math # TODO: the math module contains lots of pre-built functions +print("The square root of 16 is", math.sqrt(16)) # TODO: in addition to functions, some modules contain useful constants +print("Pi is", math.pi) # TODO: try some of the math functions for yourself here: +print("3.5 rounded up is", math.ceil(3.5)) +print("3.5 rounded down is", math.floor(3.5)) +print("The absolute value of -123 is", math.fabs(-123)) +print("2 to the power of 5 is", math.pow(2,5)) From 4fb0b907b5cb90d429cbcc4061698f1f36065363 Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Thu, 16 Feb 2023 12:30:58 -0500 Subject: [PATCH 08/23] complete exceptions exercise --- Ch2 - Basics/exceptions_start.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Ch2 - Basics/exceptions_start.py b/Ch2 - Basics/exceptions_start.py index a1209c4..d6a52f7 100644 --- a/Ch2 - Basics/exceptions_start.py +++ b/Ch2 - Basics/exceptions_start.py @@ -5,10 +5,26 @@ # Errors can happen in programs, and we need a clean way to handle them # TODO: This code will cause an error because you can't divide by zero: +# x = 10 / 0 # TODO: Exceptions provide a way of catching errors and then handling them in # a separate section of the code to group them together - +try: + x = 10 / 0 +except: + print("Well that didn't work!") # TODO: You can also catch specific exceptions - +try: + answer = input("What should I divide 10 by?") + num = int(answer) + print(10/num) +except ZeroDivisionError as e: + print("You can't divide by zero!") +except ValueError as e: + print("You didn't give me a valid number!") + print(e) +except: + print("Well that didn't work!") +finally: + print("This code always runs.") From fc6af48a8158fdf841d8ba38c8a0aa5ec5cb6a98 Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Thu, 16 Feb 2023 12:46:15 -0500 Subject: [PATCH 09/23] complete Chapter 2 challenge --- Ch2 - Basics/challenge.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 Ch2 - Basics/challenge.py diff --git a/Ch2 - Basics/challenge.py b/Ch2 - Basics/challenge.py new file mode 100644 index 0000000..7b1b021 --- /dev/null +++ b/Ch2 - Basics/challenge.py @@ -0,0 +1,15 @@ + +# function prompts user for a string +# checks if that string is a palindrome +def main(): + prompt = "Enter string to test for palindrome or 'exit': " + while(True): + test_string = input(prompt) + if test_string.lower() == "exit": + break + else: + test_string = "".join(filter(lambda ch : ch.isalnum(), test_string)) + print(test_string == test_string[::-1]) + +if __name__ == "__main__": + main() \ No newline at end of file From 6f5cbc7e0ffd9c2bf5dbec606a0c54b647f2f227 Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Fri, 17 Feb 2023 13:55:42 -0500 Subject: [PATCH 10/23] complete files exercise --- Ch3 - Files/files_start.py | 24 ++++++++++++++++-------- Ch3 - Files/textfile.txt | 20 ++++++++++++++++++++ 2 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 Ch3 - Files/textfile.txt diff --git a/Ch3 - Files/files_start.py b/Ch3 - Files/files_start.py index fb026bb..1c3b5d5 100644 --- a/Ch3 - Files/files_start.py +++ b/Ch3 - Files/files_start.py @@ -5,19 +5,27 @@ def main(): - # Open a file for writing and create it if it doesn't exist - + # # Open a file for writing and create it if it doesn't exist + # my_file = open("textfile.txt", "w+") - # Open the file for appending text to the end - - - # write some lines of data to the file + # # Open the file for appending text to the end + # my_file = open("textfile.txt", "a+") + # # write some lines of data to the file + # for i in range(10): + # my_file.write("This is some text\n") - # close the file when done - + # # close the file when done + # my_file.close() # Open the file back up and read the contents + my_file = open("textfile.txt", "r") + if my_file.mode == "r": + # contents = my_file.read() + # print(contents) + file_lines = my_file.readlines() + for line in file_lines: + print(line) if __name__ == "__main__": diff --git a/Ch3 - Files/textfile.txt b/Ch3 - Files/textfile.txt new file mode 100644 index 0000000..6d6f21b --- /dev/null +++ b/Ch3 - Files/textfile.txt @@ -0,0 +1,20 @@ +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text From a0724c57ece03fe7c68ea5022673648f35df3334 Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Fri, 17 Feb 2023 14:04:46 -0500 Subject: [PATCH 11/23] complete os path utilities exercise --- Ch3 - Files/ospathutils_start.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/Ch3 - Files/ospathutils_start.py b/Ch3 - Files/ospathutils_start.py index 3384cbd..9a1fe72 100644 --- a/Ch3 - Files/ospathutils_start.py +++ b/Ch3 - Files/ospathutils_start.py @@ -3,8 +3,8 @@ # LinkedIn Learning Python course by Joe Marini # -import os -from os import path +import os # allows access to operating system +from os import path # access to path functions import datetime from datetime import date, time, timedelta import time @@ -12,18 +12,26 @@ def main(): # Print the name of the OS - + print(os.name) # Check for item existence and type - + print("Item exists:", str(path.exists("textfile.txt"))) + print("Item is a file:", path.isfile("textfile.txt")) + print("Item is a directory:", path.isdir("textfile.txt")) # Work with file paths - + print("Item's path:", path.realpath("textfile.txt")) + print("Item's path and name:", path.split(path.realpath("textfile.txt"))) # Get the modification time - + t = time.ctime(path.getmtime("textfile.txt")) + print(t) + print(datetime.datetime.fromtimestamp(path.getmtime("textfile.txt"))) # Calculate how long ago the item was modified + td = datetime.datetime.now() - datetime.datetime.fromtimestamp(path.getmtime("textfile.txt")) + print("It has been", td, "since the file was modified") + print("or", td.total_seconds(), "seconds") if __name__ == "__main__": From 197ac7de6e42943b7f23c76fa6c3532587e09171 Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Fri, 17 Feb 2023 14:12:14 -0500 Subject: [PATCH 12/23] complete shell utilities exercise --- Ch3 - Files/archive.zip | Bin 0 -> 6902 bytes Ch3 - Files/{textfile.txt => newfile.txt} | 0 Ch3 - Files/shell_start.py | 22 +++++++++++++++++----- Ch3 - Files/testzip.zip | Bin 0 -> 948 bytes Ch3 - Files/textfile.txt.bak | 20 ++++++++++++++++++++ 5 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 Ch3 - Files/archive.zip rename Ch3 - Files/{textfile.txt => newfile.txt} (100%) create mode 100644 Ch3 - Files/testzip.zip create mode 100644 Ch3 - Files/textfile.txt.bak diff --git a/Ch3 - Files/archive.zip b/Ch3 - Files/archive.zip new file mode 100644 index 0000000000000000000000000000000000000000..5aa70e37df19dd2c5dbcaa398e445c5e02002c08 GIT binary patch literal 6902 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 literal 0 HcmV?d00001 diff --git a/Ch3 - Files/textfile.txt b/Ch3 - Files/newfile.txt similarity index 100% rename from Ch3 - Files/textfile.txt rename to Ch3 - Files/newfile.txt diff --git a/Ch3 - Files/shell_start.py b/Ch3 - Files/shell_start.py index 5cb9ec5..3935766 100644 --- a/Ch3 - Files/shell_start.py +++ b/Ch3 - Files/shell_start.py @@ -5,19 +5,31 @@ import os from os import path +import shutil # import shell utilities +from shutil import make_archive +from zipfile import ZipFile def main(): # make a duplicate of an existing file - if path.exists("textfile.txt"): + if path.exists("textfile.txt.bak"): # get the path to the file in the current directory + src = path.realpath("textfile.txt") - # let's make a backup copy by appending "bak" to the name + # # let's make a backup copy by appending "bak" to the name + # dst = src + ".bak" + # shutil.copy(src, dst) - # rename the original file + # # rename the original file + # os.rename("textfile.txt", "newfile.txt") - # now put things into a ZIP archive + # # now put things into a ZIP archive + # root_dir, tail = path.split(src) + # shutil.make_archive("archive", "zip", root_dir) - # more fine-grained control over ZIP files + # # more fine-grained control over ZIP files + # with ZipFile("testzip.zip", "w") as newzip: + # newzip.write("newfile.txt") + # newzip.write("textfile.txt.bak") if __name__ == "__main__": diff --git a/Ch3 - Files/testzip.zip b/Ch3 - Files/testzip.zip new file mode 100644 index 0000000000000000000000000000000000000000..c72116b3e94e6ce261a91db6ee609d27f10425eb GIT binary patch literal 948 zcmWIWW@Zs#0D%R0fnoFC_^4$tGBAKJH&84uwLC2|CsnVcq9i0EvseL$it}?*6-rVo zO1MTvXb~C#@CdnHfEpnJzz6{aJS;}^k`l8=hTVvA6aau8V3I1!lV(4#lNo0SbD%LIhwKw6y{!~+0&3M~@= literal 0 HcmV?d00001 diff --git a/Ch3 - Files/textfile.txt.bak b/Ch3 - Files/textfile.txt.bak new file mode 100644 index 0000000..6d6f21b --- /dev/null +++ b/Ch3 - Files/textfile.txt.bak @@ -0,0 +1,20 @@ +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text +This is some text From aa92dbca87dc91426299117b69ab7b3da9c57a11 Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Sun, 19 Feb 2023 11:32:50 -0500 Subject: [PATCH 13/23] complete Chapter 3 challenge on files --- Ch3 - Files/challenge.py | 36 +++++++++++++++++++++++++++++++++ Ch3 - Files/results/results.txt | 15 ++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 Ch3 - Files/challenge.py create mode 100644 Ch3 - Files/results/results.txt diff --git a/Ch3 - Files/challenge.py b/Ch3 - Files/challenge.py new file mode 100644 index 0000000..5c2cf4d --- /dev/null +++ b/Ch3 - Files/challenge.py @@ -0,0 +1,36 @@ + +import os +from os import path + +def main(): + dir, this_file = path.split(path.realpath("challenge.py")) + + # get file names & stats + file_names = [] + total_bytes = 0 + for item in os.listdir(dir): + if path.isfile(item): + total_bytes += path.getsize(item) + file_names.append(str(item + "\n")) + file_names.sort() + + # create results folder + if not os.listdir(dir).__contains__("results"): + os.mkdir("results") + results_path = path.join(dir, "results", "results.txt") + + # create results file & populate + try: + results_file = open(results_path, "w+") + results_file.write(f"Total byte count: {total_bytes}\n") + results_file.write("Files list:\n--------------\n") + results_file.writelines(file_names) + results_file.close() + finally: + if not results_file.closed: + results_file.close() + + +# only run if primary application +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/Ch3 - Files/results/results.txt b/Ch3 - Files/results/results.txt new file mode 100644 index 0000000..ce469b0 --- /dev/null +++ b/Ch3 - Files/results/results.txt @@ -0,0 +1,15 @@ +Total byte count: 16835 +Files list: +-------------- +archive.zip +challenge.py +challenge_solution.py +files_finished.py +files_start.py +newfile.txt +ospathutils_finished.py +ospathutils_start.py +shell_finished.py +shell_start.py +testzip.zip +textfile.txt.bak From efe420672f3f238a4bac69817fd4d514e8ada4d8 Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Sun, 19 Feb 2023 11:36:56 -0500 Subject: [PATCH 14/23] improve Chapter 3 challenge after watching solution --- Ch3 - Files/challenge.py | 5 ++--- Ch3 - Files/results/results.txt | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Ch3 - Files/challenge.py b/Ch3 - Files/challenge.py index 5c2cf4d..8f09101 100644 --- a/Ch3 - Files/challenge.py +++ b/Ch3 - Files/challenge.py @@ -15,13 +15,12 @@ def main(): file_names.sort() # create results folder - if not os.listdir(dir).__contains__("results"): + if not path.exists("results"): os.mkdir("results") - results_path = path.join(dir, "results", "results.txt") # create results file & populate try: - results_file = open(results_path, "w+") + results_file = open("results/results.txt", "w+") results_file.write(f"Total byte count: {total_bytes}\n") results_file.write("Files list:\n--------------\n") results_file.writelines(file_names) diff --git a/Ch3 - Files/results/results.txt b/Ch3 - Files/results/results.txt index ce469b0..d0b30e6 100644 --- a/Ch3 - Files/results/results.txt +++ b/Ch3 - Files/results/results.txt @@ -1,4 +1,4 @@ -Total byte count: 16835 +Total byte count: 16767 Files list: -------------- archive.zip From f6d44288a26d3e29878c8a6b3ef59f5d5a75e4c6 Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Sun, 19 Feb 2023 11:47:41 -0500 Subject: [PATCH 15/23] complete dates exercise --- Ch4 - Dates and Times/dates_start.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Ch4 - Dates and Times/dates_start.py b/Ch4 - Dates and Times/dates_start.py index 9091c40..18e8875 100644 --- a/Ch4 - Dates and Times/dates_start.py +++ b/Ch4 - Dates and Times/dates_start.py @@ -3,24 +3,34 @@ # LinkedIn Learning Python course by Joe Marini # - +from datetime import date +from datetime import time +from datetime import datetime def main(): ## DATE OBJECTS # TODO: Get today's date from the simple today() method from the date class - + today = date.today() + print("Today's date is", today) # TODO: print out the date's individual components - + print("Today's date components:") + print(" day:", today.day) + print(" month:", today.month) + print(" year:", today.year) # TODO: retrieve today's weekday (0=Monday, 6=Sunday) - + days = ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday") + print("Today's weekday number is", today.weekday(), "which is a", days[today.weekday()]) ## DATETIME OBJECTS # TODO: Get today's date from the datetime class - + today = datetime.now() + print("The current date and time is", today) # TODO: Get the current time + t = datetime.time(datetime.now()) + print("The current time is",t) From 9d5709f328c9dfb740937fb8eb06f91579dfbbcb Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Sun, 19 Feb 2023 11:53:38 -0500 Subject: [PATCH 16/23] complete date & time formatting exercise --- Ch4 - Dates and Times/formatting_start.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Ch4 - Dates and Times/formatting_start.py b/Ch4 - Dates and Times/formatting_start.py index 6c40839..e57ad79 100644 --- a/Ch4 - Dates and Times/formatting_start.py +++ b/Ch4 - Dates and Times/formatting_start.py @@ -9,19 +9,25 @@ def main(): # Times and dates can be formatted using a set of predefined string # control codes - + now = datetime.now() #### Date Formatting #### # %y/%Y - Year, %a/%A - weekday, %b/%B - month, %d - day of month - + print(now.strftime("The current year is %Y")) + print(now.strftime("%a, %d %B, %Y")) + print(now.strftime("%A, %B %d, %Y")) # %c - locale's date and time, %x - locale's date, %X - locale's time - + print(now.strftime("Locale date and time: %c")) + print(now.strftime("Locale date: %x")) + print(now.strftime("Locale time: %X")) #### Time Formatting #### # %I/%H - 12/24 Hour, %M - minute, %S - second, %p - locale's AM/PM + print(now.strftime("The current time is %I:%M:%S %p")) + print(now.strftime("The current time is %H:%M")) if __name__ == "__main__": From b04e5bf465f7c07c21cd08da0d33851f0fdd8597 Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Sun, 19 Feb 2023 12:03:21 -0500 Subject: [PATCH 17/23] complete timedeltas exercise --- Ch4 - Dates and Times/timedeltas_start.py | 24 +++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/Ch4 - Dates and Times/timedeltas_start.py b/Ch4 - Dates and Times/timedeltas_start.py index a6b62bc..8d12481 100644 --- a/Ch4 - Dates and Times/timedeltas_start.py +++ b/Ch4 - Dates and Times/timedeltas_start.py @@ -7,29 +7,37 @@ from datetime import date from datetime import time from datetime import datetime +from datetime import timedelta # TODO: construct a basic timedelta and print it - +print(timedelta(days=365, hours=5, minutes=1)) # TODO: print today's date - +now = datetime.now() +print("Today is", now) # TODO: print today's date one year from now - +print("One year from now it will be", str(now + timedelta(days=365))) # TODO: create a timedelta that uses more than one argument - +print("In 2 weeks and 3 days it will be", str(now + timedelta(weeks=2, days=3))) # TODO: calculate the date 1 week ago, formatted as a string - +t = datetime.now() - timedelta(weeks=1) +s = t.strftime("%A, %B %d, %Y") +print("One week ago it was", s) ### How many days until April Fools' Day? - +today = date.today() +afd = date(today.year, 4, 1) # TODO: use date comparison to see if April Fool's has already gone for this year # if it has, use the replace() function to get the date for next year - +if afd < today: + print("April Fool's Day was", (today - afd).days, "days ago") + afd = afd.replace(year = today.year + 1) # TODO: Now calculate the amount of time until April Fool's Day - +time_to_afd = afd - today +print("There are", time_to_afd.days, "days until April Fool's Day!") From f6c16152e5e5d7b23b9d10eb8114ed93b5f2a4e3 Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Sun, 19 Feb 2023 12:13:21 -0500 Subject: [PATCH 18/23] complete calendars exercise --- Ch4 - Dates and Times/calendars_start.py | 34 ++++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/Ch4 - Dates and Times/calendars_start.py b/Ch4 - Dates and Times/calendars_start.py index 2963f70..08e5cd3 100644 --- a/Ch4 - Dates and Times/calendars_start.py +++ b/Ch4 - Dates and Times/calendars_start.py @@ -5,24 +5,48 @@ # TODO: import the calendar module - +import calendar # TODO: create a plain text calendar - +c = calendar.TextCalendar(calendar.MONDAY) +str = c.formatmonth(2023, 2, 0, 0) +print(str) # TODO: create an HTML formatted calendar - +hc = calendar.HTMLCalendar(calendar.SUNDAY) +str = hc.formatmonth(2023, 2) +print(str) # TODO: loop over the days of a month # zeroes mean that the day of the week is in an overlapping month - +for d in c.itermonthdays(2023, 2): + print(d) # TODO: The Calendar module provides useful utilities for the given locale, # such as the names of days and months in both full and abbreviated forms +for m in calendar.month_name: + print(m) +for d in calendar.day_name: + print(d) + +for m in calendar.month_abbr: + print(m) + +for d in calendar.day_abbr: + print(d) # TODO: Calculate days based on a rule: For example, consider # a team meeting on the first Friday of every month. # To figure out what days that would be for each month, # we can use this script: - +print("Team meetings will be on:") +for m in range(1, 13): + cal = calendar.monthcalendar(2023, m) + week1 = cal[0] + week2 = cal[1] + if week1[calendar.FRIDAY] != 0: + meetday = week1[calendar.FRIDAY] + else: + meetday = week2[calendar.FRIDAY] + print(calendar.month_name[m], meetday) From 004b9cd29025fbabde2658d7b7848bc136a986bd Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Sun, 19 Feb 2023 13:00:54 -0500 Subject: [PATCH 19/23] complete Chapter 4 challenge on dates & times --- Ch4 - Dates and Times/challenge_start.py | 118 +++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/Ch4 - Dates and Times/challenge_start.py b/Ch4 - Dates and Times/challenge_start.py index 9da42cb..b8e23d1 100644 --- a/Ch4 - Dates and Times/challenge_start.py +++ b/Ch4 - Dates and Times/challenge_start.py @@ -3,3 +3,121 @@ # import calendar + +# count number of specific weekday in given month & year +def main(): + # instructions + print() + print("This program will calculate the number of weekdays in a given month and year.") + print("Enter 'exit' at any time to quit. Enter 'help' for more information.") + print() + + run_program = True + while(run_program): + + weekdays = ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday") + + # get weekday selection + weekday = None + while(weekday == None): + weekday = input("Which day of the week (0-6) do you want to count? ") + if weekday.lower() == "exit": + weekday = None + break + elif weekday.lower() == "help": + print() + for i, day in enumerate(weekdays): + print(i, "-", day) + print() + weekday = None + continue + try: + weekday = int(weekday) + except ValueError as e: + print("Invalid entry. Please enter a number from 0-6.\n") + weekday = None + + # quit if user exits + if weekday == None: + return + + # get month selection + month = None + while(month == None): + month = input("Of which month (1-12)? ") + if month.lower() == "exit": + month = None + break + elif month.lower() == "help": + print() + print(" 1 - January") + print(" 2 - February") + print(" 3 - March") + print(" 4 - April") + print(" 5 - May") + print(" 6 - June") + print(" 7 - July") + print(" 8 - August") + print(" 9 - September") + print("10 - October") + print("11 - November") + print("12 - December") + print() + month = None + continue + try: + month = int(month) + except ValueError as e: + print("Invalid entry. Please enter a number from 1-12.\n") + month = None + + # quit if user exits + if month == None: + return + + # get year selection + year = None + while(year == None): + year = input("In what year (YYYY)? ") + if year.lower() == "exit": + year = None + break + try: + year = int(year) + except ValueError as e: + print("Invalid entry. Please enter a valid year.\n") + year = None + + # quit if user exits + if year == None: + return + + cal = calendar.monthcalendar(year, month) + num_days = 0 + for week in cal: + if week[weekday] != 0: + num_days += 1 + + print(f"\nThere are {num_days} {weekdays[weekday]}s in {calendar.month_name[month]} {year}.\n") + + # prompt user to run again or exit + run_program = None + while(run_program == None): + run_program = input("Check another month? (y/N) ") + match run_program.lower(): + case "": + run_program = False + case "exit": + run_program = False + case "n": + run_program = False + case "y": + run_program = True + case _: + print ("Invalid response. Please enter 'Y' to repeat or 'N' to exit.") + run_program = None + print() + + +if __name__ == "__main__": + main() \ No newline at end of file From d97f165425ef67491d03cb57189658f0cab85ee6 Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Wed, 22 Feb 2023 11:01:56 -0500 Subject: [PATCH 20/23] complete internet data exercise --- Ch5 - Internet Data/inetdata_start.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Ch5 - Internet Data/inetdata_start.py b/Ch5 - Internet Data/inetdata_start.py index 86dc094..84c6ec7 100644 --- a/Ch5 - Internet Data/inetdata_start.py +++ b/Ch5 - Internet Data/inetdata_start.py @@ -3,8 +3,13 @@ # LinkedIn Learning Python course by Joe Marini # +import urllib.request + def main(): - pass # this is a placeholder, do-nothing statement + web_url = urllib.request.urlopen("http://www.google.com") + print(web_url.getcode()) + data = web_url.read() + print(data) if __name__ == "__main__": main() From 859c5490ccbebacd7e336c3789ee57516e851161 Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Wed, 22 Feb 2023 11:13:03 -0500 Subject: [PATCH 21/23] complete JSON data exercise --- Ch5 - Internet Data/jsondata_start.py | 30 +++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/Ch5 - Internet Data/jsondata_start.py b/Ch5 - Internet Data/jsondata_start.py index e0da623..c217010 100644 --- a/Ch5 - Internet Data/jsondata_start.py +++ b/Ch5 - Internet Data/jsondata_start.py @@ -4,24 +4,40 @@ # import urllib.request +import json def printResults(data): # Use the json module to load the string data into a dictionary theJSON = json.loads(data) # now we can access the contents of the JSON like any other Python object - + if "title" in theJSON["metadata"]: + print(theJSON["metadata"]["title"]) # output the number of events, plus the magnitude and each event name - + count = theJSON["metadata"]["count"] + print(count, "events recorded") + print("--------------\n") # for each event, print the place where it occurred + print("All quakes in the past day:") + for quake in theJSON["features"]: + print(quake["properties"]["place"]) - + print("--------------\n") # print the events that only have a magnitude greater than 4 + print("Quakes with a magnitude of >= 4.0:") + for quake in theJSON["features"]: + if quake["properties"]["mag"] >= 4.0: + print(quake["properties"]["place"]) - + print("--------------\n") # print only the events where at least 1 person reported feeling something + print("Quakes where 1+ person reported feeling it:") + for quake in theJSON["features"]: + num_felt = quake["properties"]["felt"] + if num_felt != None and num_felt > 0: + print(quake["properties"]["place"]) def main(): @@ -33,6 +49,12 @@ def main(): # Open the URL and read the data webUrl = urllib.request.urlopen(urlData) print ("result code: " + str(webUrl.getcode())) + + if webUrl.getcode() == 200: + data = webUrl.read() + printResults(data) + else: + print("Received error from server, cannot print results. Code:", webUrl.getCode()) if __name__ == "__main__": From 48bcf91cb43ce2967760dfa5b6c05afd6222b55e Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Wed, 22 Feb 2023 11:21:02 -0500 Subject: [PATCH 22/23] complete HTML Parser exercise --- Ch5 - Internet Data/htmlparsing_start.py | 28 ++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/Ch5 - Internet Data/htmlparsing_start.py b/Ch5 - Internet Data/htmlparsing_start.py index a759ac3..18500dd 100644 --- a/Ch5 - Internet Data/htmlparsing_start.py +++ b/Ch5 - Internet Data/htmlparsing_start.py @@ -5,15 +5,33 @@ from html.parser import HTMLParser +paragraphs = 0 class MyHTMLParser(HTMLParser): def handle_comment(self, data): - pass + print("Encountered a comment:", data) + pos = self.getpos() + print("at line", pos[0], "and position", pos[1]) def handle_starttag(self, tag, attrs): - pass + print("Encountered a start tag:", tag) + pos = self.getpos() + print("at line", pos[0], "and position", pos[1]) + + global paragraphs + if tag == "p": + paragraphs += 1 + + if len(attrs) > 0: + print("Attributes:") + for a in attrs: + print("\t", a[0], "=", a[1]) def handle_data(self, data): - pass + if data.isspace(): + return + print("Encountered text data:", data) + pos = self.getpos() + print("at line", pos[0], "and position", pos[1]) def main(): # instantiate the parser and feed it some HTML @@ -22,7 +40,9 @@ def main(): f = open("samplehtml.html") if f.mode == "r": contents = f.read() # read the entire file - parser.feed(contents) + parser.feed(contents) + + print("Paragraph tags:", paragraphs) if __name__ == "__main__": main() From 1f199850f8e89613480eed3f39e24913c9668024 Mon Sep 17 00:00:00 2001 From: Bailey Cage Date: Wed, 22 Feb 2023 11:26:34 -0500 Subject: [PATCH 23/23] complete XML parsing exercise --- Ch5 - Internet Data/xmlparsing_start.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/Ch5 - Internet Data/xmlparsing_start.py b/Ch5 - Internet Data/xmlparsing_start.py index 3129b0c..b5b0350 100644 --- a/Ch5 - Internet Data/xmlparsing_start.py +++ b/Ch5 - Internet Data/xmlparsing_start.py @@ -3,18 +3,32 @@ # LinkedIn Learning Python course by Joe Marini # +import xml.dom.minidom def main(): # use the parse() function to load and parse an XML file - + doc = xml.dom.minidom.parse("samplexml.xml") # print out the document node and the name of the first child tag - + print(doc.nodeName) + print(doc.firstChild.tagName) # get a list of XML tags from the document and print each one - + skills = doc.getElementsByTagName("skill") + print(len(skills), "skills are listed:") + for s in skills: + print(s.getAttribute("name")) # create a new XML tag and add it into the document + new_skill = doc.createElement("skill") + new_skill.setAttribute("name", "jQuery") + doc.firstChild.appendChild(new_skill) + + # print skills again to check new skill added + skills = doc.getElementsByTagName("skill") + print(len(skills), "skills are listed:") + for s in skills: + print(s.getAttribute("name"))