まっつーのブログ

本の感想や振り返りなど雑多に書いてます

2022年3月振り返り

42 Tokyoでの取り組み

  • C++STLコンテナ再実装

mapの実装をAVL木で実装しました。
これで必須パートのvector、stack、mapの実装が終わったことになります。

残りは細かい仕様の確認と実行速度の改善など行っていく予定です。

4月中旬には完成させたいですね。


42 Tokyo x 株式会社ドリーム・アーツのイベントでした。

耐障害性など普段あまり考えたことがなかったので、勉強になりました。
内容についてはnafuka11さんがまとめられています。

nafuka.hatenablog.com

その他

グループワーク形式でDBやAPIの設計について考えられて楽しかったです。
チームで良い設計について議論ができて学ぶことが多かったです。 LTはDB設計の話が特に勉強になりました。

少しずつRuby on Railsでの開発に慣れてきました。 できることも微量ながら増えてきたので、今後も42の課題と並行して取り組んでいきたいです。 また普段オフラインで業務しているのですが、気軽に隣にいる人に質問できるのは魅力的だなと感じています。 オンラインの場合だと質問するのにも文章を考えたり、返答に時間がかかったりと色々コストがかかるので、オフラインならではのメリットもありそうです。

読書

先月から引き続き読書会に参加して色々読みました。

基礎の基礎から丁寧に解説してあるので、考え方や解法の導き方など順を追って学べました。

まだ解けていない練習問題があるので、移動中などに考えるようにしています。 今後も時間を見つけて残りの問題も解いていきたいです。

学生時代にあまり数学を学んでこなかった方こそ読むべき一冊だと感じました。

問題の解き方が学べるというよりは、数学的思考力の必要性や実際にどのように考えるかなどを知ることができました。もっと早くに読んでおきたかったです。とてもオススメです。

今のところ順調に読み進められているので初心者に優しい本です。 0章の環境構築がWindowsしか書いていないので、一瞬つまずきかけました。Macユーザーにも優しくしておくれ。。
まだ3分の1くらいしか読めてないので続きは来月に持ち越します。

  • タコピーの原罪

久しぶりにちゃんと漫画を読みました。

おわりに

桜の季節はロゼワインが飲みたくなりますね。
食事と合わせやすいので、普段飲まない方もぜひ試してほしいッピ。

2022年2月振り返り

42 Tokyoでの取り組み
  • ターミナル上に回転する3dモデルを表示する課題

github.com

ペア課題でターミナル上に3dモデルを表示するプログラムを作成しました。

お互い空いた時間に進めようと話していましたが、ペアの方がめちゃめちゃコミットしてくれたので、自分も1週間ほぼこれだけやっていました。短期間で学ぶことがたくさんあり楽しかったです。

自分たちは平行投影で実装しましたが、中にはレイトレーシングで実装しているチームもありそれぞれ個性があって面白い課題でした。

反省点としては互いのコードをレビューをする時間があまり取れていなかったことです。
事前に防げそうなバグが後から見つかったので、プルリク時のコードレビューで少しでも気になった点は気軽に質問し合うべきでした。反省です。
今後のペア課題に活かしたいと思います。


  • C++STLコンテナの再実装

ひとまず vectorと stack の実装まで終えました。

本家と実行速度の比較など細かいテストはしていませんがひとまず動くようになったのでmapの実装に入ろうと思います。

内部で平衡二分木を使用するので、AVL木とRB木のどちらで実装するか考え中です。 今の所比較的シンプルに実装できそうなAVL木でやろうかな〜と心が揺らいでいます。

その他

Webを支える技術を購入しました。

今月の頭にこのような投稿をしたところ、

と42の友人に声を掛けてもらったので、
それから毎朝1時間読書会を行っています。

それぞれ学んだ内容を発表し合っているので、様々な知識が身についていい感じです。
ぜひ今後も継続していきたい。。

ちなみに今月は

以上3冊読みました。

Webを支える技術は、いつか読もうと思っていたのでこのタイミングで読めて良かったです。

過去の自分の投稿を見ると内容も良かったみたいですね。

ちなみにアルゴリズム x 数学本は読破できず。。

急いで読むものでもないので今後も地道に読み進めていきます。


Railsを用いたインターンに今月から参加しています。

オフラインなので運動不足が解消されそうです。わーい。


完走しました。

そしてこちらが感想記事。

ryo-manba.hatenablog.com

おわりに

