ステップ1「はじめに」
センリの道も一歩から!
みんなおはよう~、水彩センリだよ
今日はラボノートの新しいページを紹介するね
前回の記事を読んでいない人にも分かるように書くけど、前回説明した部分は説明省略しちゃうよ~
今回の記事は
ステップ1「はじめに」…………開発環境や概略
ステップ2「Are You Ready?」…………ディレクトリの準備
ステップ3「コードを書いていこうねぇ」…………スクリプト
ステップ4「細かく細かく砕こう!」…………詳細説明
ステップ5「これからもよろしくね」…………改善点の洗い出し
っていう進行をするから、順に見ていってね!!
第二回はこれ!
今日紹介するのは、現在テスト中のあれ!
「センリのごはんWordle」だよ~
画像提供に協力してくれたのはスッチーさん
柔らかなイラストが心落ち着く配信者さんだよ!
ゲーム配信の他に、お絵描きライブをやってるんだって!
4/24~4/30に開催されるVtuberクリエイトフェスティバルに出展すべく、絶賛イラスト作成中!
完成が今から楽しみだねぇ。皆も一緒に応援しようねっ!
→(https://www.youtube.com/channel/UCfZz3WBvmmSNwTPM1YJywQQ)
仕様
1、正解を作成する
2、解答を貰う
3、何回目の解答かチェックする
4、解答と正解を比較して⬜🟨🟩で返信
5、正解が出たら紹介する
6、以降の解答は締め切る
ラボの環境
センリの開発環境を説明するよ
Windows 10 Home
Visual Studio Code
Python 3.10.1
tweepy 4.5.0
tweepyのインストール、TwitterAPIの取得は各自で別途調べてね!
参考リンク
今回はどこも参考にしてないから、粗が目立つかもしれないの(∩´﹏`∩)
ステップ2「Are You Ready?」
たまには英語、使いたくなるよね!
ファイルやディレクトリの準備をしていくよ~
ごはんリストの作成
普段食べたものを思いつく限りリストに記入するよ~
特に読まなくても良いけど、興味がある人は開いてね
ごはんリスト(折りたたみ)
あらじる
いかめし
うにどん
おにぎり
おむれつ
おさしみ
せきはん
かきあげ
かけそば
かけもち
かつどん
かにたま
きんとん
くずもち
クッキー
くれーぷ
ここっと
さいだー
ざるそば
しぇいく
しめさば
すいとん
すきやき
ぜんざい
ぞうすい
そうめん
たいやき
かこやき
たんめん
とんかつ
にらたま
ぱえりあ
ばってら
ばばろあ
びーふん
ぴざまん
びびんば
ぴろしき
ぼるしち
みつまめ
らーめん
りぞっと
いそじる
いももち
まきずし
きもすい
よせなべ
くしかつ
さけめし
にざかな
はるまき
やきなす
やきとり
やきにく
むしぱん
むしどり
みずたき
てんぷら
ゆどうふ
とんじる
にくそば
にくまん
かすじる
あげそば
ひやじる
あじふらい
あなごどん
いかふらい
いくらどん
いなりずし
うぃんなー
うなぎどん
うなじゅう
えびぴらふ
えびふらい
おみそしる
おむらいす
おちゃづけ
かきふらい
かけうどん
かつかれー
かつさんど
かれーぱん
かれーまん
きつねそば
きむちなべ
ごまだんご
こんぽーと
さつまじる
さらだまき
ざるうどん
しゅーまい
そぼろどん
たぬきそば
ちきんかつ
ちゃーはん
つなさらだ
てぃらみす
ところてん
とろろそば
なぽりたん
にぎりずし
にしんそば
にゅうめん
はむえっぐ
はんばーぐ
びーふかつ
まぐろかつ
まぐろどん
みぞれじる
めんちかつ
もろきゅう
らざーにあ
わらびもち
いそべもち
ぎゅうどん
くりごはん
つきみそば
ごこくまい
ごもくずし
ごもくまめ
ちらしずし
わかたけに
てまきずし
やきうどん
おやこどん
すれんこん
せんばじる
たにんどん
ちくぜんに
てっかまき
まめごはん
ぶたきむち
にくうどん
にくじゃが
こふきいも
めだまやき
たまごやき
たまごやき
たまごどん
さといもに
たつたあげ
ひややっこ
いりどうふ
いりたまご
あさりごはん
あっぷるぱい
いかのにつけ
いんどかれー
えびてんどん
はやしらいす
きつねうどん
てんぷらそば
おこのみやき
たまごすーぷ
かきあげそば
かきあげどん
かつばーがー
かにぐらたん
かにたまどん
かるぱっちょ
かれーうどん
かれーすーぷ
かれーらいす
きつねうどん
きなこごはん
きのこごはん
きゅうりまき
けんちんじる
こーるすろー
こーんぴらふ
ごぼうさらだ
ころっけぱん
ささみふらい
しゃぶしゃぶ
すなっくがし
すぱげってぃ
そばがきじる
たぬきうどん
たんたんめん
ちーずけーき
ちーずけーき
ちーずさらだ
ちきんかれー
ちきんそてー
ちきんどりあ
ちきんぴらふ
ちきんらいす
どらいかれー
とろみすーぷ
とろろうどん
のっぺいじる
ばたーらいす
はむすてーき
はやしらいす
はんばーがー
ばんばんじー
ぴざとーすと
ぶりだいこん
ぽーくそてー
ほっとけーき
ほっとどっぐ
ぽてとさらだ
まーぼーなす
まーぼーどん
みーとぼーる
みーとろーふ
みそらーめん
みっくすぴざ
みもざさらだ
みるくせーき
みるふぃーゆ
めれんげぱい
もやしいため
もんじゃやき
ゆかりごはん
ゆばちゃづけ
ろーるけーき
わかめうどん
わかめすーぷ
わんたんめん
うのはなじる
しおらーめん
つきみうどん
さばのみそに
さんぺいじる
やまかけどん
さんさいそば
にこみうどん
わかたけじる
やきおにぎり
やきぎょうざ
やきそばぱん
やきそばぱん
あかだしじる
だいがくいも
ちゃわんむし
ちゅうかそば
ちゅうかどん
てんぷらそば
まめのさらだ
とうふさらだ
とうふさらだ
なんばんやき
なっとうまき
なっとうまき
はっぽうさい
やさいかれー
やさいさらだ
やさいぜりー
やさいそてー
あげたこやき
たまごどうふ
ちからうどん
わふうさらだ
あんにんどうふ
あんもちぞうに
だしまきたまご
えびかつさんど
ぐらたんすーぷ
おにおんすーぷ
おむれつけーき
かきあげうどん
かつおのたたき
かぼちゃぷりん
きゃらめるらて
きんぴらごぼう
こーひーぜりー
こんそめすーぷ
サーモンマリネ
さんどうぃっち
しーざーさらだ
しょーとけーき
すいーとぽてと
すこっちえっぐ
すてぃっくぱい
たけのこごはん
だしまきたまご
たたききゅうり
だぶるばーがー
ちーずばーがー
ちきんぐらたん
ちきんばーがー
ちゃんぽんめん
はにーとーすと
にしょくぜりー
ぱうんどけーき
ばけっとさんど
びーふしちゅー
びーふすてーき
ふかひれすーぷ
ふらんくふると
ふるーつさらだ
ふるーつさんど
ふるーつぜりー
ふるーつぽんち
まーぼーどうふ
まかろにさらだ
まんごーぷりん
みっくすさんど
みねすとろーね
らいすばーがー
ろーすとちきん
ろーすとびーふ
ろーるきゃべつ
わんたんすーぷ
おんせんたまご
かいそうさらだ
かまあげうどん
とりのからあげ
とりのとまとに
とりのてりやき
こうはくなます
さけのむにえる
さばのみそしる
さんしょくどん
さんさいうどん
さんさいおこわ
さんしょうやき
はるさめさらだ
たきこみごはん
あおなのそてー
だいこんさらだ
ちゃきんしぼり
ちゅうかちまき
てんぷらうどん
とうにゅうなべ
とうふぐらたん
とうふすてーき
にくだんごなべ
やさいころっけ
あげだしどうふ
たまごぞうすい
ひやしちゅうか
ぶりのてりやき
いきなりだんご
あさりのみそしる
あさりのさかむし
あすぱらべーこん
いかしょうゆやき
うぃんなーろーる
うなぎのかばやき
かすたーどぷりん
かぼちゃころっけ
かぼちゃのにもの
きのこのみそしる
くりーむしちゅー
こーんぽたーじゅ
さざえのつぼやき
しーふーどさらだ
じゃーまんぽてと
すらいすおにおん
ちゃーしゅーめん
クラムチャウダー
てりやきばーがー
ふれんちとーすと
とろろこんぶじる
とんこつらーめん
びーんずしちゅー
ぷりんあらもーど
ふるーつばばろあ
ふるーつみっくす
ふれんちとーすと
ふろふきだいこん
まーぼーはるさめ
まかろにぐらたん
みっくすじゅーす
よーぐるとさらだ
りんごのふらんべ
れあちーずけーき
くりのしぶかわに
さけのほいるやき
さしみこんにゃく
さんまのしおやき
にんじんぐらっせ
あおなのおひたし
あおなのごまあえ
あおなのしらあえ
きりぼしだいこん
だいこんのにもの
とりなんばんそば
とうふのあんかけ
とうふのでんがく
とうふはんばーぐ
ぶたにくのかくに
にくのやさいまき
にくやさいいため
まっちゃきんとき
あじつけかずのこ
やさいのごまあえ
やさいののりまき
やさいのてんぷら
やさいろーるかつ
さといもでんがく
れいしゃぶさらだ
わふうはんばーぐ
うぃんなーこーひー
がーりっくとーすと
かぼちゃぽたーじゅ
きのこすぱげってぃ
きのこのいためもの
きゅうりのすのもの
ごーやちゃんぷるー
こんにゃくいために
さつまいもばたーに
すくらんぶるえっぐ
すぱげってぃさらだ
たぴおかここなっつ
たらこすぱげってぃ
ちょこれーとけーき
ぴーまんのにくずめ
ひじきのいためもの
ふぃっしゅばーがー
ふるーつよーぐると
ぎゅうにくのたたき
さんしょくおにぎり
だいこんのみそしる
ちゅうかふうすーぷ
とうにゅうみそしる
とうふのすましじる
とうふのつくねあげ
はくさいのおひたし
やさいのたまごとじ
ディレクトリ
それじゃあ、ディレクトリがこんな感じになるよう作成&配置してね
/Senri
├── reply-list.txt (既返信リスト)
├── done-log.txt (実行ログ)
├── auth.py (APIファイル)
├── Functions.py (関数ファイル)
├── run.py (実行ファイル)
├── run.bat (バッチファイル)
├── Automation.py (定期ツイートファイル)
├── Automation.bat (定期ツイートバッチファイル)
└── /wordle
├── wordList.txt (ごはんリスト)
├── able.txt (可返信リスト)
├── answer.txt (正解ファイル)
├── question.txt (出題ファイル)
└── /reactions (解答フォルダ)
ステップ3「コードを書いていこうねぇ」
センリはAPIファイルと関数ファイル、実行ファイルの三つに分けて動かしてるよ
APIは大事に保管したいし、実行ファイルは簡潔にまとめたいからね~
説明用に用語を定義してるよ
【リプライ】
センリが受け取るもの
【返信】
センリが送るもの
【可返信リスト】
ここにリプライを貰った場合、返信するよ~っていうツイートたち
→ただのリプライと、解答リプライを区別するために必要だね
【既返信リスト】
センリが返信し終わったツイートたち
→何度も返信しないようにリスト化してるよ
APIファイル
ここにTwitterAPIを入力するよ
consumer_key="xxxxxxxxxxxxxxxxxxxxxxxxxx"
consumer_secret="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
access_token="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
access_token_secret="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
定期実行ファイル
一日一回、出題するために使うよ~
from Functions import *
if __name__ == '__main__':
refresh()
実行ファイル
解答のチェックをするよ
センリは5分間隔で動かすようにしてるけど、お好みで良いと思うんだぁ
from Functions import *
if __name__ == '__main__':
ReplytoReply()
関数ファイル
中身はここに書き込むね
関数部分と実行部分を分けると、機能追加が楽なんだよ~
前回実装した関数も一部あるけど、ちゃんと全部書くね~
すっごく長いから折りたたんでるよ! 読むときは開いてね!!
関数ファイル、折りたたみ
import os
import shutil
import sys
import time
import random
import re
from logging import getLogger, StreamHandler, FileHandler, DEBUG, Formatter
#今回のTwitterモジュール
import tweepy
#auth.pyに書いてるキーをimportします
from auth import(
consumer_key,
consumer_secret,
access_token,
access_token_secret)
#Tweepyのおまじないです
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth)
#ログ出力のおまじない
logger = getLogger(__name__)
handler1 = StreamHandler()
handler1.setFormatter(Formatter("%(asctime)s %(levelname)8s %(message)s"))
handler2 = FileHandler("done-log.txt", encoding="utf-8-sig")
handler2.setLevel(DEBUG)
handler2.setFormatter(Formatter("%(asctime)s %(levelname)8s %(message)s"))
logger.setLevel(DEBUG)
logger.addHandler(handler1)
logger.addHandler(handler2)
logger.propagate = False
#君の名は。
my_name = "SuisaiSenri"
#可返信リスト/既返信リストの取得関数だよ
def get_listfile(file):
#可返信リストのファイルを読み込みます
with open(file, mode='r', encoding="utf-8-sig") as f:
reader = f.readlines()
f.close()
#可返信ツイートのリストを作ります。改行文字ジャマなので消すね~
return [x.rstrip('\n') for x in reader]
#返信して良いかどうかの確認
def able_check(tweet, ablelist, alreadylist):
#貰ったリプライのリプライ先が可返信ツイートであることを確認します
if tweet.in_reply_to_status_id_str in ablelist:
usr = tweet.user.screen_name + ":" + tweet.id_str
#未返信であることを確認します
if usr not in alreadylist:
return True
else:
return False
else:
return False
#可返信ツイートの記録
def save_Replyable(tweet, file):
#可返信ツイートに追記します
#aは末尾への追記モード、encodingは絵文字認識のためsig
with open(file, mode='a', encoding="utf-8-sig") as f:
f.write("\n" + tweet.id_str)
f.close()
#既返信リストの更新
def already(alreadylist):
#ファイルを開き、書き出します。
with open("reply-list.txt", mode='w', encoding="utf-8-sig") as f:
f.write('\n'.join(alreadylist))
f.close()
#貰ったリプライへの返信
def ReplytoReply():
#可返信リスト、既返信リストを取得
ablelist = get_listfile("wordle/able.txt")
alreadylist = get_listfile("reply-list.txt")
#貰ったリプライを取得します
try:
#こまめに動かす予定なので検索数は10件程度
tweets = api.mentions_timeline(count=10, tweet_mode='extended')
#古いツイートから順番に返信したいので、reversedを使います
tweets = reversed(tweets)
except tweepy.errors.TweepyException as e:
logger.error(e.msg)
sys.exit(1)
for tweet in tweets:
try:
#いいね数が0ならいいねを付けます
if tweet.favorite_count == 0:
api.create_favorite(tweet.id)
except tweepy.errors.TweepyException:
logger.info(f"いいねに失敗しました\n@{tweet.user.screen_name}")
#返信しても良いリプライか考えます。
check = able_check(tweet, ablelist, alreadylist)
if check == True:
try:
#リプライ操作
wordle(tweet)
except tweepy.errors.TweepyException:
pass
else:
logger.info("リプライしました: \n{0}".format(tweet.full_text))
#既返信リストを準備します
usr = tweet.user.screen_name + ":" + tweet.id_str
alreadylist.append(usr)
time.sleep(random.uniform(6,10))
#既返信リストを更新します
already(alreadylist)
#リプライ実行
def Reply(tweet, sentence):
#名前の加工
name = nameProcess(tweet.user.name)
#名前が消滅した場合、IDで呼ぶ
if name == "":
name = tweet.user.screen_name
#@ID を文頭に付けなければリプライとして処理されない
name = "@" + tweet.user.screen_name + "\n" + name
text = name + sentence
#よろしくお願いしまぁぁぁすっ!!
return api.update_status(status=text, in_reply_to_status_id=tweet.id)
#名前の加工部分
def nameProcess(name):
name = name.rstrip('\n')
r = r"[\((\[<\{<「『“【[〈{《〔‘].*?$"
if re.sub(r, "", name) == "":
r = r"\(.+?\)|(.+?)|\[.+?\]|<.+?>|\{.+?\}|<.+?>|「.+?」|『.+?』|“.+?”|【.+?】|[.+?]|〈.+?〉|{.+?}|《.+?》|〔.+?〕|‘.+?’"
p = re.sub(r, "", name)
r = r"[@@].*?$"
if re.sub(r, "", p) == "":
r = r"[@@]"
p = re.sub(r, "", p)
r = r"[//\||::].+?$"
if re.sub(r, "", p) == "":
r = r"[//\||::]"
p = re.sub(r, "", p)
r = r"[\u0000-\u007F\uFF01-\uFF0F\uFF1A-\uFF20\uFF3B-\uFF40\uFF5B-\uFF65\u3000-\u303F\u3041-\u309F\u30A1-\u30FF\uFF66-\uFF9F\u2E80-\u2FDF\u3005-\u3007\u3400-\u4DBF\u4E00-\u9FFF\uF900-\uFAFF\U00020000-\U0002EBEF]+"
m = re.search(r, p)
if m:
p = m.group()
else:
p = ""
r = r"[!!]+"
p = re.sub(r, "", p)
r = r"bot$|Bot$|BOT$"
p = re.sub(r, "", p)
#それでも文字数が過剰な場合、空白以降も消します
if len(p) > 18:
r = r"[ ].+?$"
p = re.sub(r, "", p)
#名前が消滅している場合もあるので場合分け
if p != "":
#名前に最初から敬称が付いてる人はそのまま呼んであげます。他はさん付け
r = r"たん$|さん$|ちゃん$|くん$|君$|様$"
if re.search(r, p):
title = ""
else:
title = "さん"
p = p + title
return p
#毎日の出題を行います
class refresh():
def __init__(self):
#ごはんリストを取得します
self.wordList = get_listfile("wordle/wordList.txt")
self.refresh()
def refresh(self):
with open("wordle/able.txt", mode='w', encoding="utf-8") as f:
f.write("")
f.close()
answer = random.choice(self.wordList)
#正解を正解ファイルに書き込みます
with open("wordle/answer.txt", mode="w", encoding="utf-8")as f:
f.write(answer)
f.close()
self.Tweet(len(answer))
#リアクションファイルのリセット
target_dir = 'wordle/reactions'
shutil.rmtree(target_dir)
os.mkdir(target_dir)
def Tweet(self, n):
try:
text = f"センリのごはんwordle~!\n\nQ、センリは今日何を食べたでしょう?\n\nルール:ひらがな{n}文字のごはんをリプライしてね\n回答は一人6回までだよ~"
#ツイート実行
tweet = api.update_status(status=text)
#送信できない場合の処理
except tweepy.errors.TweepyException:
logger.info("送信に失敗しました")
else:
save_Replyable(tweet, "wordle/able.txt")
#出題ツイートのIDを記録します
with open("wordle/question.txt", mode='w', encoding="utf-8") as f:
f.write(tweet.id_str)
f.close()
class wordle():
def __init__(self, tweet):
with open("wordle/answer.txt", mode="r", encoding="utf-8")as f:
answer = f.read()
f.close()
#正解が出た後か調べます。正解が出た時にanswerは""になる仕組みだよ
if answer == "":
self.correct = True
else:
self.correct = False
self.num = len(answer)
self.answer = answer
self.tweet = tweet
self.usr = self.tweet.user.screen_name + ":" + self.tweet.id_str
self.reply = self.tweet.full_text[len(my_name)+2:]
while(len(self.reply) < self.num):
self.reply = self.reply + " "
self.wordle()
def wordle(self):
if self.correct == False:
id = self.tweet.user.screen_name
try:
#解答ファイル
with open(f"wordle/reactions/{id}.txt", mode="r", encoding="utf-8-sig")as f:
reactions = f.readlines()
f.close()
except:
a = 1
else:
#解答数を調べる
a = len(reactions)
react = self.reaction()
text = f"の{a}回目の回答~\n\nただいまの結果:{react}"
if "🟨" not in react and "⬜" not in react and a <= 6:
text = text + f"\n\nおめでとう!\n正解は{self.answer}でした~"
name = nameProcess(self.tweet.user.name)
#名前が消滅した場合、IDで呼ぶ
if name == "":
name = id
self.Tweet(name, id)
elif a == 6:
text = text + f"\n\n残念!\n今日の回答はここまでだよ~\n\nまた明日も挑戦してねっ!"
elif a > 6:
text = f"\n回答は6回までだよ~\n\nまた明日も挑戦してねっ!"
with open(f"wordle/reactions/{id}.txt", mode="a", encoding="utf-8-sig")as f:
f.write("\n" + react)
f.close()
address = Reply(self.tweet, text)
save_Replyable(address, "wordle/able.txt")
else:
text = "今日はもう正解が出ちゃったんだあ\n\nまた明日も挑戦してねっ!"
Reply(self.tweet, text)
save_Replyable(self.tweet, "wordle/able.txt")
def reaction(self):
answer = list(self.answer)
a = []
for n in range(self.num):
if self.reply[n] == answer[n]:
a.append("2")
answer[n] = "a"
else:
a.append("0")
for n in range(self.num):
if a[n] == "0":
if self.reply[n] in answer:
pos = answer.index(self.reply[n])
a[n] = "1"
answer[pos] = "a"
react = "".join(a)
react = react.replace("2", "🟩")
react = react.replace("1", "🟨")
react = react.replace("0", "⬜")
return react
def Tweet(self, name, id):
try:
with open("wordle/answer.txt", mode="r", encoding="utf-8")as f:
answer = f.read()
f.close()
with open("wordle/question.txt", mode="r", encoding="utf-8")as f:
q = f.read()
f.close()
url = f"https://twitter.com/{my_name}/status/{q}"
text = f"今日の正解者が出たよ~!\n答えは{answer}でした~\n\n一番乗りは{name}(@{id})\nおめでとう~!\nみんな明日もぜひぜひ挑戦してねっ!\n{url}"
#ツイート実行
api.update_status(status=text)
with open("wordle/answer.txt", mode='w', encoding="utf-8") as f:
f.write("")
f.close()
#送信できない場合の処理
except tweepy.errors.TweepyException as e:
logger.error(e.msg)
ステップ4「細かく細かく砕こう!」
今回もしっかり説明していくよ~
def able_check(tweet, ablelist, alreadylist):
if tweet.in_reply_to_status_id_str in ablelist:
usr = tweet.user.screen_name + ":" + tweet.id_str
if usr not in alreadylist:
return True
else:
return False
else:
return False
これは返信して良いのか確かめる関数だよ。貰ったリプライが
・送信先が「可返信リスト」に含まれている
・既返信リストに含まれていない
っていう二点をクリアしてたら返信するんだぁ
try:
tweets = api.mentions_timeline(count=10, tweet_mode='extended')
tweets = reversed(tweets)
ツイートの取得は最新のものから行われるよ
時系列順に返信しないと、先に正解者が出た時の対応を間違えちゃうから注意だね~
try:
if tweet.favorite_count == 0:
api.create_favorite(tweet.id)
検索するたびにいいねを押しちゃうから、いいねの数が0のときだけにしたよ
センリが知らないだけで、既にいいねしたかどうかの値が存在するかも……?
返信して良いツイートじゃない場合でもいいねは付けておきたいから、このタイミングでいいね操作したいの(ノω·`o)
answer = random.choice(self.wordList)
with open("wordle/answer.txt", mode="w", encoding="utf-8")as f:
f.write(answer)
f.close()
答えをランダムで選択、ファイルに書き込んでおくよ
target_dir = 'wordle/reactions'
shutil.rmtree(target_dir)
os.mkdir(target_dir)
解答フォルダを空にしておくよ
一旦フォルダを削除して、同名のフォルダを作成する感じ~
with open("wordle/question.txt", mode='w', encoding="utf-8") as f:
f.write(tweet.id_str)
f.close()
解答発表に使うから、出題ツイートを別ファイルに保存しておくよ
ここからはお待ちかね、Wordle機能の本体だよ
with open("wordle/answer.txt", mode="r", encoding="utf-8")as f:
answer = f.read()
f.close()
if answer == "":
self.correct = True
else:
self.correct = False
解答ファイルが空白かどうかで挙動が変わるようにしてるよ
これはね、正解者が出た時に解答ファイルを空白に書き換えてるからなんだ~
self.reply = self.tweet.full_text[len(my_name)+2:]
while(len(self.reply) < self.num):
self.reply = self.reply + " "
Twitterのテキストは「@SuisaiSenri (ツイート本文)」っていう形だから、@と" "の2文字を除いたところからが本文なんだ~
もしも6文字で答えてねって言ってるのに解答が5文字しかなかった場合!
このときは空白で文字数を補ってあげるよ~
try:
with open(f"wordle/reactions/{id}.txt", mode="r", encoding="utf-8-sig")as f:
reactions = f.readlines()
f.close()
except:
a = 1
else:
a = len(reactions)
まだ解答したことのない人は解答ファイルが存在しないから、エラーになっちゃうの~
そのときは1回目の解答ってことになるね
既に解答したことのある人は、解答ファイルを参照するよ
一行目が空白*1 だからそのまま要素の数を見たら解答数になるんだね
*1……あとで f.write("\n" + react) っていう書き方をするんだけど、一行目に空白が入って不格好なの
でもそのおかげで要素の数が解答数そのままになって楽だから、これで良いのかなぁ
react = self.reaction()
text = f"の{a}回目の回答~\n\nただいまの結果:{react}"
if "🟨" not in react and "⬜" not in react and a <= 6:
text = text + f"\n\nおめでとう!\n正解は{self.answer}でした~"
name = nameProcess(self.tweet.user.name)
if name == "":
name = id
self.Tweet(name, id)
elif a == 6:
text = text + f"\n\n残念!\n今日の回答はここまでだよ~\n\nまた明日も挑戦してねっ!"
elif a > 6:
text = f"\n回答は6回までだよ~\n\nまた明日も挑戦してねっ!"
解答が緑一色で、解答数が6回以下なら正解!
解答数が6回で不正解なら、今日は解答上限のお知らせ
解答が7回目以降なら締め切りの返信をするよ
answer = list(self.answer)
a = []
for n in range(self.num):
if self.reply[n] == answer[n]:
a.append("2")
answer[n] = "a"
else:
a.append("0")
for n in range(self.num):
if a[n] == "0":
if self.reply[n] in answer:
pos = answer.index(self.reply[n])
a[n] = "1"
answer[pos] = "a"
react = "".join(a)
【問題点】
ここはたくさん考えたよ~
🟩の条件は完全一致だから良いけど、🟨が難しかったぁ(∩´﹏`∩)
「完全一致じゃないけど検索で引っかかる」のを🟨にするとね、
正解が「にしんそば」のとき、「ちらしずし」って答えると「⬜⬜🟨⬜🟨」になっちゃうの
本家のルールだと「⬜⬜🟨⬜⬜」になるはずだから、そこを実現するために工夫したよ
【解決法】
まず一回完全一致だけ探して、⬜🟩だけの状態にするよ。
そのとき正解の文字列から該当の文字を削除、"a"に置き換えておくよ
同様に🟨の調査をしたとき、その正解の中で引っかかった文字を"a"に置き換えるの!
こうすることで【問題点】の部分が解決したんだぁ
with open("wordle/answer.txt", mode='w', encoding="utf-8") as f:
f.write("")
f.close()
正解が出たから、正解ファイルを空にしておくよ~
自動実行
出来上がったら、Run.py、Automation.pyを自動で実行するバッチファイルを準備するよ。
タスクスケジューラで実行時間を決めたら完成~
センリはAutomation.pyを毎日13時に、run.batを常時(5分おき)動かしてるよ
ただ実行するだけでも良いんだけど、ウィンドウが毎回出てくるのはイヤだから最小化状態で実行してもらうね
@echo off
cd /d %~dp0
:最小化状態で実行する
if not "%X_MIMIMIZED%"=="1" (
set X_MIMIMIZED=1
start /min cmd /c,"%~0" %*
exit
)
cd C:\Users\...\Senri
python run.py
exit /b
下の方のrun.pyをAutomation.pyにしたファイルも準備してね
ステップ5「これからもよろしくね」
まだまだ改善点があるから精査したいねっ!
その1 wordleのロジック
wordleの解答チェックで、for文を二回使ってるけど、一回でする方法ないかなぁ?
answer = list(self.answer)
a = []
for n in range(self.num):
if self.reply[n] == answer[n]:
a.append("2")
answer[n] = "a"
else:
a.append("0")
for n in range(self.num):
if a[n] == "0":
if self.reply[n] in answer:
pos = answer.index(self.reply[n])
a[n] = "1"
answer[pos] = "a"
react = "".join(a)
その2 リストが少ない!
ごはんリストが少ないかなぁ
もっと未知の料理も増やしていきたいなっ!
その3 ひらがなにしか対応してない!
カタカナで答えちゃう人もいるから、対応できるようにしたいなぁ
元のファイルにカタカナも記入しておくか、カタカナ→ひらがな変換のコードを混ぜるかって感じかな?
その4 みんなの声
コードの間違い、改善案があったらコメントで指摘してくれると成長に繋がって嬉しいんだぁ
逐一修正していきたいから、どしどし指摘してね!
次回予告
大変っ! ラボノートが無くなっちゃったんだぁ
たくさん書いてたのに、どこで落としたんだろう……?
でもでも大丈夫、ラボの皆にも手伝ってもらってすぐに探し出すよ!