bmstu.py lecture 2

aori.ru

			bmstu.py
		

План лекции

Начнём с кода

			def append_to(element, array):
			    array.append(element)
			    return array
		
			print append_to(4, [1, 2, 3])  # [1, 2, 3, 4]
		

Начнём с кода

			def append_to(element, array=[]):
			    array.append(element)
			    return array
		
			print append_to(4)  # [4]
		

Начнём с кода

			def append_to(element, array=[]):
			    array.append(element)
			    return array
		
			print append_to(4)  # [4]
			print append_to(5)  # ???
		

Начнём с кода

			def append_to(element, array=[]):
			    array.append(element)
			    return array
		
			print append_to(4)  # [4]
			print append_to(5)  # [4, 5]
		

Объекты

# один объект, одна переменная
a = 3
			

Объекты

# три объекта, одна переменная
a = 3
a = 3.14
a = 'pi'
			

Объекты

# один объект, три переменных
a = 3.14
b = a
c = a
			

Объекты

				a = 3.14
				b = a
				a = 5
				print b  # ???
			

Объекты

				a = 3.14
				b = a
				a = 5
				print b  # 3.14
			

Объекты

				a = 3.14         #  var | obj      obj | val
				b = a            #    a | 1          1 | 3.14
				                 #    b | 1
			

Объекты

				a = 3.14         #  var | obj      obj | val
				b = a            #    a | 2         1 | 3.14
				a = 5           #    b | 1          2 | 5
			

Объекты

				a = 3.14         #  var | obj      obj | val
				b = a            #    a | 2          1 | 3.14
				a = 5            #    b | 1          2 | 5
				print b  # 3.14
			

Объекты

				a = []
				b = a
				a.append(1)
				print b  # ???
			

Объекты

				a = []
				b = a
				a.append(1)
				print b  # [1]
			

Объекты

				a = []         #  var | obj      obj | val
				b = a          #    a | 1          1 | []
				               #    b | 1
			

Объекты

				a = []         #  var | obj      obj | val
				b = a          #    a | 1          1 | [1]
				a.append(1)   #    b | 1
			

Неизменяемость (immutability)

Неизменяемость чисел

			a = 5
			a += 2
		

Неизменяемость чисел

			a = 5  # объект со значением 5
			a += 2  # другой объект со значением 7
		

Изменяемость списков

			a = [1]
			a.append(2)
		

Изменяемость списков

			a = [1]
			a.append(2)  # тот же объект, что на строке 1
		

Ревью

Базовые типы данных

Базовые типы данных

Базовые типы данных

Базовые типы данных

Базовые типы данных

Базовые типы данных

Кортеж (tuple)

tuple vs list

			animals = ['cat', 'rat', 'dog', 'monkey']
		

tuple vs list

			animals = ['cat', 'rat', 'dog', 'monkey']
			points = [(3, 7), (45, 23), (77, 32), (3, 7)]
		

tuple vs list

			animals = ['cat', 'rat', 'dog', 'monkey']
			points = [(3, 7), (45, 23), (77, 32), (3, 7)]
			movies = [
				('Edward Scissorhands', 'Tim Burton', 1990),
				('Avatar', 'James Cameron', 2009),
				('Terminator', 'James Cameron', 1984)
			]
		

Кортеж (tuple)

tuple unpacking

			movie = ('Edward Scissorhands', 'Tim Burton', 1990)
			title, director, year = movie
			print title  # Edward Scissorhands
		

tuple packing

			title = 'Edward Scissorhands'
			director = 'Tim Burton'
			year = 1990
			movie = title, director, year
			print movie  # ('Edward Scissorhands', 'Tim Burton', 1990)
		

tuple unpacking example

			animals = ['cat', 'rat', 'dog', 'monkey']
			print list(enumerate(animals))
			# [(0, 'cat'), (1, 'rat'), (2, 'dog'), (3, 'monkey')]
			for animal_num, animal in enumerate(animals):
			    ...
		

tuple unpacking example

			animals = ['cat', 'rat', 'dog', 'monkey']
			print list(enumerate(animals))
			# [(0, 'cat'), (1, 'rat'), (2, 'dog'), (3, 'monkey')]
			for animal_num, animal in enumerate(animals):
			    ...
		

