◯こちらのサンプルコードは指導等にご自由にお使いください。
【サンプルコードの使い方】
◯サンプルコードを写す時はコピペをしないようにしましょう。
◯▶を押すと出力が表示されます。
◯Geminiボタンを押すとGemini(AI)による解説が表示されます。間違っていることもあるので、疑問に思った場合はご質問ください。
◯本マークを押すとカテゴリーの解説が見られます。
◯サンプルコードを写す時はコピペをしないようにしましょう。
◯▶を押すと出力が表示されます。
◯Geminiボタンを押すとGemini(AI)による解説が表示されます。間違っていることもあるので、疑問に思った場合はご質問ください。
◯本マークを押すとカテゴリーの解説が見られます。
【カテゴリーごとのページへ移動】
【Code List】
すべて見る
- CODE: 0-1 (if文)
- CODE: 0-2 (if文)
- CODE: 0-3 (if文)
- CODE: 0-4 (if文)
- CODE: 1-1 (for文)
- CODE: 1-2 (for文)
- CODE: 1-3 (for文)
- CODE: 1-4 (for文)
- CODE: 1-5 (for文)
- CODE: 1-6 (for文)
- CODE: 2-1 (関数)
- CODE: 2-2 (関数)
- CODE: 2-3 (関数)
- CODE: 2-4 (関数)
- CODE: 2-5 (関数)
- CODE: 2-6 (関数)
- CODE: 3-1 (配列)
- CODE: 3-2 (配列)
- CODE: 3-3 (配列)
- CODE: 3-4 (配列)
- CODE: 3-5 (配列)
- CODE: 3-6 (配列)
- CODE: 4-1 (配列)
- CODE: 4-2 (配列)
- CODE: 4-3 (配列)
- CODE: 5-1 (メイン関数)
- CODE: 5-2 (メイン関数)
- CODE: 5-3 (メイン関数)
- CODE: 5-4 (メイン関数)
- CODE: 5-5 (メイン関数)
- CODE: 5-6 (メイン関数)
- CODE: 5-7 (メイン関数)
- CODE: 6-1 (openpyxl)
- CODE: 6-2 (openpyxl)
- CODE: 6-3 (openpyxl)
- CODE: 7-1 (文字列)
- CODE: 7-2 (文字列)
- CODE: 7-3 (文字列)
- CODE: 7-4 (正規表現)
- CODE: 7-5 (正規表現)
- CODE: 7-6 (正規表現)
- CODE: 8-1 (ファイル入出力)
- CODE: 8-2 (ファイル入出力)
- CODE: 9-1 (ファイル入出力)
- CODE: 9-2 (ファイル入出力)
- CODE: a-1 (Numpy)
- CODE: a-2 (Numpy)
- CODE: a-3 (Matplotlib)
- CODE: a-4 (Matplotlib)
- CODE: b-1 (Pandas)
- CODE: b-2 (Pandas)
- CODE: b-3 (Pandas)
- CODE: b-4 (Pandas)
- CODE: c-1 (Biopython)
- CODE: c-2 (Biopython)
- CODE: c-3 (Biopython)
- CODE: d-1 (scikit-learn)
- CODE: d-2 (scikit-learn)
- CODE: d-3 (scikit-learn)
- CODE: e-1 (seaborn)
- CODE: e-2 (Graphviz)
- CODE: f-1 (Gemini)
- CODE: f-2 (Gemini)
- CODE: g-1 (Tkinter)
- CODE: g-2 (Tkinter)
- CODE: g-3 (Tkinter)
- CODE: g-4 (Tkinter)
CODE: 0-1 (if文)
wake_up_time = 12 if ( wake_up_time==7 ): print("朝ごはんを食べる") elif ( wake_up_time==12 ): print("昼ごはんを食べる") else: print("何も食べない")

- elifで、「上のifの条件に当てはまらなかった時」という意味になる。
- elseは、「上の全てのifとelifの条件に当てはまらなかった時」という意味になる。
- ifに()をつけているが、つけなくてもOK。(個人的にはつけた方がわかりやすいと思っている。)
- 参考サイト1

CODE: 0-2 (if文)
wake_up_time = 7 is_hungry = True if ( wake_up_time==7 ): if ( is_hungry==True ): print("朝ごはんを食べる") else: print("朝ごはんを食べない") else: print("何も食べない")

- インデント(字下げ)が重要!! インデントでどこまでがそのifの中身かを判断する。
- 今回のようにifが入れ子構造になっているとわかりづらいが、一つずつ分解して考えていこう。

CODE: 0-3 (if文)
wake_up_time = 8 if ( wake_up_time == 7 ): print("たべる") print("おなかいっぱい")

CODE: 0-4 (if文)
wake_up_time = 8 if ( wake_up_time == 7 ): print("たべる") print("おなかいっぱい")

CODE: 1-1 (for文)
for i in range(0, 3): print(i)

- for文はrange()と組み合わせることが多いが、 for i in range(0, 10):としたときのiの範囲は 「0〜10」ではなく 「0〜9」 であることに注意!!
- forの後はインデントされている部分だけループが行われる。
- 参考サイト1

CODE: 1-2 (for文)
a = 3 for i in range(0, 10): a += 4 print(a)

- forの後はインデントされている部分だけループが行われる。
- +=という演算子は、左辺に右辺を足すという処理を表す。 a += 4 は a = a + 4 と同じ。

CODE: 1-3 (for文)
s = 0 for i in range(3, 12): s += i print(s)

CODE: 1-4 (for文)
for i in range(0, 5): print(i) print("Hello!")

CODE: 1-5 (for文)
s = 0 for i in range(0, 5): s += i * 2 print(s)

CODE: 1-6 (for文)
a = 1 for i in range(1, 6): a = a * i print(a)

CODE: 2-1 (関数)
def print_name(name): print("私の名前は" + name + "です。") return print_name("田中太郎")

- defで関数定義ができる。
- この関数は何もreturnしない関数。
- +で文字列の連結ができる。
- 参考サイト1

CODE: 2-2 (関数)
def calc_mean(a, b, c): m = (a + b + c) / 3 return(m) m = calc_mean(3, 6, 9) print(m)

