Oneonet Python Cheat Sheet v2022.02
これで事足りてます。不定期に更新していきます。
#■■■■■■■■■■ #Oneonet Python Cheat Sheet 2022.02版 #■■■■■■■■■■ #■■■■■■■■■■ #■マジックコメント/Magic comment # -*- coding: utf-8 -*- #■■■■■■■■■■ #■main if __name__ == "__main__": main() #■■■■■■■■■■ #■コメント # This is a comment a = 1 # initialization """ 複数行コメント です! """ #■■■■■ #■エスケープ文字 """ \' #Single quote \" #Double quote \t #Tab \n #Newline \\ #Backslash """ #■■■■■■■■■■ #■アンダースコア for _ in range(10): x, _, _ = func() value = 100_000_000 #■■■■■■■■■■ #■変数初期化 a , b = 0, 100 a = b = 0 del a #削除 #■■■■■■■■■■ #■計算1 """ + 足し算 - 引き算 * 掛け算 / 除法 // 整数除算 % 剰余 ** 指数 """ #■■■■■■■■■■ #■代入 x += 5 #x = x + 5 x -= 5 #x = x - 5 x *= 5 #x = x * 5 x /= 5 #x = x / 5 x %= 5 #x = x % 5 x ** = 5 #x = x ** 5 #--- x = [1,2,3] x1, x2, x3 = x #x1=1, x2=2, x3=3 #--- x, y = 1, 2 x, y = y, x #x=2,y=1 #■■■■■■■■■■ #■文字列操作 'Hello %s' % 'world' #'Hello world' 'Hello %d' % 100 #'Hello 100' 'Hello %x' % 100 #'Hello 64' #--- x = 123 f'value = {x*2}' #'value = 246 #--- #■■■■■■■■■■ #■比較 """ == 等しい != 等しくない < 未満 > より大きい <= 以下または等しい >= 大きいまたは等しい """ #--- x = [1,2,3,4,5] x1 = (3 in x) #True x2 = (10 in x) #False x3 = (3 not in x) #False x4 = (10 not in x) #True #■■■■■■■■■■ #■計算2 ルート: #--- import math x = math.sqrt(5) #--- import numpy x = numpy.sqrt(5) degrees<->radians: #--- import math x = math.degrees(math.pi/2) #Rad to Deg x = math.radians(90) #Deg to Rad #■■■■■■■■■■ #■リスト / スライス x = [1,2,3,4,5] #xの初期値は常にこの値として・・・ x #[1, 2, 3, 4, 5] x[0] #1 x[3] #4 x[-1] #5 x[-3] #3 x[1:3] #[2, 3] x[1:] #[2, 3, 4, 5] x[:2] #[1, 2] *** x[1:3] #[2, 3] x[0:-1] #[1,2,3,4] *** x[::-1] #[5, 4, 3, 2, 1] len(x) #5 x.append(10) #[1, 2, 3, 4, 5, 10] x.index(4) #3 x.remove(4) #[1, 2, 3, 5] x.insert(1,100) #[1, 100, 2, 3, 4, 5] del x[4] #[1, 2, 3, 4] x = x + x #[1, 2, 3, 4, 5, 1, 2, 3, 4, 5] x = x * 3 #[1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5] #--- x = [1,2,3,4,5] for i,s in enumerate(x): print ('x[{}] = {}'.format(str(i),str(s))) #x[0] = 1 #x[1] = 2 #x[2] = 3 #x[3] = 4 #x[4] = 5 #--- x = [1,2,3,4,5] y = [10,20,30,40,50] for i,j in zip(x,y): print ('x=[{}], y=[{}]'.format(i,j)) #x=[1], y=[10] #x=[2], y=[20] #x=[3], y=[30] #x=[4], y=[40] #x=[5], y=[50] #■■■■■■■■■■ #■リスト作成 x = [0]*5 #[0, 0, 0, 0, 0] x = [1,2]*5 #[1, 2, 1, 2, 1, 2, 1, 2, 1, 2] x = range(5) #[1, 2, 3, 4, 5] [i * 2 for i in range(5)] #[1,2,3,4,5] -> [2, 4, 6, 8, 10] [s.upper() for s in x] #['ABC', 'def'] -> ['ABC', 'DEF'] x = [(x,y) for x in range(3) for y in range(x,3)] #[(0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2)] #■■■■■■■■■■ #■print print('Hello world') print('Hello world', x) print('Hello world', end='') print('x={}, y={}'.format(x, y)) print(f'{x:05}') #x=255 -> 00255 print(f'{x:b}') #x=255 -> 11111111 print(f'{x:o}') #x=255 -> 377 print(f'{x:x}') #x=255 -> ff print(f'{x:X}') #x=255 -> FF print('a','b','c', sep=(',')) #a,b,c print ('{:.5f}'.format(0.123456789)) #0.12346 #■■■■■■■■■■ #■数値系関数 len('hello') #5 str(30) #'30' str(-3.14) #'-3.14' int(7.7) #7 #■■■■■■■■■■ #■文字系関数 x = 'Hello world' 'Hello world'.upper() #'HELLO WORLD' 'Hello world'.lower() #'hello world' 'H'.isupper() #True 'h'.islower() #True 'A'.isalpha() #True '1'.isalnum() #True a-z,A-Z,0-9 '1'.isdecimal() #True 0-9 ' '.isspace() #True 'Gundam'.istitle() #True 単語の先頭だけが大文字か? 'Gundam'.startswith('Gu') #True 'Gundam'.endswith('am') #True ' '.join(['Hello', 'world']) #'Hello world' '***'.join(['Hello', 'world']) #'Hello***world' 'Hello world'.split() #['Hello', 'world'] 'Hello world'.split('o') #['Hell', ' w', 'rld'] 'Hello'.rjust(10,'*') #'*****Hello' 'Hello'.ljust(10,'*') #'Hello*****' 'Hello'.center(10,'*') #'**Hello***' ' Hello '.strip() #'Hello' ' Hello '.lstrip() #'Hello ' ' Hello '.rstrip() #' Hello' 'Hello world'.replace('o','0') #'Hell0 w0rld' #■■■■■■■■■■ #■乱数 import random x = random.random() # 0.000 < x < 1.000 x = random.uniform(0, 3) # 0.000 < x < 3.000 x = random.randint(0, 3) # 0 <= x <= 3 x = randrange(0, 10, 3) # 0,3,6,9 x = random.sample('abcdefg',3) #['a', 'c', 'b'] 重複なし x = random.choices('abcdefg',k=3) #['g', 'g', 'a'] 重複可能性あり #--- x = [1,2,3] random.shuffle(x) #■■■■■■■■■■ #■判定 if x == 1: else x == 0: else: #■■■■■■■■■■ #■while ループ x = 0 while x < 5: x = x + 1 if x == 2: continue #Skip print (str(x)) if x == 3: break #Exit #-> 1\n3 #■■■■■■■■■■ #■range() range(0,10, 2) #0,2,4,6,8 // Start, stop, step range(5, -1, -1) #5,4,3,2,1,0 #■■■■■■■■■■ #■for ループ for i in range(10): if i == 5: break else: print('breakしなかった時だけ') #■■■■■■■■■■ #■関数/function def func(x): print(str(x)) return x+1 #■■■■■■■■■■ #■スコープ / Global x = 1 y = 1 def func(): global x #<- x = 2 y = 2 func() #x=2,y=1 #■■■■■■■■■■ #■例外処理 try: x = 42 / 0 except ZeroDivisionError as e: print('エラーの時だけ: Invalid argument: {}'.format(e)) finally: print('必ず処理される') #■■■■■■■■■■ #■ソート x = [5, 1, 3, 2, 4] x.sort() #[1, 2, 3, 4, 5] #--- x = ['ア', 'あ', 'A', 'a', 'A'] x.sort() #['A', 'a', 'あ', 'ア', 'A'] x.sort(reverse=True) #['A', 'ア', 'あ', 'a', 'A'] #reverse=True #keyと同時指定可能 #key=str.lower #大文字小文字無視 #key=len #長さ順 sorted(x) #[5, 1, 3, 2, 4] #コピーしてソート #■■■■■■■■■■ #■辞書 Gundam = {'size': 18.0, 'code': 'RX-78-2', 'pilots': 'Amuro Ray'} for v in Gundam.values(): print (v) #18.0 / RX-78-2 / Amuro Ray #--- for k in Gundam.keys(): print (k) #size / code / pilots #--- for i in Gundam.items(): print (i) #('size', 18.0) / ('code', 'RX-78-2') / ('pilots', 'Amuro Ray') print (i[0]) #size / code / pilots print (i[1]) #18.0 / RX-78-2 / Amuro Ray #--- 'size' in Gundam.keys() #True 'size' in Gundam.values() #False 18.0 in Gundam.values() #True #--- Gundam.setdefault('color', 'white') #未登録の場合追加される Gundam.setdefault('size', 20.0) #登録済の場合何も設定されず現在値を返す #--- GundamA = {'size': 18.0, 'code': 'unknown'} GundamB = {'code': 'RX-78-2', 'pilots': 'Amuro Ray'} Gundam = {**GundamA , **GundamB} #{'size': 18.0, 'code': 'RX-78-2', 'pilots': 'Amuro Ray'} #■■■■■■■■■■ #■正規表現 #\d 任意の数字 #\D 任意の数字以外 #\s 任意の空白文字 #\S 任意の空白文字以外 #\w 任意の英数字 #\W 任意の英数字以外 #\A 文字列の先頭 #\Z 文字列の末尾 #. 任意の一文字 #* 0回以上の繰り返し #+ 1回以上の繰り返し #? 0回または1回 #{n} n回の繰り返し #{n1,n2} n1-n2回の繰り返し #[] 集合 #| 和集合 #() グループ化 import re s = 'Hello world 123!' regex = re.compile(r'wo') regex.search(s) #<re.Match object; span=(6, 8), match='wo'> regex = re.compile(r'\d\d\d') regex.search(s) #<re.Match object; span=(12, 15), match='123'> #■■■■■■■■■■ #■クラス / class class Sample: def __init__(self): print('constructor') def __del__(self): print('destructor') def func(self, x): return x+x s = Sample() #constructor s.func(100) #200 s = '' #destructor s = 0 , s = 'abc' #■■■■■■■■■■ #■マルチプロセス from multiprocessing import Process from time import sleep def func_1(num): print ('func1---') sleep(num) print ('---func1') def func_2(num): print ('func2---') sleep(num) print ('---func2') if __name__ == '__main__': p = Process(target=func_1, args=(10,)) p.start() # p.join() #func_1終了まで待機 # p.join(5) #finc_1起動後5秒待機 func_2(10)
Blender x Python 三角形のドミノ倒し
一直線ばかりだったドミノを少し変化させていきたいと思います。倒すドミノを1枚づつ増やしていく配置としました。あまり面白味がないので、ドミノの配置に少し乱数を加え、マテリアルを2種類用意してランダムに割り当てました。
そろそろ立体にしてみようかと思っているところです。
#blender 3.0.0 import bpy import random for item in bpy.data.meshes: bpy.data.meshes.remove(item) domino_distance = 10 domino_count = 50 domino_width = 4 mat_b = bpy.data.materials.new("Blue") mat_b.diffuse_color = (0, 0, 1, 1.0) mat_w = bpy.data.materials.new("White") mat_w.diffuse_color = (1, 1, 1, 1.0) for x in range(1,domino_count): for y in range(x): x_location = (x - 1)*domino_distance + random.random() y_location = (y-x/2)*domino_width *3 bpy.ops.mesh.primitive_cube_add(location=(x_location, y_location, 0), scale=(1,domino_width,10),rotation=(0, 0, 0.0) ) bpy.ops.rigidbody.object_add() bpy.context.object.rigid_body.friction = 1 if random.random() > 0.6: bpy.context.object.data.materials.append(mat_w) else: bpy.context.object.data.materials.append(mat_b) if x== 1: bpy.context.object.rotation_euler[1] = 0.3 s=domino_distance * domino_count*1.2 bpy.ops.mesh.primitive_plane_add(size=s, location=(s/2 - 10, 0, -10 ), scale=(1, 1, 1)) bpy.ops.rigidbody.object_add() bpy.context.object.rigid_body.type = 'PASSIVE'

