42Tokyoのオンライン特別カリキュラム参加記録

概要

42Tokyoにて2020年Piscine合格者向けに実施された、オンライン特別カリキュラムの参加記録です。

42Tokyo公式サイトより。

・期間

第一セクション 4月6日(月)〜 4月27日(月)

※変更の可能性あり

・対象者

2020年Piscineの合格者

基本的には以下の記事の内容 + αな感じです。

xtech.nikkei.com

ainow.ai

カリキュラムの内容

はじめに

2020年1月、42TokyoというITエンジニア養成機関の入学試験、Piscineを受け合格しました。その後、新型コロナウィルスの影響で42Tokyoの開校は延期。代わりに4月から特別カリキュラムが始まりました。

日経クロステックの記事 にもあるように、カリキュラムは以下の3つの段階を経ていきました。

  1. 基礎的な技術の習得
  2. Webサイトやアプリケーションのプロトタイプの作成
  3. ハッカソン形式のワークショップ

1で新しい環境になれつつPiscineの復習をし、

2でプログラミングで作れるものを知り、

3で今まで学んだことを生かして課題を解決するという感じでした。

1. 基礎的な技術の習得

この期間で、Piscineの振り返りをしつつリモートの環境に徐々に慣れていきました。

文字数チャレンジ

この辺りで、AINOWの記事 にある「文字数チャレンジ」をしました。指定のプログラムをできるだけ短く書くチャレンジです。

まず普通にコードを書いたあと、コードを短くしていきました。変数名を短くしたり、余分なスペースを削除したりしていきました。

思いがけず優勝して嬉しかったです。最初、普通にコードを書いたのが良かったのだと思います。文字数削減をすると可読性が下がり、コーディング規約の大切さが改めてよく分かりました。

42 Network Coding Challengeの参加

「基礎的な技術の習得」と「Webサイトやアプリケーションのプロトタイプの作成」の間に、 42 Network Coding Challenge という42の学校間のコンテストに参加しました。ゲームAIを競わせるコンテストです。

このコンテストは学校・生徒でランキングがありました。学校ランキングでは、14校中Tokyo校が1位。生徒ランキングでは、358人中16位に入りました。

参加中に取り組んだこと

学校の順位は参加者上位n人のスコア平均のようでした。このため、まずは参加者を増やす必要がありました。参加者を増やすためにルールの翻訳をしたり、参加を呼びかけたりしました。

提出したアルゴリズムは、以下のような感じにしました。

  • 1ターン毎にプログラムしたルールに沿って行動
  • 一部の行動は角度毎に評価点を計算して最適な行動を取る

上位に入った生徒は、数ターン先まで自分・相手の行動をシミュレートして最適な行動を取っていたようです。

2. Webサイトやアプリケーションのプロトタイプの作成

Webサイトを作成したり、Discord Botを作成したりしました。プログラミングで出来ることを学び、作りたいもの・作れるものを知りました。

3. ハッカソン形式のワークショップ

最後がハッカソンです。チームを組み、あるテーマで1つの成果物を作りました。日経クロステックの記事 にも書いてある内容です。

ハッカソンを通じ、学習環境のリモート化で42が失った『対面の教え合い』をどのように補うか考え、プロトタイプし、今後の42に対して提案してもらうことを考えている

ハッカソンに参加して以下のことを学びました。

  • 抽象的なテーマに対しチームメンバーが認識を合わせていく方法。
    • テーマは抽象的で、初めはチームメンバーの認識がバラバラでした。個々の認識がバラバラだと1つの物を作ることはできません。ボイスチャットやMiroを使ってテーマについて掘り下げて考えていくことで、認識を合わせることができました。
  • 「未来」の見せ方の重要性。
    • ハッカソンは投票でチームの順位が決まりました。上位チームのプレゼンテーションは「どういう未来を作りたいか」の見せ方がうまく、ワクワクして引き込まれました。今現在実装したことではなく、これから先どうしていきたいかを示すのが大事なのだと知りました。
    • またハッカソンの機会があるなら、もっと技術・できることを知って、「未来」を上手に見せられるようになりたいです。

感想

良かったところ

とても魅力的なカリキュラムでした。

Piscineでは合格するために課題を解くという感もありましたが、今回は問題解決力をつけるための課題だと思いました。

また、Piscineで会った生徒や2月Piscine生と会えたことも嬉しかったです。

難しかったところ

本来オフラインを想定していた学校がオンラインになり、皆が手探り状態でした。

