Notice that Visual Studio Code will report errors and warnings in your Python code. In the lower left corner of the window, you'll see a count of errors and warnings. For example, there are 4 errors and 2 warnings indicated here:
To see more about these errors, click the error or warning count in the lower left corner. Now the Problems pane will appear at the bottom of the window, showing detailed information about each error or warning:
You can click on any error in the list to highlight the corresponding editor line.
You'll need to fix errors to be able to run your program. I recommend that you also always fix all warnings in your code (not only in Python but also in any programming language).
By default, Visual Studio Code enables numerous features that display extra information. For example:
The editor displays line numbers at the left edge of the window.
At the right side of the window, the editor displays a mini-map that you can use to scroll through your program:
When you type a left parenthesis or bracket, the editor automatically inserts the corresponding right parenthesis or bracket.
As you type any word, the editor displays a list of possible completions:
When you type a function name and a left parenthesis, the editor immediately displays documentation for the function:
If you find these features to be helpful, great. For me personally, many of them are distracting. I prefer an editor interface that doesn't display so much information, and that displays documentation only when I ask for it.
Fortunately, Visual Studio Code is highly customizable. If you want its editor to be quieter, you can use my preferred editor settings:
In the lower left, click the gear icon.
Select "Settings" to edit your settings.
In the upper right, click the small icon with an arrow ("Open Settings (JSON)").
The editor will display the file settings.json. Paste in these lines after the opening brace:
"editor.autoClosingBrackets": "never", "editor.autoClosingQuotes": "never", "editor.autoSurround": "never", "editor.codeLens": false, "editor.guides.indentation": false, "editor.lightbulb.enabled": false, "editor.lineNumbers": "off", "editor.minimap.enabled": false, "editor.occurrencesHighlight": false, "editor.parameterHints.enabled": false, "editor.quickSuggestions": { "comments": "off", "strings": "off", "other": "off" }, "editor.renderLineHighlight": "none", "editor.renderWhitespace": "none", "editor.selectionHighlight": false, "editor.suggestOnTriggerCharacters": false, "editor.suggestSelection": "first", "editor.tabCompletion": "on", "editor.unicodeHighlight.ambiguousCharacters": false, "editor.wordBasedSuggestions": false
With these settings, the editor will not display name autocompletions or function documentation automatically. If you're typing a name and want to see autocompletions, you can still get them by pressing Ctrl+Space. If you're typing a function call and want to see the function's documentation, you can still get it by pressing Ctrl+Shift+Space.
Python has boolean operators that can combine boolean values:
and
or
not
For example:
>>> True or False True >>> True and False False >>> not True False >>> not False True
We often use these boolean operators to combine comparisons:
>>> 3 < 5 and 10 < 20 True >>> not 10 <= 50 False
As we know, the statement 'x = x + 2' means "add 2 to the variable x".
In fact, this type of operation is so common that Python has a special assignment operator += for this purpose, which lets us write this statement more succinctly:
>>> x = 10 >>> x = x + 2 # add 2 to x >>> x 12 >>> x += 2 # add 2 to x >>> x 14
The operators -=
, *=
,
/=
, //=
and
%=
are similar. For example:
>>> y = 100 >>> y *= 20 # multiply y by 20 >>> y 2000
To increment a variable is to add 1 to it. Similarly, to decrement a variable is to subtract 1 from it:
x += 1 # increment x y -= 1 # decrement y
In the last lecture, we saw that range(a, b) represents a sequence of integers from a up to but not including b. For example, the loop
for n in range(1, 10): print(n)
prints
1 2 3 4 5 6 7 8 9
Alternatively you may call range() with only a single argument. range(a) means the same as range(0, a): it will produce the integers from 0 up to but not including a. For example, the loop
for n in range(5): print(n)
prints
0 1 2 3 4
Notice that for any non-negative integer n, range(n) produces n distinct numbers. And so a 'for' loop over range(0) will iterate 0 times, i.e. its body will never execute. This code produces no output:
for n in range(0): print(n)
You may also call range() with three arguments. range(a, b, c) means the integers from a up to but not including b, stepping by c. For example, the loop
for n in range(4, 20, 2): print(n)
produces this output:
4 6 8 10 12 14 16 18
In other words, this loop generates numbers from 4 up to (but not including) 20, adding 2 at each step.
The step value may even be negative. The loop
for n in range(10, 0, -1): print(n)
will print
10 9 8 7 6 5 4 3 2 1
In general, if c > 0 then the loop
for n in range(a, b, c): … (body) …
is equivalent to
n = a while n < b: … (body) … n += c
By studying this code, you should be able to see e.g. that range(10, 20, 30) will produce just a single value (10).
The 'break' statement will exit any kind of loop immediately. For example:
n = 1 while n <= 100: print(n) if n == 8: break n += 1
produces the output
$ py hello.py 1 2 3 4 5 6 7 8
When n is 8, the loop immediately exits.
'break' is sometimes convenient when we're looking for a certain value, and want to exit a loop when we find it. For example, suppose that we're looking for the first integer n such that the last 3 digits of n2 are 504 or 505. We could write
n = 0 while True: if 504 <= (n * n) % 1000 <= 505: print(n) break n += 1
Let's try it:
$ py find.py 248
Here's another way to write the program, without 'break':
n = 0 while not (504 <= (n * n) % 1000 <= 505): n += 1 print(n)
You can decide which version you prefer.
A related statement is 'continue', which aborts the current iteration of a loop and continues with the next iteration.
For example, the following loop adds up the sum of numbers from 1 to 100. However it uses the 'continue' statement to skip the number 28:
sum = 0 for i in range(1, 101): if i == 28: continue sum += i print(sum)
In this particular loop, actually we could trivially replace 'continue' with a comparison using '!=':
for i in range(1, 101): if i != 28: sum += i
However 'continue' is sometimes convenient in situations where more code follows it, to avoid moving all that code into a nested block.
It's common to nest one loop inside another. For example:
for x in 'abcd': # outer loop for y in 'efg': # inner loop print (x + y)
During each iteration of the outer loop, the inner loop will run in its entirety. This program will print
ae af ag be bf bg ce cf cg de df dg
Note that the 'break' and 'continue' statements affect only the innermost loop that contains them. For example, let's add a 'break' to the previous program:
for x in 'abcd': # outer loop for y in 'efg': # inner loop print (x + y) if y == 'f': break
This version will produce this output:
ae af be bf ce cf de df
The 'break' statement aborts the inner ('for y') loop, which causes the next iteration of the outer ('for x') loop to run.
Python includes a few math functions that are always available. abs(x) computes the absolute value of x, often denoted as |x|:
>>> abs(-5) 5
round() rounds a float to the nearest integer:
>>> round(2.3) 2
max() computes the maximum of two or more numbers:
>>> max(10, 5) 10 >>> max(10, 5, 20, 3) 20
Similarly, min() computes the minimum of two or more numbers:
>>> min(100, 77, 200, 88) 77
To get access to more math functions, import the 'math' module at the top of your program:
import math
Our Python Library Quick Reference lists various useful functions in this module, such as
sqrt(x) - square root of x
exp(x) - return ex
log(x) - return loge(x)
sin(x), cos(x), tan(x) - trigonometric functions
To use any of these functions, write "math." followed by the name of the function. For example:
import math print(math.sqrt(2))
prints
1.4142135623730951
Our quick library reference also lists various functions that can generate random numbers. To use these, you must first write 'import random'. We will often use these as well.
A particularly useful function is random.randint(a, b), which returns a random integer n in the range a ≤ n ≤ b. Let's write a program that rolls a number of 6-sided dice, and prints their sum:
import random n = int(input('How many dice? ')) sum = 0 for i in range(n): sum += random.randint(1, 6) print('The total is', sum)
Let's run it:
$ py dice.py How many dice? 100 The total is 337
Here's something to consider: if we roll 100 dice and compute their sum, will it usually be less than or greater than 337?
We've already seen Python's input() and print() functions. input() reads a line from standard input. print() reads a line to standard output. By default standard input and output are the terminal, but we'll soon see that we can redirect them from or to a file.
At some point the input may reach its end. When the input comes from a terminal, we can signal the end of the input by typing ctrl+D (on Linux or macOS) or Ctrl+Z Enter (on Windows).
Let's write a program that reads numbers from
standard input, one per line, until it ends. The program will print
the sum of the numbers. We could try to use input() to read the
numbers, however when the input ends input() will produce an error,
which is inconvenient. As another approach, we can use the object
sys.stdin
, which represents a program's
standard input. We can loop over sys.stdin using a 'for' statement.
On each iteration, we'll receive the next input line as a string:
import sys sum = 0 for line in sys.stdin: # for each line of standard input n = int(line) # convert string to integer sum += n print('The sum is', sum)
Let's run the program, and give it some numbers as input:
$ python sum.py 3 4 5 ^D
At the end we typed ^D (control D), meaning end of input. The program now prints
The sum is 12
When you run a program you may redirect its standard input to come from a file, and may also redirect standard output to a file.
Use the
'<' character to
redirect the input. For example, let's use a text editor to create a
file test.in
with these contents:
4 5 6
Now let's run the Python program frm the previous section, redirecting its input from test.in:
$ python sum.py < test.in 15
Similarly, you can use the > character to redirect a program's output. Let's run the program again, redirecting both the input and output:
$ python sum.py < test.in > test.out $
The program ran, but produced no output on the terminal since its output was redirected. Let's look at the output it produced. You can view it in an editor. Alternatively, the 'cat' command (on Linux or macOS) will display the contents of a file:
$ cat test.out 15 $
Many of our homework assignments in our ReCodEx system will contain sample input(s) and sample output(s) for the program that you're supposed to write. You may want to place each sample input in a text file. Then you can run your program with its input redirected from each file in turn. That will be much more convenient than manually entering input data each time you run your program.
Let's consider more string operations in Python. First, the len() function will give us the length of a string:
>>> len('zmrzlina') 8
We can use the [] operator to extract individual characters of a string s. The first character is s[0], the second is s[1], and so on:
>>> s = 'zmrzlina' >>> s[0] 'z' >>> s[1] 'm'
The number in the brackets (e.g. 0 or 1 above) is called an index. In Python, a negative index retrieves a character from the end of the string. For example, s[-1] is the last character, and s[-2] is the second to last:
>>> s[-1] 'a' >>> s[-2] 'n'
Notice that strings in Python are immutable, meaning that they cannot change. So you cannot modify string characters:
>>> s = 'watermelon' >>> s[2] = 'x' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'str' object does not support item assignment
We'll learn about more string operations in next week's lecture.