振り返ってみると今月も色々取り組んでいたみたいです。 3月も頑張るぞ〜。

Rails チュートリアルを完走した

はじめに

今月からRailsを用いた開発に携わることになったので、かの有名なRails チュートリアルに取り組んでみました。 大体かかった期間は1ヶ月です。

内容

TwitterのようなSNSアプリケーションの開発を通して学びます。

MVCモデルとはなんぞやというところから始まり、少しずつステップアップしていくことができます。

ソースコードは全て記載されているので、文法などを学びつつ写経(or コピペ)して進めていきます。

感想

率直な感想としては、Webアプリケーション開発の基礎を学ぶのにとても良い教材だと感じました。

その代わり分量がかなり多いので、完走するぞ!というモチベで取り組まないと途中でやめてしまう気がします。

また手取り足取り教えてくれるので、自分で考えて課題解決しながら学んでいきたいという方にも向いていないかもしれないません。

個人的には、これまでC言語C++などでCUIのみで動作するプログラムの開発を行うことが多かったので、楽しみながら学習することができました。

事前にRubyの文法について学習していたので、文法面では大きく戸惑うことはありませんでしたが、HTML、CSSに関してはかなりなんとなくで進めていました。。

テスト駆動開発をベースに進めていくので、開発手法も学ぶことができて、今後に繋がる良い学習となりました。

今後取り組む方へ

完走してみて重要だなと思ったことは、

  • 1周目はざっくり理解でサクサク進める。
  • なるべく時間は空けずに進める。

この2点です。

分量がかなり多いので、全てを1周目に理解しようとするとかなりの時間がかかります。
気になった点があれば調べても良いと思いますが、なるべくサクサク進めてしまった方が良いと思います。

私自身、現在2周目に入っていますが圧倒的に内容が頭に入ってきている気がします。
なんとなくで進めていたところも2週目となると理解できるようになってくるのでオススメです。

また時間を空けてしまうと、嫌になって挫折してしまうかもしれないので、ぜひ短時間で進めることを意識してみてください。

おわりに

Webアプリケーション開発の基礎的な部分が学べて良かったです。復習しつつ理解を深めていこうと思います。

これが無料で見れるのは激アツだと思うので、興味ある方はぜひ試してみてください。

2022年1月振り返り

はじめに

活動を振り返ることで、自分の現在地や次のステップが見えてくるという噂を耳にしたので、今年から毎月振り返り記事を書きます。(いつまで続けるかは不明)
主に42 Tokyoでの取り組みが中心になりそうですが、さっそく振り返っていきます。

42 Tokyoでの取り組み

約3ヶ月前から取り組んでいたレイトレーシングのペア課題をクリアすることができました。
ベクトルの計算すらあやふやな状況からのスタートだったのでかなり苦戦しました。
グラフィック系の課題は分かりやすく結果が出るので、予想通りに表示された時の達成感が大きかったです。 ペアを組ませて頂いた方には大変お世話になりました。感謝です。

C++の課題は8つステップで構成されてあり、クラスや継承、例外などC++独自の構文やルールを通じて基本的なOOPについて学ぶことができました。
この課題もレイトレーシングの課題と並行してコツコツ進めていたので、なんとか終わらせることができて良かったです。
今月は勉強会と称して毎日3〜8人くらいでボイスチャットに集まって進めていました。ピアラーニングのおかげでいいペースで進めることができて良かったです。

その他

2022年の目標であったインターン採用をしていただきました。嬉しい。。
来月からRuby(Rails)を用いた開発に携わらせていただく予定です。

  • Rubyの勉強を始めた

インターンで使用する予定なのでRubyの勉強を始めました。
AtCoderのABCのAB問題をRubyで解いたり、RailsでTODOリストの作成などを行いました。

今やっていること
  • STLContainersの再実装

具体的にはvector, map, stack, setなどのデータ構造とイテレーターの再実装に取り組んでいます。

江添亮の入門C++ | 江添亮のC++入門を参考にvectorの実装から進めていますが、なかなか時間がかかりそうです。。

途中まで読みました。
後回しにしてしまっているので来月中には読破する予定です。

始めたばかりなので、まだまだこれからです。頑張りたい。

おわりに

来月からは42の課題と並行してインターンでも貢献できるよう精進していきます。
2月も頑張るぞ。

2021年振り返り

軽い自己紹介

