Slide 1

Slide 1 text

ͬ͟ͱΘ͔Δ Python hakobe

Slide 2

Slide 2 text

ൃදͷഎܠ • ͍ΖΜͳݴޠΛదࡐదॴͰ࢖͍͜ͳ͍ͨ͠
 ΋ͷͰ͢Ͷ • Pythonʹ੎͍͕͋ΔͷͰ࢖͑ΔΑ͏ʹͳͬ ͯΔͱศརͦ͏ • ͬ͘͟Γௐ΂ͨͷͰͬ͘͟Γ঺հ͠·͢

Slide 3

Slide 3 text

Python (ͬ͘͟Γ) • ൚༻εΫϦϓτݴޠ • ΠϯσϯτͰΞϨ͢Δ΍ͭ • 2ͱ3͕͋Δ • ࠷ۙΘΓͱਓؾ͕͕͋ͬͯΔ

Slide 4

Slide 4 text

Python class Blog(): def __init__(self, id, owner_id, title): self.id = id self.owner_id = owner_id self.title = title def is_owned_by(self, user): return user.id == self.owner_id

Slide 5

Slide 5 text

ࠓ೔ͷΰʔϧ: 
 Pythonͷงғؾ͕ͬ͟ͱΘ͔Δ ˒ ։ൃ؀ڥ ˒ Web։ൃ ˒ σʔλ෼ੳ ˒ ݴޠͷਐԽ ˒ ίϛϡχςΟ

Slide 6

Slide 6 text

։ൃ؀ڥ

Slide 7

Slide 7 text

Python 2? 3? • Python3 Λ࢖͑͹OK • ۙ೥ϥΠϒϥϦ΋ἧ͖ͬͯͨ • Python2ܥ͸2020೥Ͱऴྃ • 2.7ܥ͕࠷ޙͷϦϦʔε

Slide 8

Slide 8 text

