From 63593ef6da4d0b1021e82e52a6fb3cb4a7a59c03 Mon Sep 17 00:00:00 2001 From: AH Date: Sat, 6 Aug 2022 11:36:44 +0100 Subject: [PATCH 1/8] Adding exercise files --- Ch2 - Basics/conditionals_finished.py | 24 +++++++------- Ch2 - Basics/conditionals_start.py | 2 ++ Ch2 - Basics/exceptions_start.py | 5 ++- Ch2 - Basics/functions_start.py | 45 +++++++++++++++++++++++--- Ch2 - Basics/helloworld_start.py | 6 ++++ Ch2 - Basics/loops_finished.py | 34 +++++++++---------- Ch2 - Basics/variables_start.py | 19 +++++++---- Ch3 - Files/archive.zip | Bin 0 -> 7609 bytes Ch3 - Files/files_finished.py | 27 ++++++++-------- Ch3 - Files/files_start.py | 8 +++-- Ch3 - Files/newfile.txt | 10 ++++++ Ch3 - Files/ospathutils_finished.py | 1 + Ch3 - Files/ospathutils_start.py | 21 ++++++++---- Ch3 - Files/shell_start.py | 14 ++++++-- Ch3 - Files/textfile.txt.bak | 10 ++++++ 15 files changed, 161 insertions(+), 65 deletions(-) create mode 100644 Ch3 - Files/archive.zip create mode 100644 Ch3 - Files/newfile.txt create mode 100644 Ch3 - Files/textfile.txt.bak diff --git a/Ch2 - Basics/conditionals_finished.py b/Ch2 - Basics/conditionals_finished.py index 2a77f66..61fd2a8 100644 --- a/Ch2 - Basics/conditionals_finished.py +++ b/Ch2 - Basics/conditionals_finished.py @@ -8,22 +8,22 @@ 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 same as y" - else: - result = "x is greater than y" - print(result) + # # conditional flow uses if, elif, else + # if x < y: + # result = "x is less than y" + # elif x == y: + # result = "x is same as y" + # else: + # result = "x is greater than 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) + # # 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) # new in Python 3.10 # the match-case construct can be used for multiple comparisons - value = "one" + value = "four" match value: case "one": result = 1 diff --git a/Ch2 - Basics/conditionals_start.py b/Ch2 - Basics/conditionals_start.py index f6b58d6..aab5d26 100644 --- a/Ch2 - Basics/conditionals_start.py +++ b/Ch2 - Basics/conditionals_start.py @@ -11,6 +11,8 @@ def main(): # conditional flow uses if, elif, else # 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" diff --git a/Ch2 - Basics/exceptions_start.py b/Ch2 - Basics/exceptions_start.py index a1209c4..4ca2993 100644 --- a/Ch2 - Basics/exceptions_start.py +++ b/Ch2 - Basics/exceptions_start.py @@ -8,7 +8,10 @@ # 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("Whoops") # TODO: You can also catch specific exceptions diff --git a/Ch2 - Basics/functions_start.py b/Ch2 - Basics/functions_start.py index 56cb247..30c4b6a 100644 --- a/Ch2 - Basics/functions_start.py +++ b/Ch2 - Basics/functions_start.py @@ -5,17 +5,54 @@ # TODO: define a basic function +import re -# TODO: function that takes arguments +def func1(): + print("I am a function") -# TODO: function that returns a value +# 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 + +# you can combine *args with defined args but *args must be at the end of params: +def multi_add_two(arg1, *args): + result = arg1 + for x in args: + result = result + x + return result + +# func1() +# print(func1()) +# print(func1) + +# func2(10, 20) +# print(func2(10, 20)) +# print(cube(3)) + +# print(power(2)) +# print(power(2,3)) +# print(power(x=3, num=2)) + +# print(multi_add(1, 1, 1, 1)) +print(multi_add_two(5, 1, 1)) \ No newline at end of file diff --git a/Ch2 - Basics/helloworld_start.py b/Ch2 - Basics/helloworld_start.py index 7d6b753..d35a00c 100644 --- a/Ch2 - Basics/helloworld_start.py +++ b/Ch2 - Basics/helloworld_start.py @@ -3,4 +3,10 @@ # LinkedIn Learning Python course by Joe Marini # +def main(): + print("Hello World!") + name = input("What is your name? ") + print("Nice to meet you, ", name) +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/Ch2 - Basics/loops_finished.py b/Ch2 - Basics/loops_finished.py index b348924..51637b6 100644 --- a/Ch2 - Basics/loops_finished.py +++ b/Ch2 - Basics/loops_finished.py @@ -7,30 +7,30 @@ def main(): x = 0 - # define a while loop - while (x < 5): - print(x) - x = x + 1 + # # define a while loop + # while (x < 5): + # print(x) + # x = x + 1 - # define a for loop - for x in range(5,10): - print (x) + # # define a for loop + # for x in range(5,10): + # print (x) - # use a for loop over a collection - days = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"] - for d in days: - print (d) + # # use a for loop over a collection + # days = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"] + # for d in days: + # print (d) # use the break and continue statements for x in range(5,10): - #if (x == 7): break - #if (x % 2 == 0): continue + # if (x == 7): break + if (x % 2 == 0): continue print (x) - # using the enumerate() function to get index - days = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"] - for i, d in enumerate(days): - print (i, d) + # # using the enumerate() function to get index + # days = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"] + # for i, d in enumerate(days): + # print (i, d) if __name__ == "__main__": main() diff --git a/Ch2 - Basics/variables_start.py b/Ch2 - Basics/variables_start.py index b2756cc..f692341 100644 --- a/Ch2 - Basics/variables_start.py +++ b/Ch2 - Basics/variables_start.py @@ -22,16 +22,23 @@ print(mydict) # re-declaring a variable works - +myint = "abc" # to access a member of a sequence type, use [] - +print(mylist[4]) # use slices to get parts of a sequence - +print(mylist[1:3]) +print(mylist[1:5:2]) # you can use slices to reverse a sequence - +print(mylist[::-1]) # dictionaries are accessed via keys - +print(mydict["two"]) # ERROR: variables of different types cannot be combined - +print("real string " + str(123)) # Global vs. local variables in functions +def someFunction(): + global mystr + mystr = "def" + print(mystr) +someFunction() +print(mystr) diff --git a/Ch3 - Files/archive.zip b/Ch3 - Files/archive.zip new file mode 100644 index 0000000000000000000000000000000000000000..692dfd8b2def1d9b118bb8cecafe80cb71b2d1a0 GIT binary patch literal 7609 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 i0eW=r^#63(#1J9pZB#rPjCFg_;$ literal 0 HcmV?d00001 diff --git a/Ch3 - Files/files_finished.py b/Ch3 - Files/files_finished.py index a88083a..91bf898 100644 --- a/Ch3 - Files/files_finished.py +++ b/Ch3 - Files/files_finished.py @@ -4,30 +4,31 @@ # -def main(): +def main(): # Open a file for writing and create it if it doesn't exist - f = open("textfile.txt","w+") - + f = open("textfile.txt", "w+") + # Open the file for appending text to the end - # f = open("textfile.txt","a+") + f = open("textfile.txt", "a+") # write some lines of data to the file for i in range(10): - f.write("This is line %d\r\n" % (i+1)) - + f.write("This is line %d\r\n" % (i + 1)) + # close the file when done f.close() - + # Open the file back up and read the contents - f = open("textfile.txt","r") - if f.mode == 'r': # check to make sure that the file was opened + f = open("textfile.txt", "r") + if f.mode == 'r': # check to make sure that the file was opened # use the read() function to read the entire file # contents = f.read() # print (contents) - - fl = f.readlines() # readlines reads the individual lines into a list + # + fl = f.readlines() # readlines reads the individual lines into a list for x in fl: - print (x) - + print(x) + + if __name__ == "__main__": main() diff --git a/Ch3 - Files/files_start.py b/Ch3 - Files/files_start.py index fb026bb..7a5c52f 100644 --- a/Ch3 - Files/files_start.py +++ b/Ch3 - Files/files_start.py @@ -6,13 +6,15 @@ def main(): # Open a file for writing and create it if it doesn't exist + myfile = open("textfile.txt", "w+") - - # Open the file for appending text to the end + # Open the file for appending text to the end + for i in range(10): + myfile.write("This is some text\n") # write some lines of data to the file - + myfile.close() # close the file when done diff --git a/Ch3 - Files/newfile.txt b/Ch3 - Files/newfile.txt new file mode 100644 index 0000000..fcbf0f0 --- /dev/null +++ b/Ch3 - Files/newfile.txt @@ -0,0 +1,10 @@ +This is line 1 +This is line 2 +This is line 3 +This is line 4 +This is line 5 +This is line 6 +This is line 7 +This is line 8 +This is line 9 +This is line 10 diff --git a/Ch3 - Files/ospathutils_finished.py b/Ch3 - Files/ospathutils_finished.py index e6b8fe4..f83aaa2 100644 --- a/Ch3 - Files/ospathutils_finished.py +++ b/Ch3 - Files/ospathutils_finished.py @@ -21,6 +21,7 @@ def main(): # Work with file paths print ("Item's path: " + str(path.realpath("textfile.txt"))) + # SPLIT PATH AND FILE IN TO A TUPLE: print ("Item's path and name: " + str(path.split(path.realpath("textfile.txt")))) # Get the modification time diff --git a/Ch3 - Files/ospathutils_start.py b/Ch3 - Files/ospathutils_start.py index 3384cbd..6c0d10a 100644 --- a/Ch3 - Files/ospathutils_start.py +++ b/Ch3 - Files/ospathutils_start.py @@ -12,19 +12,28 @@ 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")) + + # SPLIT PATH AND FILE IN TO A TUPLE: + 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__": main() diff --git a/Ch3 - Files/shell_start.py b/Ch3 - Files/shell_start.py index 5cb9ec5..3a0ff50 100644 --- a/Ch3 - Files/shell_start.py +++ b/Ch3 - Files/shell_start.py @@ -5,17 +5,25 @@ import os from os import path +import shutil +from shutil import make_archive def main(): # make a duplicate of an existing file if path.exists("textfile.txt"): # 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 - + dst = src + ".bak" + shutil.copy(src, dst) + # rename the original file - + os.rename("textfile.txt", "newfile.txt") + # now put things into a ZIP archive + root_dir, tail = path.split(src) + # more fine-grained control over ZIP files diff --git a/Ch3 - Files/textfile.txt.bak b/Ch3 - Files/textfile.txt.bak new file mode 100644 index 0000000..fcbf0f0 --- /dev/null +++ b/Ch3 - Files/textfile.txt.bak @@ -0,0 +1,10 @@ +This is line 1 +This is line 2 +This is line 3 +This is line 4 +This is line 5 +This is line 6 +This is line 7 +This is line 8 +This is line 9 +This is line 10 From c8848f631701556123feaec3a782e3321e58fbd3 Mon Sep 17 00:00:00 2001 From: AH Date: Sat, 13 Aug 2022 13:01:10 +0100 Subject: [PATCH 2/8] Finished examples only --- Ch2 - Basics/classes_start.py | 5 -- Ch2 - Basics/conditionals_start.py | 21 ------- Ch2 - Basics/exceptions_start.py | 17 ------ Ch2 - Basics/functions_start.py | 58 -------------------- Ch2 - Basics/helloworld_start.py | 12 ---- Ch2 - Basics/loops_start.py | 27 --------- Ch2 - Basics/modules_start.py | 14 ----- Ch2 - Basics/variables_start.py | 44 --------------- Ch3 - Files/files_start.py | 26 --------- Ch3 - Files/ospathutils_start.py | 39 ------------- Ch3 - Files/shell_start.py | 32 ----------- Ch4 - Dates and Times/calendar-example.html | 19 +++++++ Ch4 - Dates and Times/calendars_finished.py | 4 +- Ch4 - Dates and Times/calendars_start.py | 28 ---------- Ch4 - Dates and Times/challenge_solution.py | 4 +- Ch4 - Dates and Times/challenge_start.py | 5 -- Ch4 - Dates and Times/dates_start.py | 30 ---------- Ch4 - Dates and Times/formatting_finished.py | 4 +- Ch4 - Dates and Times/formatting_start.py | 28 ---------- Ch4 - Dates and Times/timedeltas_start.py | 35 ------------ Ch4 - Dates and Times/year-calendar.py | 11 ++++ 21 files changed, 36 insertions(+), 427 deletions(-) delete mode 100644 Ch2 - Basics/classes_start.py delete mode 100644 Ch2 - Basics/conditionals_start.py delete mode 100644 Ch2 - Basics/exceptions_start.py delete mode 100644 Ch2 - Basics/functions_start.py delete mode 100644 Ch2 - Basics/helloworld_start.py delete mode 100644 Ch2 - Basics/loops_start.py delete mode 100644 Ch2 - Basics/modules_start.py delete mode 100644 Ch2 - Basics/variables_start.py delete mode 100644 Ch3 - Files/files_start.py delete mode 100644 Ch3 - Files/ospathutils_start.py delete mode 100644 Ch3 - Files/shell_start.py create mode 100644 Ch4 - Dates and Times/calendar-example.html delete mode 100644 Ch4 - Dates and Times/calendars_start.py delete mode 100644 Ch4 - Dates and Times/challenge_start.py delete mode 100644 Ch4 - Dates and Times/dates_start.py delete mode 100644 Ch4 - Dates and Times/formatting_start.py delete mode 100644 Ch4 - Dates and Times/timedeltas_start.py create mode 100644 Ch4 - Dates and Times/year-calendar.py diff --git a/Ch2 - Basics/classes_start.py b/Ch2 - Basics/classes_start.py deleted file mode 100644 index de3226d..0000000 --- a/Ch2 - Basics/classes_start.py +++ /dev/null @@ -1,5 +0,0 @@ -# -# Example file for working with classes -# LinkedIn Learning Python course by Joe Marini -# - diff --git a/Ch2 - Basics/conditionals_start.py b/Ch2 - Basics/conditionals_start.py deleted file mode 100644 index aab5d26..0000000 --- a/Ch2 - Basics/conditionals_start.py +++ /dev/null @@ -1,21 +0,0 @@ -# -# Example file for working with conditional statements -# LinkedIn Learning Python course by Joe Marini -# - - - -def main(): - x, y = 10, 100 - - # conditional flow uses if, elif, else - - # 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" - -if __name__ == "__main__": - main() diff --git a/Ch2 - Basics/exceptions_start.py b/Ch2 - Basics/exceptions_start.py deleted file mode 100644 index 4ca2993..0000000 --- a/Ch2 - Basics/exceptions_start.py +++ /dev/null @@ -1,17 +0,0 @@ -# -# Example file for working with classes -# LinkedIn Learning Python course by Joe Marini -# - -# 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: - -# 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("Whoops") - -# TODO: You can also catch specific exceptions - diff --git a/Ch2 - Basics/functions_start.py b/Ch2 - Basics/functions_start.py deleted file mode 100644 index 30c4b6a..0000000 --- a/Ch2 - Basics/functions_start.py +++ /dev/null @@ -1,58 +0,0 @@ -# -# Example file for working with functions -# LinkedIn Learning Python course by Joe Marini -# - - -# TODO: define a basic function -import re - - -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 - -# you can combine *args with defined args but *args must be at the end of params: -def multi_add_two(arg1, *args): - result = arg1 - for x in args: - result = result + x - return result - -# func1() -# print(func1()) -# print(func1) - -# func2(10, 20) -# print(func2(10, 20)) -# print(cube(3)) - -# print(power(2)) -# print(power(2,3)) -# print(power(x=3, num=2)) - -# print(multi_add(1, 1, 1, 1)) -print(multi_add_two(5, 1, 1)) \ No newline at end of file diff --git a/Ch2 - Basics/helloworld_start.py b/Ch2 - Basics/helloworld_start.py deleted file mode 100644 index d35a00c..0000000 --- a/Ch2 - Basics/helloworld_start.py +++ /dev/null @@ -1,12 +0,0 @@ -# -# Example file for HelloWorld -# LinkedIn Learning Python course by Joe Marini -# - -def main(): - print("Hello World!") - name = input("What is your name? ") - print("Nice to meet you, ", name) - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/Ch2 - Basics/loops_start.py b/Ch2 - Basics/loops_start.py deleted file mode 100644 index f7d2e75..0000000 --- a/Ch2 - Basics/loops_start.py +++ /dev/null @@ -1,27 +0,0 @@ -# -# Example file for working with loops -# LinkedIn Learning Python course by Joe Marini -# - - -def main(): - x = 0 - - # TODO: define a while loop - - - # TODO: define a for loop - - - # TODO: use a for loop over a collection - days = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"] - - - # TODO: use the break and continue statements - - - # TODO: using the enumerate() function to get index - - -if __name__ == "__main__": - main() diff --git a/Ch2 - Basics/modules_start.py b/Ch2 - Basics/modules_start.py deleted file mode 100644 index 8c8bf6c..0000000 --- a/Ch2 - Basics/modules_start.py +++ /dev/null @@ -1,14 +0,0 @@ -# LinkedIn Learning Python course by Joe Marini -# - - -# TODO: import the math module, which contains features for working with mathematics - - -# TODO: the math module contains lots of pre-built functions - - -# TODO: in addition to functions, some modules contain useful constants - - -# TODO: try some of the math functions for yourself here: diff --git a/Ch2 - Basics/variables_start.py b/Ch2 - Basics/variables_start.py deleted file mode 100644 index f692341..0000000 --- a/Ch2 - Basics/variables_start.py +++ /dev/null @@ -1,44 +0,0 @@ -# -# Example file for variables -# LinkedIn Learning Python course by Joe Marini -# - - -# Basic data types in Python: Numbers, Strings, Booleans, Sequences, Dictionaries -myint = 5 -myfloat = 13.2 -mystr = "This is a string" -mybool = True -mylist = [0, 1, "two", 3.2, False] -mytuple = (0, 1, 2) -mydict = {"one" : 1, "two" : 2} - -print(myint) -print(myfloat) -print(mystr) -print(mybool) -print(mylist) -print(mytuple) -print(mydict) - -# re-declaring a variable works -myint = "abc" -# to access a member of a sequence type, use [] -print(mylist[4]) -# use slices to get parts of a sequence -print(mylist[1:3]) -print(mylist[1:5:2]) -# you can use slices to reverse a sequence -print(mylist[::-1]) -# dictionaries are accessed via keys -print(mydict["two"]) -# ERROR: variables of different types cannot be combined -print("real string " + str(123)) -# Global vs. local variables in functions -def someFunction(): - global mystr - mystr = "def" - print(mystr) - -someFunction() -print(mystr) diff --git a/Ch3 - Files/files_start.py b/Ch3 - Files/files_start.py deleted file mode 100644 index 7a5c52f..0000000 --- a/Ch3 - Files/files_start.py +++ /dev/null @@ -1,26 +0,0 @@ -# -# Read and write files using the built-in Python file methods -# LinkedIn Learning Python course by Joe Marini -# - - -def main(): - # Open a file for writing and create it if it doesn't exist - myfile = open("textfile.txt", "w+") - - - # Open the file for appending text to the end - for i in range(10): - myfile.write("This is some text\n") - - # write some lines of data to the file - myfile.close() - - # close the file when done - - - # Open the file back up and read the contents - - -if __name__ == "__main__": - main() diff --git a/Ch3 - Files/ospathutils_start.py b/Ch3 - Files/ospathutils_start.py deleted file mode 100644 index 6c0d10a..0000000 --- a/Ch3 - Files/ospathutils_start.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# Example file for working with os.path module -# LinkedIn Learning Python course by Joe Marini -# - -import os -from os import path -import datetime -from datetime import date, time, timedelta -import time - - -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")) - - # SPLIT PATH AND FILE IN TO A TUPLE: - 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__": - main() diff --git a/Ch3 - Files/shell_start.py b/Ch3 - Files/shell_start.py deleted file mode 100644 index 3a0ff50..0000000 --- a/Ch3 - Files/shell_start.py +++ /dev/null @@ -1,32 +0,0 @@ -# -# Example file for working with filesystem shell methods -# LinkedIn Learning Python course by Joe Marini -# - -import os -from os import path -import shutil -from shutil import make_archive - -def main(): - # make a duplicate of an existing file - if path.exists("textfile.txt"): - # 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 - dst = src + ".bak" - shutil.copy(src, dst) - - # rename the original file - os.rename("textfile.txt", "newfile.txt") - - # now put things into a ZIP archive - root_dir, tail = path.split(src) - - - # more fine-grained control over ZIP files - - -if __name__ == "__main__": - main() diff --git a/Ch4 - Dates and Times/calendar-example.html b/Ch4 - Dates and Times/calendar-example.html new file mode 100644 index 0000000..420a28c --- /dev/null +++ b/Ch4 - Dates and Times/calendar-example.html @@ -0,0 +1,19 @@ + + + + + Calendar HTML + + + + + + + + + + + +
January 2022
SunMonTueWedThuFriSat
      1