25歳ソムリエの Ryo です。以前はミシュラン2つ星レストランやワインバーに勤めていました。
現在はエンジニア転職を目指して、42TokyoでC言語を中心にコンピュータの基礎から学習しています。

はじめに

2021年を一言で表すと
「42」
これにつきます。
1月に入学試験のPiscineに参加し、4月に入学してから毎日約10時間以上を学習に費やしてきました。
そんな怒涛の一年間を振り返ってみます。

42で行ったこと

カリキュラム

  • libc, fgets, printfの再実装

  • TCP/IPサブネットマスクなどネットワークの基礎知識を学ぶ課題

  • DockerでLEMP環境の構築

  • シグナルを使ったメッセージの送受信を行う課題

  • 2つのスタックを限られた操作でソートする課題

  • X Window Systemのラッパーライブラリを利用してfractalを表示する課題

  • 食事をする哲学者の問題

  • bashの再実装(ペア課題)

  • debianをインストールしてパスワードポリシーやパーティションなどの基本設定を行う課題

  • IPv4のルーティングを学ぶ課題

その他

  • テストフレームワークの実装(ペア課題)

  • Go, Node.js, Vue.js の基本的な構文を学ぶ課題

  • 2週間に渡るPython版Piscineの参加

  • コードレビューを100回行う(課題によるが1回につき1時間程度)

  • 亀山会長に腹筋を見せる

  • Tutorになる

個人的に行ったこと
触った技術

C言語
1年間ほとんどCでコードを書いてました。 libcの再実装から始まり、2ヶ月間かけてbashの再実装を行ったりしました。

C++
主に競プロで利用していました。42の課題を通して基本的な構文やオブジェクト指向プログラミングについて学び始めています。

Python
42のPython Piscineをきっかけにちょっとした作業で使ったりしています。 Discord Botの作成、NBA API を利用したデータのグラフ化などを行いました。

Go
42の課題で軽く触れました。これから本格的に勉強していく予定です。

Node.js
Node.jsとsqlite3を利用してCRUD操作を行うREST APIを作成しました。

Vue.js
42の課題で軽く触れました。

印象的な課題

約2ヶ月に渡るbashの再実装は、これまで取り組んできた課題の中で一番濃かったです。
GitやNotionを利用して細かく情報共有を行いながら課題を進めていきました。
マニュアルやbashのソースを読みこむ必要があり、実装量も多いため時間をかけた分、学ぶことがたくさんあったように思います。
ここでコードの読みやすさや一貫性、機能の疎結合化などを意識するようになりました。
またペアの方がエンジニアとして10年以上の経験があったため、課題の取り組み方や実装方針の立て方、困難にぶつかったときの解決方法などを教わりました。
現在はここで学んだことを意識して日々の課題に取り組んでいます。

印象的なできごと

詳細は省きますが、亀山会長に腹筋を見ていただくという貴重な経験をしました。今年こそはマッチョになりたいです。
42TokyoのTutorになれたことも印象的でした。今後も積極的にコミュニティに貢献していきます。

今やっていること

Raytracingのペア課題に取り組んでいます。これでC言語の課題が終わるので1月中に完成させたいです。 C++、Goの勉強も少しづつ行っています。

今年の目標
  • firstcircle突破

  • AtCoder 入緑

  • アルバイト or インターン or 就職

  • ブログを月1回以上更新

改めて1年間を振り返って

42Tokyoで多種多様な人達と出会い、ともに成長していくことができたと思います。 さまざまな価値観や考え方に触れることで自分にない気づきを得ることもありました。 今後もピアラーニングを通じて成長していきたいです。

おわりに

出会ったすべての人に感謝です。2022年も頑張ります。

モンテカルロ法を用いた四目並べAIを作ってみた

制作物

github.com

はじめに

C++で立体四目並べのプログラムを作成しました。

ただ交互にコマを置いていくだけだと、おもしろくない(そもそも戦う相手がいない)ので、敵を作ることにします。
なるべく強キャラにするため、モンテカルロ法というアルゴリズムを用いて実装してみました。

モンテカルロ法って?

ランダムな候補手で終局までゲームをシミュレーションし、その中でもっとも勝率の高いものを次の手として選択するアルゴリズムとなっています。

シミュレーション回数が少ないと得られる結果はデタラメとなってしまいますが、回数を増やすことでより統計的な分布を得ることができます。

このアルゴリズムを利用したコンピュータ囲碁が世界トップ棋士を倒したことが一時期話題になっていましたね。

