#author("2024-10-31T17:58:30+09:00","default:okazaki","okazaki") #author("2024-11-07T10:49:13+09:00","default:okazaki","okazaki") #menu(howto/MenuBar) * howto/python [#i439c96a] #contents ** コメント [#ffd23d8f] - "Fortran, C ユーザに向けた実践的 Python プログラミング" https://www.cc.kyushu-u.ac.jp/scp/doc/users/lecture/2016/riit_lecture160824_python_rev16251200.pdf -- &new{2019-10-01 (火) 07:40:13}; -- 基本、NumPy, SciPy, MPI並列, ライブラリ(.so等)内の関数利用, LAPACK利用, 各種インストール の説明あり - pythonでは i++はできないので、i+=1 -- &new{2021-08-26 (木) 09:46:13}; - numpy.linspace(0,10,5) # 0と10を含む5要素のリスト -- &new{2021-08-30 (月) 16:22:40}; - デコレータ(@hogehoge) https://qiita.com/mtb_beta/items/d257519b018b8cd0cc2e https://zenn.dev/ryo_kawamata/articles/learn_decorator_in_python -- &new{2021-09-08 (水) 16:09:25}; (例) from functools import wraps def trace( func ): @wraps( func ) # 問題を起こさないように、wrapsでメタデータを複製しておく。 def wrapper( *args, **kwargs ): result = func( *args, **kwargs ) print( f"{func.__name__}( {args}, {kwargs} ) -> {result}" ) return result return wrapper @trace def fib( n ): """return fibonacci number""" if n in ( 0, 1 ): return n return fib(n-2) + fib(n-1) #fib = trace(fib) #trace(fib)(4) print( fib(4) ) help( fib ) print( fib ) - アインシュタインの和の規則みたいなものをする numpy.einsum https://qiita.com/d-takagishi/items/94e47ecd1abc54978b44 -- &new{2021-09-08 (水) 16:40:47}; - assert( 条件式 ) が使える -- &new{2021-09-08 (水) 17:08:32}; - pythonのオブジェクト解説 https://postd.cc/pythons-objects-and-classes-a-visual-guide/ (青矢印はクラス継承、黒矢印はインスタンス生成) -- &new{2021-09-13 (月) 16:40:30}; - try、Tkinter、浅いコピー、簡易テキストエディタ作成、NumPy、SciPy、Matplotlib、pandas、名前空間、docstring、ミュータブルなど -- プログラミング演習 Python 2019 (喜多 一) https://repository.kulib.kyoto-u.ac.jp/dspace/bitstream/2433/245698/1/Version2020_02_13_01.pdf -- プログラミング演習 Python 2019(コラム編) (同) https://repository.kulib.kyoto-u.ac.jp/dspace/bitstream/2433/245698/2/Version2020_02_13_02.pdf - イテレータからイテレータを呼んでいる例 -- &new{2021-09-15 (水) 21:02:02}; def myg( itarg ): for i in [ 0, 1, 2, 3, 4 ]: try: yield str(i)+"+"+next(itarg) except StopIteration: print( "STOP in myg" ) break except: print( "OTHER" ) def myf(): for i in [ "a", "b", "c", "d"+"e" ]: yield i it = myg( myf() ) for i in range(0,10): try: o = next( it ) print( o ) except StopIteration: print( "STOP" ) break except: print( "OTHER" ) - del インスタンス #インスタンスを削除する -- &new{2021-10-07 (木) 09:54:57}; - a[0][:,0] と a[0][:][0] は違う結果になるようだ。 -- &new{2021-10-08 (金) 20:07:29}; - ブロードキャスト: たとえば、サイズの異なる配列間の演算に出てくる概念のこと -- &new{2022-03-13 (日) 19:37:49}; - numpyにloadtxtというのがあり、列ごとにコンバーター converters = {0: datestr2num} などを渡せる。 -- &new{2022-06-22 (水) 21:17:08}; - クラスについての説明と名前空間の話し(python.org) https://docs.python.org/ja/3/tutorial/classes.html -- &new{2022-06-23 (木) 10:55:17}; (例) #import copy class Warehouse: purpose = 'storage' region = 'west' tricks = [ 'init' ] #全てのインスタンスで共有されてしまう(mutableなオブジェクトを代入した場合。 #オブジェクトのポインタが代入されてるようなもの。) #名前空間と関係するようだが、よくわからん。 #tricks = copy.deepcopy( [ 'init' ] ) #オブジェクトをコピーしたところで意味は無い #self.tricks = [ 'init' ] #文法エラー def add_trick( self, t ): self.tricks.append( t ) def initialize( self ): self.purpose = 'storage' self.regaion = 'west' self.tricks = [ 'init' ] self.__init__() def __init__( self ): self.floor = '2F' w1=Warehouse() w2=Warehouse() print( (w1.purpose, w1.region, w1.floor, w1.tricks) ) print( (w2.purpose, w2.region, w2.floor, w2.tricks) ) -> ('storage', 'west', '2F', ['init']) -> ('storage', 'west', '2F', ['init']) w2.region = 'east'; w2.floor = '5F'; w2.add_trick( "play" ) print( (w1.purpose, w1.region, w1.floor, w1.tricks) ) print( (w2.purpose, w2.region, w2.floor, w2.tricks) ) -> ('storage', 'west', '2F', ['init', 'play']) -> ('storage', 'east', '5F', ['init', 'play']) w2.initialize() print( (w1.purpose, w1.region, w1.floor, w1.tricks) ) print( (w2.purpose, w2.region, w2.floor, w2.tricks) ) w1.initialize() print( (w1.purpose, w1.region, w1.floor, w1.tricks) ) print( (w2.purpose, w2.region, w2.floor, w2.tricks) ) -> ('storage', 'west', '2F', ['init', 'play']) -> ('storage', 'east', '2F', ['init']) -> ('storage', 'west', '2F', ['init']) -> ('storage', 'east', '2F', ['init']) - goto文の代用 -- &new{2022-06-28 (火) 11:12:12}; -- https://note.nkmk.me/python-break-nested-loops/ -- [[https://www.web-dev-qa-db-ja.com/ja/python/pythonにラベル-gotoはありますか?/958125936/>https://www.web-dev-qa-db-ja.com/ja/python/python%E3%81%AB%E3%83%A9%E3%83%99%E3%83%AB-goto%E3%81%AF%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%81%8B%EF%BC%9F/958125936/]] - print(*map(lambda x: '"{}"'.format(x), '日月火水木金土'), sep=',') #個々の文字を引用符 " で括って、*により個々にprintの引数として渡される -- &new{2022-06-28 (火) 11:19:24}; - (memo)Visual Studio Code -- &new{2022-06-29 (水) 17:54:11}; -- https://qiita.com/kusanoiskuzuno/items/c323446f2707f9950ebb -- https://code.visualstudio.com/#alt-downloads -- https://code.visualstudio.com/docs/supporting/requirements -- https://qiita.com/IntenF/items/dbfe1bef4568719a0133 - 字句/構文解析ライブラリ https://qiita.com/shinsa82/items/94d800df630e63511014 -- &new{2022-06-29 (水) 20:06:39}; - scikit-learnライブラリ https://utokyo-ipp.github.io/7/7-2.html -- &new{2022-07-03 (日) 11:12:16}; - 数値が整数か小数かを判定 https://note.nkmk.me/python-check-int-float/ -- &new{2022-07-12 (火) 09:29:03}; - a is None #変数aがNoneであればTrueを与える -- &new{2022-07-12 (火) 09:50:17}; - numpy、配列の比較 https://nishidy.hatenablog.com/entry/2016/04/23/120519 -- &new{2022-07-14 (木) 07:47:45}; - Pythonプログラミング入門 https://utokyo-ipp.github.io/ -- &new{2022-07-14 (木) 08:03:53}; - gnuplotの呼び出し -- &new{2022-09-08 (木) 18:22:14}; >>>>import subprocess >>> p=subprocess.Popen( ['gnuplot' ], bufsize=0, stdin=subprocess.PIPE ) #bufsize=0 で、下で p.stdin.flush() は不要になる。 #stdout=None, stderr=None(デフォルト)のときは、サブプロセスの出力は端末に出る。 >>> a=input() plot tan(x) >>> p.stdin.write( a.encode() ); p.stdin.write( "\n".encode() ) >>> a=input() quit >>> p.stdin.write( a.encode() ); p.stdin.write( "\n".encode() ) その他のメモ >>> subprocess.call( [ 'gnuplot' ] ) #gnuplotのプロンプトが来る。 >>> subprocess.call( [ 'gnuplot', "-e", "plot sin(x); pause 2", "script1", "script2", "-", "script3", "-", "script4" ] ) #スクリプトの実行など(scriptNのファイルの中は print "scriptN" などの gnuplotのスクリプト)。 #- の標準入力のときには gnuplotのプロンプトが来る。 - https://repo.anaconda.com/ -- &new{2022-11-09 (水) 11:35:10}; - PyQt4 https://myenigma.hatenablog.com/entry/2016/01/24/113413#Window%E3%82%92%E4%BD%9C%E3%82%8B -- &new{2022-11-13 (日) 04:06:52}; - tkinter https://myenigma.hatenablog.com/entry/2017/09/15/150945#Window%E3%82%92%E4%BD%9C%E3%82%8B -- &new{2022-11-13 (日) 04:07:59}; - Qt Desinger https://showa-yojyo.github.io/notebook/python-pyqt5.html#qt-desinger -- &new{2022-11-13 (日) 04:11:42}; - PyQt5 https://ops.jig-saw.com/tech-cate/pyqt_graph (ウィンドウを出してみよう、から) -- &new{2022-11-13 (日) 04:13:33}; - たぶん再掲(pythonによるParaViewの操作) -- &new{2022-11-13 (日) 05:45:46}; -- https://www.opencae.or.jp/wp-content/uploads/2015/06/course20111201handout.pdf -- https://ss1.xrea.com/penguinitis.g1.xrea.com/study/ParaView/Python/Python.html -- https://www.rccm.co.jp/icem/pukiwiki/?%E6%93%8D%E4%BD%9C%E3%81%AE%E8%A8%98%E9%8C%B2 - PyQt5, Quick Guide https://www.tutorialspoint.com/pyqt5/pyqt5_quick_guide.htm -- &new{2022-11-17 (木) 06:59:10}; - PyQt5など -- &new{2022-11-22 (火) 12:38:44}; -- https://qiita.com/montblanc18/items/0188ff680acf028d4b63 -- https://www.sejuku.net/blog/75467 -- https://www.xsim.info/articles/PySide/how-to-layout.html -- https://www.naka-sys.okinawa/python-pyqt-gui-devlop/ -- https://myenigma.hatenablog.com/entry/2016/01/24/113413 -- https://zetcode.com/gui/pyqt5/ -- https://www.riverbankcomputing.com/static/Docs/PyQt5/ (リファレンスガイド) -- https://github.com/diego0020/tutorial-vtk-pyqt (VTKとPyQt)-- &new{2022-11-22 (火) 12:41:36}; - from apackage import * を使用したとき、パッケージの__init__.py内の__all__で指定されているものがimportされるらしい。 -- &new{2022-11-29 (火) 15:33:14}; - hoge.pyをfrom hoge import * することもできる。 -- &new{2022-11-29 (火) 16:48:58}; - matplotlibのAPI説明など https://matplotlib.org/stable/api/index.html , https://matplotlib.org/stable/users/index.html , https://matplotlib.org/ -- &new{2022-12-22 (木) 09:54:20}; - Tcl/Tk の Python インタフェース https://docs.python.org/ja/3.7/library/tkinter.html?utm_source=pocket_reader -- &new{2023-02-07 (火) 23:38:46}; - os.listdir().sort() のオブジェクトには、iterateのメソッドが含まれない -- &new{2023-03-31 (金) 22:33:55}; - subprocess.runの例 -- &new{2023-04-01 (土) 17:27:11}; a = "input-data-hogehoge" r = subprocess.run( "cat", shell=True, input=a.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE ) print( "a=", a ) print( "stdout=", r.stdout.decode() ) print( "stderr=", r.stderr.decode() ) - emacsでリージョンのインデントを変更する -- &new{2023-04-17 (月) 15:39:32}; C-c < M-x python-indent-shift-left インデント変更 C-c > M-x python-indent-shift-right インデント変更 - jupyter notebookでinteractiveにグラフを変更する -- &new{2023-05-16 (火) 15:36:35}; import numpy, matplotlib.pyplot, ipywidgets, math @ipywidgets.interact( m=(-20,20,1) ) #min,max,step def f(m=2.0): x=numpy.linspace(-10,10) y=numpy.power(x,m) #print(x) #print(y) #matplotlib.pyplot.xlim(-10,10) matplotlib.pyplot.plot(x,y) - その他interactiveの例 -- https://ebi-works.com/jupyternb-gui/ -- https://toyoki-lab.ee.yamanashi.ac.jp/~toyoki/lectures/simulationMethods/ipywidgetsExamples.html - 実例つき、QWidget 逆引きリファレンス https://tadosuke.com/programming/4547/ -- &new{2023-07-21 (金) 22:08:13}; - https://ja.wikipedia.org/wiki/PyQt -- &new{2023-07-21 (金) 22:28:35}; - https://riverbankcomputing.com/software/pyqt/ から-> "PyQt5 Reference Guide" -> "list of modules" -> "QtWidgets" -> このモジュールの各クラスのマニュアル(不十分) -- &new{2023-07-21 (金) 22:28:54}; - QWidgetを継承した画面開発のテンプレート https://tech.nkhn37.net/pyqt-qwidget-program-template/ -- &new{2023-07-21 (金) 22:32:32}; - フーリエ変換の例 -- &new{2023-08-03 (木) 17:09:18}; import cmath N = 8 x = [] for k in range(0,N): x.append( 1/cmath.sqrt(N) ) #区間[0,1]をN等分して、全てに1/√8のデータをセット y = [] #フーリエ変換 for k in range(0,N): a = 0.0 for j in range(0,N): a = a + 1/cmath.sqrt(N)*x[j]*cmath.exp( 1J*2*cmath.pi*k*j/N ) #1/√N倍している y.append( a ) print( "FT" ) a = 0.0; b = 0.0 for k in range(0,N): print( "{: >5d} {: >20.4f} {: >20.4f}".format( k, x[k], y[k] ) ) a = a + cmath.polar( x[k] )[0] **2 b = b + cmath.polar( y[k] )[0] **2 print( "power = {: >15.4f} {: >15.4f}".format(a, b) ) x = [] #逆フーリエ変換 for j in range(0,N): a = 0.0 for k in range(0,N): a = a + 1/cmath.sqrt(N)*y[k]*cmath.exp( -1J*2*cmath.pi*k*j/N ) #1/Nでなく1/√N倍している x.append( a ) print( "Inverse FT" ) for k in range(0,N): print( "{: >5d} {: >20.4f} {: >20.4f}".format( k, x[k], y[k] ) ) - Python3簡易資料 https://blackknight.ics.nara-wu.ac.jp/pub/doc/python3.pdf -- &new{2023-08-30 (水) 11:25:47}; - openしたときのストリームインスタンスの型とreadlineメソッド -- &new{2023-08-30 (水) 13:11:27}; python仮想環境で (py3913) allium$ python3 >>> f=open("hoge.vti","r") #"rt"と同じでテキストモード読込 >>> type(f) <class '_io.TextIOWrapper'> >>> type(f.buffer) <class '_io.BufferedReader'> >>> f.encoding #encoding属性を持つ(_io.BufferedReaderは持たない) 'UTF-8' >>> f=open("hoge.vti","rb") #バイナリモード読込 >>> type(f) <class '_io.BufferedReader'> 同じく仮想環境で、 (py3913) allium$ python -m pydoc _io.TextIOWrapper (py3913) allium$ python -m pydoc _io.BufferedReader により f.readline() と f.buffer.readline()のドキュメントを見ることができる。 _io.TextIOWrapper の readline Read until newline or EOF. Returns an empty string if EOF is hit immediately. _io.BufferedReader の readline Read and return a line from the stream. If size is specified, at most size bytes will be read. The line terminator is always b'\n' for binary files; for text files, the newlines argument to open can be used to select the line terminator(s) recognized. - 色空間変換パッケージ https://pypi.org/project/colorspacious/ (CIELab→sRGBなど) -- &new{2023-10-13 (金) 17:30:11}; - バイトコンパイル・コンパイル -- &new{2024-04-04 (木) 15:10:00}; バイトコンパイル $ python3 -m compileall *.py __pycache__に.pycが作られる。 マシンコードにコンパイルすることもできるようであるが、 通常のpythonで使える文法の範囲が極端に狭まってしまうようだ。 - ver 3.7未満でファイルの先頭で if sys.version_info < ( 3, 7 ) : sys.exit("ERROR") をしても f-stringがあると文法エラーになるため、先頭にコードを追加するだけではバージョンチェックはできなさそう。 -- &new{2024-05-18 (土) 15:39:38}; - f-stringsを使えないバージョンのpythonで、バージョンが古いというエラーメッセージを出すには次の方法がよさそうである(ファイル先頭でversion_infoを調べても、後方にf文字があるとそこで文法エラーが出て期待するエラー処理が行われないため) -- &new{2024-05-20 (月) 18:04:09}; # check python version dummy_f_string = f"PLEASE USE PYTHON 3.7 OR LATER if you get SyntaxError." import sys if sys.version_info < ( 3, 7 ) : sys.exit( "ERROR: python -v < 3.7" ) - ネットワーク(ノードとエッジ図)のインタラクティブな可視化: https://qiita.com/mitch0807/items/0314a793192b69f5771c + https://qiita.com/baby-degu/items/bf97545595a781050cb5 -- &new{2024-05-28 (火) 09:38:08}; - p=1e+14; print( f'{p: >+12.2g}') #f文字列と書式の例(.formatと同じようだ) -- &new{2024-05-30 (木) 17:52:16}; - disモジュール(逆アセンブルの結果を見る) https://qiita.com/AkariLuminous/items/ab3f382643e92122f8ef#31-%E8%AA%BF%E3%81%B9%E3%82%8B%E6%96%B9%E6%B3%95 -- &new{2024-06-16 (日) 13:20:19}; - べき乗は**を使う 2.73*10**2 #mathematicaは 2.73*^2 -- &new{2024-06-16 (日) 13:23:58}; - Pythonでは、プログラムを起動したディレクトリが自動的にPythonのモジュール検索パスに含まれるらしい。[chatgpt] -- &new{2024-11-07 (木) 10:49:13}; #comment //-------------------------------------------------------------------------------- ** ドキュメント [#dca7f077] - Python標準ドキュメント http://www.python.jp/ (メニューのドキュメントに和訳ドキュメントがある。全モジュール索引もあり) - Python早見帳 https://chokkan.github.io/python/index.html (Python言語の説明) - 特殊メソッドの一覧 https://qiita.com/y518gaku/items/07961c61f5efef13cccc ( __add__ が + 演算子であるなど) - pydoc オンラインヘルプ python -m pydoc -n `hostname` -p 8801 #その後 webブラウザで http://`hostname`:8801に接続 python -m pydoc sys - ヘルプ関係の関数など dir( hoge ) #オブジェクトの属性を調べる。引数無しだと、現在のスコープの属性を返す。 help( hoge ) #オブジェクトのドキュメントを調べる(ドキュメンテーションが書かれていれば) type( hoge ) # オブジェクトの型を知る。 # type, function, methodなどが返ってきたら、クラス、関数、クラスメソッドなどのようだ type( hoge ).mro() # 何のクラスのインスタンスかが出るようだ(クラス継承含む) hoge.dtype #numpy.ndarray型のオブジェクトであるhogeの要素のデータ型を調べる -- 例 >>> b=open( "hogehoge.readme", "r" ) >>> c=b.read(16); print(c); b.close() #readで16文字読み込み >>> help( b.read ) #説明 -- オブジェクトがどのクラスインスタンスであるかであるか知る(例1) a = Hoge() # クラスHogeのインスタンスとして、オブジェクトを生成 type(a) == Hoge # aがクラスHogeのインスタンスの場合、真。 a.__class__ == Hoge でも同じ。 isinstance( a, Hoge ) # aが、クラスHoge又は Hogeを継承したクラスであれば、真 ・https://www.lifewithpython.com/2014/06/python-check-object-instance-class-relationship-by-type-isinstance.html #何のクラスのインスタンスかを知る~ ・https://docs.python.org/ja/3.7/library/inspect.html # import inspect で、オブジェクトについていろいろ調べられるようである~ -- オブジェクトがどのクラスインスタンスであるかであるか知る(例2) from pyscf import gto, scf mol=gto.M( atom='H 0 0 0; H 0 0 1.4', basis='sto-3g' ) mf=scf.RHF( mol ) mf.kernel() type( gto ) # moduleと返るので、モジュール type( scf ) # moduleと返る gto.__file__ # moduleがどのファイル(ディレクトリ階層と__init__.py)かがわかる type( gto.M ) # functionと返るので、関数 # def Mの定義は、ディレクトリ階層内や__init__.pyにあるはず type( mol ) # pyscf.gto.mole.Moleと返るので、そのクラスのインスタンスらしい type( mol ).mro() # 何のクラスのインスタンスかが出るようだ(クラス継承含む) => [pyscf.gto.mole.Mole, pyscf.lib.misc.StreamObject, object] #type( gto.mole.Mole ) # typeと返り、クラスらしい(インスタンスではないため、mro()は使えない) type( scf.RHF ) # functionと返るので、関数 type( scf.RHF ).mro() => [function, object] type( mf ) # pyscf.scf.hf.RHFと返るので、このクラスのインスタンスらしい type(mf).mro() => [pyscf.scf.hf.RHF, pyscf.scf.hf.SCF, pyscf.lib.misc.StreamObject, object] type( mf.kernel ) # methodと返るので、クラスメソッド type( mf.kernel ).mro() => [method, object] ** 命名の慣例 [#iac36e1f] 2022/06/26+α pythonでの命名の慣例 * 先頭に _ をつけたものは外部から書き換え禁止。 * 先頭に __ をつけたものはアクセス禁止。 * 関数名は すべて小文字でスネークケース(単語をつなげる場合は _ でつなぐ)。 * 変数は すべて小文字でスネークケース。 * クラス名は アッパーキャメルケース(大文字から始め、単語をつなげる場合は最初を大文字にしてつなぐ)。 クラスのメソッドの第1引数は selfにする * 定数は すべて大文字でスネークケース。 * 破棄変数として _ 名のみの変数がある。eg) for _ in range(10): print( "hello" ) * 名前の末尾 _ は名前衝突を避けるために使用される(末尾 __ や ___ なども)。 * 名前の先頭と末尾 __...__ はpythonが特別な用途として使っているもの。eg) __init__ * パッケージ名は すべて小文字の短い名前で _ は使わない。 なお、パッケージ名はディレクトリ名やファイル名に対応している。 eg) import tkinter の tkinter eg) import turtle の turtle * モジュール名は すべて小文字の短い名前で _ を使ってもよい。 なお、モジュール名は拡張子を除いたファイル名に対応している。 eg) import tkinter.font の font [ref]~ https://qiita.com/shiracamus/items/bc3bdfc206b39e0a75b2 ~ https://mako-note.com/ja/python-underscore/ ~ https://python.softmoco.com/basics/python-naming-conventions.php ~ ** tkinerモジュール [#xd2790e9] (注) python2は Tkinter、python3は tkinterを importするようだ。名前が異なる。 %%お気楽 Python/Tkinter 入門%% %% http://www.geocities.jp/m_hiroi/light/pytk01.html %% 1. Hello world! http://www.shido.info/py/tkinter1.html PythonのTkinterを使ってみる https://qiita.com/nnahito/items/ad1428a30738b3d93762 ** 実行時間を測る、sleepする [#l5cdfcc5] >>> import time >>> time1 = time.clock() >>> time2 = time.clock() >>> print( time2 - time1 ) 0.0009600000000000164 >>> >>> help( time ) #ドキュメントをみる >>> time1 = time.clock(); time.sleep(10); time2 = time.clock(); print( time2 - time1 ) 4.599999999999049e-05 time.clock()は3.8?から廃止されているので time.time()を使う。 sleepを使う。import time しておいて、time.sleep(2)など ** いくつかの例 [#r7174bd4] インタプリタ起動 $ python #たいていpython2が起動するらしい $ DISPLAY=hostname:0 python3 -B #python3を起動、バイトコンパイルさせない(-Bオプション)、DISPLAYを指定。 $ export PYTHONDONTWRITEBYTECODE=t #これでもバイトコンパイルさせないらしい スクリプトの実行 $ DISPLAY=hoge:0 python3 -B filename.py #filename.pyを実行する。 $ DISPLAY=hoge:0 ./filename.py #filename.pyを実行する。 いくつかの例 >>> from turtle import * >>> for i in range(6): #図形が表示される ... forward(100) ... right(60) ... >>> a = "Python3 is awsome!" >>> a . lower() 'python3 is awsome!' >>> len(a) 18 >>> (1+2J)/5J (0.4-0.2j) >>> for item in [ 'a', 'b', 'c' ]: ... print( item ) ... a b c >>> for c, item in enumerate( [ 'a', 'b', 'c' ] ): ... print( c, item ) ... 0 a 1 b 2 c >>> f=open("temp.txt", "w") >>> for c in range(1,101): #1から100までの数字をファイルに書き出す。 ... f.write( str(c) ) ... >>> f.close() >>> [ord(s) for s in "Python"] #内包記法で文字コードのリストを作る [80, 121, 116, 104, 111, 110] >>> val=10; [ x for x in range(1,val+1) if val %x == 0 ] #内包記法で10の約数のリストを作る [1, 2, 5, 10] #二次元配列を作る >>> a = [ [ str(i)+str(j) for j in range(8)] for i in range(5) ] >>> a [['00', '01', '02', '03', '04', '05', '06', '07'], ['10', '11', '12', '13', '14', '15', '16', '17'], ['20', '21', '22', '23', '24', '25', '26', '27'], ['30', '31', '32', '33', '34', '35', '36', '37'], ['40', '41', '42', '43', '44', '45', '46', '47']] >>> a[4][5] '45' >>> int(a[4][5]) 45 >>> for i in range(5): ... a[i] ... ['00', '01', '02', '03', '04', '05', '06', '07'] ['10', '11', '12', '13', '14', '15', '16', '17'] ['20', '21', '22', '23', '24', '25', '26', '27'] ['30', '31', '32', '33', '34', '35', '36', '37'] ['40', '41', '42', '43', '44', '45', '46', '47'] >>> i = { "GMT" : "+000", "BST" : "+100", "EET" : "+200", "JST" : "+900" } >>> i {'BST': '+100', 'EET': '+200', 'JST': '+900', 'GMT': '+000'} >>> i.items() dict_items([('BST', '+100'), ('EET', '+200'), ('JST', '+900'), ('GMT', '+000')]) ### dict_items( ) が付く意味はなに? 辞書型インスタンスの特殊メソッド__repr__の単なる仕様? >>> import os >>> os.walk("./") >>> i=os.walk("./") >>> next(i) ('./', ['QCLObot', 'ProteinDF_bridge', 'ProteinDF', 'ProteinDF_pytools', 'OpenFOAM', 'LOG_kiku'], ['2dn2.pdb', '1omb-mod.pdb', 'LOG_kiku.tar', 'p3.py~', 'p3.py', 'temp.txt', 'fws.gro.pdb']) >>> next(i) ('./QCLObot', ['.git', 'qclobot', 'scripts'], ['.gitignore', 'LICENSE', 'setup.py', 'README.md']) ### 現在作業中のディレクトリ、作業中ディレクトリ内のディレクトリのリスト、作業中ディレクトリ内の ### ファイルのタプルがイテレータ(next(i))で次々と得られる。 >>> from decimal import Decimal >>> Decimal( '0.1' ) * 3 Decimal('0.3') ### この*はDecimalクラスの特殊メソッド __mul__が使われている。Decimalのインスタンスが生成され(値0.1)、 ### __mul__が引数3で動いている。演算結果は __repr__で表示か。 >>> import sys >>> sys.getfilesystemencoding() 'utf-8' >>> sys.float_info sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1) スクリプトの例 -------------------------------------------------- #!/usr/bin/env python3 #-*- coding:utf-8; -*- import sys def spamfactory( times ): """ スパム工場 """ return "Spam ! " * times print( spamfactory( 3 ) ) input() -------------------------------------------------- $ ./p3.py -------------------------------------------------- #!/usr/bin/env python3 #-*- coding:utf-8; -*- import os #p= "./LOG_kiku" p= "./" for path, dirs, files in os.walk( p ): for f in files: print( path, ":", f ) -------------------------------------------------- $ ./p4.py みんなのPython 第3版, 柴田亨, SBクリエイティブ (2012) 14章の例、 ファイルはここちら [[todoapp.tar>https://orange.eit.hirosaki-u.ac.jp/pw151/index.php?LABO/%E3%81%84%E3%81%8F%E3%81%A4%E3%81%8B%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E7%BD%AE%E3%81%8D%E5%A0%B4#pbbdc599]] #正規表現を使ったファイル一覧の取得 >>> import glob >>> print glob.glob('/dev/sd?') ['/dev/sda', '/dev/sdb'] その他、個々に置換するとき >>> import re >>> [ re.replace('/dev/','') for s in glob.glob('/dev/sd?') ] ['sda', 'sdb'] ** 基本 [#w45c8860] *** 組み込みデータ型 [#f93ebd39] 整数 浮動小数点 複素数 文字列 リスト [ 1, 2, 3 ] タプル ( 1, 2, 3 ) 要素ひとつの場合は ( 1, )とする。( 1 ) = 1 = 整数の値などとなるため ディクショナリ { k1:v1, k2:v2, k3:v3 } bytes型 bool型 set型 { 1, 2, 3 } iter イテレート可能なインスタンスに変換する 備考: 順番があるものが、シーケンス型。 書き換えが可能なものが、書き換え可能型。 書き換え可能でない型は、文字列、タプル(ただし要素追加は可能)と、数値もである(丸ごとの書き換えは可)。 関数の引数は、関数で値を書き換えても、呼び出し元では変わらない(値渡しに相当)。書き換え 可能なものもある(例:リストを渡して、リストの要素を書き換えると呼び出し元でも変更されている)。 *** 型変換 [#gef482c7] int() 文字列を数値に変換 float() str() chr() 数値を文字(列)に変換 hext 数値を16進数に変換 bin 数値を2進数に変換 oct 数値を8進数に変換 *** スライス [#l89629d3] リストのインスタンスaについて、a[2:3]などとして要素を取り出すこと。 *** lambda式 [#m7fbdaf6] see Python文法詳細、p197、オライリー *** 整数除算(商) [#g9b1a36a] i // 2 (iは整数だけでなく、浮動点小数でも切り捨て) *** 文字列操作 [#m496fcb7] raw文字列 r"C:\path\to\file" split join *** アンパック代入 [#kdbd609b] a, b = c, d #スワップ return a, b a, b = foo(hoge) x = ( 1, 2, 3, 4, 5 ) a, *b, c = x #最初と最後を a, cに、それ以外を bに代入 print( f"{a}, {b}, {c}" ) *** リストのアンパック [#yb0c4c62] L=[1, 2, 3] *L # 1, 2, 3 の並び(リストではない) (使用例) def foo( a, b, c ): hogehoge foo( *L ) *** 可変長引数 [#k0a08017] *args タプル **kwargs ディクショナリ def a( *args, **kwargs ): print( "*args=", *args ) #print( "**kwargs=", **kwargs ) # **kwargsは何? #print( type(**kwargs) ) print( "args=", args ) print( "*kwargs=", *kwargs ) print( "kwargs=", kwargs ) ### kwargs.pop( "hoge", default ) で値を得ることもできるらしい。 a( 'zero', 1, 2, 3, term='TERM', val='VAL' ) (出力結果) *args= zero 1 2 3 args= ('zero', 1, 2, 3) *kwargs= term val kwargs= {'term': 'TERM', 'val': 'VAL'} https://note.nkmk.me/python-args-kwargs-usage/ *** ゲッターとセッター(プロパティ) [#s2f31a23] x = property( getx, setx ) # xはアトリビュート、getx, setxはゲッターとセッターのメソッド。 # こうしておくと、インスタンス.xで代入や参照ができる。 例(以下をprop.pyとして保存して、コメントにあるようにpython3インタプリタで使う) class Prop: _val = None def __init__( self, arg=10.0 ): self._val = arg def getvv( self ): print( "In get, return _val/3.0" ) return self._val / 3.0 def setvv( self, arg ): print( "In set, set arg*3.0 to _val" ) self._val = arg * 3.0 # Prop().val で Prop().getvv() が動いたり(getter)、 # Prop().val=arg で Prop().setvv(arg) が動いたり(setter)する。 val = property( getvv, setvv ) # val = property( getvv ) # val = property( None, setvv ) def show( self ): print( "In show, _val of Prop object is ", self._val ) class PropAt: _val = None def __init__( self, arg=10.0 ): self._val = arg @property # Prop().vv で次の Prop().vv()が動く def vv( self ): print( "In get, return _val/3.0" ) return self._val / 3.0 @vv.setter # Prop().vv=arg で次の Prop().vv(arg)が動く # setterはpropertyのあとに定義しなくてはならないようだ。 # また、propertyとsetterとで同じメソッド名の必要あるようだ。 def vv( self, arg ): print( "In set, set arg*3.0 to _val" ) self._val = arg * 3.0 def show( self ): print( "In show, _val of Prop object is ", self._val ) """ import prop import importlib importlib.reload( prop ) #デバッグ用:prop.pyを修正して再度インポート # propertyを使った場合 a=prop.Prop() ; a.show() ; a.val = 100 ; a.val ; a.show() # In show, _val of Prop object is 10.0 # In set, set arg*3.0 to _val # In get, return _val/3.0 # 100.0 # In show, _val of Prop object is 300.0 #100を入れて100を取り出しているように見えるが、 #実際は100*3の値を保持しているインスタンスである。 # @propertyを使った場合 a=prop.PropAt() ; a.show() ; a.vv = 100 ; a.vv ; a.show() # In show, _val of Prop object is 10.0 # In set, set arg*3.0 to _val # In get, return _val/3.0 # 100.0 # In show, _val of Prop object is 300.0 """ [ref]~ https://www.nblog09.com/w/2019/01/09/python-setter-getter/ ~ https://chaika.hatenablog.com/entry/2020/12/10/083000 *** 標準エラー出力に書き出す [#rcbe37c6] print( "hoge", file=sys.stderr ) *** コメント [#zf4c11dc] #comment1 ''' comment2a ''' """ comment2b """ //-------------------------------------------------------------------------------- ** python環境がらみの情報取得 [#p4a8886c] - import sys; print( sys.version_info ); print( sys.version ) #pythonのバージョンを知る - import os; os.environ['LD_LIBRARY_PATH'] #環境変数の値を得られる - import sys, pprint; pprint.pprint(sys.path) #パッケージを読み込むパス - import sys, pprint; pprint.pprint(sys.modules) #読み込んだモジュールの一覧を得る(builtinか、ライブラリか、パス名かなどが判る) ** import [#xacd9999] モジュールの検索順 1)カレントディレクトリ 2)環境変数PYTHONPATH 3)標準ライブラリ 4)site-packages import モジュール名 from モジュール名 import クラス名 他に、 from パッケージ名 import サブパッケージ名 from モジュール名 import 関数名 などいろいろある。 importは、グローバルでも、ローカルにでも可能である。 モジュールの再読み込み import hoge が既に実行されていた場合、再度 import hoge をしても何も 実行はされない。再度、実行する場合は reloadが必要。 なお、マニュアルをみると、完全に挙動が同じなるというわけでななさそうである。 >>> import imp >>> imp.reload( module ) #なお、import moduleが以前になされていること。 Python3.3まではimp.reload() Python3.4以降はimportlib.reload() #importlibの例 import importlib importlib.reload( dispmodule ) #既にいちどimport dispmoduleしていること https://docs.python.org/3/library/imp.html#imp.reload import math math.sin( 1.23 ) or from math import sin sin( 1.23 ) 複素数の数学関数を利用するには import cmath をする πは、import math ののち、math.pi classはモジュールの中などに定義される。モジュールを importして継承クラスを作れる。 #ファイルbook.py内のBookクラスを利用する例 from book import Book class Blog ( Book ) or import book class Blog ( book.Book ) クラスの初期化メソッド __init__ ふつうは継承したクラスの初期化メソッドを super().__init__(hoge)として呼ぶ 丸括弧で括るとインポートする複数のモジュールを複数行で書ける from math import ( sin, cos, tan ) #なお、mathモジュール内の他の関数なども評価されるが、名前空間には登録されていないだけ、と思われる? 同じパッケージを、異なる別名をつけてインポートできる import hoge as alias1 import hoge as alias2 ここで __init__.pyは一回だけしか評価されない ** パッケージ [#x4e1986c] ディレクトリ階層で束ねられたモジュールの集まり ** 関数の動的呼び出し [#wd9462a2] モジュール mod11 の名前空間から、関数を実行するcallableの例 for i in dir( mod11 ): print( "================================================", "mod11."+i ) if i[0:1] == "_": print( "SKIP" ) else: if callable( eval("mod11."+i) ): print( "RUN" ) print( eval( "mod11."+i ) ) eval( "mod11."+i+"()" ) else: print( "NOT-RUN" ) print( eval( "mod11."+i ) ) クラスメソッドを動的に呼び出したり、引数を渡したりする例 class Hoge: def hoge( self, a ): ... def meth( self ): ... eval( "self.hoge" )( a ) ... のように、meth()の中で呼び出すメソッドを文字列演算等で決めることができ、 引数も渡すことができる。 なお、セキュリティ的に evalに渡す引数は、SQLインジェクションのようなものに 注意する。 ** 複素数の扱い [#rbf8b97c] https://note.nkmk.me/python-complex/ ** 例外処理 [#p035b324] - 基本的なエラー一覧とその原因の確認方法 https://note.nkmk.me/python-error-message/ - 例外処理(try, except, else, finally) https://note.nkmk.me/python-try-except-else-finally/ ** globalとnonlocal [#na4e8769] - 関数内でのグローバル変数の利用~ http://www.ops.dti.ne.jp/ironpython.beginner/global.html ~ 関数内で、グローバル変数に代入したいとき、関数内でglobal宣言をする。 さもないとエラーになるか、ローカル変数として扱われる。 - 違い global hoge # hogeはモジュールスコープ(グローバルスコープ)のものであることを宣言 nonlocal hoge # hogeは外側、無ければ、外側の外側、外側の外側の...のスコープのもの # であることを宣言。 # ただし、モジュールスコープのものであることを宣言することはできない - 用語: クロージャ=外側のスコープの変数を参照して値を変える関数のこと? ** globalsとlocals [#t158b244] それぞれグローバル変数、ローカル変数を表示する。追加も可。 >>> b=10 >>> def hoge(): ... c=20 ... print(globals()) ... print(locals()) ... >>> globals() { ..., 'b': 10, 'hoge': <function hoge at 0x2adffbbe5040>} >>> locals() { ..., 'b': 10, 'hoge': <function hoge at 0x2adffbbe5040>} >>> hoge() { ..., 'b': 10, 'hoge': <function hoge at 0x2adffbbe5040>} {'c': 20} >>> globals()['d']=30 >>> d 30 ** exec [#jf5644ed] ソースコードを実行する。他のファイルを読み込んで実行するときは exec( open("hoge.py").read() ) デフォルトで変数は残らない。 関数内でexecにより定義された変数が、関数終了後に追加されているか消えるかを以下のように調べた。 なお、以下のコードをモジュールとして作り、importさせた場合も結果は同じだった。 >>> import pprint >>> def delf(): ... global f ... try: del f ... except: pass #1行で書けない? #G,Lに追加あり >>> (lambda: exec('f=90', globals(),None ))(); pprint.pprint({'G':globals(),'L':locals()});delf() #※ >>> (lambda: exec('f=90', locals(), globals()))(); pprint.pprint({'G':globals(),'L':locals()});delf() #G,Lに追加無し >>> (lambda: exec('f=90', None, None ))(); pprint.pprint({'G':globals(),'L':locals()});delf() #デフォルトの動作 >>> (lambda: exec('f=90', globals(),locals() ))(); pprint.pprint({'G':globals(),'L':locals()});delf() >>> (lambda: exec('f=90', None, locals() ))(); pprint.pprint({'G':globals(),'L':locals()});delf() >>> (lambda: exec('f=90', locals(), locals() ))(); pprint.pprint({'G':globals(),'L':locals()});delf() execによりimportしても同じである。 >>> (lambda: exec('import time,pprint; pprint.pprint({"G":globals(),"L":locals()}); time.sleep(3)'))(); \ pprint.pprint({'G':globals(),'L':locals()}) #timeは追加無し >>> (lambda: exec('import time,pprint; pprint.pprint({"G":globals(),"L":locals()}); time.sleep(3)',globals()))(); \ pprint.pprint({'G':globals(),'L':locals()}) #timeは追加あり globals, localsの挙動がいまいちよくわからないが、変数を追加する場合は ※にすればよい。 そうでなければデフォルトの動作でよい。 ParaViewのマクロは、importは追加されるが変数は追加無しであるため、execで実行されている訳ではなさそうである。 ** yeild [#k1d8f154] https://qiita.com/weedslayer/items/11de0f314ccbb70de812 ~ returnは関数がそのまま終了する。これに対して、yeildは返値を渡し、制御を戻すが、再度関数が呼ばれると 続きから実行される。 返す値が無くなると、StopIteration例外が発生するようだ。 ** printとformat [#n2d42994] print( hogehoge, end='' ) #printで改行しない end='\t' だと最後にtabが出力 sep=',' で複数出力する時のセパレータを指定 file=ファイルオブジェクト でファイルに出力 fo=open('file.txt', 'w')とし、file=fo とし、使った後で fo.close() flush=True で、出力後にフラッシュ https://note.nkmk.me/python-format-zero-hex/ ~ https://note.nkmk.me/python-numpy-set-printoptions-float-formatter/ ~ 'フォーマット指定の文字列'.format( arg1, arg2, ... ) #フォーマットされた文字列を作る '{: >+6,}'.format(+123) #例 formatを使わなくても、 f'...{argN: >+6,}...' のようにして、同様の文字列を作ることができる 以上は、print関数と一緒に使う必要は無い。 {} のところが argNになる { や } をそのまま出力する場合には {{ や }} とする : の次が空白だと、余った部分が空白で埋められる。 + で正の数でも符号を表示、 >6 は6文字以下(6文字以上あるとはみ出して表示) , で3桁ずつ,を付ける {:10x} で10桁の16進数表示 {: >+12.2f} で12文字以下で、小数点以下が2桁で表示 {: >+12.2e} で同様に指数表現(小数点以下2桁で指数表現) {: >+12.2g} で有効数字2桁で表示 例) print('{: >+6,}'.format(+1234567)) print('{:10x}'.format(+1234567)) print('{: >+12.2f}'.format(+1234567)) print('{: >+12.2e}'.format(+1234567)) print('{: >+12.2g}'.format(+1234567)) +1,234,567 12d687 +1234567.00 +1.23e+06 +1.2e+06 numpyのndarray型のデータをフォーマット指定する場合 numpy.set_printoptions( formatter={ 'complex_kind' : '{: >+20.4f}'.format } ) でcomplex128型のデータのndarrayのオブジェクトを出力をすると、 [ +0.2967-0.4617j +0.2967-0.4617j] などとなる __str__メソッドを定義すると、print(インスタンス)で__str__を実行して独自の出力を出せる。 例) class MC: def __init__(self,v): self.value = v def __str__(self): return f"MC instance, value = {self.value}" print( MC(42) ) MC instance, value = 42 //-------------------------------------------------------------------------------- ** クラス変数 [#z81ab08f] class Hoge: dumm = None #クラス変数 def __init__( self ) self.junk = None #ただのインタンス obj1 = Hoge(); obj1.junk = 1 obj2 = Hoge(); obj2.junk = 2 obj3 = Hoge(); obj3.junk = 3 Hoge.dumm = 56789 print( Hoge.dumm ) print( obj3.junk ) //-------------------------------------------------------------------------------- ** その他 [#p1bc6d4f] *** インデントのタブとスペース [#u5078b6f] 同じスコープのインデントに、タブとスペースが混ざっていたらインデントエラーになる。 どちらかに統一する。 *** 全角スペースは \u3000 である [#e50b412e] a="abc\u3000def" b=open( "hoge.txt", "w" ); print(a,file=b); b.close() *** 文字の置き換え [#t32318a4] "AB789CDあEいFG".translate( "".maketrans("あいABC","ai012") ) これは echo "AB789CDあEいFG" | tr "あいABC" "ai012" のようなものに相当。 ただし trは日本語不可。 *** 文字列内のパタンを検索 [#i300b42b] パタンに一致した場合、その部分を示すre.Matchのオブジェクトを返す。 reMatchのオブジェクトは、group()によって文字列を受け取れる。 パタンに一致が無かったらNoneを返す。 >>> import re >>> a=re.search( "\d{4}", "ab12345cd5678ef" ) >>> a <re.Match object; span=(2, 6), match='1234'> >>> a.group() #a=Noneのときは None.group()はエラーになる '1234' #1行で、エラー込みで、一致した文字列を受け取る(もっとよい方法は?) x=re.search( "\d{8}", "ab12345cd5678ef" ); x = x.group() if x else None https://note.nkmk.me/python-re-match-object-span-group/ *** リストと辞書とsorted [#ecbcce6f] >>> d=[ ('A','5'), ('B','4'), ('D','1'), ('C','2'), ('E','3'), ('B','9') ] >>> dict(d) {'A': '5', 'B': '9', 'D': '1', 'C': '2', 'E': '3'} #キーが同じものはひとつのみになる。おそらく最後の要素の値になる >>> dict(d).items() dict_items([('A', '5'), ('B', '9'), ('D', '1'), ('C', '2'), ('E', '3')]) #辞書をタプルのリストにしたようなものを与える。see help(dict) >>> sorted(dict(d)) #キーのみ並び替えたリストを与える ['A', 'B', 'C', 'D', 'E'] >>> sorted(dict(d).items()) #(キー,値)の並び替えたリストを与える [('A', '5'), ('B', '9'), ('C', '2'), ('D', '1'), ('E', '3')] *** リストとsort [#a8e126d8] (注意) リストのメッソドsortは データを書き換える。 組み込み関数のsortedは 新しいリストを生成して与え、元のリストは書き換えない。 sortは安定な並び替えである。sortedは安定化は不明(helpに無し)。 sortとsortedの違い https://note.nkmk.me/python-list-sort-sorted/ >>> d=[ ('A','5'), ('B','4'), ('D','1'), ('C','2'), ('E','3'), ('B','9') ] >>> d.sort(key=lambda x: x[1], reverse=True) >>> d [('B', '9'), ('A', '5'), ('B', '4'), ('E', '3'), ('C', '2'), ('D', '1')] >>> d=[ ('A','5'), ('B','4'), ('D','1'), ('C','2'), ('E','3'), ('B','9') ] >>> d.sort(key=lambda x: x[0], reverse=True) >>> d [('E', '3'), ('D', '1'), ('C', '2'), ('B', '4'), ('B', '9'), ('A', '5')] 途中にprint文を挟めた例(なお、stderrに出力させないとキーの値に使われる) >>> d=[ ('A','5'), ('B','4'), ('D','1'), ('C','2'), ('E','3'), ('B','9') ] >>> d.sort(key=lambda x: (print(x, x[1], file=sys.stderr), x[1]), reverse=True) ('A', '5') 5 ('B', '4') 4 ('D', '1') 1 ('C', '2') 2 ('E', '3') 3 ('B', '9') 9 >>> d [('B', '9'), ('A', '5'), ('B', '4'), ('E', '3'), ('C', '2'), ('D', '1')] *** リスト、辞書の整形出力 [#e1df08f7] import pprint pprint.pprint( list_val, widhth=160 ) https://note.nkmk.me/python-pprint-pretty-print/ *** ファイルをseek [#z9f1b5c5] 先頭にする例 fp.seek(0,0) # offset=0, referencepoint=0 でファイル位置変更 *** 比較演算の組み合わせ [#pa46333c] w = 3 2 <= w and w <= 8 2 <= w <= 8 #上記と同じ *** zip [#k45c029a] x = ( 1, 2, 3, 4, 5 ) y = ( 10, 20, 30, 40, 50 ) for i, j in zip( x, y ): print( i, j ) *** 辞書のループ [#j14014dd] z = {'a': 1, 'b': 2, 'c':3 } for key, val in z.items(): print( key, val ) for k in z.keys(): print( k ) for v in z.values(): print( v ) //-------------------------------------------------------------------------------- ** Excelのワークブックの読み書き [#qaa96a7d] import openpyxl wb=openpyxl.load_workbook("testbook.xlsx", data_only=True) wksheet=wb["Sheet1"] for i in wksheet.iter_rows(min_row=2): print( "i=", i, "i[0].row=", i[0].row ) # 各行のループ変数 iは、excelのセルを要素とするタプルが入っている。 # i[0], i[1], ..., i[p], ... は左からp番目のセルである。 # i[p].rowはそのセルがexcelのシートで何行目かの番号である。 wb = openpyxl.load_workbook( 'sample.xlsx') #ワークブックの読み込み wb = openpyxl.Workbook() #新規ワークブック生成、 wb.sheetnames #シート名のリスト(新規の場合、シートは"Sheet"のみ) wb.active #現在選択されているシート(新規の場合、"Sheet") st = wb.active #現在選択されているシート st.title = 'Sheet100' #シート名変更 st2 = wb[ st.title ] #シートの取得 True if id(st) == id(st2) else False #Trueが返るのでstとst2は同じもの st2[ "D2" ] = "d-2 cell contents" #セルに代入 st2.merge_cells( "D3:f4" ) #セルを結合 st2[ "D3" ] = "combined d-3 cell contents" st2[ "D3" ].alignment = openpyxl.styles.alignment\ .Alignment( vertical="center" ) #中央配置 wb.save( "wb-temp.xlsx" ) #ワークブックの保存 https://gammasoft.jp/support/how-to-use-openpyxl-for-excel-file/ ~ https://atmarkit.itmedia.co.jp/ait/articles/2202/08/news031.html ~ https://note.nkmk.me/python-openpyxl-usage/ ** csvファイルを読む [#sfe13c9f] #csvのフォーマットは生成するソフトに依存しているため注意。Excelの推奨形式は #csv.readerで大丈夫らしい。 import csv fp=open( "testbook.csv", encoding='utf-8-sig' ) #BOM付きのファイルの場合 list( csv.reader( fp ) ) または list(...) の代わりに ite=csv.reader( fp ) #_csv.reader関数を返す(イテレータ機能をもつ) #_csvはモジュールらしい。_csvは import _csv; _csv.__file__ #してみると、.soの共有ライブラリのファイルである。 #help(_csv); type(_csv); type(_csv).mro() をみよ。 for r in ite: #rはcsvの各行のリスト for c in r: #各行について、cは列の項目 print( c, end=' / ', file=sys.stdout ) print( file=sys.stdout ) (注) openするとき、BOMがある場合は必ず encoding='utf-8-sig' を指定する。 さもないと、読み込んだ最初の項目の先頭に BOMを示す文字( "\ufeff" )が付いてしまう。 確か、Excelアプリで xlsxから csvを作ると BOM付きである。 BOMなしのファイルは encoding='utf-8-sig' でオープンしても構わないようだ。 https://qiita.com/msk02/items/c3a1c4a1e1ef94c37228 ~ https://www.lifewithpython.com/2017/10/python-detect-bom-in-utf8-file.html - openのencoding fp=open( "testbook.csv" ) #環境に依るが たいていデフォルトで encoding='utf-8' fp=open( "testbook.csv", encoding='utf-8' ) #BOMなしファイル fp=open( "testbook.csv", encoding='utf-8-sig' ) #BOMつきファイル - 他 #- - - - - - - - - - - - - - - - - - - - - #ファイルdisp.py def disp(ite): fo=open( "disp-temp.txt", "w" ) #BOMなしで書き出し for r in ite: for c in r: print( c, end=' / ', file=fo ) print( file=fo) fo.close() #- - - - - - - - - - - - - - - - - - - - - を作っておいて >>> import disp >>> disp.disp( ite ) # iteは上のもの のように使える。 //-------------------------------------------------------------------------------- * パッケージとモジュールの構造(まとめ) [#t12fefe2] ** 説明の前提(用語、予備知識) [#a2bcf5c7] 次のディレクトリ階層を仮定して、以下を説明。 mytp |-- __init__.py |-- mod01.py |-- mod02.py `-- mysp1 |-- __init__.py |-- mod11.py `-- mod12.py いま、mod01,02,11,12内に 関数func01,02,11,12があるとする。 また、インポートのために、mytpを含むディレクトリが PYTHONPATH環境変数などに含まれていること。 - 用語: パッケージ = ディレクトリ, 例 mytp サブパッケージ = サブディレクトリ, 例 mysp1 モジュール = ファイル, 例 mod01.pyなど オブジェクト = モジュール、関数、などなど オブジェクト名は、名前空間でもあり、名前空間には名前空間(オブジェクト)を階層的に含むようだ。 最初に pythonが実行している名前空間は __main__ である。 (__main__で import hoge すると __main__内に hogeの名前空間が作られると思うが、 __main__.hoge のような記述はできないようで、暗黙的に __main__. が付くと思われる。ちょっとちがう?) 名前空間に登録されている名前は dir() で知ることができる。 __name__ # 現在の名前空間 dir( [オブジェクト名] ) # オブジェクト名(名前空間)に登録されている名前(インスタンス名、関数名、 # 名前空間名など)のリスト。 //---------------------------- ** (トップレベルの) パッケージのインポート [#m67d209d] import mytp # mytp/__init__.pyがあれば実行される。 # 現在の名前空間に mytpが追加されるが、mytp/__init__.pyが無かったり、空であれば、 # mytpの名前空間もほぼ空のままであり mytp.mod01などは使用できない。 - モジュールや、モジュール内のオブジェクトのインポート import mytp.mod01 # 現在の名前空間にmytpが追加され、mytpの名前空間に mod01が追加され、 # mod01モジュールの関数などが使用できる。 mytp.mod01.func01() from mytp import mod01 # mytpディレクトリの mod01が、現在の名前空間に追加される。 # mod01モジュールの関数などが使用できる。 mod01.func01() from mytp.mod01 import func01 # mytpディレクトリのmod01内の func01が、現在の名前空間に追加され、 # そのままで func01を使用できる。 # 追記:func01がモジュールスコープ(今の場合mod01)にて if文を使って条件に #よって defされている関数であってもよいらしい。 func01() - mytp/__init__.py を用意すると次のようなことができる // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - print( "* __name__ = ", __name__ ) # このパッケージ名 mytp となっている # __main__で import mytp としただけで mytp.mod01.func01() が使用できるようになる。 from mytp import mod01 # mytpの名前空間に mod01が追加される。mytp は . でもよいようだ from mytp import mod02 # mytpの名前空間に mod01が追加される。mytp は . でもよいようだ #このファイル ( 名前空間 mytp ) では mod01.func01() が使用できる。 mod01.func01() # 関数は名前空間 mytp に登録されるため、 mytp.initmytp() で使用できる。 def initmypt(): print( "initmypt" ) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //---------------------------- ** サブパッケージのインポート [#a1e00469] import mytp.mysp1 # mytp/__init__.pyがあれば実行される。 # 現在の名前空間に mytpが追加される。 # mytp/mysp1/__init__.pyがあれば実行される。 # mytp名前空間に mysp1が追加されるが、mysp1の名前空間はほぼ空であり、 # mytp.mysp1.mod11などは使用できない。(状況は import mytp と同じ)。 from mytp import mysp1 # mytp/__init__.pyがあれば実行される。 # mytp/mysp1/__init__.pyがあれば実行される。 # 現在の名前空間に mysp1が追加されるが、mysp1の名前空間はほぼ空であり、 # mysp1.mod11などは使用できない。(状況は import mytp と同じ)。 - モジュール、モジュール内のオブジェクトのインポート import mytp.mysp1.mod11 # mytp/__init__.pyがあれば実行される。 # mytp/mysp1/__init__.pyがあれば実行される。 # 現在の名前空間にmytpが追加され、mytpの名前空間に mysp1が追加され、 # mysp1の名前空間に mod11が追加され、 # mod11モジュールの関数などが使用できる。 mytp.mysp1.mod11.func11() from mytp.mysp1 import mod11 # mytp/__init__.pyがあれば実行される。 # mytp/mysp1/__init__.pyがあれば実行される。 # mytp/mysp1ディレクトリの mod11が、現在の名前空間に追加される。 # mod11モジュールの関数などが使用できる。 mod11.func11() from mytp.mysp1.mod11 import func11 # mytp/mysp1ディレクトリのmod11内の func11が、現在の名前空間に追加され、 # そのままで func11を使用できる。 func11() - mytp/mysp1/__init__.py を用意すると次のようなことができる // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - print( "* __name__ = ", __name__ ) # このパッケージ名+サブパッケージ名 mytp.mysp1 となっている # __main__で import mytp としてもこのサブパッケージは読み込まれない。 # import mytp.mysp1 とすると mytp.mysp1.mod11.func11() などが使用できるようになる。 from mytp.mysp1 import mod11 # mytp.mysp1の名前空間に mod11が追加される。mytp は . でもよいようだ from mytp.mysp1 import mod12 # mytp.mysp1の名前空間に mod12が追加される。mytp は . でもよいようだ # __main__で from mytp import mysp1 とすると mysp1 が名前空間に追加され、mysp1.mod11.func11()など # が使用できるようになる。 #このファイル ( 名前空間 mytp.mysp1 ) では mod11.func11() などが使用できる。 mod11.func11() # 関数は名前空間 mytp.mysp1 に登録されるため、 mytp.mysp1.initmysp1() で使用できる。 def initmysp1(): print( "initmysp1" ) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //---------------------------- ** (__main__などからの) パッケージ、サブパッケージの使い方 [#je2cf510] 1) myptや mytp.mysp1をインポートして、mytpからfunc11を指定する。 - 指定が長いが、把握しやすい。 - 混乱しないのであれば asを併用するとよい。 import mypt mypt.mod01.func01() import mytp.mysp1 mytp.mysp1.mod11.func11() import mytp.mysp1 as subn subn.mod11.func11() 2) mod01や mod11, mysp1をインポートして、mod01や mod11, mysp1からfunc11などを指定する。 - 名前衝突が起こる。 - 把握しにくく、混乱しやすい。 from mytp import mod01 mod01.func01() from mytp.mysp1 import mod11 mod11.func11() from mytp import mysp1 mysp1.mod11.func11() //---------------------------- ** その他 __main__.pyなど [#l0c9f01a] python -m モジュール名 で、モジュールを読み込み。そのモジュールのディレクトリにある __main__.pyを実行する(無ければエラー)。 __init__.pyがあれば事前に実行される。 python -m bcone で bcone/__main__.pyを実行させるのがめんどいなら、 alias bcone='python -m bcone' するとよいだろう。 また、__main__.pyで他のファイルを実行したい時は、import bcone.main とするとよいでしょう(この場合は bcone/main.pyが実行)。 setup.cfg :~ パッケージインストールに関するひとつのファイルである。 中の entry_pointで /usr/bin内に置くコマンドと、そのコマンドにより実行される パッケージ内のpython関数を指定することができるらしい。 ~ setup.py :~ 似たようなもの。setuptoolsをimportして使われるようだ。 python -c 'import hoge; hoge.func()' などコードを-cオプションで実行する。importの前に空白があると インデントエラーになる。'...'の文字列を改行込みでタイプしても良い。 //---------------------------- //-------------------------------------------------------------------------------- * matplotlibモジュール [#v875f700] - グラフを描く -- matplotlib 線・マーカー種類など [[URL>https://science-log.com/pc%E9%96%A2%E9%80%A3/%E3%80%90python%E3%80%91matplotlib%E3%81%A7%E3%82%B0%E3%83%A9%E3%83%95%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%80%90%E7%B7%8F%E3%81%BE%E3%81%A8%E3%82%81%E3%80%91/#b]] -- https://qiita.com/nkay/items/d1eb91e33b9d6469ef51 - 3Dグラフを描く -- https://techacademy.jp/magazine/29976 -- https://dreamer-uma.com/python-3d-graph/ -- https://qiita.com/orange_u/items/8a1e285a45093857aef7 //-------------------------------------------------------------------------------- * numpy, scipyのドキュメント [#ud5a2b2a] - Numpy and Scipy Documentation https://docs.scipy.org/doc/ -- SciPy search the docs? https://docs.scipy.org/doc/scipy/ reference/ -- SciPy search the docs(正しいURL)? https://docs.scipy.org/doc/scipy/search.html -- NumPy search the docs https://numpy.org/doc/stable/ //-------------------------------------------------------------------------------- * scipyモジュール [#n9aeaedb] ** scipy.integrate.RK45クラスの説明 [#cc1f236f] https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.RK45.html ~ import scipy.integrate; help(scipy.integrate.RK45) も同じ情報が表示される ~ c.f. help(scipy.integrate.solve_ivp) http://www.physics.okayama-u.ac.jp/~otsuki/lecture/CompPhys2/ode/ode.html ~ //https://www.fixes.pub/program/465196.html ~ RK45は5次のルンゲクッタ法を使用して、4次のルンゲクッタ法のステップサイズを制御している。 また、マニュアル help(solve_ivp) によると、RK45は複素数も利用できる。 ただし、初期値が実数であっても、複素数のデータ型で与えること。 //-------------------------------------------------------------------------------- * numpyモジュール [#x0b905c7] ** ndarray型と matrix型 [#t6f1099c] 以下は 二次元配列の ndarray型 ( type(a)でインスタンスの型を調べられる。また、下の float64の 64などは環境依存だろう ) a=numpy.zeros( (2,2) ) # 2行2列のfloat64のゼロで初期化した二次元配列を作る # a.dtypeは float64 a=numpy.array( [[1,2],[3,4]] ) # 組み込みリスト型から、二次元配列を作る # a.dtypeは int64, リストの要素が整数なので a=numpy.empty( (2,2) ) # 2行2列のfloat64の未初期化の二次元配列を作る # a.dtypeは float64 a=numpy.array( [[1,2],[3,4]], dtype='complex128') # dtype指定もできる # ビット数を省略するとpythonの組込み型のビット数(環境依存)となる b=numpy.zeros_like( a, dtype='float64' ) # aと同じ配列サイズのゼロで初期化した多次元配列を作る b[:,:] = 1.2 #すべての要素を 1.2にする b = b.astype( numpy.int64 ) #要素のdtypeをint64に変換する。要素は型変換される 以下は matrix型(二次元配列に限定され、扱いはndarrayと同じではない) a=numpy.matrix( [[1,2],[3,4]] ) # 組み込みリスト型から作る # a.dtypeは int64, リストの要素が整数なので scipyモジュールは、matrixは使わずに、ndarrayを利用しているようだ。 ndarrayで要素毎に型の違う配列を扱う事も出来るが、その場合には pandasモジュールの方が便利らしい。 行列の用意、初期化など https://note.nkmk.me/python-numpy-zeros-ones-full/ ~ データ型の指定、など https://note.nkmk.me/python-numpy-dtype-astype/ ~ numpy.ndarray型 https://note.nkmk.me/python-list-array-numpy-ndarray/ ~ 二次元配列と行列の演算など https://note.nkmk.me/python-numpy-matrix/ ~ ** Python組み込み型変数のビット数を調べる [#v5ef60fe] numpy.float_ #らしい。この例は floatについて調べている ** 2次元配列と行列 [#j37d6922] ndarrayの要素・行などの参照 https://note.nkmk.me/python-numpy-select-element-row-column-array/ ~ a=numpy.array( [[1,2],[3,4]] ) の2次元配列のとき a[0,1] や a[0][1] は (0,1)要素 スライスで参照できる、代入もできる a[0,:] は 0行目の1次元配列(次元がひとつ減る) a[0:1,:] は 0行目からなる2次元配列 a[:,0] は 0列目からなる1次元配列(次元がひとつ減る) a[:,0:1] は 0列目からなる2次元配列 a[:,0] = 9 #参照したすべての要素に 9を代入(右辺が配列の場合、サイズが合うなどすれば代入可) 次元がひとつ減る => スライスではなく、数字の指定で減る 2次元配列や1次元配列を使って行列演算ができる。 numpy.dot関数、 dotメソッド や @ メソッド、で掛算(matrix型の場合は * メソッドも掛算)。 なお、2次元配列と1次元配列の掛算では、 1次元配列が、演算の左にある場合は行ベクトル、右にある場合は列ベクトルの2次元配列のように扱われる。 そして、1次元配列同士の掛算は内積になる。 dtype型の違う2次元配列(行列)の演算は、高いほうの型に変換されるようである。(どちらが高い型かの順番は?) ブーリアンインデックスによる参照、代入も可 a[ :, (True,True,False,False) ] ファンシーインデックスによる参照、代入も可 a[ :, (0,1) ] #参照する列の添え字を指定(重複可)、代入も可。 a > 5 # 配列aの各要素が、条件に対して Trueか Falseかになった配列(ブーリアンインデックス)が返る a[ a > 5 ] # 5より大きい要素のみを指定して参照、代入も可。参照の結果は1次元配列化されて得られる 複数の次元で指定する場合は a[ numpy.ix_( (False,True,True), (True,False,True,False) ) ] のように ix_関数 を使わないと正しく指定できない。 また、 3次元以上の配列は、ひとつの次元で指定することしか出来ないようである(期待通りの結果にはならないとのこと)。 (※注) 配列がビューではなく、コピーで作られてしまっている場合(生じうる?)は、代入しても値は変化しない ** 多次元配列の次元を減らす [#ba905119] 多次元配列を1次元化する https://note.nkmk.me/python-numpy-ravel-flatten/ ~ 多次元配列の次元を減らす https://codechacha.com/ja/python-flatten-list/ ~ a=numpy.arange(12).reshape( (3, 4) ) # 0~11の要素をもつ 3x4行列 a.reshape(-1) # 数字ひとつなので1次元配列。サイズ -1は自動で決められる(この場合は要素数) a.ravel() #可能な限りビューを返す a.flatten() #データはビューでは無く、必ずコピーされる などなど 多次元配列の形状を変える https://note.nkmk.me/python-numpy-reshape-usage/ ~ a=numpy.arange(12).reshape( (3,4) ) a.reshape( (4,3) ) # データはコピーされるが、データの1次元的なメモリー配置変わらなく # サイズが切り直されるような形。 # 可能な限りビューが返る。 a.reshape( (4,3) ).copy() # 明示的にコピーを返したい場合 # 引数で、変換順序 order='C' (デフォルト) や 'F' などの指定はできるが、使い道はない? # a.reshape( (4,3) ) をそのまま端末に出力した場合と、printで出力した場合で、表示のされ方が異なる。 # order='C' や order='F' を指定した場合の挙動がよくわからない。 配列の次元、サイズを調べる a=numpy.arange(12).reshape( (3, 4) ) a.ndim a.shape ** reshape関数の仕様を調べる [#nc1fe31b] import numpy as np type( a ) # aが numpy.ndarray のとき help( np.ndarray ) # import numpy as np してると、typeで numpy. と出るが、numpy. ではなく np. で指定する # reshapeメソッドの説明はあるが、numpy.reshapeを見よとある help( np.reshape ) # 引数newsharpは、intか intのタプルとある ** 注意(viewとcopyを参照) [#u24da219] >>> import numpy >>> a = numpy.array( [ 1.2, 2.3] ) >>> b = 2*a >>> b array([2.4, 4.6]) >>> a[0] = 7.7 >>> a array([7.7, 2.3]) >>> b array([2.4, 4.6]) >>> c=b >>> c array([2.4, 4.6]) >>> b[0]=9.8 >>> c array([9.8, 4.6]) #ただの代入であればcも変化するので注意! ** ビュー(view)とコピー(copy) [#k5043c15] https://note.nkmk.me/python-numpy-view-copy-shares-memory/ a.copy() #コピーを生成する rcd = a.base is None #Trueなら、ビューである - numpy.shares_memory( a, b ) #片方がもう一方のビューviewのときTrue - 引数のデフォルトオブジェクトが共有されてしまう例 def d( default = {} ): # defaultの返値 {} が共有されてしまう例 return default av = d() au = d() av['FOO'] = 100; print( 'av=', av, ' au=', au) av['BAR'] = 200; print( 'av=', av, ' au=', au) def d( default = None ): if default == None: default = {} # 共有されない return default av = d() au = d() av['FOO'] = 100; print( 'av=', av, ' au=', au) av['BAR'] = 200; print( 'av=', av, ' au=', au) 出力結果 av= {'FOO': 100} au= {'FOO': 100} av= {'FOO': 100, 'BAR': 200} au= {'FOO': 100, 'BAR': 200} av= {'FOO': 100} au= {} av= {'FOO': 100, 'BAR': 200} au= {} - pythonの代入等、基本は参照を渡すが、場合によって複製を渡すようだ - 深いコピー(deep copy) import copy hoho = copy.deepcopy( hoge ) #オブジェクトに含まれるオブジェクトも複製する 単純に、複製である。 - 浅いコピー(shallow copy) hoho = hoge #オブジェクトに含まれるオブジェクトについては参照を渡す オブジェクトにオブジェクトが含まれない場合には、深いコピーと同じ。 - 備考 オブジェクトのcopyメソッドが実際どのようなコピーをするかは、そのクラスに依存すると思われる。 スライスした次元は、浅いコピーになると思われる。 https://note.nkmk.me/python-copy-deepcopy/ *** mutable(ミュータブル)とimmutable(イミュータブル) [#tb55fdb0] 『オブジェクトによっては 値 を変更することが可能です。 値を変更できるオブジェクトのことを mutable と呼ぶ。 生成後に値を変更できないオブジェクトのことを immutable と呼ぶ。 (mutableなオブジェクトへの参照を格納している immutableなコンテナオブジェクトの値は、 その格納しているオブジェクトの値が変化した時に変化するが、コンテナがどのオブジェクトを 格納しているのかが変化しないのであれば immutableです。 immutable かどうかは値が変更可能かどうかと無関係。) オブジェクトが mutable かどうかはその型によって決まる』~ [ref] https://docs.python.org/ja/3/reference/datamodel.html から改変 c.f.~ オブジェクトは、同一性(identity)、型、値をもつ。~ id() 関数は同一性を表す整数を返します。~ CPython では、id(x) は x が格納されているメモリ上のアドレスを返す。~ 組み込みのデータ型のうち、list, set, dict型のみmutable。~ def print_id_obj( obj ): print( 'id=', id(obj), ' obj=', obj ) a=1 b=a print_id_obj(a) print_id_obj(b) print() b=2 print_id_obj(a) print_id_obj(b) // // #-> // #id= 94427975430944 obj= 1 // #id= 94427975430944 obj= 1 // # // #id= 94427975430944 obj= 1 // #id= 94427975430976 obj= 2 // // a=[1,2] // b=a // print_id_obj(a) // print_id_obj(b) // print() // b[0]=3 // print_id_obj(a) // print_id_obj(b) // print() // b=[4,5] // print_id_obj(a) // print_id_obj(b) // // #-> // #id= 47087150371464 obj= [1, 2] // #id= 47087150371464 obj= [1, 2] // # // #id= 47087150371464 obj= [3, 2] // #id= 47087150371464 obj= [3, 2] // # // #id= 47087150371464 obj= [3, 2] // #id= 47087163414024 obj= [4, 5] ** numpy.stack, hstack, vstack [#jddcdb5f] a = numpy.arange(4).reshape( (-1,) ) +100 #[100 101 102 103] b = numpy.arange(4).reshape( (-1,) ) +200 #[200 201 202 203] numpy.hstack( [a,b] ) # [100 101 102 103 200 201 202 203] になる numpy.vstack( [a,b] ) # [[100 101 102 103] # [200 201 202 203]] になる numpy.stack( [a,b], axis=0 ) # hstackと同じ numpy.stack( [a,b], axis=1 ) # [[100 200] # [101 201] # [102 202] # [103 203]] になる ** numpy.meshgrid [#h7f8821f] ax = numpy.linspace(0,4,5).astype(int) #[ 0 1 2 3 4] ay = numpy.linspace(10,14,5).astype(int) #[ 10 11 12 13 14] x, y = numpy.meshgrid( ax, ay ) # x # [[ 0 1 2 3 4] # [ 0 1 2 3 4] # [ 0 1 2 3 4] # [ 0 1 2 3 4] # [ 0 1 2 3 4]] # y # [[ 10 10 10 10 10] # [ 11 11 11 11 11] # [ 12 12 12 12 12] # [ 13 13 13 13 13] # [ 14 14 14 14 14]] for j in range(4,0,-1): for i in range(0,4,+1): print( " {: >2d}-{: >2d}".format(x[j,i], y[j,i]), end="" ) print() # 0-14 1-14 2-14 3-14 # 0-13 1-13 2-13 3-13 # 0-12 1-12 2-12 3-12 # 0-11 1-11 2-11 3-11 xx = x / 2.0 yy = y / 2.0 for j in range(4,0,-1): for i in range(0,4,+1): print( " {: >3.1f}-{: >3.1f}".format(xx[j,i], yy[j,i]), end="" ) print() # 0.0-7.0 0.5-7.0 1.0-7.0 1.5-7.0 # 0.0-6.5 0.5-6.5 1.0-6.5 1.5-6.5 # 0.0-6.0 0.5-6.0 1.0-6.0 1.5-6.0 # 0.0-5.5 0.5-5.5 1.0-5.5 1.5-5.5 ** numpy.diff [#fcfc04b7] a = np.arange(10).reshape( (-1,) ); b = a*a # b[i] , i=0~9 c = numpy.diff( b, n=1 ) # c[i] = b[i+1] - b[i] , i=0~8 d = numpy.diff( c, n=1 ) # d[i] = c[i+1] - c[i] , i=0~7 numpy.diff( b, n=2 ) # d[i]と同じ(n回 diffを繰り返す)。二階微分の、中央差分近似に対応 ** numpy.where [#z9bb7370] a = numpy.arange(10).reshape( (-1,) ) numpy.where( 5<a, 9.5, 0.5 ) # 配列aの要素が条件( 5< )を満たすとき 9.5、否なら 0.5 numpy.where( 5<a ) # 条件を満たす要素だけの配列(のタプルが返る) numpy.where( 5<a )[0] # 条件を満たす要素だけの配列 //-------------------------------------------------------------------------------- * mpi4pyモジュール [#g611561b] MPIモジュールによる並列化 importすると、並列実行すると思われる。 comm = MPI.COMM_WORLD //-------------------------------------------------------------------------------- * anacondaなどによる環境作成 [#s41caa22] ** パッケージ(pythonやモジュール)のインストール方法の種類 [#s5d3fdce] python自体のインストールと利用バージョン切替 - インストール -- 各linuxディストリビューションのパッケージ -- ソースからコンパイル -- pyenv -- anacondaの conda -それぞれ利用するpythonのバージョン切り替え -- OS側のコマンド -- pyenv -- conda モジュール・パッケージのインストールと使用・不使用切替 -- pipや PyPI(パッケージ管理のみ)( python.orgによる説明 https://packaging.python.org/en/latest/tutorials/installing-packages/ ) -- venv(使用・不使用の環境切替のみ) -- conda &color(RED){(注)conda環境で、pipは使えるが基本的に使ってはいけない。}; anacondaによる condaコマンドは、 + 科学計算技術計算のモジュールが豊富(らしい) + condaによる環境切替ができる(pythonバージョンやモジュール) そのため、モジュール間の依存バージョン、依存するpython自体のバージョン、の整合性をとるには condaが楽だろう。 なお、"環境"は、実際には仮想ではないが "仮想環境"と呼ばれている。 ** リンク [#u9fff003] - 参考:パッケージやビルドによる環境 -- CentOS 環境のPython https://www.python.jp/install/centos/index.html - 参考:anaconda環境 -- Anacondaで仮想環境を作ってみる https://qiita.com/ozaki_physics/items/985188feb92570e5b82d -- Anacondaを使った仮想環境を保存・再構築、複製 https://qiita.com/ozaki_physics/items/13466d6d1954a0afeb3b -- condaとpip:混ぜるな危険 https://onoz000.hatenablog.com/entry/2018/02/11/142347 , CondaとPip: https://www.python.jp/install/anaconda/pip_and_conda.html --- condaとpip:ver.2020 https://onoz000.hatenablog.com/entry/2020/10/24/conda%E3%81%A8pip%3A_ver__2020 --- pip installとconda installの比較 https://chitose-nanase.com/pip-and-conda-install/ -- Anacondaで仮想環境を作るときに役立つTips集 https://cpp-learning.com/anaconda_venv_tips/ -- Anacondaで仮想環境を作ってC++プログラミングをするまで https://cpp-learning.com/anaconda_cpp/ -- Conda コマンド https://www.python.jp/install/anaconda/conda.html -- パッケージによってはライブラリが必要になる --- libm (glibc) インストール https://minecraft.server-memo.net/bedrock_server_install/#libm_glibc --- libffi インストール https://noknow.info/it/os/install_libffi_from_source?lang=ja , https://qiita.com/rabi0102/items/8a749505c78ddc5e4a7d - 参考:jupyter -- notebook, lab, hub, lab-hubがある。 -- CentOS7にJupyter Notebookを導入 https://qiita.com/hiroseabook/items/1da01ea439b01c1eb48c -- CentOS7でJupyter Notebookを簡単インストール・設定 https://qiita.com/y-araki-qiita/items/77c56d266225fe5663a1 -- リモートサーバでJupyter Notebookを実行する方法 https://qiita.com/alchemist/items/ce7f6790bdc2c7cee674 -- (ノードでの使用)Jupyter Notebookの利用 https://docs.abci.ai/ja/tips/jupyter-notebook/ -- JupyterじゃなくてJupyterLabを勧めるN個の理由 https://qiita.com/marutaku0131/items/9881d0430462e655a701 -- JupyterLab-Hubで快適な分析環境を共有しよう! https://qiita.com/atsushi_wagatsuma/items/89b714328663992b54f4 -- 無償で使えるJupyter Notebookオンライン環境 https://www.atmarkit.co.jp/ait/articles/1812/07/news146.html (中央にリンク) -- JupyterHubを複数ユーザーで使用するための環境構築方法 https://nodaki.hatenablog.com/entry/2019/04/17/220613 -- Jupyter Notebookで分析結果を社内共有!! https://www.optsp.co.jp/news/detail/1080/ (一番下に「数式」入力方法) -- UbuntuにAnacondaをインストールしてPythonとJupyter Notebookを動かすまでの手順 https://www.virment.com/setup-anaconda-python-jupyter-ubuntu/ - その他 -- 並列計算のパッケージ ipyparallel https://github.com/ipython/ipyparallel -- ipythonの使い方 https://qiita.com/5t111111/items/7852e13ace6de288042f //-------------------------------------------------------------------------------- * conda環境の利用方法 [#m726dded] conda activate [環境名] #アクティベート(環境を設定) conda deactivate #デアクティベート(環境を終了) conda create -n 環境名 [python[=バージョン] [パッケージ名[=バージョン]] [...]] #環境作成 conda remove -n 環境名 --all #環境の削除 (補足) conda create -n hoge により、インストール場所の/share/apps/anaconda3/{pkgs,envs} や ~/.conda/envs にパッケージや環境が置かれるようだ。 例えば appbinユーザにより /share/apps/anaconda3に anacondaがインストールされているとする。 シェルコマンド eval "$(/share/apps/anaconda3/bin/conda shell.bash hook)" により、appbinや他のユーザは conda環境を利用できる。 - appbinユーザにより作成された環境は /share/apps/anaconda3/{pkgs,envs} にファイルが置かれ、 他のユーザも利用できる。 - 個人のユーザが環境を作った場合には ~/.conda/envs ともともとの /share/apps/anaconda3/pkgs に ファイルが置かれて、そのユーザが利用できる。 - conda create -p pathEnvName により、環境のファイルを置く場所を指定できるため、そのユーザ以外も利用 できるようにできる、らしい。(/share/apps/envsを指定するなど?) (補足2:パッケージの追加インストール) 各仮想環境へパッケージを追加インストールするには appbinグループを使用して行う。 (appbinアカウントによるインストールは、誰が入れたか不明になるため非推奨。) 追加されたパッケージは、他のユーザも利用できるようになる。 (注1) 依存関係でパッケージのアップデートも必要に応じて行われるため、その場合は 既存の環境が変更を受ける。アップデートに伴い不具合が出る可能性がある。 アップデートされたパッケージをすべてアンインストールしてもとに戻すことは ほぼ絶望的である。 環境を壊す危険が高い場合など、検証用にanacondaを別途でインストールをして確認後に、 パッケージをアップデートするのが望ましい。 (注2) pipコマンドは /share/app/anaconda3のすべての既存の仮想環境を壊しうるので、使用しない。 pipを使用した仮想環境は、condaとpipのパッケージの整合性はチェックされないようなので 不具合が出うる。 pipでインストールしたパッケージを pipでアンインストールすると、同じパッケージが condaに存在していても利用できなくなるようだ。少なくともpyqt5はそうなった、他の 仮想環境への影響は今のところ無さそうである。2023/08/09 appbinグループを使用した追加方法は、 sgコマンドまたはnewgrpコマンドにより、所属グループをappbinに変更後にインストール操作 をする。手順は以下 1)-3) のいずれか 1) $ sg appbin bash $ インストール作業 $ exit 2) $ sg appbin "インストールのためのコマンドライン" #第3引数は引用符で括る 3) $ newgrp appbin $ インストール作業 $ exit なお、所属グループをappbinに変更し忘れた場合は、 chown -R :appbin /share/apps/anaconda3 をすればよいようだ(not permittedは多量に出る)。 (rootユーザが chown -R :appbin /share/apps/anaconda3 をしても同様) 仮想環境の追加作成のときは appbinアカウントを使用する。 環境は /share/apps/anaconda3/envsに、パッケージは /share/apps/anaconda3/pkgsに入る。 個人ユーザで conda create -n py36 python=3.6 などで仮想環境を作ることもできる。 この場合、仮想環境は ~/.conda/envsに、パッケージは /share/apps/anaconda3/pkgsに入る。 そのためこの場合も作成時には appbinグループを使用すること。 個人的にいろいろ試す場合は、個人環境に別途でanacondaをインストールすればよい。 conda info #condaの情報 conda info -e #環境のリスト conda -V #バージョン conda -h #ヘルプ conda config --help #コマンドconfigのヘルプ anaconda search --help #コマンドsearchのヘルプ conda create --help #コマンドcreateのヘルプ conda search [-c チャネル] [--full-name] パッケージ名 #パッケージのバージョンに対応するpythonのバージョン表示 conda install パッケージ名[=バージョン] #現在の環境に、パッケージをインストール conda uninstall パッケージ名 #現在の環境から、パッケージをアンインストール conda list [-n 環境名] #インストールされているパッケージのリスト デフォルト以外のチャンネル: https://docs.conda.io/projects/conda/en/latest/user-guide/concepts/channels.html //? condaが対応していないパッケージのインストールの場合 //? anaconda search -t conda パッケージ名 #パッケージが対応しているリスト //? anaconda show パッケージ名 #チェネルURLなど表示(いずれかの環境がアクティベートされていること) // conda install -c チャネルURL パッケージ名 環境の保存や、それを使った環境作成 conda env export > ファイル名.yaml conda env create -n 新しい環境名 -f ファイル名.yaml or デフォルトのチャネルだけなら conda list --export > ファイル名.txt conda create -n 新しい環境名 -f ファイル名.txt conda clean --all #不要なパッケージやキャッシュを削除 conda create -n 新しい環境名 --clone もとの環境名 #環境名を変更する conda remove -n もとの環境名 --all conda config --set env_prompt "({default_env}) " #デフォルトでconda環境のときに付くプロンプトのプレフィックス conda config --set env_prompt "p:" #プロンプトプレフィックスを変更 conda config --set changeps1 false #プロンプトを変更しない echo $CONDA_SHLVL #0以外でconda環境であることを確認できる conda config --set auto_activate_base false #conda環境に入ったとき自動的にbase環境をactivateしない、たぶん。 標準的なパッケージをごっそり入れる? conda create -n 新しい環境名 [python=バージョン] anaconda アップデート conda update -n base -c defaults conda #condaのupdate? base仮想環境もupdateされる? conda update conda;conda update anaconda;conda update --all #conda,anacondaのアップデート?,全パッケージがupdate アンインストール 次のものを削除するようだ。 インストール先のanaconda3 ディレクトリ ~/.conda ディレクトリ ~/.condarc ファイル ~/.bashrcに追加された conda initialize のブロック *** ハードリンク [#ce9ae41a] - hoge1, hoge2, hoge3という共通のi-nodeをもつハードリンクのファイルがあったとする。 いずれかのファイルを上書き変更すると、他のファイルもすべて上書き変更された内容になる。 (仮想環境で使われているファイルは、ハードリンクで共通に利用されており、ここに pipで上書きが発生すると 他の全ての仮想環境で意図しないファイルの変更が起こる。) - emacsで例えば hoge3のファイルを変更・保存したとする。変更された内容は hoge3のみに含まれる。 もともとハードリンクされていたファイルは hoge3~になっている。 *** スクリプトを実行する時だけ conda activateする(通常は OSデフォルトのpythonバージョンが動くままにしておきたい) [#va63ed21] 下記のようなスクリプトを mypyなどとして作っておき、mypy hoge.py などとする。 #!/bin/bash --norc #==== set your python env ==== MYPYTHON=py370 if [ $# == 0 ]; then echo "usage: $0 command [args]" >&2 exit 1 fi source /share/apps/anaconda3.bash_conda conda activate $MYPYTHON #==== execute command [args] ==== "$@" //-------------------------------------------------------------------------------- * 実行時の symbol lookup error や relocation error の対処 [#n3757fde] pythonプログラムを実行したときに symbol lookup error や relocation error が出た場合は、 [[LABO/Rocks]]のページの対処法を見よ。 //-------------------------------------------------------------------------------- * 弘大JupyterHub [#t375c760] - 弘前大学情報基盤システム(HIROINS) 教育研究事務業務支援システム -- ログイン https://jupyter01.hirosaki-u.ac.jp:8000/hub/login --- 裏で動いているCPUは Xeon Gold 5220R 2.20GHz (32コア,第2世代) らしい -- 実習室パソコンの情報 https://home.hirosaki-u.ac.jp/heroic-2020/ //-------------------------------------------------------------------------------- * Jupyter Notebook [#q450c36b] ** alliumのjupyter notebook [#m5ba35f1] 使用方法は [[LABO/Rocks#tdb7fe60]]を見よ。 ** 長い出力部分の表示切替 [#qc798443] - 長い出力は、スクロールバーが出て部分的に表示される。 -- 左部分をクリックすると、全て表示 ⇔ スクロールバーによる部分表示 の切替が出来る。 -- ダブルクリックすると、非表示になる(クリックで、全て表示にもどる)。 ** 括弧などの入力補完(autoCloseBrackets)をオフにする [#y2997562] from notebook.services.config import ConfigManager c = ConfigManager() c.update('notebook', {"CodeCell": {"cm_config": {"autoCloseBrackets": False}}}) を実行して、ノートブックを開きなおす。設定は ~/.jupyter/nbconfig/notebook.json に保存される。 ** ipynbをpyに変換する [#u91d1cb0] jupyter nbconvert --to python hogehoge.ipynb #==> hogehoge.pyが作られる ** jupytextを使えるようにする(ipynbとpyの同期) [#mccae438] デフォルト以外のチャンネル https://docs.conda.io/projects/conda/en/latest/user-guide/concepts/channels.html → https://conda-forge.org/feedstock-outputs/ より conda-forgeにあるパッケージとして jupytextを検索して https://github.com/conda-forge/jupytext-feedstock を参考に、 $ conda activate py370 $ conda install jupytext --channel conda-forge のようにパッケージをインストールする(/share/apps/anaconda3でインストール済)。 jupyter notebookを起動して hoge.ipynbファイルを開く→ファイル→Jupytext →Pair Notebook with light Scriptにチェックを入れる。 これで hoge.ipynbと hoge.pyが同期される。 [ref] https://qiita.com/ku_a_i/items/ccdeb7f1d9384fb4767b ** マジックコマンド(%) [#wd5d9a96] %matplotlib notebook %matplotlib inline %time など