Blender x Python アルキメデスの螺旋でドミノを並べるスクリプト
アルキメデスの螺旋(Archimedes' spiral)と呼ばれる方程式 r=a\theta によって表される曲線(うずまき)があります。線同士の間隔が等しいのが特徴です。この方程式を利用して渦巻でドミノを並べてみました。
グラフにプロットするだけなら計算式そのままで良いのですが、ドミノということでポイントが2つあります。1つは、等間隔となる必要があり、1つドミノ(キューブメッシュ)を配置したら一定距離になるまで次のドミノを配置しないこと。直前のドミノのx1,y1と配置しようとする新ドミノの位置x2,y2の距離を測り、距離が一定値以上となったら配置するようにしています。ドミノの高さ以下の距離であれば大丈夫です。 プロットする位置は計算で導き出せるようなのですが、何をしてもうまくいかなかったので、細かくループを回してその都度距離を測定する方法にしました。2点目はドミノの角度です。グラフにするだけなら角度という概念は出てきませんが、ドミノが前のドミノと次のドミノの中間の角度になる必要がありますので、プロットするタイミングでZ軸の角度を調整します。
動画を見て頂けるとわかるのですが、ドミノを並べる個数とその間隔、うずまきの密集具合も指定することができ、どの場合でもドミノがキレイに倒れます。

2000個までやってみました。スクリプトの実行完了に10分ぐらいかかります。パラメタを少し変えるだけで、渦の密度を変化させられるのも面白いですね。
是非気持ちよく倒れていくドミノの様子を動画でご覧になってください。
oneonet-blog.blogspot.com
Blender ドミノアニメーションに自動で効果音を付けてみた
オブジェクトの衝突に合わせて効果音を設定するアドインを使って、ドミノ倒しに効果音を設定してみました。これはほんとにスゴイとしか言いようがないです。最後のドミノが倒れた後の「トコトコン♪」部分最高じゃないですか。
■前準備
ドミノの並べるスクリプトもしくは自分で並べてドミノ倒しを準備しましょう。ポイントはリジッドボディですね。面倒な方は以下をご利用ください。工夫としては、ドミノの隙間を少しづつ短くしている点です。これにより音の出る間隔が短くなるはずで、それに合わせて効果音が短い間隔で再生されることがお分かり頂けるかと思います。
#blender 3.0.0で動作確認 import bpy for item in bpy.data.meshes: bpy.data.meshes.remove(item) bpy.ops.mesh.primitive_plane_add(size=400, align='WORLD', location=(0, 0, -5), scale=(1, 1, 1)) bpy.context.object.rotation_euler[2] = 0.78 bpy.ops.rigidbody.object_add() bpy.context.object.rigid_body.type = 'PASSIVE' for i in range (0 ,100 ): bpy.ops.mesh.primitive_cube_add(location=(-200+i*5-((i/10)**2) , 0, 0), scale=(1,4,10) ) bpy.ops.rigidbody.object_add() bpy.context.object.rigid_body.friction = 1 if i==0: bpy.context.object.rotation_euler[1] = 0.3
■効果音設定
例のアドインで効果音を設定します。ポイントは[しきい値]で、落下等の衝突より移動が少ないので、値は「0.01」ぐらいを目安にしてください。落下するより動きが少ないため、「0.1」だと衝突として検出せず効果音が設定されません。音源はドミノの倒れる音が良いとは思いますが、あえて違う音を設定してみました。今回は、WindowsPCにUSBデバイスを接続した時の音です。効果音次第で楽しめそうな気がします。
アドインにより効果音を設定した後の設定です。効果音の間隔が短くなっていることがおわかり頂けるかと思います。最後の「トコトコン♪」はこうなってます。

是非ミラーサイトで動画ご覧になってください。面白いですよ。
oneonet-blog.blogspot.com