- 関数は「何を入れて(引数)」「何が出てくるか(返り値)」が重要!!
- calc_mean()は、3つの数字を入れたら、その平均が出てくる関数。
- 今回のcalc_mean()の中にあるmは、calc_mean()の中だけで通用する変数。外にあるmとは「関係が無い」。

CODE: 2-3 (関数)
def print_hello(): print("hello!") return print_hello()

- このように、引数も返り値もない関数もあるが、特殊な場合を除いてあまり使われることはない。

CODE: 2-4 (関数)
def calc3(x, y, z): a = (x * y * z) / 3 return(a) for i in range(0, 4): x = calc3(i, 3, 6) print(x)

- 関数は「何を入れて(引数)」「何が出てくるか(返り値)」を考えるのが大事!!
- 今回のcalc3()はx, y, zを入れると、それぞれの値の積を3で割った値が出てくる。

CODE: 2-5 (関数)
def calc3(x, y, z): a = (x * y * z) / 3 return(a) x = 0 for i in range(0, 4): x += calc3(i, 3, 6) print(x)

- x += aでxにaを加算する意味となる。

CODE: 2-6 (関数)
def calc3(x, y, z): a = (x * y * z) / 3 return(a) x = 0 for i in range(0, 5): x += calc3(i, 3, 6) if ( x<100 ): print("OK") else: print("NG")

CODE: 3-1 (配列)
a = [3, 4, 9, 2] print(a[0]) print(a[3])

- a[n]で、配列のn番目の要素にアクセスすることができる。
- 配列のインデックスは0はじまりなことに注意!!
- 参考サイト1

CODE: 3-2 (配列)
a = [3, 5, 9, 0] a[2] = 4 print(a)

- a[n] = xとすることで、n番目の要素をxに書き換えることができる。
- print(配列)で配列全体を出力し、確認できる。

CODE: 3-3 (配列)
a = [] a.append(4) a.append(2) a.append(8) a.pop(2) print(a)

- a = []で空の配列を作成できる。これがないと後のappend()やpop()は使えない。
- append()で配列に要素を追加できる。(頻出!!)
- pop(n)で配列のn番目の要素を削除する。nという要素を探して削除するのではなく、nはインデックスであることに注意!!

CODE: 3-4 (配列)
def calc3(x, y, z): a = (x * y * z) / 3 return(a) a = [3, 5, 9, 10] x = 0 for i in range(0, 4): b = a[i] x += calc3(b, 3, 6) print(x)

- 配列とfor文の組み合わせは頻出!!
- for n in a:のように、配列をそのままfor文に入れることもできる。わかりやすい方で書けばOK。
- 今回のようにiを変化させてa[i]として配列の要素を取り出す方法は、後からデバッグがしやすいという利点がある。

CODE: 3-5 (配列)
def calc_tax(a): r = 1.1 x = a * r return(x) goods = [1000, 2000, 3000] total = 0 for i in range(0, len(goods)): total += goods[i] total = calc_tax(total) print(int(total))

- calc_tax()は「商品の値段を入れて」「消費税込みの値段が返ってくる」関数。
- 関数が出てきたら「何を入れて」「何が出てくるか」を考えよう!!

CODE: 3-6 (配列)
def calc_tax(a): r = 1.1 x = a * r return(x) goods = [] goods.append(1000) goods.append(2000) goods.append(3000) goods.append(4000) total = 0 for i in range(0, len(goods)): total += calc_tax(goods[i]) print(int(total))

- append()は便利で非常によく使われるのでチェック!!
- goods = []で空の配列を作成できる。これがないとappend()が使えないので注意。

CODE: 4-1 (配列)
def calc_pow(x, n): y = 1 for i in range(0, n): y = y * x return(y) x = 4 n = 3 y = calc_pow(x, n) print(y)

CODE: 4-2 (配列)
def calc_pow(x, n): y = 1 for i in range(0, n): y = y * x return(y) x = 2 n = 5 y = calc_pow(x, n) if ( y<40 ): print("OK") else: print("NG")

CODE: 4-3 (配列)
def calc_pow(x, n): y = 1 for i in range(0, n): y = y * x return(y) x = 2 list0 = [] for i in range(0, 4): y = calc_pow(x, i) list0.append(y) s = sum(list0) print(s)

CODE: 5-1 (メイン関数)
def inch2cm(inch): cm = inch*2.54 return(cm) def main(): inch = 15 cm = inch2cm(inch) print(cm) return(0) main()

CODE: 5-2 (メイン関数)
def inch2cm(inch): cm = inch*2.54 return(cm) def feet2cm(feet): cm = feet*30.48 return(cm) def main(): inch = 15 feet = 3 cm = inch2cm(inch) + feet2cm(feet) print(cm) return(0) main()

CODE: 5-3 (メイン関数)
def inch2cm(inch): cm = inch*2.54 return(cm) def feet2cm(feet): cm = feet*30.48 return(cm) def main(): inch = 10 feet = 2 cm = inch2cm(inch) + feet2cm(feet) if ( cm>90 ): print("OK") else: print("NG") return(0) main()

CODE: 5-4 (メイン関数)
def calc_second(day, hour, minute): sec = day * 24 * 60 * 60 + hour * 60 * 60 + minute * 60 return(sec) def main(): day = 3 hour = 5 minute = 15 sec = 38 result_sec = calc_second(day, hour, minute) + sec print(f"{day}日{hour}時間{minute}分{sec}秒 => {result_sec}秒") return(0) main()

CODE: 5-5 (メイン関数)
def calc_loan_month(loan, year_rate, month_pay): year_rate = 1 + year_rate/100 month = 0 while ( 1 ): month += 1 if ( month%12==0 ): loan *= year_rate loan -= month_pay if ( loan<=0 ): break if ( month>10000 ): # 無限ループを防ぐ break return(month) def main(): loan = 13200000 # 借入金額 (円) year_rate = 2 # 年利 (%) month_pay = 120000 # 月々の支払 (円) month = calc_loan_month(loan, year_rate, month_pay) print(f"借入金額: {loan} 円") print(f"金利: {year_rate} %") print(f"月々の支払: {month_pay} 円") print(f"返済期間: {month} 月") return(0) main()