Piscineとは違いオンラインのコミュニティが全てになってしまうので、場をどうやって盛り上げていくか考えさせられました。

生徒それぞれに事情があって時間が取れなかったり、単方向・非同期的なコミュニケーションになってしまったり、課題がありました。

オンライン学習にあたり必要なこと

オンラインでの学習にあたり、以下が必要になると思いました。

  • 発言する勇気
    • オフラインと違い、オンラインでは気軽に横にいる人に話しかけることができません。発言しないと誰にも伝わらないため、テキストチャットでもボイスチャットでも積極的に発言した方がいいと思いました。
  • モチベーションの維持
    • 校舎に集まって絶対にやらなければいけない状況にならないため、モチベーションが維持しづらく感じました。モチベーションを保つ仕組みが必要だと思います。
  • 環境が不安定でもなんとかやっていく力
    • 自分の環境だとDiscordで画面共有ができなくなる等、オフラインにはないトラブルがありました。それを自力もしくは人の力を借りてなんとかして乗り越えていく力も必要だと思いました(画面共有ができなかった際は音声だけでなんとかしました)。

終わりに

42Tokyoは課題解決型学習を謳っていますが、42Tokyoが抱える課題も生徒が解決していき、より良い組織にしていくのだと感じます。

今後も42Tokyoに所属しながら、プログラミングを学びつつ、より良い組織について考えていきたいです。

Zh3r0 CTF writeup

Zh3r0 CTFという初級〜中級者向け?のCTFに参加した記録です。高校生が主催されてたみたいです。SUGOI。

9問解け、 スコアは1615ptでした。

Misc

Welcome to Phase 1

textareaの文字を入力。

答え:zh3r0{is_this_a_real_flag?}

Welcome to Phase 2

Zh3r0 CTFのDiscordサーバの#shellでコマンドを打っていきます。

f:id:nafuka11:20200619123856p:plain

答え:zh3r0{Hav3_FuN}

Web

Web-Warmup

bg.cssにflagがコメントアウトされています。

/*css is easy, I think. Don't you?zh3r0{y3s_th1s_1s_w4rmup}*/

答え:zh3r0{y3s_th1s_1s_w4rmup}

Tokens

問題文で与えられているTokenはDiscordのUserToken。

DiscordChatExporterを使い、Userのメッセージからflagを得ます。

DiscordChatExporterを使ってguildsを見ると、DMしか送られていないことが分かります。

$ docker run --rm tyrrrz/discordchatexporter:stable guilds -t NzIyMzM1MTQ5NDA0MTkyODIw.XunLaw.xASADEeu9iXsYf1wqTFOil_jgfo
@me | Direct Messages

exportdmで出力したファイルにflagがあります。

$ cat ./Direct\ Messages\ -\ Private\ -\ Mr.4N0NYM4U5\ \[722336834264498177\].html | grep zh3r0
        <span class="chatlog__author-name" title="zh3r0{1et_7he_F0rce_8e_With_YoU}#5799" data-user-id="722335149404192820" >zh3r0{1et_7he_F0rce_8e_With_YoU}</span>
                    <div class="markdown"><span class="pre pre--inline">flag : zh3r0{1et_7he_F0rce_8e_With_YoU}</span></div>
                    <div class="markdown"><span class="pre pre--inline">flag : zh3r0{1et_7he_F0rce_8e_With_YoU}</span></div>

答え:zh3r0{1et_7he_F0rce_8e_With_YoU}

Reversing

snakes everywhere

py_dis1はPythonバイトコードを逆アセンブルした結果のファイルのようです。snake.txtはpy_dis1を実行して生成されるファイル(本来はciphertext.txtとして保存されるファイル)です。

py_dis1の中に変数flagがあり、snake.txtから逆算してflagを求める問題です。

py_dis1を 公式ドキュメント を見つつ、python -m dis py_dis1.pyで都度確認しつつ、コードに復元しました。逆ポーランド記法っぽく読めます(自動で復元できるツールがあったら教えてください)。

復元したコードからsnake.txtを読み込んでreverseするコードを書いてflagを求めました。

答え:zh3r0{Python_disass3mbly_is v3ry_E4sy}

Subset of subset of hacking machines challenges

Flag 5

ポート22番が空いています。

PORT    STATE    SERVICE
22/tcp open     ssh

curlしてflagを入手。

$ curl hackit.zh3r0.ml:22
z3hr0{shouldve_added_some_filter_here}

