Python

Table of Contents

Python

開発環境

# auto complete , analyzer
$ pip install jedi
# refactoring
$ pip install rope
# python formatter
$ pip install yapf

Syntax checkのインストール

# systax check tool
$ brew install flake8

Caskに下記を追加

(depends-on "elpy")

elpyをinstall

$ cask install

.emacs.d/init.elに下記を追加

(elpy-enable)

M-x pyvenv-activateで環境~/.pyenv/shims/をセット、 M-x elpy-configで設定情報をチェックできる

Elpy Configuration

Virtualenv........:  (/Users/tma/.pyenv/shims/)
RPC Python........: 3.6.1 (/Users/tma/.pyenv/shims/python)
Interactive Python: python (/Users/tma/.pyenv/shims/python)
Emacs.............: 26.1
Elpy..............: 1.28.0
Jedi..............: 0.13.2
Rope..............: Not found (0.12.0 available)
Autopep8..........: 1.4.3
Yapf..............: 0.26.0
Black.............: Not found (18.9b0 available)
Syntax checker....: flake8 (/usr/local/bin/flake8)

The black package is not available. Commands using this will not work.

[run] python -m pip install black

Options

`Raised' text indicates buttons; type RET or click mouse-1 on a button
to invoke its action.  Invoke [+] to expand a group, and [-] to
collapse an expanded group.  Invoke the [Group], [Face], and [Option]
buttons below to edit that item in another window.

M-x elpy-set-project-rootでプロジェクトのRootをセットする。

C-c C-p エラー箇所に飛ぶ 
C-c C-n エラー箇所に飛ぶ 
M-. 定義に飛ぶ

空リスト判定

lis = []
if lis:
   return 'not empty'
else:
   return 'empty'

ファイル操作

import os

// ファイル、ディレクトリ一覧
os.listdir('/path/to/dir')

withを使えば自動でcloseしてくれる

with open(file_path) as f:
    lines = f.readlines()

python doc

http://azunobu.hatenablog.com/entry/2015/05/02/080000

help関数で出力されるドキュメンテーションの書き方。 下記のように記載する。

def binary_search(lis, val):
    u""" 引数で与えられたListの中から検索valの位置を検索して返す。
    検索値が存在しない場合は-1を返す
    """

    length = len(lis)
    if length == 0:
        return -1

    mid = math.floor(length / 2)

    return _search_array(lis, val, mid, 0, length - 1)

インクリメント

count = 1
while count <= 100:
    print(count)
    count += 1

小数点の切り上げ、切り捨て

import math

# 切り捨て
math.floor(x)

# 切り上げ
math.ceil(x)

# 中間(0.5)の場合は偶数に丸められる
round(x)

例外

例外の投げ方

raise Exception("I know python!")

Unittest

with self.assertRaises(Exception):
    reverse('hoge')

クラス

https://qiita.com/Usek/items/a206b8e49c02f756d636

Pythonではメソッドは最低1つの引数を持ちます。この最初の引数は必ずselfという名前にする慣例があります。

class Spam:
    val = 100
    def ham(self):
        self.egg('call method')

コンストラクタは__init__() デストラクタは__del__

クラスチェック oがstrクラスまたはそのサブクラスかをチェック

if isinstance(o, str):

strクラスであることをチェック

if type(o) is str:

標準入出力

for line in sys.stdin:
    lis = line.replace('\n', '').split(',')
    if score.header == None:
        score.header = lis
    elif lis != '':
        score.score.append(lis)

文字列

str = 'test'
# 小文字判定
if str.islower():
    return 'lower case'
str = 'TEST'
# 大文字判定
if str.isupper():
    return 'upper case'
str = '123'
# 数字判定
if str.isdigit():
    return 'degit'

stringsからbyteへ

b = 'あ'.encode('utf-8')
return b

byteからstringsへ

b = b'\xe3\x81\x82'

return b.decode('utf-8')

str = '[ERROR] this is wrong'
print(str.contain('ERROR'))

文字列が含まれるか?

# 含まれる場合は True
print('ho' in 'hoge')

# 含まれない場合は False
print('fu' in 'hoge')

# 無限
float('inf')

高階関数

reduce

import functools

print (functools.reduce(lambda x, y: x + y, range(1, 5)))

if

https://www.tutorialspoint.com/python/python_if_else.htm

if condition:
     ...
elif confition:
    ....
else:
    ....

条件のand,or条件

if condition1 and condition2:
     ...
elif condition1 or condition2:
    ....
else:
    ....

NoneはFalse扱い

if None:
    print('If block')
else:
    print('Else block')

0はFalse扱い

if 0:
    print('If block')
else:
    print('Else block')

1はTrue扱い

if 1:
    print('If block')
else:
    print('Else block')

空文字はFalse扱い

if '':
    print('If block')
else:
    print('Else block')

リスト内包表記

print([i for i in range(10)])
lis =[1, 2, 3, 4, 5, 6, 7, 8, 9]
print([ x**2 for x in lis])
print([ x**2 for x in lis if x % 2 == 0])

# 実行順序は左から右
matrix = [[ 1, 2, 3], [4, 5, 6], [7, 8, 9]]
print([x for row in matrix for x in row])

generator

内包表記における遅延評価

matrix = [[ 1, 2, 3], [4, 5, 6], [7, 8, 9]]
gen = (x for row in matrix for x in row)
print (next(gen))
print (next(gen))

closure

def test(val):
    print(val)
    # closureは関数の外の変数(val)にアクセスできる
    def inner1():
        print(val)
    inner1()
    val = 'hoge'
    inner1()

    # valの値を変更しても外のスコープには影響しない
    def inner2():
        val = 'woo'
        print(val)
    inner2()
    print(val)

    # nonlocalを使って外のスコープの値を変更する
    def inner3():
        nonlocal val
        val = 'woo'
        print(val)
    inner3()
    print(val)

test('fuga')

list tuple

listとtupleの違い http://d.hatena.ne.jp/r_ikeda/20111111/listtuple

  • リストは変更可能だがタプルは変更不可能
  • タプルはマップのキーにできる

slice

list[start:end] end番目の要素は含まれない。

負の数を使うと末尾からの計算が楽になり、いちいちlenを使わなくてよくなる。 sliceは新しいlistを作成するため、元のlistに影響しない。

list = [1, 2, 3, 4, 5]
print(list[1:4])
print(list[0:1])
print(list[1:])
print(list[-1:])
print(list[-2:])
print(list[:-2])
print('1234567890'[:8])

enumrate

counterの値をプラスした値をiterateできるジェネレータを返す。

list = ['zero', 'one', 'two' , 'three', 'four']
for key, val in enumerate(list):
    print(key , ':' , val)

yield

yieldを用いて、Listの結果自身ではなく、Listを生成するGeneratorを返却するようにすれば、 例えば巨大なListを扱う必要がある場合もメモリを逼迫させることなく処理を行うことができる。

def list_gen():
    yield 0

    for i in range(1, 10):
        yield i

for i in list_gen():
    print(i)

empty 空リスト判定

len(lst) == 0

インデックス要素の削除

# 値を返す
list.pop(index)

https://www.pythonweb.jp/tutorial/list/index8.html

stack

listでstackを実現するにはappendとpopを使う。

lis  = [3, 4, 5]
lis.append(6)
lis.pop()
-> 6

https://docs.python.org/3.1/tutorial/datastructures.html

listをある値で初期化する

lis = [0] * 4
print(lis)

zip リストの要素を同時に取得して処理したい場合

i = [1, 2, 3]
k = [4, 5, 6]
j = zip(i, k)
for p, q in j:
    print(p, q)

dictionary

val = {'hoge': [9], 'fuga': [0], 'hige': []}
print(val.get('hige'))

# keyが存在しないとNoneが返る。デフォルト値を第二引数に渡せる
print(val.get('hage'))
print(val.get('hage', []))

sort

list.sort() と sorted(list)の違い

sorted()は新しいlistを、list.sort()はそのlist自体を変更する。

numbers = [8,3,1,2,5,4,7,6]
# 昇順
print(sorted(numbers))
# 降順
print(sorted(numbers,reverse=True))

def iseven(x):
    if (x % 2) == 0:
        return (0, x)
    return (1, x)

# コンパレータを渡す
print(sorted(numbers, key=iseven))

unitttest

https://qiita.com/hoto17296/items/fa0166728177e676cd36

tests ディレクトリ内のすべてのテストケースを実行する

$ python -m unittest discover tests

ひとつのテストケースだけを実行する

$ python -m unittest tests.test_foo

unittestでpdbを起動

コード中に下記を記述

import pdb; pdb.set_trace()  # デバッグコード

https://qiita.com/TakesxiSximada/items/45b6d71a44f2706798ed

mysql util mentenance

pyenv

Mac

$ brew install pyenv

~/.bash_profile

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
export PATH=$HOME/.nodebrew/current/bin:$PATH

3.6.1をインストール

$ pyenv install 3.6.1
$ pyenv rehash
$ pyenv global 3.6.1
$ python -V
Python 3.6.1
pyenv install –list インストール可能なバージョン一覧を表示する

Amazon Linux https://qiita.com/rysk92/items/878fddbf23262628d89e

pipenv

$  pip install pipenv
$ cd src/python/
$ pipenv --three
$ pipenv install

環境に入ってモジュールをインストールする。

$ pipenv shell
$ pipenv install twilio

Pipfile

[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
twilio = "*"

[requires]
python_version = "3.7"

$ pipenv --venv
/Users/hoge/.local/share/virtualenvs/monitor-ywBsqNFq

脆弱性チェック

$ pipenv check
Checking PEP 508 requirements…
Passed!
Checking installed package safety…
All good!

emacs

C-c C-l ファイルを選択して評価
C-c C-c バッファを評価
C-c C-p インタプリタを起動

jedi

pip install virtualenv

(add-hook 'python-mode-hook 'jedi:setup)
(setq jedi:complete-on-dot t)


M-x jedi:install-server

python programing

関数

引数は全て参照渡し デフォルト値には同じオブジェクトがわたさる

>>> def hoge(foo, bar=[]):
...   bar.append(foo)
...   return bar

>>> print(hoge('a'))
['a']
>>> print(hoge('a'))
['a', 'a']
>>> print(hoge('a'))
['a', 'a', 'a']

nolocal: 1つ外側のスコープに属する変数への代入が可能になる

可変長引数

アスタ(*)で表現する

def hoge(foo, bar, *arg):
    print(foo,bar,arg)

>>> hoge('a', 'b', 'c', 'd')
a b ('c', 'd')

クラス

コンストラクタは__init__

numpy

import numpy as np
return np.arange(0, 6, 0.1)

0から6 まで0.1ずつ増やした値を出力

ndim(A) 配列の次元数をだす

import numpy as np

A = np.array([1, 2, 3, 4])
B = np.array([[1, 2],[ 3, 4]])

print(np.ndim(A))
print(np.ndim(B))

dot(X, Y) ドット積

import numpy as np

A = np.array([[1,2], [3,4]])
B = np.array([[5,6],[7,8]])
return np.dot(A,B)
#array([[19, 22],
#       [43, 50]])

ctypes

import ctypes

PyArray = ctypes.py_object * 2
x = PyArray()

x[0] = 0
x[1] = 1

array

配列の宣言

import sys

# 0で初期化した length 3の配列
A = []
print(sys.getsizeof(A))
A = [0] * int(3)
print(sys.getsizeof(A))
A = ['hoge'] * int(7)
print(sys.getsizeof(A))

format

print('hoge %s hige' % ('fuga'))
print('hoge %s %s' % ('fuga', 'hige'))

fプリフィックスによるテンプレート

val1 = 'fuga'
val2 = 'hige'
print(f'hoge {val1} hige')
print(f'hoge {val1} {val2}')

pip

モジュールをターゲットを指定してインストール

$ pip install requests -t functions/python_lambda

requirements.txtからインストール


$ pip install --requirement functions/myfunc/requirements.txt -t functions/myfunc/

Validate