CODE: 5-6 (メイン関数)
def calc_monthly_interest_rate(annual_interest_rate): return(annual_interest_rate / 12) def calc_total_months(years): return(years * 12) def simulate_savings(annual_interest_rate, years, monthly_deposit): monthly_interest_rate = calc_monthly_interest_rate(annual_interest_rate) total_months = calc_total_months(years) total_amount = 0.0 total_principal = 0.0 total_interest = 0.0 for month in range(1, total_months + 1): total_amount += monthly_deposit total_principal += monthly_deposit current_month_interest = total_amount * monthly_interest_rate total_amount += current_month_interest total_interest += current_month_interest if ( month % 12 == 0 ): current_year = month // 12 return(total_interest) def main(): monthly_deposit = 20000 years = 20 annual_interest_rate = 0.03 final_interest = simulate_savings(annual_interest_rate, years, monthly_deposit) final_interest = int(final_interest) print(f"月々の積立額: {monthly_deposit}円") print(f"積立年: {years}年") print(f"年利: {annual_interest_rate}%") print(f"最終運用益: {final_interest}円") return(0) main()

CODE: 5-7 (メイン関数)
def calculate_epicenter_distance(s_p_time_diff, vp, vs): """ 大森公式を使って、P波とS波の到達時間差から震源地までの距離を計算する。 """ if ( s_p_time_diff < 0 ): return(-1) if ( vp <= vs ): return(-1) if ( vs <= 0 ): return(-1) k = (vp * vs) / (vp - vs) distance = k * s_p_time_diff return(distance) def main(): # 例: S-P時間が5秒で、異なるP波/S波速度を指定 sp_time = 5.0 vp = 8.0 vs = 4.5 distance = calculate_epicenter_distance(sp_time, vp, vs) if ( distance>=0 ): print("S-P時間: %.2f秒 (Vp=%.2f, Vs=%.2f) の場合、震源地までの距離は %.2f km です。" % (sp_time, vp, vs, distance)) else: print("Error") return(0) main()

- sprintfスタイルの場合、%.2fとすることで、小数第二桁まで出力することができる。
- 参考サイト1

CODE: 6-1 (openpyxl)
import openpyxl as px OUTPUT_FILE = "6-1_test.xlsx" def main(): wb = px.Workbook() ws = wb.active ws.cell(column=1, row=1).value = 3 ws.cell(column=2, row=1).value = 5 ws.cell(column=1, row=2).value = 9 ws.cell(column=2, row=2).value = 2 wb.save(OUTPUT_FILE) main()


CODE: 6-2 (openpyxl)
import openpyxl as px OUTPUT_FILE = "6-2_test.xlsx" def main(): wb = px.Workbook() ws = wb.active for i in range(1, 10): for j in range(1, 10): ws.cell(column=i, row=j).value = i * j wb.save(OUTPUT_FILE) main()

CODE: 6-3 (openpyxl)
import openpyxl as px INPUT_FILE = "6-2_test.xlsx" def main(): wb = px.load_workbook(INPUT_FILE) ws = wb.active cell25 = ws.cell(column=2, row=5).value print(cell25) cell38 = ws.cell(column=3, row=8).value print(cell38) return(0) main()

- エクセルファイルの読み込みはpx.load_workbook(ファイル名)とする。

CODE: 7-1 (文字列)
def print_myinfo(first, last, age): print("私の名前は%s%sです。" % (first, last)) print("私の年齢は%d歳です。" % (age)) return firstname = "山田" lastname = "太郎" age = 39 print_myinfo(firstname, lastname, age)

- この%記法(sprintfスタイル)の他にもf文字列やformat()メソッドがある。 文字列は%s, 整数は%dだけは覚えておこう。
- 参考サイト1

CODE: 7-2 (文字列)
for i in range(0, 4): print("%04d.jpg" % (i))

- %04dとすることで、強制的に0埋めの4桁の整数を出力させることができる。

CODE: 7-3 (文字列)
def jpg2png(jpgname): if ( not(".jpg" in jpgname) ): print("Error: 拡張子が.jpgではありません") return("") else: pngname = jpgname.replace(".jpg", ".png") return(pngname) fname = "sample.jpg" pngname = jpg2png(fname) print(pngname)

- "in"を使うことで、特定の文字列が含まれているかどうかを確かめることができる。
- 文字列の関数(メソッド)の中でもreplace()は頻出!

CODE: 7-4 (正規表現)
import re def main(): text = "名前:山田太郎、年齢:30歳、職業:エンジニア" pattern = r'名前:(.*)、年齢:(.*)歳、職業:(.*)' dates = re.findall(pattern, text) for name, age, job in dates: print("%s, %s, %s" % (name, age, job)) return(0) main()

- reモジュールにはいろいろな関数があるが、まずはre.findall()を押さえておけばOK。
- 基本は()でくくって、そこの中に正規表現を入れる。
- 特に(.*)は頻出! これで数値/文字列関係なくマッチさせることができる。
- 参考サイト1 参考サイト2

CODE: 7-5 (正規表現)
import re def main(): text = "イベントは2023年5月15日から2023年5月17日まで開催されます。" pattern = r'(\d{4})年(\d{1,2})月(\d{1,2})日' dates = re.findall(pattern, text) for year, month, day in dates: print("%04d/%02d/%02d" % (int(year), int(month), int(day))) return(0) main()

- 数値4桁のマッチは\d{4}, 数値1or2桁のマッチは\d{1,2}で表現できる。

CODE: 7-6 (正規表現)
import re def main(): text = "イベントは2023年5月15日から2023年5月17日まで開催されます。" pattern = r'(\d{4})年' text_sub = re.sub(pattern, "2025年", text) print(text_sub) return(0) main()

CODE: 8-1 (ファイル入出力)
# ---- Config ---- FILE_NAME = "8-1_output.txt" def main(): s = "40 92 20 44 91" fname = FILE_NAME f = open(fname, mode="w") f.write(s) f.close() return(0) main()


CODE: 8-2 (ファイル入出力)
# ---- Config ---- FILE_NAME = "8-1_output.txt" def main(): fname = FILE_NAME f = open(fname, mode="r") s = f.read() f.close() s_list = s.split(" ") print(s_list) return(0) main()

