Post

Python Crash Course 10 - Files & errors

I’m YouKoutaku. These codes are from the book python_Crash_Course, 2nd edition. I learned python and took these notes for this book.

10 files and errors

10.1 read dates from files

10.1.1 read all of files

  • open() open a file.
  • close() close a file. But if your program has an error, your file will not be closed.   
  • with open a file , and close it when you not need access to it.
  • as make name of a file.

So with open("Path/file_name") as name of a file can be used to open a file and close it automatically.

1
2
3
with open('Python_Crash_Course,2nd_Edition/files/10_1_1.txt') as f:
    contents = f.read()
print(contents)

10.1.2 path of a file

path: “Path/file_name”. we use / not \ in python.

But in windows, the path of a file is used \.

If you want to ues \, you need to use \\.

  • absolute path of a file is C:\Python_Crash_Course,2nd_Edition\files\file_name.
  • relative path of a file is files\file_name.

10.1.3 read files by lines

This way also reads the blanks in the file. And we can use rstrip() to remove the blanks.

1
2
3
4
filename = '10_1_3.txt'
with open(filename) as file_object:
    for line in file_object:
        print(line)
1
2
3
4
filename = '10_1_3.txt'
with open(filename) as file_object:
    for line in file_object:
        print(line.rstrip())

10.1.4 create a list including all lines of a file.

We can only use files in the with when we use with open() to open a file. If you want to access files outside with, you can use readlines() to read all lines of a file.

1
2
3
4
5
6
filename = '10_1_3.txt'
with open(filename) as file_object:
    lines = file_object.readlines()

for line in lines:
    print(line.rstrip())

10.1.5 using information of a file.

1
2
3
4
5
6
7
8
9
filename = '10_1_4.txt'
with open(filename) as file_object:
    lines = file_object.readlines()

a = ''
for line in lines:
    a += line.strip()
print(a)
print(len(a))
  • strip(): removes the left and right spaces from a string.
  • lstrip(): removes the left spaces from a string.
  • rstrip(): removes the right spaces from a string.

10.1.6 a large data file

To print a large data file, We need to only print to a few decimal places to prevent the terminal from displaying all.

string_name[:number_of_decimal_places]

1
2
3
4
5
6
7
8
9
filename = '10_1_4.txt'
with open(filename) as file_object:
    lines = file_object.readlines()

a = ''
for line in lines:
    a += line.strip()
print(f"{a[:10]}...")
print(len(a))

10.1.7 check information of a file.

1
2
3
4
5
6
7
8
9
10
11
12
filename = 'pi_string.txt'
with open(filename) as file_object:
    lines = file_object.readlines()

a = ''
for line in lines:
    a += line.strip()
birthday = input("Enter your birthday, in the form mmddyy:")
if birthday in a:
    print("Your birthday appears in the first million digits of pi!")
else:
    print("Your birthday does not appear in the first million digits of pi!")

10.2 write in a file

10.2.1 write in a blank file

with open('filename', 'w') as file_object

  • 'r' means read mode.
  • 'w' means write mode.
  • 'a' means append mode.
  • 'r+' means read and write mode.

python only write string to a file.

1
2
3
filename = '10_2_1.txt'
with open(filename, 'w') as file_object:
    file_object.write("Hello, World!")

10.2.2 write multiple lines in a file.

  • \n means new line.
  • \t means tab.
  • \" means double quote.
1
2
3
4
filename = '10_2_1.txt'
with open(filename, 'w') as file_object:
    file_object.write("Hello, World!\n")
    file_object.write("I love Python!\n")

10.2.3 add a line to a file.

append mode means to add a string to a file , not to overwrite the file.

with open('filename', 'a') as file_object:

1
2
3
4
filename = '10_2_1.txt'
with open(filename, 'a') as file_object:
    file_object.write("I also love C!\n")
    file_object.write("I love programming!\n")

10.3 Error

