どらめも

なんでもないことをかきます

Unity初心者がググったりしたことの忘備録

まえがき

ミクさんにおうちでも踊ってもらいたくない??wowwowARミクさんアプリだとみくちゃとかが有名ですね。完成度が高くて素晴らしいと思います。ですが著作権とかもあるのかな、曲に合わせて踊ってくれる機能に関してはついていません。ないなら作ればいいじゃないか、我々にはUnityとか強いARのapiがある、ということで頑張ってみました。なお始まった時点では筆者はsceneってなんやってくらいUnityの初心者でした。(今も初心者ですが)今回ググりまくって色々やったのですが情報がたくさんありすぎて結構時間がかかったので動いたものに関して個人的に引っかかったところをQ&A方式でブログは書いていきたいなと思います。
注意ですがとりあえず私の環境で動くというだけなので、もっといいやり方があるかもしれないし間違っているかもしれません。(なので間違いはコメント等でビシバシ指摘していただけると幸いです)

前提知識

jyukoさんのARがわかる本(https://jyuko.booth.pm/items/1560126)というのを最初にやりました。やった本はこれだけです。Unity初心者にもわかるようにめちゃくちゃ親切に書いてあるし、Unityでは今最新?のARFoundation(Unity用のAndroidiOS両対応のライブラリ)使えるのでとてもオススメです。この本に書いてあることは本を買ってください。主にARFoundationの基礎的な使い方です。

環境

macOS Mojave(バージョン10.14.5)
Unity 2019.2.6f1
Xcode Version 11.1

Q&A

Q1

ARだとキャラクターを元からヒエラルキーに置かずにinstantiateしたりして配置することも多いけれど、そのキャラクターに対する操作はどうやってやればいいの?
誤答例
Assetsからスクリプトに直接キャラクターのプレハブを[Serializefield]などを用いてアタッチして動かす
解説
誤答例のようにしてしまうとゲーム画面には存在しないけど確かにどこかに存在するキャラクターに対しスクリプトの処理を実行してしまうのでinstantiateしたオブジェクトは思い通りに動かないし、エラーメッセージも出ないので意味不明に陥ってしまいます、、、、、正解としてはinstantiateした返り値を用いて処理の実行を行います。以下に例を示します。

character = Instantiate(prefabs[0], trackedImage.transform);  
Animator animator = character.GetComponent<Animator>();  

上の例だとcharacterにアタッチされているAnimatorを取得しています。このように返り値を通常のゲームオブジェクトと同様に扱うと良いです。

Q2

ボタン押したときに関数を実行したくない?wowwow
誤答例 ゲームオブジェクトのボタンを[Serializefield]使ってアタッチしてなんかやろうとする
解説
ボタンを操作するにはUnityについている機能を使います。onClick()というやつですね。結構時間がかかったので丁寧に説明します。
1. 何らかのGameObjectにアタッチされているスクリプトの中でボタンに紐付けたい関数をpublic属性をつけて宣言する。

public void onClickscreen(){
    Debug.Log("HelloWorld");
}
  1. f:id:doradorasuki:20191018180718j:plain
    ボタンの設定

    以上のようにします。ゲームオブジェクトの欄にはヒエラルキーからゲームオブジェクトをドラックアンドドロップし、その後、関数を選びます。(選べる関数は自動で出てきます)
    以上のようにすると、ボタンが押されたときに指定した関数が呼ばれるようになります。実はとても簡単です。

Q3

IOSにアプリを焼くとUIのレイアウトが思ってたのと違うようになるけどどうすればいいの?
解説 Canvasのinspectorの設定をいじりましょう。(Canvas Scaler)

f:id:doradorasuki:20191018181443p:plain
Canvasの最適化

Canvasの設定をiOSに揃えました。UI Scale ModeはScale With Screen Sizeです。私の開発機のiphone8はx=320,y=568と調べたら出てきました。あと、Matchをwidth=1まで引っ張ると見た目の横の縮尺が合う代わりに縦がおかしくなります。逆も然りです。どうやらUnityのウィンドウ上の横長の長方形はどうにもならないみたいです。(うまい方法があるなら教えて欲しいです)しっかりと合わせたいときはウィンドウで合わせるのではなく数値を設定して合わせましょう。数値の基準は先ほど設定したReference Resolutionです。出来るだけ初期に設定してしまうことをお勧めします。

Q4

スクリプト同士で変数の共有したいけどどうやればいいかわからん!!!publicとかかいとけばいいの??
解説
1. 宣言したいスクリプト内でpublic宣言します。(GameObject hoge内のhogehoge.csとします)

public int flag ;

こんな感じですね。ここで注意なのですが、グローバル領域で初期化してしまうとupdate関数が呼ばれるたびに初期化されてしまうのでやめましょう。startなどの中で初期化しましょう。
2. 別のその変数を使いたいスクリプトでゲームオブジェクト、スクリプトの取得を行う。

[Serializefield]
private GameObject hoge;
hogehoge hoge_script;
void start(){
    hoge_script=hoge.GetComponent<hogehoge>();
}

void hello(){
    hoge_script.flag=1;
}

そしてSerializefieldにGameObject hogeをアタッチする。
こうすることでhello関数を実行するとpublicのflagが1に更新されます。まあしかしpublic変数をいたずらに増やすことはバグの原因になるので注意しましょう。

Q5

たくさんのScene使いたい!!
解説
sceneが増えるとアプリっぽくて嬉しいし機能増やしやすくていいですよね。
1. File->new sceneで新しいsceneを作成してsaveし、sceneを作っていく。
2. 変数の共有などをする
[やり方]
変数宣言するシーンで

public static string music_title;

こんな感じでstatic宣言しておく。(関数の外です)
その後変数を利用したいシーン内において

[変数宣言したシーンの名前].music_title

で利用可能です。引き継ぎなどはunity側がやってくれるみたいです。とてもラクチンですね。

Q6

キャラクターにアニメーションつけて、スクリプトで操作したいねー
解説
1. Animator Controllerを作成しEntryから順番に遷移したい順番に右クリックして矢印を生やして繋げる。(Entryから一つ目へは勝手に遷移するので注意)

f:id:doradorasuki:20191020230330p:plain
Animator Controllerの例

こんな感じですね。 2. parametersのタブで遷移の条件となるparameterを作成する(今回の画像はbool値で作成しています)
f:id:doradorasuki:20191020230508p:plain
Parametersの例
ここで注意ですがbool値の場合チェックが入っていない場合初期値がFalseになります。逆も然りです。
3. 1.で作成した矢印を選択し、矢印の遷移条件を定める。
f:id:doradorasuki:20191020230704p:plain
矢印の遷移条件

parameterを使う場合Has Exit Timeはオフで良いそうです。(ここよくわからないので誰か教えてください())
conditionsのところでparameterと遷移の条件を設定します。
4. スクリプトでいじいじする。

Animator animator = character.GetComponent<Animator>();
animator.SetBool("odoru", true);

今回の例だとこんな感じです。 今回はcharacterというゲームオブジェクトにAnimator Controllerがアタッチされているとします。(characterの中にキャラの3dモデルが子として存在しています)
Animatorをゲームオブジェクトから取得した後で、animatorを操作します。parameterの名前はそのまま流用します。意外と簡単です。(時間かかりました)

Q7

UIをデフォルトのものじゃなくてもっと綺麗にしたいな
解説
試行錯誤中

あとがき

Unityよくわかんないですね。今回いわゆる入門本的なものを買わずに(結構高いので)ググってやっているわけですが、↑の内容全部入門書の1章とかに書いてありそうな気がしているのでこれからUnityやる人は本買うなり公式のチュートリアルするなりしたほうがいい気がします。また気づいたことがあったらどんどん追記予定です。間違いあったらどんどん指摘してください。

seleniumでスクレイピングする話 ~ページ解析用にseleniumIDEを添えて~

まえがき

突然ですがch○nithmnetって使いにくくないですか??フレンドランキングはアクティブ10人までしか見れないし、プレイ回数ランキングは見れないし、そのくせに有料だし...。機能がないなら作ればいいじゃない!ということでseleniumというchrome自動操作ライブラリの存在を知ったので上の機能を実装してraspberry piに食べさせてslackで情報を送ると自動であれこれしてくれるようにしました。やったね!今回の記事はその時に得たselenium周りについての記事です。

スクレイピングについて

基本的に相手方のサーバに負荷をかけるやり方はDoS攻撃として見なされる可能性もあるし、そもそもマナーとして好ましくないのでpythonだとtime.sleepなどを用いて適宜時間を置くようにしましょう。当ブログの方法でaimeの垢バンとか訴えられたとかあったとしても一切責任は取れませんのでご了承ください。スクレイピングについて、Pythonだと主にrequestsモジュールを扱うやり方とseleniumでブラウザを直接操作して行うやり方の2通りがあります。今回の実装ではログイン処理などが伴うため、それのやりやすいseleniumで実装しました。そのため、今回の記事では後者について説明します。

使ったライブラリとか

使用した言語はPython3です。 今回使うツールは
selenium(chromeの操作)
・BeautifulSoup4(htmlの解析)
GoogleChrome(Chromium)
・seleniumIDE(HPの解析)
です。前の二つはpythonのモジュールとしてダウンロードでき、seleniumIDEはChrome拡張機能としてダウンロードすることができます。一番つまづきやすそうなポイントとしてGoogleChromeを操作する際に別途chromedriverが必要になるのですが、これはChromeのバージョンに合わせたものをダウンロードしてくる必要があります。適当にググってください。
あと、seleniumIDEを使うとデスクトップ上でスクリプトを書かなくても簡単に動作を自動化できるらしいですが、そういう使い方については今回触れていないのでご了承ください。

seleniumを使ってみる

では早速使っていきましょう。まずは

from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.google.com")

でとりあえずchromeGoogle.comを表示してくれます。とても簡単です。これからのブラウザの動作は全てこのdriver.なんちゃらで行なっていきます。
それでは次に実際にホームページを操作してみましょう。今回の例はウェザーニュース(https://weathernews.jp/onebox/)の例を用いて行います。(chunithmnetは毎月お金を払わないと色々見れないので...)
これが多分今あなたの見えているWebページです。

f:id:doradorasuki:20190916170939p:plain
ウェザーニュースHPのスクリーンショット

今回は目標として都市名のところに大阪、と打ち込み、検索ボタンを押すことをまずは目標とします。それでは操作をするためにまずホームページのソースコードをのぞいてみましょう。ホームページのソースコードの見方はわかりますか?今回GoogleChromeを例にとって説明すると、右上のグーグルアカウントのアイコンの右にある設定を開くボタンをクリックすると、
f:id:doradorasuki:20190916171649p:plain
Chromeの設定画面のスクリーンショット

このように表示できるので、その他のツールからデベロッパーツールを選びます。(macだとcommand+alt+iでもひらけます)
そして、sourceからweathernews.jp/onebox/(index) みたいなファイルをクリックするとページのhtmlソースが見れると思います。それでは文章の部分のbodyを見てみましょう。seleniumでは基本的にここに書かれいたりする情報を指定してクリックや入力を行います。(html周りについては筆者もよく知らないのでググるなりなんなりしてください)

 <header id="header">
        <section class="header__bar">
            <figure class="wni-logo"><a href="https://weathernews.jp/"><img src="https://smtgvs.weathernews.jp/onebox/img/logo-wni.svg" alt="ウェザーニュース"></a></figure>
        </section>
        <section class="global-search">
            <form onsubmit="search_city1();return false;" class="search-box">
                <input type="text" id="search_city_input1" placeholder="都市名,郵便番号,市外局番など" class="form-txt">
                <button type="submit" class="form-submit">検索</button>
            </form>
        </section>
    </header>

適当に今回の目標的に必要そうな日本語が並んでいるところをコピペしてきました。ここら辺は頑張って見つけてください。(それかのちに説明する方法を使いましょう)
まず、都市名のところに大阪、と打ち込みたいのですが

<input type="text" id="search_city_input1" placeholder="都市名,郵便番号,市外局番など" class="form-txt">

こういうものが日本語的にhtmlから読み取れると思います。ここの情報を使っていきます。今回はこのidの情報を使ってみましょう。(要素の指定方法は複数あるので、うまくいかない場合は他の方法を試してみたりします。)

place_form=driver.find_element_by_id("search_city_input1")
place_form.send_keys("大阪")

idを用いて記述する場合にはfind_element_by_idメソッドを用います。文字の入力には基本的にsend_keysメソッドを用います。簡略化して

driver.find_element_by_id("search_city_input1").send_keys("大阪")

と書くこともできます。find_element_by_なんちゃらには色々あってclass_nameやxpathなど必要に応じて使い分けることが可能です。
そして、次にクリックですが、

<button type="submit" class="form-submit">検索</button>

このように記述があるので次はクラスを指定してクリック操作を行いたいと思います。すると、

place=driver.find_element_by_class_name("form-submit")
place.click()

こんな風になります。簡単ですね。seleniumの基本動作はこれが全てです。プログラミングというよりいかに正しく操作できるタグを早く見つけるかです。のちのtipsで紹介しますが、プラウザバック操作などもメソッド一つで簡単に行えます。
(xpathとは
XPath (XML Path Language)とは、XML形式の文書から、特定の部分を指定して抽出するための簡潔な構文(言語)です。 HTML形式の文書にも対応します。 CSSではセレクタを使ってHTML文書内の特定の部分を抽出しますが、XPathはより簡潔かつ柔軟に指定ができるとされています。
Google先生に検索かけたら出てきました参考程度に)

seleniumIDE利用の勧め

前の項で感じたと思いますが、seleniumの操作はとても簡単です。それでは何が大変なのか。そうhtmlをよんで要素を指定するところです。ウェザーニュースのページは比較的操作しやすくhtmlも綺麗ですが、ページによっては動作がjavascriptで書いてあったり、別のソースファイルに書いてあったりとそもそも発見が困難な場合があります。(筆者もこれになって一時期諦めました)そこで登場するのがseleniumIDEです。本来の使い方とは異なるかもしれませんが、非常に有用なツールです。なんとホームページのクリックしたところに働いているcssxpathを簡単に知ることができます!!前の項にhtmlを読もうとか書きましたが、これを使えば読む必要がないです!!(ちゃんとしたseleniumIDEの使い方すればそもそもpython書かなくていい説がありますが、今回はslack_botに移植が最終目標だったためpythonで書きました)それでは実際に使っていきましょう。
seleniumIDEは前項の通り、chrome拡張機能として公開されているのでインストールしてください。開いて適当にプロジェクトを作ってください。今回は調べ物として使うだけなので適当でいいです。

f:id:doradorasuki:20190916183544p:plain
seleniumIDEのスクリーンショット

こんな風な画面になると思います。Playback base URLには自動化を始めるURLにしておきましょう。あとはRECボタンを押すと、そのページにおける自分の挙動を記録することができます。さっきのウェザーニュースのページで色々やってみましょう。さっきのページで文字入力するところをクリックして、大阪とうち、検索ボタンをクリックすると、以下のような感じになると思います。
f:id:doradorasuki:20190916184337p:plain
操作後のseleniumIDEのスクリーンショット

今回だと3番目がフォームのクリック、5番目が検索ボタンのクリックに該当します。また、seleniumIDEでは対象をクリックし、targetを変更することで、その要素の他の指定項目を参照することが可能です。
f:id:doradorasuki:20190916184653p:plain
seleniumIDEのtarget

それではせっかくなので今回はxpathを用いて先ほどと同じ操作をしてみましょう。すると、こんな感じのコードになります。

place_form=driver.find_element_by_xpath('//input[@id="search_city_input1"]')
place_form.send_keys("大阪")
place=driver.find_element_by_class_name('//button[@type="submit"]')
place.click()

先ほどのhtmlと格闘するよりは10000000000倍くらい楽勝だし正確です。しかもこれだとjavascript関連でも結構問題なくいけます。この方法について書いてあるところがあまりなかったので今回ブログに書いています。ちなみにこのcss情報などは次の項で説明するBeautifulSoupでも応用可能です。収集したい文字列のところをクリックすると、そこについての情報がseleniumIDE上に表示されます。

BeautifulSoupで要素を抜き出してみる

ブラウザを動かしたところでやっと情報の収集です。この項ではウェブサイトから文字列を拾ってくるやり方について書きます。そのためにBeautifulSoupというライブラリを用いてhtmlから情報を取ってきます。そのためにまずdriverからhtml情報をもらいます。

from bs4 import BeautifulSoup
soup=BeautifulSoup(driver.page_source,"html.parser")

driverからはdriver.page_sourceでhtmlを取得可能です。parserとは、htmlのタグ情報から情報を解釈するプログラムのことらしいです。今回は標準搭載されているhtml.parserを採用しています。これにより、soupからはタグなどに応じた情報取得が可能になります。それでは1例としてウェザーニュースのサイトの時刻情報を抜き出してみましょう。時刻情報についてhtmlを読んで調べてみましょう。(今回もseleniumIDEを用いてcssの情報が取得できれば、それを利用することが可能です)

<div class="weather-day__item">
                                <p class="weather-day__time">17:00</p>
                                <p class="weather-day__icon"><img src="//smtgvs.weathernews.jp/onebox/img/wxicon/200.png"></p>
                                <p class="weather-day__r">0mm/h</p>
                                <p class="weather-day__t">25℃</p>
                                <p class="weather-day__w">5m/s<br></p>
                            </div>

今回はこのような記述があるので17:00という文字列を取得したい場合は

weather_time=soup.find("p",class_="weather-day__time")

を実行します。しかし、これでは一番初めにp class="weather-day_time"でヒットしたものがweather_timeに格納されます。全てを取得したい場合は

weather_time=soup.find_all("p",class_="weather-day__time")

を使いましょう。
ちなみに、(わかりやすいようにsoup.findの方で説明します)このときにprint(weather_time)を使うと

<p class="weather-day__time">23:00</p>

のようにhtml情報がprintされます。
これを避けるためにはprint(weather_time.string)とすると23:00と表示されるようになります。あと、この後sortなどをする場合に知っておくべきこととして、実験してもらうとわかると思うのですが、print(type(weather_time.string))の実行結果は

<class 'bs4.element.NavigableString'>

このようになります。なので、sortなどをしたい場合には必要に応じて文字列の組み替えなどを行なった上で適切な型にキャストしてやる必要があります。(筆者はこれでハマりました)pythonって普段型意識しないのでこういうところで詰まると発見が難しいですね。
以上のようにするのがBeautifulSoupの基本操作だと思います。

知っていると良さそうなTips

ここはコードを書く上でググったりして得た知見を適当に羅列しておきます。
・バグったり、うまくいかないときはtime.sleepとかでページの遷移を待つといいかもしれません(基本がブラウザ操作なので表示されるまでは情報が得られません)
chromeを表示させたくないときはheadless chromeとかでググるといいかもしれません
・driver.execute_script("javascriptのコード")でjavascriptのコードを実行させたりできます
・Alert(driver).accept()で出現したダイアログに対し、OKを送ることが可能です
・BeautifulSoupでcssを指定したいときはsoup.select(CSSの指定先)で指定可能です(seleniumIDEとの併用に便利)
xpathを使えばクリック操作はうまくいきやすい気がします(ただの経験則です)
・ブラウザバックはdriver.back()でできます
・最後にdriver.quit()するのを忘れないようにしましょう(無限にウィンドウが増えます)

最後に

スクレイピングの項でも触れましたが、過度なアクセスは相手方の迷惑になるためNGです。スクレイピングは仕様、用法を守り正しく服用しましょう。
できるだけググりやすいように記事は書いたつもりです。(環境構築とか書きたくないので)
以上の情報で少なくともch○nithmnetをスクレイピングするコードは書けます。
私の書いたch○nithm用のコードは github.com

に上がっているので興味があったり例をみたい人はどうぞ。
ここまで読んでいただきありがとうございました。

Fixstarsインターン参加記

事務的なこととか概要

この夏に3週間ほどフィックスターズさんで機会があり、インターンシップに参加させていただきました。私は組み込みOS入門というテーマで横浜オフィスでインターンシップに参加しました。(本社は大崎です。)ちなみに横浜勤務は10数名いた同期の中で私一人でした。(ええっ...)大崎オフィスでは知り合い同士が隣同士とかもあったみたいでウラヤマ〜でした。他のタームには横浜勤務の人もいたらしいので少し残念でした。インターンシップの概要についてはそんな感じです。

参加するまでの流れ

OSとかに興味があってそういうのやってそうなインターンないかなーと例のスプレットシートみてたら発見したので募集始まったらすぐさま応募しました。(AtCoderjobsに水色とか書いてあったので緑だった私は普通に応募しました)すると、面接しましょうのメールが来たので面接と、ライブコーディングの試験をして通過という感じです。インターンの面接はほとんどしたことがなかったのですが、雰囲気も良く話しやすい感じでした。

インターンシップの内容

私の行ったことは特に業務機密に関わるようなことでもなく、メンターの方から許可をいただけたので書いています。横浜オフィスは業務の契約上開発に直接触るような人のみの部屋を設ける必要があるらしく、事務やインターン、アルバイトの人は部屋が分かれていました。(残念)そのため、直接疑問点などを聞くというよりは、slackで質問を投げたりgitlabでレビューしてもらったりするのが中心でインターンシップを行なっていました。私個人的には集中しやすくて良い環境だったと思いました。レスのスピードも十分早かったです。 そんな中で具体的な話をしたいと思います。私がしていたのはbeagleboneとよばれるハードの強いラズパイのようなものにQNXと呼ばれる組み込み向けOSを搭載し、そこにカメラを接続し、そのカメラのドライバのようなプログラムを書いたりすることでした。 実際企業に貢献するようなことは何もしていません()

QNXについて

まず最初に私の扱ったQNXやその内部の仕組みについて説明しておきます。QNXときいて馴染みがあった人はすごいのでぜひ組み込み界隈で頑張ってください。私は知りませんでした。気になる人はwikipediaとか(https://ja.wikipedia.org/wiki/QNX)で詳しく調べてみてもらえると幸いです、簡単にいうと組み込み向けのリアルタイムOSです。ライセンスが必要ですが、学生ライセンスがあるみたいな話も聞きました。特徴としてマイクロカーネルOSと呼ばれる仕組みを採用していて、OSの機能が小さく、OSの機能だったものがそれぞれ小さなタスクとして独立に動いています。(下記の図を参照)そのため、例えばDevice Driverに変更を加えたい、となった場合OS全体に変更を加える必要がなく、あくまでDevice Driverのみに変更を加えれば良いので保守性なども高いと言えます。

f:id:doradorasuki:20190911194437p:plain
wikipediaより引用
そして、この仕組みを制御しているのがQNXではリソースマネージャという仕組みです。これについて少し説明します。
リソースマネージャというのはデータの受け渡しを制御するサーバープログラムのことでこれを用いるとディレクトリに仮想の設定フォルダ的なものを出現させてそこに命令を送ることで様々な動作をさせることが可能です。例として私のやったことでいうと、

cat /dev/Camera/satsuei >sample.jpg  

でカメラを用いて写真を撮れるようにし、

echo 1600X1200 > /dev/Camera/kaizoudo   

でカメラの解像度を変更できるようにしました。リソースマネージャを駆使することで、システム内のread,write命令などによって様々な動作が可能になります。QNXでは通常のファイルシステムなどもこの仕組みによって構築されているそうです。

f:id:doradorasuki:20190911200615p:plain
リソースマネージャについて

実際にやったこと

・ドキュメントを読んだ
・接続したカメラと頑張ってデータの受け渡しをした
・リソースマネージャの実装とその応用
簡単に書くとこの3つに私の3週間は集約されます。まず初めにドキュメントについてですが、QNXというOSには基本的にドキュメント以外に参照できるものが存在しません。日本語の記事は当然ながらほとんどないですし(Qiitaの記事は1人の人が少し書いた2件のみ...)英語の記事も全然ないです。そのため基本的にドキュメントと戦うかどうしようもなくなったらメンターの人に聞いてみるかどちらかしかないです。Qiitaとかはてブしか日常的に読んでいなかった私にとってこのことはとても辛く、かなり時間のかかる作業でした。話に聞くところによると企業の人はどうしようもなくなったら契約してるQNXサポートに聞くので問題ないらしいです。(ええ...)カメラのユーザーガイドなんかも初めて読みました。次にカメラとの接続に関してですが、spiやi2cとよばれるシリアル通信の規格を用いてデータの受け渡しを行いました。実際のコーディングについてですが、もちろんpythonとかでimportするだけで終わる話じゃないのでデータの通信を行うべきレジスタを指定したり、タイミングチャート読んだり、データの読み飛ばしをしたりと普段は意識しないことをたくさんしました。ポインタ辛いよ〜とか言っている場合じゃないくらいポインタを多用したのでふえええってなってました。最後にリソースマネージャの実装ですがこれもドキュメントとの格闘でした。リソースマネージャはある程度決まった仕組みなので仕組みの上に乗る感じで謎の関数などを使うわけなのですが、それについての情報などがドキュメント上でかなり分散していてふえええってなってました。(n回目)しかも動かないくせにコンパイルはすぐ通るのでデバッグが大変でした。あとドキュメントに乗ってない情報もあり、ヘッダファイルを読みにいったりもしました。ドキュメント読んで実装するってとても難しいですね。そして最後に残った時間で解像度のコマンドの実装やtcp通信を使った写真データの受け渡しの実装などをしました。

感想

今回コードを書いていく中でメンターの方から大量のコードレビューをいただきました。今回の実装は全てCで行ったのですが、エラー処理をはじめとした、実装方法などのレビューを大量にいただき、すごく勉強になりました。(職場の方に聞くとそのメンターの方は特に厳しい方だったそう)プログラミングをしていてこんなに自分のコードに対して指摘を受けたのは初めてだったのですごく新鮮でかつありがたかったです。(大学の実習などは基本的に動けば何も言われないので)これからは日常的に指摘されたことなどを注意していきたいと思いました。あとは日常的にドキュメントとかもっと読もうと感じました。
あとハードウェアを扱う上でのデバッグの難しさも感じました。いつもは基本ターミナルが全てなのでデバッグもまあまあという感じですが(ほんまか)、今回の場合プログラムはもちろんのことハードウェアの繋ぎミスやQNXとしては関数が実装されていてもその関数がbeaglebone上では非対応であるために動かないということなどがありました。その場合はもうどうしようもないので他の方法で書き直しました...ハードウェアを扱うって難しいですね。
またオフィスについてですが、作業環境は16gメモリのubuntuデュアルディスプレイでライセンス的にokなら好きに環境構築していいって感じだったのでとても作業しやすい環境でした。先ほどにも触れましたが、コミュニケーションツールもslackとgitlabが基本で扱いやすかったです。あと個人的に好きだったのが10円でドリンクが飲めるところでした。コーヒーだけじゃなくココアとかジュースとかもあって嬉しかったです。

最後に

今回のインターンシップは業務に触れるという感じではありませんでしたが、色々と学びも多くとても良いインターンシップでした。フィックスターズ社にはとても感謝しています。ありがとうございました!
また、私の参加したものは横浜でしかも組み込みに関するもので結構フィックスターズでも特殊なインターンシップだと思うので、高速化とかに興味あるよって人は是非他の人の体験記なども読むのもいいと思います。

enjapma.hatenablog.com

ysugiyama.hatenablog.com

ここまで読んでくださり、ありがとうございました。

AtCoderで水色になった話

AtCoderでやっと水色になれたので変色ブログを書きたいと思います。
注意ですがこのブログの著者は競技プログラミングに真剣とは言えない態度向き合い方が目立つので競技プログラミングに真剣な方はここで読むのをやめて引き返してもらえると幸いです。
あとこういうアルゴリズムが使えるようになったよとかはバイアスもあるしそもそも僕よりまともな人が大勢いるので他の方の変色記事を書いていただけると幸いです。

ここまでに解いた問題数など

とりあえずみんな大好きProblemsと精進グラフ、Scoresを載せておきます。 f:id:doradorasuki:20190826001423p:plain
f:id:doradorasuki:20190826001441p:plain
f:id:doradorasuki:20190826001416p:plain
精進して無いですね〜17ヶ月かかってやっとポイント的に10万くらいです。グラフ見るとわかると思いますが精進してる時期としてない時期の差が明確です。してない時期はとりあえずコンテストだけ出ている感じです(最悪)。感触として(新ABCだとやや異なりますが)300まではコンテスト中に解けないことはまずなくなりました。(AGCは別として)400位も大方解ける感じです。500は練習してないのでガチャでSSR引かないと解けません。数学の地力は高校数学の参考書は一通り解けるよくらいで同じ大学の人には3秒で抹殺されるレベルなのでAtCoder的にはそういうアドはないと考えてもらって結構です。

なぜ水色になれなかったのか

根本的に僕はコンテストが好きな人間であって問題を解くのが好きなタイプでないことが挙げられると思います。100分(ABCだと)という限られた時間内で頭を回すのは好きですが、精進は好きじゃないしなんなら時と場合によっては嫌いです。そういう人は多分急激に精進をしてコンテストのパフォをあげてーのサイクルに入れるといいんだと思いますけど僕にはそれができなかったしそもそも少し精進してもレートが上がりませんでした。下に僕のパフォーマンス推移を載せておきます。
f:id:doradorasuki:20190826003413p:plain
精進グラフと見比べてもらうとわかると思うんですが、精進してもパフォーマンスが変わっていません!!!!(ええええええええ)いやいやいやいやこれは引退でしょとn回思いました。こっちは授業時間もやったのに。。。そしてやる気も消えました。(そんなこと言ってる暇あるなら精進しろやという話ですが)僕が水色になれなかった理由として大きく分けて二つの理由があると僕は思いました。(完全に個人の主観と感想なのでくだらない戯言くらいで読み流して欲しいです)
・ABCは500解けるか400速解き安定できないと水色に上がるのは厳しい
AtCoder全体のレベルが上がっている(青色以上はしりません)
まずは一つ目に関してですが、直近5回のABCを見てみるとABCDEを解けた人の最低パフォはABC138から1265、1717、1631、1299(これはDまで)←この回は5完で2309なので...、1361と何十回も出ていると1100くらいでレート50くらいあげるためにはパフォが1600くらい必要なので(これは人によって異なるし記憶ですが)5完か速解き4完はまあ必要そうってことがわかると思います。しかし僕はEまで解けたことはないのでそりゃレートが上がらないよねって感じでした。Eの練習はあまりしていなかったのでそりゃ解けません。人間天才じゃない限り解いていない点数帯が突然解けるようになったりしません。そして、速解きというのは上から殴る場合を除いては問題ガチャ的な性質を持っているところもあるので安定しません。
水色になりたい人はEを解けるようにすると早いと思います。
そして二つ目に関してですが、先に断っておきますがここからは数値的な話ではなく完全に感覚の話です。水色以下のレベルは新規参入者もあり、多分上がっています。というのもここ最近はBFSやDFSとか簡単なdpとか昔水色のための必須スキル?はささっと書けないと冷えます(ABC128-Dとか最たる例)。一昔前の水色になるための必須スキルは今や緑を維持するための必須スキルになっています。(あと最近中学受験数学的な問題をサラッととく技術が必要な気がします。(中学受験してないので詳しくはよく知りませんが))これが割と一つ目の理由にも繋がってきます。(あと今のABC-Dは旧ABC-Dよりも簡単です)

コンテストに出続けることについて

僕の他の人にない特徴としてコンテスト出場回数が多いくせにレートが低くて精進量もイマイチだというのがあります。それについてなのですが、精進やりたくない時にはやらなくていいけどコンテストには出ようという僕の考えがあります。まず競プロはただのネトゲなので(本気でやってる人はすみません)やりたくない時はやらなくていいと思います。楽しむためにやっているゲームで不快になるのは本末転倒だと思います。(なので話は変わりますが僕は音ゲーにおいても下埋めという作業(地力の養成のために低難易度の譜面を全てやること)があまり好きではありません。精進したくなった時に精進すればいいです。界隈には息を吸うように精進をしている人もいるし、なにより精進はして当たり前みたいな空気が流れてますが、別にそこに乗っかりたい人は乗っかればいいし必ずしも乗っかる必要もないわけです。競プロが世界の全てではないですし。まあでも目標(僕でいう水色)があるならログインという意味も込めて(レートガチャでもいいので)コンテストには出るべきです。一度無くしてしまった習慣を取り戻すのはなかなか難しいもので(ゲームとかでもそうだと思います)(しかもコンテストは土曜の夜という一週間で一番目か二番目に嬉しい時間)出なくなってしまうともうでないと思います。あとこれは競プロ特有だと思いますが、周りのレベルの上昇についていけなくなるような感じがしています。僕の経験談ですが、精進してもパフォが全然上がってないのはギリギリレートを維持できていたことの裏返しでもあると感じています。一度下がったレートを上げ直すのはhighestを上げるよりも全然精神的にしんどいので(失敗ができない)コンテストに出ないのはあまりオススメしません。あと、精進レートとか量は指標にしたくなりますが勉強時間を指標にするなの議論と同じでといたからと言って解けるようになるものでないし1回で解けるようになる人間とかもいたりするのであんまり気にしすぎるとよくないです。(自戒)(周りを見ると自分よりrated points sumとか低くて青色とかザラにいるので)

AtCoder以外でやったこと

・競プロキャンプに行った
これは単純に楽しかったのでオススメです。趣味や興味が似ている人たちと遊んだりBBQしたり素数大富豪するのは楽しいですね。あとこの頃競プロモチベはあまりなかったのですが行ってみるとみんなそれぞれ頑張っててモチベが湧いたりもしました。その日の夜のABCは初めて人と同じ空間で解いてしかも温まったので最高でした。レートがなくてオンサイトいけないよって人も行くといいかもです。
ICPCに出た
学科の友達と今年はICPCに出てみました。結果は3完でまあ実力が出たなあという感じでしたが(大学内ほぼ最下位)チームでデバッグし合うというのはまたいつもと違って新鮮味があって楽しかったです。

さいごに

なんか感想文みたいになっちゃいましたがまあいいでしょう。(これはqiitaじゃなくてブログなので)精進することも大事ですが、せっかくの趣味を嫌いになってしまうのももったいないし思いつめすぎないことも大事なんじゃないかと思ってこのブログを書きました。最後に僕が水色という色に固執した理由について話しておきます。それは私の好きな音楽ゲームにおいてもとりあえず100クレ入れて考えるとか虹レまではチュートリアルとか(これは賛否両論ありそう)があり、競プロでいうそれが水色であると感じたからです。(青以上の人に怒られそう)実際これを音ゲーで感じていてある程度実力がつかないとそのゲームの面白さは理解できないし、楽しい高難易度譜面にまともに挑戦することすら叶いません。そこで僕は水色を目指し、水色に固執しました。(想像以上に時間がかかりましたが)初期段階の終わった今はとりあえず色落ちしないように頑張っていきたいと思います。(青色は流石に遠すぎるので...)ここまで拙い文章を読んでいただきありがとうございました。では