[[プログラミング]]

*概要 [#w618884a]
-つらいけどpython3の勉強
-最近流行ってるので習得しなければならない…
-pythonは言語を作る気で行かないと死ぬ

*下位ページ [#ydce84f6]
-[[Seaborn]]

*目次 [#a5607792]
#contents









*まとめるべきこと [#y7538dcf]


collection系
https://docs.python.org/2/library/datatypes.html
調べたいもの:heap, bisect, setsとsetのちがい、ordered set,  queueとstack, priority_queue, repr, 
Pythonのordered dict
まんまOrderedDictという名前のcollectionがある
http://azunobu.hatenablog.com/entry/2015/05/01/115413
お手軽構造体namedTuple
http://sucrose.hatenablog.com/entry/2014/04/21/000909
dequeがある





pythonには亀グラフィクスという2Dグラフィクスが備わっている
http://www.ic.daito.ac.jp/~mizutani/python/using_turtle.html

pythonの二分木
http://www.ic.daito.ac.jp/~mizutani/python/binary_tree.html





type hinting(タイポ)
IFは書いた方がいいですね
C++以外ですが、私はint,string,list,map,setの関数内変数についてはあまり書かないです
PythonのIFにtype hitingするのもありかなって思います(書かない人多いですが)
assert isinstance祭りしましょう

pythonの@はデコレータ
処理の前後に、処理を追加する
あと数年するといろんな分野の統計で、「AIの予測に従った場合と、プロが独自の判断でAIを無視した場合、前者の方が成績が良い」という結果が出始める。で、プロが「数値で見えない価値」とか「長期的な視点」を主張し出す。広告のアドテクで起きたことが、全業界で起こると思えば想像しやすい
















*疑問 [#r037df37]
-一般にPythonで変数を出力・ロードする方法ってどうすればいいの?






















*参考 [#t603e7f2]
-https://www.programiz.com/python-programming/numbers
-sympyなる数式演算ライブラリがイケてるらしいので後で調べる









*環境構築 [#mb27dc33]
-鬼門

 sudo apt-get -y install python3-dev
 python -V
 python3 -V #バージョンを確認。3.5だとする。
 sudo apt-get install python3.5-dev #ここのバージョンとして3.5を入れる
 sudo apt-get install python3-setuptools
 sudo easy_install3 pip
 pip -V # pipの場所がpython3になっていることを確認
 
 sudo pip install virtualenv

*開発を始める時 [#s699ba42]
-はじめて
 virtualenv envname
 pip3 install numpy

-二回目以降
 . envname/bin/activate
 pip list # envname環境でのパッケージ

-開発を終える時
 deactivate

**基本は使ってはならないがpip3について [#of44a678]
-グローバルに入れるには、必ず使うバージョンまで指定しないといけない

 sudo python3.5 -m pip install numpy




*参考 [#n66c183a]
-入門
--http://www.pythonweb.jp/tutorial/
--http://www.tohoho-web.com/python/index.html
*文法 [#f8f3bc94]
-☆
--セミコロンなし,インデントが文法.
--配列はmatlab式.[10, [20, 16], [32, u"太郎"], 18]など.スライス使える(a[1:2], a[:3], a[2:])が、スライス自体がリストにはならない.長さはlen(list),追記はlist.append(hoge).
--数値配列の作成はrange(1, 5)など([1, 2, 3, 4])
--文字列では、シングルとダブルクオートの区別がない
---取得は配列と同じ
---[[pythonの文字列処理の素晴らしいまとめ>http://d.hatena.ne.jp/yumimue/20071223/1198407682]]
--ifに括弧なし.if, elif, elseはすべて行末に:
--forはmatlab式+行末に:.forのinに文字列は一文字ずつ取得.for, whileのあとにelseを入れることができる
--コメントは#comment, """comment"""
--数字->文字はstr(num).文字→整数はint(str),文字→浮動はfloat(str),数値判定はstr.isdigit()
--論理演算子はor, and, not.真偽はTrue, False
--関数はdef function_name(arg1, ...):.行末に:が必要
---*でargs, **でパラメータを渡せる([[参照>http://www.tohoho-web.com/python/function.html#function]])
--intも含め配列の関数渡しも、「すべて」参照渡し
--a={}でc++でいうmapになる
---pythonのdictは存在しないキーを出力しようとするとデフォルトエラーなので、そうじゃなくしたいならgetを使う。
--printf
---print aでprintf("%d\n",a);
---print a,でprintf("%d",a);
--for-else構文は、break「しなかったとき」に入るスペシャルステージ
--if 3>a>1<b<5: print(a, b)ができる!

-☆☆
--空オブジェクトはNone(Noneは予約語)
--空白文字削除はstr.strip()
--[[Pythonは日本語がクソ>http://lab.hde.co.jp/2008/08/pythonunicodeencodeerror.html]]
---以下を一行目に入れる
 # coding: UTF-8

-可変長引数

 >>> def func(*a):
 ...   print a
 ...
 >>> func("a","b","c")
 ('a', 'b', 'c')

-[[pythonのis operator>http://dackdive.hateblo.jp/entry/2014/08/07/172135]]
--ポインタの一致
--Immutableなら==と同じだが、リストとかmutableなものではポインタの一致を見るようになる



















*Pythonの難しさ [#od3272a7]
-結局型を意識しなければいけないなら、型を全て省略する意味は一体どこにあるのだろう
--理由: めんどいので(一方コードリーディングつらくない?)
--データオペレションのみに注力できるから、って思ったけど、少なくともいろい型やなんやらは考えてるので、見た目的に何もないだけで意識は、型から解放されてない



















*バブルソート [#t4875c64]
 def bubblesort(a):
     for i in range(len(a)-2):
         for j in range(len(a)-1-i):
             if a[j] < a[j+1]:
                 tmp = a[j]
                 a[j] = a[j+1]
                 a[j+1] = tmp
 
 
 
 a=[2,4,5,1,2]
 bubblesort(a)
 for i in range(len(a)):
     print a[i]











*代表的なデータ型の操作 [#z907b3e1]
**型の大まかな特徴 [#me1efb06]
-pythonでは型が暗黙の了解となっている
-型
--int, float
--iterativeな型:list, set(, str)。これらの間は自由に行き来できる(strはちょっと怪しい)
---strは静的!
--tuple
---tupleは静的!(1, 3, 4)[2]などのアクセスが可能。
--dict
--ndarray
---listしか突っ込めない
--map object
---このままでは使えないので、list, setに渡してやる必要がある(strはダメ)
-変換

**型の相互変換 [#pfe4c017]
||int|float|str|list|set|dict|ndarray|h
|int|=|float(n)|str(n)|[n]|{n}|{n: m}|np.array([n])|
|float|int(x)|=|str(x)|[x]|{x}|{f: x}|np.array([x])|
|str|int(s), 失敗でRE, int('0.1')はRE。ord(s)でもOKで、ordは1文字以外だとRE|float(s), 失敗でRE|=|list(s)|set(s)|x|np.array(list(s))|
|list|a[i]|a[i]|str(a)は、listのデバッグ出力が文字列として得られる。a: [char]なら"".join(a)、a: [int]なら"".join(list(map(lambda x: chr(x+ord('0')), [0, 3])))|=|set(a)|ts = [(1, 2), (3, 4), (5, 6)]; dict(ts)。同じようにdict(zip(a, b))などが可能(zipはzip objectでlistを返すわけではないが、list(zip(a,b))で同様になる)。キーだけ指定する場合は、marks = {}.fromkeys(['Math','English','Science'], 0)|np.array(a)|
|set|for x in s: print(x)|for x in s: print(x)|str(s)、setのデバッグ出力が文字列として得られる|list(s)|=|x|np.array(list(s))|
|dict|d[x], xがなければRE|d[x], xがなければRE|str(d)、dictのデバッグ出力が文字列として得られる|list(d)はdのkeys list。dd.keys()は実はdict_keysという型!ペアで欲しいならlist(zip(d.keys(), d.values()))|set(d)はdのkeys set。d.keys()は実はdict_keysという型!|=|np.array(list(d))|
|ndarray|v[i]|v[i]|str(a)でデバッグ出力らしきもの(違う)が出る|list(a)かa.tolist()|set(a)|x|=|


**二次元配列 [#fc438b69]
-変な作り方をすると、参照になって代入が独立じゃなくなる。毎回リスト内包で作成すること!

**型ごとに可能な操作 [#v341765c]
-str以外全部に対してビルトイン関数: all(), any(), enumerate(), len(), max(), min(), sorted(), sum()などが使える
-sequence(list, string)には、reversedが使える。
-sortedはstrを突っ込んでもリストが帰ってくる

||サイズ|要素追加|要素削除|反復|積|和|差分|検索|ソート|逆順|h
|list|len(a)|push_backがa.append(x), a.insert(i, x)はiの次にxを挿入する|push_backがa.pop()。a.pop(i)は#iを返して#iを消す。del a[i]で#iを消す。a.remove('a')でaを先頭1個削除(削除できないとRE)|[1] * 100|なし|+, これは.extend(b)と同等|なし|a.index('x'): xのfirst occurenceを取得|a.sort()|a.reverse()が可能。reversed(a)でもまあ良い|
|set|len(s)|s.add(x)|a.discard(x)がエラー無し。remove(x)はxがないとRE。s.pop()はなんか一個削除して値を返す(順序がない、ハッシュなので)。|なし|and|or。論理排他和は^。包含関係はa <= b|s-t|x in s, x not in s|setはハッシュなのでソートしてくれない!sorted(s)|なし|
|dict|len(d)|d[i] = x|d.pop(i)でkeyがiの要素削除して値を返す。d.popitem()で何か一つ削除して値を返す。|なし|d = {x:d1[x] for x in d1 if x in d2}|なし|なし|d[i]はiがなければRE。d.get(i)はなければNoneを返す。|sorted(d)だが、これはキーしかソートしてくれないのでsorted(list(zip(d.keys(), d.values())))|なし|
|str|len(s)|s + t, O(len(s)+len(t))|不可能|s*3|なし|なし|なし|'ab' in s|''.join(sorted(s))|''.list(reversed(s))|

**list [#bf64cf26]
-listには.countという出現回数を取得する関数がある


**str [#ic2a70d2]
-''静的データ構造!!''途中で#iの変更をしたくなっても無理。変更にO(n)かかり、基本的に遅い。Javaみたいな感じ。
-対策:動的文字列は、strではなくlistで管理する
-'a'+1みたいなことをしたい場合は?めんどいが 

 chr(ord(s)+1)

-したがって+演算子は毎回新たなオブジェクトを生成するので、あまり行儀が良くない

 s = s + "新たな文字列1"
 s = s + "新たな文字列2"
 . . .
 とせずに、配列を使って、
 L = []
 L.append("新たな文字列1")
 L.append("新たな文字列2")
 . . .
 s = ''.join(L)
 
 とするのが定石イディオム

-split
--これは便利
--複数文字delimiterもできる

 >>> 'I have a pen'.split()
 ['I', 'have', 'a', 'pen']

 >>> 'aabbababbabbbb'.split('a')
 ['', '', 'bb', 'b', 'bb', 'bbbb']
 >>> 'aabbababbabbbb'.split('aa')
 ['', 'bbababbabbbb']

-文字列にはupper, lowerという関数がある

-小文字リスト

 import string
 string.ascii_lowercase
 ‘abcdefghijklmnopqrstuvwxyz’

**その他のデータ構造 [#s2544b19]
-Counter
--便利

 from collections import Counter
 Counter([‘apple’,‘red’,‘apple’,‘red’,‘red’,‘pear’])
 Counter({‘red’: 3, ‘apple’: 2, ‘pear’: 1})




















*ファイル [#y240e194]
 for line in open("test.txt", "r")
     line.strip()
     print line



















*正規表現 [#qa327b62]
 import re
 a = re.search(r'^[a-z]', line)



















*numpy [#de8fc638]
Numpy 
Transposeに同値な
Tというメンバ変数らしきものがあるhttps://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.T.html
pythonできれいな2次元グラフを書く
http://qiita.com/kenmatsu4/items/d282054ddedbd68fecb0
パラメータ分布を{coda}パッケージを使ってプロットするとこんな感じです。

**ndarray [#wd032910]
-スライスアクセス
-ファンシーアクセス
-[[要素アクセス>http://stackoverflow.com/questions/33885201/access-ndarray-using-list]]
 import numpy as np
 ndarr = np.array([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]])
 indices = [1,1]   # row,col
 ndarr[tuple(indices)]


**逆引き [#je973f50]
-countしたい場合

 np.count_nonzero(v==-1)

-npでmapしたい場合

 np.vecorize(func)(v)

-0配列を作る

 np.zeros(n)。

-max, min

 max(v), min(v)

-条件を満たすインデックス列挙

 np.where(a>1)



















*コーディングイディオム [#db53a3ec]
**not a [#t69380fd]
-C++のa.empty()はnot aで可能
**隠れビルトイン関数 [#y31559e5]
-pow(x, y[, z])
--x^y%zの高速実装
--競プロのために作られたとしか思えないがRSA暗号で使う

-sorted(d.items(), reverse=True)
--逆順ソートする。

-all, any
--iterableの全てTrue、もしくはどれかがTrueでTrue

-bin(int)
--二進数表記する

-ascii(obj), repr(obj)
--printで出力される文字列と同じものを返す

-complex(re, [im])
--複素数。文字列を突っ込むことができる。

-divmod(a, b)
--商と余りのtuple。divmod(10.2, 3)=(3.0, 1.1999999999999)

-int(str, [base=10])
--a = int('1000', base=3)で81になる

-普通のint型n
--普通にC++と同じようなbit操作が可能。n & (1 << 4)
--n.bit_length()は二進数桁数。log2と同じ。
-普通のfloat型x
--x.is_integer()は整数かを雑に判定する。if abs(x - int(x)) < 1e-6:とかしなくて良くなる

-str
--countという部分文字列のカウントがある。 'abcabcbcbc'.count('bc') # 4
--findは、最初の出現位置を返す。なければ-1 'abcabcbcbc'.find('bc') # 1
--replaceは全出現の置換 'abcabcbcbc'.replace('bc', '')
--stripは前後の空白文字を消去する。


**C++より実装速度が早いアルゴリズム [#f1e69e89]
-気軽にsplitとかを前提にしたアルゴリズムを組めるのはいい
-setの|や&
-reversed(range(10))はrange(10)[::-1]でもできる。


**内包表記 [#ad485c54]
-内包表記には後置if条件を複数つけることができる。
--[x for x in range(100) if x % 2 if x % 3]
-if-elseもできる。前置になる
--[ i if i%2==0 else str(i) for i in range(10)]
-速度的にも3倍程度早い
-gotoモジュールはデフォルトではなく、頑張ってインストールしなければならないので残念。多重ループ抜け出しは基本for-elseかフラグしか方法がなさそう。あとは関数化


**一括比較・一括処理 [#de6abd67]
-swap
 a, b = b, a

-一括等価チェック
--複数のオブジェクトの比較はつなげて一度に行う

 # long
 # 最初の文字と最後の文字両方が一致する
 a[1] == b[1] and a[-1] == b[-1]
 
 # short
 a[1] + a[-1] == b[1] + b[-1]


-リストで場合分け
--これはC++でもできそう

 # long
 t = a % 3
 if t == 0:
     a = a * 2
 elif t == 1:
     a = 0
 elif t == 2:
     a = t * 2
 
 # short
 a = [a * 2, 0, t * 2][a % 3]

-if-elseの代わりにand orを使うワンライナー

 条件 and True時 or False時

-forのワンライナー。:は一行一個だが、それ以内のものはセミコロンでくっつけられる。

 for x in[None]*10:print(a);a+=1

-forでループ変数は絶対に参照しないぞという気構え(range書くより短い)

 for _ in [1]*10:








*mapオブジェクト、filterオブジェクトなど [#k56ca9a0]
-ジェネレータと呼ばれるらしい
--リストなどの遅延評価
-評価するには、for文なのでgenerateするか、明示的にlist(map_object)などとする([map_object]はだめ)






*参照・ポインタ [#raec3d09]

**概要 [#d8fe44d6]
-pythonの変数は全て参照!
--変数に新たなオブジェクトそのものが代入されるときには、これまでの参照先から変わって新たなオブジェクトが作られた場所を参照するようになる。



**まず [#gea8e88b]
-とりあえずこれ動かしてなんかヤバイことを察して

-1つめ

 >>> a = [1,2,3]
 >>> b=a
 >>> b[0]=3
 >>> a
 [3, 2, 3]
 >>> b
 [3, 2, 3]
 >>> b += [4]
 >>> a
 [3, 2, 3, 4]
 >>> b
 [3, 2, 3, 4]

-2つめ

 >>> L = [1,2,3,4]
 >>> def func(ll):
 ...   ll = [5,6,7,7]
 ...
 >>> func(L)
 >>> L
 [1, 2, 3, 4]

-3つめ

 >>> def func(ll):
 ...   ll[0] = 5
 ...
 >>> func(L)
 >>> L
 [5, 2, 3, 4]



**注意すべき挙動 [#xc1fa967]
-listを関数に渡して、
--''リスト全体を変えた場合は副作用がないが、''
--リストの一部を変えると副作用が起きる
--対策:func(a[:])とコピーを渡す。もしくは、関数内部始めに必ずdeep copyしてから使う。

-二次元配列を[[0]*m]*nで実装するとダメ
--超有名なのでググッて
--対策:リスト内包表記を使う

-クラスの初期値を[]にするとダメ
--http://amacbee.hatenablog.com/entry/2016/12/07/004510
--対策:デフォルト引数やクラス初期値は、a=Noneをいれておいて、if a==None: a = []とする。

-関数のデフォルトにMutableを入れるとダメ
--[[デフォルト引数にMutableを入れちゃいけない>https://rcmdnk.com/blog/2015/07/08/computer-python/]]理由

-[[ジェネレータをコピーしても内部変数は変わらないのでダメ>http://bugrammer.g.hatena.ne.jp/nisemono_san/20111210/1323444429]]


**pythonの変数と実体は独立 [#k2290eea]
-''変数は全部ポインタ''
--変数はラベルでしかなく、実体と独立にふわふわ浮いている
-代入
--変数にオブジェクトを代入すると、
---変数にオブジェクトの参照が代入される
--変数に変数を代入すると、
---変数に、変数が持つオブジェクトの参照が代入される
-関数呼び出し
--関数内部の変数に、入れた変数の参照が代入される

-例:以下は、4行出力するうち、3番目のみ相違となる。

 def func(x):
   print(id(x))
   x = 3
   print(id(x))
     
 a = 1
 print(id(a))
 func(a)
 print(id(a))

-これはC++に例えると、[[こう>https://t.co/f3RW9c01Jg]]なる(thx to hakuyume君)


**なぜimmutableとmutableで説明がつくと思っているのか [#t5dc3c35]
-なんか皆immutableだからかーふーんと言っているが、なぜあの理解で理解できていると思っているのか理解できない
-listはおそらく、listオブジェクトの中にいっぱいintの参照が詰まっている
--list[0]を変更しようとした場合、listオブジェクトの0番目のintの参照を張り替える必要がある
---''mutableというのは、おそらくこれが可能というだけであって、listだからという話ではないと思う''
--実際に、listそのものを完全に代入しなおした場合、listオブジェクトが変わるのでmutableだがidが変わる
--したがって、mutableオブジェクトの場合、mutableオブジェクトのメンバ変数を実行可能だというだけで、それが関数渡しのidの話とは直接関係ないのでは?と感じている


**pythonのポインタのようなもの [#x5b287e0]
-idというものでポインタが取れる

 a = 1
 id(a)

**リストのdeep copy [#wf9e9d84]
-a[:]とするとdeep copyができる

 >>> a = [1,2,3] 
 >>> b = a[:] # b = list(a)とか、b = copy.copy(a)でも大丈夫
 >>> a
 [1, 2, 3]
 >>> b
 [3, 2, 3]



**関数わたし [#lc8ddaa4]
-''重要:list, dict, set, bytearray''は、自身を変更できるので、参照渡しであることを強く意識せねばならない
-関数に渡された値を変更した際に元の値自体も変更できるどうかは,オブジェクトの型に依存
--変更不可(Immutable)な型
---int, float, str, tuple, bytes, frozenset 等
--変更可能(Mutable)な型
---list, dict, set, bytearray 等

-int型を参照わたししたいときは?
--int型に変更できる余地がないので無理です




*bitwise op. [#mec64fd7]
-bytearrayをつかう?





*その他 [#wf9b439d]
-sqrt(n)
--n**0.5ができる

-数学変数
--pi, e, infなどは、math.pi, math.e, math.infなどでアクセスす

-pythonのfor内部で添字をいじっても意味ないので注意!!!
--C++ではたまにfor内部でiを加速するが、pythonは毎回代入される。

-2**100000くらいならまあ余裕で計算できる

*注意 [#y12c9082]
-{}はどっち?
--dictであり、setではない
--s = set()とする










*闇魔法 [#u508d4f8]
-無理やりapplicableっぽくするやつがある











*入出力 [#y4e39d86]

-改行なし

 import sys
 sys.stdout.write(str)










*開発用 [#y2ae2c8d]

**デバッグ [#jab28cb8]
-assert 条件式, ‘エラーメッセージ’
-そもそもコンパイルレベルで発覚するミスをどうやって未然に検出するんだろう?

-loggerという、デバッグレベルを設定できるパッケージがある


**引数の扱い [#kc5f5fe0]
 import argparse
 parser = argparse.ArgumentParser()
 parser.add_argument('processes', type=int)
 parser.add_argument('--env', type=str, default='CartPole-v0')
 parser.add_argument('--arch', type=str, default='FFSoftmax',



















*Pythonでの高階関数 [#m9e08a72]
-[[「なぜ関数プログラミングは重要か」という文章>http://qiita.com/kwatch/items/03fd035a955235681577#%E8%A8%88%E7%AE%97%E5%BC%8F%E5%A4%89%E6%8F%9B%E5%BC%8F%E3%82%92%E5%8F%97%E3%81%91%E5%8F%96%E3%82%8B%E9%AB%98%E9%9A%8E%E9%96%A2%E6%95%B0
]]
--ソフトウェアがどんどん複雑になるので、モジュール化が重要
--関数型言語は、強力なモジュール化機能を提供している
--特に「高階関数」と「遅延評価」が重要である
-関数型言語の良さを関数型言語のコードで説明しているので、関数型言語を知らないユーザにはちっとも伝わらない
 
 
















*メモ [#i00cafb4]
-[[バッチ系関数群>http://python.civic-apps.com/map-reduce-filter/]]
--Map, Reduce, Filter
-[[Cの共有ライブラリを使う>http://akiniwa.hatenablog.jp/entry/2013/09/28/142947]]
-[[型指定して高速化>http://kesin.hatenablog.com/entry/20120306/1331043675]]
--そして更に[[Numpy+Cythonで爆足>http://kesin.hatenablog.com/entry/20120314/1331689014]]
-[[多次元配列>http://bun6memo.blogspot.jp/2013/06/matlab_27.html]]
-[[ヒートマップの書き方>http://qiita.com/hik0107/items/67ad4cfbc9e84032fc6b]]

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS