Skip to content

Learning Python: Day 32

Large files: One Million Digits

  • start with a text file that contains pi to 1,000,000 decimal places, instead of 30
  • can create a single string
  • same program, but we’ll pass it a different file
  • we’ll only print the first 50 decimal places

pi_string.py

from pathlib import Path

path = Path(‘pi_million_digits.txt’)

contents = path.read_text()

lines = contents.splitlines()

pi_string = “

for line in lines:

….pi_string += line.lstrip()

print(f”{pi_string[:52]}…”)

print(len(pi_string))

3.14…02

  • can work with as much data as your system’s memory can handle

Is your birthday contained in Pi

  • let’s check if a birthday is found in the first million digits of pi
  • we’ll express each birthday as a string of digits and see if it appears in pi_string

pi_birthday.py

–snip–

for line in lines:

….pi_string += line.strip()

birthday = input(‘Enter your birthday, in the form mmddyy: “)

if birthday in pi_string:

….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.”)

  • first prompt for the user’s birthday, then check if the string is in pi_string

Enter your birthdate, in the form mmddyy: 120372

Your birthday appears in the first million digits of pi!

Writing to a file

  • save data by writing text to a file
  • output is available after closing the terminal
  • can examine output or write programs that read the text back into memory

Writing a single line

  • once a path is defined, you can write to a file using the write_text() method

write_message.py

from pathlib import Path

path = Path(‘programming.txt’)

path.write_text(“I love programming.”)

  • the write_text() method takes a single argument: the sting you want to write
  • this program doesn’t have a terminal output, but if you open the file programming.txt, you’ll see one line

programming.txt

I love programming.

  • can open this file, write new text, copy from it, paste to it, and so on
  • Python can only write strings to a text file
  • to store numerical data in a text file, you’ll have to convert the date to string format using the str() function

Writing multiple lines

  • write_text() method does a few things
  • if the file that path points to doesn’t exist, it creates the file
  • after writing the string to the file, it makes sure the file is closed properly
  • files that aren’t closed properly can lead to missing or corrupted data
  • to write more than one line to a file, you need to build a string containing the entire contents of the file, and then call write_text() with that string

from pathlib import Path

contents = “I love programming./n”

contents += “I love creating new games.\n”

contents += “I also love working with data.\n”

path = Path(‘programming.txt’)

path.write_text(contents)

  • define a variable called contents that holds the entire contents of the file
  • user the += operator to add to his string
  • include newline characters at the end of each line, to make sure each statement appears on its own line
  • if you run this and then open programming.txt, you’ll see each of these lines in the text file

I love programming.

I love creating new games.

I also love working with data.

  • can use spaces, tab characters, and blank lines to format your output, just like with terminal-based output
  • if you call write_text() on a path object that already exists, write_text() will overwrite the contents of the file and write new contents to it

Exceptions

  • exceptions – manage errors that arise during a program’s execution
  • Python creates an exception object when it is unsure of what to do after an error occurs
  • if you write code that handles the exception, the program continues running, otherwise, it will halt
  • traceback = includes a report of the exception that was raised
  • try-except block – handles exception that asks Python what to do if an exception is raised
  • program will continue to run when things go down

Handling the ZeroDivisionError exception

  • let’s look at a simple error that causes Python to raise an exception

division_calculator.py

print(5/0)

Traceback error

ZeroDivisionError: division by zero

  • ZeroDivisionError – is an exception object
  • Python creates this kind of object in response to a situation where it can’t do what we ask
  • Python stops the program to tell us the kind of exception that was raised
  • can use this info to modify our program and tell Python what to do when this kind of exception occurs

Using try-except blocks

  • use a try-except block when you think an error may occur to handle the exception that might be raised

try:

….print(5/0)

except ZeroDivisionError:

….print(“You can’t divide by zero!”)

  • put print(5/0), the line that caused the error, inside a try block
  • if the code in a try block works, Python skips over the except block
  • if the code causes an error, Python looks for an except block whose error matches the one that was raised and runs the code in that block
  • in this instance, the code in the try block produces a ZeroDivisionError, so Python looks for an except block telling it how to respond
  • Python then runs the code in that block and the user sees a friendly error message instead of a traceback

You can’t divide by zero!

  • if more code followed the try-except block, the program would continue running