2345678
9101112131415
16171819202122
23242526272829
3031     
+ + \ No newline at end of file diff --git a/Ch4 - Dates and Times/calendars_finished.py b/Ch4 - Dates and Times/calendars_finished.py index 1372384..b412b36 100644 --- a/Ch4 - Dates and Times/calendars_finished.py +++ b/Ch4 - Dates and Times/calendars_finished.py @@ -8,13 +8,13 @@ # create a plain text calendar c = calendar.TextCalendar(calendar.SUNDAY) -str = c.formatmonth(2022, 1, 0, 0) +str = c.formatmonth(2022, 8, 0, 0) print (str) # create an HTML formatted calendar hc = calendar.HTMLCalendar(calendar.SUNDAY) str = hc.formatmonth(2022, 1) -print (str) +print(str) # loop over the days of a month # zeroes mean that the day of the week is in an overlapping month diff --git a/Ch4 - Dates and Times/calendars_start.py b/Ch4 - Dates and Times/calendars_start.py deleted file mode 100644 index 2963f70..0000000 --- a/Ch4 - Dates and Times/calendars_start.py +++ /dev/null @@ -1,28 +0,0 @@ -# -# Example file for working with Calendars -# LinkedIn Learning Python course by Joe Marini -# - - -# TODO: import the calendar module - - -# TODO: create a plain text calendar - - -# TODO: create an HTML formatted calendar - - -# TODO: loop over the days of a month -# zeroes mean that the day of the week is in an overlapping month - - -# 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 - - -# 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: - diff --git a/Ch4 - Dates and Times/challenge_solution.py b/Ch4 - Dates and Times/challenge_solution.py index 7e57b30..9c4c2cb 100644 --- a/Ch4 - Dates and Times/challenge_solution.py +++ b/Ch4 - Dates and Times/challenge_solution.py @@ -4,6 +4,7 @@ import calendar + # This function counts the number of the given weekday for the # specified year and month and returns the result def countdays(theyear, themonth, whichday): @@ -18,7 +19,7 @@ def countdays(theyear, themonth, whichday): print("--Day counter program--\n") run = True -while(run): +while (run): try: print("Which day of the week do you want to count?") print("0: Monday") @@ -48,4 +49,3 @@ def countdays(theyear, themonth, whichday): except Exception as e: print(e) print("Sorry, that's not valid input") - diff --git a/Ch4 - Dates and Times/challenge_start.py b/Ch4 - Dates and Times/challenge_start.py deleted file mode 100644 index 9da42cb..0000000 --- a/Ch4 - Dates and Times/challenge_start.py +++ /dev/null @@ -1,5 +0,0 @@ -# Start file for programming challenge for Learning Python course -# LinkedIn Learning Python course by Joe Marini -# - -import calendar diff --git a/Ch4 - Dates and Times/dates_start.py b/Ch4 - Dates and Times/dates_start.py deleted file mode 100644 index 9091c40..0000000 --- a/Ch4 - Dates and Times/dates_start.py +++ /dev/null @@ -1,30 +0,0 @@ -# -# Example file for working with date information -# LinkedIn Learning Python course by Joe Marini -# - - - -def main(): - ## DATE OBJECTS - # TODO: Get today's date from the simple today() method from the date class - - - # TODO: print out the date's individual components - - - # TODO: retrieve today's weekday (0=Monday, 6=Sunday) - - - ## DATETIME OBJECTS - # TODO: Get today's date from the datetime class - - - # TODO: Get the current time - - - - -if __name__ == "__main__": - main() - \ No newline at end of file diff --git a/Ch4 - Dates and Times/formatting_finished.py b/Ch4 - Dates and Times/formatting_finished.py index a8449d6..5ec7e22 100644 --- a/Ch4 - Dates and Times/formatting_finished.py +++ b/Ch4 - Dates and Times/formatting_finished.py @@ -15,7 +15,7 @@ def main(): # %y/%Y - Year, %a/%A - weekday, %b/%B - month, %d - day of month print (now.strftime("The current year is: %Y")) # full year with century - print (now.strftime("%a, %d %B, %y")) # abbreviated day, num, full month, abbreviated year + print (now.strftime("%A, %d %B, %Y")) # abbreviated day, num, full month, abbreviated year # %c - locale's date and time, %x - locale's date, %X - locale's time print (now.strftime("Locale date and time: %c")) @@ -26,7 +26,7 @@ def main(): # %I/%H - 12/24 Hour, %M - minute, %S - second, %p - locale's AM/PM print (now.strftime("Current time: %I:%M:%S %p")) # 12-Hour:Minute:Second:AM - print (now.strftime("24-hour time: %H:%M")) # 24-Hour:Minute + print (now.strftime("24-hour time: %H%M")) # 24-Hour:Minute if __name__ == "__main__": diff --git a/Ch4 - Dates and Times/formatting_start.py b/Ch4 - Dates and Times/formatting_start.py deleted file mode 100644 index 6c40839..0000000 --- a/Ch4 - Dates and Times/formatting_start.py +++ /dev/null @@ -1,28 +0,0 @@ -# -# Example file for formatting time and date output -# LinkedIn Learning Python course by Joe Marini -# - - -from datetime import datetime - -def main(): - # Times and dates can be formatted using a set of predefined string - # control codes - - - #### Date Formatting #### - - # %y/%Y - Year, %a/%A - weekday, %b/%B - month, %d - day of month - - - # %c - locale's date and time, %x - locale's date, %X - locale's time - - - #### Time Formatting #### - - # %I/%H - 12/24 Hour, %M - minute, %S - second, %p - locale's AM/PM - - -if __name__ == "__main__": - main() diff --git a/Ch4 - Dates and Times/timedeltas_start.py b/Ch4 - Dates and Times/timedeltas_start.py deleted file mode 100644 index a6b62bc..0000000 --- a/Ch4 - Dates and Times/timedeltas_start.py +++ /dev/null @@ -1,35 +0,0 @@ -# -# Example file for working with timedelta objects -# LinkedIn Learning Python course by Joe Marini -# - - -from datetime import date -from datetime import time -from datetime import datetime - - -# TODO: construct a basic timedelta and print it - - -# TODO: print today's date - - -# TODO: print today's date one year from now - - -# TODO: create a timedelta that uses more than one argument - - -# TODO: calculate the date 1 week ago, formatted as a string - - -### How many days until April Fools' Day? - - -# 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 - - -# TODO: Now calculate the amount of time until April Fool's Day - diff --git a/Ch4 - Dates and Times/year-calendar.py b/Ch4 - Dates and Times/year-calendar.py new file mode 100644 index 0000000..33838b6 --- /dev/null +++ b/Ch4 - Dates and Times/year-calendar.py @@ -0,0 +1,11 @@ +import calendar +import datetime + +year = datetime.datetime.now().year + +cal = calendar.TextCalendar(calendar.SUNDAY) +for m in range(1,13): + print(cal.formatmonth(year, m, 0, 0)) + + + From 7a8d8e81c6fa623fac47e3f911873a16eb02af0c Mon Sep 17 00:00:00 2001 From: AH Date: Sat, 13 Aug 2022 15:01:41 +0100 Subject: [PATCH 3/8] Finished 'Learning Python' --- Ch5 - Internet Data/htmlparsing_finished.py | 34 +++++++++--------- Ch5 - Internet Data/htmlparsing_start.py | 29 --------------- Ch5 - Internet Data/inetdata_finished.py | 12 ++++--- Ch5 - Internet Data/inetdata_start.py | 10 ------ Ch5 - Internet Data/jsondata_finished.py | 2 +- Ch5 - Internet Data/jsondata_start.py | 39 --------------------- Ch5 - Internet Data/xmlparsing_finished.py | 23 ++++++------ Ch5 - Internet Data/xmlparsing_start.py | 23 ------------ 8 files changed, 38 insertions(+), 134 deletions(-) delete mode 100644 Ch5 - Internet Data/htmlparsing_start.py delete mode 100644 Ch5 - Internet Data/inetdata_start.py delete mode 100644 Ch5 - Internet Data/jsondata_start.py delete mode 100644 Ch5 - Internet Data/xmlparsing_start.py diff --git a/Ch5 - Internet Data/htmlparsing_finished.py b/Ch5 - Internet Data/htmlparsing_finished.py index 48fa8fe..8308d0f 100644 --- a/Ch5 - Internet Data/htmlparsing_finished.py +++ b/Ch5 - Internet Data/htmlparsing_finished.py @@ -9,6 +9,7 @@ paragraphs = 0 + # create a subclass of HTMLParser and override the handler methods class MyHTMLParser(HTMLParser): # function to handle an opening tag in the doc @@ -18,41 +19,42 @@ def handle_starttag(self, tag, attrs): if tag == "p": paragraphs += 1 - print ("Encountered a start tag:", tag) - pos = self.getpos() # returns a tuple indication line and character - print ("\tAt line: ", pos[0], " position ", pos[1]) + print("Encountered a start tag:", tag) + pos = self.getpos() # returns a tuple indication line and character + print("\tAt line: ", pos[0], " position ", pos[1]) if attrs.__len__() > 0: - print ("\tAttributes:") + print("\tAttributes:") for a in attrs: - print ("\t", a[0],"=",a[1]) - + print("\t", a[0], "=", a[1]) + # function to handle character and text data (tag contents) def handle_data(self, data): if (data.isspace()): return - print ("Encountered some text data:", data) + print("Encountered some text data:", data) pos = self.getpos() - print ("\tAt line: ", pos[0], " position ", pos[1]) - + print("\tAt line: ", pos[0], " position ", pos[1]) + # function to handle the processing of HTML comments def handle_comment(self, data): - print ("Encountered comment:", data) + print("Encountered comment:", data) pos = self.getpos() - print ("\tAt line: ", pos[0], " position ", pos[1]) + print("\tAt line: ", pos[0], " position ", pos[1]) + def main(): # instantiate the parser and feed it some HTML parser = MyHTMLParser() - + # open the sample HTML file and read it f = open("samplehtml.html") if f.mode == "r": - contents = f.read() # read the entire file + contents = f.read() # read the entire file parser.feed(contents) - - print ("Paragraph tags:", paragraphs) + + print("Paragraph tags:", paragraphs) + if __name__ == "__main__": main() - \ No newline at end of file diff --git a/Ch5 - Internet Data/htmlparsing_start.py b/Ch5 - Internet Data/htmlparsing_start.py deleted file mode 100644 index a759ac3..0000000 --- a/Ch5 - Internet Data/htmlparsing_start.py +++ /dev/null @@ -1,29 +0,0 @@ -# -# Example file for parsing and processing HTML -# LinkedIn Learning Python course by Joe Marini -# - -from html.parser import HTMLParser - -class MyHTMLParser(HTMLParser): - def handle_comment(self, data): - pass - - def handle_starttag(self, tag, attrs): - pass - - def handle_data(self, data): - pass - -def main(): - # instantiate the parser and feed it some HTML - parser = MyHTMLParser() - - f = open("samplehtml.html") - if f.mode == "r": - contents = f.read() # read the entire file - parser.feed(contents) - -if __name__ == "__main__": - main() - \ No newline at end of file diff --git a/Ch5 - Internet Data/inetdata_finished.py b/Ch5 - Internet Data/inetdata_finished.py index 656ff92..672b05c 100644 --- a/Ch5 - Internet Data/inetdata_finished.py +++ b/Ch5 - Internet Data/inetdata_finished.py @@ -3,18 +3,20 @@ # LinkedIn Learning Python course by Joe Marini # -import urllib.request # instead of urllib2 like in Python 2.7 +import urllib.request # instead of urllib2 like in Python 2.7 + def main(): # open a connection to a URL using urllib2 webUrl = urllib.request.urlopen("http://www.google.com") - + # get the result code and print it - print ("result code: ", webUrl.getcode()) - + print("result code: ", webUrl.getcode()) + # read the data from the URL and print it data = webUrl.read() - print (data) + print(data) + if __name__ == "__main__": main() diff --git a/Ch5 - Internet Data/inetdata_start.py b/Ch5 - Internet Data/inetdata_start.py deleted file mode 100644 index 86dc094..0000000 --- a/Ch5 - Internet Data/inetdata_start.py +++ /dev/null @@ -1,10 +0,0 @@ -# -# Example file for retrieving data from the internet -# LinkedIn Learning Python course by Joe Marini -# - -def main(): - pass # this is a placeholder, do-nothing statement - -if __name__ == "__main__": - main() diff --git a/Ch5 - Internet Data/jsondata_finished.py b/Ch5 - Internet Data/jsondata_finished.py index d244ebf..b047516 100644 --- a/Ch5 - Internet Data/jsondata_finished.py +++ b/Ch5 - Internet Data/jsondata_finished.py @@ -50,7 +50,7 @@ def main(): # Open the URL and read the data webUrl = urllib.request.urlopen(urlData) print("result code: " + str(webUrl.getcode())) - if (webUrl.getcode() == 200): + if webUrl.getcode() == 200: data = webUrl.read().decode("utf-8") # print out our customized results printResults(data) diff --git a/Ch5 - Internet Data/jsondata_start.py b/Ch5 - Internet Data/jsondata_start.py deleted file mode 100644 index e0da623..0000000 --- a/Ch5 - Internet Data/jsondata_start.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# Example file for parsing and processing JSON -# LinkedIn Learning Python course by Joe Marini -# - -import urllib.request - -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 - - - # output the number of events, plus the magnitude and each event name - - - # for each event, print the place where it occurred - - - # print the events that only have a magnitude greater than 4 - - - # print only the events where at least 1 person reported feeling something - - -def main(): - # define a variable to hold the source URL - # In this case we'll use the free data feed from the USGS - # This feed lists all earthquakes for the last day larger than Mag 2.5 - urlData = "http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.geojson" - - # Open the URL and read the data - webUrl = urllib.request.urlopen(urlData) - print ("result code: " + str(webUrl.getcode())) - - -if __name__ == "__main__": - main() diff --git a/Ch5 - Internet Data/xmlparsing_finished.py b/Ch5 - Internet Data/xmlparsing_finished.py index bfc0309..186fce0 100644 --- a/Ch5 - Internet Data/xmlparsing_finished.py +++ b/Ch5 - Internet Data/xmlparsing_finished.py @@ -6,30 +6,31 @@ 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) - + 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 ("%d skills:" % skills.length) + print("%d skills:" % skills.length) for skill in skills: - print (skill.getAttribute("name")) - + print(skill.getAttribute("name")) + # create a new XML tag and add it into the document newSkill = doc.createElement("skill") newSkill.setAttribute("name", "jQuery") doc.firstChild.appendChild(newSkill) skills = doc.getElementsByTagName("skill") - print ("%d skills:" % skills.length) + print("%d skills:" % skills.length) for skill in skills: - print (skill.getAttribute("name")) - + print(skill.getAttribute("name")) + + if __name__ == "__main__": main() - diff --git a/Ch5 - Internet Data/xmlparsing_start.py b/Ch5 - Internet Data/xmlparsing_start.py deleted file mode 100644 index 3129b0c..0000000 --- a/Ch5 - Internet Data/xmlparsing_start.py +++ /dev/null @@ -1,23 +0,0 @@ -# -# Example file for parsing and processing XML -# LinkedIn Learning Python course by Joe Marini -# - - -def main(): - # use the parse() function to load and parse an XML file - - - # print out the document node and the name of the first child tag - - - # get a list of XML tags from the document and print each one - - - # create a new XML tag and add it into the document - - - -if __name__ == "__main__": - main() - From 37509b133ee18aea2719060752afc238edb7c5bc Mon Sep 17 00:00:00 2001 From: Andy Hopwood Date: Sun, 14 Aug 2022 10:06:29 +0100 Subject: [PATCH 4/8] Update README.md --- README.md | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/README.md b/README.md index 57e45ff..8591b9e 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,5 @@ # Learning Python -This is the repository for the LinkedIn Learning course Learning Python. The full course is available from [LinkedIn Learning][lil-course-url]. - -![Learning Python][lil-thumbnail-url] - -Python—the popular and highly-readable object-oriented language—is both powerful and relatively easy to learn. Whether you're new to programming or an experienced developer, this course can help you get started with Python. Joe Marini provides an overview of the installation process, basic Python syntax, and an example of how to construct and run a simple Python program. Learn to work with dates and times, read and write files, and retrieve and parse HTML, JSON, and XML data from the web. - -## Installing -1. To use these exercise files, you must have the following installed: - - The latest version of Python, at least version 3.9 but preferably 3.10 - - A text editor such as Atom, Visual Studio Code, or another editor -2. Clone this repository into your local machine using the terminal (Mac), CMD or PowerShell (Windows), or a GUI tool like SourceTree. - - You can also just download a ZIP file from Github and extract the contents to your machine. -3. Place the examples folder on your computer where they are easy to get to - - -### Instructor - -Joe Marini - -Senior Director of Product and Engineering - - - -Check out my other courses on [LinkedIn Learning](https://www.linkedin.com/learning/instructors/joe-marini). +This is my repository for learning Python and storing exercise examples. [lil-course-url]: https://www.linkedin.com/learning/learning-python-14393370 [lil-thumbnail-url]: https://cdn.lynda.com/course/2896241/2896241-1637338967910-16x9.jpg From 179bb9decefca214261028dbfd4c1a6958ce2248 Mon Sep 17 00:00:00 2001 From: Andy Hopwood Date: Sun, 14 Aug 2022 10:06:59 +0100 Subject: [PATCH 5/8] Delete CONTRIBUTING.md --- CONTRIBUTING.md | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 164cbd5..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,7 +0,0 @@ - -Contribution Agreement -====================== - -This repository does not accept pull requests (PRs). All pull requests will be closed. - -However, if any contributions (through pull requests, issues, feedback or otherwise) are provided, as a contributor, you represent that the code you submit is your original work or that of your employer (in which case you represent you have the right to bind your employer). By submitting code (or otherwise providing feedback), you (and, if applicable, your employer) are licensing the submitted code (and/or feedback) to LinkedIn and the open source community subject to the BSD 2-Clause license. From a90ea734893d360b00513f9028d8734e4515d0b4 Mon Sep 17 00:00:00 2001 From: Andy Hopwood Date: Sun, 14 Aug 2022 10:07:08 +0100 Subject: [PATCH 6/8] Delete NOTICE --- NOTICE | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 NOTICE diff --git a/NOTICE b/NOTICE deleted file mode 100644 index 4bf8ec7..0000000 --- a/NOTICE +++ /dev/null @@ -1,12 +0,0 @@ -Copyright 2021 LinkedIn Corporation -All Rights Reserved. - -Licensed under the LinkedIn Learning Exercise File License (the "License"). -See LICENSE in the project root for license information. - -Please note, this project may automatically load third party code from external -repositories (for example, NPM modules, Composer packages, or other dependencies). -If so, such third party code may be subject to other license terms than as set -forth above. In addition, such third party code may also depend on and load -multiple tiers of dependencies. Please review the applicable licenses of the -additional dependencies. From c1e382b1c97c75404579f47bd38b32115cc39cdf Mon Sep 17 00:00:00 2001 From: Andy Hopwood Date: Sun, 14 Aug 2022 10:07:18 +0100 Subject: [PATCH 7/8] Delete LICENSE --- LICENSE | 105 -------------------------------------------------------- 1 file changed, 105 deletions(-) delete mode 100644 LICENSE diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 52571f1..0000000 --- a/LICENSE +++ /dev/null @@ -1,105 +0,0 @@ -LinkedIn Learning Exercise Files License Agreement -================================================== - -This License Agreement (the "Agreement") is a binding legal agreement -between you (as an individual or entity, as applicable) and LinkedIn -Corporation (“LinkedIn”). By downloading or using the LinkedIn Learning -exercise files in this repository (“Licensed Materials”), you agree to -be bound by the terms of this Agreement. If you do not agree to these -terms, do not download or use the Licensed Materials. - -1. License. -- a. Subject to the terms of this Agreement, LinkedIn hereby grants LinkedIn -members during their LinkedIn Learning subscription a non-exclusive, -non-transferable copyright license, for internal use only, to 1) make a -reasonable number of copies of the Licensed Materials, and 2) make -derivative works of the Licensed Materials for the sole purpose of -practicing skills taught in LinkedIn Learning courses. -- b. Distribution. Unless otherwise noted in the Licensed Materials, subject -to the terms of this Agreement, LinkedIn hereby grants LinkedIn members -with a LinkedIn Learning subscription a non-exclusive, non-transferable -copyright license to distribute the Licensed Materials, except the -Licensed Materials may not be included in any product or service (or -otherwise used) to instruct or educate others. - -2. Restrictions and Intellectual Property. -- a. You may not to use, modify, copy, make derivative works of, publish, -distribute, rent, lease, sell, sublicense, assign or otherwise transfer the -Licensed Materials, except as expressly set forth above in Section 1. -- b. Linkedin (and its licensors) retains its intellectual property rights -in the Licensed Materials. Except as expressly set forth in Section 1, -LinkedIn grants no licenses. -- c. You indemnify LinkedIn and its licensors and affiliates for i) any -alleged infringement or misappropriation of any intellectual property rights -of any third party based on modifications you make to the Licensed Materials, -ii) any claims arising from your use or distribution of all or part of the -Licensed Materials and iii) a breach of this Agreement. You will defend, hold -harmless, and indemnify LinkedIn and its affiliates (and our and their -respective employees, shareholders, and directors) from any claim or action -brought by a third party, including all damages, liabilities, costs and -expenses, including reasonable attorneys’ fees, to the extent resulting from, -alleged to have resulted from, or in connection with: (a) your breach of your -obligations herein; or (b) your use or distribution of any Licensed Materials. - -3. Open source. This code may include open source software, which may be -subject to other license terms as provided in the files. - -4. Warranty Disclaimer. LINKEDIN PROVIDES THE LICENSED MATERIALS ON AN “AS IS” -AND “AS AVAILABLE” BASIS. LINKEDIN MAKES NO REPRESENTATION OR WARRANTY, -WHETHER EXPRESS OR IMPLIED, ABOUT THE LICENSED MATERIALS, INCLUDING ANY -REPRESENTATION THAT THE LICENSED MATERIALS WILL BE FREE OF ERRORS, BUGS OR -INTERRUPTIONS, OR THAT THE LICENSED MATERIALS ARE ACCURATE, COMPLETE OR -OTHERWISE VALID. TO THE FULLEST EXTENT PERMITTED BY LAW, LINKEDIN AND ITS -AFFILIATES DISCLAIM ANY IMPLIED OR STATUTORY WARRANTY OR CONDITION, INCLUDING -ANY IMPLIED WARRANTY OR CONDITION OF MERCHANTABILITY OR FITNESS FOR A -PARTICULAR PURPOSE, AVAILABILITY, SECURITY, TITLE AND/OR NON-INFRINGEMENT. -YOUR USE OF THE LICENSED MATERIALS IS AT YOUR OWN DISCRETION AND RISK, AND -YOU WILL BE SOLELY RESPONSIBLE FOR ANY DAMAGE THAT RESULTS FROM USE OF THE -LICENSED MATERIALS TO YOUR COMPUTER SYSTEM OR LOSS OF DATA. NO ADVICE OR -INFORMATION, WHETHER ORAL OR WRITTEN, OBTAINED BY YOU FROM US OR THROUGH OR -FROM THE LICENSED MATERIALS WILL CREATE ANY WARRANTY OR CONDITION NOT -EXPRESSLY STATED IN THESE TERMS. - -5. Limitation of Liability. LINKEDIN SHALL NOT BE LIABLE FOR ANY INDIRECT, -INCIDENTAL, SPECIAL, PUNITIVE, CONSEQUENTIAL OR EXEMPLARY DAMAGES, INCLUDING -BUT NOT LIMITED TO, DAMAGES FOR LOSS OF PROFITS, GOODWILL, USE, DATA OR OTHER -INTANGIBLE LOSSES . IN NO EVENT WILL LINKEDIN'S AGGREGATE LIABILITY TO YOU -EXCEED $100. THIS LIMITATION OF LIABILITY SHALL: -- i. APPLY REGARDLESS OF WHETHER (A) YOU BASE YOUR CLAIM ON CONTRACT, TORT, -STATUTE, OR ANY OTHER LEGAL THEORY, (B) WE KNEW OR SHOULD HAVE KNOWN ABOUT -THE POSSIBILITY OF SUCH DAMAGES, OR (C) THE LIMITED REMEDIES PROVIDED IN THIS -SECTION FAIL OF THEIR ESSENTIAL PURPOSE; AND -- ii. NOT APPLY TO ANY DAMAGE THAT LINKEDIN MAY CAUSE YOU INTENTIONALLY OR -KNOWINGLY IN VIOLATION OF THESE TERMS OR APPLICABLE LAW, OR AS OTHERWISE -MANDATED BY APPLICABLE LAW THAT CANNOT BE DISCLAIMED IN THESE TERMS. - -6. Termination. This Agreement automatically terminates upon your breach of -this Agreement or termination of your LinkedIn Learning subscription. On -termination, all licenses granted under this Agreement will terminate -immediately and you will delete the Licensed Materials. Sections 2-7 of this -Agreement survive any termination of this Agreement. LinkedIn may discontinue -the availability of some or all of the Licensed Materials at any time for any -reason. - -7. Miscellaneous. This Agreement will be governed by and construed in -accordance with the laws of the State of California without regard to conflict -of laws principles. The exclusive forum for any disputes arising out of or -relating to this Agreement shall be an appropriate federal or state court -sitting in the County of Santa Clara, State of California. If LinkedIn does -not act to enforce a breach of this Agreement, that does not mean that -LinkedIn has waived its right to enforce this Agreement. The Agreement does -not create a partnership, agency relationship, or joint venture between the -parties. Neither party has the power or authority to bind the other or to -create any obligation or responsibility on behalf of the other. You may not, -without LinkedIn’s prior written consent, assign or delegate any rights or -obligations under these terms, including in connection with a change of -control. Any purported assignment and delegation shall be ineffective. The -Agreement shall bind and inure to the benefit of the parties, their respective -successors and permitted assigns. If any provision of the Agreement is -unenforceable, that provision will be modified to render it enforceable to the -extent possible to give effect to the parties’ intentions and the remaining -provisions will not be affected. This Agreement is the only agreement between -you and LinkedIn regarding the Licensed Materials, and supersedes all prior -agreements relating to the Licensed Materials. - -Last Updated: March 2019 From 3bd908f991280513f13d15a193af10672df64d64 Mon Sep 17 00:00:00 2001 From: AH Date: Sun, 14 Aug 2022 10:25:14 +0100 Subject: [PATCH 8/8] Finished 'Learning Python' --- .../inspectionProfiles/profiles_settings.xml | 6 + Ch3 - Files/.idea/misc.xml | 4 + Ch3 - Files/testzip.zip | Bin 0 -> 570 bytes Libraries/Pendulum/basicdates_finished.py | 38 ++++ Libraries/Pendulum/calculation_finished.py | 54 +++++ Libraries/Pendulum/challengesolution.py | 28 +++ Libraries/Pendulum/formatting_finished.py | 29 +++ Libraries/PyFilesystem/FileExamples.zip | Bin 0 -> 37961 bytes .../PyFilesystem/FileExamples/Dir1/File4.txt | 6 + .../FileExamples/Dir1/WordDoc1.docx | Bin 0 -> 11864 bytes .../FileExamples/Dir1/WordDoc2.docx | Bin 0 -> 11862 bytes .../PyFilesystem/FileExamples/Dir2/File5.rtf | 207 ++++++++++++++++++ .../PyFilesystem/FileExamples/Dir2/File6.rtf | 207 ++++++++++++++++++ Libraries/PyFilesystem/FileExamples/File1.txt | 7 + Libraries/PyFilesystem/FileExamples/File2.txt | 2 + Libraries/PyFilesystem/FileExamples/File3.txt | 8 + Libraries/PyFilesystem/basicfiles_finished.py | 36 +++ Libraries/PyFilesystem/challengesolution.py | 17 ++ .../PyFilesystem/directories_finished.py | 36 +++ Libraries/PyFilesystem/walking_finished.py | 35 +++ Libraries/Requests/advreqs_finished.py | 39 ++++ Libraries/Requests/auth_finished.py | 20 ++ Libraries/Requests/basicreqs_finished.py | 23 ++ Libraries/Requests/responses_finished.py | 22 ++ 24 files changed, 824 insertions(+) create mode 100644 Ch3 - Files/.idea/inspectionProfiles/profiles_settings.xml create mode 100644 Ch3 - Files/.idea/misc.xml create mode 100644 Ch3 - Files/testzip.zip create mode 100644 Libraries/Pendulum/basicdates_finished.py create mode 100644 Libraries/Pendulum/calculation_finished.py create mode 100644 Libraries/Pendulum/challengesolution.py create mode 100644 Libraries/Pendulum/formatting_finished.py create mode 100644 Libraries/PyFilesystem/FileExamples.zip create mode 100644 Libraries/PyFilesystem/FileExamples/Dir1/File4.txt create mode 100644 Libraries/PyFilesystem/FileExamples/Dir1/WordDoc1.docx create mode 100644 Libraries/PyFilesystem/FileExamples/Dir1/WordDoc2.docx create mode 100644 Libraries/PyFilesystem/FileExamples/Dir2/File5.rtf create mode 100644 Libraries/PyFilesystem/FileExamples/Dir2/File6.rtf create mode 100644 Libraries/PyFilesystem/FileExamples/File1.txt create mode 100644 Libraries/PyFilesystem/FileExamples/File2.txt create mode 100644 Libraries/PyFilesystem/FileExamples/File3.txt create mode 100644 Libraries/PyFilesystem/basicfiles_finished.py create mode 100644 Libraries/PyFilesystem/challengesolution.py create mode 100644 Libraries/PyFilesystem/directories_finished.py create mode 100644 Libraries/PyFilesystem/walking_finished.py create mode 100644 Libraries/Requests/advreqs_finished.py create mode 100644 Libraries/Requests/auth_finished.py create mode 100644 Libraries/Requests/basicreqs_finished.py create mode 100644 Libraries/Requests/responses_finished.py diff --git a/Ch3 - Files/.idea/inspectionProfiles/profiles_settings.xml b/Ch3 - Files/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/Ch3 - Files/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/Ch3 - Files/.idea/misc.xml b/Ch3 - Files/.idea/misc.xml new file mode 100644 index 0000000..dc9ea49 --- /dev/null +++ b/Ch3 - Files/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Ch3 - Files/testzip.zip b/Ch3 - Files/testzip.zip new file mode 100644 index 0000000000000000000000000000000000000000..d6f012b4bce9d704de0bb4b0df820ac1fbe748a1 GIT binary patch literal 570 zcmWIWW@Zs#00HShw$QU?Yu>E}vO$;|i1Sj*(=u~X^-3yALNYRo6@VxwGcQ%ake8PW zMZgGMz!+V?1YN)sUBC=oz#Lt`0$sooUBJ))C=vkoQ&bqLp9Fw@DoL# dt2) +print(dt1 < dt2) + +dt3 = pendulum.datetime(2020, 12, 22) +print(dt3 == dt2) +dt3 = dt3.set(second=1) +print(dt3 == dt2) + +# TODO: Create a Period using difference +dt1 = dt1.set(year=2020, month=7, day=28) +p = dt1.diff(dt2) +print(p.in_hours()) +print(p.in_days()) +print(p.in_months()) + +p = dt2.diff_for_humans(dt1) +print(p) diff --git a/Libraries/Pendulum/challengesolution.py b/Libraries/Pendulum/challengesolution.py new file mode 100644 index 0000000..7ee7869 --- /dev/null +++ b/Libraries/Pendulum/challengesolution.py @@ -0,0 +1,28 @@ +# Python Essential Libraries by Joe Marini course example +# Example file for Pendulum library +import pendulum + +# Challenge: how many days until International Clash Day? +# https://www.kexp.org/internationalclashday/ + +# First, let's figure out what day today is +today = pendulum.today() +# Use the general format method to print the day and month +print("Today is: {0}".format(today.format("dddd, MMMM Do"))) + +# Next, create a date to represent International Clash Day +# Which, of course, is February 7 +icd = pendulum.datetime(today.year, 2, 7) +# Use the general format method to print the day and month +print("Internation Clash Day is: {0}".format(icd.format("dddd, MMMM Do"))) + +# Figure out if the day has already gone by +if icd < today: + old = today - icd + print("International Clash Day went by {0} days ago".format(old.days)) + # if so, get the date for next year + icd = icd.add(years=1) + +# Now calculate the number of days until the next one +time_to_afd = icd - today +print("It's {0} days until Internation Clash Day!".format(time_to_afd.days)) diff --git a/Libraries/Pendulum/formatting_finished.py b/Libraries/Pendulum/formatting_finished.py new file mode 100644 index 0000000..cf226df --- /dev/null +++ b/Libraries/Pendulum/formatting_finished.py @@ -0,0 +1,29 @@ +# Python Essential Libraries by Joe Marini course example +# Example file for Pendulum library +import pendulum + +# create a datetime and print it +dt1 = pendulum.datetime(2020, 7, 28, 15, 30) +print(dt1) + +# TODO: use some formatting functions +print(dt1.to_date_string()) +print(dt1.to_time_string()) +print(dt1.to_datetime_string()) + +# TODO: use functions for nice formatting +print(dt1.to_formatted_date_string()) +print(dt1.to_day_datetime_string()) + +# TODO: use some common formats +print(dt1.to_cookie_string()) +print(dt1.to_iso8601_string()) +print(dt1.to_rfc822_string()) + +# TODO: use the format function for pretty printing +print(dt1.format("YYYY MM-DD HH:MM A")) +print(dt1.format("dddd DD MMMM YYYY")) + +# TODO: use localization +print(dt1.format("dddd DD MMMM YYYY", locale="de")) +print(dt1.format("dddd DD MMMM YYYY", locale="fr")) diff --git a/Libraries/PyFilesystem/FileExamples.zip b/Libraries/PyFilesystem/FileExamples.zip new file mode 100644 index 0000000000000000000000000000000000000000..59fccaa49c9b8fd9a7cf649cd5b67ecf34dfd37c GIT binary patch literal 37961 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�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 WSnS|k!oF`A@T%nof&3EL-+l+;-rOVr literal 0 HcmV?d00001 diff --git a/Libraries/PyFilesystem/FileExamples/Dir1/File4.txt b/Libraries/PyFilesystem/FileExamples/Dir1/File4.txt new file mode 100644 index 0000000..9fae01e --- /dev/null +++ b/Libraries/PyFilesystem/FileExamples/Dir1/File4.txt @@ -0,0 +1,6 @@ +This is a sample text file for the Essential Python Libraries course on LinkedIn Learning. + +Somewhere in la Mancha, in a place whose name I do not care to +remember, a gentleman lived not long ago, one of those who has a lance +and ancient shield on a shelf and keeps a skinny nag and a greyhound for +racing. —Miguel de Cervantes, Don Quixote (1605) \ No newline at end of file diff --git a/Libraries/PyFilesystem/FileExamples/Dir1/WordDoc1.docx b/Libraries/PyFilesystem/FileExamples/Dir1/WordDoc1.docx new file mode 100644 index 0000000000000000000000000000000000000000..91ff05bde2cfe71fe72c0e1f7388ef540e658c10 GIT binary patch literal 11864 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