以前Excel VBAで「人工無能俳句作成ソフト」を作りましたが、Pythonでも作ってみました。
作り方ですが、次のような骨子をまず考えました。
先ず準備:
1.俳句を200句位集める
2.その俳句を上五、中七、下五に分けてtextファイルを作る
3.各句のうちの季語の有る句に1を付加する、ないものには0を付ける
codeの考え方:
1.まず表示フォームを作る
2.上中下句を変数に読み込む
3.乱数に応じた各句の季語合計が1になるまで、組み合わせを続ける
4.季語が一個になったら、その組み合わせを表示する
5.このやり方で俳句を五句作り表示する
とまぁここまでザックリと考えて、作ってみます。 Python二年生なので時間がかかります。
読むときは下から(最後の方から)お読みください。
************************ ④で完了しました **********************
④ codeを分かり易くするため、無理を承知で変数を日本語にしてみました。
普通codeは英数半角ですが、ローマ字はOKです。
クラスの作成はdef __init__(self):と必ずと言って良いほどselfが使われておりますが、クラスの意味が分かるようにここも例えばselfを”自分”とかに置き換えても動作はします(今回はselfのままです)。
データが多い場合は、テキストファイルにして読み込ませますが、簡単なcodeにするために今回は5句だけにしてcodeの中に書き込みました。
俳句に必要な季語がしっかり一個入っております。 一句には上中下の三人の詠み人がおりますので、それを当てるのもご愛敬かと思います。
お好きな俳句の上・中・下の句をcodeに追加すれば、素晴らしい名句が出来るかもしれません。
下のcodeを動作させると下図のようなウィンドーが出ます。 意味不明のAI俳句が出来る場合もありこれまた面白いです。
このプロジェクはこれで完了!
1 import tkinter as tk |
2 import random |
3 |
4 class Test(): |
5 |
6 上の句 = (“赤い椿1”, |
7 “夕立の1”, |
8 “菊の香や1”, |
9 “朝立や0”, |
10 “荒海や0”, |
11 “海に出て0”) |
12 |
13 中の句 = (“雪を染めたる1”, |
14 “雪がふうはり1”, |
15 “春の雲あり1”, |
16 “白い椿と0”, |
17 “隣は何を0”, |
18 “筑波に雲も0”) |
19 |
20 下の句 = (“秋の暮れ1”, |
21 “落ち葉かな1”, |
22 “散るもみぢ1”, |
23 “落ちにけり0”, |
24 “する人ぞ0”, |
25 “なかりけり0”) |
26 |
27 俳句1 = ‘1’ |
28 |
29 def __init__(self): |
30 self.root = tk.Tk() |
31 self.root.title(“人工無能俳句”) |
32 self.root.geometry(‘300×150’) |
33 |
34 self.button = tk.Button(self.root, |
35 text=’次の人工無能俳句’, |
36 command=self.output_5俳句) |
37 self.button.pack() |
38 |
39 self.ラベル俳句1 = tk.Label(self.root, text=”Pyhon作成俳句1″) |
40 self.ラベル俳句2 = tk.Label(self.root, text=”Pyhon作成俳句2″) |
41 self.ラベル俳句3 = tk.Label(self.root, text=”Pyhon作成俳句3″) |
42 self.ラベル俳句4 = tk.Label(self.root, text=”Pyhon作成俳句4″) |
43 self.ラベル俳句5 = tk.Label(self.root, text=”Pyhon作成俳句5″) |
44 |
45 self.ラベル俳句1.pack() |
46 self.ラベル俳句2.pack() |
47 self.ラベル俳句3.pack() |
48 self.ラベル俳句4.pack() |
49 self.ラベル俳句5.pack() |
50 |
51 self.root.mainloop() |
52 |
53 def output_5俳句(self, *args): |
54 for ラベル in [self.ラベル俳句1, |
55 self.ラベル俳句2, |
56 self.ラベル俳句3, |
57 self.ラベル俳句4, |
58 self.ラベル俳句5]: |
59 ラベル[“text”] = self.俳句() |
60 |
61 def 俳句(self, *args): |
62 while True: |
63 上 = random.choice(self.上の句) |
64 中 = random.choice(self.中の句) |
65 下 = random.choice(self.下の句) |
66 |
67 if self.is_俳句(上, 中, 下): |
68 return 上[:-1] + ” ” + 中[:-1] + ” ” + 下[:-1] |
69 |
70 def is_俳句(self, 上, 中, 下): |
71 俳句1_count = sum(俳句1 in 句 |
72 for 句 in (上, 中, 下) |
73 for 俳句1 in self.俳句1) |
74 |
75 if 俳句1_count == 1: |
76 return True |
77 else: |
78 return False |
79 |
80 Test() |
******************************************
③ ボタンに複数の処理をさせるやり方(code)見つけた!
見つけたのではなく、Python集団に教えて頂きました。
成程ね、クラスや関数の作り方を勉強させてもらいました。
codeを短くするため、俳句は五句だけのテキストファイルにしました。 その五句をバラバラに組み合わせするやり方です。
先ずは一句だけ表示させてます。 次回で五句作れるようにします。
codeは次に様なものです。
1 import tkinter as tk |
2 import random |
3 |
4 class Test(): |
5 |
6 KAMI = (“赤い椿1”, |
7 “春曇り1”, |
8 “夕立が1,” |
9 “朝立や0”, |
10 “荒海や0”, |
11 “海に出て0”) |
12 |
13 NAKA = (“雪を染めたる1”, |
14 “雪がふうはり1”, |
15 “春の雲あり1”, |
16 “白い椿と0”, |
17 “隣は何を0”, |
18 “筑波に雲も0”) |
19 |
20 SHIMO = (“秋の暮れ1”, |
21 “落ち葉かな1”, |
22 “散るもみぢ1”, |
23 “落ちにけり0”, |
24 “する人ぞ0”) |
25 |
26 Haiku1 = ‘1’ |
27 |
28 def __init__(self): |
29 self.root = tk.Tk() |
30 self.root.title(“人工無能俳句”) |
31 self.root.geometry(‘300×200’) |
32 |
33 self.labelSpace_0 = tk.Label(self.root).pack() |
34 self.button = tk.Button(self.root, |
35 text=’次の人工無能俳句’, |
36 command=self.make) |
37 self.button.pack() |
38 |
39 self.labelSpace_0 = tk.Label(self.root).pack() |
40 |
41 self.labelKami = tk.Label(self.root, text=”上の句”) |
42 self.labelNaka = tk.Label(self.root, text=”中の句”) |
43 self.labelShimo = tk.Label(self.root, text=”下の句”) |
44 self.labelHaiku1 = tk.Label(self.root, text=”Pyhon作成俳句1″) |
45 |
46 self.labelHaiku2 = tk.Label(self.root, text=”Pyhon作成俳句2″) |
47 self.labelHaiku3 = tk.Label(self.root, text=”Pyhon作成俳句3″) |
48 self.labelHaiku4 = tk.Label(self.root, text=”Pyhon作成俳句4″) |
49 self.labelHaiku5 = tk.Label(self.root, text=”Pyhon作成俳句5″) |
50 |
51 #self.labelKami.pack() |
52 #self.labelNaka.pack() |
53 #self.labelShimo.pack() |
54 self.labelHaiku1.pack() |
55 self.labelHaiku2.pack() |
56 self.labelHaiku3.pack() |
57 self.labelHaiku4.pack() |
58 self.labelHaiku5.pack() |
59 |
60 self.root.mainloop() |
61 |
62 def make(self, *args): |
63 while True: |
64 kami = random.choice(self.KAMI) |
65 naka = random.choice(self.NAKA) |
66 shimo = random.choice(self.SHIMO) |
67 self.labelKami[“text”] = kami |
68 self.labelNaka[“text”] = naka |
69 self.labelShimo[“text”] = shimo |
70 if self.is_Haiku1(kami, naka, shimo): |
71 return |
72 |
73 def is_Haiku1(self, kami, naka, shimo): |
74 Haiku1_count = sum(Haiku1 in ku |
75 for ku in (kami, naka, shimo) |
76 for Haiku1 in self.Haiku1) |
77 self.labelHaiku1[“text”] = Haiku1_count |
78 self.labelSpace_0 = tk.Label(self.root).pack() |
79 |
80 if Haiku1_count == 1: |
81 Haiku1 = kami[:-1] + ” ” + naka[:-1] + ” ” + shimo[:-1] |
82 self.labelHaiku1[“text”] = Haiku1 |
83 return True |
84 else: |
85 self.labelHaiku1[“text”] = “季語がないか又は多すぎます。” |
86 return False |
87 |
88 Test() |
**********************************************
新規投稿を最初にしてます。
② 中の句表示を追加
あれ、中七はOKだけど、上の句が出てこない。
いろいろcodeを書き換えたけれど、結論を云うと関数の中にまた関数があり、その中には自分も含んでいるという迷路になってしまい上手く行きませんでした。
なのでcodeは書きません。 ネットで調べると一つのコマンド命令に複数処理をさせる場合は、クラスを作って云云かんぬんとありました。
これからそのクラス作りの学習を始めます。
下の図は中句だけ表示されたところ。
*****************************************
① 上の句だけ表示 季語があれば1と表示
フォームとcodeはこんな風になりました。 一週間もすると自分でも何を書いているのか分からなくなります。
1 import tkinter as tk |
2 import random |
3 |
4 root = tk.Tk() |
5 |
6 root.geometry(‘400×250+150+70’) |
7 root.title(‘AI俳句’) |
8 |
9 # Label |
10 lbl1 = tk.Label(text=’上の句:’) |
11 lbl1.place(x=20, y=30) |
12 lbl2 = tk.Label(text=’中の句:’) |
13 lbl2.place(x=150, y=30) |
14 lbl3 = tk.Label(text=’下の句:’) |
15 lbl3.place(x=280, y=30) |
16 |
17 lbl4 = tk.Label(text=’季語なら1:’) |
18 lbl4.place(x=20, y=90) |
19 |
20 |
21 # Text(Entry) |
22 txt1 = tk.Entry(width=15) |
23 txt1.place(x=20, y=60) |
24 txt2 = tk.Entry(width=15) |
25 txt2.place(x=150, y=60) |
26 txt3 = tk.Entry(width=15) |
27 txt3.place(x=280, y=60) |
28 |
29 txt4 = tk.Entry(width=5) |
30 txt4.place(x=80, y=90) |
31 txt5 = tk.Entry(width=5) |
32 txt5.place(x=210, y=90) |
33 txt6 = tk.Entry(width=5) |
34 txt6.place(x=340, y=90) |
35 |
36 #Command Button1 |
37 btn1=tk.Button(root, text=’開始/次へ’) |
38 btn1.place(x=50, y=200) |
39 import tkinter as tk |
40 import randomdef read_haikus(): |
41 file = open(‘有名俳句上句10.txt’,’r’, encoding=’utf_8′) |
42 root = tk.Tk() lines = file.readlines() |
43 file.close() |
44 root.geometry(‘400×250+150+70’) |
45 root.title(‘AI俳句’) kami5_haikus = [] # 上5俳句list |
46 kami5_indexes = [] # 上五季語インデックスlist |
47 |
48 # Label line_count = 0 #上5カウンター |
49 lbl1 = tk.Label(text=’上の句:’) for line in lines: |
50 lbl1.place(x=20, y=30) name = line.rsplit(“\t”) #tabで区切ったファイルの場合 |
51 lbl2 = tk.Label(text=’中の句:’) if len(name) == 2: # 要素2個をそれぞれのlistへ追加する |
52 lbl2.place(x=150, y=30) kami5_haikus.append(name[0]) # 英単語をlistへadd |
53 lbl3 = tk.Label(text=’下の句:’) kami5_indexes.append(name[1]) # 意味をlistへadd |
54 lbl3.place(x=280, y=30) line_count += 1 |
55 return line_count,[kami5_haikus, kami5_indexes] # txtがなくなるまで繰り返す |
56 lbl4 = tk.Label(text=’季語なら1:’) |
57 lbl4.place(x=20, y=90) |
58 def show_data(count,num, kami5_haikus, kami5_indexes): # 乱数に応じた要素を表示する関数 |
59 kami5_haiku = kami5_haikus[num] # 英単語をkami5_haikuに格納 |
60 # Text(Entry) kami5_index = kami5_indexes[num] |
61 txt1 = tk.Entry(width=15) |
62 txt1.place(x=20, y=60) #ボタン1(開始/次)の関数 |
63 txt2 = tk.Entry(width=15) def haiku_Show(event): |
64 txt2.place(x=150, y=60) num = random.randrange(0, count) |
65 txt3 = tk.Entry(width=15) #print(f’num={num}’) #変数numの表示 |
66 txt3.place(x=280, y=60) kami5_haiku = kami5_haikus[num] # kami5_haikuに格納 |
67 kami5_index = kami5_indexes[num] |
68 txt4 = tk.Entry(width=5) |
69 txt4.place(x=80, y=90) txt1.delete(0, tk.END) |
70 txt5 = tk.Entry(width=5) txt4.delete(0, tk.END) |
71 txt5.place(x=210, y=90) |
72 txt6 = tk.Entry(width=5) txt1.insert(0, f’ {kami5_haiku}’) #txt1.insert(tk.END, kami5_haiku)でもOK |
73 txt6.place(x=340, y=90) txt4.insert(0, f’ {kami5_index}’) |
74 |
75 btn1.bind(“<Button>”, haiku_Show) |
76 |
77 count, haikus = read_haikus() |
78 kami5_haikus = haikus[0] |
79 #Command Button1 kami5_indexes = haikus[1] |
80 btn1=tk.Button(root, text=’開始/次へ’) |
81 btn1.place(x=50, y=200)num = random.randrange(0, count) |
82 show_data(count, num, kami5_haikus, kami5_indexes) |
83 def read_haikus(): |
84 file = open(‘有名俳句上句10.txt’,’r’, encoding=’utf_8′) |
85 lines = file.readlines()def destroy(): |
86 file.close() global root |
87 root.destroy() |
88 kami5_haikus = [] # 上5俳句list |
89 kami5_indexes = [] # 上五季語インデックスlist#Command Button2 |
90 btn2=tk.Button(root, text=’終わる’, command=destroy) |
91 line_count = 0 #上5カウンターbtn2.place(x=180, y=200) |
92 for line in lines: |
93 name = line.rsplit(“\t”) #tabで区切ったファイルの場合root.mainloop() |
94 if len(name) == 2: # 要素2個をそれぞれのlistへ追加する |
95 kami5_haikus.append(name[0]) # 英単語をlistへadd |
96 kami5_indexes.append(name[1]) # 意味をlistへadd |
97 line_count += 1 |
98 return line_count,[kami5_haikus, kami5_indexes] # txtがなくなるまで繰り返す |
99 |
100 def show_data(count,num, kami5_haikus, kami5_indexes): # 乱数に応じた要素を表示する関数 |
101 kami5_haiku = kami5_haikus[num] # 英単語をkami5_haikuに格納 |
102 kami5_index = kami5_indexes[num] |
103 |
104 #ボタン1(開始/次)の関数 |
105 def haiku_Show(event): |
106 num = random.randrange(0, count) |
107 #print(f’num={num}’) #変数numの表示 |
108 kami5_haiku = kami5_haikus[num] # kami5_haikuに格納 |
109 kami5_index = kami5_indexes[num] |
110 |
111 txt1.delete(0, tk.END) |
112 txt4.delete(0, tk.END) |
113 |
114 txt1.insert(0, f’ {kami5_haiku}’) #txt1.insert(tk.END, kami5_haiku)でもOK |
115 txt4.insert(0, f’ {kami5_index}’) |
116 |
117 btn1.bind(“<Button>”, haiku_Show) |
118 |
119 count, haikus = read_haikus() |
120 kami5_haikus = haikus[0] |
121 kami5_indexes = haikus[1] |
122 |
123 num = random.randrange(0, count) |
124 show_data(count, num, kami5_haikus, kami5_indexes) |
125 |
126 def destroy(): |
127 global root |
128 root.destroy() |
129 |
130 #Command Button2 |
131 btn2=tk.Button(root, text=’終わる’, command=destroy) |
132 btn2.place(x=180, y=200) |
133 |
134 root.mainloop() |