Базовые типы данных

Множества (sets)

Множества (sets)

			students_info = [('bmstu.py@gmail.com', 3), ...]
			students_courses = [s[1] for s in students_info]
			print len(students_courses)  # 76
		

Множества (sets)

			students_info = [('bmstu.py@gmail.com', 3), ...]
			students_courses = [s[1] for s in students_info]
			print len(students_courses)  # 76
			print set(students_courses)  # {2, 3, 4, 5, 6}
		

Множества (sets)

			students_info = [('bmstu.py@gmail.com', 3), ...]
			students_courses = [s[1] for s in students_info]
			print len(students_courses)  # 76
			print set(students_courses)  # {2, 3, 4, 5, 6}
			print set(xrange(1, 7)) - set(students_courses)
			# {1, }
		

Базовые типы данных

Базовые типы данных

Хороший код

Хороший код

Стиль кода

Табы или пробелы?

4 пробела

Какая максимальная длина строки?

80 символов

Одинарные или двойные кавычки?

Не важно

WAT?

Плохо:

				'''This is a multiline
				string.'''
		

WAT?

Плохо:

				'''This is a multiline
				string.'''
			
Хорошо:

				"""This is a multiline
				string."""
			

WAT?

Плохо:

				'''This is a multiline
				string.'''
			
Хорошо:

				"""This is a multiline
				string."""
			

Одинарные или двойные кавычки?

Не важно
... но для тройных кавычек нужно использовать двойные

Где ставить пробелы, а где - нет?

Например, после запятых или перед и после арифметических действий.

Сколько ставить пустых строк?

Как импортировать?

Какой стиль именования сущностей?

PEP 8

https://www.python.org/dev/peps/pep-0008/

pep8


$ pep8 articles_generator.py
		

pep8


$ pep8 articles_generator.py
articles_generator.py:3:80: E501 line too long (87 > 79 characters)
articles_generator.py:43:1: E101 indentation contains mixed spaces and tabs
articles_generator.py:45:1: W191 indentation contains tabs
articles_generator.py:45:18: E231 missing whitespace after ','
articles_generator.py:45:80: E501 line too long (158 > 79 characters)
		

Сторонние модули

Например


$ pip install vk
		

Например


$ pip install vk
Downloading/unpacking vk
  Downloading vk-1.5.3.tar.gz
  Running setup.py (path:/tmp/.virtualenvs/cabot/build/vk/setup.py) egg_info for package vk

Downloading/unpacking requests (from vk)
  Downloading requests-2.7.0-py2.py3-none-any.whl (470kB): 470kB downloaded
Installing collected packages: vk, requests
  Running setup.py install for vk

Successfully installed vk requests
Cleaning up...
		

Например

			import vk
			 
			api = vk.OAuthAPI(login, password, ...)
			audios = api.audio.get()['items']
			print audios[0]['artist']  # Guns N' Roses
		

Зависимостей много

			 
			vk
			requests
			simplejson
			pytest
			pep8
			...
		

Зависимостей много

			$ cat requirements.txt
			vk
			requests
			simplejson
			pytest
			pep8
			...
		

Зависимостей много

			$ pip install -r requirements.txt
			# pip устанавливает все зависимости из requirements.txt
		

Разные версии пакетов ведут себя по-разному

			# vk версия 1.5
			api = vk.api.APISession(login, password, ...)
			 
			# vk версия 2.0
			api = vk.OAuthAPI(login, password, ...)
		

Зависимости надо замораживать

			$ cat requirements.txt
			vk==2.0-beta
			requests==2.7.0
			simplejson==3.8.0
			pytest==2.6.4
			pep8==1.5.7
			...
		

Зависимости надо замораживать

			$ pip freeze
			vk==2.0-beta
			requests==2.7.0
			simplejson==3.8.0
			pytest==2.6.4
			pep8==1.5.7
			...
		

Ревью лекции

Ещё кое-что

Практикум

Но сначала пара слов про первое ДЗ