CODE: 9-1 (ファイル入出力)
import random # ---- Config ---- FILE_NAME = "9-1_output.txt" ROWS = 3 COLUMNS = 5 def make_rand_table(rows, cols): datalist = [] for i in range(0, rows): d = [] for j in range(0, cols): d.append(str(random.randint(1, 100))) datalist.append(d) return(datalist) def write_file(datalist, fname): table_str = "" rows = len(datalist) for i in range(0, rows): table_str += " ".join(datalist[i]) + "\n" f = open(fname, mode="w") f.write(table_str) f.close() return(0) def main(): rows = ROWS cols = COLUMNS datalist = make_rand_table(rows, cols) print(datalist) fname = FILE_NAME write_file(datalist, fname) return(0) main()


CODE: 9-2 (ファイル入出力)
# ---- Config ---- FILE_NAME = "9-1_output.txt" def read_file(fname): f = open(fname, mode="r") table_str = f.read() f.close() datalist = [] lines = table_str.split("\n") rows = len(lines) for i in range(0, rows): if ( lines[i]=="" ): continue d = lines[i].split(" ") datalist.append(d) return(datalist) def main(): fname = FILE_NAME datalist = read_file(fname) print(datalist) return(0) main()

CODE: a-1 (Numpy)
import numpy as np def main(): a_arr = np.array([4, 6, 3, 1, 9]) print(a_arr) print(a_arr.ndim) # 次元 print(a_arr.shape) # 大きさ b_arr = np.zeros((4, 3)) # 4行3列の行列を作成(0埋め) print(b_arr) print(b_arr.ndim) # 次元 print(b_arr.shape) # 大きさ c_arr = np.zeros((5, 8)) # 5行8列の行列を作成(0埋め) print(c_arr) print(c_arr.ndim) # 次元 print(c_arr.shape) # 大きさ return(0) main()

- pip install numpyなどでライブラリのインストールが必要。
- numpyはいろいろな処理ができるが、まずはnumpy arrayが扱えればOK!!
- numpy arrayは通常の配列からパワーアップしたものだと考えればよい。特に二次元配列(行列)を得意としている。
- np.zeros((m, n))でm行n列の0埋めの行列を作成できる。(頻出!!)
- 参考サイト1

CODE: a-2 (Numpy)
import numpy as np def main(): arr = np.array([4, 3, 5, 2, 9]) print(np.min(arr)) # 最小値 print(np.max(arr)) # 最大値 print(np.mean(arr)) # 平均値 print(np.std(arr)) # 標準偏差 print(np.var(arr)) # 分散 print(np.sum(arr)) # 合計値 print(np.sort(arr)) # 並び替え # 九九の表を作成 arr99 = np.zeros((9, 9)) for i in range(0, 9): for j in range(0, 9): arr99[i][j] = (i+1) * (j+1) print(arr99) return(0) main()

- numpyを使うと、各種計算が簡単にできる。
- 二次元配列(行列)の値を参照する時は、arr99[行][列]のように記述する。

CODE: a-3 (Matplotlib)
import numpy as np import matplotlib.pyplot as plt # ---- Config ---- FILE_NAME = "a-3_output.png" def main(): fname = FILE_NAME x_arr = np.linspace(0, 10, 1000) y_arr = np.sin(x_arr) plt.plot(x_arr, y_arr) plt.savefig(fname) return(0) main()


CODE: a-4 (Matplotlib)
import numpy as np import matplotlib.pyplot as plt # ---- Config ---- FILE_NAME = "a-4_output.png" # y = ax^3 + bx^2 + cx + d def cubic_equation(a, b, c, d, x): y = a * x**3 + b * x**2 + c * x + d return(y) def main(): a = 1 b = -5 c = -2 d = 5 fname = FILE_NAME x_arr = np.linspace(-10, 10, 1000) y_arr = cubic_equation(a, b, c, d, x_arr) plt.plot(x_arr, y_arr) plt.savefig(fname) return(0) main()

- a-3のsin()とは異なり、今回は自作の関数(三次関数)を使用。
- a_4-output.pngというファイルが作成されるのでチェック!!
- 生成ファイル1

CODE: b-1 (Pandas)
import pandas as pd # ---- Config ---- FILE_NAME = "http://python.hisakatano.com/data/weight1.xlsx" def main(): fname = FILE_NAME df = pd.read_excel(fname, index_col=0, header=0) print("読み込んだデータ:") print(df) print() # "一日目"の列を抜き出す col1 = df[1] print("一日目の列:") print(col1) print() # "体重[kg]"の行を抜き出す weight_row = df[0:1] print("体重[kg]の行:") print(weight_row) print() # numpy arrayへ変換 weight_arr = weight_row.to_numpy() print("numpy arrayへ変換された体重[kg]の行:") print(weight_arr) return(0) main()


CODE: b-2 (Pandas)
import pandas as pd import matplotlib.pyplot as plt # ---- Config ---- FILE_NAME = "http://python.hisakatano.com/data/weight1.xlsx" OUTPUT_FILE = "output_b-2.png" def main(): fname = FILE_NAME df = pd.read_excel(fname, index_col=0, header=0) # headerを抜き出す header = df.columns header_arr = header.to_numpy() print("header:") print(header_arr) print() # "歩数"の行を抜き出す hosu_row = df[1:2] print("歩数の行:") hosu_arr = hosu_row.to_numpy()[0] print(hosu_arr) output_file = OUTPUT_FILE plt.plot(header_arr, hosu_arr) plt.savefig(output_file) return(0) main()

- 行をnumpyに変換するときに行が一つであっても二次元配列になるためto_numpy()[0]とする。
- output_b-2.pngが出力されるので要確認!
- 生成ファイル1

