I719 Fundamentals of Python/lecture5
Advanced Testing
See
https://wiki.itcollege.ee/index.php/I719_Fundamentals_of_Python/testing
Linting
Python has a style guide called PEP8.
you can check if your code follows PEP8 using the PEP8 linter.
(you may also install this using your OS's package manager)
pip3 install pep8 python3 -m pep8 ~/path/to/your_file.py
This will print out each error as a line in stdout
path/to/your_file.py:LINE:COLUMN PEP8_ERROR EXPLANATION
for example:
btc/btc_price_tests.py:8:80: E501 line too long (648 > 79 characters) btc/btc_price_tests.py:11:1: E302 expected 2 blank lines, found 1
There is another tool called flake8
, which is installed the same way and checks for problems in your code that will cause runtime problems, as well as the pep8 checking.
I recommend you configure your editor to use flake8
Please see http://blog.sideci.com/2015/12/14/style-guide-of-python-and-lint-tool/ for more information on linting
Datetime
see https://docs.python.org/3/library/datetime.html
from datetime import datetime
# convert a timestamp to python native datetime object
timestamp = 1488430906
d = datetime.fromtimestamp(timestamp)
TASK 1
Print the titles of all the frontpage articles on reddit, with the time in normal format (i.e 11:23) next to it.
resource: https://www.reddit.com/.json
example output
11:23 Sessions spoke twice with Russian ambassador during Trump\u2019s presidential campaign, Justice officials say \/\/ CAN WE HAVE AN INDEPENDENT INVESTIGATION NOW? Call your Representative and get them on the record, Country or party?
NOTE
reddit has rate limiting and does not give consistent responses!
download the json data as a json file and use the following code
import json
json_file = open('frontpage.json')
data = json.load(json_file)
json_file.close()
Solution
import argparse
import json
from datetime import datetime
def get_time_with_title(article):
timestamp = article['data']['created_utc']
d = datetime.fromtimestamp(timestamp)
time = d.strftime('%H:%M')
title = article['data']['title']
result = '{time} {title}'.format(time=time, title=title)
return result
def print_headlines(path):
with open(path) as json_file:
data = json.load(json_file)
articles = data['data']['children']
for article in articles:
line = get_time_with_title(article)
print(line)
def main():
parser = argparse.ArgumentParser()
parser.add_argument('file_name')
args = parser.parse_args()
print_headlines(args.file_name)
if __name__ == '__main__':
main()
Classes part 2
see "6. Classes" section of https://learnxinyminutes.com/docs/python3/
lamdbas
Lamdbas are like functions, but are not necessarily defined with a name. You can assign a lamdba expression to a variable, but if you do this, then you should define a function.
# do this
def plus_one(x):
return x + 1
# do not do this
plus_one_lambda = lamdba x: x + 1
plus_one(1) # 2
plus_one_lambda(1) # 2
Lamdba expressions are used when a short function is needed as an argument for another function.
Function that take lambda expression often work on some iterable and need to be called on each iteration. For example map
is a function found in many programming languages. It take an iterable and returns an iterable of equal dimension (i.e. length), but with each element modified in a some way. In python, the first argument of the map function is a function, which is called on each element in the iterable.
def square(x):
return x**2
# map returns a special map type that must be converted to a list to print
print(list(map(square, range(4))))
print(list(map(lambda x: x**2, range(4))))
prints:
[0, 1, 4, 9] [0, 1, 4, 9]
list comprehension
in modern python, the map function is rarely used. The preferred syntax is the list comprehension. it is like a for
loop.
the syntax is the following:
[x + 1 for x in iterable]
The first part, x + 1
in this example, can be anything. Whatever this evaluates to, becomes an element in the resulting list. The rest of the comprehension is like a for loop, but the x
variable is used in the first part.
All of the following print the same values
# Non-functional way, generate a new list
squares = []
for x in range(4):
squares.append(x**2)
print(squares)
# map() functional way
squares = map(lambda x: x**2, range(4))
print(list(squares))
# modern way
squares = [x**2 for x in range(4)]
print(squares)