import json
statii = json.load(open('articles.json', 'r'))
p=2
s = 5
i=0
while i < 100:
	if (i >= (p-1) * s) and (i <= p*s): print statii[i]
	i = i + 1
		

import json
statii = json.load(open('articles.json', 'r'))
p=2
s = 5
i=0
while i < 100:
	if (i >= (p-1) * s) and (i <= p*s): print statii[i]
	i = i + 1
		

import json
articles = json.load(open('articles.json', 'r'))
p=2
s = 5
i=0
while i < 100:
	if (i >= (p-1) * s) and (i <= p*s): print articles[i]
	i = i + 1
		

import json
articles = json.load(open('articles.json', 'r'))
p=2
s = 5
i=0
while i < 100:
	if (i >= (p-1) * s) and (i <= p*s): print articles[i]
	i = i + 1
		

import json
articles = json.load(open('articles.json', 'r'))
page_num = 2
articles_on_page = 5
articles_counter=0
while articles_counter < 100:
	if (articles_counter >= (page_num-1) * articles_on_page) and (articles_counter <= page_num*articles_on_page): print articles[articles_counter]
	articles_counter = articles_counter + 1
		

import json
articles = json.load(open('articles.json', 'r'))
page_num = 2
articles_on_page = 5
articles_counter=0
while articles_counter < 100:
	if (articles_counter >= (page_num-1) * articles_on_page) and (articles_counter <= page_num*articles_on_page): print articles[articles_counter]
	articles_counter = articles_counter + 1
		

import json
articles = json.load(open('articles.json', 'r'))
page_num = 2
articles_on_page = 5
articles_counter = 0
while articles_counter < 100:
	first_index = (page_num - 1) * articles_on_page
	last_index = page_num * articles_on_page
	if (first_index <= articles_counter <= last_index): print articles[articles_counter]
	articles_counter = articles_counter + 1
		

import json
articles = json.load(open('articles.json', 'r'))
page_num = 2
articles_on_page = 5
articles_counter = 0
while articles_counter < 100:
	first_index = (page_num - 1) * articles_on_page
	last_index = page_num * articles_on_page
	if (first_index <= articles_counter <= last_index): print articles[articles_counter]
	articles_counter = articles_counter + 1
		

import json
articles = json.load(open('articles.json', 'r'))
page_num = 2
articles_on_page = 5
articles_counter = 0
while articles_counter < 100:
	first_index = (page_num - 1) * articles_on_page
	last_index = page_num * articles_on_page
	if (first_index <= articles_counter <= last_index):
		print articles[articles_counter]
	articles_counter = articles_counter + 1
		

import json
articles = json.load(open('articles.json', 'r'))
page_num = 2
articles_on_page = 5
articles_counter = 0
while articles_counter < 100:
	first_index = (page_num - 1) * articles_on_page
	last_index = page_num * articles_on_page
	if (first_index <= articles_counter <= last_index):
		print articles[articles_counter]
	articles_counter = articles_counter + 1
		

import json
articles = json.load(open('articles.json', 'r'))
page_num = 2
articles_on_page = 5
articles_counter = 0
for articles_counter in xrange(100):
	first_index = (page_num - 1) * articles_on_page
	last_index = page_num * articles_on_page
	if (first_index <= articles_counter <= last_index):
		print articles[articles_counter]
		

import json
articles = json.load(open('articles.json', 'r'))
page_num = 2
articles_on_page = 5
first_index = (page_num - 1) * articles_on_page
last_index = page_num * articles_on_page
for article in articles[first_index:last_index]:
	print article
		

import json
articles = json.load(open('articles.json', 'r'))
page_num = 2
articles_on_page = 5
first_index = (page_num - 1) * articles_on_page
last_index = page_num * articles_on_page
for article in articles[first_index:last_index]:
	print article
		

import json

def load_data():
	return json.load(open('articles.json', 'r'))

def filter_data():
	page_num = 2
	articles_on_page = 5
	first_index = (page_num - 1) * articles_on_page
	last_index = page_num * articles_on_page
	return articles[first_index:last_index]

def print_articles(articles):
	for article in articles:
		print article
		

import json