CODE: b-3 (Pandas)
import pandas as pd import numpy as np # ---- Config ---- FILE_NAME = "https://python.hisakatano.com/data/exams.csv" def main(): fname = FILE_NAME df = pd.read_csv(fname, index_col=None, header=0, skip_blank_lines=True) # "math"の列を抜き出す math_arr = df["math"].to_numpy() math_arr = math_arr.astype(np.float32) # 平均値 mean = np.mean(math_arr) print("平均値: %.1f" % (mean)) # 中央値 median = np.median(math_arr) print("中央値: %.1f" % (median)) # 分散 var = np.var(math_arr) print("分散: %.1f" % (var)) # 標準偏差 std = np.std(math_arr) print("標準偏差: %.1f" % (std)) # 最小値 min0 = np.min(math_arr) print("最小値: %.1f" % (min0)) # 最大値 max0 = np.max(math_arr) print("最大値: %.1f" % (max0)) return(0) main()

- 平均値、中央値、分散などはNumpyを使って簡単に求まる。
- 元データ

CODE: b-4 (Pandas)
import pandas as pd import numpy as np # ---- Config ---- FILE_NAME = "https://python.hisakatano.com/data/exams.csv" OUTPUT_FILE = "b-4_output.csv" # --------------------------------------------------------- # 平均からの差を求める # --------------------------------------------------------- def calc_mean_diff(arr): r = arr - np.mean(arr) return(r) # --------------------------------------------------------- # 偏差値を求める # --------------------------------------------------------- def calc_t_score(arr): std = np.std(arr) md_arr = calc_mean_diff(arr) t_score_arr = (md_arr / std) * 10 + 50 return(t_score_arr) def main(): fname = FILE_NAME df = pd.read_csv(fname, index_col=None, header=0, skip_blank_lines=True) # "math"の列を抜き出す math_arr = df["math"].to_numpy() math_arr = math_arr.astype(np.float32) # 平均からの差 md_arr = calc_mean_diff(math_arr) # 偏差値 ts_arr = calc_t_score(math_arr) # 出力データ df_out = pd.DataFrame() df_out["score"] = math_arr df_out["mean_diff"] = md_arr df_out["t_score"] = ts_arr print(df_out) df_out.to_csv(OUTPUT_FILE, index=False) return(0) main()

- Tスコア(偏差値)はNumpyで直接求める関数がないため、自作している。
- arr - np.mean(arr) は、配列からスカラー値を引いているので数学的にはおかしいが、「ブロードキャスト」という書き方で、Numpyでは正しく実行される。
- 出力ファイル

CODE: c-1 (Biopython)
from Bio import SeqIO # ---- Config ---- #FILE_NAME = "https://www.uniprot.org/uniprot/P59082.fasta" FILE_NAME = "P59082.fasta" def main(): fname = FILE_NAME with open(fname, mode="r") as f: for record in SeqIO.parse(f, "fasta"): id_part = record.id desc_part = record.description seq = record.seq print("id: %s" % (id_part)) print("desc: %s" % (desc_part)) print("seq: %s" % (seq)) return(0) main()


CODE: c-2 (Biopython)
from Bio import SeqIO # ---- Config ---- FILE_NAME = "P59082.fasta" def calc_gc(seq): gc = (seq.count("G") + seq.count("C")) / len(seq) return(gc) def main(): fname = FILE_NAME with open(fname, mode="r") as f: for record in SeqIO.parse(f, "fasta"): id_part = record.id desc_part = record.description seq = record.seq rev_seq = seq.reverse_complement() gc = calc_gc(seq) print("id: %s" % (id_part)) print("desc: %s" % (desc_part)) print("Reverse complement seq: %s" % (rev_seq)) print("GC: %s" % (gc)) return(0) main()

- reverse_complement()で逆相補鎖の配列を作成。
- 文字列操作の部分はBiopythonの関数に頼らなくてもOK。むしろ自分自身で書けるようになった方がよい。
- calc_gc()でGC含量を計算。
- 参考サイト1
- biopythonのドキュメント
- アップデートによって前まで使われていた関数が使えなくなっていたりするので、あまりBiopythonの関数を信用しないようにしたほうがよい。

CODE: c-3 (Biopython)
from Bio import SeqIO import gzip # ---- Config ---- FILE_NAME = "pdb_seqres.txt.gz" PRINT_NUM = 5 def main(): fname = FILE_NAME f = gzip.open(fname, mode="rt") i = 0 for record in SeqIO.parse(f, "fasta"): id_part = record.id desc_part = record.description seq = record.seq print("id: %s" % (id_part)) print("desc: %s" % (desc_part)) print("seq: %s" % (seq)) i += 1 if ( PRINT_NUM<=i ): break f.close() return(0) main()

- .gzファイルはこちらからダウンロード
- .gzファイルの読み込みは通常のopen()ではなくgzip.open()を使う。
- c-0, c-1のようにwithを使ってもいいが、インデントが深くなり可読性が悪くなることがある。今回のようにopen()/close()を使うとインデントが深くならないという利点があるが、close()を忘れないようにしないといけない。
- 今回は出力が延々と続くので、5件で切っている。

CODE: d-1 (scikit-learn)
from sklearn.decomposition import PCA import pandas as pd import matplotlib.pyplot as plt # ---- Config ---- CSV_FILE = "http://python.hisakatano.com/data/iris.csv" OUTPUT_FILE_1 = "d-1_output_1.png" OUTPUT_FILE_2 = "d-1_output_2.png" # --------------------------------------------------------- # PCAの次元圧縮結果のプロット # --------------------------------------------------------- def plot_pca_result(df, output_file): plt.clf() label_type = set(df["label"]) for t in label_type: df2 = df.query('label=="%s"' % (t)) plt.scatter(x=df2[0], y=df2[1], label=t) plt.legend() plt.grid() plt.xlabel("PC1") plt.ylabel("PC2") plt.savefig(output_file) return # --------------------------------------------------------- # メイン # --------------------------------------------------------- def main(): # ---- (1) data frameでのデータ取得 ---- df = pd.read_csv(CSV_FILE, index_col=None, header=0) print(df) # ---- (2) numpyに変換しデータ成形 ---- x = df.iloc[:, 0:4].to_numpy() # ---- (3) scikit-learnによる分析処理 ---- pca = PCA(n_components=2) pca.fit(x) x0 = pca.transform(x) # ---- 次元圧縮結果の可視化 ---- df2 = pd.DataFrame(x0) df2["label"] = df["species"] print(df2) plot_pca_result(df2, OUTPUT_FILE_1) # ---- 寄与度の可視化 ---- df3 = pd.DataFrame(pca.components_.T) df3["label"] = df.columns[0:4] print(df3) plot_pca_result(df3, OUTPUT_FILE_2) return(0) main()