Using exceptions to prevent crashes

  • handling errors correctly is especially important when the program has more work to do after the error occurs
  • happens often when programs prompt users for input
  • if the program responds to invalid input appropriately, it can prompt for more valid input instead of crashing

division_calculator.py

print(“Give me two numbers, and I’ll divide them.”)

print(“Enter ‘q’ to quit.”)

while True:

….first_number = input(“\nFirst number: “)

….if ifrst_number == ‘q’:

……..break

….second_number = input(“Second number: “)

….if second_number == ‘q’:

……..break

….answer = int(first_number) / int(second_number)

….print(answer)

  • this program prompts the user to input a first_number
  • if the user does not enter q to quit, a second_number
  • then divide these two numbers to get an answer
  • this program does nothing to handle errors, so asking to to divide by zero causes it to crash

Give me two numbers, and I’ll divide them.

Enter ‘q’ to quit.

First number: 5

Second number: 0

Traceback error

ZeroDivisionError: division by zero

  • don’t let users see tracebacks, bad experience for nontechnical users, attackers can learn more than you want them to, such as the name of your program file, and they’ll see part of your code isn’t working properly
  • skilled attacker can use this info to determine which kind of attacks to use against your code

The else block

  • can make this program more error resistant by wrapping the line that might produce errors in a try-except block
  • error occurs on the line that performs the decision, so we’ll put the try-except block there
  • this example includes an else block
  • any code that depends on the try block executing successfully goes in the else block

–snip–

while True:

….–snip–

….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)

  • ask Python to try to complete the division operation in a try block, which includes only the code that might cause an error
  • any code that depends on the try block succeeding is added to the else block
  • in this case, if the division operation is successful, we use the else block to print the result
  • the except block tells Python how to respond when a ZeroDivisionError arises
  • if the try block doesn’t succeed because of a division-by-zero error, we print a friendly message telling the user how to avoid this kind of error
  • program runs and the user never sees a traceback

Give me two numbers, and I’ll divide them.

Enter ‘q’ to quit.

First number: 5

Second number: 0

You can’t divide by 0!

First number: 5

Second number: 2

2.5

First number: q

  • the only code that should go in a try block is code that might cause an exception to be raised
  • sometimes you’ll have additional code that should run only if the try block was successful, this code goes in the else block
  • the except block tells Python what to do in case a certain exception arises when it tries to run the code in the try block
  • anticipate likely errors to write robust programs that run despite invalid data and missing resources
  • your code will be resistant to innocent user mistakes and malicious attacks

Handling the FileNotFoundError exception

  • handling missing files is common when working with files
  • file might be in a different location, filename might be misspelled, or may not exist
  • can handle all of these situations with a try-except block
  • the following program tries to read the contents of Alice in Wonderland, but we haven’t save the file alice.txt in the same directory as alice.py

alice.py

from pathlib import Path

path = Path(‘alice.txt’)

contents = path.read_text(encoding=’utf-8′)

  • we’re using read_text() differently
  • encoding argument is ended when your system’s default encoding doesn’t match the encoding of the file that’s being read
  • this is most likely to happen when reading from a file that wasn’t created on your system
  • Python can’t read from a missing file so it raises an exception

Traceback error (more complex)

FileNotFoundError: [Errno 2] No such file or directory: ‘alice.txt’

  • best to start at the end of a complex traceback
  • last line see a FileNotFoundError exception was raised
  • this is important because it tells us what kind of exception to use in the except block that we’ll write
  • at the beginning of the traceback we see the error occurred in line 4 in the file alice.py
  • next line shows the line of code that caused the error
  • the rest of the traceback shows some code from the libraries that are involved in opening and reading from files
  • don’t usually need to read through all of the lines in a traceback
  • try block will begin with the lines that was identified as problematic in the traceback to hand the error being raised
  • in this instance, this is the line that contains read_text()

from pathlib import Path

path = Path(‘alice.txt’)

try:

….contents = path.read_text(encoding=’utf-8′)

except FileNotFoundError:

….print(f”Sorry, the file {path} does not exist.”)

  • in this example, the code in the try block produces a FileNotFoundError, so we write an except block that matches that error
  • Python runs the code in that block when the file can’t be found

Sorry, the file alice.txt does not exist.

  • program has nothing more to do if the file doesn’t exist, so this is all the output we see

End of study session.

Tags:

Leave a Reply

Your email address will not be published. Required fields are marked *