When the program has an error, it will stop and print the error message(Traceback) to the terminal.

10.3.1 ZeroDivisionError

division by zero

1
print(5/0)
1
2
3
4
5
6
7
8
9
---------------------------------------------------------------------------

ZeroDivisionError                         Traceback (most recent call last)

Input In [1], in <cell line: 1>()
----> 1 print(5/0)


ZeroDivisionError: division by zero

10.3.2 try-except

try-except can be used to avoid the error and make the program continue to run.

  • If codes in try have no problem, it will pass the part of except.
  • If codes in try have an error, it will run the part of except.
1
2
3
4
try:
    print(5/0)
except ZeroDivisionError:
    print("division by zero")
1
division by zero

10.3.3 use try-except to avoid crashes

If you don’t use try-except, the program maybe crashes and user can see the traceback. It is not a good practice.

1
2
3
4
5
6
7
8
9
10
11
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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Give me two numbers, and I'll divide them.
Enter 'q' to quit.



---------------------------------------------------------------------------

ZeroDivisionError                         Traceback (most recent call last)

Input In [3], in <cell line: 4>()
      8 if second_number == 'q': 
      9     break 
---> 10 answer = int(first_number) / int(second_number) 
     11 print(answer)


ZeroDivisionError: division by zero

10.3.4 else

else can be used to run code if there is no error.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 cam't division by zero!")
    else:
        print(answer)
1
2
3
4
Give me two numbers, and I'll divide them.
Enter 'q' to quit.
You cam't division by zero!
5.0

10.3.5 FileNotFoundError

FileNotFoundError means raised when a file is not found. So, we can use try-except to avoid the Traceback in the terminal.

1
2
3
filename = 'not_exist.txt'
with open(filename, encoding='utf-8') as f:
    contents = f.read()
1
2
3
4
5
6
7
8
9
10
11
---------------------------------------------------------------------------

FileNotFoundError                         Traceback (most recent call last)

Input In [7], in <cell line: 2>()
      1 filename = 'not_exist.txt'
----> 2 with open(filename, encoding='utf-8') as f:
      3     contents = f.read()


FileNotFoundError: [Errno 2] No such file or directory: 'not_exist.txt'
1
2
3
4
5
6
filename = 'not_exist.txt'
try:
    with open(filename, encoding='utf-8') as f:
        contents = f.read()
except FileNotFoundError:
    print(f"Sorry, the file {filename} is not found!")
1
Sorry, the file not_exist.txt is not found!

10.3.6 Analyzing text

split() splits a string into a list.

1
2
title = "Alice in Wonderland"
print(title.split())
1
['Alice', 'in', 'Wonderland']
1
2
3
4
5
6
7
8
9
10
11
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.") 
else:  
    #compute the number of words in the file.
    words = contents.split() 
    num_words = len(words) 
    print(f"The file {filename} has about {num_words} words.")

10.3.7 using multiple files

make a function for each file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def count_words(filename):
    try: 
        with open(filename, encoding='utf-8') as f: 
            contents = f.read() 
    except FileNotFoundError: 
        print(f"Sorry, the file {filename} does not exist.") 
    else:  
        #compute the number of words in the file.
        words = contents.split() 
        num_words = len(words) 
        print(f"The file {filename} has about {num_words} words.")

filenames = ['alice.txt', 'siddhartha.txt', 'john.txt'] 
for filename in filenames: 
    count_words(filename)

10.3.8 silent for error

pass means pass the part of the code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def count_words(filename):
    try: 
        with open(filename, encoding='utf-8') as f: 
            contents = f.read() 
    except FileNotFoundError: 
        #silent
        pass
    else:  
        words = contents.split() 
        num_words = len(words) 
        print(f"The file {filename} has about {num_words} words.")

filenames = ['alice.txt', 'siddhartha.txt', 'john.txt'] 
for filename in filenames: 
    count_words(filename)