- pip install scikit-leranが必要。
- 「(1)data frameでのデータ取得 -> (2)numpyに変換しデータ成形 -> (3) scikit-learnによる分析処理」 が共通する一連の流れ。
- numpy arrayへの変換は必要ないときもあるが、本格的なデータ分析のときには必須の手順となるため慣れておこう。
- 参考サイト1
- 出力ファイル1 出力ファイル2
- irisデータについて
- PCA(主成分分析)とは?

CODE: d-2 (scikit-learn)
from sklearn.linear_model import LinearRegression import pandas as pd import matplotlib.pyplot as plt # ---- Config ---- CSV_FILE = "http://python.hisakatano.com/data/linear_regression_data.csv" OUTPUT_FILE = "d-2_output.png" # --------------------------------------------------------- # メイン処理 # --------------------------------------------------------- def main(): # ---- (1) data frameでのデータ取得 ---- df = pd.read_csv(CSV_FILE, index_col=None, header=0) print(df) # ---- (2) numpyに変換しデータ成形 ---- data_na = df.to_numpy() # ---- (3) scikit-learnによる分析処理 ---- lr = LinearRegression() x = data_na[:, 0] y = data_na[:, 1] x = x.reshape(len(x), 1) # xは行列にする。 # 今回は2次元データなのでNx1の行列。 print(x) print(y) lr.fit(x, y) coef = lr.coef_[0] # 傾き intercept = lr.intercept_ # 切片 print("傾き: %f" % (coef)) print("切片: %f" % (intercept)) plt.scatter(x, y, color="red") plt.plot(x, lr.predict(x), color="blue") plt.grid() plt.savefig(OUTPUT_FILE) return(0) main()


CODE: d-3 (scikit-learn)
from sklearn.model_selection import train_test_split from sklearn.neural_network import MLPClassifier from sklearn.preprocessing import LabelEncoder import pandas as pd import numpy as np import warnings # ---- Config ---- warnings.simplefilter("ignore") # 警告が表示されないようにする CSV_FILE = "http://python.hisakatano.com/data/iris.csv" # --------------------------------------------------------- # MLPの学習 # --------------------------------------------------------- def learn_mlp(x_arr, y_arr): print("Learning ... ") model = MLPClassifier(hidden_layer_sizes=(100,), max_iter=100, activation="relu", verbose=True) model.fit(x_arr, y_arr) print("Learning ... done") return(model) # --------------------------------------------------------- # メイン処理 # --------------------------------------------------------- def main(): # ---- (1) data frameでのデータ取得 ---- df = pd.read_csv(CSV_FILE, index_col=None, header=0) print(df) x_df = df.iloc[:, 0:4] y_df = df.iloc[:, 4] # ---- (2) numpy arrayに変換しデータ成形 ---- x_arr = x_df.to_numpy() y_arr = y_df.to_numpy() print(x_arr[0:5]) print(y_arr[0:5]) # ---- (3) scikit-learnによる分析処理 ---- # ラベルを数値に変換 ("setosa"->0, "versicolour"->1, "virginica"->2) le = LabelEncoder() y_arr = le.fit_transform(y_arr) print(y_arr[0:5]) # モデルの学習 model = learn_mlp(x_arr, y_arr) # スコアの確認 # 0.9以上であればだいたいOK score = model.score(x_arr, y_arr) print("Score: %.2f" % (score)) # モデルのテスト tmp_data = np.array([[7.4,2.8,6.1,1.9]]) # テストデータは行列(二次元配列)にする y = model.predict(tmp_data) for i in range(0, 4): print("%s: %f" % (df.columns[i], tmp_data[0][i])) print("の品種は") print(le.inverse_transform(y)[0]) # ラベルの数値を文字列に戻す return(0) main()


CODE: e-1 (seaborn)
import seaborn as sns import matplotlib import matplotlib.pyplot as plt import pandas as pd # ---- Config ---- CSV_FILE = "http://python.hisakatano.com/data/iris.csv" OUTPUT_FILE = "e-1_output.svg" matplotlib.rcParams['font.family'] = 'DejaVu Serif' def main(): df = pd.read_csv(CSV_FILE, index_col=None, header=0) print(df) bar_color = ["#479FFF", "#47DFFF", "#47FFC4"] sns.barplot(data=df, x="species", y="sepal_width", hue="species", palette=bar_color) plt.xlabel("") plt.title("Iris sepal width", fontsize=16) plt.savefig(OUTPUT_FILE) return(0) main()


CODE: e-2 (Graphviz)
import graphviz DOT_FILE = "e-2_input.dot" OUTPUT_FILE = "e-2_output" def main(): graph = graphviz.Source.from_file(DOT_FILE, format="png") print(graph) graph.render(filename=OUTPUT_FILE, cleanup=True) return(0) main()


CODE: f-1 (Gemini)
import google.generativeai as genai GEMINI_API_KEY = "" def main(): genai.configure(api_key=GEMINI_API_KEY) gemini = genai.GenerativeModel("gemini-2.0-flash") prompt = "今日の東京の天気は?" response = gemini.generate_content(prompt) print(response.text) return(0) main()

- pip install google-genarativeai でインストール。
- GEMINI_API_KEYは各自設定する。
- モデル名は実装時期によって変化するため、公式サンプルを参考にする。
- 使い方はかなり簡単なので、promptを色々変化させて試してみよう。

CODE: f-2 (Gemini)
import google.generativeai as genai from markdown import markdown # ---- Config ---- GEMINI_API_KEY = "" OUTPUT_MD = "f-2_output.md" OUTPUT_HTML = "f-2_output.html" # --------------------------------------------------------- # MDファイルへの書き込み # --------------------------------------------------------- def write_md(md, mdfile): with open(mdfile, mode="w") as f: f.write(md) return # --------------------------------------------------------- # HTMLファイルへの書き込み # --------------------------------------------------------- def md2html(md, htmlfile): html = markdown(md) with open(htmlfile, mode="w") as f: f.write(html) return def main(): genai.configure(api_key=GEMINI_API_KEY) gemini = genai.GenerativeModel("gemini-2.0-flash") prompt = """ 今日の天気のレポートを作成してください。 **条件** - 国: 日本 - 地域: 宮城県仙台市 - 文字数: 1000文字程度 - レポートのみ書き出す """ response = gemini.generate_content(prompt) print(response.text) write_md(response.text, OUTPUT_MD) md2html(response.text, OUTPUT_HTML) return(0) main()