Python3 Unicodeจࣈྻ ໰୊ 1. ৗʹ use utf8; ͞ΕΔΑ͏ʹͳͬͨ(Perl೴ 2. จࣈྻͱόΠτྻΛ·ͥΔͱྫ֎ʹͳΔ • ݕࡧΩʔϫʔυ: “python3 unicode ͳͥ”

Slide 9

Slide 9 text

Python3ͷจࣈྻͷߟ͑ํ • ೖྗΛdecode/ग़ྗΛencode(஌ͬͯΔ΍ ͭ! # 外部からの入力はバイト列 in_bytes = b'\xf0\x9f\x8d\xa3' string = in_bytes.decode('utf-8') # バイト列にして外部に出力 out_bytes = string.encode('utf-8')

Slide 10

Slide 10 text

खݩ؀ڥͷߏங • ݕࡧΩʔϫʔυ: “Python yamaguchi 2017” • ʙ؆୯3εςοϓʙ • pyenvͰॲཧܥΛ͍ΕΔ • python -m venv Ͱ؀ڥ੾Γସ͑Δ • pip ͰϥΠϒϥϦΛΠϯετʔϧ͢Δ ͿͬͪΌ͚ॾઆ͋Δ͚ͲखݩͰ͸͜ΕͰշద

Slide 11

Slide 11 text

ϥΠϒϥϦ • ඪ४ϥΠϒϥϦ • Battery Included ํࣜͰॆ࣮ • https://docs.python.jp/3/library/ • CPANతͳ΍ͭ = PyPI • ඪ४ͷpip ίϚϯυͰΠϯετʔϧͰ͖Δ

Slide 12

Slide 12 text

PyPI

Slide 13

Slide 13 text

ΤσΟλ • ͍͍ͩͨPythonαϙʔτ͕͋ͬͯ҆৺ • ྑ͍IDE΋͋Δ: PyCharm • ࠷ۙࣗ෼͸Visual Studio CodeΛ࢖ͬͯΔ • linter΍ิ׬͕͙͢࢖͑ͯศར

Slide 14

Slide 14 text

Linter • flake8Λ࢖͑͹͍͍ͩͨOK • ΍ͨΒLinterతϥΠϒϥϦ͕ଟ͍ • pycodestyle, pydocstyle, pyflake, flake8, hacking … • autopep8 ॻ͖׵͑ͯ͘ΕΔ΍ͭ΋͋Δ

Slide 15

Slide 15 text

flake8 • pycodestyle + pyflake > flake8 enjoy.py enjoy.py:1:1: F401 'os' imported but unused enjoy.py:3:1: E302 expected 2 blank lines, found 1 enjoy.py:4:5: F841 local variable 'i' is assigned to but never used enjoy.py:9:5: E303 too many blank lines (2)

Slide 16

Slide 16 text

Test VOJUUFTU ඪ४ఴ෇ɺඞཁे෼ QZUFTU ׆ൃɺΑ͘࢖ΘΕͯΔɺQPXFSBTTFSU OPTF ੲ͸੎͍͕͋ͬͨΒ͍͠

Slide 17

Slide 17 text

py.test def inc(x): return x + 1 def test_answer(): assert inc(3) == 5 def test_misc(): assert [1,2,3,4], [1,2,3,4] assert isinstance('hello', str)

Slide 18

Slide 18 text

pytest ͷ࣮ߦ݁Ռ ================== FAILURES =================== _________________ test_answer _________________ def test_answer(): > assert inc(3) == 5 E assert 4 == 5 E + where 4 = inc(3) test_pyt.py:5: AssertionError ===== 1 failed, 1 passed in 0.06 seconds ======

Slide 19

Slide 19 text

TestࢧԉϥΠϒϥϦ • freezegun = Test::TimeΈ͍ͨͳ΍ͭ from freezegun import freeze_time import datetime def test_time(): with freeze_time("2020-06-06"): assert datetime.datetime.now() == \ datetime.datetime(2020, 6, 6)

Slide 20

Slide 20 text

Web։ൃ

Slide 21

Slide 21 text

WebϑϨʔϜϫʔΫ 'MBTL "NPOతͳܰྔλΠϓ %KBOHP 3BJMTతͳΜͰ΋͍ΓϦονλΠϓ 1ZSBNJE ద౓ͳ͓΋ͯͳ͠

Slide 22

Slide 22 text

Flask from flask import (Flask, request, redirect) web = Flask(__name__) @web.route('//edit', methods=['POST']) def edit(): title = request.form['title'] body = request.form['body'] entry = create(title, body) return redirect('/entry/' + entry.id)

Slide 23

Slide 23 text

WSGI • αʔόͱΞϓϦέʔγϣϯؒͷϓϩτίϧ • PSGIͷܑ͓͞Μ def app(environ, start_response): start_response( '200 OK', [('Content-Type', 'text/plain')] ) yield b'Hello World\n’

Slide 24

Slide 24 text

HTTPαʔό • جຊ͸ prefork worker model • uWSGI͸thread΋࢖͑ΔͬΆ͍? V84(* ࠷ۙྲྀߦΓͰଟػೳ (VOJDPSO 3VCZͷΞϨ༝དྷͰγϯϓϧ

Slide 25

Slide 25 text

σʔλϕʔε • DB͝ͱͷϥΠϒϥϦ: e.g. mysqlclient • API͸PEP 249Ͱඪ४Խ (DBI+DBD) import MySQLdb conn = MySQLdb.connect(db='enjoy') with conn.cursor() as cursor: cursor.execute('SELECT UUID_SHORT() as uuid') print(cursor.fetchone().get('uuid'))

Slide 26

Slide 26 text

ORM • DBϥΠϒϥϦΛͦͷ··࢖͏͘Β͍Ͱ΋ 42-"MDIFNZ ਓؾɻΫΤϦϏϧμతͳ࢖͍ํ΋ %KBOHP03. %KBOHP࢖͏ͳΒ

Slide 27

Slide 27 text

ബ͍Web Appͷߏ੒Λࢼͯ͠Έͨ • hakobe/hakoblog-python • ബ͍WebϑϨʔϜϫʔΫ (Flask) • ORMͳ͠ (mysqlclientΛ௚ʹ࢖͏) • ServiceϨΠϠ • ςϯϓϨʔτΤϯδϯ͸ Jinja2

Slide 28

Slide 28 text

ORM࢖Θͣʹૉ๿ʹ΍͍ͬͯ͘ class BlogLoader(): @classmethod def find_by_id(cls, db, blog_id): with db.cursor() as cursor: row = cursor.execute(''' SELECT id, owner_id, title FROM blog WHERE id = %s''', (blog_id, ) ).fetchone() return Blog(**row)

Slide 29

Slide 29 text

ϔϧύΛఆ͍͍ٛͯ͠ײ͡ʹςετ def test_find_by_id(): "EntryLoader.find_by_id() can find a entry by id" db = DB() entry = create_entry() found_entry = EntryLoader.find_by_id(db, entry.id) assert isinstance(found_entry, Entry) assert found_entry.id == entry.id

Slide 30

Slide 30 text

σʔλղੳ

Slide 31

Slide 31 text

σʔλղੳϥΠϒϥϦ • ͱʹ͔͘ॆ࣮ͯ͠Δ ɹ ͷΩϥʔίϯςϯπ • numpy • scipy • scikit-learn • pandas • matplotlib • Jupyter notebook • σʔλղੳ͍ͨ͠ਓ͕ू·͍ͬͯͯ޷॥؀

Slide 32

Slide 32 text

Numpy • ΊͬͪΌߴ଎ʹߦྻԋࢉͰ͖Δ΍ͭ • ߦྻ಺ͷσʔλܕΛ౷Ұ͢Δ͜ͱͰC΍ FortranͰߴ଎ʹԋࢉՄೳʹͯ͠Δ

Slide 33

Slide 33 text

Numpy import numpy as np m1 = np.array([ [1, 2, 3], [4, 5, 6], ]) m2 = np.array([ [ 7, 8, 9], [10, 11, 12], ]) m1.dot(m2.T) np.zeros([2, 3]) # array([[ 0., 0., 0.], # [ 0., 0., 0.]]) np.identity(2) # array([[ 1., 0.], # [ 0., 1.]]) np.arange(10).reshape(2,5) # array([[0, 1, 2, 3, 4], # [5, 6, 7, 8, 9]])

Slide 34

Slide 34 text

Scipy • NumpyϕʔεͷศརͳՊֶܭࢉάοζू • ౷ܭͱ͔ઢܗ୅਺ͱ͔৴߸ॲཧͱ͔?? • ౷ܭάοζ͸ABςετͷݕఆͱ͔ʹ࢖͑Δ

Slide 35

Slide 35 text

Scipy • ࢀߟ: A/Bςετʹ༻͍ΒΕΕΔ౷ܭతݕఆ ख๏ʢϩδοΫʣͷ·ͱΊˍൺֱ import scipy import scipy.stats data = [ # click, access [ 150, 500120 ], # A [ 70, 320050 ], # B ] chi2, p, dof, expected = scipy.stats.chi2_contingency(data) print(p) # 0.0339

Slide 36

Slide 36 text

scikit-learn • σʔλ෼ੳ/σʔλϚΠχϯά ϥΠϒϥϦू • ධՁͷͨΊͷศརάοζ΋ • ͰػցֶशΤϯδχΞͷؾ෼ʹͳΕΔ from sklearn import svm svc = svm.SVC() svc.fit(X, y) svc.predict(Xtest)

Slide 37

Slide 37 text

pandas • σʔλղੳϥΠϒϥϦ • ϝϞϦ্ͷσʔλʹରͯ͠SQLΈ͍ͨʹ
 σʔλΛϑΟϧλͨ͠Γू໿ͨ͠ΓͰ͖Δ • ௐࠪܥͷλεΫͰศར౓͕ߴ͍

Slide 38

Slide 38 text

matplotlib • σϑΝΫτͷάϥϑඳըϥΠϒϥϦ • ͍͍ͩͨͳΜͰ΋Ͱ͖ͯศར • API͕Ή͍ͣͷͰ୅ସϥΠϒϥϦ͕ຄڵ͍ͯ͠ Δͱ͔ • ݕࡧΩʔϫʔυ: “matplotlib alternative”

Slide 39

Slide 39 text

Jupyter notebook • REPLͷ͓Խ͚(ݩIPython) • ίʔυΛ࣮ߦͨ͠Γ࣮ߦ݁ՌΛදࣔͨ͠Γ
 આ໌Λॻ͍ͨΓͰ͖ΔWebΞϓϦ • ΊͪΌͪ͘Όࢼߦࡨޡ͠΍͍͢ • ͳΊ͚ͯͨͲ࣮ࡍ͔ͭ͏ͱ͛͢ʔࢼߦࡨޡ͠ ΍͍͢…

Slide 40

Slide 40 text

ݴޠͷਐԽ

Slide 41

Slide 41 text

ܕΞϊςʔγϣϯ • ؔ਺΍ม਺ͷܕΛ෦෼తʹهड़Ͱ͖Δ • Generics΍Structual subtyping΋ • ݴޠػೳͱͯ͠͸ΞϊςʔγϣϯͷΈ • ͋͘·Ͱ΋ಈతܕ෇͚͕ओ • Smart::Argsͷ͍͍΍ͭ͘Β͍

Slide 42

Slide 42 text

ࣗ࡞filterؔ਺΁ͷܕ෇͚ from typing import List, Callable, TypeVar T = TypeVar('T') def even(n: int) -> bool: return n % 2 == 0 def filter(l: List[T], f: Callable[[T], bool]) -> List[T]: result: List[T] = [] for e in l: if f(e): result.append(e) return result filter(['a', 'b', 'c'], even)

Slide 43

Slide 43 text

mypy • ܕΞϊςʔγϣϯΛ࢖͏ܕνΣοΧʔ࣮૷ > mypy filter.py filter.py:14: error: Argument 2 to "filter" has incompatible type Callable[[int], bool]; expected Callable[[str], bool]

Slide 44

Slide 44 text

typeshed • TypeScriptͷDefinitelyTypedΈ͍ͨͳ
 ܕఆٛϦϙδτϦ • .pyi ͱ͍͏֦ுࢠͰఆٛΛ͚ͩΛಡΈࠐΉ
 ࢓૊Έ͕͋Δ • https://github.com/python/typeshed

Slide 45

Slide 45 text

asyncio • ࠷ۙ࢖͑Δඪ४ϥΠϒϥϦ (Python 3.4 ~ • ਺͋ΔඇಉظϥΠϒϥϦΛ౷Ұ • ཁ͸AnyEvent(Perl೴ • ೿ੜϥΠϒϥϦ΋ग़͖ͯͯΔ: e.g. aiohttp • ߏจʹ૊Έࠐ·Εͨ (Python 3.6 ~

Slide 46

Slide 46 text

asyncio ͱ async/await ߏจ import aiohttp import asyncio async def fetch(session, url): with aiohttp.Timeout(10, loop=session.loop): async with session.get(url) as response: return await response.text() async def main(loop): async with aiohttp.ClientSession(loop=loop) as session: html = await fetch(session, 'http://python.org') loop = asyncio.get_event_loop() loop.run_until_complete(main(loop))

Slide 47

Slide 47 text

ίϛϡχςΟ

Slide 48

Slide 48 text

ίϛϡχςΟ • ࣮͸͋Μ·Γ஌Βͳ͍… ڭ͍͑ͯͩ͘͞ʂ • PyCon ͸͍͢͝੝Γ্͕ͬͯ·͢Ͷʂʂ

Slide 49

Slide 49 text

࢖ΘΕͯΔ҆৺ײ • اۀ • fastly/Google/redhat/Microsoft ͳͲ.. • ࠷৽ٕज़/اۀϥΠϒϥϦ • AWS/Google/Swaggerͱ͔.. • ڭҭ • Raspberry Pi

Slide 50

Slide 50 text

·ͱΊ

Slide 51

Slide 51 text

·ͱΊ • PythonงғؾΛͬ͘͟Γ঺հ • ݁ہPython͸Ͳ͏ͳΜ? • ศརͳ৔໘Ͱ͸࢖͍ͬͯͬͨΒ͑͑ΜͪΌ͏ • ͍ΖΜͳ͜ͱ͕Ͱ͖ΔΑ͏ʹɺPython΋
 ࢖͍͜ͳͤΔͱྑ͍Ͱ͢Ͷʂ