ぴよまるの雑多な技術所

間違えて休職中ってずっと書いていて心配されていました。全部ちょっとずつ齧って好きって思える技術を見つけたい。研究分野は数理最適化。

Pythonで実装したLambda + API Gatewayで任意のエラーコードを返す

サーバレスな構成を作っている時、Lambdaのステータスコードを500で返してもAPI Gatewayで200に書き換わってしまうということがありました。その時は独自エラークラスを作って、マッピングテンプレートを設定してなどなど、大掛かりなことをしたのですが、マッピングテンプレートなしで任意のエラーコードを返す方法をまとめます。

全体図

LambdaがAPI本体、API GatewayAPIのエンドポイントになる構成です。

結論

先に結論を書くと、マッピングテンプレートは必要ありません。API GatewayのPOSTの「統合リクエスト」は「Lambda プロキシ統合の使用」のまま、Lambda側でエラー用のjsonをreturnすれば大丈夫です。

参考記事 https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/handle-errors-in-lambda-integration.html

以下に具体的なコードを載せます。POSTで{'test': '何か文字列'}という値を送信するという想定です。

Lambda

import json

def lambda_handler(event, context):
    body = json.loads(event['body'])#例えばbodyを読み込んで

    if (len(body['test'])>10000):#文字が長すぎたら500エラーを返す
      return {
            'errorType': "InternalServerError",
            'httpStatus': 500,
      }
   #文字が長すぎなければ200のレスポンス
    return {
        'statusCode': 200,
        'isBase64Encoded': False,
        'body': 
            json.dumps({'result': 'OK!'})
        ,
        'headers': {
            "Content-Type" : "application/json",
            "Access-Control-Allow-Origin" : "*"
        }
    }

API Gateway

これから記事を書く予定の記事のserverless.yamlの設定をコピペすれば動きます。書いたらリンクをはります。 おそらく「OPTIONS」と「POST」の2つのリソースができていると思いますが、「OPTIONS」はpreflightレスポンスに使います。「POST」の方が実際にLambdaにリクエストを送るリソースで、細かいマッピングは「統合リクエスト」の中の「Lambda プロキシ統合の使用」にチェックをするとよしなに行ってくれるため、マッピングテンプレートが不要です。

f:id:let_piyomaru:20200310105435p:plain
API Gatewayの設定
私の環境だと「POST」の方は「メソッドレスポンス」にステータスコードを登録する必要すらありませんでした。 留意点としては、Lambda側で返すjsonの項目がAWSによって定められています。その形さえ間違わなければ動くはずです。

Pythonでテトリスを作ることでよく知らない分野の実装手順について考察する(2)実装編

今回は後編として、実装したコードについて書きます。 前回の記事は以下です。

let-piyomaru.hatenablog.com

リポジトリは以下です。

github.com

実装する際にどういう手順で取り掛かるかも悩んだので、私が実際に考えた順に記事を書きます。内容としてはクラス設計、実装を悩んだ箇所の調査、実際の実装という順番です。 ちなみにまだリポジトリのコードは動きません。とりあえず動いたら追記します。

クラス設計

ゲームクラス

  • フィールド
    • スクリーン
    • テトリミノ
    • 次に落下するテトリミノ
  • メソッド
    • 初期化
    • テトリミノの衝突判定(衝突していたら固定)
    • 1行埋まったかの判定
    • 次に落下するテトリミノの生成(種類・回転をランダムに決定)
    • ゲームオーバー判定(次に落下するテトリミノが入りきらない時)
    • メインからゲームループの中で呼ばれる処理(ゲームの流れの管理)
    • スクリーンの描画処理

テトリミノクラス

  • フィールド
    • x座標
    • y座標
    • 回転の種類
    • テトリミノの種類
  • メソッド
    • テトリミノの左右移動
    • テトリミノの下移動

シーケンス設計

初期化

  • スクリーンの初期化
  • テトリミノの初期化
  • スクリーンの表示
  • 次に落下するテトリミノの生成(種類・回転をランダムに決定)
  • 左右と回転