- プロンプトはマークダウン形式とすると、Gemini側が理解しやすい。
- 出力フォーマットもマークダウン形式であることに注意!
- ヒアドキュメントを駆使しよう。
- HTMLファイルをブラウザで開くと、印刷やPDF化が可能。
- VSCodeが使える場合はmdファイルを直接PDFにすることもできる。
- 参考サイト

CODE: g-1 (Tkinter)
import tkinter as tk def tk_label_0(frame, text): fg = "black" bg = "white" font = ("MSゴシック", 12) return(tk.Label(frame, text=text, fg=fg, bg=bg, font=font)) def tk_entry_0(frame): fg = "black" bg = "white" font = ("MSゴシック", 12) return(tk.Entry(frame, fg=fg, bg=bg, font=font)) def tk_button_0(frame, text): fg = "black" bg = "white" font = ("MSゴシック", 12) return(tk.Button(frame, text=text, fg=fg, bg=bg, font=font)) def main(): root = tk.Tk() root.title("Sample") root.geometry("400x300") root.config(bg="white") id_label = tk_label_0(root, "ID") id_label.grid(row=0, column=0, padx=10, pady=10) id_entry = tk_entry_0(root) id_entry.grid(row=0, column=1, padx=10, pady=10) pass_label = tk_label_0(root, "Password") pass_label.grid(row=1, column=0, padx=10, pady=10) pass_entry = tk_entry_0(root) pass_entry.grid(row=1, column=1, padx=10, pady=10) login_button = tk_button_0(root, "Login") login_button.grid(row=2, column=0, padx=10, pady=10) root.mainloop() return(0) main()

- 毎回fg, bg, fontを指定するのが面倒なので、ラッパー関数を作ると便利。
- 要素が多くなってくると変数名に混乱が起きやすくなるため、変数の命名を統一しよう。今回のサンプルコードのように命名するとわかりやすい。
- 要素の指定はpack(), grid(), place()があるが、まずはgrid()をマスターしよう。
- grid()はエクセルと同じような感覚で要素を位置を指定できる。
- padx, padyは「その行・列自体の空白を作る」イメージ。他の要素にも影響が及ぶところに注意!! 面倒ではあるが、今回のように全て一様に設定しておいたほうがわかりやすくはある。
- 参考サイト1

CODE: g-2 (Tkinter)
import tkinter as tk def tk_label_0(frame, text): fg = "black" bg = "white" font = ("MSゴシック", 12) return(tk.Label(frame, text=text, fg=fg, bg=bg, font=font)) def tk_entry_0(frame): fg = "black" bg = "white" font = ("MSゴシック", 12) return(tk.Entry(frame, fg=fg, bg=bg, font=font)) def tk_button_0(frame, text, command): # commandを新たに追加 fg = "black" bg = "white" font = ("MSゴシック", 12) return(tk.Button(frame, text=text, command=command, fg=fg, bg=bg, font=font)) # --------------------------------------------------------- # フレーム上の要素を全て削除する関数 # --------------------------------------------------------- def clear_frame(root): for w in root.winfo_children(): w.destroy() return # --------------------------------------------------------- # ログインボタンクリック後の画面 # --------------------------------------------------------- def view_logined(root, id0, pass0): # ---- ウィンドウ上の要素を全て削除 ---- clear_frame(root) # ---- ウィンドウ上に要素を配置 ---- id_label = tk_label_0(root, "ID") id_label.grid(row=0, column=0, padx=10, pady=10) id_label_2 = tk_label_0(root, id0) id_label_2.grid(row=0, column=1) pass_label = tk_label_0(root, "Password") pass_label.grid(row=1, column=0, pady=10) pass_label_2 = tk_label_0(root, pass0) pass_label_2.grid(row=1, column=1) return # --------------------------------------------------------- # ログインボタンクリック前の画面 # --------------------------------------------------------- def view_login(root): # ---- ウィンドウ上の要素を全て削除 ---- clear_frame(root) # ---- ウィンドウ上に要素を配置 ---- id_label = tk_label_0(root, "ID") id_label.grid(row=0, column=0, padx=10, pady=10) id_entry = tk_entry_0(root) id_entry.grid(row=0, column=1) pass_label = tk_label_0(root, "Password") pass_label.grid(row=1, column=0, pady=10) pass_entry = tk_entry_0(root) pass_entry.grid(row=1, column=1) login_button = tk_button_0(root, "Login", lambda:view_logined(root, id_entry.get(), pass_entry.get())) login_button.grid(row=2, column=0, pady=10) return # --------------------------------------------------------- # メイン処理 # --------------------------------------------------------- def main(): # ---- ウィンドウの設定 ---- root = tk.Tk() root.title("Login") root.geometry("400x300") root.config(bg="white") # ---- 最初の画面表示 ---- view_login(root) root.mainloop() return(0) main()

- 一つの画面に一つの関数と考えよう。
- 画面の関数名は"view_"を付けるとわかりやすい。
- buttonが押されたときの動作はcommandにて関数で定義する。lambda:がついているのは、こういうものだと思っておけばOK (lambda式)。
- 「次の画面に何の値を渡すか」を考えて関数を作成する。(今回はIDとPass)