答え:z3hr0{shouldve_added_some_filter_here}

Flag 2

nmapでポートスキャンをすると、324番が空いていることが分かります。

$ nmap -p301-400 hackit.zh3r0.ml
Starting Nmap 7.80 ( https://nmap.org ) at 2020-06-17 02:10 JST
Nmap scan report for hackit.zh3r0.ml (139.59.3.42)
Host is up (0.14s latency).
Not shown: 98 closed ports
PORT    STATE    SERVICE
324/tcp open     rpki-rtr-tls
329/tcp filtered unknown

ncしてみます。

$ nc hackit.zh3r0.ml 324
220 (vsFTPd 3.0.3)

Name (hostusername):

220 (vsFTPd 3.0.3)ググるFTPサーバであることが分かります。ftpコマンドでアクセス。パッシブモードでないと一部コマンドが使えないため、-pで指定しました。

$ ftp -p hackit.zh3r0.ml 324
Connected to hackit.zh3r0.ml.
220 (vsFTPd 3.0.3)
Name (hackit.zh3r0.ml:vagrant): admin
530 This FTP server is anonymous only.
Login failed.

ユーザ名はanonymousしか受け付けていない様子。「anonymous FTP」でググった感じ、ユーザ名anonymousだとパスワードは何でもいいようでした。

anonymousでログイン。

220 (vsFTPd 3.0.3)
Name (hackit.zh3r0.ml:vagrant): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.

ls -a コマンドでディレクトリを見て、cd ...でどんどんディレクトリを移っていきます。

test.txtと.stayhiddenはダミー。

ftp> ls -a
227 Entering Passive Mode (139,59,3,42,138,97).
150 Here comes the directory listing.
drwxr-xr-x    3 ftp      ftp          4096 Jun 15 15:05 .
drwxr-xr-x    3 ftp      ftp          4096 Jun 15 15:05 ..
drwxr-xr-x    3 ftp      ftp          4096 Jun 15 15:05 ...
-rw-r--r--    1 ftp      ftp            22 Jun 15 15:05 test.txt
226 Directory send OK.

ftp> cd ...
250 Directory successfully changed.

ftp> ls -a
227 Entering Passive Mode (139,59,3,42,174,119).
150 Here comes the directory listing.
drwxr-xr-x    3 ftp      ftp          4096 Jun 15 15:05 .
drwxr-xr-x    3 ftp      ftp          4096 Jun 15 15:05 ..
drwxr-xr-x    2 ftp      ftp          4096 Jun 15 15:05 ...
-rw-r--r--    1 ftp      ftp            46 Jun 15 15:05 .stayhidden
-rw-r--r--    1 ftp      ftp            22 Jun 15 15:05 test.txt
226 Directory send OK.

ftp> cd ...
250 Directory successfully changed.

ftp> ls -a
227 Entering Passive Mode (139,59,3,42,171,225).
150 Here comes the directory listing.
drwxr-xr-x    2 ftp      ftp          4096 Jun 15 15:05 .
drwxr-xr-x    3 ftp      ftp          4096 Jun 15 15:05 ..
-rw-r--r--    1 ftp      ftp            34 Jun 15 15:05 .flag
-rw-r--r--    1 ftp      ftp            22 Jun 15 15:05 test.txt
226 Directory send OK.

get .flag でローカルに.flagを転送します。ファイルを開くとflagがあります。

$ cat .flag
Flag 2: zh3r0{You_know_your_shit}

答え:zh3r0{You_know_your_shit}

Flag 1

4994番ポートが空いています。

PORT     STATE SERVICE
4994/tcp open  unknown

ncでアクセス。

$ nc hackit.zh3r0.ml 4994

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                     ||Employee Entry||

----------------------------------------------------------
                     Sherlock Holmes Inc.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Here's a free flag for you, just for finding this door! Flag 1: zh3r0{pr05_d0_full_sc4n5}
Heyo, Watcha looking at? Employee ID yoo! :

答え:zh3r0{pr05_d0_full_sc4n5}

Flag 4

Flag1の入力でEmployee IDを入力します。

Employee IDはFlag2にあったファイル、.stayhomeの中にあります。

$ cat .stayhidden
Employee ID: 6890d90d349e3757013b02e495b1a87f

IDを入力します。

Heyo, Watcha looking at? Employee ID yoo! :
6890d90d349e3757013b02e495b1a87f
Hey I know you! You work here!
Books are a uniquely portable magic. - Stephen King

Flag 4: zh3r0{y0ur_s4l4ry_wa5_cr3dit3d}

答え:zh3r0{y0ur_s4l4ry_wa5_cr3dit3d}

AWS Lambda + Serverless FrameworkでSlackに定期的にメッセージを投稿する

f:id:nafuka11:20200318221150p:plain

AWS Lambda + Serverless Frameworkで、AtCoderの特定ユーザの成績(AC数、Rated Point Sum)を定期的にSlackに投稿する仕組みを作りました。

成果物URL

github.com

技術構成

f:id:nafuka11:20200318220556p:plain
構成図

Serverless Framework

Serverless Frameworkは、サーバーレスアプリケーションを構築できるオープンソースCLIツールです。

AWS, GCP, Azureなど様々なクラウドプラットフォームにデプロイ、テストもできます。YAML形式でアプリケーションの定義を記述します。

Serverless Dashboardというサービスを使うと監視もできるようですが、今回は使っていません。

個人的にサーバーレスだと嬉しい点は2点あります。

  1. 文字通りサーバがないところ。サーバのお守りをすることなく、ただ処理だけ記述すればいいのが嬉しい。
  2. 使った分だけ課金。今回は無料枠で十分収まる。

AWS

AWSとはAmazon Web Serviceの略で、Amazonが提供しているクラウドプラットフォームです。

AWS Lambda

AWS LambdaはAWSが提供しているサービスの1つです。サーバを管理することなくコードを実行できます。

ユーザの成績の取得、Slackの通知はLambda上で行っています。

Amazon CloudWatch Events

Amazon CloudWatch Eventsは他のAWSのサービスの変化や特定の時間をトリガーとして、他のサービスを実行できるサービスです。

今回はcron式を使って1日ごとにLambdaを実行するようにしています。

Amazon CloudWatch Logs

Amazon CloudWatch LogsでAWSのサービスからのログを一元管理することができます。

Lambdaで実行したログは自動でここに保存されます。

AWS Systems Manager Parameter Store

AWS Systems Manager Parameter Storeは、設定・機密管理の情報をkey-value形式で保管できるサービスです。

SlackのIncoming Webhook URLをうっかりGitHubにpushしないよう、Parameter StoreにURLを保管しています。

AWS CloudFormation

ここまでAWSのいろいろなサービスを説明しましたが、それらを一つにまとめて管理できるのがAWS CloudFormationです。JSONまたはYAMLファイルを使い、サービスをまとめてデプロイすることができます。

Serverless Frameworkはデプロイ時、内部的にCloudFormationを使ってデプロイしています。

テスト

pytest

pytestPython用のテストフレームワークです。

Python標準ライブラリのunittestと比べ、

  • テスト失敗時の表示が分かりやすい。

  • Pythonicにassertを記述できる(unittestはXUnitライクな書き方です)。

のが魅力だと思います。

pytest-mock

pytest-mockはpytestのプラグインです。unittest.mockのラッパーで、pytestのfixtureライクにmockを使うことができます。

pytestにあるmonkeypatchはただpatchするだけですが、unittest.mockは関数の呼び出し回数や渡された引数など取得でき、強力です。そのためプラグインを使うことにしました。

静的解析

mypy

mypyPythonスクリプトの型チェックを行うツールです。Pythonでは型ヒントを追加すると、IDEで静的解析され、自動補完などの恩恵を受けられます(型ヒントを追加しても、実行時に型チェックされるわけではありません)。

普段使っているIDE(PyCharm)でもある程度型チェックしてくれていたのですが、二重チェックで今回導入してみました。

flake8

flake8は、コードのエラー、循環的複雑度、コーディングスタイル(PEP8)をチェックするツールです。

これもPyCharmである程度チェックしてくれていたのですが、二重チェックで導入しました。

CI(GitHub Actions)

CIとは継続的インテグレーション(Continuous Integration)の略で、ソフトウェア開発手法の一つです。 リポジトリへのコミット毎に自動でテストを実行し、品質を常に保証する助けをします。

GitHub Actionsを使うと、GitHubのイベント(リポジトリへのpush、Pull Request作成など)をトリガーに任意のコマンドをGitHub上のコンテナで実行できます。

今回はリポジトリへpushされたら、mypy + flake8 + pytestを実行するようにしています。実行結果はSlatifyを使ってSlackに通知するようにしています。

f:id:nafuka11:20200318221448p:plain

ハマったところ

AtCoder Problems API

返ってくるデータはgzip圧縮されており、gzipを許可するヘッダーが必要です。許可していないとリクエストがブロックされるそうです。

Content-Encoding - HTTP | MDN

gzipを有効にしていないリクエストが多すぎて転送料が高すぎて死ぬ · Issue #211 · kenkoooo/AtCoderProblems

Serverless Framework

ホワイトリスト形式でデプロイするファイルを記述する方法が分からずにいましたが、以下を参考に設定することができました。

Package excludes do not seem to work - Serverless Framework - Serverless Forums

pytest

全般

最初、型ヒントを使っていなかったのですが、引数からフィクスチャを受け取るため、型ヒントをつけないと何を受け取るのか分からなくなるなと感じました。

tmpdir

tmpdirはテスト用に一時的なディレクトリを作成するフィクスチャです。

今はtmpdirでなく、 tmp_path 推奨のようです。tmpdirはpy.path.LocalPathを返しますが、tmp_pathは pathlib.Path を返し、扱いやすいです。

Temporary directories and files — pytest documentation

pytest-mock

テスト対象のモジュールでmock対象をimportしている場合、mockする時のモジュール名に気をつける必要があります。

https://docs.python.org/ja/3/library/unittest.mock.html#where-to-patch

mypy

  • サブディレクトリ内を走査するために__init__.py を作る必要があります。
  • --ignore-missing-importsで解決できないモジュールのimportを無視することができます。デフォルトで実行すると大量にimportエラーが出たため、このオプションをつけて対処しました。

作ってみて

定期的にSlackに投稿するだけなら、clasp + GASでやるのも良かったかもしれません。あちらの方がGoogleアカウントを持っていれば誰でもすぐデプロイできるし、スプレッドシートでデータを管理できて便利だし。

テストを書いたり、静的解析してみたり、それらを自動化してみたり、以前からやってみたかったことができてとても満足しました。

課題

  • AC数、Rated Point Sumの増分を表示したいです。
  • 現状だとuseridリストをファイルで持っており、変更するたびにデプロイする必要があります。slash commandを使ってSlack上で追加・削除できるようにしたいです。

『スッキリわかるC言語入門』読書感想

所要時間:30-35h

所要日数:12日

読んだ目的:42 TokyoのPiscineでC言語を使用するため

感想

内容

以前『スッキリわかるJava入門』を読んで以来スッキリシリーズには全幅の信頼を寄せていたのですが、やはり分かりやすい。少しずつ教える、概要から詳細を教えることが徹底されていると感じました。ただ分かりやすいとはいえ、C言語の記法が混乱を招きやすく、直感的でない部分もあります。この辺りはコードを書いて慣れる必要がありそうです。

出版が2018年6月と比較的最近で内容が新しいこと、基本的な文法から、ビルドパイプライン・処理系やC言語規格の違い・コーディングガイドラインなど、内容が網羅的なことも嬉しいです。網羅的な分、本は分厚いですが読みやすくスラッと読めます。

パズルRPG

f:id:nafuka11:20200105210750p:plain
パズルRPG作例

表紙に書かれてるウリの一つ。パズドラっぽいコンソールのRPGを作ります。本家と違ってドロップは一次元です。

学習者のレベル・時間に応じ、4段階の難易度から課題に取り組めるようになっています。上級を選択しましたが、10時間以上かかりました。初学者だと1週間〜1ヶ月ほどかかるそうです。

一番難易度の高い超上級では、仕様を見て自力で設計・実装。それ未満の難易度は、制作の流れを読んで実装していきます。シーケンス図や関数一覧もあり、かなり実務を意識していると思います。余談ですが実務の意識に関して、本書は実務で見かけるコードの解説もあるのが良いです(実務ではこういうコードを見かけるけど、これはこういう理由があって〜等)。

この課題は1つのソースファイルに500行ほどコードを書いていきます。課題を終えた後は、後ろの章を読みつつソースファイルを分割したり、ゲームバランスを調整したり、機能追加するのも面白そうです。

環境

本書では、VirtualBox + Vagrantで立ち上げた仮想マシン上で開発することになっていますが、エディタの動作が重かったので、ホストOSのVSCodeからリモート開発することにしました。

PCのスペックによっては仮想マシンの立ち上げですら重いかもしれません。その場合自分で環境を用意する必要がありそうです。

おわりに

今からC言語を勉強される方にオススメの本です。