Ubuntu20.04でWeb面接環境を整える

これはWMMCAdventCalendar2022

adventar.org

の14日目の記事です。

昨日は太郎🔖君の[「HM-StarterKitについて(初学者向け)」](https://jitsuhataro.hatenablog.com/entry/2022/12/12/002323?_ga=2.51530729.1707336129.1670857021-2015111682.1670857020)でした。

はわぷろさんも言及していましたが、読んでいると、「楽しい」という感情が出てくるのは素晴らしいですね。この調子で頑張っていってほしいです。

なんか、標準DCマウス作ってもいいんじゃねみたいな気がしましたね。結局、面白くないと続かないのと、コロナでマウスやってた人口が激減しているので、ノウハウがロストしてしまって...みたいなのは、全国のマウスサークルの悩みの種なのではないでしょうか。(3年ぐらいマイクロマウスの大会行ってないので近況が全くわからんですが)

人口復活のためにもいいのかもしれないっすね。工夫点やノウハウの蓄積していくフェーズがなくなりますが、まぁその分他に充てられるような気もするっすしね。(※以上は老害の独り言です)

で、今回ですが、書くことのネタが2個あったので、片方のやつだします。 今週忙しくて、普通に楽なやつを今回放出します。

0.事故

~とある日のしがない就活生の J君~

J君「お、面接まであと10分だな〜」(10)

J君「PCの電源、オンっと…」(10)

J君「あれれ〜?おっかしいぞ〜?Windowsが…吹っ飛んで……ないかこれ!!!?」(7)

ワイ()「仕方ない!ubuntuで入ってブラウザから面接会場に入ろう!」(6)

(ubuntu起動)

ワイ「あ、あれ…?Airpodsがつながってるのにマイクが入らない…」(3)

ワイ「あれ?マイクテストー、マイクテストー、あれ?マイクマジで入らん」(1)

ワイ「あれもう面接時間だ…orz」(0.5)

ってなりました(マジ変に寿命減った)

ちなむとマイクの調子悪いので再起動しますとかチャットして面接官に待ってもらって、 他のPC持ってきてどうにかこうにか対処したんすが、結構焦りました。

なので、あらかじめちゃんとubuntuサイドで面接環境を整えておけば良かったななどと思って普通に後悔したので備忘録として残します

1.やること

今回やることは以下の3つです。 もし、「これもあると便利です」っていうのがあれば ぜひとも教えてください(笑)

①Web会議のアプリをインストールする

②Airpodsがつながらない問題を解決する

③パワポを使えるようにする

では、初めて行きましょう

2.①Web会議のアプリをインストールする

て、まず、面接で使うオンラインweb会議アプリは

①Zoom

②Teams

③Webex

あたりです。 ブラウザで使うことができるものもありますが、 ここは一旦インストールしておきましょう。

詳細なインストール方法は、省きます。 一応、簡単に言っておくと、「.DEB」をダウンロードして、そのダウンロードしたファイルがあるディレクトリで

sudo dpkg -i (.DEBファイル名)

とするとはいるはずです。

3.②Airpodsがつながらない問題を解決する

Linuxの環境では音声アプリケーションと 実際に音を入手力させるデバイスのドライバー(デバイスドライバー)の仲介役として

ALSA(とPulseAudio)

があります 基本的にALSAが取りまとめており、各オーディオアプリケーションへのリソースを調節するのがPulseAudioなのです 従って複数のアプリの音声入出力を調停するのは PulseAudio が担当しているようです。

例えを出すと ALSAが正規販売店「Pulse Audioがマルチディーラー」の役割を担っているみたいな(ほんまか?)かんじです。

しかし、この関係性は必ずしも守られるわけではないようです。 いくつかのアプリケーションは Pulse Audio(ディーラー)を介さず直接ALSA(正規販売店)を介するようになっています。 他にも、Pulse Audio(ディーラー)があたかもALSA(正規販売店)のふりをして、顧客とやりとりをして、取引が終わったらALSA(正規販売店)とやりとりを始めるみたいなことも多いのです。 そのため、オーディオ設定が面倒になることも多いです。

なので、今回はPulse Audioの設定をいじってやれば、 きっと繋がらなかった Airpodsも繋がると考えられます。 そして、その設定ファイルは/etc/pulse/default.pa にあるようです。

/*************************************************************************/

ここで、「systemd」について、にわかより補足です。

基本的にLinuxが起動すると以下の手順で起動されます。

この中の「Init」がこの「systemd」が動くところです。

Initシステムでは、

①systemd プロセス (/usr/lib/systemd/systemd) を開始

②/etc/systemd/system/default.target のシンボリックリンクからターゲットを確認

③ターゲットに対して、依存関係/順序を持つサービスを自動で起動

の3ステップで動きます。

systemdについては 【入門】systemd とは?設定ファイルの書き方や自動起動の設定 | ほげほげテクノロジーがわかりやすい気がします。まだ。

systemd内の「.service」の基本構成は [unit]と[install]で、各サービス固有の設定がある場合は[Service]タグ内に記述するようです。

しかし、この中で ターゲットレベル「multi-user.target」に関して、systemdファイルはユーザーレベルでの起動ができません。

そこでデーモンをリロードしておく必要があります。 ちなむとよく勘違いされがちですが、 デーモンは、↓

「ユーザーが意識することがないような裏の部分で動いており、システムを維持したりユーザーにサービスを提供したりといったことを行っています。ちなみにこのデーモンとは悪魔の事を指すdemonではなくdaemon(守護神)です。」

引用: Linux リテラシ - 第4回 デーモン

デーモンのリロードと同時に

systemctl --user enable (サービス名)

でサービスを自動起動にさせておくことで、 phonesimなどの、音声入出力関連が自動起動するようになります。

では、以上を踏まえて、実際に設定を進めていきましょう。 /*************************************************************************/

(1)まず、音声入出力パッケージである「ofono」をインストールします。

sudo apt install ofono

(2)Pulse Audioの設定ファイル(/etc/pulse/default.pa )にて、以下を記載。 まず設定ファイルを開く。

code /etc/pulse/default.pa

そして、以下を記載する。

#load-module module-bluetooth-discover #ここをコメントアウト
load-module module-bluetooth-discover headset=ofono #ここを追記する

なお、管理者権限できちんと変更を有効にする必要がある。

(3)ユーザー「pulse」をbluetoothグループに追加します。これで、「sudo」権限なしでpulseユーザーとしてbluetooth グループを使用できます。

sudo usermod -aG bluetooth pulse

(4)「ofono」の設定ファイル(/etc/dbus-1/system.d/ofono.conf)の変更

先ほど同様にまずは設定ファイルを開く

code /etc/dbus-1/system.d/ofono.conf

そして以下を追記する

<policy user="pulse">
  <allow send_destination="org.ofono"/>
</policy>

(5)次に、「ofono-phonesim」をインストールする

リポジトリの登録からインストールまでは以下をターミナルで実行すればよい

sudo add-apt-repository ppa:smoser/bluetooth
sudo apt update
sudo apt install ofono-phonesim

(6)「ofono-phonesim」の設定ファイル(/etc/ofono/phonesim.conf)に以下を追記する

また、先ほど同様に、以下でファイルを開く。

code /etc/ofono/phonesim.conf

そしたら、以下を追記する

[phonesim]
Driver=phonesim
Address=127.0.0.1
Port=12345

(7)「ofono」を再起動

sudo systemctl restart ofono

(8)上記で説明した、「ofono」のsystemdユニットファイル(/etc/systemd/system/ofono-phonesim.service)を作成して、中に以下を記載する

まず、/etc/systemd/system/ofono-phonesim.serviceを作成する。

cd /etc/systemd/system/  #ディレクトリに移動
touch ofono-phonesim.service  #ファイルを作成

作れたら、以下を記載する。

[Unit]
Description=Run ofono-phonesim in the background

[Service]
ExecStart=ofono-phonesim -p 12345 /usr/share/phonesim/default.xml
Type=simple
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

先ほどの説明のように、基本構成は[Unit]と[Install]であるが、今回は[Service]もある。

(9)ofono のソースコードをクローンし、配置

git clone git://git.kernel.org/pub/scm/network/ofono/ofono.git
cd ofono
git checkout 
cd ..
sudo mv ofono /opt/

(10)「phonesim 」の Systemd ユニットファイル( /etc/systemd/system/phonesim-enable-modem.service) を作成

まず、/etc/systemd/system/phonesim-enable-modem.serviceを作成する。

cd /etc/systemd/system/  #ディレクトリに移動
touch phonesim-enable-modem.service  #ファイルを作成

作れたら、以下を記載する。

[Unit]
Description=Enable and online phonesim modem
Requires=ofono-phonesim.service

[Service]
ExecStart=/opt/ofono/test/enable-modem /phonesim
ExecStart=/opt/ofono/test/online-modem /phonesim
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

(11)デーモンのリロードと自動化を有効にする

sudo systemctl daemon-reload
sudo systemctl enable ofono-phonesim
sudo systemctl enable phonesim-enable-modem
sudo systemctl start ofono-phonesim
sudo systemctl start phonesim-enable-modem

(12)最後に実行&再起動

pulseaudio -k

sudo reboot

これで、Airpodsがつながっている..はず!

4.③パワポを使えるようにする

あ、で、オンライン面接、自分の研究スライド出せって言われることもあってですね、 officeがubuntuだと容易に使えなくて不便だったので 下記のdebパッケージをダウンロードし、

linux.wps.com

sudo dpkg -i <パッケージ名>

で、インストール完了です。 実際にターミナルで

wpp

と打つと開いてパワポが使えるようになります。 スライドショーもできる。

フォントが崩れるのこともあるらしが、それはググると解決しそうなので、ここでははぶきます。

とりあえず、 これで最低限のオンライン面接環境が整いました。

もしこれもあると便利だよ! ってのがあれば教えてもらえると助かります。

5.最後に

以上で、最低限の面接環境を整えることができました。 二度と、あんな悲惨な事故を起こすわけにはいかないので備忘録です。 次の記事では、ロボットに関する記事でもあげたいとおもっています。 一応、ロボット系の研究室の修士なので...

さて、次回予告です。 明日は、Xfa君の、「Nucleoマウスの話か何か」だそうです。 卒論時期にあざす。本当ほどほどにで大丈夫です。 ちなむと、あの機体はユーザビリティが高そうということで 先輩たちに絶賛でした。素晴らしいですね。

では、また次回に。

参考

AirPods ProをUbuntu 20.04で使用する(マイク(音声入力))│hirooka.pro

PulseAudio/サンプル - ArchWiki

UbuntuでPowerPointドキュメントを作成する - Qiita

開催の言葉(ブラックフライデーで買ったものと買ってよかった本の話)

この記事は WMMC Advent calendar 2022

adventar.org

の1日目の記事です。

[目次]

※クリックで飛べるので内容だけ知りたい人は2の項目へどうぞ

0.開催宣言

1.書くことが....ねぇ!

2.ブラックフライデーで買ったもの

3.買ってよかった本の話

4.最後に

0.開催宣言

お久しぶりです。久しぶりのブログ更新です。

今年もなんだかんだでやりましたWMMC Advent Calendar。

自分が学部3年生のコロナ禍で主催し始めてからついに今年で 3回目 ということで、また、この一か月楽しんでいきましょう! ちなむと参加人数がまだ足りないので現役生・OB・OGの皆さん 参加よろしくお願いします。 今年は、近年一番活発だった2個上が社会人となり、一個下は卒論、同期は就活なので、参加人数が集まりません助けてください~

過去のWMMCサークルのアドベントカレンダーが気になる方は いかに乗せておくのでご覧ください。

2021年度:

WMMC Advent Calendar 2021 - Adventar

2020年度:

WMMC Advent Calendar 2020 - Adventar

1.書くことが....ねぇ!

修士erになったら 忙しいとは思っていましたが、 卒論とは別ベクトルの忙しさでした。 大雑把に分けると以下のようになります。

①就活 ②大学院の授業と課題 ③研究(1年だけ全く別の研究をするという弊研究室の恒例のやつ) ④研究室雑務 ⑤修論へ向けた準備

こう書くと、お、そうでもないなとなる人も多いと思いますが 基本的に4〜6割のキャパシティと7割ぐらいの時間が割かれるのが就活です。(個人差あり) メインタスクに対しての割り込み頻度が高いため、負荷が大きく感じているのかもしれませんが。

2番目は研究ですかね。 言わずもがな。

3番目は研究室雑務。 私の場合はコロナでやらなくて良さそうということでサボっていますが。

あとは同じくらいなんですが、 この、多方向へのキャパシティ割り振りってのは思っていた以上に面倒です。

マイクロマウス開発で まとまった時間が必要ってのと同じやつです。割り込みタスクがあると開発がマジで進まない…ってなります。

話は脱線しつつあるので戻しますが、 半導体不足で3〜4ヶ月サイトを張っていてもラズパイ4は手に入らないなどで電子工作もあまりできなかったので技術ネタが1つぐらいしかないです。 すいません(#技術系サークルとは)

このネタは次回に回そうと思います。

てなると書くことがありません!

就活は終わってないですしおすし。なんなら今日面接だハハハ(は?)

ということで、 本日まで開催されている、 Amazonブラックフライデーで散財したので買ったものでも紹介します…

2.ブラックフライデーで買ったもの

ブラックフライデーは、在庫処理でいろいろ安くなっているやつです。

www.amazon.co.jp

今回私が買ったものは

iPad

[用途]

・論文を読む

・製図チェック→手書きでチェックします。

・授業や説明会のノート

Youtubeや映画を見るのに非常に便利です。

・3年ほど使っているiPhoneの容量がいっぱいになってきたのでiPadで代替できるアプリや写真はこっちで処理したい。

 

AirPods Pro

[用途]

・音楽・ASMR聞く用

・就活面接用のマイク付きイヤホン

・作業時の騒音対策

思っていたよりも指向性が高いのか、マイクの機能も高く結構よかったです。

ノイズキャンセルばかりに目が行きがちですが、マイク性能や圧倒的な充電速度(数分ほど充電すれば数時間使える)などもレベルが高くて驚きました。

音質は....まぁって感じでした(素人の感想です)

Apple製品は円安で高くなってしまっていたので、これを機に上記の2つを買ってみました。まぁ安くなっていても高いのには変わらないですが

Amazon echo dot

[用途]

・スマート家電に興味を持ったから購入

(最近は照明・カーテンなど、面白いスマート家電が増えているので、調べてみるといいかもしれません)

・二重予備目覚まし

 →最近就活やTAで朝早く起きなきゃいけないことが多いのでそれ対策で買いました。

・天気予報や気温を聞く

・室内音楽を流す

買ってみて思ったのが、スマート家電がないと意外と使う機会がない。 あれば便利だけど、いざ必要になったときに、これを使うという意識が出てこなくて、結局スマホで調べてしまったりします。 愚弟は「ダジャレ100連発頼むAlexa」とかで使っていましたw 追記:昨日からアメリカではAlexaでジェネレーティブAIを導入したようです。 「Alexa、お話作って」でAIによるつくり話を聞かせてくれるようです。 科学の力ってすげー www.engadget.com

Apple pencilもどき www.amazon.co.jp

[用途]

iPad

以上すかね。 他にもこまごましたものは買ったのですが、大したものではないので省略

3.買ってよかった本の話

今年もいっぱい本を買いました。 本の紹介は適当に済ませますが、一応紹介だけしておきます。

詳解 3次元点群処理 ~Pythonによる基礎アルゴリズムの実装~

点群って...面白いのかもしれない。 そう思いましたね。修士論文で使うと思うので勉強のために購入しました。 絶賛現在進行形で勉強しています。

詳解 確率ロボティクス Pythonによる基礎アルゴリズムの実装

もともと、青い英語の原本の方を購入して持っているのですが、挫折しました。 上田先生はYoutubeで解説動画を載せていたりするので普段から見るようにしています。 工学系の学生なので、理学チックな数式を追うのは正直苦手なのですが、 とりあえず使えればオッケ。知っておけばオッケ理論でとりあえず読んでいます。 わかれば面白いんだろーなーと思いつつわけわからん定期をかましています。

コンピュータビジョン最前線シリーズ

このシリーズも先日2022Autumnが出ましたね。買っては積読になりがちな本ですが、書いてあることが難しいせいだと言い聞かせています。 見る分には面白かったですね。

interface 2023年1月号

今回はLidar特集で面白いことが書いてありました。 基本的にトラ技は自分には難しすぎるので、 インターフェイスの方がまだわかって楽しいですが、今回のは特に面白かったです。 来月も楽しみだ。

4.最後に

いろいろ紹介しました。 忙しいので雑に書いてしまいましたが、 次回は少し実践的なことを書けたらと思います。

では、次回予告です。

明日はパワプロさんで、「自己紹介と今年やった課外活動」だそうです。

ロボマス、見てて面白いっすね。それの話なんでしょうかね。楽しみです。

いつもいつも2日目、ありがとうございます。お忙しいところすいません。

では、また次の記事で会いましょう。ばあい。

幻の26マン(Apexlegendsを自分で作りたかった話)

注意)本記事は著者のメンタル状況に応じて抽象度が変化するようになっております。
ご了承ください。

みんなー!忘れてたやろー!!!
俺も忘れてたー!!!(わけではないけど忙しくて忘れさせられかけてた)
2021年以内に終わらせられてよかったー!!!


WMMC Advent Calendar 2021 - Adventaradventar.org

の26日目(ですらない)の記事ですぅぅぅ!!
本当なら昨日は19日(もはや遠く昔の日だな)は…
たまかけ君の「学生大会の感想」
学生マイクロマウス大会の感想(懺悔) - HackMD
でした。
…お疲れ様でした…
コロナ禍で製作意欲の下がっている人が多い中
標準マウスを作成したのは素晴らしいでプリプリィッ!!!

(というべきなのか、
それとも
昨日(ですらない)の記事は
僕の脅迫で無理やり書いてくださった
某さんの
ものづくりのチーム開発を攻略しよう① リーダーが気をつけるべきこと - まんぼーの技術記
とすべきだったのか…?)

0.まずはじめに

まずはじめに、なにはともあれ開催者として一言申し上げさせていただきます。
あ、その前に謝罪しますか

遅れてすいませんでした…
一応毎日研究の合間にコード書いたりデバッグしたりして一日100文字ぐらいは書いてたんですけど年末ということもあって遅れました。
言い訳は以上です。

そして

25日間皆さまありがとうございましたぁぁ!!


技術的なことからゆるふわ趣味趣向の話まで毎日卒論で白目剥きながら口角上げて読ませていただきました。
1、2年生は大半が知らないと思うのですが
このサークル、コロナ前までは
大体なぜかM2どころか卒業してもサークルに顔を出してました(頻度は少なめ)
一応老害という枠になるのですがね…

そんなわけで修士生にマイクロマウス問わず色々なものづくりの相談ができます。
たまに先輩が来たら相談してみたり雑談してみてください。
ふとした話から技術的なことを学べることは多いですし僕は大学で自分で勉強したものより先輩と話してて知ったことの方が多い気もします。
なんなら先日の記事のGASの存在もA.Tさんに聞いて知った気もします。

ま、とりあえず開催者の言葉はここまでにして

幻の26マン(トウェンティシックスマン)
の記事でもいきますか(黒子のバスケをまねただけです)


 さて!アドベントカレンダーの主催者なのでまともな記事をあげておくかと作った先の2つ

(1つめ:
WMMC AdventCalendar 2021 1日目 - judgeのブログjudge.hatenadiary.com
)

(2つ目:
judge.hatenadiary.com
)

を見て、同じクオリティを求められても困りますはい。
僕は卒論生ですから…(現実)
アドベントカレンダーより卒論書かなきゃいけないのに…!(なお0文字)
今日だけ一日中お休みして
明日から卒論機体の評価試験を行なっていこうかなって思っているぐらいなのに…
3つも記事書いてもうたやないか…!

最後ぐらいゆるふわでやらせてもらいます。
これで僕の精神も保たれるので…
MOSIマウス関連の記事が読みたい人がいれば昨年度のあたりは参考になるかもです...(昨年の)

1.またこいつGASかよ

 前回GASというものを紹介しました。

(本記事は前回を前提にするので環境構築等がわからない人は前のを読んでくれると幸いです)
前回→
judge.hatenadiary.com

実はあれには7章目があり、そこで書く予定のものがあったのですが、長すぎたので断念しました。それをここで書きます。

ではまず、僕のGmailの惨状は
メールが数千たまっています。

Gmailの件数、やばないですか?

それもそのはずで、
僕のGmailアカウントは

①大学用
②趣味用その1
③趣味用その2
インターン
⑤その他用

などという無駄におおく、しかもそれぞれそこそこに営業メールが来るのでこうなってます。
大学からは内容も無いメールばかりが届く中で奨学金などの有意義なメールが紛れ込んでいて普通に見逃しがちです。(見逃したことはないですけど)

なので整理したいというか、いらないメールは消し去っておきたいんですよね。

そこで、GASでまず全ての不要なメールを削除します。
これでメールボックスはスッキリするので
その後も毎日不要なメールを削除して行きます。
着信拒否すれば良いと思うんですが、
その中にたまに大事だったり興味のあるメールもあるので着信だけはしておきたい、という感じです。
では早速やっていきます。

2.早速消し去ってみる

僕のGmailを開き、さっそく不要なメールを確認して削除します。
今回は削除対象を
spotify」「AtCoder」「UltimakerCura」からのメールを削除します。
削除理由:興味はもうないので.....

コードは以下のようになります。

/*****************************************************
 * delgmail()
 * 引数:なし 
 * 返り値:なし
 * 
 *[処理の説明]
 *・対象のGmailを消す
 *****************************************************/
function delgmail() {
  //検索条件
  //今回はspotifyとultimakerとAtcoderからのメールはもはや興味ないのでこいつらを消し去ってみる
  conditions="{from:no-reply@spotify.com from:info@e.ultimaker.com from:noreply@atcoder.jp}";

/*複数条件(AND)の場合、条件をスペースで区切るだけでOK
   複数条件(OR)の場合、条件をスペースで区切りつつ、{}で囲う

<基本的な条件検索法>
・「from:」→メールの送り主で検索
・「subject:」→メールのタイトルで検索
・「to:」→メールの送信先で検索
・「is:unread」→メールが未読の場合を検索
・「is:read」→メールを既読した場合を検索
・「is:starred」→メールにお気に入りがついたものを検索
・「has:attachment」→添付ファイルがあるものを検索
・「after:」→指定日以降に送信されたメールを検索
    ex) after:2021/12/20 ⇒ 2021年12月20日以降に送信されたメールを検索

・「before:」→指定日以前に送信されたメールを検索
    ex) before:2021/12/20 ⇒ 2021年12月20日以前に送信されたメールを検索

・「newer_than:」→指定した年数・月数・日数を遡った時点から現在までに送信されたメールを検索
     ex1) newer_than:1d  ⇒ 1日前から現在までに送信されたメールを検索
     ex2) newer_than:2m  ⇒ 2か月前から現在までに送信されたメールを検索
     ex3) newer_than:3y  ⇒ 3年前から現在までに送信されたメールを検索

・「older_than:」→指定した年数・月数・日数を遡った時点から現在までに送信されたメールを検索
     ex1) older_than:1d  ⇒ 1日前以前に送信されたメールを検索
     ex2) older_than:2m  ⇒ 2か月前以前に送信されたメールを検索
     ex3) older_than:3y  ⇒ 3年前以前に送信されたメールを検索
*/

  //上記の条件にあうメールを取得
  delete_mail_list=GmailApp.search(conditions);
 //全消し
  for (var i = 0; i < delete_mail_list.length; i++) {
    delete_mail_list[i].moveToTrash();
  }
}

メールリストは個人情報の塊すぎたので結果は載せられないんですが、
消えました。数百ものメールが。

お、これならスッキリするのもはやいな〜!
って思ってましたが、大学メールで問題が発生しました。

どうやらW大学のドメインが@gmail.comじゃないのはGoogleからGMail機能だけ借りてきてそれをアレンジしたっぽくて、
しかも権限とかの問題でメールの削除、これできなかったんすよね…

まぁしゃーないです。
とりあえず消すことに成功したので
大学メールはこまめに消していこうな〜
(戒め)

GASについてはこれで終わります。
息抜き回というか中間発表が終わったばかりでメンタル的には瀕死なので勘弁してください…

3.で、ここからは適当

 この一年、メイドカフェ行った〜!!
とか、相席屋…とは…?みたいなそういうのは何もなく、面白エピソードも特に何もないんで、書くことないんすよね。
(来年はあると思うんで来年書きます)

強いて言えば今年の2〜3月ごろにはまった
Apex legends
っていうゲームにあるランクシステムで(要するにどれぐらいの実力があるか)で
ダイヤ帯💎って言う、いわばある程度の
一般人ゴール(諸説)
【Apex】一般プレイヤー的にゴールのランク帯ってここじゃね?|Apex Legendsまとめ速報 - えぺタイムズ
に達した、ぐらいですかね…
とはいえ大体1000時間ぐらいやると到達する感じ
(僕は人生初のFPSゲームだったので1100時間ぐらいかかったんですが…)
なので超簡単!ってわけではないです。

1回だけだとまぐれかもなとか思ってとりあえず3シーズン(s9〜s11)連続で行けましたが、(このゲームでは一定期間毎にランクがリセットされる)
ダイヤの上のマスターは絶対に自分じゃ行けないと強く感じた
のと、
これ以上は時間の無駄だなって思ったので
最近は友達とカジュアル回す程度の熱量です。
やらなすぎて下手くそになってきてるんですが
たまに誘って遊んでくれると嬉しがります。

で、 ゲームしてて思ったのが、
FPSというか、簡単でもゲーム作れたら楽しそうだなって。
専門は機械なのでこう言うスキルは役に立つかわからないのですが、
モットーが
「技術は広くそこそこ深く」なので
Unityで簡単なゲームを作ってみた(行動力の権化)
おい誰だ現実逃避って言ったやつ
それを紹介して終わります。
本格的なゲームエンジンでもやってみたいな〜

①金玉転がし
 ただ矢印キーの入力に応じて玉が動くのでそれで迷路をクリアする、だけの簡単なやつです。
もともと少し古めの公式チュートリアルをアレンジしてみたんですが、これやる時に参考にしたらUIが変わりすぎてて何も参考にならなかったのでオススメしません。
ただ研究という現実からの逃避には最適な暇つぶしです。
初めてのUnityの雰囲気つかみでやってみました。
ちなむと金玉なのに金色じゃないのは現実志向だからなんていえない

↓実際のプレイ動画(作者なのにへたくそという残念ぶり)

②シャドバもどき
[謝罪]
→作成していたがバグ多くてなんかの参照無いみたいなエラー出てきてでも参照できてるはずみたいななんかごちゃごちゃしてたら
萎えてやめたので慣性もしてないですし動画もないです。

③Apexというかバイオ?もどき

まーーーーーじで一からFPSゲームなんて個人で作ろうとするものではない(先人のサイトは死ぬほど見て猿真似したが結局デバッグの時に苦労する)

 ま・じ・で脳みそ狂うかと思いましたまる。

ローカル座標、ワールド座標の変換やら
クオータニオンベクター3を用いた様々な計算…

もうなんでそうなるのかわからんけど
Google it したらそうやって書いてあった。
それしか言えません。
恥ずかしながら
私はテンソルやらクオータニオンやらの概念をマジでよくわかってないので解説できない!!!今もわかりません!!!
授業で取り扱った際にも
苦手すぎてよくわからんけどとりあえず単位もらったからヨシ!のスタンスです。
とりあえず聞かれてもよくわからないけどこれを作るにあたって勉強はした。身になったかは置いておいて…

最後の方に追加した何かが悪かったのか、最終版はバグり散らかしててとてもお見せできる状態でないことと、2021年が僕を待っててくれなさそうなので
もうこの状態でだします....
見栄えしなかったので見るに堪えなかったので途中撮っておいた試験版のやつだけ載せます。
今後クオリティが上がったら載せるかもです..
ちなむとこの後追加した敵キャラの動作の幅や操作のオーバーレイは結構クオリティが高くできたので満足でしたが、それらも今はなぜかばぐってて直せません。作戦が卒論優先なので時間がない...
少なくともFPSゲームって作るの難しすぎて二度とApex任意のゲームクソとかいえない身体にされたわ...
では以下、私のつたないPCゲームのおぼつかない操作をどうぞ…

↓実際のプレイ動画(50%完成地点)


(補足)
これらの3Dモデルは無料の外部のやつ持ってきたのでもちろん僕が作ってるはずないです。
こちらのサイトpolyhaven.com
などからテクスチャーは奪ってきました
地形などは作りました。

4.最後に

 以上です。今年はおふざけなしでブログ書いたんですが疲れるのと
性分に合わないなって感じでしたね。
とりあえずゲームはお粗末なものでしたができて動くと楽しいものです。
卒論機体も動けば楽しいのですが…
あ、なんか卒論がバブみ幼稚園にお迎えに来たので帰りますバブッ!

明日は…あれ…バトン引き継ぐ先が…
来年の開催もお楽しみに〜


一応本来引き継ぐはずだったぱわぷろさんの2日連続記事は…

  • >

ss-sholaw-wmmc.hatenablog.com

っていうか2日連続!?
すごいっすねばぶばぶっ!
修論大丈夫なんですか〜?
ここ数年で一番サークルでマウスマウスしてた人の記事なので新入生とかは今後の指針とかに役立つかもです!

では、もうすぐ年明けですね!良いお年を!













…あ?クリスマス?こないだ終わったよ
その話題あと1年は出してくるなよ?

卒論発表前に焦ったはなし

どーも。
卒論やりたくないよーな感じのワシれす。
アドベントカレンダーをこの調子だと遅れて出すのですが、その前に実はその直前に研究室の中間発表があり、正直どたばたしてました。(現在進行形)

事実、卒論設計の発注しないと流石に間に合わねーや(今ここ)で設計と発注を焦ってやっていたら
気づけばアドベントカレンダーの日はすぎて行くんだろう〜なぁ〜。(素知らぬ顔)

そんなドタバタの最中、困ったのでついでに布教と備忘録でもって話。

0.背景
私の研究室の発表はコロナ禍に入ってからは
パワポとそのナレーションを録画してそれを当日流すという形式を取っています。
 
僕はB3の時から(僕の学科ではB3から研究室配属なので中間発表等があります)
これを行うのに
AG_デスクトップレコーダー」というソフトを使ってました。無料です。オススメです。(最終的に)
しかし問題は中間発表前日、
長年使っていたこいつが突然動かなくなったのです。


1.事件

ThinkPadたそ「出力できません」

は?お前は乳首のカーソルもドリフトするしほんまなんやねん潰すぞ(台パン)

突然のエラー通知。混乱する脳みそ。何も考えず先輩に何の録画ツール使ってます?のヘルプLINEを飛ばす本能的理性。

僕はあれソフト前いれたっけ?そうだ多分きっとおそらくmaybe入れ忘れたんだ!(と思い込もおう)
再度サイトからAGデスクトップレコーダーを入れ直そう!
そう思ったところで、

もうー嫌だって!!
何やねんこれもう無理やねんと脳内のボドカさんが叫び始めます。
なんとこのソフトのインストール先のサイトは学内wifiだと危ないサイト判定になっているのでアクセスすら出来なかったのです(は?)

その日研究室に15時半に行ったのも悪かったのですが前日の16時に録音ソフトが用意できてなくてノートパソコン片手に街中を走ってドトールに凸るとはおもわなんだ。

近くのドトールに駆け込み、wifiを借ります。
ほっ、ようやく入れることができそうだ。
カフェモカうめー…
そういやドトールは消し去ったあの、なんだっけあれ、あの甘いパン!
なんだっけ、まぁいいやアレ返せ!!

12月17日追記:
(これを思い出すのにまさか1日丸ごとかかるとはこれを書いているときには夢にも思わなかったのですが甘いパンの答えはクイニーアマンでした)

話は戻って無事ドトールWi-Fiインスコの終了。

そこへ突然あらわれる

「有料プランじゃありません」

の文字。

は?課金しろ?いつからフリーじゃなくなったんだ!?

もう中間発表の録音提出はもうすぐそこ。
焦る自分と貧乏ゆすり初期微動。
ここから使える画面キャプチャツールはねぇのか??ここから入れる保険はねぇのか?
OBS studio やら スクリーンなんたらとかいう
ツールを検索しては

「OBS studio 使い方」
→ごちゃごちゃしてて挫折
サイトが古くて最新のUIに追いついてない
MacBookのUIしかねぇやんけ

などと、無駄に時間を費やすばかり…
ようやく見つけたソフトがあってもまさかの出力形式がmp4じゃないなど、
散々時間だけかけて何も得られませんでした(某巨人感)

目の前のカップルの存在はいつも以上にイラつく。はい密密密密密密密
脳内の過激派小池百合子が発狂しています。
当の僕は
お前が中間発表してみろやなどと言う謎の八つ当たり心ボイスが止まらないやめられない。
そして始まる主要動貧乏ゆすり。

しかしさすがカフェモカ。圧倒的winnerのカフェもか。ナイスカフェモカMVPすぎるのだ。、うますぎて普通にニチャ笑いする。
なんなら目的忘れてyoutube開いて推しのVtuberの切り抜きを見始める落ち着きよう。

ただふと推しの笑顔を見ながら
気づいたのです。
最新バージョンを入れていたことに。
オタク特有のニチャ笑いが止まります。

そうだ花芽すみれ可愛いじゃなかったAGデスクトップレコーダーやるんやった!!!

3.解決…?

AGデスクトップレコーダーは

・フリー版
→数年前にサポート終了したバージョン

・有料版
インスコまでは無料だが使用の際は有料になるサポート付きのバージョン


があり、焦るあまり有料版を入れてしまっていたことに気づきました。ありがとうすみれ。

安堵です。これでデバッグが終わる。
安心していつも通りの録音ができる…
人は解決策を見つけたと思うとここまで安堵するものなんですねはい。

4.解決してくれぅぅ…

そう思っていました。
しかしここで皆さんには思い出してほしいのです。
フリー版は数年前にサポート終了したことに。
もう一度言います。

フリー版は数年前にサポートが終了したことに。

エラーが起こっても知らねー。
不便利な部分があっても知らねー。

そう言うことなのです。

有料版を消してフリー版を入れても
何故か「出力できません」の文字。
またまたぁw
機嫌直してくださいよ〜w
再起動するんでおなしゃす〜w

「出力できません」(再起動後)

あぁあぁあぁああ゛あ゛ぁ゛ぁぁあ!!
(ぶりぶりぶりぶりぶりぶりぶり)

しかしTwitterというのはいいものですね(再確認)

元ツイ廃なので
日頃の経済のニュースも日本の新総理も何もかもをTwitterで知る性癖があったので
Twitter

「AGデスクトップ 使えない」

で検索してみました。
もしそもそもフリー版自体の利用を停止していたら他のソフトを使わねばならないのでまずは周辺捜査です。
しかし、2日前にAGデスクトップ使いやすい!の声が流れています。

どうやらフリー版はまだ使えるらしい。
ダメ元で録音開始します、、

Thinkopadたそ「出力ファイル(以下ry」

握り拳と腕に浮き上がる血管。
周りに聞こえないようにする舌打ち。
抑えきれない中指の勃起。
しかし耐えました。台パンは。
台パンしたら目の前のカップルに哀れなものを見る目で見られかねないしなんなら
いつもいる巨乳で可愛い店員さんに嫌われてしまうかもしれない。(というのも僕は研究室の先輩に連れられてこのドトールによく行くからこの店員さんのことは知っているのだというか
この人に淹れてもらうコーヒーなので美味しいのだ。)

理性とは素晴らしいものです。
僕は大人しくAGデスクトップの設定を1から見直すことにしたのです。

〜5分後〜

結末はのどちんこが勃起する程度にしょうもなさすぎてはっきり言ってえっちぜん龍馬でした。(は?)

昨今のソフトは保存先のディレクトリを自動で指定してくれます。まぁ大抵デフォルトでユーザーファイルに入ってくれるんでもはやチェックする習慣がなかったのですが
出力したらここに保存するよー!ってファイルを毎回手動で作成してパス通しておく必要があるようです。やってなかったんすねー。

まぁちなむとこれで録音は実際にできましたし解決しました。ちゃんちゃん。
結局うまく動かないのはプログラムでもなんでもヒューマンエラーなんすね〜

4.布教
まぁ凝るならOBS studioなんですが
簡易的な用途なら
AGデスクトップレコーダーがオススメです。
AG-デスクトップレコーダー ダウンロードページ

使い方は「ctrl+12」で開始と終わり。

マジで簡単。
下手な設定はほぼなし。
UIがシンプルすぎて使いやすい。

オススメです。

以上終わります。
前もって言っておくとアドベントカレンダー遅れるのでこれでお茶をにごしつつ追加で書いておきましたのでこれで許して…

GoogleAppsScriptしか勝たん

本記事はWMMCAdventCalendar2021

adventar.org

の4日目の記事です。

昨日はImanishi君のEagleでユニバーサル基板の回路設計 - 気ままな日々日記でした。
自分が3年生の時の研究室課題でユニバーサル基板の回路設計があったんですけど、その時eagleでやろうとして面倒くささのあまり途中で投げてしまった記憶が…2.54mm…とか意識してビア開けたんですけど…心が折れたので来年の指導の際に参考にします…


 えーみなさん3日ぶりです。初日がついこないだ終わったと思ったらもう4日目が来てしまい、
記事が足りません。(OB・OGは参加してくださいね(圧力))
というかこのサークルにいる人間は24日と25日は絶対暇だろなんで空いてんだ忙しぶるな

12月4日追記:
aluminum君が24日に入れてくれました!
ありがとう!そして同志すぎる!
そして25に先輩が入ってくれました。
誰に脅迫されたんでしょうか…?
怖い人もいるものですねぇ…?

初日の記事は[これ](https://judge.hatenadiary.com/entry/2021/12/01/000000)です。

目次

0.まずはじめに
1.Google Apps scriptって?????
2.Google Apps ScriptでLINEに通知してみる
3.Google apps ScriptでSlackに通知してみる
4.Google apps Scriptでカレンダー情報を取得してみる
5.Google apps Scriptでのトリガー
 5-1.Google apps Scriptでトリガーを作製する
 5-2.Google apps Scriptでトリガーを削除してみる
6.これまでのすべてを組み合わせると...?


0.まずはじめに

 ことの始まりはすごく単純で、あまり研究室の話は外部に出してはならないので簡潔に話しますと、
今年から研究室のイベントが総務からメール通知されなくなりました。
以前までは会議やイベントの会場や議事録の提出先、資料のアップロード先などがリンクとともに通知されていたのですが
それが廃止となり、各自で「Google Calendar」を見る流れとなったわけです。

僕「いや~でもみるのめんどくさ。」

ちくいち開いて確認するのもだるいし、いきなり明日会議か!?になる未来が容易に想像できました。
そこで毎日1週間先のイベントまで通知してくれないかなって思ったのがGoogleAppsScriptを本格的に触るきっかけとなったわけです。

*実は1年前に仮想彼女を作ってLINEをしようという大層気色悪いユーモアにあふれた記事を投稿したのですが(リア滅の刃(無限爆破編) - judgeのブログ)
あの時は簡単にしか理解してなかったので再度やっていることになるのですが.....

1.Google Apps Scriptってなに

 Googleが提供するJavaScriptベースのプログラミング言語(というかGoogleソフトをCUIで扱うための開発環境に近い気がする)です。
何か自動化するとき、ラズパイだったりだと電源つけっぱにしないといけないのですが、
これは一度書いて実行してしまえば(かつトリガーを管理すれば)電源消しても動くので便利です。
まずは準備です。
Google Apps Scriptのエディタに移ってみましょう。
もちろんこれを見ている諸君はGoogle Chromeを使っているだろうから(エクスプローラerいないよな....?)
Googleアカウンコにログインし、Google Driveに移りましょう。
下の画像の①のところをクリックするとDriveがあるはずです。
f:id:WMMCsaiteihen:20211202011334p:plain

そうしたら②の「新規」→「その他」→「Google Apps Script」の順で進みますと以下のような画面に移ります。
なければ「アプリを追加」から追加してみてください

f:id:WMMCsaiteihen:20211202011832p:plain

これで一応GoogleAppsScriptのエディタ画面に移れたわけです。
これで一応の準備はできました。
ここでこの後の説明が面倒にならぬように「GoogleAppsScript」を「GAS」と略して表記いたします。
よろちくbi

2.Google Apps ScriptでLINEに通知してみる
 なぜ最初がLINEなのでしょうか。というのもSlackへの通知の布石です。
個人的にLINEのAPIの説明は初心者に優しいドキュメントなので実装が楽で勉強になります。
またここでLINEでの実装をしておくとほぼそのままSlackでの実装につなげられます。要するにエッセンス的な感じです。
では早速初めて行きましょう。
そもそもまずAPIをたたく手順を軽く説明します。
LINEからメッセージをいただくには以下の手順を踏みます。

①こちらから「リクエスト」と呼ばれるものをLINEのサーバに送ります。

②「リクエスト」を受け取ったサーバが「リクエスト」内容にそって情報を処理します

③サーバからデータが送られてきます。

④メッセージを受け取れます

これを実行するためにまずは「リクエスト」なるものの中身をどう書けばいいのか、それを調べる必要があるのです。

従ってLINEが公開しているAPIのドキュメント
developers.line.biz
を読みに行きます。が、その前に大切な準備があります。

上記のリンクを踏むと右上にログインボタンがあるのでLINEアカウントでログインしてください。
(日本人の70%がLINEユーザらしいのでさすがにアカウントはもっているものとします)
すると新規プロバイダーを「作製」というボタンがあるのでそれを押してLINEの通知用のアカウントを作成していきます。
名前を決めたら次に以下の画面になると思うので真ん中をクリックしてください
f:id:WMMCsaiteihen:20211202015844p:plain

するとアカウントの名前や説明などを入力することになるのでお好きにしてどーぞ
通知用アカウントを作製したら、まずは「Basic Setting(基本設定)」の項目に移りましょう。
一番下に「Your user ID」があると思うのでそれを保存しておきます
f:id:WMMCsaiteihen:20211202020951p:plain

また、その次に「Message APIの項目に移り、
その一番下にあるAccess Token」「issue」します。
(要するにアクセストークンというURlみたいなのを発行します)
f:id:WMMCsaiteihen:20211202021549p:plain

これもコピーして保存しておいてください
f:id:WMMCsaiteihen:20211202021729p:plain

ではここまでのことをコードに記述しておきます。

function NotifyLINE() {
  const USER_ID="あなたのUserIDを入力";
  const ACCESS_TOKEN="あなたのACCESS_TOKENを入力";
}

ここで関数の名前を「NotifyLINE」にかえておきました。

さぁ!ようやくドキュメント
Messaging APIリファレンス | LINE Developers
を読みます。

「Message」の項目のリクエスト部分の一行目は以下のようになっていると思います。
f:id:WMMCsaiteihen:20211202025557p:plain

その下は「ヘッダー」について
f:id:WMMCsaiteihen:20211202025620p:plain

更にその下は「ボディ」について
f:id:WMMCsaiteihen:20211202025644p:plain

書かれています。
「ボディ」の中の「messages」はさらに配列構造を持っていて
その中身は以下のようになっているということもわかりました。(テキストを送信する場合)
f:id:WMMCsaiteihen:20211202131132p:plain
今回はテキスト(文章)を送信するのでスタンプや動画を送りたいときは
同ドキュメントの別の項を参照してください。

「ヘッダー」やら「ボディ」やらと言いましたがこれらは「リクエスト」の中身です。
つまりこれらを含む「リクエスト」を作製して送り付ければよいのです。
これらをコードに落とし込んでいきましょう

function NotifyLINE() {
  const USER_ID="あなたのUserIDを入力";
  const ACCESS_TOKEN="あなたのACCESS_TOKENを入力";

  //以下が今回新しく記載した部分
  var url="https://api.line.me/v2/bot/message/push";

  var text="Hello, world";

  //リクエストヘッダー
  headers={
  "Content-Type":"application/json; charset=UTF-8",
  "Authorization":"Bearer "+ACCESS_TOKEN
  };

  //リクエストボディ
  body={
    "to":USER_ID,
    "messages":[{
      "type":"text",
     "text": text
    }]  
  };

  //リクエストの作製
  request={
    "method":"post",
    "headers":headers,
    "payload":JSON.stringify(body)
  };

  //fetch:引っ張ってくる
  UrlFetchApp.fetch(url,request);
}

これで準備ができました。
「Ctrl + s」で保存したら実行してみましょう!の前に、
ここで先程の「Message APIのところに行き、
QRコードから先程作製した通知用アカウントを友達登録しておきます。
f:id:WMMCsaiteihen:20211202133902p:plain

友達登録を終えたらGASのエディタから実行ボタンを押すことで通知が来るはずです。
         f:id:WMMCsaiteihen:20211202135521p:plain
これでGASを使ってLINEにメッセージを送ることができるようになりました。


3.Google apps ScriptでSlackに通知してみる

 先程のLINE通知を応用すればSlackへの通知も簡単です。
ちょちょいとコードを軽く変えるだけなのとドキュメントを読めばわかるので詳細は省きます。
それよりもLINEとは異なってSlackに「Incoming Webhook」を入れておく必要があります。
slackを開き①~③の順番でクリックし、
「カスタムインテグレーション」より
「Incoming Webhook」と検索し、インストールします。
f:id:WMMCsaiteihen:20211202142508p:plain
f:id:WMMCsaiteihen:20211202142821p:plain

その後、「Webhook URL」を保存しておきましょう
f:id:WMMCsaiteihen:20211202143537p:plain

これで準備が終わりました。
これらをコードに落とし込むと

function notifySlack() {
 //自分用のslack
  var url="先程のコピーした部分";
  var text="Hello, world";
  
  var body={
    "username":"予定リマインダー",
    
    "text":"<!channel>\n\n"+text,
    
    //自分のSlackの宛先チャンネル
    "channel":"#general"
  }

  var request={
    "method":"POST",
    "contentType":"application/json",
    "payload":JSON.stringify(body)
  } 
  
  UrlFetchApp.fetch(url,request);
}

通知は以下のようになります。
これでGASを使ってSlackへの通知をすることができました!
f:id:WMMCsaiteihen:20211202140434p:plain

4.Google apps Scriptでカレンダー情報を取得してみる
Google Chrome「GAS Calendar」などと検索すると公式のドキュメントに到達します。
これです。
developers.google.com

ではドキュメントを読んでいくのですがサポートされている関数が膨大なので今回は雑に省いていきます。

上から関数を見ていくと
「getEventById」という関数が見つけられま。
f:id:WMMCsaiteihen:20211202164039p:plain

クリックしてみると
関数の詳細が以下のように載っています。
f:id:WMMCsaiteihen:20211202164151p:plain

「Return」のところをみると「CalendarEvent」というものが返ってくるようです。
これをクリックしてみると
このように「CalendarEvent」クラスが表示されます。
クラスの中にある関数(=メソッド)も出てくるのでさらに調べることができます。
また、サンプルコードが出てくることもあります。
さぁコードを書いてみましょうと行きたいですがまず準備があります。
「GoogleCalendar」を開き、以下の①をクリックすると②の部分が出てくるので「設定と共有」をクリックします。
f:id:WMMCsaiteihen:20211202170133p:plain

その後下に移っていくと「カレンダーID」があるのでこれを保存しておきます。
f:id:WMMCsaiteihen:20211202170506p:plain

これにて準備は完了です。
ではまず簡単にカレンダー情報をとってくるコードを書いてみましょう
ここではまず例としてイベント名を取得するコードを書いてみます。

function getCalendar(){
  //もしgooglecalendarが変更になった場合、以下のCALENDAR_IDを変更
  const CALENDAR_ID="    ";//ここに先程のIDを入力!!!!!!

  //calendarIDを元にcalendar情報を取得
  var my_calendar=CalendarApp.getCalendarById(CALENDAR_ID);
  //イベント情報を取得する日を本日に指定
  var start_date=new Date();
  var my_events=my_calendar.getEventsForDay(start_date);
  
  my_events.forEach(function(my_event){
    //ここではためしにイベント名を取得してみる
    var title=my_event.getTitle().toString();
    Logger.log(title);
  })
}

上記の出力結果は以下のようになります
f:id:WMMCsaiteihen:20211202174848p:plain
今日のイベント名は「研究」でした。(してない)

他にも同様の情報を取得できます。
後のコードで紹介するのですが
大体はいかのこのメソッドで取得できます
f:id:WMMCsaiteihen:20211202180013p:plain

以下のコードでやってみます。

function getCalendar(){
  //もしgooglecalendarが変更になった場合、以下のCALENDAR_IDを変更
  const CALENDAR_ID="    ";//ここに先程のIDを入力!!!!!!

  //calendarIDを元にcalendar情報を取得
  var my_calendar=CalendarApp.getCalendarById(CALENDAR_ID);
  //イベント情報を取得する日を明日に指定
  var start_date=new Date();
  start_date.setDate( start_date.getDate() + 1 );

  var my_events=my_calendar.getEventsForDay(start_date);
  
  my_events.forEach(function(my_event){
    //ここではためしにイベント名を取得してみる
    var title=my_event.getTitle().toString();
    var mtg_url=my_event.getLocation();
    var my_event_description=my_event.getDescription();
    var event_start_time=my_event.getStartTime();   
    var event_end_time=my_event.getEndTime();

    Logger.log("イベント名:"+title);
    Logger.log("リンク:"+ mtg_url);
    Logger.log("開始時刻:"+ event_start_time);
    Logger.log("終了時刻:"+ event_end_time);
    Logger.log("説明:"+ my_event_description);
  })
}

結果はこうなります。
f:id:WMMCsaiteihen:20211202181049p:plain

しかしこれだと時刻が見にくいので修正します。
以下のコードに直すと

function getCalendar(){
  //もしgooglecalendarが変更になった場合、以下のCALENDAR_IDを変更
  const CALENDAR_ID="      ";//ここに先程のIDを入力!!!!!!

  //calendarIDを元にcalendar情報を取得
  var my_calendar=CalendarApp.getCalendarById(CALENDAR_ID);
  //イベント情報を取得する日を明日に指定
  var start_date=new Date();
  start_date.setDate( start_date.getDate() + 1 );

  var my_events=my_calendar.getEventsForDay(start_date);
  
  my_events.forEach(function(my_event){
    //ここではためしにイベント名を取得してみる
    var title=my_event.getTitle().toString();
    var mtg_url=my_event.getLocation();
    var my_event_description=my_event.getDescription();
    var event_start_time=my_event.getStartTime(); 
    event_start_time=Utilities.formatDate(event_start_time,"Asia/Tokyo","HH時mm分");  
    var event_end_time=my_event.getEndTime();
    event_end_time=Utilities.formatDate(event_end_time,"Asia/Tokyo","HH時mm分");

    Logger.log("イベント名:"+title);
    Logger.log("リンク:"+ mtg_url);
    Logger.log("開始時刻:"+ event_start_time);
    Logger.log("終了時刻:"+ event_end_time);
    Logger.log("説明:"+ my_event_description);
  })
}

結果はこうなります
f:id:WMMCsaiteihen:20211202181410p:plain

見やすくなりましたね。

これでGooglecalendarから1日のイベントは取得できましたね。
(逆に言えばfor文を使えば何日分もイベントは取得できますね)

7日分のイベント情報を取得するコードは以下のようになります。

function getCalendar(){
  //もしgooglecalendarが変更になった場合、以下のCALENDAR_IDを変更(以下は2021年現在のもの)
  const CALENDAR_ID="  ";

  //calendarIDを元にcalendar情報を取得
  var my_calendar=CalendarApp.getCalendarById(CALENDAR_ID);
  //イベント情報を取得する日を本日に指定
  var start_date=new Date();
  
  //1日のイベントを取得し${SHOW_PERIODS}回繰り返してtextを作成する
  for(var i=0;i<SHOW_PERIODS;i++){
    //今日一日のイベントを配列で取得
    my_events=my_calendar.getEventsForDay(start_date);
    my_events.forEach(function(my_event){//配列の各項目に対して以下の処理を行う
      var title=null; //イベント名
      var mtg_info;   //イベント情報全体
      var mtg_url;    //イベントのURL
      var my_event_description;  //イベントの備考欄
      var event_start_time;       //予定開始時間
      var event_end_time;         //予定終了時間

     //MTGのURLがLocationプロパティに入っているので今回はgetLocation()メソッドを使う
      mtg_url=my_event.getLocation();

      //イベント説明の取得
      my_event_description=my_event.getDescription();

      //イベントの開始・終了時刻を取得、それをフォーマット化する。(Utilities.formatDateをコメントアウトしてLogger.logすれば意味が分かる)
      event_start_time=my_event.getStartTime();
      event_start_time=Utilities.formatDate(event_start_time,"Asia/Tokyo","HH時mm分");
      event_end_time=my_event.getEndTime();
      event_end_time=Utilities.formatDate(event_end_time,"Asia/Tokyo","HH時mm分");      

      title=my_event.getTitle().toString();
      text+="・${month}月${date}日[${day}]の予定\n".replace("${month}",(start_date.getMonth()+1).toString()).replace("${date}",start_date.getDate(). toString()).replace("${day}",day_array[start_date.getDay()].toString());
      text+="`"+title+"`"+"\n";
      text+=" 時間:"+event_start_time+"~"+event_end_time+"\n";
      text+=" MTG場所:"+mtg_url+"\n";

      if(mtg_url!=""){//URLが存在する場合
        text+=" MTG場所:"+mtg_url+"\n";
      }

      if(my_event_description!=""){//説明がある場合
        text+=" [補足事項]\n"
        text+=" "+my_event_description+"\n\n";

        //正規表現をもちいてHTMLタグを消去
        text=text.replace(/(<([^>]+)>)/gi,'');
        text=text.replace(/&nbsp;/gi,"");
        text+="----------------------------------------------------------------------------------------------\n";         
      }else{//説明がない場合
        text+=" [補足事項]\n 無し\n\n"
        text+="----------------------------------------------------------------------------------------------\n";      
      }
    })
    //日付を進める
  start_date.setDate(start_date.getDate() + 1);
  }
      //予定がないとき
    if(text==""){
      text+="この1週間は学部・修士生に関係するイベントはありません";
    }
    //送信するtextの内容を確認する時用の関数
    Logger.log(text);
  return text;
}

結果はこのようになります。
f:id:WMMCsaiteihen:20211202183856p:plain

正規表現などの部分は自分で勉強しておいてください...

5.Google apps Scriptでのトリガー

5-1.Google apps Scriptでトリガーを作製する
トリガーというのは、これまで書いたコードを実行開始する何かしらのきっかけのことを指します。
コードは以下のようになります。
なお実行させたい関数の名前を「ScriptApp.newTrigger」関数に入れておけばオッケーです。

/****************************************************************
 * setTrigger()
 * 引数:なし
 * 返り値:なし
 *
 *[処理の説明]
 *・次の関数実行の時間トリガーを設定する(次の日の0:00) 
 ****************************************************************/
function setTrigger() {
 var setTime = new Date();
  setTime.setDate(setTime.getDate() + 1)
  setTime.setHours(0);
  setTime.setMinutes(00); 
  ScriptApp.newTrigger('実行させたい関数の名前').timeBased().at(setTime).create();  
}

実際に実行し、
以下のように画像の左の時計のマークをクリックすると
トリガーが作製されていることが確認できます。
f:id:WMMCsaiteihen:20211202144706p:plain


5-2.Google apps Scriptでトリガーを削除してみる

上節と同様にトリガーを消すことも可能です。

/*****************************************************
 * deltrigger()
 * 引数:なし 
 * 返り値:なし
 * 
 *[処理の説明]
 *・関数実施トリガーをいったんすべて消す
 *****************************************************/
function deltrigger() {
  const triggers = ScriptApp.getProjectTriggers();
  for(const trigger of triggers){
    if(trigger.getHandlerFunction() == "関数の名前"){
      ScriptApp.deleteTrigger(trigger);
    }
  }
}

6.これまでのすべてを組み合わせると...?

//**グローバル変数の定義***************************************//
//本文の変数text.これに本文を追加していく
var text="";
//曜日の配列
var day_array = new Array('日', '月', '火', '水', '木', '金', '土');

//以下のマクロ(的なの)を変えることでcalendarのイベント情報取得期間を決定している(以下では7日)
const SHOW_PERIODS=7;
//***********************************************************/

/****************************************************************
 * setTrigger()
 * 引数:なし
 * 返り値:なし
 *
 *[処理の説明]
 *・次の関数実行の時間トリガーを設定する(次の日の0:00) 
 ****************************************************************/
function setTrigger() {
 var setTime = new Date();
  setTime.setDate(setTime.getDate() + 1)
  setTime.setHours(0);
  setTime.setMinutes(00); 
  ScriptApp.newTrigger('notifySlack').timeBased().at(setTime).create();  
}

/*****************************************************
 * deltrigger()
 * 引数:なし 
 * 返り値:なし
 * 
 *[処理の説明]
 *・関数実施トリガーをいったんすべて消す
 *****************************************************/
function deltrigger() {
  const triggers = ScriptApp.getProjectTriggers();
  for(const trigger of triggers){
    if(trigger.getHandlerFunction() == "notifySlack"){
      ScriptApp.deleteTrigger(trigger);
    }
  }
}

/******************************************************************
 * getCalendar()
 * 引数:なし 
 * 返り値:Slack通知内容本文
 * 
 *[処理の説明]
 *・GoogleCalendarより1週間分の予定を取得して本文作成
*******************************************************************/
function getCalendar(){
  //以下にCALENDAR_IDを入力
  const CALENDAR_ID= "              ";

  //calendarIDを元にcalendar情報を取得
  var my_calendar=CalendarApp.getCalendarById(CALENDAR_ID);
  //イベント情報を取得する日を本日に指定
  var start_date=new Date();
  
  //1日のイベントを取得し${SHOW_PERIODS}回繰り返してtextを作成する
  for(var i=0;i<SHOW_PERIODS;i++){
    //今日一日のイベントを配列で取得
    my_events=my_calendar.getEventsForDay(start_date);
    my_events.forEach(function(my_event){//配列の各項目に対して以下の処理を行う
      var title=null; //イベント名
      var mtg_info;   //イベント情報全体
      var mtg_url;    //イベントのURL
      var my_event_description;  //イベントの備考欄
      var event_start_time;       //予定開始時間
      var event_end_time;         //予定終了時間

     //MTGのURLがLocationプロパティに入っているので今回はgetLocation()メソッドを使う
      mtg_url=my_event.getLocation();

      //イベント説明の取得
      my_event_description=my_event.getDescription();

      //イベントの開始・終了時刻を取得、それをフォーマット化する。(Utilities.formatDateをコメントアウトしてLogger.logすれば意味が分かる)
      event_start_time=my_event.getStartTime();
      event_start_time=Utilities.formatDate(event_start_time,"Asia/Tokyo","HH時mm分");
      event_end_time=my_event.getEndTime();
      event_end_time=Utilities.formatDate(event_end_time,"Asia/Tokyo","HH時mm分");      

      title=my_event.getTitle().toString();
      text+="・${month}月${date}日[${day}]の予定\n".replace("${month}",(start_date.getMonth()+1).toString()).replace("${date}",start_date.getDate(). toString()).replace("${day}",day_array[start_date.getDay()].toString());
      text+="`"+title+"`"+"\n";
      text+=" 時間:"+event_start_time+"~"+event_end_time+"\n";

      if(mtg_url!=""){//URLが存在する場合
        text+=" MTG場所:"+mtg_url+"\n";
      }

      if(my_event_description!=""){//説明がある場合
        text+=" [補足事項]\n"
        text+=" "+my_event_description+"\n\n";

        //正規表現をもちいてHTMLタグを消去
        text=text.replace(/(<([^>]+)>)/gi,'');
        text=text.replace(/&nbsp;/gi,"");
        text+="----------------------------------------------------------------------------------------------\n";         
      }else{//説明がない場合
        text+=" [補足事項]\n 無し\n\n"
        text+="----------------------------------------------------------------------------------------------\n";      
      }
    })
    //日付を進める
  start_date.setDate(start_date.getDate() + 1);
  }
      //予定がないとき
    if(text==""){
      text+="この1週間は学部・修士生に関係するイベントはありません";
    }
    //送信するtextの内容を確認する時用の関数
    Logger.log(text);
  return text;
}

/******************************************************************
 * notifySlack()
 * 引数:なし 
 * 返り値:なし
 * 
 *[処理の説明]
 *・getCalendar()関数より帰ってきた本文をそのまま通知する
*******************************************************************/
function notifySlack() {
  deltrigger();
  setTrigger();
  var text=getCalendar();

  var body={
    "username":"Calendar",
    "text":"<!channel>\n\n"+text,
    //自分のSlack時
    "channel":"#random"//好きなチャンネル名に変えてください
  }

  var request={
    "method":"POST",
    "contentType":"application/json",
    "payload":JSON.stringify(body)
  } 

  //自分用のslackのID
  var url="   ";
  
  UrlFetchApp.fetch(url,request);

}

f:id:WMMCsaiteihen:20211202184633p:plain
結果としてSlackにカレンダー情報を1週間分取得して通知してくれるシステムが完成しました。


さて、明日はxfa君の
GMSなんていらん!?」
です。
すまん単語がまずわからん…から何書いてくれるのかわからんけどとりあえずお楽しみに!

WMMC AdventCalendar 2021 1日目

この記事は

WMMC Advent calendar 2021

adventar.org

の1日目の記事です。

当方は素人で、内容についての厳密性などが欠けていることがありますのでご了承ください。

0.開催者の戯言

さて!皆さまお久しぶりです。 コロナ第三波?の中始まったなんとも楽しくなさそうな1年も大半が過ぎ、今思えばなかなか楽しかった気もします。(気のせいです) そんな一年の最後の師走。 皆さんはどんな一年でしたか?

卒論・修論で大変な人もいると思います。(僕です) 社会人一年目で早くも転職を考えている人もいるでしょうか() それとも、初の対面授業にやっと大学生活っ!を感じた人もいるのかもしれません。

僕は、まぁ寂しさと悲しさが多かった一年でした。 研究室が違うとコロナも相まって仲の良かった同期とも会うことはなくなりました。 中には一人で何かを抱えてしまう人もいたでしょう。 悲しいこともいくつかありました。

寂しい、といえば入学して仲の良くなった先輩達(今年だと2つ上)はもう卒業ですね。 気が早いんですけど少し寂しいです。未だに自分が1年生の気分でいるときがあるので..

とまぁしんみりはおいといて 最後ぐらい楽しくブログのリレーでもしましょうか。(記事をたくさん書くことになると卒論と相まってつらくなるんでOBOGの人参加者募集です)

1.本題

 AdventCalendarの予約の内容を見ていると各々が結構楽しそうな記事を上げそうなので 僕はここ1週間で頑張ってまともな技術的な記事を書いてみました。 内容はそれなりに複数用意していたんですけどいくつかお粗末すぎるのでまともなやつを先に上げておいて、 参加者がいなければお粗末すぎるやつも挙げていきます(仕方ないので) 最悪まともなやつを2分割すればよいので大丈夫ですが。 (11/30追記:結局今回の記事の類似版を別の記事にするかもです)

以下のリンクを踏むとここから先が読めます(変なサイトとかじゃないので踏んで大丈夫です。) ただ、開くならPCがおすすめです

ここから先

2.最後に

バトンを渡し損ねる前にここで渡しておきます(笑) 明日はぱわぷろさんの記事で

「動画…作ってみないか?」とのことです。

例の某SAMURAIのほうで培ったスキルの紹介なんですかね...? よくわかんないですけど読むの楽しみにしてます。 忙しい中2日目に入れてもらって助かりましたありがとうございました!!!!!!!! ついでに3日目も入ってくれた後輩くんもカンシャッ!

また、その他の参加者の皆さんも年末のお忙しいところ大変ありがとうございました。 ちなむと今のうちに言っておくと僕に気力さえあれば()来年も僕が主催でやるつもりなので 参加よろしくお願いします!

飲食における「●/円」の追求

1.はじめに
お久しぶりです。皆さんお元気でしょうか。
コロナという聴き慣れなかった単語も、もはや聞かない日が1日もない、そんな1年半を過ごしていると思います。
その中で仕事が無くなったり、バイトが減ったりと収入面で困った方はいるのではないでしょうか。

収入が減ると、食費の点で非常に苦労しますよね?
そこで、私はある素晴らしい評価単位を考えました。
(ここでいう評価単位は独断と偏見に満ちた評価関数のようなものです)

そう、

「○/円」

です。
これの素晴らしいところは、食材に求める目的に対してのコスパがわかるというところにあります。

例えば、食材毎に
「ビタミンC含有量/円」
を調べるとしましょう。
ビタミンCには以下の効果があります。

ビタミンCが不足すると、コラーゲンが合成されないために、血管がもろくなり出血を起こします。これが壊血病です。壊血病のそのほかの症状としては、いらいらする、顔色が悪い、貧血、筋肉減少、心臓障害、呼吸困難などがあります。また、毛細血管・歯・軟骨などを正常に保つ働きがあるほか、皮膚のメラニン色素の生成を抑え、日焼けを防ぐ作用や、ストレスやかぜなどの病気に対する抵抗力を強める働きがあります。

 最近はビタミンCの抗酸化作用が注目され、がんや動脈硬化の予防や老化防止にビタミンCが有効であることが期待されています。

引用:ビタミンCの働きと1日の摂取量 | 健康長寿ネット(2021年8月20日現在)

例えば、あなたが壊血病を防ぐ食生活をしたい時、この評価単位を用いればどの食材がコスパよく壊血病を防げるか、がわかるのです。
でも、自分で勝手に作っておいてアレですが、
本当にコレでいいのでしょうか。
工学的には評価関数はある程度厳密に作成するものですが、今回はおふざけなのでガバガバ評価をしてみたいと思います。

これによる評価は本当に適した食材に行き着くのか、それを知るべく、我々は日本社会の食材に目を凝らし始めた…


2.これはアカンかった
いや結果から言ってアカンかった。
色々調べてみたので実際に紹介しつつ、読者にも「これはアカン」を追体験していただこう。

➀「kcal/円」
以前Twitterで見かけた気がするが、この評価指標は結構なじみがある人も多いと思う。
コスパ良く太りたい人・安くエネルギー源を補給したい人に向けている。

まずは身近にあるもののの中でカロリーの高そうなものを3つほど調査してみよう。
ここでは「ラーメン」・「ポテトチップス」・「カロリーメイト」を調べてみる。

まずはデブ食代表の「ラーメン」だ。
ラーメンといっても味や種類によってカロリーが違うと思われるのでネットにあった二郎情報で算出を行った。

二郎系ラーメン
値段:900円(アバウト)
カロリー:2500kcal(大盛時)
kcal/円:2.7777

という結果となった。これだけではこの値が高いのか、低いのか全く分からない。そこでほかの2つでも算出してみた。

ポテトチップス のり塩(湖池屋)
値段:144円(アバウト)
カロリー:337kcal
kcal/円:2.34

カロリーメイト ブロック チョコレート味
値段:170円(最安)
カロリー:400kcal
kcal/円:2.353

どうであろうか。あのコスパ最強とよばれ、一杯食べると1日他の食事が不要とまで言われる二郎ラーメンや、デブ食の代表ポテチ・さらには「カロリー」を冠するカロリーメイトをもってしても「kcal/円」で3を超えられないという結果となった。

では、逆に3を超える食べ物は何なんであろうか。
僕が簡単に思いついたものとしては
ブラックサンダー
②チョコチップスナックパン

がある。
実際、それぞれを計算してみると

ブラックサンダー
値段:32円(アバウト)
カロリー:112kcal
kcal/円:3.5

...おぉ!!強い!つえー。ここにきて大台の3を軽く超え、4に近い値を確認することができた。
この調子で次も算出してみる。

チョコチップスナックパン(山崎製パン株式会社)
値段:178円
カロリー:1152kcal
kcal/円:6.47

f:id:WMMCsaiteihen:20210824225301p:plain
今回のチョコチップパン

...「kcal/円」界の吉田沙保里が来ました。インフレ甚だしいにもほどがあります。
これを超えるものはないです。調査終了!

















と、思い込んでいました僕は。
でも気づいてしまったんです。
「サラダ油」直飲みの可能性に。もう一度言います。

「サラダ油」直飲みの無限の可能性に。

あの「wawawa」然り、この世には「サラダ油」直飲み勢がいあるはずでしょう。多分きっとおそらくmaybe...
算出してみましょう。

サラダ油(1300g)
値段:342円(アバウト)
カロリー:11700kcal
kcal/円:34.2

f:id:WMMCsaiteihen:20210824230201p:plain
悪魔の飲み物

..................................異世界転生モノのチートってこんな感じなんでしょうね。
コスパ良く太る・安くエネルギー源を補給する、の解答はこれで間違いありません。
....ね、アカンでしょ????

②「アルコール含有量/円」
まぁこれは言ってしまえば安く酔いたい人に向けた指標です。
っていってもじゃあ「エタノールとかの原液飲みなよウェイwowwow」って話ではなくて、
市販の飲料で比較します。流石に。
ここではまず、「日本酒」「スト缶」「スピリタス」あたりでやってみましょう。
ノリが軽いけどスピリタス出してるの笑う

用いる式は

摂取量(ml)×度数(%)×0.01×0.8(比重)=アルコール含有量(g)

です

日本酒(関白 壱弐七)
値段:990円(アバウト)
アルコール含有量:124.992g
アルコール含有量g/円:0.126

スト缶(500ml)
値段:211円(アバウト)
アルコール含有量:36g
アルコール含有量g/円:0.17

スピリタス
値段:2073円(アバウト)
アルコール含有量:384g
アルコール含有量g/円:0.18


これらからわかることはこの指標では0.2を超えるのは非常に難しいということです。
日本酒はアルコール度数が22度以下である必要があり、今回の指標では小さい値になっています。
逆にあのスト缶はスピリタスに近い値をとっており、実質安価スピリタスです。
毎日3本程度飲んで研究・仕事・課題などの嫌なことは忘れましょうお酒はほどほどにしましょう

で、話はまだ終わらなくて。
まぁ異世界チーターを探してみたんですよ。この指標での。

いたんですよ。最強が。
僕の脳内には「おいしいかもー」の声とあの愉快な音楽が聞こえてきます。
ちゃっちゃっちゃーちゃっちゃちゃちゃー
ちゃっちゃっちゃーちゃっちゃちゃちゃー デーン♪

f:id:WMMCsaiteihen:20210825000603p:plain
wawawaの生命線

そう、こいつですね。

業務用ハイボール(5000ml)
値段: 6,779円(アバウト)
アルコール含有量:1600g
アルコール含有量g/円:0.236

0.2こえたぁぁあぁぁぁぁぁぁ!!!!!!!!!!
....wawawa恐るべし...

このようにコスパを追い続けると破綻を招くことがわかります

3.最後に
 いかがだったでしょうか(底辺サイト感)
このように「/円」を食材に求めすぎると、人外を目指す必要があることが判明しました。

今後も何かの「/円」を追っていきたいと思います。

なにかもっと上があれば教えていただけると幸いです。

追記:
餅(業務用)→9.8kcal/円で
チョコチップスナックパンを超えてます