8.4. Builtin Printing¶
8.4.1. Escape Characters¶
\r\n
- is used on windows\n
- is used everywhere else

Figure 8.12. Why we have '\r\n' on Windows?¶
Sequence |
Description |
---|---|
|
New line (LF - Linefeed) |
|
Carriage Return (CR) |
|
Horizontal Tab (TAB) |
|
Single quote |
|
Double quote |
|
Backslash |
Sequence |
Description |
---|---|
|
Bell (BEL) |
|
Backspace (BS) |
|
New page (FF - Form Feed) |
|
Vertical Tab (VT) |
|
Character with 16-bit (2 bytes) hex value |
|
Character with 32-bit (4 bytes) hex value |
|
ASCII character with octal value |
|
ASCII character with hex value |
print('\U0001F680') # 🚀
8.4.2. String Module¶
import string
string.punctuation
# '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
string.whitespace
# ' \t\n\r\x0b\x0c'
string.ascii_lowercase
# 'abcdefghijklmnopqrstuvwxyz'
string.ascii_uppercase
# 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
string.ascii_letters
# 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
string.digits
# '0123456789'
string.hexdigits
# '0123456789abcdefABCDEF'
string.octdigits
# '01234567'
string.printable
# '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'
8.4.3. print
function¶
8.4.4. Function definition¶
def print(*values, sep=' ', end='\n', file=sys.stdout, flush=False):
"""
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.
"""
...
8.4.5. Intuitive implementation¶
Intuitive implementation of print
function:
def print(*values, sep=' ', end='\n', ...):
return sep.join(values) + end
8.4.6. Printing multiple values¶
name = 'José Jiménez'
print('My name...', name, '!')
# My name... José Jiménez!
name = 'José Jiménez'
print('My name...', name, '!', sep=';')
# My name...;José Jiménez;!
8.4.7. String concatenation¶
+
operator (with side effects)str.join()
str.format()
f-string formatting (preferred)
8.4.8. +
Operator¶
f-string formatting are preferred over
str
additionHow many
str
are in the memory?
name = 'Mark Watney'
'My name... ' + name
# 'My name... José Jiménez'
+
Operator side effect:
name = 'Mark Watney'
age = 42
'My name... ' + name + ' and I am ' + str(age) + ' years old!'
# 'My name... Mark Watney and I am 42 years old!'
8.4.9. str.join()
¶
data = ['Mark Watney', 'Melissa Lewis', 'Rick Martinez']
' '.join(data) # 'Mark Watney Melissa Lewis Rick Martinez'
','.join(data) # 'Mark Watney,Melissa Lewis,Rick Martinez'
', '.join(data) # 'Mark Watney, Melissa Lewis, Rick Martinez'
8.4.10. Variable interpolation¶
8.4.11. Operator: %s
, %d
, %f
¶
positional
keyword
%s
-str
%d
-int
%f
-float
name = 'José Jiménez'
age = 42
pi = 3.141592653589793
'My name... %s' % name # My name... José Jiménez
'My name... %d' % name # TypeError: %d format: a number is required, not str
'My name... %f' % name # TypeError: must be real number, not str
'I have %s years' % age # 'I have 42 years'
'I have %d years' % age # 'I have 42 years'
'I have %f years' % age # 'I have 42.000000 years'
'Number PI is %s' % pi # 'Number PI is 3.141592653589793'
'Number PI is %f' % pi # 'Number PI is 3.141593'
'Number PI is %d' % pi # 'Number PI is 3'
name = 'José Jiménez'
age = 42
'%s has %s years' % (name, age)) # José Jiménez has 42 years
'%s has %s years' % (age, name)) # 42 has José Jiménez years
pi = 3.141592653589793
def square(value):
return value ** 2
'PI squared is %f' % square(pi) # 'PI squared is 9.869604'
data = {
'name': 'José Jiménez',
'age': 42,
}
'%(name)s has %(age)d years' % data
# 'José Jiménez has 42 years'
'%(name)s has %(age)d years' % {'name': 'José Jiménez', 'age': 42}
# 'José Jiménez has 42 years'
name = 'José Jiménez'
age = 42
'My name... %(name)s' % locals()
# 'My name... José Jiménez'
8.4.12. str.format()
¶
name = 'José Jiménez'
age = 42
'{} is {} years'.format(name, age) # 'José Jiménez is 42 years'
'{0} is {1} years'.format(name, age) # 'José Jiménez is 42 years'
'{1} is {0} years'.format(name, age) # '42 is José Jiménez years'
name = 'José Jiménez'
age = 42
'{a} is {b} years'.format(a=name, b=age) # 'José Jiménez is 42 years'
'{name} is {age} years'.format(name=name, age=age) # 'José Jiménez is 42 years'
'{age} is {name} years'.format(**locals()) # '42 is José Jiménez years'
8.4.13. f-strings - Python >= 3.6¶
Preferred way
name = 'José Jiménez'
pi = 3.141592653589793
def square(value):
return value ** 2
f'My name... {name}' # 'My name... José Jiménez'
f'PI squared is {square(pi)}' # 'PI squared is 9.869604401089358'
from datetime import datetime
now = datetime.now()
iso = '%Y-%m-%dT%H:%M:%SZ'
f'Today is: {now:%Y-%m-%d}') # 'Today is: 1969-07-21'
f'Today is: {now:{iso}}') # 'Today is: 1969-07-21T02:56:15Z'
8.4.14. Advanced String Formatting¶
Since Python 3.0: PEP 3101 -- Advanced String Formatting
8.4.15. Basic formatting¶
text = 'PI'
number = 3.14
f'{text} = {number}' # 'PI = 3.14'
8.4.16. Padding and aligning strings¶
text = 'hello'
f'{text:10}' # 'hello '
f'{text:<10}' # 'hello '
f'{text:^10}' # ' hello '
f'{text:>10}' # ' hello'
f'{text:.<10}' # 'hello.....'
f'{text:_^10}' # '__hello___'
8.4.17. Type casting¶
number = 3
f'{number}' # '3'
f'{number:d}' # '3'
f'{number:f}' # '3.000000'
number = 3.141592653589793
f'{number}' # '3.141592653589793'
f'{number:d}' # ValueError: Unknown format code 'd' for object of type 'float'
f'{number:f}' # '3.141593'
text = 'hello'
f'{text}' # 'hello'
f'{text:d}' # ValueError: Unknown format code 'd' for object of type 'str'
f'{text:f}' # ValueError: Unknown format code 'f' for object of type 'str'
f'{14:#b}' # '0b1110'
f'{14:b}' # '1110'
f'{10:#o}' # '0o12'
f'{10:o}' # '12'
f'{255:#x}' # '0xff'
f'{255:x}' # 'ff'
f'{255:X}' # 'FF'
8.4.18. Truncating and rounding¶
text = 'Lorem Ipsum'
f'{text:.5}' # 'Lorem'
f'{text:10.5}' # 'Lorem '
number = 3.141592653589793
f'{number:.2f}' # '3.14'
f'{number: 6.2f}' # ' 3.14'
f'{number:06.2f}' # '003.14'
f'{number:.6.2f}' # ValueError: Invalid format specifier
8.4.19. Signed numbers¶
positive = 42
negative = -42
f'{positive:d}' # '42'
f'{negative:d}' # '-42'
f'{positive: d}' # ' 42'
f'{negative: d}' # '-42'
f'{positive:+d}' # '+42'
f'{negative:+d}' # '-42'
f'{negative:=5d}' # '- 42'
f'{positive:=+5d}' # '+ 42'
8.4.20. Get from dict
¶
data = {
'firstname': 'Mark',
'lastname': 'Watney'
}
f'{data["firstname"]}' # 'Mark'
f'{data["lastname"]}' # 'Watney'
8.4.21. Get from sequence
¶
data = ['a', 'b', 'c']
f'{data[1]}' # 'b'
f'{data[0]} -> {data[2]}' # 'a -> c'
data = ('a', 'b', 'c')
f'{data[1]}' # 'b'
f'{data[0]} -> {data[2]}' # 'a -> c'
data = {'a', 'b', 'c'}
f'{data[1]}'
# Traceback (most recent call last):
# TypeError: 'set' object is not subscriptable
8.4.22. Get from class
¶
class Iris:
species = 'setosa'
measurements = {
'sepal_length': 5.1,
'sepal_width': 3.5,
'petal_length': 1.3,
'petal_width': 0.4,
}
flower = Iris()
f'{flower.species}' # 'setosa'
f'{flower.species:.3}' # 'set'
f'{flower.measurements["sepal_width"]}' # '3.5'
f'{flower.measurements["sepal_width"]:.3f}' # '3.500'
8.4.23. Parametrized formats¶
text = 'hello'
align = '^'
width = 10
f'{text:{align}}' # 'hello'
f'{text:{align}{width}}' # ' hello '
number = 3.14159
align = '>'
width = 10
precision = 2
sign = '+'
f'{number:.{precision}f}' # '3.14'
f'{number:{width}.{precision}f}' # ' 3.14'
f'{number:{align}{sign}{width}.{precision}f}' # ' +3.14'
8.4.24. Datetime¶
from datetime import datetime
now = datetime(1969, 7, 21, 2, 56, 15)
iso = '%Y-%m-%dT%H:%M:%SZ'
date = '%Y-%m-%d'
time = '%H:%M'
f'{now:%Y-%m-%d %H:%M}' # '1969-07-21 02:56'
f'{now:{iso}}' # '1969-07-21T02:56:15Z'
f'{now:{date}}' # '1969-07-21'
f'{now:{time}}' # '02:56'
8.4.25. Custom object formatting¶
class Point:
def __init__(self, x, y, z=0):
self.x = x
self.y = y
self.z = z
def __format__(self, format):
if format == '2D':
return f"({self.x}, {self.y})"
elif format == '3D':
return f"({self.x}, {self.y}, {self.z})"
elif format == 'dict':
return str(self.__dict__)
elif format == 'tuple':
return str(tuple(self.__dict__.values()))
elif format == 'json':
import json
return json.dumps(self.__dict__)
else:
raise ValueError
point = Point(x=1, y=2)
f'{point:2D}' # '(1, 2)'
f'{point:3D}' # '(1, 2, 0)'
f'{point:tuple}' # '(1, 2, 0)'
f'{point:dict}' # "{'x': 1, 'y': 2, 'z': 0}"
f'{point:json}' # '{"x": 1, "y": 2, "z": 0}'
8.4.26. str
and repr
¶
!s
executes__str__()
!r
executes__repr__()
class Point:
def __init__(self, x, y, z=0):
self.x = x
self.y = y
self.z = z
def __str__(self):
return f'({self.x}, {self.y}, {self.z})'
def __repr__(self):
return f'Point(x={self.x}, y={self.y}, z={self.z})'
point = Point(x=1, y=2)
f'{point!s}' # '(1, 2, 0)'
f'{point!r}' # 'Point(x=1, y=2, z=0)'
8.4.27. Quick and easy debugging¶
Since Python 3.8: See https://bugs.python.org/issue36817
f'{expr=}'
expands to the text of the expression, an equal sign, then the repr of the evaluated expression
number = 3
f'{number*9 + 15=}'
# x*9 + 15=42
astronaut = 'Watney'
born = date(1975, 7, 31)
delta = date.today() - member_since
f'{user=} {member_since=}'
# "astronaut='Watney' born=datetime.date(1975, 7, 31)"
f'{astronaut=!s} {delta.days=:,d}'
# 'astronaut=Watney delta.days=16,075'
print(f'{theta=} {cos(radians(theta))=:.3f}')
# theta=30 cos(radians(theta))=0.866
8.4.28. pprint
¶
from pprint import pprint
data = [
{'firstname': 'Mark', 'lastname': 'Watney'},
{'firstname': 'Melissa', 'lastname': 'Lewis'},
{'firstname': 'Rick', 'lastname': 'Martinez'},
]
pprint(data)
# [{'firstname': 'Mark', 'lastname': 'Watney'},
# {'firstname': 'Melissa', 'lastname': 'Lewis'},
# {'firstname': 'Rick', 'lastname': 'Martinez'}]
from pprint import pformat
data = [
{'firstname': 'Mark', 'lastname': 'Watney'},
{'firstname': 'Melissa', 'lastname': 'Lewis'},
{'firstname': 'Rick', 'lastname': 'Martinez'},
]
# returns formatted data
my_string = pformat(data)
8.4.29. Use Case - 0x01¶
>>>
... from time import sleep
...
...
... def progressbar(percent):
... filled = '=' * percent
... empty = ' ' * (100-percent)
... clear = '\b' * 110
... bar = f'{clear}{percent:4}% |{filled}{empty}|'
... print(bar, end='')
...
...
... for i in range(0,101):
... progressbar(i)
... sleep(0.2)
8.4.30. Assignments¶
8.4.30.1. Powielanie napisów¶
Assignment: Powielanie napisów
Complexity: easy
Lines of code: 8 lines
Time: 5 min
- English:
TODO: English Translation Run doctests - all must succeed
- Polish:
Dany jest ciąg znaków:
text = 'Lorem Ipsum'
Napisz trzy funkcje:
print_1(text)
wykorzystującąrange()
print_2(text)
wykorzystującą pętlęwhile
print_3(text)
wykorzystującą mnożenie stringów
Każda funkcja ma wyświetlić 5 kopii tego ciągu znaków
Każdy ciąg znaków w osobnej linii
Napisz doctest do wszystkich funkcji
Uruchom doctesty - wszystkie muszą się powieść
8.4.30.2. Przeliczanie temperatury¶
Assignment: Przeliczanie temperatury
Complexity: easy
Lines of code: 8 lines
Time: 13 min
- English:
TODO: English Translation Run doctests - all must succeed
- Polish:
Napisz program, który wyświetli tabelę przeliczeń stopni Celsjusza na stopnie Fahrenheita w zakresie od –20 do +40 stopni Celsjusza (co 5 stopni).
Wynik musi być taki jak na listingu poniżej
Znak ma być zawsze wyświetlany
Zwróć uwagę na wyjustowanie tekstu
Zwróć uwagę na wypełnienie miejsca niezajętego przez cyfry
Uruchom doctesty - wszystkie muszą się powieść
- Tests:
>>> import sys; sys.tracebacklimit = 0
------------------------------------------- | Temperature | - 20°C | ....-4....°F | ------------------------------------------- | Temperature | - 15°C | ....+5....°F | ------------------------------------------- | Temperature | - 10°C | ...+14....°F | ------------------------------------------- | Temperature | - 5°C | ...+23....°F | ------------------------------------------- | Temperature | + 0°C | ...+32....°F | ------------------------------------------- | Temperature | + 5°C | ...+41....°F | ------------------------------------------- | Temperature | + 10°C | ...+50....°F | ------------------------------------------- | Temperature | + 15°C | ...+59....°F | ------------------------------------------- | Temperature | + 20°C | ...+68....°F | ------------------------------------------- | Temperature | + 25°C | ...+77....°F | ------------------------------------------- | Temperature | + 30°C | ...+86....°F | ------------------------------------------- | Temperature | + 35°C | ...+95....°F | ------------------------------------------- | Temperature | + 40°C | ...+104...°F |
- Hints:
Fahrenheit to Celsius: (°F - 32) / 1.8 = °C
Celsius to Fahrenheit: (°C * 1.8) + 32 = °F
def celsius_to_fahrenheit(degree): return degree*1.8 + 32