yn2011's blog

技術メモ

Rictyのバッククォート`が隣接する文字と重なる問題を解決したメモ

環境

問題

  • スクリーンショットを撮るのを忘れていたが、`が隣の文字と重なってしまっていた(`uがúみたいな感じになる)
  • markdownや文字列リテラルでバッククォートはよく使うんだけど、その度にこれが起きていて微妙な気持ちになっていた

解決策

  • Rictyのバッククオートを修正する
  • 多分簡単には直らないんじゃないかなと思っていたが、重い腰を上げてググってみたらすぐに解決方法が見つかった上にすぐ直った

FontForgeのインストール

  • GUI版もあるが、CLI版で十分なのでbrew install fontforgeする

スクリプト実行

  • 上の記事のコメント欄のスクリプトを保存
  • ./script.sh ~/Library/Fonts/RictyDiminished-Regular.ttf (ファイル名は修正したいフォントに合わせる)
  • ちなみに、VSCodeのフォントで使っている場合は、1度workspaceを開き直さないと表示が変になった

やっぱり気になったことはスルーしないで解決していく姿勢が大事ですね...(案外すぐ直ることも多い)

「勝ち続ける意志力 世界一プロ・ゲーマーの「仕事術」」を読んだ感想

前回の記事に続き、プロゲーマー本シリーズ。今回は勝ち続ける意志力 世界一プロ・ゲーマーの「仕事術」を読んだので感想を書く。最近、自分語りの投稿が増えているのはリモートワークが続いていることと何か関係あるのかもしれない。

成長が目的

  • ときど氏が「ゲームを通じた交流」をモチベーションにしていたのに対して、梅原氏は「自身の成長と人生の充実」こそが目的であるとしているのが対照的
    • ゲーム自体は手段に過ぎない
    • 成長を楽しむという目的で割り切って何かをするのも確かに楽しそう。例えば競技プログラミングは、言語はC++*1だし、複雑なアルゴリズムや数学的な考察は実生活では特に役に立たないので*2モチベーション湧きにくいけど、人生を充実させるための趣味と捉えれば別にいいのかもしれない。(むしろゲームよりは遥かに収入に結びつきやすい競技ではある)

お金が目的の人にとっては、効率の悪い努力とか、荒波に揉まれる経験は必要ないのかもしれない。お金さえ手に入れば、自分自身の成長などなくても満足なのだから。

梅原大吾. 勝ち続ける意志力 世界一プロ・ゲーマーの「仕事術」 (小学館101新書) (Japanese Edition) (Kindle の位置No.972-974). 小学館. Kindle 版.

僕はゲームを楽しみたいとか、ゲームで勝ちたいとか、その程度の気持ちではなく、もう少し別の次元で物事を考えている。やはり、ゲームはあくまでもゲームで、本当の目的は自分自身の成長にある。だから、あえて暗くて険しい道を行く。

(Kindle の位置No.1063-1065). 小学館. Kindle 版.

ゲームを通して自分が成長し、ひいては人生を充実させる。いまは、そのために頑張っているんだ、と。

(Kindle の位置No.1646). 小学館. Kindle 版.

何度か書いてきたことだが、いまの僕は日々の成長、継続に喜びを感じている。そうやって毎日、一歩一歩進んでいる。

(Kindle の位置No.1526-1527). 小学館. Kindle 版.

目標と目的の違い

大会で勝つこと自体を目的にするとろくなことはない。少なくとも僕の場合、結果だけを求めて出場した大会で良い成績を残せたことはない

(Kindle の位置No.1634-1635). 小学館. Kindle 版.

大会というのは、日々の練習を楽しんでいる人間、自分の成長を追求している人間が、遊びというか、お披露目の感覚で出るものではないだろうか。大会における勝利は目標のひとつとしてはいいかもしれないが、目的であってはいけない

(Kindle の位置No.1642-1645). 小学館. Kindle 版.

  • 受験、資格試験、転職なんかにも言えそう。それは目標なのか?目的なのか?
    • 受験(入学)や転職(入社)は目的化してはいけないものの典型だろうなという実感がある
    • 自分も大学受験(入学)は完全に目的化していて、大学生活で何をしたい・どう過ごしたい等は全然想像していなかった...
    • 本当は、自分の興味関心を追求する勉強の通過点であるべきなんだろう
      • 当時の自分は勉強が好きというよりも、テストの点数という「結果」と他者との「競争」、それを通じた「成長」が好きだったのかなとも思う*3
        • でもここをもっと掘り下げると、実は梅原氏と同様に自分に対するコンプレックス、疎外感、アイデンティティの確立みたいなものが関わっていたようにも思えて、なかなか深い。それはまさに、格ゲーで対戦相手を"倒す"こと、強さを求めていた以前の梅原氏の行為と本質的には同じことなのかもしれない

勝っても喜ばず、負けても落ち込まない。結果はあくまでも結果で、自分にとってはもっと大事なことがあるから、どちらにせよすぐ忘れる。

(Kindle の位置No.1812-1813). 小学館. Kindle 版.

何かを目標に、ある一定の時期だけ頑張っていると、目標がすべてになってしまう。そして、目標を達成できなかったときに立ち直れなくなってしまう。

(Kindle の位置No.1862-1863). 小学館. Kindle 版.

  • 梅原氏は、自分のモチベーションが低下して何もしたくなくなることに対する恐れみたいなものを持っている印象
  • 自分も勝ち負けに拘らず、求道者といった感じの生き方を志向していきたい(とはいえ、梅原氏は「飽きるほど勝ってみないとこの感覚は分からないかもしれない」とも講演で話している)

基礎を学ぶ

何かを身につけたいと思うのであれば、丁寧に、慎重に、基本を学ぶべきだ。下手なうちから独自の取り組み方をしたり、自由に伸び伸び練習したりすると、最終的に底の浅い仕上がりになってしまう。少なくとも2年、あるいは3年、基礎を学ぶ必要がある。自分の我を通すことなく、セオリックなことを学ぶべきだと考えている。

(Kindle の位置No.1216-1219). 小学館. Kindle 版.

  • ときど氏が「世界一のプロゲーマーがやっている 努力2.0」でも同じことを書いていた。"丁寧に・慎重に"という部分が印象的。
  • 麻雀は2年ぐらいはまったく成果が出ていなかったそうで、さらっと2年とか書くけど成果でないまま2年は相当辛いと思うので凄い。

継続

毎日、60の幸せを手にするため、作業しているとき以外は逆に自信を持って休むことが大切だ。明日の英気を養うことも、継続的な努力の内なのだから。時間を費やすことだけで努力している気になる人が多いが、限界を超えて打ち込んでも成果は上がらない。1日6時間なら6時間、3時間なら3時間と時間を決めて、集中する方がいい。そして後は自信を持って休む

(Kindle の位置No.1845-1849). 小学館. Kindle 版.

  • これも「世界一のプロゲーマーがやっている 努力2.0」と類似の内容で、ON/OFFの重要性はやっぱり普遍的なんだろうな

嫌悪感

だけど正直、みんなから孤立してゲームを追求するというのは、なかなかどうして辛かった。しかし、ゲームが好きという気持ちを裏切ることはできなかった。

(Kindle の位置No.269-271). 小学館. Kindle 版.

中学卒業のとき、高校卒業のとき、進学先や就職先を決めていく同級生を見ながら、ゲームしかない自分への嫌悪感を拭うことができなかった。

(Kindle の位置No.1440-1442). 小学館. Kindle 版.

  • 梅原氏も当然に1人の人間なんだと思わせる一節
  • 自分もプログラミングは好きだと思うが、やはり他者と自分を比較して、嫌悪感とまでは言わないが、孤立感や、本当に自分はこれでいいのか?と自問自答して憂鬱になったりといった経験はある
  • しかし、プロゲーマーになった後の梅原氏は、ゲームしかない自分が世間から認められることで自身を肯定できるようになったとのこと
    • 自分は何か世間から認められているというわけでもないけど、最近は自分の生き方を他者と比べるようなことはあまりしなくなった。結局、人間はその人らしく生きることしかできないし、それが1番幸せなのかなと思っている

*1:選択は自由だが実質C++デファクトらしい

*2:上位層になるとそれを仕事に活かせるかもしれないけど

*3:逆に純粋に興味があったのは英語、数学(代数系)、歴史(幕末~)ぐらいで偏りあるし、好きな分野だけでコンスタントに試験で得点することは難しい

「世界一のプロゲーマーがやっている 努力2.0」を読んだ感想

世界一のプロゲーマーがやっている 努力2.0が面白かったので雑にメモを書く。

「75点」取れたら次に行く

他人より格段にうまくなろうとか、100点を目指そうと意気込む必要はありません。まずは人並みでいい。そのくらい軽い気持ちでかまいません。そしてそこから少しずつできることを伸ばしていく。問題はそれをどこまで、「その環境で」伸ばしていくかです。僕は感覚的に75点からせいぜい80点で打ち切ります。80点とは、その集団では上位20%に入るくらいです。打ち切ってどうするのか。次のレベルの環境へ移ります。

ときど. 世界一のプロゲーマーがやっている 努力2.0 (Japanese Edition) (Kindle の位置No.635-641). Kindle 版.

  • これは共感できる。根拠を問われると経験的にそう思うとしか言えないけれど...
    • 例えば、公立中学・高校は進学時にしか環境を移れない*1ので、自分は同じ学校内で上位数%になるために疲弊していたこともあったんだけど、適切に違う環境に移れていれば心理的にも楽だし成長も早かったんだろうなと思う。

自分が無理をしていないか、常にモニターする

自分のことをモニターするために、僕は1冊のノートを使っています。毎朝、昨日1日の自分の状態を記録する、いわば「自分の通信簿」です。

ときど. 世界一のプロゲーマーがやっている 努力2.0 (Japanese Edition) (Kindle の位置No.827-828). Kindle 版.

  • 心のエネルギーは有限リソースなので、無理をしていないかを常にモニタリングしているとのこと。
  • いかにもプロっぽい、ストイックな習慣で素直に凄いなと思った。
    • 具体的には睡眠時間、食事回数、脈拍、幸せ度etc...を段階評価しているらしい。
  • 自分はあまり項目が多いと続かなそうだからある程度厳選した上でやってみたい

体力

移動だけで疲労しているようでは、それだけで実力を発揮することはできなくなってしまう。強烈な危機感から、僕は2015年ごろから、筋トレを始めました。

ときど. 世界一のプロゲーマーがやっている 努力2.0 (Japanese Edition) (Kindle の位置No.889-890). Kindle 版.

  • 自分が筋トレをする目的の1つはこれ。結局、現実的に何かを成し遂げるために必要なのは体力なんじゃないかと思っている。
    • 人間の努力・経験・思考力・記憶力etcなんて他の人とは(大抵は)大差なくて、多くの場面で最後に差がつくのは意思と体力なのかなあと。もちろん例外はあるとは思うが。

基本の完成度

気をつけないといけないのは、70%くらいの完成度になっていると、練習レベルでは99%の人と差があまりないと錯覚してしまうこと。さらに、基本の技でミスをして負けても、単なるケアレスミスと勘違いしてしまうことです。プレッシャーのかかる場面や複雑な場面になると、基本の完成度の差が現れるのはよくあることで、これは「必然のミス」です。不意に九九を聞かれて答えられないようでは、数学のどんな試験でも使い物にはならないですよね。それと同じことです。「平凡だ」と感じるまで仕上げるとは、どんな大舞台、どんな非日常の場面でも、何も考えず技が出せるくらいの完成度に仕上げることをいいます。

ときど. 世界一のプロゲーマーがやっている 努力2.0 (Japanese Edition) (Kindle の位置No.1113-1115). Kindle 版.

  • これもストイックなお話で、数学の例もめちゃくちゃよく分かる。九九ではないけど受験/試験で嫌というほど味わったな...
  • プログラミングの場合だと、コーディングの素早さ・品質の高さなんかに現れてきそう
    • 基本的な言語仕様、構文、標準ライブラリを頭で理解しているだけでなく、"どんな大舞台、どんな非日常の場面でも、何も考えず技が出せるくらいの完成度に仕上げ"ているか
      • 迷いなく手を動かしてコードを書けるかみたいな感じ?  競プロだと基本的なアルゴリズムについても同じことが言えそう。
    • とはいえ、自分はコーディングに関しては意図して反復練習するよりも、繰り返し書いていたら身に付いていた、という感じの方が自然で楽しいんじゃないかなとも思っている
      • 受験数学は確かに間違った問題を3~5回ぐらい解くのを自分もやっていたが、そういうストイックさは今の自分にはもうない気がしている...
      • また、業務を進めるだけなら、そこまで1つの言語に全力で向き合う必要もないんじゃないかという思いもあり複雑

ルーティン

ルーティンを設定するのは大事だが、縛られないようにする。予想外のことが起きてもイライラしないで柔軟に対応する。ただし1番大事なポイントは抑える。それだけは何が起きても優先させる。

Kindleの引用上限に達したので以下引用ではなく要約。

  • ルーティン設定あるあると、その対処法
  • 自分の場合だと起床してから出社までのルーティンを確立したい気もするが、結構気分や体調で変わるのであんまり意味なさそう

自分を変えるな、環境を変えろ

  • 例えば、ときど氏は部屋にベッド以外何も置かないことで練習やジムに行きやすくしているらしい。
  • こういう話好きだけど、自分に適用できるかというとあまり思いつかない。姿勢を良くするよりアーロンチェアを買うとかそんな感じかな

アウトソーシング

  • ときど氏は、目的と関係ない部分は全てアウトソーシングしているとのこと
    • 例えば東大受験の例だと、合格することが目的なので、受験対策の研究・勉強の進め方は全部予備校に任せて、自分は勉強することだけに集中して時間を節約した
  • 自分も筋トレは同じことを考えていて、パーソナルトレーナーに完全依存している。自分で筋トレの仕方を研究するモチベーションはない。
  • 多分もっとアウトソーシングできることありそうな気もするが、そこまで時間を節約して自分は何がしたいのか?というところが実は曖昧だったりもする。

ちょっとしたことを「やめる」訓練

  • ときど氏は、ゲームの練習・ジム等の大事な毎日の習慣でも、あえて2週間休むこともあり、長期的にはその決断が有効に働いているとのこと
  • 義務感・根性で1日も欠かさず続けることよりも、「嫌ならやめる」ことで結果につなげる
  • これはめちゃくちゃ分かる
    • 趣味でコードを書くのも基本的には自分のモチベーションを大事にしている。無理に生産的なことをしよう・”しなければならない”と思うようになったら危険信号だと思う
    • 「嫌だからやめる」がずっと続く場合はきっと自分に向いていないので自分がやらない方が良いことだということも分かる。その分別のことに時間を使えばいいと思う

「努力したい」と思える場所

  • ときど氏は、コミュニティの雰囲気、仲間意識、ゲームが好きという共通点だけで世界中の人と繋がれる喜びがプロゲーマーとしての強いモチベーションになっているとのこと
  • そう考えると、自分もはてな界隈を中心とした所謂Web系エンジニアのコミュニティ*2の自由な雰囲気と技術に対する情熱に魅力を感じているのかもなあと思った
    • 特に学部4年あたりの時期までは、まさに"「努力したい」と思える場所"を探していたんだろうなあと思う、そしてそれが見つかったことも院進ではなく就職を選んだ理由の1つなのかもしれない*3

*1:転居等の特別の場合は除く

*2:というほどの実体はなくて観念的・自分の幻想ともいえるかもしれないけど

*3:一応正確に書くと、Web系エンジニアのコミュニティを認識し始めたのは3年後期の就活終了後だったんだけど、4年で院進の判断自体はできた中でやっぱり社会に出てみようと思えた理由なのかもという感じ

Alfredでユーザと検索ワードを指定してTwitter検索するWorkflowsを作った

自分のtweetはメモ代わりでもあるので、時々検索したくなる。Alfredから検索できると便利かなーと思ったのでWorkflowsの練習がてら作ってみたので記録。

環境

  • Alfred 4.0.8 (Power Pack)

作ったもの

f:id:pokuwagata:20200308204037g:plain

作り方

f:id:pokuwagata:20200308204717p:plain

f:id:pokuwagata:20200308204336p:plain

read user word<<< "{query}"

open "https://twitter.com/search?q=${word}%20(from%3A${user})&src=typed_query"

感想

シェルスクリプトは便利です

TypeScriptで「ヒーリングっど・プリキュア」を実装してnpmパッケージとして公開した

作ったもの

www.npmjs.com

モチベーション

以下感想

クラス設計(モデリング)の難しさ

  • やっぱりOOPのクラス設計は悩む
  • 最初はプリキュア毎にクラスを作ったが何か違う感があった(例えばCureFontaineクラス, CureGraceクラス...)
    • new CureFontaine()インスタンスを作るが、キュアフォンテーヌは1人しかいないはず(シングルトンにしてもいいけど...)何か違う
  • というわけで、ここでは状態をモデリングするのが多分妥当だろうと結論付けた
    • プリキュア毎に、人間状態、変身状態クラスを定義しPrecureクラスのインスタンス作成時に注入する(new Precure(new fontaine.Human())みたいな感じ)
    • 違和感が解消されプリキュアという概念を正しくモデリングできている(と思う)
    • 変身時の共通の口上はHumanState, PrecureStateクラスで定義して継承すれば変更にも強い(例えば変身時にはプリキュアによらず「スタート!プリキュア ・オペレーション」と出力する)

Stateパターンによるタイプコードの置き換え

  • 状態のモデリングの着想はここから得た
  • プリキュアは変身前後で2つの状態を持ち、状態に依存して振る舞いが変わる(名前や技、変身の可否等)
  • インスタンスに状態を示す変数を持たせて、メソッド内で状態に応じて分岐させることもできる(例えばisTransformedを定義して、if文で分けて...等)
    • しかし、状態や状態固有のロジック等が追加されていくと辛くなる(例えば2段階変身が追加されたり、感情が追加されて振る舞いが変わるとか)
  • Java言語で学ぶリファクタリング入門State/Strategyによるタイプコードの置き換えというパターンが紹介されていることを思い出したので適用してみたらけっこう良い感じになった
  • 状態が増えても固有の振る舞いが追加されても非常に見通しが良い

npmパッケージを公開

  • npmのアカウントさえあれば本当にすぐ出来る
  • ローカルでは$npm packして生成したtarを$npm install path/to/tarして動作検証可能

TypeScriptの言語仕様

  • クラス定義周りの言語仕様で、Javaと同じだと勝手に思っていたというか「そういえばそうなんだな」という発見があった
    • Reactのコンポーネントクラスの実装と0からのクラス設計では使う言語機能が違うからかもしれないし、単にTypeScriptを書く量が不足しているのかもしれない
  • 例えば
    • enum classは定義できない
    • innner classは定義できない
    • クラス内でthisは省略できない(Javaのサンプルコードを読んでいて、そういえばとなった。TypeScriptはやはりJavaScript

HerokuでDocker, Go, Postgresを使ってAPIサーバを動かしてみた感想

環境

モチベーション

  • データのCRUDを伴うWebAPI(とDB)をサクッと作って公開したい

どうやったか

  • ローカルはAPIとDB共にDockerで環境構築
    • APIはそのDockerfileを使ってHerokuにデプロイ
    • DBはHeroku addonsのPostgresを使用
  • APIの実装はgin, gormを使って楽をした
  • スキーマのmigrationはgoose(下の記事で使われてたのでそのまま使った)

できたもの

https://infinite-hollows-34092.herokuapp.com/api/ping

GETリクエストすると現在日時を格納する。これまでに格納された現在日時を全て返す。

github.com

手順

以下の手順に従って進めた。上記のコードはほぼ以下の記事のコードの写経に近い。フロントエンドがないのとgormを使っている点が違うだけ。

以下、感想を書きます。

Heroku addonsのPostgresについて

今まで使ったことなかったけど、コマンド1つでクラウド上にDBを作成できてここまで色々できるの凄いなと思った。

Dataclips

data.herokuのDataclipsを使うとブラウザからPostgresを参照できる。参照系のクエリを書くのでViewみたいな感じ。 このViewに対するURLを発行することもできて外部連携も可能な模様。

f:id:pokuwagata:20200222155840p:plain

pgsql

ターミナルからpg:psqlで接続することも可能。

❯ heroku pg:psql
--> Connecting to postgresql-rectangular-83658
psql (12.1)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

infinite-hollows-34092::DATABASE=> delete from ping_timestamp where id = 4;
DELETE 1
infinite-hollows-34092::DATABASE=> select * from ping_timestamp;
 id |           occurred
----+-------------------------------
  1 | 2020-02-22 06:06:15.302206+00
  2 | 2020-02-22 06:06:26.004438+00
  3 | 2020-02-22 06:06:33.051055+00
(3 rows)

infinite-hollows-34092::DATABASE=> \q

Dockerを利用したHeroku デプロイについて

Dockerfileを使ってHerokuにデプロイするためにheroku.ymlを書く。例えば今回は以下になる。

build:
  docker:
    web: Dockerfile
    worker:
      dockerfile: Dockerfile
      target: builder    
release:
  image: worker
  command:
    - ./migrate.sh

ちょっとイメージしにくかったのがreleaseフェーズで使用されるworkerの部分

  • このDockerfileではmulti stage buildをしていて、Goのモジュールのビルドと実行を分離している
  • releaseフェーズではPostgresに対してmigrationを実行するだけだが、その実行環境をworkerとしてbuildフェーズで事前にビルドしている
    • なので同一のDockerfileを元に2つのイメージを作成している。webの方はGoのビルドと実行までで、workerはGoのビルドまで。

これは実際に$ git push heroku masterしてHerokuが出力してくれるログを眺めると何をしているのかが分かって良かった

その他

  • Netlify, Heroku, Firebase等、遊びで何かを作って公開するのが楽な時代になった
  • 業務のサービス開発にいつも使えるとは限らないけど、選択肢として持っておくべきと思う
    • 仮説検証的・速度重視の開発や、パフォーマンスを求められない単機能なWebAPIの開発など?

docker rmiで image is referenced in multiple repositoriesが発生した

環境

  • macOS 10.14.6
  • Docker version 19.03.5, build 633a0ea

Dockerの掃除をしていたら

  • docker images を全削除するを参考に、イメージとコンテナの掃除をしていた
  • その中になぜか削除できないイメージがいた
~/.ghq/github.com/pokuwagata/go-gin-gorm-heroku-example master* 11s
❯ docker images
REPOSITORY                               TAG                 IMAGE ID            CREATED             SIZE
portfolio-go-mysql-docker-webapp_nginx   latest              8a2fb25a19f5        10 months ago       16MB
nginx                                    1.14-alpine         8a2fb25a19f5        10 months ago       16MB

~/.ghq/github.com/pokuwagata/go-gin-gorm-heroku-example master*
❯ docker images -aq | xargs docker rmi
Error response from daemon: conflict: unable to delete 8a2fb25a19f5 (must be forced) - image is referenced in multiple repositories
Error response from daemon: conflict: unable to delete 8a2fb25a19f5 (must be forced) - image is referenced in multiple repositories

An image will be listed more than once if it has multiple repository names or tags. This single image (identifiable by its matching IMAGE ID) uses up the SIZE listed only once.

docker images | Docker Documentation

  • そういうわけで、idではなく、リポジトリ(とタグ)を指定してdocker rmiすれば削除できる
❯ docker rmi portfolio-go-mysql-docker-webapp_nginx

結果

スッキリ

~/.ghq/github.com/pokuwagata/go-gin-gorm-heroku-example master*
❯ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

~/.ghq/github.com/pokuwagata/go-gin-gorm-heroku-example master*
❯ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

定期的に掃除していきましょう