Write Code Every Day (1年目)
概要
Write Code Every Dayを1年間達成しましたので、感想云々を記載します。
一応、日付ずらし等はやらずにいけました。
(ユーザーミスが1日だけあったくらいですかね..)
Write Code Every Dayとは?
毎日コード書いて commit
して、GitHubに芝を生やすことです。
昨年のこの時期に、 @t_wada
さんのスライドを見てはじめてみました。
(元ネタはこれかな) John Resig - Write Code Every Day
@t_wada
さんのスライド
Write Code Every Day // Speaker Deck
結果
(色薄..)
作ったもの
主にGolangの勉強系で作ったものが多いです。 (90%くらい..)
gosns
- Messaging Sever です
- Amazon SNSを初めて触れて、書いてみたかったのでGoで書いてみました
- Pub/Sub Modelをイメージして作成してます
mercari/go-httpdoc
を使ってテストコードから、API Docを生成したことをよく覚えてます
gtrello
- 日報作成ツールです
- 毎日簡単に書きたくて作りました (まだ使ってます)
- Trelloの情報をSlackへ送信する流れです
$ gtrello
→ editor open(所感記入) →#times_midori
へ配信
- Trello用のClient (
BurntSushi/toml
) をガッツリ使ってます- こういうClient利用をきれいにテスト書かねばというのが課題です
- Go標準のtemplateを利用して、Markdown生成とかしてました
- (Slack投稿にしたので、最終的にはあんまり残ってないです..)
gmd
- コマンド保存ツールです
- 同じコマンド打つの辛いなぁと思って作りました
- 現在はhistoryに置き換わって使ってないですね…
- history + peco (参考: pecoる - Qiita)
- コマンド自体をまるっと保存します
- できること
- 保存
- 実行
- 一覧
gchat
- チャットサーバーです
websocket
ってどんな感じなんだろうと思って作りました- (まだよくわかってないですね..)
gorilla/websocket
をwrapしているだけって感じでサクッと作れました
その他
- 作りかけ放置多数
原則の達成度
- 毎日コード書くこと
- 達成度 70%
- NG Point
README.md
更新- メモ等のcommit
- NG Point
- 達成度 70%
- 意味のあるコードを書くこと
- 達成度 70%
- NG Point
- 上記と同様
- NG Point
- 達成度 70%
- 深夜24時前に終わらせること
- 達成度 80%
- NG Point
- 24時超えのcommitは少しはあった
- NG Point
- 達成度 80%
- 書いたコードをGitHubのOSS化すること
- 達成度 100%
やってみての感想
メリット
- 毎日コード書く(commitする) 習慣 は完全に身についた
- ほぼストレスなくできるようになった
- 頭の片隅にいつも、今日のcommitはちらつく
- (勉強する習慣を社会人1年目から作れたのは良かった)
- Goがとても好きにになった
- 新しいものに触れるととりあえず手を動かすようになった
- 芝生えるしちょうどいいと思って、コード書いてみる
- gRpc
- GraphQL
- Eclipse Collection
- ML
- etc..
- 芝生えるしちょうどいいと思って、コード書いてみる
デメリット
- インプットが少なくなりがち
- 本読んだり等が二の次になってしまう
- つなげるための苦肉の策
REAMD.md
更新- (正直結構やりましたね、
README.md
だけの更新..)
- (正直結構やりましたね、
- 家に帰るのが間に合わずスマホからcommit
- 飲み会で遅くなり、commit → pushできるツールを探しました..
- source (https://source.ianmcdowell.net/)
- これでできましたが、pushするためには課金(500円?)が必要で..
- 泣く泣く課金しました…
- (後日、一緒に飲み会に行っていた同期が謎に500円くれました)
- 24時超えcommit
- 次の日できなさそうな時、やってました
今後
習慣化しているので、続けていこうかと思います。
エンジニアである以上、日々手を動かしていけるようにしていきたいです。
2年目
README.md
更新頻度の削減- ちゃんとコード書く
- コード書くための時間づくりも大事にする
- インプット → アウトプットの習慣化
- 本をもっと読みたい
- 基礎知識が低すぎる課題
- 本を読んだことを活かしてコードを書く
- 本をもっと読みたい
- 続けること
- 2年目もがむしゃらにとにかく続ける
- OSSへcommitする
- Libraryもしくは有用なツールを公開する
- ちゃんと使えるものを作りたい
- 設計からしっかり実施したもの
- テストコードを書く
まとめ
1年続けてみて、個人的には良い習慣かなと思いました。
基本サボり症である程度の強制力があるものがないと続かない人には、
向いているかと思います。(自分はこれです)
作ったもの等は、稚拙なものが多いですがこれも実力の内なので、
2年目はまた違った結果がみせれると良いかなと思います。
ijaas導入時に詰まった点
概要
ijaasを導入に当たって、変なところで詰まったので残しておきます。
ijaasとは
Make IntelliJ as a Java server that does autocompletion for Vim.
IntelliJをサーバーとして立てて、Vim
からAPI経由で各種機能を
利用できるようにしている模様です。
導入の基本は、 README.md
に記載の通りの手順で問題ないはずです。
詰まった点
1. PluginがInstallできない
Setting > Plugins > install plugin from disk
実行時に、下記エラーが発生
解消
IntelliJのバージョンが合ってなかったため、発生していた模様です。
build.gradle
def intellijVersion = 'IC-2017.1.5' if (project.hasProperty('intellij.version')) { intellijVersion = getProperty('intellij.version') }
intellij.version
で切り替えができる模様のため、
build.properties
を追加して上げれば良いです。
intellij.version=IC-2017.2.6
2. IntelliJ上からbuildPluginするとIdea取得で失敗
S3より、Ideaを取得する部分で失敗していました。
解消
コンソールより実行で解消できました。
% gradle buildPlugin
3. NeoVimから実行できない
ch_open
がNeoVimに実装されていない(?) 関係上、利用できませんでした。
(IntelliJへの接続に利用しているため、全般の機能が利用不可かと..)
if exists("$IJAAS_PORT") let s:ch = ch_open('localhost:' . $IJAAS_PORT) else let s:ch = ch_open('localhost:5800') endif
解消
Vim
を使う。
4. 保存時の ijaas#buf_write_post()
でTimeout
一旦コメントアウトしております。
( complete()
や organize_import()
は利用できました。)
5. IntelliJで該当Projectを起動していないと動作しない
該当ProjectをIntelliJで開いた状態で、利用する必要があるみたいです。
所感
まだ、実用的なコードで試せてないですが、
オートコンプリートはきれいに動作してました。
その他の機能に関しては、上手く動かせない部分もありました。
(機能を理解できていないからかと..)
あと、 メソッドジャンプ機能 が欲しいです。
vim-goの便利コマンド一覧
概要
Goを開発している際に、vim-goを利用しています。
最低限のコマンドしか利用できていなかったため、
便利なコマンドを再洗い出ししてみます。
(個人的なまとめの意味合いが強いです。)
Commands
下記を参照しております。
vim-go/vim-go.txt at master · fatih/vim-go · GitHub
:GoRun
go run
コマンドに相当します。
vim上から実行できるところが便利です。
:GoBuild
go build
コマンドに相当します。build後のバイナリは排出しないです。
buildが成功するかどうかを確認する際に利用すると便利です。
成功すると、下記のように出力されます。
vim-go: SUCCESS
失敗すると、quickfix windowに一覧が出力されます。
1 main.go|16| syntax error: unexpected semicolon or newline, expecting comma or } Quickfix go build -i . errors vim-go: FAILED
:GoDef
カーソル以下の、宣言元にjumpできます。
実際の実装がどうなっているか確認したりする際に利用します。
gd
で同等の動作をします。
(基本的には、 gd
で移動することが多い印象です。)
:GoCallers
カーソル以下のfuncの、呼び出し元を一括検索できます。
(ファイル全検索していたのが、馬鹿らしく思えます..)
注意点 として、複数packageで検索したい場合は、 :GoGuruScope
でスコープを設定します。
(どのディレクトリ以下で検索をかけたいかを設定するイメージです。)
:GoGuruScope github.com/midorigreen/gprof
selectPeco()のカーソル上で
:GoCallers
quickfix window
1 main.go|93 col 6| github.com/midorigreen/gmd.selectPeco is called from these 3 sites: 2 /Users/midori/src/golang/src/github.com/midorigreen/gmd/exec.go|28 col 28| static function call from github.com/midorigreen/gmd.cmdExec 3 /Users/midori/src/golang/src/github.com/midorigreen/gmd/hist.go|38 col 28| static function call from github.com/midorigreen/gmd.cmdHist 4 /Users/midori/src/golang/src/github.com/midorigreen/gmd/del.go|29 col 25| static function call from github.com/midorigreen/gmd.cmdDel
:GoCallstack
カーソル以下のfuncのcallstackがquickfix windowで見れます。
(こちらも :GoGuruScope
の指定が必要です。)
1 main.go|120 col 7| Found a call path from root to github.com/midorigreen/gmd.run 2 main.go|120 col 6| github.com/midorigreen/gmd.run 3 main.go|138 col 13| static function call from github.com/midorigreen/gmd.main
:GoTest
テストを実行します。
:GoTestFunc
カーソル以下のtest funcのみテストを実行します。
:GoDoc
カーソル以下のGoDocを別windowで参照することができます。 (Shift+k と同等の認識です。)
:GoDocBrowser
カーソル以下のGoDocをブラウザ上で参照することができます。
わざわざGoDocを検索する手間が省けます。
[range]:GoAddTags
range指定した、structにタグを自動で追加してくれます。
Before
type Prof struct { Cores []Core Model string ModelName string CacheSize int32 }
After
(defaultはjsonタグ)
type Prof struct { Cores []Core `json:"cores"` Model string `json:"model"` ModelName string `json:"model_name"` CacheSize int32 `json:"cache_size"` }
- dbタグ =
[range]:GoAddTags db
- omitempty =
[range]:GoAddTags json,omitempty
:GoFillStruct
structの宣言時に、literalをdefault値で埋めてくれます。
初期化時に、各literalを打たなくて良いのが楽です。
Before
prof := Prof{}
After
prof := Prof{ Cores: nil, Model: "", ModelName: "", CacheSize: 0, }
:GoRename [to]
カーソル以下の文字を、一括でrenameしてくれます。
呼び出し元も、合わせて修正してくれろところが便利です。
func
, struct
, 変数名
のそれぞれ動作可能です。
:GoPlay
開いているファイルをGo Playgroundで見ることができます。
サンプルコード書いて、展開する場合とかに便利そうです。
所感
他にもまだまだ眠ってそうですが、追加され次第、追記していく形を取ろうかと思います。
ここまで揃っていると、vimで十分な効率で開発できそうです。
技術書展3に行ってきた
概要
技術書展3に行ってきたので、戦利品(2点)をさらします。
まだ、中身は読めていないです。
(あまり買えなかったですね..)
戦利品
- こうしてぼくらは、書籍を売るアプリを作った
- Gopher Walker
こうしてぼくらは、書籍を売るアプリを作った
メルカリカウル を作った話ですね。
気になる内容
- ChatOpsの勘どころ
- Goのinterface設計
Gopher Walker
golang.tokyo が出版した本(PDF)です。
Gopherとして読んでみたい本でした。
(無料配布でしたが、少額の寄付をさせていただきました!)
気になる内容
感想
この台風前の雨の中、大勢の方が来られていました。 よくみられた出版物は下記の形の印象でした
- 機械学習系
- やっぱり多かったですね
- Swift
- Swift系の出版物がちらほらみられました
Go系のものがまだまだ少なかったので、増えてくれるとうれしいですね。
次回も覗きに行けたらいいかなぁと思います。
補足
「Goならわかるシステムプログラミング」が買えなかったのが残念です。
Serverless App作成ツール Up を利用してみた
概要
up と呼ばれるツールを利用してみました。
(Introductionをそのまま試してみただけです。)
upとは?
Serverless Applicationを簡単に作成、デブロイできるツールです。
現状の構築環境と方式は、下記のとおりです。
対応言語
個人的にはGolangに対応しているのが良いですね。
(Lambda自体はまだ、Golang対応していないので)
手順
こちらのサイト に記載のまんまです。
1. Install
curl直接 or npm
# curl版 % curl -sfL https://raw.githubusercontent.com/apex/up/master/install.sh | sh # npm版 (内部で上記curlを叩いているだけです) % npm i -g up
2. AWS Credenstialsの設定
~/.aws/credentials
に追記が楽かと思います。
[go-up-test] aws_access_key_id = xxxxxxxx aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxx
3. up.json
(設定ファイル)作成
必須の項目は、profile
のみです。
~/.aws/credentials
で設定したprofile名と合わせてください。
{ "profile": "go-up-test", "regions": ["ap-northeast-1"] }
4. 好きな言語でサーバー側の処理を記載
package main import ( "fmt" "log" "net/http" "os" ) func main() { addr := ":" + os.Getenv("PORT") http.HandleFunc("/", hello) log.Fatal(http.ListenAndServe(addr, nil)) } func hello(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hello go-up-test") }
5. Deploy
# develop環境へのDeploy % up # production環境へのDeploy % up deploy production
6. 確認
# ブラウザでOpen % up url --open # ClipbordにCopy % up url --copy
% curl "https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/development/" Hello go-up-test
補足
# past 5 minutes % up logs # real time log % up logs -f
up stack delete
で作成したresourcesを全て削除できます
サンプルコード
所感
AWSの設定さえ終わっていれば、非常に簡単にServerless Appを作成できると感じました。Slack Commandが簡単に作れるようなので、試してみたいです。 (元々、SlackのSlash Commandを簡単に作れるという記事を見かけて、興味を持ちました。)
参考
Machine Learning事始め (TensorFlow)
概要
お盆休みを利用して、Machine LearningをTensorFlowのTutorialを通して触れてみました。
解いた問題は、手書き数値の認識です。
Machine Learning
おこなっていることは、任意のグラフに対して近似する関数(=Model)を見つけること
用語
- データ
- (Training用) データとそのラベルのセットを持つ必要がある
- ex) 手書き文字 <-> 書いてある文字
- (Test用) accuracyを計測するためのデータ
- 同様にデータと正解ラベルを持つ必要がある
- (Training用) データとそのラベルのセットを持つ必要がある
- weight
- 入力値への重みテンソル(行列)
- bias
- weightと入力値の積をずらす
- x
- 入力値
- y
- 出力
- activation function
evidence = W * x + b ------------------- Tensor W = weight x = input b = bias -------------------
- softmax function
- evidence(活性化関数=activation functionの結果)を確率へと変換する
- 確率より 0 <= y <= 1
- loss function
- 期待値と実際の結果の差分を計測する関数
- ※ loss functionの結果を0に近づけることが目標
(=期待値と実際の値が一致する)
Machine Learningの流れ
- Trainingデータセットを用意する
- activation function(
W * x + b
)を定義 - loss functionを定義
- TrainingするOptimizerを決めて、loss functionをセットする
ex) Gradient Decent (最小勾配法) - Trainingを実施
テストデータを利用して、関数を何度も実行する。
実行するたびに、W
とb
をOptimizeする。(TensorFlow利用時は勝手にOptimizeしてくれる) - Modelのaccuracyを測定する
サンプルコード
手書き数値の認識
CNNを利用せずにの実装もできましたが、accuracyを上げるためにも、CNNを利用したほうが良いみたいです。
Convolutional Neural Network
- 畳み込みニューラルネットワーク
- 面を一定の大きさのフィルタで覆い、領域で特徴量を抽出する方法
- ex) 32x32の画像を5x5のフィルタでスライド1の場合 => 28x28の画像となる
- pixel単位でないため画像が全体的に類似しているかを判断できる
- Filter
- パラメータ
- filterの数
- filterの大きさ
- filterの移動幅
- padding
- 画像の端の領域を0で埋める
- パラメータ
- Layer
- Convolutional Layer
- Pooling Layer
- サイズを圧縮する層
- max poolingが利用される
- 領域内の最大値を取る手法
- Fully Connected Layer
肝となると感じた部分
- 大量のTrainingデータを用意すること
- accuracyを向上させるためのチューニング
まとめ
基本的に、TensorFlowのTutorialを上からなぞってコード書いてみただけですが、
Machine Learningで何やってるかを少しだけ知ることができました。
絶賛、下記を読み込み中なので読めたらneural networks
とdeep learning
について
正確に理解できるかなと思います。
Neural networks and deep learning
ひとまずPythonでやってみてますが、GolangでもTensorFlow自体は使えるので、
書き直したいところです。
参考
【WEB+DB PRESS Vol.99】k8sの記事での利用コマンド
概要
WEB+DB PRESS Vol.99 の記事を参考にk8sを利用してみました。
詳しい内容は、記事をご参照いただければと思います。(非常にわかりやすい記事でした)
下記は、記事に書いてあるコマンドのままですが、メモ書き程度に思っていただければ。
コマンド
gcloud側の設定
# project の設定 % gcloud config set project xxxx # ゾーンの設定 % gcloud config set compute/zone asia-northeast1-a # 認証設定 % gcloud auth login
コンテナクラスタ起動
# クラスタ起動 % gcloud container clusters create one \ --cluster-version=1.6.7 \ --machine-type=g1-small Creating cluster one...done. Created [https://container.googleapis.com/v1/projects/xxxxx/zones/asia-northeast1-a/clusters/one]. kubeconfig entry generated for one. NAME ZONE MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS one asia-northeast1-a 1.6.7 35.190.233.232 g1-small 1.6.7 3 RUNNING
GCRにイメージをbuildしてpush
# Container build file % cat manifest/cloudbuild.yaml env: ['PROJECT_ROOT=one'] args: ['build', '-o', 'goneup'] - name: 'gcr.io/cloud-builders/docker' env: ['PROJECT_ROOT=one'] args: ['build', '--tag=asia.gcr.io/$PROJECT_ID/one/goneup', '.'] images: ['asia.gcr.io/$PROJECT_ID/one/goneup']% # push gcr % gcloud container builds submit --config=manifest/cloudbuild.yaml .
kubernetes利用
Pod単独
% cat manifest/pod.yaml apiVersion: v1 kind: Pod metadata: name: goneup spec: containers: - image: asia.gcr.io/[project]/one/goneup:latest imagePullPolicy: Always name: goneup # create pod % kubectl create -f manifest/pod.yaml # port forward % kubectl port-forward [pod name] [local port]:[external port]
ReplicaSet
apiVersion: extensions/v1beta1 kind: ReplicaSet metadata: name: goneup spec: replicas: 3 template: metadata: labels: name: goneup spec: containers: - image: asia.gcr.io/[project]/one/goneup:latest imagePullPolicy: Always name: goneup # create replicaset % kubectl create -f manifest/replicaset.yaml # check replicasets % kubectl get replicasets NAME DESIRED CURRENT READY AGE goneup-1100937273 2 2 2 57s # replace replicaset % kubectl replace -f manifest/replicaset.yaml
Deployment
% cat manifest/deployment.yaml apiVersion: apps/v1beta1 kind: Deployment metadata: name: goneup spec: replicas: 3 template: metadata: labels: name: goneup spec: containers: - image: asia.gcr.io/[project]/one/goneup:latest imagePullPolicy: Always name: goneup # create deployment % kubectl create -f manifest/deployment.yaml # check deployment % kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE goneup 2 2 2 2 50s
Service
% cat manifest/service.yaml apiVersion: v1 kind: Service metadata: name: goneup spec: type: LoadBalancer selector: name: goneup ports: - port: 8080 # create service % kubectl create -f manifest/service.yaml
Ingress
% cat manifest/ingress.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: goneup spec: rules: - http: paths: - path: /* backend: serviceName: goneup servicePort: 8080 # create ingress % kubectl create -f manifest/ingress.yaml
まとめ
各マニフェストファイルを作成することで、簡単にGCP上にk8sを構築できました。
また情報にアクセスしたい際は、kubectl get xxx
で簡単にアクセスできるところが非常にいいなと感じました。
基本的な設定しか入れていないので、利用してみてもっと詳細な設定まで使いこなせると良いかと思います。