みなくんの日記

やる気が皆無で自由気ままに生きてる人のブログ

ブログの更新を忘れていました

相変わらずブログを更新するのを忘れる人です

ブログ書くのって難しくないですか?
人に語れるような出来事が毎日起きてないわけではないんでしょうけど、文字に起こすのが非常に難しい(何より面倒)
あと純粋に忙しすぎて精神的にも参ってることが多くて何も手がつかないのが現状かもしれない
せっかくブログあるんだからちょっとは書けよ…と自分をたたきながら、これからも気が向けば書いていきます…。

近況報告といきましょうか

無事に大学を卒業させていただき、そのまま大学院へ進学ということになりました。
さらに、縁あって新しく技術系のアルバイトを始めることになったので、新しくて刺激のある学生生活が始まったわけです。
そのおかげで忙しくなったわけですが 学校にいる間は楽しく過ごしています。
不思議なもので、自分がポンコツであるにも関わらず今まで降りかかってきたタスクを特段問題なく消化出来ています。
少しは成長出来ている、ということでしょうか。そういうことにしておきましょう。
人にアドバイスする立場になりつつあるので、そろそろポンコツから脱却できるよう、日々努力していく必要がありそうです。
大学でのお仕事を通じてより強くなれるよう頑張ります。

PCのこと

自宅で使っていたPC、ゲーミングPCなのですが、最近のゲームや特にVRではスペックが圧倒的に足りない…ということで、あちこちサイトを調べてPCの買い替えを本格的に検討していました。 んで、見つけたのがこちら。

f:id:minamint:20190617013106p:plain
月末祭で20万弱で購入できたゲーミングPC

たまたまFRONTIERさんに出会い、他店と比較してみると数万円規模で安かったのでこちらを購入!
せっかくよくなったし、VRもやりたいよね…ということで、最近話題になっているもの(のPCVR版)まで購入しちゃいました。
www.oculus.com そう、Oculus Rift Sです。VRの世界はすごい…と言われていたので、どうしても体験したくて。学生にとっては高すぎるお買い物でしたが、一切後悔はしていません。
実際に複数のゲームを体験してみたのですが、本当に高画質で、現実と錯覚してしまうほどです。実際のレビューは他に詳しくされている方がいるので割愛しますが、体験すると世界が変わりますよ!オススメです。 最新技術に触れ続ける…という自分の趣味、とても楽しいけど本当に金額面で苦労するので、困ったなあ…。

iPadのこと

これは3月の出来事になりますが、私がずっと使っていたiPad Air2くん、話題?のApple Pencilに対応していなかったということで、買い替えることにしました。
んで、当時まだ最新のやつが発売されていなかったので、第六世代のiPadか…いっそのことiPad Proか…と悩んでたんですが。

iPad Proを買いましたー!
一番の理由は、Apple Pencil第二世代対応ということ!ピタっとくっつくPencilが非常にスマートで、第一世代のような何とも言い難いもどかしさを感じなかったのが良かったのです。
そのために+5万円ほどしているわけですが
大学院での講義でノートをとるとき、オンラインで配布された資料を読んで、メモするとき…そういったノートテイキング用として、活用しています。
寝るときはYoutubeを垂れ流すデバイスになっていますが。もっと使い方がわかれば、クリエイティブな活動ができるのかも…?
良い使い方があったら教えてください。現状だとpromptでsshできるようにしたり、NASにアクセスしてiPadで書いたものを移動させたりはしてます。

そんなこんなで

なんだか物を買ってばかりな感じですが、これからも何かあれば日記ついでに残していけたらな…とは思ってます。
今、地味にRaspberry Piを使ってVPNと内向きDNSを作ってルータが提供する簡易NAS機能を利用してやろう…と企んで、あれこれやってたりするので、それを技術ブログ的な感じで残してもいいかもしれないですね!
ではでは、また気が向いたときに……

あーしんねん(新年のご挨拶)

2019年の幕開けです

皆さま、明けましておめでとうございます。
今年もどうぞよろしくお願いいたします。
年明け最初にやる事が日記を書く、という…。もっと他にすることないのかと思いましたが、Vtuberの方の配信を見ている中できることは数少ないので、ブログでご挨拶をと思いまして。
今年は平成が終わり、新たな元号へと変わる年!これからどんなことがあって、何が起こるのでしょうか?楽しみですね!

今年の抱負

今年の抱負。毎年よく分からない抱負を掲げてたりするんですが、地味にまじめに考えてたりします。
ずばり今年は…「常に前を向いて、毎日を楽しむ」!
後ろめたい気持ちになったり、諦めたくなったり、挑戦することに躊躇ってしまう。そんなときでも前を向いて、進んでみる。そして何より毎日楽しく生きないと意味がない!
ということで、今年はこれを抱負として掲げて頑張っていこうと思います。
それ以上にまず卒業して入学しないといけないんですけどね

因みに去年の抱負は?

去年は「冗長性をなくす」でした。全く達成できてないですね。難しすぎたようです。もう少し段階を踏んで頑張っていきます。

最後に

私にとって、今年もきっと忙しい1年になると思います。なので、疲れ果てて倒れてしまわないように…頑張っていきます! それでは皆さま、ハッピーハロウィン!

あーねんまつ(年末のご挨拶)

メリークリスマス失敗

ま た や ら か し た。
去年もやらなかった?これ。

minamint.hateblo.jp

ほれぇ!去年もやってる!クリスマスにブログ更新忘れ奴!うわあ!!!
というのはさておいて、またまた色々手遅れになってしまってるんですが、今年も1年色々あって大変でしたねー。お疲れ様でございました。
私も配属,退社,転職,ゼミ,研究,飲み会とあらゆる所で初体験をして、多くのことを学んで、仲間がいっぱい増えて、本当に濃い1年でした。
来年からも働きたくない侍である私は学生なので,学生特権である自由を利用してあれこれ挑戦してやろうと思ってます。
特に先輩から得たものというのは本当にデカかった。同期からも様々なアドバイスをもらったし、感謝してもしきれないです。
私に関わって色々とサポートしてくれた皆さん、本当にありがとうございました。来年もどうぞよろしくお願いいたします。
来年こそはコンスタントにブログ更新できたらいいなーとか思ってたりしますが、特段私の人生において筆を執るほどの出来事って起こらないことが多いので…。 来年からは今までそんなに経験のない「後輩」という存在が現れることになります(もちろん卒業できれば、だけれども)。失望されないように頑張ります。頼れる仲間と共に、自分も頼られる存在にならねば。
あまり長く書いても仕方ない気がするので今年はこの辺で締めさせていただきます。

みなさま、よいお年をお迎えください!ハッピーバレンタイン!

あれからかなりの月日が経ちました

題名だけ見たら「付き合ってから~」とか「別れてから~」とか恋愛関連の内容を想定した?残念、その話はもう終わっちゃいました。

今回はこれminamint.hateblo.jpを投稿してからかなり経ったので、個人的にどうなのかをここでまとめておこうと思って。

長文だけど許して、それだけ書きたいことあるの

使ってみた感想

正直な話、買って良かったなと思います。別にスポーツするわけじゃないし、Bluetoothイヤホンなんて持ってないからApple Watchで音楽聴くこともないし。私には絶対要らないデバイスだろ~と思いながら、ただ純粋な興味で買っただけなんですが…。なんというか、手放しても良いけど手放すと少し物寂しいな~と感じる程に愛着のあるものになってしまったというか…。ちゃっかり生活の一部になってるんですよね。
別になくてもいいと思います。なくても、特に困らないし。腕時計ならアナログでお気に入りの奴持ってるので、それで十分だし。でも、Apple Watchの方を着けていたくなる。
こんな感じです、今は。

良いな、と思ったポイント

多分某Youtuberの方がレビューされてたコメントとほぼ一緒になるかもしれませんが、私自身も本当に共感してたことなので許して!
あと、他社のスマートウォッチにも同じのあるぞ、とかあるかもだけど、使った事ないからそこは何ともいえません!ごめん!