実装

四目並べの盤面を 縦 6 x 横 7 としているため、置ける手数は 7 通りあります。
それぞれ 1~7 に対して順番にシミュレーションを行うことで最善の手を選ぶような実装にします。

実装する上で注意する点は

  • 勝利判定
  • 盤面の継承
  • シミュレーション方法

の3点でした。

順に説明していきます。

勝利判定
愚直に縦横斜めに4つコマが並んでいるかをチェックします。
またすべてのコマが埋まっている場合引き分けとなります。

盤面の継承
シミュレーションをするために、ユーザーの代わりのAIと相手のターンにプレイするAIの2つで盤面を共有する必要があります。
そのため、それまでの盤面のコピーのオブジェクトを生成して、2つのAIそれぞれでコピーしたオブジェクトを参照するようにしました。

そうすることで本来の盤面に影響を及ぼさずにシミュレーションを行うことができます。

Board copyBoard = board; // これまでの盤面のコピー
 // それぞれ同じ盤面を参照する。
Cpu userCpu(1, copyBoard);
Cpu ememyCpu(2, copyBoard);

シミュレーション方法

それぞれの手に対して、最も勝率が高いものを探します。

シミュレーションの流れは以下になります。

  1. プレイヤーがコマを置く。

  2. int score[7] を0初期化する。

  3. 一手目を決め打ちする。(1~7)

  4. 互いにランダムでコマを置きあい、勝利したら score[一手目] += 1(scoreを増やす)

  5. 指定されたシミュレーション回数分 3、4 を繰り返す。

  6. もっともscoreが高い手を選択してコマを置く。

  7. 決着がつくまで 1 から繰り返す。

シミュレーション回数を100にした場合の例

void Cpu::montecarlo(const Board &board, int depth)
{
    if (depth >= g_maxDepth) return; // 指定した回数になるまでシミュレーションを行う
    playOut(board, depth);
    montecarlo(board, depth + 1);
}

こんな感じで再帰的にシミュレーションしていました。


以上の3点に気をつけることで、つよつよの四目並べAIを作ることができました。
めでたしめでたし。

感想

今回の実装はいわゆる原始モンテカルロ法でそれぞれの手に対して複数回のシミュレーションを行うだけでした。そのため実装もかなりシンプルにできたと思います。
それぞれの手を成長させていくモンテカルロ木探索というアルゴリズムもあるので気が向いたら試してみたいです。

興味ある方はぜひ戦ってみてください〜。

参考

モンテカルロ木探索-コンピュータ囲碁に革命を起こした新手法

nba_apiを使って1996年ドラフトNo.1プレイヤーを決めてみた

はじめに

スター選手が多いことから伝説とされる1996年ドラフトで
誰がNo.1なのかnba_apiを使って決めてみました。

方法としては、各スタッツの合計値をもとにグラフで表示し確認しています。
言語はPythonです。


制作物

github.com


まずはnba_apiを使って、stats.nba.comから情報を取得します。
サイト内にあるサンプルコードをもとに試してみます。

from nba_api.stats.endpoints import commonplayerinfo

def main():
    # データを取得
    player_info = commonplayerinfo.CommonPlayerInfo(player_id=2544)

    # DataFrameオブジェクトに変換
    pd = player_info.player_headline_stats.get_data_frame()
    print(pd)

if __name__ == '__main__':
    main()
$ python3 main.py
   PLAYER_ID   PLAYER_NAME TimeFrame   PTS  AST  REB    PIE
0       2544  LeBron James   2021-22  25.9  6.8  6.6  0.161

いい感じに選手の情報が取得できていますね。


次にこの情報を元にmatplotを使ってグラフにしてみます。

from nba_api.stats.endpoints import commonplayerinfo
import matplotlib
import matplotlib.pyplot as plt

def main():
    # データを取得
    player_info = commonplayerinfo.CommonPlayerInfo(player_id=2544)

    # DataFrameオブジェクトに変換
    pd = player_info.player_headline_stats.get_data_frame()

    # 各項目を取得
    pts   = pd['PTS'][0]
    ast   = pd['AST'][0]
    reb   = pd['REB'][0]
    name  = pd['PLAYER_NAME'][0]
    frame = pd['TimeFrame'][0]

    # matplotの設定
    left   = [1, 2, 3]
    label  = ['PTS', 'AST', 'REB']
    height = [pts, ast, reb]
    fig    = plt.figure('NBA STATS')

    plt.bar(left,height, tick_label=label, align='center')
    plt.title(name + ' (' + frame + ')')
    for x, y in zip(left, height):
        plt.text(x, y, y, ha='center', va='bottom')
    plt.show()