ゲームループの中

  • テトリミノの衝突判定
    • 衝突していたら次に落下するテトリミノの生成
    • していなければテトリミノのy座標を1つ落とす
  • キー入力があれば動かせるか判定してテトリミノの操作
  • ゲームオーバー判定
  • スクリーンの描画処理

詰まった実装

Pythonでキー入力を受け取る

  • pip install readchar
import readchar
while True:
    kb = readchar.readchar()
    if kb == "q":
        break
    else:
        print(kb)

(注意)上記の実装だとキー入力があるまでループが止まります

キー入力で待たない

こちらの記事のコードをお借りしました。

Pythonでキー入力待ちをしないキー入力 - Qiita

(だいたい)1秒ごとに描画ループ

import time
while True:
    # 何か処理
    time.sleep(1)

Pythonでテトリスを作ることでよく知らない分野の実装手順について考察する(1)設計編

今年はコーディング力向上を目標にしており、いろんなジャンルのコードを自力でゴリゴリ書こうと思っています。理由としては普段自分で考えて実装する時間が少なくコンプレックスだからです。 まずは落ちものゲームの代表であるテトリスPythonでゴリゴリ書いてみました。 前提として、私はゲーム系のプログラミングの常識を知らず、そもそもテトリスで遊んだことがありません。実装を通してよく知らない分野の実装手順について考察します。 今回は前編として、実装前の設計と事前調査部分についてまとめます。

リポジトリは以下です。

github.com

テトリスとは

上からテトリミノというブロックが落ちてきて、横一列揃うとブロックが消えるゲームです。

テトリスの仕様

ネット上で調べたところ、下記のような項目にまとめられそうでした。

  • できる操作はテトリミノの左右移動、落下速度をあげるの3つ
  • テトリミノの種類は7種類で、90°の回転でそれぞれ4パターンずつ
  • テトリミノは縦横最大4*4
  • 横1列揃ったらその行のブロックを消す
  • ゲームスクリーンは横6、縦20(一般的ではなく今回向けの仕様)

実装方針

  • ゲーム画面は配列で管理する
  • テトリミノはクラスのインスタンスとして管理する
    • 自分の座標、回転の種類、状態(非表示、移動中、停止)をもつ
  • テトリミノの管理は配列を用いる
  • 描画とできる操作は関数として定義する

まとめ:よく知らない分野の実装手順(設計編)

  1. 実装対象について実際に動かして仕様を調べてみる
  2. 実装対象の分野(今回ならゲーム)の常識を調べる(今回の例なら以下のようになる)
    • リアルタイムのゲーム系は無限ループを回しておく
    • リアルタイムのゲーム系は無限ループの中で状態更新、画面描画を繰り返す
    • ゲーム盤面やパズルパーツを配列で管理する
    • キーボード入力のとり方
  3. 実際のオブジェクトと操作を洗い出し、クラスと関数を書き出してみる
  4. 処理順序の確認をする(無限ループのなかで表示をするとか、状態更新いつするとか)

競技プログラミングデビューした

競プロデビューしたのでまとめます。

競技プログラミングとレーティングとは

与えられた問題を早く正確にとくあれです。よくいわれる「青色コーダー」とか「赤色コーダー」はAtCoder上のコンテストに参加するレートがつくので、それに付随した色をさします。 コンテストもレベルがあって、初心者はAtCoderのABCコンテストに出ます。週末の夜に開催していて、おそらく最初の数回は色がつきません(レーティングが上がるのゆっくりなので)。はじめたばかりで目指すのは茶色コーダー、水色までいけばアルゴリズムに関してはまあまあなスキルが担保されているような印象です。

参加方法

AtCoderに登録して、毎週日曜日の21時あたりにリアルタイムで参加します。

環境構築とかファイル管理まわり

私はPython使いですが、

pip3 install online-judge-tools
npm install -g atcoder-cli

こんな感じで、オンラインからテストケースとってきて良い感じに設定してくれるツールを使っています。自動でフォルダもコンテストごとに切られます。

//ログイン
acc login
//ログイン確かめる
acc session
//online-judge-toolsもログイン
oj login https://beta.atcoder.jp/

初期設定はこんな感じで、

//コンテストのディレクトリ作る
acc new abc101
//あとは対話式で解く問題を選択する

