Chapter 17 Applied Python Exercise 6
17.1 Goal – recreate the Bash tool head
in Python; adding some new functionality that skips header lines
Write Python code that recreates the Bash tool head
, displaying a default number of lines in an input file if a specific number of lines isn’t specified; but extend the tool so that it skips header lines (specifically, for this example, lines that start with a pound sign (#
)).
17.2 Learning Objectives
After going through this chapter, students should be able to:
- State the sub-steps needed to meet the coding goal
- Use the following datatypes, structures, and fundamentals to meet the coding goal:
- importing modules
- variable assignment
- list indexing
- list length
- integer conversion
- opening a file
- initializing a counter variable before a for loop
- updating a counter variable within a the body of a for loop
- for loop
- chaining logical expressions
- looking at the character a line starts with
- conditional statement
- printing output
17.3 Coding Blueprint
Let’s again start with and edit the pseudocode from the previous chapter to meet the needs of this chapter.
Previous chapter’s pseudocode:
First, we need to SET the input file
Next, IF the user-specified a desired number of lines to display
THEN we need to SET the desired number of displayed lines
END IF
OTHERWISE
THEN we need to SET the desired number of displayed lines to a default
END OTHERWISE
Then, FOR every line in the open file
IF a desired line (by its numerical position)
PRINT the line
END IF
END FOR
We do want to edit this past pseudocode, adding a condition that should be true before we print a line. Edit that line of the pseudocode, expanding it with logical expression language to reflect this change in the program behavior.
ANSWER:
First, we need to SET the input file
Next, IF the user-specified a desired number of lines to display
THEN we need to SET the desired number of displayed lines
END IF
OTHERWISE
THEN we need to SET the desired number of displayed lines to a default
END OTHERWISE
Then, FOR every line in the open file
IF a desired line (by its numerical position) AND NOT a header line (line doesn’t start with a pound sign #
)
PRINT the line
END IF
END FOR
We also can no longer assume that the numerical position of the line within the file corresponds to the number of lines that have been printed since we’re filtering out the header. Therefore, we need to track the number of lines that have been printed. Add two lines to the pseudocode that will help you do this, and further edit the conditional that we check before printing a line. As a hint for those, this is the first time we’ll be using the third optional component of a for
loop: initializing a variable before the for
loop (and then subsequently) updating it within the body of the loop.
ANSWER:
First, we need to SET the input file
Next, IF the user-specified a desired number of lines to display
THEN we need to SET the desired number of displayed lines
END IF
OTHERWISE
THEN we need to SET the desired number of displayed lines to a default
END OTHERWISE
SET counter of number of lines that have been displayed to 0
Then, FOR every line in the open file
IF a desired line (counter hasn’t reached desired number of lines) AND NOT a header line
PRINT the line
SET counter to ADD one
END IF
END FOR
17.4 Building the code
Create a new Python script
17.4.1 Usage statement and module importing
The usage statement and module importing from the previous Applied Python Exercise chapter are still accurate for this chapter, so go ahead and reuse the usage and import statements from the fifth Applied Python Exercise chapter within your new Python script.
ANSWER:
#USAGE: python scriptname.py input_filename [number_lines_to_display]
import sys
17.4.2 SET the input filename
Within your Python script, set the filename variable to be equal to the first command line argument like you did in fourth and fifth Applied Python Exercise chapters.
ANSWER:
= sys.argv[1] filename
17.4.3 IF the user-specified a desired number of lines to display
Within your Python script, set up the conditional statement structure like you did in the fifth Applied Python Exercise chapter to check if the user has provided a desired number of lines to display.
ANSWER:
if len(sys.argv) > 2:
17.4.4 THEN SET the desired number of lines
Within your Python script, use the variable assignment statement from the fourth and fifth Applied Python exercise chapters to define the desired number of lines as specified by the user, indenting under the conditional statement.
ANSWER:
= int(sys.argv[2]) n_lines
17.4.5 OTHERWISE
Use the alternate conditional statement structure from the fifth Applied Python Exercise chapter to start defining the alternate behavior we will want (in how we define the desired number of lines variable in cases where the user didn’t specify a specific value). Put this statement in your Python script.
ANSWER:
else:
17.4.6 THEN SET the desired number of lines to a default
Use the alternate variable assignment statement from the fifth Applied Python Exercise chapter to define the desired number of lines variable if the user didn’t specify a specific value. Put this statement in your Python script, indented correctly.
ANSWER:
= 10 n_lines
17.4.7 SET counter of number of lines that have been displayed to 0
Because we no longer assume that the numerical position of the line within the file corresponds to the number of lines that are printed, since we’re filtering out the header lines, we need to define a counter variable we can use to track the number of lines that we print. When first initializing this variable, we haven’t printed any lines. Therefore, you want to set the counter variable equal to the value of zero. Do this within your Python script.
ANSWER:
= 0 counter
17.4.8 FOR every line in the open file
Next, we no longer need to track the position of the line in the file. We only want to work with each line line-by-line in the open file. Therefore, we can go back to the for
loop statement that we used in the first Applied Python Exercise chapter. Add the appropriate for
loop statement to your Python script.
ANSWER:
for line in open(filename):
17.4.9 IF a desired line (because counter hasn’t reached the desired number of lines) and NOT a header line
Let’s break this task down into two separate conditions and then chain the conditions together into one conditional expression.
First, we want to check if the value of the counter is less than the number of desired lines. Write an expression that will evaluate to a boolean variable answering whether an integer is less than another integer. Use the appropriate variable names that refer to the integer variable we’re interested in.
ANSWER:
< n_lines counter
Next, we want to verify that the specific line we’re working with is not a header line. Specifically, does the line not start with a pound sign ("#"
)? Consult the Python notes on negating a boolean expression and checking if a string variable starts with a specific character. Then write an expression that will evaluate to a boolean variable answering whether the line does not start with the pound sign ("#"
). Make sure to use the appropriate variable name in the expression.
ANSWER:
not line.startswith("#")
Now, chain the expressions together within your Python script to form a chained conditional expression, within the body of the for
loop, indented correctly under your for
loop statement. Recall that you want both booleans to be True for the conditional’s body (printing the line) to be executed.
ANSWER:
if counter < n_lines and not line.startswith("#"):
17.4.10 PRINT the line
Finally, reuse the code from the first five Applied Python Exercise chapters to print the line, adding this print()
statement indented correctly under the conditional within your Python script.
ANSWER:
print(line.strip('\r\n'))
17.4.11 SET counter to ADD one
If we were to end writing the program now, our script would print every line in the file that wasn’t a header line. What can we do to avoid this and only print the specific number of lines we want?
ANSWER:
To avoid this, we have to update the counter every time we print a line so we have an accurate count of the number of lines we’ve printed.Write a variable assignment statement within your Python script that updates the value of the counter variable, adding one to it. Make sure it is appropriately indented in line with the print statement under the conditional statement.
ANSWER:
= counter + 1 counter
Within your Python script, you should now have the twelve lines of code together which makes our complete intended goal code – code that prints a user specified number of lines from the beginning of a user specified input file, skipping header lines that begin with a pound sign (#
).
Use the command line or the Run button in the online interface to run the Python script and look at the output.
17.5 Complete Intended Goal Code
ANSWER:
#USAGE: #USAGE: python scriptname.py input_filename [number_lines_to_display]
import sys #import module
= sys.argv[1] #SET the input filename
filename if len(sys.argv) > 2: #IF user-specified number of lines provided
= int(sys.argv[2]) #SET the desired number of lines
n_lines else: #OTHERWISE
= 10 #SET the desired number of lines to a default
n_lines = 0 #SET counter of number of lines that have been displayed ot 0
counter for line in open(filename): #FOR every line in the open file
if counter < n_lines and not line.startswith("#"): #IF the counter hasn't reached the max number of desired lines AND NOT a header line
print(line.strip('\r\n')) #PRINT the line
= counter + 1 #SET counter to add one counter