if __name__ == '__main__':
    main()

実行してみる。

おおー。いい感じにグラフにできました。
さすがレブロン、36歳でこのスタッツですからね。すごすぎる。

またplayer_idを変更することで他の選手のデータも取得できます。
以下に選手の情報がまとまっているので参考にしました。
https://github.com/djblechn-su/nba-player-team-ids/blob/master/NBA_Player_IDs.csv

ウェイドのスタッツもこんな感じで取れます。
引退してる選手に関してはキャリアスタッツが取得できるみたいですね。


そして本題の1996年のNo.1プレイヤーを決めていきます。
調べてみると ID が連番になっているみたい(なっていない選手もいるが今回は割愛)なので、ドラフト1位から順番に60位までの情報を取ってみます。

from nba_api.stats.endpoints import commonplayerinfo
import matplotlib
import matplotlib.pyplot as plt

ID_IVERSON = 947
NB_DRAFT   = 59

def get_info(id):
    player_info = commonplayerinfo.CommonPlayerInfo(player_id=id)
    return player_info.player_headline_stats.get_data_frame()

def get_players_info(start, end):
    pd = None
    for i in range(start, end):
        try:
            pd = get_info(i)
            print(pd['PLAYER_NAME'][0])
        except:
            continue

def main():
    get_players_info(ID_IVERSON, (ID_IVERSON + NB_DRAFT))

if __name__ == '__main__':
    main()
Allen Iverson
Marcus Camby
Shareef Abdur-Rahim
Stephon Marbury
Ray Allen
Antoine Walker
Lorenzen Wright
Kerry Kittles
...(下に続く)

正しくデータが取れてそうです。

あとはポイント、アシスト、リバウンドの平均値を計算してグラフにしてみます。

from nba_api.stats.endpoints import commonplayerinfo
import matplotlib
import matplotlib.pyplot as plt

class my_nba:
    ID_IVERSON = 947
    NB_DRAFT   = 59

    def __init__(self):
        self.pd      = None
        self.index   = []
        self.score   = []
        self.players = []

    def get_info(self, id):
        """
        選手情報を取得
        """
        player_info = commonplayerinfo.CommonPlayerInfo(player_id=id)
        self.pd = player_info.player_headline_stats.get_data_frame()

    def get_players_info(self, start, end):
        """
        指定された範囲の選手情報をインスタンス変数に追加していく
        """
        index = 1
        for i in range(start, end):
            try:
                self.get_info(i)
            except:
                continue
            try:
                pts   = self.pd['PTS'][0]
                ast   = self.pd['AST'][0]
                reb   = self.pd['REB'][0]
                name  = self.pd['PLAYER_NAME'][0]
            except IndexError:
                continue
            self.players.insert(0,name)
            self.index.append(index)
            index += 1
            score = (pts + ast + reb)
            self.score.insert(0,score)

    def plot_bar_graph(self, year):
        """
        横棒グラフを表示する
        """
        plt.barh(self.index, self.score, align="center")
        plt.yticks(self.index, self.players)
        plt.title(str(year) + " Draft Players Score")
        plt.show()

def main():
    print("Please wait...")
    nba = my_nba()
    nba.get_players_info(nba.ID_IVERSON, (nba.ID_IVERSON + nba.NB_DRAFT))
    nba.plot_bar_graph(1996)

if __name__ == '__main__':
    main()

実行してみる。

できました!(見づらいのでクリックして見てみてください)

1位 Allen Iverson
2位 Kobe Bryant
3位 Stephon Marbury
という結果となりました。

文句なしで1位はアイバーソンですね!
コービーファンとしては悔しい結果となりましたが、正しく表示できたので良しとしましょう。


終わりに

各ポジションごとに得点の重み付けを変えてみるとより面白いかなと思いました。また時間があるときに試してみようと思います。
それとPythonでグラフを線描するのが初めてだったので面白かったです。

NBA大好きなので今後も気分転換に遊んでみようと思います。
それでは良いNBAライフを!

おまけ(2003年ドラフト)

開始idをいじると他の年代も表示することができます。

未だに現役の選手に関しては昨年のスタッツになっています。
それにしてもレブロン強すぎる。。