Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Sage beginners guide - Finch Kraigh copy.pdf
Скачиваний:
13
Добавлен:
10.02.2015
Размер:
5.86 Mб
Скачать

Chapter 4

To create a plot like the one shown below, these two plotting statements should be placed before the loop:

plt.figure(figsize=(6,4)) # open new plotting window

plt.hold(True)

# keep old plots

Your loop should include only one plotting statement in the loop body:

pylab.plot(x, profile) # plot the profile

The rest of the plotting statements should come after the loop.

List comprehensions

A list comprehension is a way of creating a list that is similar to a for loop, but more compact.

Timeforaction–usingalistcomprehension

Let's see how list comprehensions work by comparing them to a for loop that performs a similar operation. Enter the following code in a text file or an input cell in a worksheet:

list1 = [' a ', '

b ', 'c ']

list1_stripped = [] for s in list1:

list1_stripped.append(s.strip()) print(list1_stripped)

list1_stripped_2 = [s.strip() for s in list1]

[ 99 ]

Introducing Python and Sage

print(list1_stripped_2)

list2 = []

for val in srange(0.0, 10.0, 1.0): if val % 2 == 0:

list2.append(numerical_approx(val**2, digits=3)) print(list2)

list3 = [numerical_approx(val**2, digits=3) for val in srange(0.0, 10.0, 1.0) if val % 2 == 0]

print(list3)

Run the example. You should get:

What just happened?

This example demonstrated how a list comprehension can be used in place of a for loop to create a list. In the first part of the example, we defined a list of strings, each of which contained whitespace before and/or after the character. First, we defined an empty list and used a for loop to iterate over the list of strings. The string method strip was used to remove the whitespace from each string, and we used the list method append to create a new list of stripped strings. We then used a list comprehension to perform the same operation. The general syntax for a list comprehension is:

new_list = [ operation_on_value for value in existing_list ]

If you are creating a new list, then the existing list can be generated by a function like range or srange. In the second part of the example, we used a for loop with the srange function to generate a list of even floating-point numbers. We used an if clause so that our list

will contain only squares of even numbers. We did this to demonstrate how the if clause works—a better way to generate a list of even numbers would be to give srange a step size of two. We then repeated the operation with a list comprehension. We'll learn more about if statements soon. List comprehensions are somewhat more compact than an equivalent for loop. For more examples of list comprehensions, see http://docs.python.org/ tutorial/datastructures.html#list-comprehensions

[ 100 ]

Chapter 4

WhileloopsandtextfileI/O

Lists and loops are the two basic tools we need to access data that is stored in a file. The problem with using a for loop to access a data file is that we don't necessarily know how many iterations will be needed, because we don't always know how many lines are in the file. The solution is to use a while loop.

Timeforaction–savingdatainatextfile

Let's save the results of a calculation to a text file. In the next example, we will get the data back into Sage. When you enter the following code, change the path to the data file so that it gets saved in a convenient location.

from matplotlib import pyplot as plt import os

# Create some data

times = srange(0.0, 10.0, 0.1) data = [sin(t) for t in times]

#Plot the data plt.figure(figsize=(6,4)) plt.plot(times, data) plt.savefig('example2a.png') plt.close()

#Save data to a text file

path = '/Users/cfinch/Documents/Writing/Sage for Beginners/Chapters/ Chapter 4/'

fileName = 'data.txt'

text_file = open(os.path.join(path, fileName), 'w') for i in range(len(data)):

text_file.write('{0}, {1}{2}'.format(times[i], data[i], os.linesep))

text_file.close()

[ 101 ]

Introducing Python and Sage

Run the script using one of the methods previously described. A plot of the data is saved to a

PNG file, and the data is saved to a text file with two columns. The plot should look like this:

The first few lines of the text file should look like this:

0.000000000000000, 0.000000000000000 0.100000000000000, 0.0998334166468282 0.200000000000000, 0.198669330795061

What just happened?

We used the srange function to generate a list of time points, and then used a list comprehension to create a list containing the sine of each time point. We plotted the data, using the pyplot interface to matplotlib, like we did in a previous example. The data was then saved to a text file.

The file object is the key component in file operations. A file object is created using the open function:

text_file_object = open('data.txt', 'w')

The first argument to open is a string containing the name of the file. The second argument is a string that indicates in which mode the file should be opened. The first letter of the mode string chooses read, write, or append mode. The letter b can be appended to the mode string to indicate that the file should be opened in binary mode. If the mode string is omitted, the file is opened for reading in text mode.

[ 102 ]

 

 

Chapter 4

 

 

 

 

Text

Binary mode

Result

mode

string

 

 

string

 

 

 

r

rb

File is opened for reading. The file must already exist. Attempting to

 

 

write to the file returns an error.

w

wb

File is opened for writing. If the file exists, it will be overwritten.

a

ab

File is opened for appending. Data that is written to the file will be

 

 

appended at the end of the file.

 

If you open a file in text mode, the special character \n may be converted to the appropriate newline character for your platform. If you don't want this conversion to happen, add the letter 'b' to the end of the mode string to open the file in binary mode.

We used the write method of the file object to write data to the file:

text_file.write(my_string)

The write method accepts one argument, which is the string to be written to the file. When we were finished with the file, we used the close method to close it. It's very important to close a file, especially when the file is open for writing. Many operating systems buffer data, rather than writing every little piece of data to the file. Closing the file is the easiest way to ensure that all of the data actually gets written to the file.

We used a module called os from the Python standard library module to help us write code that can run on multiple platforms. A text file must have a special character to denote the end of each line in the file. Unfortunately, for historical reasons, each family of operating systems (Mac, Windows, and UNIX) uses a different end-of-line character. The os module has a constant called linesep that contains the correct character for the platform that the code is run on. We used the statement import os to make the module available, and accessed the constant using the syntax os.linesep. We also used the function os.path.join to join the path to the file name with the correct character for the current operating system.

Timeforaction–readingdatafromatextfile

Now, we will read the data from the text file. This is a good place to demonstrate the while loop, since we won't always know in advance how many lines are in the file. Run the following code to load the data.

from matplotlib import pyplot as plt import os

path = '/Users/cfinch/Documents/Writing/Sage for Beginners/Chapters/ Chapter 4/'

fileName = 'data.txt'

[ 103 ]

Introducing Python and Sage

# Read in the data file times = []

data = []

text_file = open(os.path.join(path, fileName), 'r') line = text_file.readline()

while len(line) > 0: print(line)

#split each line into a list of strings elements = line.split(',')

#Strip newlines and convert strings to real numbers times.append(float(elements[0].strip())) data.append(float(elements[1].strip()))

line = text_file.readline()

text_file.close()

# Plot the data plt.figure() plt.plot(times, data) plt.savefig('example2b.png') plt.close()

The data is plotted to another image file. This plot should be identical to the plot in the previous example. When you run this example in the Notebook interface, Sage will not print every line of the file. When text output gets too long, Sage will truncate the output and provide a link that you can click to see the rest of the output. The result will look like this:

[ 104 ]

Chapter 4

What just happened?

This script demonstrated how to open a text file for reading and read in one line at a time. The open function was used to create a file object as previously described. Since we are reading data, the readline method was used to read one line of data from the file and return the line as a string. Once again, we used the os module to handle operations involving paths and newlines.

Whileloops

A while loop is used when we don't know how many iterations will be required. The general syntax for a while loop is:

while conditional_expression: statement 1

statement 2

...

The loop iterates as long as the conditional expression evaluates to the Boolean value True. The loop terminates as soon as the expression evaluates to False. In this example, the loop iterates as long as the string that is read from the file has one or more characters. The readline method returns a string for every line in the file. Even a blank line has a newline character, so the conditional expression will be True for every line in the file. The readline method returns an empty string after reading the last line of the file, which causes the conditional expression to evaluate to False and end the loop. There are two very important things to remember when using a while loop:

1.Make sure the conditional expression can be evaluated before the first iteration of the loop. In the example, the first line is read from the file before the while loop.

2.Make sure that the conditional expression will evaluate to False at some point. Otherwise, the loop will repeat endlessly. The last statement of the loop in the example loads another line from the file. When the end of the file is reached, the conditional expression will evaluate to False.

Parsingstringsandextractingdata

Since each line of the file was read as single string, we had to do some work to extract the numerical data. First, we used the split method of the string object to break the string at the comma:

elements = line.split(',')

[ 105 ]

Introducing Python and Sage

The result was a list of strings called elements. The first element of this list is the string that contains the time value. Next, we used the strip method of the string object to remove any unnecessary white space, such as the invisible newline character that is found at the end of every line:

elements[0].strip()

Finally, we used the float function to convert the string to a Python floating-point number, and appended the result to a list. In the example, the parsing operations were combined like this:

times.append(float(elements[0].strip()))

data.append(float(elements[1].strip()))

Finally, the lists are ready to be plotted.

Alternativeapproachtoreadingfromatextfile

A Python file object is iterable, which means that you can iterate over a file object just like you can iterate over a list. This allows you to use the following syntax:

for line in text_file:

#split each line into a list of strings elements = line.split(',')

#Strip newlines and convert strings to real numbers times.append(float(elements[0].strip()))

When using this approach, you should not include a call to text_file.readline() in the loop body.

Haveagohero–defineafunctionforreadingthetextfile

It's good practice to organize your code as you're writing. In the previous example, we should separate the code that reads the data from the file from the code that does the plotting. Define a function that takes a file name as an argument and reads the data. Use a tuple to return a list of time values and a list of data values. Call the function to read the data, and to plot the data.

[ 106 ]

Chapter 4

Haveagohero–replaceaforloopwithawhileloop

In a previous example, we used a for loop to sum up the first 100 terms of an infinite series. The number 100 was chosen somewhat arbitrarily because it happened to work for this particular example. Some infinite series may require more than 100 terms to converge, while others may only require a few terms. We can improve this aspect of the program by replacing the for loop that performs the summation with a while loop. The summation should continue until the sum changes very little from one iteration to the next.

Ifstatementsandconditionalexpressions

We have already seen conditional expressions in the context of while loops. Conditional expressions can be used with if statements to allow a program to make decisions while it is running. There are numerous applications for if statements. For example, they can be used to detect invalid values and prevent errors:

input_value = 1e99

if input_value > 1e10:

print("Warning: invalid parameter detected.") else:

print("--- Start of iteration ---")

The general syntax for an if statement is the following:

if conditional_expression: statements

else: statements

The else clause is optional. Python doesn't have a switch statement for choosing between multiple values. Instead, it has a special keyword called elif, which is a contraction of "else if." This can be used to emulate a switch statement. For example, we can use if with elif to choose an algorithm based on user input:

solution_type = "numerical"

if solution_type == "analytical": print('analytical')

elif solution_type == "numerical": print("numerical")

elif solution_type == "symbolic": print("symbolic")

else:

print("ERROR: invalid solution type")

[ 107 ]

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]