重要じゃないけど「あると便利」な機能が多い

一番の要因はこれです。基本の「時計機能」はもちろんのこと、

  • 各種アプリからの通知
  • タイマー機能
  • 現在気温、天気予報のワンタッチ表示
  • 豪雨予報(Yahooさんのアプリより)
  • 目覚まし機能
  • Apple Pay(Suica)
  • 懐中電灯機能
  • 電話機能

といった感じで、自分にとって結構あると有難い機能が付いてるんですねー。
何度も言うけど別に要らないんですよ。この機能群は手元に常にあるiPhoneから見ればいいし。Watchくん、iPhoneと距離離れるとただの腕時計(とアクティビティ記録装置)になるから単独で使えないし(セルラーモデルなら使える)。
でも、それが腕時計というデバイスにちゃっかり入ってる。それだけで、何か近未来って感じがするし、結構便利。
故に手放し難いデバイスになっちゃったんですねー。贅沢を知ると前に戻れなくなる的なアレだね、これは…。
どう便利やねん、ってことで軽くまとめてみます。

各種アプリからの通知

正直ね、これが一番便利なんですよ。
例えばslackの通知。重要な連絡がよく流れてくるんですが、それがWatchくんで通知を受け取れるので、歩いていようが、運転中の信号待ちだろうが(あまり見るものじゃないけど)、今日記を書いているようにPCで作業中だろうが、手元の腕時計がブルブルッと震えることで確認できる。パッと腕時計を見るだけで通知内容が確認できて、今日の会議が少し早くなったことをすぐ知れる。
凄いのは「iPhoneを取り出す必要がない」ということ。iPhoneを手に取って確認する手間が面倒だとは言わないけど、腕時計をチラ見するだけで内容が確認できるのって凄く効率的なんですよ。重要度が高ければ返信すればいいし、低ければ無視でいい。ゲームの通知とかをiPhoneでしか受け取らないようにすることで、Watchくんからの通知はSNS関連になるので無駄な通知(?)に時間を取られなくなる。
さらには

  • iPhoneを少し遠く(離れたテーブルの上など)に置いてる時
  • iPhoneをポケットに入れてて、取り出すのが大変な時
  • 誰かとの会話中(特にミーティングの場において)

こういう時に便利なんだな~これが!
これは使ってみるまで「ホーン、便利だけど別にiPhoneで見るの手間じゃないし要らんわ、ゎら」って思ってました。使ってみて初めて分かる凄さってやつだ。ありがたい…。

タイマー機能