//テスト
oj t -c " python3 ./a.py" -d ./tests/

//submit
acc submit main.cpp

//次の問題
 acc add

こんな感じで使えます。 ファイル管理でいうと、今のところ、勉強する際は1つのリポジトリに全部のコンテストをフォルダごとにつっこんでいる感じです。書き捨てない方がいいです。あとで入出力まわりとか、やったことを見返すことがわりとある気がします。

問題の難しさについて

ABCコンテストしかわかりませんが、A問題は入出力できるかな程度、B問題はちょっとソーととかfor文での全探索が入った程度です。ここまでは言語に慣れているかどうかの話な気がします。 C問題からがちょっとアルゴリズムやデータ構造の知識がいるかなという難易度で、個人的には無勉強・無知識でとけるのはCまでかなという気がしました。Dはあんまりまだチャレンジしていません…。

勉強方法

有名な蟻本…は難易度が高いので、問題の種別を蟻本でざっとみたら、コンテストで過去問をとくみたいです。問題の種別というのは、例えばforループでとく全探索問題とか、DPとか、貪欲法とか、どんな考え方をどんな時に使うかという意味です。 サイトとしては

あたりが有名みたいです。tagsの方はカテゴリ別なので、何か1つのトピックの考え方を勉強して、過去問を集中的にとく…みたいな使い方ができそうです。

所感

競プロって楽しそうですよね。楽しいです。ただ勉強時間が沼なので、その辺の配分に悩んでいます。

フライングですが来年の目標を立ててみた

ぴよまるです。夜間大学に行き、業務でもフロントもバックエンドもやって、副業もして…という生活の中で、ふと自分は目標が曖昧すぎるという課題を感じたので、とりあえず具体的になるまで落としこむべく、「来年の目標」として言語化することにしました。

エンジニア関連

  • 資格取得

秋になったら、システムアーキテクトをとりたいです。あとはPythonの資格をとりたい。1つの言語をちゃんと勉強したことがなかったので、Pythonならわかるぞ!とできると、他の言語を学ぶ時にも役立つと思っています。

  • 個人サービスのリリース

エンジニアとして業務でサービスを作る経験が少ないので、もういっそ個人で出したい。具体的にはPythonでアイディアを出して、来年中にプロトタイプを公開する。過程をアウトプットする。

最近機械学習のコードを見る機会が増えてきましたがあんまりコードがかけません。なので1習慣に1つくらいテクニックを勉強してブログで発信します。来年終わる頃にはkaggleも怖くない程度の知識と実装力を身につけます。 あと特徴量エンジニアリングとか統計モデリングの本が積まれているので、これは読みます。読んで読書録を公開します。

それ以外

  • 英語のwritingスキルあげ

実は留学がしたいタイプの人間です。能力は足りていないのですが、writingは一番時間がかかるかつ一番重要と思っています。留学するとレポートもきっとかくので…。月に1つくらいwriting練習をします。

  • 数学力あげ

3年生になると数学っぽい授業がなくなります。数学の基盤が大事だと思って夜間大学に入学したので、位相や群論については少なくとも学習します。


結局何がしたいのか

決めなければいけないと思います。 興味だけで動いている方向をまとめると、きっと

  • エンジニアとしてちゃんとサービスを作る経験が欲しい、自信を持ちたい

  • その上でアカデミックよりに方向転換して、機械学習を仕事にしたい

の2点だと思います。 社会との関わりが希薄で社会課題を解決するとか、世の中を便利にするとか、そういうたいそうなやりたいことは見つかっていません。ふわっとしたやりたいことに対して具体的にアプローチすることで、本当にやりたいことを見つけるというのが来年の課題です。

おそらく、今日の記事通りにブログのカテゴリがつけられて、ちょっとずつ成長すると思います。言ったのでやらざるを得ません。

応用情報技術者試験を受けてきました

昨日、応用情報技術者試験を受けてきました。受かっているかはわかりませんが、次に受ける人と落ちていた場合の自分のために、やったことを書きます。 多分自己採点だと受かっているような気がしますが、今年は午後が簡単だったらしいのでわかりません。