def load_data(filepath):
	return json.load(open(filepath, 'r'))

def filter_data(articles, page_num, articles_on_page):
	first_index = (page_num - 1) * articles_on_page
	last_index = page_num * articles_on_page
	return articles[first_index:last_index]

def print_articles(articles):
	for article in articles:
		print article
		

...
def print_articles(articles):
	for article in articles:
		print article

articles = load_data('articles.json')
articles_on_page = filter_data(articles, 2, 5)
print_articles(articles_on_page)
		

...
def print_articles(articles):
	for article in articles:
		print article

articles = load_data('articles.json')
articles_on_page = filter_data(articles, 2, 5)
print_articles(articles_on_page)
		

...
def print_articles(articles):
	for article in articles:
		print article

articles = load_data('articles.json')
articles_on_page = filter_data(articles=articles, page_num=2, articles_on_page=5)
print_articles(articles_on_page)
		

# paginate_articles.py
import json
def load_data(filepath):
	return json.load(open(filepath, 'r'))
...
articles = load_data('articles.json')
articles_on_page = filter_data(articles=articles, page_num=2, articles_on_page=5)
print_articles(articles_on_page)
		

# paginate_articles.py
import json
def load_data(filepath):
	return json.load(open(filepath, 'r'))
...
articles = load_data('articles.json')
articles_on_page = filter_data(articles=articles, page_num=2, articles_on_page=5)
print_articles(articles_on_page)

# print_audios.py
from paginate_articles import load_data

audios = load_data('audios.json')
		

# paginate_articles.py
import json
def load_data(filepath):
	return json.load(open(filepath, 'r'))
...
articles = load_data('articles.json')
articles_on_page = filter_data(articles=articles, page_num=2, articles_on_page=5)
print_articles(articles_on_page)

# print_audios.py
from paginate_articles import load_data

audios = load_data('audios.json')

$ python print_audios.py
		

# paginate_articles.py
import json
def load_data(filepath):
	return json.load(open(filepath, 'r'))
...
articles = load_data('articles.json')
articles_on_page = filter_data(articles=articles, page_num=2, articles_on_page=5)
print_articles(articles_on_page)

# print_audios.py
from paginate_articles import load_data

audios = load_data('audios.json')

$ python print_audios.py
		

# paginate_articles.py
import json
def load_data(filepath):
	return json.load(open(filepath, 'r'))
...
articles = load_data('articles.json')
articles_on_page = filter_data(articles=articles, page_num=2, articles_on_page=5)
print_articles(articles_on_page)

# print_audios.py
from paginate_articles import load_data

audios = load_data('audios.json')

$ python print_audios.py
		

# paginate_articles.py
import json
def load_data(filepath):
	return json.load(open(filepath, 'r'))
...
if __name__ == '__main__':
    articles = load_data('articles.json')
    articles_on_page = filter_data(articles=articles, page_num=2, articles_on_page=5)
    print_articles(articles_on_page)

# print_audios.py
from paginate_articles import load_data

audios = load_data('audios.json')

$ python print_audios.py
		

Итого

Теперь - пара слов про второе ДЗ

1. Группировка писем

emails = [{'from': 'bmstu.py@gmail.com', 'title': 'Notes', 'important': True}, ...]
Вывести emails в консоль с группировкой по полю from:

bmstu.py@gmail.com
    [!] Notes
	Какой-то спам
	Третье письмо
postmaster@python.ci.aori.ru
	Welcome
	Password reset
		
Перед важными письмами выводить восклицательный знак.

2. Беседы

messages = [{'from': 'Greg', 'text': 'Hi!', 'timestamp': '2015-10-10T03:59:32'}, ...]

3. История

history = [
	('https://mail.google.com/mail/u/0/#inbox', '2015-10-10T03:59:32'),
	('https://mail.google.com/mail/u/0/#inbox/1502c8558e30d61a', '2015-10-10T04:01:02'),
	('https://vk.com/feed', '2015-10-10T09:23:32'),
	...
	]

4. Подсчёт слов

Примерно так работают всякие CAT: системы по переводу текста и подсчёту того, сколько заработал переводчик.