CODE: g-3 (Tkinter)
import tkinter as tk def tk_label_0(frame, text): fg = "black" bg = "white" font = ("MSゴシック", 12) return(tk.Label(frame, text=text, fg=fg, bg=bg, font=font)) def tk_entry_0(frame): fg = "black" bg = "white" font = ("MSゴシック", 12) return(tk.Entry(frame, fg=fg, bg=bg, font=font)) def tk_button_0(frame, text, command): fg = "black" bg = "white" font = ("MSゴシック", 12) return(tk.Button(frame, text=text, command=command, fg=fg, bg=bg, font=font)) def tk_frame_0(frame): bg = "white" return(tk.Frame(frame, bg=bg)) def tk_listbox_0(frame, width, height): fg = "black" bg = "white" font = ("MSゴシック", 12) return(tk.Listbox(frame, fg=fg, bg=bg, font=font, width=width, height=height)) # --------------------------------------------------------- # フレーム上の要素を全て削除する関数 # --------------------------------------------------------- def clear_frame(root): for w in root.winfo_children(): w.destroy() return # --------------------------------------------------------- # タスクの追加処理 # task_entryの内容をtask_listboxに追加 # --------------------------------------------------------- def add_task(task_entry, task_listbox): task = task_entry.get() # task_entryから値を取得 if ( task!="" ): task_listbox.insert(tk.END, task) task_entry.delete(0, tk.END) # task_entryを空欄に return # --------------------------------------------------------- # タスクの削除処理 # task_listboxから値を削除 # --------------------------------------------------------- def delete_task(task_listbox): sel_index = task_listbox.curselection()[0] task_listbox.delete(sel_index) return # --------------------------------------------------------- # TODOリスト # --------------------------------------------------------- def view_todo(root): # ---- ウィンドウ上の要素を全て削除 ---- clear_frame(root) # ---- ウィンドウ上に要素を配置 ---- input_frame = tk_frame_0(root) input_frame.grid(row=0, column=0, padx=10, pady=10) task_label = tk_label_0(input_frame, "新しいタスク:") task_label.grid(row=0, column=0, sticky="W") # sticky="W"で左寄せ task_entry = tk_entry_0(input_frame) task_entry.grid(row=0, column=1, padx=5) add_button = tk_button_0(input_frame, "追加", lambda:add_task(task_entry, task_listbox)) add_button.grid(row=0, column=2) task_listbox = tk_listbox_0(root, width=50, height=10) task_listbox.grid(row=1, column=0, padx=10, pady=5) delete_button = tk_button_0(root, "削除", lambda:delete_task(task_listbox)) delete_button.grid(row=2, column=0, pady=5) return # --------------------------------------------------------- # メイン処理 # --------------------------------------------------------- def main(): # ---- ウィンドウの設定 ---- root = tk.Tk() root.title("TO-DOリスト") root.geometry("550x350") root.config(bg="white") # ---- 最初の画面表示 ---- view_todo(root) root.mainloop() return(0) main()

- add_task(), delete_task()の引数は要素そのものを入れる。どの要素の値を、どの要素に反映させるかを考えて関数を設計する。
- 今回はrootに全ての要素を載せていくのではなく、input_frameにtask_labelとtask_entryを載せた後、input_frameをrootに載せている。こうすることでtask_labelとtask_entryが同一化されるので,レイアウトの調整が楽になる。(パワポのグループ化みたいなイメージ)
- g-1, g-2は画面の遷移を扱っていたが、今回は要素の更新する方法を採用しているため、画面を再度書き換える必要はない。

CODE: g-4 (Tkinter)
import tkinter as tk from PIL import Image, ImageTk import os import glob IMAGE_DIR = "images/" IMAGE_SIZE = 600 def tk_label_1(frame, width, height): fg = "black" bg = "white" font = ("MSゴシック", 12) return(tk.Label(frame, fg=fg, bg=bg, font=font, width=width, height=height)) def tk_button_0(frame, text, command): fg = "black" bg = "white" font = ("MSゴシック", 12) return(tk.Button(frame, text=text, command=command, fg=fg, bg=bg, font=font)) def tk_frame_0(frame): bg = "white" return(tk.Frame(frame, bg=bg)) # --------------------------------------------------------- # フレーム上の要素を全て削除する関数 # --------------------------------------------------------- def clear_frame(root): for w in root.winfo_children(): w.destroy() return # --------------------------------------------------------- # 画像の表示処理 # "image_label"に"path"の画像を表示させる、という設計イメージ # --------------------------------------------------------- def show_image(image_label, path): pil_image = Image.open(path) pil_image.thumbnail((IMAGE_SIZE, IMAGE_SIZE)) tk_image = ImageTk.PhotoImage(pil_image) image_label.config(image=tk_image) image_label.image = tk_image return # --------------------------------------------------------- # 「前へ」ボタンの処理 # --------------------------------------------------------- def push_prev_button(image_label, image_paths, index): index[0] -= 1 if ( index[0]==-1 ): index[0] = len(image_paths) - 1 show_image(image_label, image_paths[index[0]]) return # --------------------------------------------------------- # 「次へ」ボタンの処理 # --------------------------------------------------------- def push_next_button(image_label, image_paths, index): index[0] += 1 if ( index[0]==len(image_paths) ): index[0] = 0 show_image(image_label, image_paths[index[0]]) return # --------------------------------------------------------- # 画像の表示ビュー # --------------------------------------------------------- def view_image(root): # ---- ウィンドウ上の要素を全て削除 ---- clear_frame(root) # ---- 画像のパス一覧取得 ---- index = [0] image_paths = glob.glob(os.path.join(IMAGE_DIR, "*")) if ( len(image_paths)==0 ): print("Error: 画像が見つかりません。") exit(1) # ---- ウィンドウ上に要素を配置 ---- image_label = tk_label_1(root, IMAGE_SIZE, IMAGE_SIZE) image_label.grid(row=0, column=0) btm_frame = tk_frame_0(root) # ボタンをまとめるフレーム btm_frame.grid(row=1, column=0) prev_button = tk_button_0(btm_frame, "前へ", lambda:push_prev_button(image_label, image_paths, index)) prev_button.grid(row=0, column=0, padx=5, pady=5) next_button = tk_button_0(btm_frame, "次へ", lambda:push_next_button(image_label, image_paths, index)) next_button.grid(row=0, column=1, padx=5, pady=5) show_image(image_label, image_paths[index[0]]) return # --------------------------------------------------------- # メイン処理 # --------------------------------------------------------- def main(): # ---- ウィンドウの設定 ---- root = tk.Tk() root.title("画像ビューワー") root.geometry("600x700") # 画像サイズ600x600より高さを大きく root.config(bg="white") view_image(root) root.mainloop() return(0) main()

