From dc9935d2c7fddc903b40983ff875e11d7e8d8de7 Mon Sep 17 00:00:00 2001 From: JasonHomeWorkstationUbuntu Date: Tue, 8 Sep 2020 17:17:39 +1000 Subject: [PATCH] Finished Chapter 10 --- .gitmodules | 3 + chap10_file_exceptions.md | 121 ++++++++++++++++++++++++++++++++++++++ pcc | 1 + pcc_2e | 1 + src/alice.py | 7 +++ src/divison_calculator.py | 17 ++++++ 6 files changed, 150 insertions(+) create mode 100644 .gitmodules create mode 100644 chap10_file_exceptions.md create mode 160000 pcc create mode 160000 pcc_2e create mode 100644 src/alice.py create mode 100644 src/divison_calculator.py diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e02cb02 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "pcc_2e"] + path = pcc_2e + url = git@github.com:ehmatthes/pcc_2e.git diff --git a/chap10_file_exceptions.md b/chap10_file_exceptions.md new file mode 100644 index 0000000..5cde039 --- /dev/null +++ b/chap10_file_exceptions.md @@ -0,0 +1,121 @@ +# Chapter 10. Files and Exceptions + +Files operation skipped here. Directly head to Exception + +## Exceptions + +* **exceptions** = objects python use to manage errors that arise during a program's execution. +* When python unsure what to do, exception object is created. + * If exceptions are handled correctly, program can continue run + * If don't handle exception, program will halt and show *traceback* + +Syntax of exception handling: `try-except` + +* `try` tells python do sth +* `except` tell python what to do if an exception is raised. + +### e.g. ZeroDivisionError Exception + +* Simple error, python will create `ZeroDivisionError` in response to do "Divide by Zero". +* When you think an error may occur, you can write a `try-except` block to handle exception + +```python +try: + print(5/0) +except ZeroDivisionError: + print("You can't divide by zero!") +``` + +If more code followed `try-except` block, the program would continue running. e.g. as shown below + +### Using Exceptions to Prevent Crashes + +Handling errors correctly is important when the program has more work to do after the error occurs. + +```python +print("Give me two numbers, and I'll divide them.") +print("Enter 'q' to quit.") + +while True: + first_number = input("\nFirst number: ") + if first_number == 'q': + break + second_number = input("Second number: ") + if second_number == 'q': + break + + answer = int(first_number) / int(second_number) + print(answer) +``` + +This function ask for numbers and will calculate division. To properly cover potential failure, use `try-except-else` block + +* `try` block: Python attempts to run code +* `except` block: catch possible error +* `else` block: if division operation is successful, carry on! + +Hence, program can be more robust + +```python + try: + answer = int(first_number) / int(second_number) + except ZeroDivisionError: + print("You can't divide by 0!") + else: + print(answer) +``` + +### Handling FileNotFoundError Exception + +```python +filename = 'alice.txt' + +with open(filename, encoding='utf-8') as f: + contents = f.read() +``` + +If python cannot find `alice.txt`, it will raise halt, and show traceback + +``` +Traceback (most recent call last): + File "alice.py", line 6, in + with open(filename, encoding='utf-8') as f: +FileNotFoundError: [Errno 2] No such file or directory: 'alice.txt' +``` + +After changing python code to + +```python +filename = 'alice.txt' + +try: + with open(filename, encoding='utf-8') as f: + contents = f.read() +except FileNotFoundError: + print(f"Sorry, the file {filename} does not exist") +``` + +Python will show "Sorry, the file alice.txt does not exist" + +### Failing Silently + +If you want the program to fail silently and carry on, use `pass` to tell Python to do nothing, and skip the try-except-else blocks + +```python +def count_words(filename): + """Count the approximate number of words in a file.""" + try: + --snip-- + except FileNotFoundError: + pass + else: + --snip-- + + filenames = ['alice.txt', 'siddhartha.txt', 'moby_dick.txt', 'little_women.txt'] + for filename in filenames: + count_words(filename) +``` + +## Storing Data + +`json.dump()` & `json.load` \ No newline at end of file diff --git a/pcc b/pcc new file mode 160000 index 0000000..f555082 --- /dev/null +++ b/pcc @@ -0,0 +1 @@ +Subproject commit f555082df0f8268b8f269e59a99da8ed5013f749 diff --git a/pcc_2e b/pcc_2e new file mode 160000 index 0000000..078318e --- /dev/null +++ b/pcc_2e @@ -0,0 +1 @@ +Subproject commit 078318e4c5a56959586a14dc03e988e9491d4cec diff --git a/src/alice.py b/src/alice.py new file mode 100644 index 0000000..c17c2af --- /dev/null +++ b/src/alice.py @@ -0,0 +1,7 @@ +filename = 'alice.txt' + +try: + with open(filename, encoding='utf-8') as f: + contents = f.read() +except FileNotFoundError: + print(f"Sorry, the file {filename} does not exist") \ No newline at end of file diff --git a/src/divison_calculator.py b/src/divison_calculator.py new file mode 100644 index 0000000..1779b24 --- /dev/null +++ b/src/divison_calculator.py @@ -0,0 +1,17 @@ +print("Give me two numbers, and I'll divide them.") +print("Enter 'q' to quit.") + +while True: + first_number = input("\nFirst number: ") + if first_number == 'q': + break + second_number = input("Second number: ") + if second_number == 'q': + break + + try: + answer = int(first_number) / int(second_number) + except ZeroDivisionError: + print("You can't divide by 0!") + else: + print(answer) \ No newline at end of file