超地味にありがたい機能。「ヘーイSiri!3分測って!(お湯入れながら」で3分計測。終わればWatch君が音と共に震えて教えてくれる。(消音モード中は震えるだけ)
これで美味しいラーメンが食べれる。iPhoneのHey,Siri機能?ああ、あれは講義中に暴発するから切ってるなあ…。

現在気温、天気予報のワンタッチ表示

これも超地味にありがたい機能。正直なところ、私の性格上アプリを入れてても天気予報見ないんですよ。テレビもつけてないので、より一層分からない。外に出て初めて、天気と気温が体感で分かる感じ?
それが時刻を見るついでに気温が分かるし、気温の所をタップするだけで天気も数時間先までは分かる(明日までは分かんないけど)。外に出る前に天気が分かるの、便利だなあって…。

豪雨予報

Yahooの雨お知らせアプリを入れると良いよって記事を以前見かけて、入れたんですが。これ便利なんですよね。あ!雨なんで帰ります!っていう言い訳に最適
雨の強さがなんとなく分かるので、「もう帰ろう」とか「早めに移動しておこう」とか、今後の行動の判断材料になるので有難い。
取り敢えず予報が来たら、豪雨予報時刻が過ぎるまで屋内退避して過ごすのがみなくん式の回避術。

目覚まし機能

iPhoneの目覚ましと連動してるので、寝てるときにもWatchくんを着けておけば、目覚ましが鳴る時に腕時計も同時に震えて起こしてくれます。この振動、こんな小柄な腕時計ながらに結構強めなので、案外目が覚める。Watchくんを持ってる他の方もこの機能のことを便利だと褒めてました。いつもお世話になっております…ありがとう、Watchくん…。

Apple Pay(Suica)

自販機の前、手ぶらな奴が一人。
おもむろに飲みたい商品のボタンを押す。所持金は0円。
Watchくんのサイドボタンをダブルクリック。そして自販機に近づける。
ピコーン、ガチャコン。飲み物を手に入れ、その場を立ち去る。
かっこいい…。(本当それだけ)

懐中電灯機能

バイト中に暗所で作業することがありました。そのときにWatchくんの懐中電灯機能が大活躍。そんなに明るくないんですが、狭い空間を照らすのには十分です。バイトの上司の方に「すげぇ…でも高いでしょ、俺には手が出せないなぁ」と、凄く羨ましそうに言われて少し気分が良かった…。
あと、夜間の道を照らしたり、夜間歩行中の歩行者アピールとしても使えます。でも、電池の消耗が早くなっちゃうのは仕方ないけど欠点かなーって。

電話機能

今日記書いてるこの瞬間に電話が鳴ったとして、携帯で出ると手が止まってしまう。でも、Watchくんで応答すれば、Watchくんに付いてるマイクとスピーカーで会話ができるので、作業の手を止める必要がなくなります。
地味に便利。iPhoneのスピーカー機能みたいなもんですけどね。音もそんなにデカくないので聴こえないことあるし。
あと、誰かと会話中に電話がかかってきたときに相手の番号が出るので出るべきか否かも判断できます。純粋にナンバーディスプレイ機能(って言うのか?)として便利。

イマイチ/不便だなと思う点

利点ばかりでべた褒めもいいんですが、ここもまとめておきたい。

電池の持ちは良いけど…

はっきり言ってあまり問題には感じない。けど、やっぱり充電しないと使えなくなっちゃうってのはどうしても不便に感じてしまうなーと。特にWatchくんを使って遊んでると電池の減りが結構早いところが不便。
風呂に入ってる時、寝るときに充電すれば別にいいんですけど…。もう少し電池持ってくれたらガンガン使えるのになーって思いました。
充電自体はもって2日なので、旅行先だと充電ケーブルをもっていかないといけないんですよね。もう少しその辺り改善してくれたら嬉しいなーって。ワガママですかね。

スピーカーの音量が小さい

これも仕方ないと言われたら納得する。けど、通知音が稀に聴こえないことがある。さらに言えば、Watchくん単体で電話できるよ!と言われてもBluetoothイヤホン利用前提になってるからなのかWatchくんのスピーカーで会話すると場所によっては聴こえないことが。もう少し大きくなってくれたらなー嬉しいなー(ワガママ)

アプリの数が少ない

基本機能で十分まかなえてるけど、アプリの数が相当少ない。Watchならではのアプリ…と言われても思いつかないので、それが原因なのかなーって思うんですが、もう少しあってもいいんじゃないかなって思う。それが残念。

あれこれ言ったけど

とにもかくにも、買った事に関して一切後悔してないし、むしろ買ってよかったと思ってます。何しろかっこいいし。最高!
もし気になってるわぁ、って人がいたときに参考にしてもらえたら、と思います。自分がレビューしてみたかっただけなんですが。
ではでは。

プログラムよ、とにかく動け ~4桁のヒット&ブローゲーム「4Numbers」を作ろう~その4

今まで作ってきたパーツを組み立て、メイン関数を作ってプログラムを完成させる総集編です!ここまで来れば、後は楽ちんですね!

今回の目標

  • [Chapter.4]「4Numbers」を完成させる
  • [Chapter.EX] タイマーの実装

部品(プログラム)を組み立てる→メイン関数を作る

過去3回分までで、以下のようなことをやってきましたね。

  • 正解の4桁の数字の生成
  • ユーザに4桁の数字を入力してもらう処理の実装
  • 正解桁とユーザの解答桁との比較

今回作成するゲームは、これらの機能を使うわけです。ということは、今までやってきたのは例えるならば「自動車の部品作り」であり、今回行う作業は「自動車の組み立て」なんですね。今まで苦労して作って来たものを良い感じに組み合わせ、ゲームとして完成させてしまいましょう!
ただし、ただ作った部品をくっつける…だけではうまくいきません。部品を部品として使えるようにしてあげる必要があります。
その準備は実は今までの回でやっていたのですが、気付いていましたか?

クラス・メソッド→オブジェクト指向

今まで作成してきたプログラムはすべて、クラスを作成していましたよね。
第2回のユーザ入力プログラムをもう一度見返してみましょう。(クラスが分からん…という人は調べてみてください)

class input_number:
    def input_num(self):
        while True: #4桁の数字かGive upが入力されるまでループ処理
            try:
                num=input("正解だと思う正の数字4桁を入力してください:")
                if len(num)==4: #4桁であった場合
                    check=int(num) #それが文字列であった場合、ここでValueErrorに飛ばす
                    if num[0]=="-":
                        raise ValueError #入っていたらそれはエラーとして処理
                    return num #何もなければユーザの入力を返り値にする
                else: #4桁以上の数字であった場合
                    raise ValueError
            except ValueError: #文字列が入力された場合(今回は4桁以上の数字もこのエラー処理になる)
                if num=="Give up": #Give upと入力された場合
                    print("諦めます。また挑戦してくださいね!")
                    exit()
                else: #他の文字列もしくは4桁以上の数字が入力された場合
                    print("4桁の正の数字かGive upのみを入力してください。")
    def start_init(self):
        input("開始するにはEnterキーを押してください...")

ここでは、input_numberクラスを作成して、その中でユーザの入力を受け付けるinput_num()と、「開始するにはEnterキーを押してください…」と表示してEnterキーの入力を促すstart_init()メソッドを定義しています。
このように、クラスの中に処理を定義することでユーザ入力を受け付けたければinput_num()メソッドを使えばよいなど、新しいプログラムに組み込む際に組み込む側の人が詳細な処理内容を理解することなく部品として使えるようになるんですね。
このように操作手順よりも操作対象に重点を置いた考え方を「オブジェクト指向」と言います。
私もこの考え方を学んだのは最近のことで、説明に間違いがあるかもしれないので…もっとよく知りたい人は「オブジェクト指向」で調べてみてください!(丸投げ)

長々と説明しましたが、今まで作成してきたプログラムはそれぞれ
* 正解桁生成処理→ create_randomクラス
* ユーザ入力処理→ input_numberクラス
* 正解桁とユーザ桁比較処理→compare_numberクラス
と定義し、使える状態にしています。あとはこれを利用して、メイン関数を作っていきましょう!

部品を組み合わせてゲームを作る(メイン関数の作成)

ではここからメイン関数を作成して、完成させていきます。
先ほどまで述べてきたように、今まで作ったものを組み合わせて…ドーンと作ります。作ったものが以下の通り。
なお、「デバッグ用」とコメントされたものはあくまで自分がテストとして使うものであり、実際のプログラムコードには使わないため予めコメントアウトしています。コメントアウトしなかった場合、正解桁が表示されてしまうので…ゲームにならないです。

import random_number #ランダム生成クラス
import input_user2 #ユーザー入力クラス
import compare #正解との比較クラス
import time #timeモジュール

Answer=random_number.create_random() #正解桁生成クラスのインスタンス化
Ans=Answer.create_num() #正解桁生成
#print(Ans) #デバッグ用
user=input_user2.input_number() #ユーザー入力クラスのインスタンス化
compare=compare.compare_number() #比較クラスのインスタンス化
user.start_init() #始めるには…
End=False #End変数の初期化
Start = time.time() #計測開始
while End==False: #継続条件:EndがFalseである間 終了条件:EndがTrue(Falseでなくなる)のとき
    Num=user.input_num()
    #print(Num,Ans) #デバッグ用
    End=compare.cmp_num(Num,str(Ans)) 
Stop = time.time() #計測終了
print("正解するまでにかかった時間:{0}秒".format(round(Stop-Start,2)))
print("また挑戦してくださいね!")

多分正解桁生成プログラムの次ぐらいにコード数が少ないプログラムなのでは…?
パッと見たとき、「これだけでゲームできるのかよ!」と思ってしまうほどですね。
コードを見てもらえばわかるように、importで今まで作成したパーツを読み込んできて、それを適宜必要なタイミングで利用している…といった感じです。何をしているのか、何となくわかるのではないでしょうか。
でもただ部品を並べただけではなく、少し手間を加えたり追加機能を付けたりしているので順に説明していくことにしましょう。

クラスの呼び出しとインスタンス

まずメイン関数の1~4行目に書いてある「import」ですが、これはモジュールや他プログラムを呼び出すのに使用しています。
4行目に関しては後々使うことになるtimeモジュールです。現在時刻の取得などに使える、便利なモノです。それ以外の3行はそれぞれのプログラムを呼び出している感じですね。
メイン関数でほかのプログラムを呼び出す際はこれでいいのですが、注意すべきことが一つ。
それは、メインプログラムとimportで呼び出したプログラムは同じディレクトリ内に入っている必要があるということです。
設定したら違うディレクトリでも行けたかもしれませんが…同一ディレクトリ内ですることをお勧めします(何となく面倒そうなので)。
そして、importで呼び出した後に以下のコードが載っていると思います。

Answer=random_number.create_random() #正解桁生成クラスのインスタンス化
…
user=input_user2.input_number() #ユーザー入力クラスのインスタンス化
compare=compare.compare_number() #比較クラスのインスタンス化

これがインスタンスです。 クラスは言わば「仕様書」であり、インスタンスは「実体」になります。今回のコードでいえば「user」という名前のインスタンス(実体/部品)を、inout_user2.pyに記載されているinput_numberというクラス(仕様書)をもとに作成した、といった意味になります。
今回は3つのプログラムを組み込んで一つのプログラムにするので、インスタンスは3つ、それぞれ違うものが必要になります。よって、Answerとuserとcompareというインスタンスを用意しているんですね。

プログラムの利用…手順通りに使っていく

インスタンスの作成によりパーツができたので、あとは利用していくだけになります。
使い方は以下のような感じ。

Ans=Answer.create_num() #正解桁生成

何と言いますか…私たちが無意識に「print("Hello, Python world!")」と打って画面上に"Hello, Python world!"を表示させているときと同じ感覚です。これは正解桁を生成してくれるメソッドで、変数に代入させれば正解桁を得られる…という仕様さえ知っていれば、これは簡単にかけると思います。
あのような書き方で、正解桁生成、スタートコール、ユーザ入力処理、正解比較…を行っていきます。
スタートコール担当は"user.start_init()"です。これを実行すれば「開始するには…」という文章が出てEnterキーの入力を促します。
ユーザ入力処理担当は"user.input_num()"です。これを実行し、返り値を変数に代入させることでユーザが入力した4桁が得られます。
正解比較担当は"compare.cmp_num(Num,str(Ans))"です。引数としてユーザ入力桁のNumと正解桁をString型に変換したstr(Ans)を与え、返り値を変数に代入させることでTrueかFalseを得ることができます。
この順番で並べるだけで、基本的にはゲームが成立するのですが…。
ユーザ入力処理と正解比較処理はクリアするまでループさせる必要があり、ループ判定条件として正解比較処理の返り値であるTrueとFalseが使えるので、この2処理をwhileループで挟んでいるわけなんですね。

while End==False: #継続条件:EndがFalseである間 終了条件:EndがTrue(Falseでなくなる)のとき
    Num=user.input_num()
    #print(Num,Ans) #デバッグ用
    End=compare.cmp_num(Num,str(Ans)) 

そして、whileループを抜ける=ユーザが正解したということで、最後に「正解です!」と文字を表示させてこのプログラムを終了するようにしています。これで、ゲームとして動作するようになりました!

追加機能「正解するまでにかかった時間」の実装

このままでも十分楽しいゲームだと思うのですが、やはりやり込み要素は欲しいところ。
というわけで、正解するまでにかかった時間を計測して表示させる機能をつけましょう。
そこで登場するのが先ほどimportで取り込んだtimeモジュールです。
「time.time()」とすることで現在時刻を取得することができます。これを用いて、ゲーム開始時刻をStart変数に格納、終了時刻をStop変数に格納して、この差を用いて正解するまでにかかった時間を求めて表示させます。

print("正解するまでにかかった時間:{0}秒".format(round(Stop-Start,2)))

解答にかかった時間=(終了時刻)-(開始時刻) で求められますが、あまりに細かい時間を表示させても意味がないので、無難に小数点第2位まで表示させるために四捨五入を行ってくれるround()関数を利用しています。
print()関数にformatが使われていますね。これは文字列に変数を組み込む際に使う形式です。print("文字列{0}",format(変数))とすることで、{0}内にformat()内の変数を組み込むことができます。

実際に動かしてみる

さあ、プログラムが完成しました!実際に起動して動作を試してみましょう。
プログラムを実行するには、以下のようにコマンドを打つ必要があります。

$ python3 main.py

python2系だと恐らく動きません。(3系で今までプログラムを作成してきたため)
で、遊んでみた結果がこちら。

開始するにはEnterキーを押してください...
正解だと思う正の数字4桁を入力してください:1234
HIT= 1 BLOW= 1
正解だと思う正の数字4桁を入力してください:1111
HIT= 0 BLOW= 0
正解だと思う正の数字4桁を入力してください:2222
HIT= 0 BLOW= 0
正解だと思う正の数字4桁を入力してください:333
4桁の正の数字かGive upのみを入力してください。
正解だと思う正の数字4桁を入力してください:3333
HIT= 1 BLOW= 0
正解だと思う正の数字4桁を入力してください:4111
HIT= 0 BLOW= 1
正解だと思う正の数字4桁を入力してください:1411
HIT= 0 BLOW= 1
正解だと思う正の数字4桁を入力してください:3111
HIT= 0 BLOW= 1
正解だと思う正の数字4桁を入力してください:1311
HIT= 1 BLOW= 0
正解だと思う正の数字4桁を入力してください:5678
HIT= 0 BLOW= 2
正解だと思う正の数字4桁を入力してください:5555
HIT= 0 BLOW= 0
正解だと思う正の数字4桁を入力してください:6666
HIT= 0 BLOW= 0
正解だと思う正の数字4桁を入力してください:7384
正解です!
正解するまでにかかった時間:66.03秒
また挑戦してくださいね!

難しい…!
しかし、特に問題もなく動いていることが分かりますね。
ちなみに、変なことばかりをするユーザになりきってもう一度遊んでみました…。

開始するにはEnterキーを押してください...aaaaaa
正解だと思う正の数字4桁を入力してください:dete
4桁の正の数字かGive upのみを入力してください。
正解だと思う正の数字4桁を入力してください:hoge
4桁の正の数字かGive upのみを入力してください。
正解だと思う正の数字4桁を入力してください:ギブアップ
4桁の正の数字かGive upのみを入力してください。
正解だと思う正の数字4桁を入力してください:GiGive up
4桁の正の数字かGive upのみを入力してください。
正解だと思う正の数字4桁を入力してください:111122
4桁の正の数字かGive upのみを入力してください。
正解だと思う正の数字4桁を入力してください:djawjdawlpdmwapdaw@da
4桁の正の数字かGive upのみを入力してください。
正解だと思う正の数字4桁を入力してください:1234
HIT= 1 BLOW= 1
正解だと思う正の数字4桁を入力してください:nwopdawpodnapodaw
4桁の正の数字かGive upのみを入力してください。
正解だと思う正の数字4桁を入力してください:amdwapampoa
4桁の正の数字かGive upのみを入力してください。
正解だと思う正の数字4桁を入力してください:Give up
諦めます。また挑戦してくださいね!

Enterキーを押せと言っているのに"aaaaa"と入力する、日本語も入れる、デタラメを入れる、数字が4桁以上…など、あらゆる動作を盛り込んでみましたがすべて弾かれていますね。問題なく例外処理ができている証拠です。

今後の課題(改善検討案)

このゲーム「4Numbers」を最大限に楽しむコツとしては、「1111」などをデタラメに入れて正解の4つの数字を当てて行くのではなく「いかに手数を少なく、かつ早く解答まで持っていけるか」にあります。
よって、今後検討すべき追加要素の一つとして「解答までの手数を表示する」というのも良いかもしれませんね!
さらに、現在はpython3で.pyファイルを指定してゲームを起動していますが、世の中のゲームというのは.「4Numbers.exe」といった実行形式のファイルになっているものです。なので実行形式にしてダブルクリックで起動できるようにする、というのも検討してみても良いかもしれません!

まとめ

  • 今まで作ったプログラムを組み合わせてゲームを作成できた!
  • ゲームのやり込み要素としてタイマー機能を実装することに成功した

今まで長々とやってきましたが、ここで【プログラムよ、とにかく動け ~4桁のヒット&ブローゲーム「4Numbers」を作ろう~】は終了になります。お疲れさまでした!最後までご覧いただいた皆様、ありがとうございました!
また、なんとかブログとして形に残せた自分を褒めたいと思います。よく頑張った、自分。

もしかしたらEX編で何かするかもしれません(改善検討案を実装する、など)。その時はどうぞよろしくお願いします!
以上、みなくんの「とにかく動け!プログラミング講座」でした!

Apple Watchデビュー

普段iPhoneを使っている私にとって、新しい腕時計型デバイスであるApple Watchは凄く気になっていました。
iPhoneと連携することで通知を素早く確認できたり、Apple Payで便利に支払いができたり…メリットが多くあるようで、腕時計なのにあれこれ出来るって近未来感凄いですよね。
友人が随分前に購入して着けはじめ、便利だと聞いていたので欲しいなと思っていたのですが…決して安いものではないので、1年ほど悩んでいたわけです。
で…遂に今日。

手に入れちゃったんですねー、Apple Watch
実は何度か買おうと思ってたんですが、学生には決して安い金額ではなかったので…機能性についてネットで見てても、あまりいい声を聞かなかった(自分にとって魅力的と感じるものが少なかった)ので、購入とまでは行かなかったのです。
でも使わないと便利かどうかも分からないですし、友人も使いやすそうにしていたので…思い切ってみました。
これからこのApple Watchと共に暮らす訳ですが、少しでも便利で、もっと効率的で…豊かになってくれるといいですね。(買って良かった、と思えたらいいな…)
便利なApple Watchの使い方とか探してみなきゃ。
そんなこんなで、報告的な日記でした。

プログラムよ、とにかく動け ~4桁のヒット&ブローゲーム「4Numbers」を作ろう~その3

更新が大幅に遅れました。私がサボっていたせいです。許して。

今回の目標

  • [Chapter.3] 正解桁との比較処理の実装

[Chapter.3]正解桁との比較処理

前回までの処理で「ユーザが正解だと思う4桁の数字」を取得できるようになったところで、Chapter.1で実装した正解の4桁との比較処理を行いましょう。
あれこれ説明しようかと悩んだのですが、これは実際にコードを見てもらって解説を加えた方が読みやすいかなと思ったのでいきなりコードを載せたいと思います。

class compare_number:
    def cmp_num(self,number,answer):
        hit = 0
        blow = 0 #ヒット・ブロー数
        if(answer == number): #完全ヒットであった場合
            print("正解です!")
            return True #ループ終了の合図
        else: #違う場合
            for i in range(4):
                if(answer[i] == number[i]): #まず部分ヒットかどうか調べる
                    hit += 1
                else: #部分ヒットではなかった場合
                    j=0
                    while(j<4):
                        if(i == j): #部分ヒット判定済箇所は除外するためjをカウントアップ
                            j += 1
                        if(j == 4): #カウントアップによるセグメンテーションフォルトの回避
                            break
                        if(answer[i] == number[j]):#ブローを発見した場合
                            blow += 1
                            break
                        j += 1
        print("HIT=", hit,"BLOW=",blow) #結果表示
        return False #ループ継続の合図

プログラムの流れを簡単に示します。

  • hit=ヒット数,blow=ブロー数として変数を設定
  • 以下に示す手順に従って判定処理を行う
    (1) 正解であった場合
     - 「正解です!」と表示してゲーム終了フラグを「True(終了)」として処理終了
    (2) 不正解であった場合
     - 条件(1桁目が部分ヒットであるか)→部分ヒットの場合は変数hitをカウントアップして2桁目を見る
     - 1桁目が部分ヒットではない→whileループによるブロー処理開始
     - ブロー処理が終了→ヒット数とブロー数を表示、ゲーム終了フラグを「False(継続)」として処理終了

流れとしては実に簡単ではありますが、もう少し具体的な処理についてみていくことにしましょう。

ヒット・ブローをどうやって判定していくか

正解?不正解?

そもそもユーザが導き出した答えが正解かどうか、これはもちろん最初に判断すべきことだと思います。コードでは以下の部分になりますね。

if(answer == number): #完全ヒットであった場合
    print("正解です!")
    return True #ループ終了の合図

answer=機械が出した数字、number=ユーザが出した数字 になっています。つまりこの条件は「機械が出した答え=ユーザが出した答え(完全一致)」となる時に処理される内容なんですね。
return文で「True」を返り値としています。これは設計図に書いた「3.正解桁との比較」から「2.ユーザが任意の4桁を入力」に戻る(ループする)ために利用する返り値で

  • Trueならループしない(ゲーム終了)
  • Falseならループする(ゲーム継続)

という仕様になっています。(これは次回のプログラミング講座「メイン関数を作ってゲームを完成させよう!」で使う値になります)
ちなみに不正解であれば完全一致とはならないので、この条件内の処理は行われません。

不正解→部分ヒット?ブロー?

機械が出した答えと違った時、このゲームではヒントとして「部分ヒット数=2、ブロー数=1」のような情報を提示するため、その判定処理が必要になります。一番今回で難しいところはここでしょうね。今回実装したアルゴリズムもまだ改善できるのかな…などまだ悩みどころは多いのですが、とりあえず今回は動いているので良しとします。
ブロー処理の具体的な処理の流れを、実例とコードを用いて説明していきましょう。見ただけで大体分かるわ、って人はここから少し長いので次の章へ進んでください。

(例) 正解=1234でユーザの答え=2537の場合(HIT=1 BLOW=1)
(1) 1桁目の比較(正解 "1" ユーザ "2")→部分ヒットではないのでブローがあるか調べる(if文の条件が満たされないためif文中処理は実行されない)
コード(answer[i]=1,number[i]=2,i=0)

for i in range(4): # i=0,1,2,3の順で増加
    if(answer[i] == number[i]): #まず部分ヒットがあるかどうか調べる(条件を今回は満たさない)
        hit += 1 #この処理は行われない!

(2) 正解1桁目(桁変数は"i")とユーザ1桁目(桁変数は"j")のブロー探索→既にi=j=0のパターンは部分ヒットの際に比較済みなのでユーザ2桁目から探索することにする(jをインクリメントする)
(i=0,j=0 "j"はユーザが答えた数字を格納する配列number[]に用いる変数)

j=0
while(j<4): 
    if(i == j): #部分ヒット判定済箇所は除外するためjをカウントアップ
        j += 1

(3) 1桁目「1」と2桁目「5」の比較→ブローではない→if文「ブローを発見した場合」の処理は行わず、ユーザ3桁目の比較に移る(jをインクリメント)

if(answer[i] == number[j]):#ブローを発見した場合
    blow += 1
    break
j += 1 #←この処理だけを行う!

(4) (3)を最後まで繰り返す→ブローは存在しなかった

(5) 正解の2桁目の比較(answer[i]=2 number[i]=5 i=1)→部分ヒットではないのでブローがあるか調べる
(6) i=1,j=0のとき…answer[i]=2 number[j]=2となり条件を満たす!→blowをインクリメントする

if(answer[i] == number[j]):#ブローを発見した!
    blow += 1 #blow=1にする
    break #これ以上他の桁と比較する必要はないのでjのwhileループを抜ける
j += 1 

(7) これ以上他の桁と比較する必要はないのでjのwhileループを抜け、正解の3桁目の比較へ移る
(8) 正解の3桁目の比較(answer[i]=3 number[i]=3 i=2)→部分ヒットなのでhitをインクリメント
(9) 部分ヒットしたためブローチェックの必要なし。次の桁の比較に移る
(10) 正解の4桁目の比較→部分ヒットなし→ブローチェック→ブローなし
(11) ヒット数とブロー数を表示、返り値をFalseとして処理終了

ちなみに、変数"i"のforループで正解桁を動かし、変数"j"のwhileループでユーザ桁を動かすようにすることで、以下の動きを実現しています。

  • whileループを抜ける→ブローチェックの終了
  • forループを抜ける→正解桁との比較終了

また、変数"j"の値をforループではなくwhileループにしているのには訳があります。
変数"j"のforループ中に変数"j"の値を累計代入しても、ループ時に変数"j"の値は変更されるという仕様が存在したためです。この仕様が適用されていると、変数"j"をインクリメントしても次のforループで値が上書きされてしまうので、比較処理ができなくなるんです。だからwhileループを用いたわけです。

言葉じゃ見にくいわ!って人へ

先ほどの(1)~(11)までの動きが説明が下手だから分からない…という人はこちらの図を参考にしてみてください。
f:id:minamint:20180418225825p:plain

プログラムの実行結果

最初に提示したプログラムの下に以下を加えて実行してみます。

#---test seciton---

hoge=compare_number()
print(hoge.cmp_num("2537","1234")) #hit=1,blow=1
print(hoge.cmp_num("1235","1234")) #hit=3,blow=0
print(hoge.cmp_num("4321","1234")) #hit=0,blow=4
print(hoge.cmp_num("1234","1234")) #hit=4

#---test end----

実行結果は以下の通り。

HIT= 1 BLOW= 1
False
HIT= 3 BLOW= 0
False
HIT= 0 BLOW= 4
False
正解です!
True

正しく動作していることが分かりますね。また、hit数とblow数が重複していないということも確認できます。でも少し心残りですね…例題ではユーザが真面目な方なので、重複しない4桁の数字を入力してくれているのですが…。

「1111」がユーザの解答だった時、プログラムはどう動く?

テスト実行だと私が期待する値を入力値に設定できるのですが…実際に他の人に動かしてもらう際、そのユーザは私の期待通りに動いてくれるとは限りません(別に信頼してないわけじゃないですよ!)。そのため、予想される入力値とは全然違った値が入力されることもあります。
「-123」や「aaaa」などは前回の入力処理で受け付けないようにできたのですが、まだもうひとパターンだけ怪しいものがあります。
それは「1111」といったゾロ目や「1212」といった数字が重複している4桁の場合。
恐らく前回のプログラムを読んだ方は疑問に思っていたのではないでしょうか。
で、この重複パターンを入力した際に今回作成した比較プログラムがどういった動きをするのか…少し考えてみましょう。
とはいっても考えるより行動した方が早い、ということでtest sectionを以下のように書き換えて実行してみましょう!

#---test seciton---

hoge=compare_number()
print(hoge.cmp_num("2525","1234")) #hit=0,blow=1 2がblow、しかも2が重複している。
print(hoge.cmp_num("1212","1234")) #hit=2,blow=0 "12"がhitだが、後ろの12もblowになってしまう…?
print(hoge.cmp_num("4422","1234")) #hit=0,blow=2 4と2がblow、でも両方重複している。2と4が解答にあると分かってれば使える位置特定手段。
print(hoge.cmp_num("2244","1234")) #hit=2,blow=0 さっきの逆。これで2と4がどちらにあるか分かるが、大まかにしか分からないのであまり良い手段とも言えない。
print(hoge.cmp_num("1111","1234")) #hit=1,blow=0 全部1。その桁が正解に含まれるかどうかを調べるのに使える戦法だったりする。ズルいけどアリ。

#---test end----

気になる実行結果はこちら…

HIT= 0 BLOW= 1
False
HIT= 2 BLOW= 0
False
HIT= 0 BLOW= 2
False
HIT= 2 BLOW= 0
False
HIT= 1 BLOW= 0
False

なんと!予想通りの結果になっている…!
それもそのはず。処理中に行った以下の動作が、重複カウントを防いでくれてたんですね。
* 最初に部分ヒットか調べる→ヒットしていれば次の正解桁の比較を開始してブロー処理を行わないので、正解桁以外にその数字が書いてあっても判定されない * ブローを発見したら次の正解桁との比較に移る→ブローの重複カウントが行われない * 部分ヒットで調べたユーザ桁はインクリメントでスキップ→ヒット・ブローの重複カウントが行われない 実装の際はここまでの配慮をしないとユーザの動きに対応できないんですね…簡単そうなゲームなのに、実は難しかったわけだ…。

まとめ

  • 正解桁との比較処理の実装ができた
  • 重複した数字との比較でも正しい動作をすることが確認できた

次回で最後となります、メイン関数の実装・プログラムの完成編です!

補足(whileとforループの使い分けについて)

変数"j"のforループ中に変数"j"の値を累計代入しても、ループ時に変数"j"の値は変更されるという仕様について、実際にどうなってしまうのかをインタプリタ上でテストして検証してみます。

>>> for i in range(4):
...     print("for:",i)
...     i=i+2
...     print("i+2=",i)
...     print(" ")
...

実行結果はこちら。

for: 0
i+2= 2

for: 1
i+2= 3

for: 2
i+2= 4

for: 3
i+2= 5

といった具合に、(forでカウントされた値)+2になっている&forループの値が演算後の値になっていないことが分かります。恐らくループする度に変数"i"にrange()の値が代入されていくから演算後の値が上書きされているのでは…。
これのせいで、今回の処理だと変数"j"がforループの時に正しく処理してくれないというわけです。よって、whileループを今回は用いることにしました。

Twitter依存な私はタスクもリプで教えてもらう

目次

背景

  • とにかく面倒臭がり
  • 忘れっぽい
    こんな性格の男が悩んでいることが一つある。それは「タスク管理が面倒すぎる(タスクを確認することすら忘れる)」ということ。
    もっと簡単に予定やタスクが追加できて、しかも向こうから「今日これがあるよ!」と通知してくれればよいのに。
    そこで、今回自分の愛用ツールをうまく利用したら便利にならないかと考え、こんなアイデアが浮かんだわけです。 「そうだ、Twitterで全部管理できたら楽じゃん!」と。
    目次に戻る

ゴール

  • Twitterでツイートした特定の内容を、明日リプで通知してもらう
  • Google home くんに「明日は~がある」と言えば、明日リプで通知してくれる
    目次に戻る

    なぜTwitterなのか

    LINEでもいいじゃないか、LINEならIFTTTのNotifyで通知できるわけだし。
    わかる。でもTwitterの方が開くから目につきやすいんだよ。だから私はTwitterがいい。
    目次に戻る

Twitterでタスク管理を行う

  • Twitterでツイートした特定の内容を、明日リプで通知してもらう

    理想

    今日:「#明日通知して 図書館の本を返す」とツイート(タスク追加)
    明日:「今日のタスク: 図書館の本を返す」とリプが飛んでくる(本日のタスクを通知)
    目次に戻る

    実装に使うもの

  • IFTTT (一番使うもの)
  • Twitterアカウント2つ (リプを送ってくれる奴、リプを受け取る奴)
  • Googleカレンダー (タスク管理に使う)
    目次に戻る

    実装してみよう

    この機能を実現するには、以下のような動きをする必要があるわけですね。

  • まずツイートを検知(#(ハッシュタグ)がキーワード)
  • ツイート内容をタスクとして保存(カレンダーに登録する)
  • 指定日時になったらリプを飛ばしてもらう (カレンダーから情報取得)

    なぜカレンダーでタスク管理をするのか。それは簡単で、IFTTTならGoogle カレンダーを使うと「いつイベントが始まるか」というのを指定でき、イベント開始時にその情報を用いてリプを飛ばすことが出来るからです。
    他にもいいのがあればそっちを使ったんだろうけど、サーっと調べて簡単だと思ったのがこっちだったので今回はこういう方針で実装することに。
    目次に戻る

    まずはIFTTTの設定を

    さまざまなサービスが連携できる「IFTTT(イフト)」の使い方を参考にサインアップ。使い方もここで学習しました。 IF ●● Then ■■ 「もし●すれば、■をする」という、一連の命令を簡単に作成することができます。例えば、「もし明日が雨なら、LINEに通知する」といった感じに。これはとても直感的にできるので便利ですね。プログラミング不要というのが私にとって嬉しかったです。
    目次に戻る

    TwitterからGoogle カレンダーに

    ここからは実際の画像と共に、具体的な実装を行っていきましょう。 まずはNew Appletから「this」を選択。今回「this」(トリガー)はTwitter、「that」(アクション)はGoogleカレンダーになります。
    thisでTwitterを選択し、「New tweet by you with hashtag」を選択しましょう。
    これは特定のハッシュタグ付きツイートを自分がしたらそれがトリガーになるというものです。
    まずは「#明日通知して」のタグをトリガーにして、設定しましょう。これでタグ付きツイートが送信されるとこのコマンドが動き出すことになります。

    f:id:minamint:20180214050200p:plain
    特定のハッシュタグをトリガーにすると便利が良い

    次にthatでGoogleカレンダーを選択。時間指定をしたいので、「Create a detailed event」を選択してください。 ずらずらーっと項目が。それぞれ順番に設定していきましょう。

f:id:minamint:20180214050740p:plain

f:id:minamint:20180214050745p:plain
全て英語だけど、調べればある程度分かるので問題はない

  • Which calendar?
    「どのカレンダーに登録するの?」というもの。今回「タスク通知用」というカレンダーを作って登録してますが、実際にこうした方が便利だと思います(本来使ってるGoogleカレンダーが変なメモで汚れないから)。
    カレンダー作成はGoogleカレンダーから直接行ってください。そうすれば選択肢に出てくるはずです。
  • Start time
    開始時刻。この機能が欲しくてGoogleカレンダーを使ったんです。ここに図のように「Tomorrow, 8AM」と入れると、明日の朝8時に予定が入ります。後で通知させるのに重要になります。
  • End time
    終了時刻。ここは別に通知で使わないので適当に1時間後にしましょう。
  • All day?
    そのイベントが終日かどうかを設定。Google homeくんが終日スケジュールを読み上げてくれない事件があったので思わず「No」を選んでしまいました。何となくこれ「Yes」にするとイベント通知来なさそう(未検証)。
  • Title
    ここには「Add ingredient」から「TextNoHashtag」を選択しましょう。これは「ハッシュタグなしの本文」を出すもので、ツイートした内容そのものをタイトルにできるという優れもの。
    「#明日通知して 図書館の本を返す」と通知すれば、タイトル名は「図書館の本を返す」となるわけですね。
    あとの設定は好きなようにして構いません。というのも、通知に影響しないからです。完成したらCreate Actionでアクションを作ります。
    そしてこのIFTTTのアプレットのタイトル名を下図のように好きに弄ってあげれば…
    f:id:minamint:20180214053817p:plain
    セットが完成するわけですね。「On」になっている限りこのアプレットは動作するため、私のツイートを監視してくれていることになります。
    試しに「#明日通知して 家の用事を済ませる」とツイートしてみます。

    f:id:minamint:20180214192420p:plain
    呟いているのが鍵垢故にユーザ名やIDなどは隠しています

    そしてGoogleカレンダーには…
    f:id:minamint:20180214054458p:plain
    オレンジ色のイベントが「タスク通知用」のカレンダー

    きちんと反映されていますね。これでTwitterでタスクを追加することができるようになりました。
    目次に戻る

    GoogleカレンダーからTwitter

    お次は一番大事な「通知してもらう」という機能の実装です。
    「this」(トリガー)はGoogleカレンダー、「that」(アクション)はTwitterになります。さっきと逆ですね。
    Googleカレンダーの設定から。
    いっぱいトリガーの選択肢が出てきますが、「Any event starts」(任意のイベントが開始される時)を選択しましょう。以下の画面が出るはずです。
    f:id:minamint:20180214055336p:plain

  • Which calendar?
    さっきと同様、タスクを入れたところを選択しましょう。

  • Time before event starts
    何分前から通知するか。さっき「朝8時」に開始時刻を設定したので、別に0分でいいでしょう。もっと前にしたかったら最大45分前まで設定できます。
    これでトリガーのセットは完了。次にアクションのTwitterの設定をしましょう。
    アクションの選択肢は最も単純な「Post a tweet」を選択しましょう。
    f:id:minamint:20180214055838p:plain
    @{ユーザ名}にはちゃんとID名を入れましょう

    上図のように設定してあげれば…あとは指定時刻に通知がリプとして来るはずです。確認してみましょう。
    先ほどカレンダーに登録した「家の用事を済ませる」が来るのを確認してもいいんですが…待つのは面倒なので、「タスク通知用」のカレンダーに「テスト通知」という予定を登録して、この通知が来るかを試しましょう。
    f:id:minamint:20180214165715p:plain
    すぐ通知が来るよう、直前でセットしました。この通知が飛んできていることを確認してみます…
    f:id:minamint:20180214170433p:plain
    指定した形式通りに届いていることが確認できる

    ばっちりIFTTTを通じて届いていますね。これで向こうから通知してくれるようになったので、忘れることもなくなりそう!
    目次に戻る

Google homeくんにもタスク管理してもらう

  • Google home くんに「明日は~がある」と言えば、明日リプで通知してくれる

    理想

    私:「ねえ,Google。明日は『テストがある』」
    Google home miniくん:「わかりました。明日は『テストがある』ということをTwitterでお知らせします。」
    目次に戻る

    実装に使うもの

  • IFTTT (一番使うもの)
  • Google assistant (Google home miniくんの中身)
  • Googleカレンダー (タスク追加にはやっぱりこれ)
  • Google home (miniなども含む) (これがないと始まらない)
  • GoogleカレンダーからTwitterにで作成したアプレット 目次に戻る

    実装してみよう

    この機能実現のために必要な動作は以下の通り。

  • Google assistantに「明日は~」というフレーズを認識させる
  • 「(明日は)~」をGoogleカレンダー「タスク通知用」に登録する
  • Google assistantにその行動が完了したことを言わせる
    つまり、Google assistantが私の代わりにカレンダーに予定を入れてくれたらOKというわけです。
    というか、Google homeくんって実はGoogle assistantだったんですね…(今知った)。だから、assistantくんを弄ればGoogle homeくんも反映してくれると。これは使いこなせたらもっと便利になりそうな予感。
    目次に戻る

    Google assistantからGoogleカレンダー

    「this」(トリガー)がGoogle assistant 「that」(アクション)がGoogleカレンダーになります。
    いくつかあるトリガーの中から、「Say a phrase with a text ingredient」(テキストを含むフレーズを言った時)を選択しましょう。以下の項目が出てきます。順に設定していきましょう。
    f:id:minamint:20180214173031p:plain

  • What do you want to say?
    「何と言った時?」ここにはフレーズを入れます。今回認識させたいのは「明日は~」。なので、「明日は $ 」と入れましょう。「$」は予定の内容が入ります。これで音声をテキスト文に認識・変換してくれるわけです。
  • What's another way to say it? (optional)
    「他にどんなこと言ったら反応させようか?」別フレーズを登録したい場合はここに。今回は漢字での「明日は」と、Google homeくんがひらがなで認識したときのことを考えて「あしたは」を別フレーズに設定しています。必要かどうかは分かりません。
  • And another way? (optional)
    「他には?」3フレーズ目を入れたい人はここに。合言葉みたいなフレーズを入れて遊ぶと面白いかもしれない。
  • What do you want the Assistant to say in response?
    Google assistantくんはなんとお返事したら?」言わせたいことをここに。ここで「$」を入れると、自分が言った音声文が読み上げられるので確認しやすいです。
  • Language
    迷わず日本語を選択。
    次にアクション側のGoogleカレンダーの設定…なんですが、実はこれ、Twitterでやった設定(TwitterからGoogle カレンダーに)とほとんど変わらないんです。
    変わるのはTitleの項目だけ。ここで、「Add ingredient」を押して「Text Field」を選択しましょう。これで「$」の内容がタイトル名になります。
    で、設定が終わったら名前を決めて保存するだけ…。これで、Google homeくんに話しかけるとカレンダーに予定を追加してくれるわけです。実際の動作をマイアクティビティの会話履歴とカレンダーを参照して確認してみましょう。(動画は割愛させていただきます)
    f:id:minamint:20180214180406j:plain
    マイアクティビティでGoogle homeくんとの会話履歴が確認できる

    f:id:minamint:20180214180735p:plain
    このように、「(明日は)テストがある」と言うと、「テストがある」という予定が翌朝8時に登録されているのが確認できます。
    目次に戻る

    GoogleカレンダーからTwitter

    Twitterの方のGoogleカレンダーからTwitterにで作成したアプレットをそのまま使いましょう。「タスク通知用」カレンダーに予定を追加さえできれば、あとはこのアプレットが動作して通知してくれるわけですからね。
    これで、Google homeくんに話しかけたらタスクを翌日教えてくれるようになりました!
    目次に戻る

まとめ

ゴールに設定したものはIFTTTを用いることで全て実装でき、その動作も確認することができました。これでTwitterから離れる必要がなくなるし、通知も来るから忘れることもなくなりそう!
IFTTTは今回紹介したもの以外にも、様々なサービスを使ってより便利にすることが出来るので、気になった方は調べてみてください。
目次に戻る

余談

今の所実装したのは明日通知するというものだけ。これを曜日指定で出来たら便利だと思って追加実装をしたんですが…月曜から金曜の5パターンをTwitterGoogle assistantそれぞれに設定する必要があるため、合計10個もアプレットを追加で作る必要があり非常に面倒でした。途中で「こんなことするならタスク管理アプリちゃんと使った方が楽そう」と思ったほどです。もう少し手間を省けないものか…。
それに、IFTTTではまだ「カレンダーの予定を消す・変更する」に対応はしていないらしく、間違えたら手動で修正が必要なんだとか。少し面倒だけど対応してないから仕方ないですね。
でもこういう風に便利にしていくのは好きなので、これからも思いついたらとりあえず実装できないか考えて手を動かしてみようと思います。

メリークリスマスとよいお年を!

メリークルシミマス クリスマス

お久しぶりです。みなくんです。メリークリスマスでした。本当はクリスマスの日にブログを書こうと思ってたのですが、すっかり忘れてましたね。すまない。
しかしまあ、クリスマスというのは不思議なものです。皆クリスマスパーティーや高級料理店などで盛大に楽しい夜を明かして。えぇ。お金ないんじゃなかったの?
私もクリスマス当日は午前中のみ大学で勉学に励んで夜KFCさんの美味しいチキンとケーキを食べましたけどね。クリスマスぐらい美味しいもの食べてもいいんじゃない?お金はないけど。
でも、クリスマスイブにパーティーする人も多いらしく、イブの日にバイトをしていた私はかなり苦しめられていました。忙しいのはある意味良い事なのかもしれませんけど…バイトの身で言わせてもらえば、歩いてるだけでお金がもらえることほど嬉しいものはないので、可能な限り暇でありたいですね。 イブの日にバイトなんて可哀想だ、恋人と遊びに行けばいいのに――そういいたい気持ちは分かりますが落ち着きましょう。イブでも働く人が居ないとあの店この店全部閉まります。特別な日に何事もなく開いているあのお店には、ちゃんと感謝しましょうね(何様)。

クリスマスに行われていた「とある技術」を用いた生放送

クリスマス、パーティーしてた人が多いと思うのでテレビやネットを見ていた人って案外少ないのかもしれませんが、クリスマスに最近話題沸騰中のある方々が生放送をやっていました。
割と最近有名になりましたよね。私は数か月ほど前から一人だけ存在は知ってたんですけど、正直ここまで話題になって自分のTwitterまでもを賑やかにするとは思ってなかったです。(流行らず消えるんじゃね?とか思ってたのは内緒)
そう、最近話題といえば、「バーチャルユーチューバー」!
代表的な方といえば、某インテリジェントなAIさんはじめ、イルカさんや「見るストロングゼロ」とあだ名がつく方、はたまた声がどう聴いても「おじさん」なあの方などなど…。
特にここ数か月で一気に増えたような気がします。(一気に増えたというか、注目されて表に出てきた人たちなのかな?)
マイナーなところからいけば、かなり前からバーチャルユーチューバーというのは存在していたようです。恐らく最初は某インテリジェントゥなAIさんでしょうけども。
私も追える限りバーチャルユーチューバーの生放送を見て回ったのですが、どれもこれも面白いですね。新ジャンルというかなんというか…あれです。何か話をしてるだけで面白いっていう。ちょっと羨ましい… 。というか、あのコミュ力が欲しい…。
あらゆる形で皆を楽しませ、元気を届ける職業にはとても憧れます。私自身もかなり楽しませてもらってる身なので、精一杯応援していきます。自分が提供する側には、ちょっとコミュ力的に厳しいけども。 それに、多くの人が最新技術のことを「知り・興味をもって・触れてくれる」ようになる――そうすれば、もっとクオリティの高いものが出来て皆がハッピーになるので、彼女たちが流行ってる今って非常に良い流れなんじゃないかなーって思ってます。そういう意味でも頑張って、バーチャルユーチューバー!(だから何様)

年明けも間近

お正月?んなもんねぇよバイトだよコノヤロー!
頑張って働いて、Viveとかそういうの欲しいなあ…。PSVRは持ってるんだけど、PC用のVRデバイスも欲しいかなって思います。でもグラボの性能が足りない…まずはそこから改善せねば…。
欲しいものがいっぱいある上にどれもこれも高価なので、ただ眺めることしかできないみなくんなのでした。

皆さん良いお年を!

私のPCに起きた変なトラブル

このブログを書いたり、Twitterを眺めたり、ゲームをしたり…またはプログラミングまでもやってのける、我が家の愛用しているデスクトップPCがあります。購入当初はWindows8.1でやってたんですが、無料につられてWin10に変更。特に差支えがなかったので、毎日楽しくパソコンで遊ばせてもらってました。そんな私のPC、Windows10に変えてしばらくしてから変なトラブルが起こるようになりました…。そのトラブルをやっと対処できたので、今回は対処できるまでの経緯とか原因をパラパラと。

シャットダウン後、何故か勝手に起動する

もう寝ようとシャットダウンをして、デスクトップモニタの電源を消す。そして寝ようとパソコンから離れた瞬間、電源ボタンも押していないのにパソコンが再度勝手に起動を始めちゃう。原因がさっぱり分からず、ウイルスなんじゃないかと思ってウイルススキャンしたりあれこれ手を尽くしたけど、異常なし。数か月謎のままでした。最初は放置してたんだけど…やっぱり勝手に起動するのは電気食うし、何か不気味。家族にも怒られるので、なんとかしたかったわけです。なので、何とかならないか、とあれこれ記事を調べることに。

そこで出会ったのが、この記事でした。 Windowsが勝手に起動する場合の原因追及 - 岩崎仁の俺は語りたい!
ほう、イベントビューアーを見れば解決するかもしれない…。以前一度だけイベントビューアーというものが存在するという話を聞いたことがあったのですが、実際に見たことがなかったのでその方法は思いつきませんでした。
やり方を見ながら早速ログを見てみよう!ということで暫くログを眺めていると…。
「(Power-Troubleshooter) システムは低電力状態から再開しました。」という文章が。さらにそこに、「スリープ状態の解除元:Realtek PCIe GBE Family Controller」とも書かれていました。

な ん だ こ れ

Realtek…?どこかで聞いたことあるぞ、と思って調べたらコンピュータ機器の会社名でした。そういえばウチのスピーカーって「Realtek High Definition Audio」だったなあ。じゃあこれは何か機器が悪さをしているのでは…?と思い、解除元の名前をそのまま検索してみました。

Realtek PCIe GBE Family ControllerはLANのドライバだった

検索すると、LANドライバであることが判明。ということは、これはインターネット上から起動できるようになっている…?と思い、さらにこのドライバとシステム起動まわりの関係性を詳しく調べることに。
すると、知恵袋に同じような状態になっている人が。今回の症状、私だけの問題ではなかったようです。
PCが自動でスリープ解除になります。 - 1~2分後にすぐに電源が切れ... - Yahoo!知恵袋

この質問の回答を見ていると、Wake On Lan誤認識が原因なのでは?と。Wake On Lanとはインターネットに繋がったコンピュータの電源を遠隔でつけることができる行為のことのようで、私の予想通りの原因でした。LANドライバというよりは、LANケーブルから伝わったインターネット信号に何らかの原因で外部からノイズが入り、その信号がWake On Lanの信号と誤検出されたために発生した可能性があるかも…と。それなら、Wake On Lanを停止すればいいだけです。この回答者の方の言う通り、設定を弄って接続しているLANから勝手に電源を付けられないようにしてみました。

見事解決

それ以降、あれだけ困っていた勝手に起動する現象も全く起こらず。我が家のPCくんは私の指示に従い、大人しくしてくれるようになりました。あんなに悩んでたのに、たった少しのことで解決してしまうとは。この数か月は一体なんだったんだろう…と、嬉しさ半分悲しさ半分の中、我が家のPCのトラブルは解決してしまったのでした。まあ、まだ解決して間がないので…もしかしたら、再発するかもしれませんが。そのときはまたトラブルシューティング頑張りましょう。お兄さん頑張る。

今回の一件を振り返って

PCって、使いこなしているように見えてもやっぱり一般人である以上知らないことも多いし、普段触れないような機能もあったりするわけで。改めてPCを扱うのは難しいなあ、と思いました。今この時代だからこそ調べればなんとかなるようにはなりましたけど。
「君情報系の学校出身でしょ、このPC壊れてない?直して」なんて言われたとき。ちゃんと直してあげられるんでしょうか。
スマホを見せられて同じことを言われたときもそう。情報系ってだけでデジタル機器を使いこなしてると思われがちなので、そこは地味に気にしています。
正直Andr〇id直してって言われても知らない…使ったこともない、だって私iPh〇neだもの…。
プログラミングとか、ターミナル操作の勉強だけじゃなくて、今回みたいなPCで起こるトラブル周りの対処法とか、そういう勉強も大事だな…と今回の一件で強く感じたのでした。