前提

  • 1ヶ月前から勉強開始
  • 夜間大学に通っている&正社員の他に副業をしているため、だいたい平日1時間、休日でも長くて2時間の勉強時間
  • とはいえ職業エンジニア、ブランクもカウントすれば3年くらい

やったこと

方針としては、時間がとにかくない&普段の授業の復習やレポートもあるので、隙間時間に午前は対策、午後は相性が悪かったら捨てる、くらいな気持ちでした。

午前は教科書でキーワード確認、あとは過去問をラスト1〜2週間でとく。午後は学費を納めたばかりでお金を使いたくないという気持ちから、2年落ちした「午後問題の重点対策」を1週眺めました。

午前について

最初はキーワードもわからないと思うので、語彙が乗っている対策本的なのでザーッとトピックを眺めて範囲の把握をするといいです。あとは過去問から何割かでるので、ひたすら過去問をときます。 直近2年は出ないとか書いてあったので、それ以外の4年分をやりました。1回目と2回目だけちゃんと2時間ずつくらいかけて丁寧にといて、わからない問題をノートにかきました。初回で4〜5割正解くらいです。 そのうちにキーワードがわかってくるので、そうしたら携帯で応用情報技術者試験ドットコムでひたすら空き時間にときます。知識が足りないなと思ったらノートに書きます。結局1週しかできませんでしたが、3〜4年分やって全部8割くらいわかっていれば午前は通るかと思います。

邪道かもしれませんが、試験の直前20分くらいで1年分をザーッと見て、計算問題は答えを覚えました。もちろん計算もできるようにしますが、パニックになった時に答えがわからないと精神的に死ぬので。

午後について

午後は1回分だけちゃんと全問題解いて、向き不向きをみました。国語の問題が難しいのと、私は文章を読むのが苦手なので、簡単と言われる組み込みの問題が難しいことがわかったので、DB、ネットワーク、アルゴリズム、あとは臨機応変にテクノロジー系から選ぶ方針にしました。 「午後問題の重点対策」を一週眺めて、記述問題の書き方とか、出る問題の範囲の把握をしました。 ストラテジーとかの問題はわかりませんが、前半でいうと、

  • DBはほぼパターンがあって、ER図の問題と簡単なSQLが知識として必要、それ以外は当日頑張ればOK
  • ネットワークも同様で、ネットワーク図に慣れておくのと、ウェルノウンポートの確認、よく午後問題の重点対策に出てくる単語を調べておく。あとはMACアドレスIPアドレスの扱いの違いくらい知っておけばそんなに過去問解かなくて平気
  • アルゴリズムは前提知識ほぼなし、当日読んで理解できれば選択
  • 組み込みは前提知識ほぼいらないけど国語力いりそう。最後の手段に
  • システムアーキテクチャシステム開発(?)は職業プログラマなら前提知識ほぼなしでいける(テストについては上記対策本で見ておく必要あるけど)、難易度ぶれるので当日判断

みたいな方針で対策しました。

当日について

お昼ご飯を買いに行く時間がないかもしれません(休憩が40分だけ)。また、午後は体感だと気力勝負な気がします。 途中退室可能なので、とにかく午前問題は即答えられる過去問でやったことある問題を増やしておいて、時間に余裕を持って途中退室をお勧めします。

午後は難易度にだいぶブレがあるので、とにかく簡単な問題を見つける練習はしてもいいかもしれません。あとは午後はちゃんと長文が読めるかにかかっているので、糖分をお昼にとるとか、お昼ちょっと目をつぶるとかすると良いです。

感想

ネットでググって出てくるほど午後はパターンでDBやらネットワークやら組み込みが簡単とか、午前はかたいみたいな感じはしませんでした。 最初はどこを解いても点数が上がらないし、午後は何見てもわからなくて絶望していましたが、午前は何度も解けばなんとかなります。午後は思い返すと問題との相性8割な気がします。

あとは起床が辛い可能性が高いので一週間くらい前から早起きの練習をするのと、ずっと座っていたり考えるのも辛いので、体力をつけてから挑むといいです。私は夜間大学に通う前だったら起きられなかったし座っていられなかったと思います。

夜間大学で学んだこと@1年生