10.3.9 deciding which errors to report

We need to consider when to report errors to users and when to silent. When an error occurs, the user may want to know the reason. At this time, we also need to consider how much information to provide to help the user while ensuring program security and information security.

10.4 storing data

JSON(JaveScript Object Notation) is a way to store data.

10.4.1 json.dumps() and json.loads()

  • json.dumps(data, file_object): to store data in a file.
  • json.loads(file_object): to load data from a file.
1
2
3
4
5
import json
numberers = [2, 3, 5, 7, 11, 13, 17, 1]
filename = '10_files/numbers.json'
with open(filename, 'w') as f:
    json.dump(numberers, f)
1
2
3
4
5
import json
filename = '10_files/numbers.json'
with open(filename) as f:
    numberers=json.load(f)
print(numberers)
1
[2, 3, 5, 7, 11, 13, 17, 1]

10.4.2 save and reload user data

1
2
3
4
5
6
7
#save
import json
username = input("Enter your name?")
filename = '10_files/username.json'
with open(filename, 'w') as f:
    json.dump(username, f)
    print(f"We'll remember you when you come back, {username}.")
1
We'll remember you when you come back, youkoutaku.
1
2
3
4
5
6
#reload
import json
filename = '10_files/username.json'
with open(filename) as f:
    username = json.load(f)
    print(f"welcome back, {username}!")
1
welcome back, youkoutaku!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#save and reload
import json 

filename = '10_files/username.json'

try:
    with open(filename) as f:
        username = json.load(f)
except FileNotFoundError:
    username = input("Enter your name?")
    with open(filename, 'w') as f:
        json.dump(username, f)
        print(f"We'll remember you when you come back, {username}.")
else:
    print(f"welcome back, {username}!")
1
welcome back, youkoutaku!

10.4.3 Reconstruction

Even the program can currently run, but usually we need to create some functions to reconstruct it. it makes codes easier to understand and expand.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def greet_user():
    """greet user using the username"""
    filename = '10_files/username.json'
    try:
        with open(filename) as f:
            username = json.load(f)
    except FileNotFoundError:
        username = input("Enter your name?")
        with open(filename, 'w') as f:
            json.dump(username, f)
            print(f"We'll remember you when you come back, {username}.")
    else:
        print(f"welcome back, {username}!")

greet_user()
1
welcome back, youkoutaku!

For easier to understand, we reconstruct the greet_user function. get_stored_username is a function that returns the stored username.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import json
def get_stored_username():
    """if there is a stored username, return it"""
    filename = '10_files/username.json'
    try:
        with open(filename) as f:
            username = json.load(f)
    except FileNotFoundError:
        return None
    else:
        return username
def greet_user():
    """ greet user using the stored username"""
    username = get_stored_username()
    if username:
        print(f"welcome back, {username}!")
    else:
        username = input("Enter your name?")
        with open(filename, 'w') as f:
            json.dump(username, f)
            print(f"We'll remember you when you come back, {username}.")

greet_user()
1
welcome back, youkoutaku!

Then, we create a function get_new_username() that creates new username.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import json
def get_stored_username():
    """if there is a stored username, return it"""
    filename = '10_files/username.json'
    try:
        with open(filename) as f:
            username = json.load(f)
    except FileNotFoundError:
        return None
    else:
        return username
def get_new_username():
    """create a new username"""
    username = input("Enter your name?")
    filename = '10_files/username.json'
    with open(filename, 'w') as f:
        json.dump(username, f)
    return username
def greet_user():
    """ greet user using the stored username"""
    username = get_stored_username()
    if username:
        print(f"welcome back, {username}!")
    else:
        username = get_new_username()
        print(f"We'll remember you when you come back, {username}.")

greet_user()
1
welcome back, youkoutaku!

So the new program is easier to understand and expand through reconstructing the function.

This post is licensed under CC BY 4.0 by the author.