京大の単位取得率等の講義情報を取得するAPIの使い方
京大の単位取得率を教えてくれるAPIを作りました。
詳しい使い方を以下に説明します。
(これをAPI【Application Programming Interface】と言っていいのか分からないけどよくあるAPIみたいなので分かりやすくAPIとしまーす)
使い方
まず、基本のURLは
https://script.google.com/macros/s/AKfycbx3yOdhfUgsUUFFcQGiSi-kKXSUVazxgWrACFGq/exec?
です。これの「APIの種類」で説明されているコードを末尾にパラメーターを追加していきます。
APIの種類
現在年度は2018年度、2017年度、2016年度、2015年度、2014年度、2013年度のデータが取得出来ます。
機能 | コード | 説明 |
---|---|---|
授業の名前から調べる | command=data&name=授業名&year=調べたい年度 | 授業名はURLエンコードしてください |
全ての講義の情報を得る | command=all&year=調べたい年度 | その年度の全ての講義の情報を返します |
講義の名前の一部から検索する | command=search&word=調べたい言葉&year=調べたい年度 | 調べたい言葉に部分一致する講義名の情報を返します。調べたい言葉はURLエンコードしてください |
※機能の追加や年度の追加は随時行い、ここに報告します。
2019/09/28 データが2018年だけでなく2017年、2016年、2015年、2014年、2013年のデータに新しく対応しました。
2019/09/28 「全ての講義の情報を得る」機能を追加しました。
2019/09/30 「講義の名前の一部から検索する」機能を追加しました。
使用例
「授業の名前から調べる」
以下のURLにアクセスすると2018年度の環境学についての情報がJSONで得られます。
「全ての講義の情報を得る」
以下のURLにアクセスすると2018年度の全ての講義の情報がJSONで得られます。
「講義の名前の一部から検索する」
以下のURLにアクセスすると2018年度の名前に「環境」を含む講義の情報がJSONで得られます。
分からない点、バグ、追加してほしい機能等があれば@iroha_nano145に気軽に声を掛けてください。使ってもらえてると知ると喜びます。
PythonでWikipediaから575を見つけてくるSlackBotを作った話
久しぶりに記事を書きます。
何年ぶりでしょうか、とりあえず三日以上の期間を開けての記事なので三日坊主の誹りを受けるいわれは無いでしょう。(某ジャンプマンガ、●UNTER×H●NTERが長期連載組扱いされるのだからそれと同じやり口であるこのブログにも文句は言わせない)
ということで祝ブログ開設から数か月、いるかいないかも分からない読者の皆様と共にこのブログも長い月日を歩んできました。
そこで今回の記事の内容は「Wikipediaから575を見つけてくるSlackBotを作った話」
まず作成の経緯について、
何故か突然一回生の中でSlackBotを開発する波が起きました。自分もその流行に乗っかって何か作ってみようということで、
はじめに
とりあえず常駐させるためにどっかのサーバー上で動かすことを考えると言語は限られてきます。その時はGASを使ってる人もいましたがサークルの講座でPyCharmを入れていたしPythonならどこのサーバーでも置かせてくれるかなと思いPythonで書くことにしました。またカッコ良さそうなので見つけた川柳を関連深い画像と合成た画像で投稿するようにしました。ただしPythonについてはほとんど素人だったので基本575の判定部分以外はコピペで仕上がっています。
逆にいえばプログラミングが分からなくてもほとんどコピペでSlackBotが作れるということです!
ということでBotの作り方というより参考になるサイト紹介ばかりとなりますがご容赦ください。
APIの取得
qiita.comAPI用トークンの取得方法から丁寧に説明されているのでBotに必要な権限にだけ注意すればこれ通りに進めるだけでいつのまにかBotが登録できてます。(なお、読者の皆さんはそこまでおつむは弱くないと思いますがこの記事ではBotの権限をAdminにしてます。自分は脳死でこれの手順通りに進めていたのでうっかりサークルのSlackに対しAdmin権限を要求してしまいました。すぐに取り消しましたが注意してください……)
Botの基礎部分
適当にググって出てきたこのサイトがPython3を使用してたので今回の言語がPython2ではなくPython3に決まったといっても過言ではありません。
qiita.com 自分みたいなのでもこれを参考にしてやりたいことが出来ましたし、これを完コピするだけでメンションに対する反応やチャンネル内の特定の言葉に対する反応など基本的なBotならもうこれだけで充分です。
それに後で機能の追加か変更がやりやすい構造で作ってあり親切でした。
これをコピペしてBotの基板部分は完璧ですね
Wikipediaの本文取得部分
まずWikipediaのランダムなページに飛ぶ方法として
http://ja.wikipedia.org/wiki/Special:Randompage
というURLがあるんですね、今回初めて知りました。
次にwebページの本文を抽出する所ですがC#では書いたことがありますがPythonでは初めてですそこでググると、
qiita.comおぉありました。これをコピペですね。するとあら不思議ランダムなWikipediaのページの本文をGet出来ます。これとその前のを組み合わせるだけでランダムなWikipediaの記事の本文を垂れ流せます。(ほんとうQiita様々です)
というかwikipediaのURL自体単語をURLの最後につけてるだけなので聞かれた内容についてWikipediaの説明を返すどっかのOKGoogleみたいなBotはこれで充分完成です。
575の判定部分
まず575の判定に必要なのが本文を読んだ時の文字数と単語単位での分解です。高校の時に作った人工無能では形態素解析のライブラリはMeCabを使ったのですが今回は導入しやすい(らしい)Janomeを使いました。
この辺はさすがにコピペでは無いです。
方法としてはまず行ごとに見ていきます。スクレイピングして本文だけを取ってくる方法では本文を各行でリストにしているのでそれを使います。
次にそれら行を単語(一応形態素解析なので単語では無く形態素だが面倒なので単語とする)で分けて、それぞれの品詞と読みを調べるその部分のコードがこちら
t = Tokenizer()
words = [token.surface for token in t.tokenize(s)]
hinsi = [token.part_of_speech.split(',')[0] for token in t.tokenize(s)]
yomi = [token.reading for token in t.tokenize(s)]
変数名適当だなとかいうツッコミはよして下さい。公開する気の無いコードなので……sが本文です。
まずまともな575になるようにスタートは名詞からに限定しました。まず文字数についてですがJanomeでは読みは基本全角カタカナですが記号は基本読みも記号で返されますし算用数字は*で返されるのでカタカナであるかどうかの確認をする必要があります。そこで参考になるのがこちらのサイト
qiita.comこれを参考にカタカナ以外の文字を除外したりカタカナだけの文字数を数えたり出来ます。
より自然な575を取得するために上五、中七、下五を跨ぐ単語が無いようにします。また句点を跨ぐことが無いようにもしました。この辺はほぼ初めてPythonを触る自分のような人間でも書けるので割愛します。
ちなみにカッコとかが入るとぐちゃぐちゃした物になるのでカッコが入らないようにしてもいいかもしれません。今回自分は一句の中で完結するカッコ以外を含む場合は別の所から575を探しなおすようにしました。
575に関連深い画像の自動取得
はじめは575の中の名詞からランダムに選んだ名詞をキーワードとしてそのキーワードに関係ある画像を取ってくるとしようかと思ってました。
しかしわざわざランダムで選ばなくても575のはじめの単語は名詞と決めていたので始めの単語をキーワードとすることにしました。キーワードは決まったので後はそのキーワードに関連する画像の取得、
そうGoogle画像検索です。
はいpythonでスクレイピングをする経験はあまりなかったのでコピペです。
はい、これです
qiita.comすごい、本当にコピペだけで出来るんですね……
画像に文字列を合成と自動生成
これは完全にコピペですね
www.crz33.comここまでコピペ祭りでこれを自分の作品と言っていいのかとても心配だったりしますがまぁいいでしょう
完成図
完成したBotです
いきなり不穏な句を発表してきました。
結構面白い物を出してくる時は出してきますね。ですがJanomeもあくまで形態素解析用であり単語分解では無いので結構変なところで切ってきたりというのもあるのですがそれもまた一興です。
WordでTwitterをやる方法(適用編)
人の三大欲求といえば
・食欲
・性欲
そして
Twitter欲、そう人は睡眠を犠牲にしてでも何故かTwitterを開いてしまうように出来ているものです。
その欲望は当然授業中でも発現します。でも講義中に堂々とTwitterの画面を開けない人は多いでしょう、ならばそんな状況でTwitterをするにはどうしたらいいか。
WordでTwitterが出来るようにすればいいのです。Wordを開いているだけなら傍から見ても講義のメモを取っているようにしか見えません。
さて、実際にWordでTwitterをする方法を説明していきます。まず、以下のコードをコピーしましょう。
(力業で書いてます汚いかもだけど許して、デバッグが面倒だったのでエラーが出ても無視するコードを突っ込んでるけど許して)
Option Explicit Private stopT As Boolean Sub Twitter() ' ' Twitter Macro ' ' Dim buf As Integer buf = InputBox("何ツイート取得しますか?") Dim IE As Object Set IE = CreateObject("InternetExplorer.Application") IE.Visible = False Call gettweet(buf, IE) ActiveDocument.Range(0, 0).Select IE.Quit Set IE = Nothing End Sub Sub autoTwitter() ' ' autoTwitter Macro ' ' Dim buf As Integer buf = InputBox("何ツイート取得しますか?") Dim IE As Object Set IE = CreateObject("InternetExplorer.Application") IE.Visible = False stopT = False Do Call gettweet(buf, IE) ActiveDocument.Range(0, 0).Select 'if Call WaitFor(60) Selection.WholeStory Selection.Delete Unit:=wdCharacter, Count:=1 If stopT Then Exit Do Loop IE.Quit Set IE = Nothing End Sub Sub stopTwitter() stopT = True End Sub Sub gettweet(ByVal num As Integer, ByRef IE As Object) IE.Navigate "https://twitter.com/" Call IEWait(IE) Dim temp As String Dim tweet_temp As String Dim name As String Dim subg As String temp = IE.Document.body.innerHTML tweet_temp = temp Dim i As Integer For i = 1 To num On Error Resume Next: tweet_temp = Mid(tweet_temp, InStr(tweet_temp, "suggest_ranked_organic_tweet")) On Error Resume Next: tweet_temp = Mid(tweet_temp, InStr(tweet_temp, "data-name=""") + 11) On Error Resume Next: name = Mid(tweet_temp, 1, InStr(tweet_temp, """") - 1) Selection.TypeText name & vbLf 'TweetTextSize tweet_temp = Mid(tweet_temp, InStr(tweet_temp, "TweetTextSize")) On Error Resume Next: tweet_temp = Mid(tweet_temp, InStr(tweet_temp, ">") + 1) On Error Resume Next: subg = Mid(tweet_temp, 1, InStr(tweet_temp, "<") - 1) Selection.TypeText subg & vbLf & vbLf & vbLf & vbLf Next End Sub Function IEWait(ByRef objIE As Object) Do While objIE.Busy = True Or objIE.ReadyState <> 4 DoEvents Loop End Function Function WaitFor(ByVal second As Integer) Dim futureTime As Date futureTime = DateAdd("s", second, Now) While Now < futureTime DoEvents Wend End Function
このコードの説明についてはまた新しく記事を書くかもしれません。
これをWordのマクロに貼り付けるだけといえばだけなんですが、まずWordにはデフォルトでマクロを編集出来る「開発」タブが表示されていないんですよね。しかもそこを説明しろと言われたのでちゃんと説明します。
なので、とりあえず今日はじめてWordを使う人向けくらいの丁寧な説明を心がけます。
まず、開発タブの出し方
Wordの右端のグレーの部分の空白の所で右クリックします。
そこで「リボンのユーザー設定」とかいうのをクリックします。
表示されるウィンドウの「リボンのユーザー設定」の部分で「開発」というところにチェック✓をつけましょう。OKを押たら開発タブが表示されてると思います。
この開発タブをクリックして「マクロ」の部分をクリックします。マクロ名に適当な名前を入れて作成をクリックします。
何かウィンドウが表示されたと思うので、そこに書いてあるものを全部消すか最後に追加するか適当に選んでさっきのコピーしたコードを貼り付けてください。(ただし一番最初の行のOption Explicitについては一番上に書き換えといてください。)
これでこのマクロ編集ウィンドウを閉じます。これでTwitterをやるマクロの適用は終わりです。
実際使ってみる
まず下準備としてInternet ExplorerでTwitterにログインし、そのログイン状態を保存しておく必要があります。
次に一度マクロをクリックすると「autoTwitter」と「Twittter」、「stopTwitter」というマクロが出来てると思います。
「Twitter」マクロについて、これを実行すると
みたいまウィンドウが表示されるので取得したいTweet数を入力してOKを押すとその数だけのTweetがWordに入力されます。(現在画像とハッシュタグは無視します)
こんな感じ
こんな感じで今のところガバガバ実装だから画像とハッシュタグは無視される pic.twitter.com/F8PIQ31cLD
— いろは_なの (@iroha_nano145) 2019年6月12日
「autoTwitter」マクロについて、これを実行すると「Twitter」と同じようなインプットボックスが表示されます。すると1分ごとにその数だけのTweetを取得してWordに入力し古いのは消すというのをずっと繰り返します。(これも現在画像とハッシュタグは無視します)終了するときは同じようにマクロから「stopTwitter」を実行するとループが停止します。
さて、使い方分かってもらえたでしょうか。もし分からない所や感想などがあれば気軽にコメントしてください。筆者が喜びます。
※なおこのコードについて
ことりちゅん (id:Kotori-ChunChun)さんから多大なるアドバイスを頂いて改善させて頂きました。本当にありがとうございます。以下にことりちゅん (id:Kotori-ChunChun)さんが提案していただいたコードを引用させて頂きます。詳しくはこの記事のコメントを参照してください。こちらの方が使い勝手がいいと思います。
一か月同居してたのに家出された話
さて、久しぶりのブログです。技術専門にしようかとも思ったのですがそれだと間違いなく更新しない気がしたので何でもブログには書いていきます。カテゴリーを分けるくらいですかね。
このブログも一日坊主になるものだと自分でも思ってました。そもそも小学生の頃から自分には日記のようなものを継続することが出来ないのです。思い出してみれば継続というものがとことん出来ず三日坊主常習者の自分にとって夏休みの宿題で唯一最初の一週間以内に終わらせた物は一つしかありませんでした。一行日記ですね。当時の自分でも一行日記なるものを毎日コツコツ書くなんて芸当を自分が出来るとは思ってないわけですよ、なのでいっそ夏休み初日に一行予定表というよりその年の夏休みを妄想して一行日記にその妄想を展開するという作業を行っていたんですよね。
さてさて今回の内容ですが、なんと今日同居していたやつに家出をされました。なので今回は家出した彼との短い思い出について
同居生活といっても一か月弱ほどしか無いのですがそれでも自分はまぁ彼にある程度依存していたところもあったのだなと彼がいなくなったあと気付くんですよ。いや彼に依存していたなんて彼がうちに来てからすぐに分かってはいたのですけどね。
うちの下宿は安いだけあってボロいので奴が出るんですよね、そうGが。自分はGみたいなのがとことん苦手でGを退治した後しばらくはGの幻影が見えちゃうくらいに苦手なのですが彼はG退治のプロだったんですよ。彼がうちに来てから自分がGと遭遇することはめっきり無くなってたんですよ、つまるところ彼がいなくなってしまった現在目下対策しないといけないことはG対策なんですよね。
別に彼がG対策にしか能が無かった訳では無いですよ。彼がいなくなってしまった今一番頭を悩ましてるのがそのことだっただけで。他には、下宿生なら理解してもらえると思うのですが一人暮らしをしてると沈黙がえらく寂しく感じるんですよね。だから観てる訳でも無いテレビをつけっぱなしにしたりとかするんですよ。でも彼がいた時は話したりしなくても彼の動く時の物音がするだけでだいぶ寂しさが紛れていたんですよね。
そんな彼がうちを出ていきそうになったのもこれが一度って訳じゃ無かったんですけど。以前も一度出ていきそうになったのを自分が止めたんですよ……それでもね、外見がちょっとキモくて度々疎ましがってしまったこともあったので家出されるのも当然かなって反省だってしてるんですよ。
特徴としては大柄なやつで手足がスラっと長いんです、体は少しばかり大きくてでも歩き方や顔が少しキモい奴だったんですよね……
さて、彼との思いでをつらつらと語るだけの記事となってしまいました。彼は見た目があれなので疎まれることもあると思うのですが見かけても引かないでやってください、いいやつなのでもしよければ友達になってあげたりなんなら部屋に上げてやったりしてくださいね。
ここでやっと明かしますが彼の正体は
僕の同居してたやつとはアシダカグモです。ゴキブリといった害虫を捕食し巣を張ることがない益虫として知られており一部では家の守り神と言われております。大型のクモでうちにいたのは10cm程度とこのクモにしては小柄でした。
Brainf*ckのインタプリタをscratchで作った話
scratchとかいうプログラミング教育用教材がありますね。
これを見た時ふとscratchで作ったプログラムはフルスクラッチって言えるんじゃね、みたいな(今考えると)激寒ジョークを考え付きました。
よし、Twitterでこのジョークを使えばバズるのでは
さて何を作ろう。
そんなに手間じゃなくて何かいかにもフルスクラッチとか言える物……そうだBrainf*ckだ。Brainf*ckを知らない人はこちらで確認してください。
要はたった8個の命令だけのプログラミング言語。これならインタプリタの作成くらい楽じゃん。ということで実際に作成しました。作ったものがこれ
寝る前という正常な判断の出来ないタイミングで思いついた激寒ギャグとそんな状態で作った物なので非効率的な部分とかマジックナンバーが登場してますが人に読まれることを想定して書いてないので許して。
さて、このブログを読んでくれる人(そもそも存在するのか……)が興味あるとはとてもじゃないが思えないが今回分かったscratchでプログラムを作成する上で注意しなければならないことを一つ書いときます
それは
大文字と小文字を判別してくれない
echoプログラムをテストした時に発覚しました
あれ?入力はhogeなのに出力がHOGEになってる。入力の文字列をアスキーコードに変換する際に
このブロックを使ってたのですが、これがどうやら大文字と小文字を区別しないらしい。だからアスキーコードで最初の方に出るアルファベットの大文字の方の番号を返していたらしい。
さて、どのように対処するか
scratchの仕様ということであきらめるか、
とりあえずググってみると「コスチューム」の名前は大文字と小文字を区別するらしいという知見を得ました。
(コスチュームって何なのか猫が服とか着るのか、その辺はよく分かりませんが)
一回文字をコスチュームの名前とやらに設定してコスチュームの名前を判定してやれば大文字小文字の判別が出来るようです。
そしたら
以上多分このブログ見てる人でscrath使って何か作ろうなんて人はいないと思いますが役立ったら嬉しいな。
最初これをコンパイラとか言ってツイートしてしまいましたがこれはインタプリタです。コンパイラは要は機械語へのインタプリタなのでBrainf*ckならインタプリタ作る感覚で作れるとか書いてあるのを見てこれもscratchで作ってやろうと思いましたが、いかんせん機械語とかアセンブリとか知識は皆無なので断念しました。ちょっと調べた感じBrainf*ckより命令も多くてアセンブリの方が書きやすそうな印象を受けました(入力は難しいのかな?)
因みに……
元々はTwitterでバズることを目指していましたが結果はどうだったのか
暇だったのでBrainf*ckのコンパイラをフルスクラッチ(scratchで作ったので嘘ではない)で作成しましたhttps://t.co/iBzZgcwbXC
— いろは_なの (@iroha_nano145) May 17, 2019
まぁいつもの自分のツイートに比べれば少しだけ伸びてるけど……うん、スベったね。
ちなみにslckでは反応が皆無でした(スベったね)
と、言ったは良いものの、autoTwitterの方は色々おかしいですね。
objIE.Quitの破棄がLoopより前にあるので2巡目以降は動きません。
マクロを中断させるとiexplore.exeがタスクとしてたまり続けてしまうのでちょいと危険です。
私なりに整理してみましたのでご参考まで。
'https://strelka-dog.hatenablog.com/entry/2019/06/15/233948
Option Explicit
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)
#End If
Private Const READYSTATE_UNINITIALIZED = 0 'デフォルト値。未完了状態。
Private Const READYSTATE_LOADING = 1 'IEオブジェクトのロード中状態。
Private Const READYSTATE_LOADED = 2 'IEオブジェクトのロード完了状態。ただし操作不可能状態。
Private Const READYSTATE_INTERACTIVE = 3 'IEオブジェクトの操作可能状態。
Private Const READYSTATE_COMPLETE = 4 'IEオブジェクトの全データ読み込み完了状態。
Private IsExit As Boolean
Function IEWait(ByRef objIE As Object)
Do While objIE.Busy Or objIE.ReadyState <> READYSTATE_COMPLETE
DoEvents
Sleep 100
Loop
End Function
'---コード2-2|指定した秒だけ停止する関数---
Function WaitFor(ByVal second As Long)
Dim futureTime As Date
futureTime = DateAdd("s", second, Now)
While Now < futureTime
DoEvents
Sleep 100
Wend
End Function
Sub autoTwitter()
'取得ツイート数
Dim tweetCount As Variant
tweetCount = InputBox("何ツイート取得しますか?")
If Not IsNumeric(tweetCount) Or tweetCount <= 0 Then Exit Sub
'待ち時間
Dim waitSecond As Variant
waitSecond = InputBox("何秒ごとに更新しますか? 0の時:更新しない。負荷を避けるため10秒切り上げします。")
If Not IsNumeric(waitSecond) Then Exit Sub
If waitSecond > 0 And waitSecond < 10 Then waitSecond = 10
Debug.Print "START", Format(Now, "hh:mm:ss")
'IEオブジェクト ※Twitterに自動ログインできる状態であること
Dim objIE As InternetExplorer
Set objIE = CreateObject("InternetExplorer.Application")
objIE.Visible = True
objIE.Navigate "https://twitter.com/"
Call IEWait(objIE)
Dim i As Long
Dim temp As String
Dim tweet_temp As String
Dim name As String
Dim subg As String
'終了フラグ(終了時はstopTwitterにてTrueを上書きすること)
IsExit = False
Do
'Word上の文章を全て削除
Selection.WholeStory
Selection.Delete Unit:=wdCharacter, Count:=1
Debug.Print "LOAD", Format(Now, "hh:mm:ss")
'HTMLを取得
On Error Resume Next
temp = objIE.Document.body.innerHTML
On Error GoTo 0
tweet_temp = temp
'HTMLを解析し出力
On Error Resume Next
For i = 1 To tweetCount
tweet_temp = Mid(tweet_temp, InStr(tweet_temp, "suggest_ranked_organic_tweet"))
tweet_temp = Mid(tweet_temp, InStr(tweet_temp, "data-name=""") + 11)
name = Mid(tweet_temp, 1, InStr(tweet_temp, """") - 1)
Selection.TypeText name & vbLf
'TweetTextSize
tweet_temp = Mid(tweet_temp, InStr(tweet_temp, "TweetTextSize"))
tweet_temp = Mid(tweet_temp, InStr(tweet_temp, ">") + 1)
subg = Mid(tweet_temp, 1, InStr(tweet_temp, "<") - 1)
Selection.TypeText subg & vbLf & vbLf & vbLf & vbLf
Next
ActiveDocument.Range(0, 0).Select
On Error GoTo 0
If waitSecond <= 0 Then Exit Do
'ブラウザを更新
objIE.Refresh
Call IEWait(objIE)
Call WaitFor(CLng(waitSecond))
If IsExit Then Exit Do
Loop
'IEオブジェクト破棄
On Error Resume Next
objIE.Quit
Set objIE = Nothing
On Error GoTo 0
End Sub
Sub stopTwitter()
IsExit = True
Debug.Print "STOP", Format(Now, "hh:mm:ss")
End Sub