私は某国立大学の夜間部(おそらく情報系に当たる)に通っているわけで、いつの間にか2年生も半ばを過ぎていました。 振り返ると大学に入ってから得たものが結構あったので、どんな授業があって、どう役立っているかを書き残しておこうと思います。1年に1記事になるかなあ。

1年生の間に受けた授業

微積分学

授業について

ひたすら矢野 健太郎さんの「微積分学」という教科書を解き続ける感じでした。 入学前も機械学習に興味があったので、マセマを独学していたのですが、やっぱり試験のために手を動かすと定着率が違いますね。 トピックとしては一通り指数関数や三角関数などの微分積分、部分積分とかの基本的なテクニック、そしてちょろっと偏微分なども行いました。 今の所、よくみるε-δ 論法とかは工学においては知っていなくても困らない印象です。具体的な問題が解ければいい科目。

役立ったこと

時間を作って問題を自分で解くみたいなくせがついて、試験慣れしたこと。この先工学系に出てくる科目に使う微積分の式変形に慣れて、数式でつまづくことが減ったこと。 シグマとかeとか出てきてもビビらなくなるので機械学習の本とか読みやすいです。

線型代数

授業について

教科書はほぼ使わず板書授業でしたが、演習をするならマセマでいいかもしれません。 行列の変形とか掃き出し法などを扱い、ちょろっとベクトル空間まで入りました。 この科目はあとで使う分、出てきたら復習すればいい感じはします。 この段階だと掃き出し法や基本的な行列の変形ができることが大事。

役立ったこと

行列の式変形に慣れたこと。機械学習はベクトルの扱いが想像できなくて漠然とつまづくことが多いと思うのですが、そう言うのの解決の糸口になったかと。独学と違って手で計算する機会が多くて、ある変形パターンに慣れているのは強い。

物理学・化学

授業について

この2つは理系教養的な感じ。内容は物理学はよくある高校物理学を微積分絡めて学んだ感じ、化学もスペクトルの話から始まって、エントロピーとかざっくり学びました。

役立ったこと

メリットは理系らしくなれたこと笑、物理学の区分けがわかったこと。

コンピューター基礎系

授業について

ざっと文字コードがどうとか、HTMLとか、アルゴリズムとか、全体を流す感じの授業でした。プログラムも組みます。

役立ったこと

アルゴリズムを自分で実装することで、コピペプログラマからは脱却した…かも?笑。ソートとか自分で書くのは実務でいるプログラミング能力とは違うかもしれませんが、動作の想像に役立ったり、思ったことをプログラムに落とし込む力みたいなのをつけたりするのに役立ちました。あと文字コードの理解が深まったのはラッキーかも。

Academic English、実験

授業について

この2つをまとめると不思議な感じですが、要は論文やレポートの書き方です。LaTexをよく使うとか、事実と結果を分けるとか、レポートは結果に対して調査を加えて書くとか。 事実を調べる癖みたいなのは身につきます。Englishの方は英語バージョンの時の体裁とか、IとかYouとか使わない、といった基本的な「アカデミックな文法」事項。

離散数学

授業について

これが地味に一番学生生活では役立っています。要は集合論です。集合についてと写像についてです。 数学的に厳密に話をするとどうしても、どの集合に対する議論かを最初に明示します。その辺りでつまづくと辛いので、数学っぽい科目の教科書を読むのに一番必要なのはこの辺の知識かも。群とかまではやっていないです。あとちょっとグラフ理論も入ってたかなあ。

役立ったこと

数学の教科書の一番最初を読むのが楽になった。定義的な部分はだいたい集合論とかが入っていて、そこでつまづくことが多かった気がします。

あとがき

夜間大学に入ってみて、独学では勉強できなかったことも身につくなあと思いました。周りを見ると大学を卒業すると、結構学んだことを忘れてしまっている人が多いように感じます。なので、まだ学んでいるうちに、何をしたかとか、どう思ったかみたいなのを残しておくのは有用かなと思いました。あと大卒じゃないから、論文書けないから、数式わからないから、と言うキャリアの狭めかたがなくなった気がするのは精神にとても良いです。学問上のコンプレックスがある人はみんな入ったら幸せになれるんじゃないかなと思っています。