OmniAICreator/Qiita-1.07M huggingface dataset:
速度改善方法

#概要
[相生葵の Advent Calendar 2020 5日目](https://adventar.org/calendars/5480)の記事です。

自分がしている速度改善方法について書きます。

#手順
1. 速度計測のためのログを仕込む
2. ログからボトルネックを探す
3. 1、2を繰り返してボトルネックを明確にする
4. 何が原因になっているか考える
5. 原因に対して解決策を出す
6. 解決策を掘り下げる
7. 改善する

##はじめに
クライアント側の場合、必ず速度計測は実機で行います。
実機ごとにボトルネックになっている箇所が違ったりするためです。

サーバ側は、サーバのスペック、データベースのデータ量などが本番と近い環境でする方がより近い速度が計測できます。

##1. 速度計測のためのログを仕込む
###目的
ボトルネック箇所を探すためです。
###理由
コードを見てどこがボトルネックになっているか分かればいいですが、ログを仕込んで確認する方が確実です。<br>

問題個所で大きな割合がかかっている箇所を潰せば、一発で大部分の時間を短縮することを期待できます。
ただ闇雲に改善していっても、本当に改善して効果がある箇所かは分からなかったりします。

###ログの入れ方

初めは大まかに入れて、だんだん範囲を絞って細かく入れていきます。

##2. ログからボトルネックを探す
出力されたログから、時間がかかっている箇所を見つけます。

##3. 1,2を繰り返してボトルネックを明確にする
1. ログを仕込む
2. 1の中で遅い場所に絞ってさらにログを細かく入れる

1,2を繰り返してボトルネックを明確にします。

##4. 何が原因になっているか考える
3まででボトルネック箇所は分かっているので原因を考えます。

* ループの重なりで計算量が大きくなっていないか
* 無駄な処理をしていないか
* クエリ発行数が膨らんでいないか

など

##5. 原因に対して解決策を出す
4で出した原因に対する解決策を考えます。

##6. 解決策を掘り下げる
解決策に対して以下を考えます。

* 既存の処理と動きが変わる部分はないか
* 動きが変わる場合は、その動作に変えてしまって問題ないか

この時点で疑問点や懸念点が出てきたら、潰しておきます。
自分で解決できそうなものは調査などをして、他の人に確認しなければいけないものに関しては確認をします。

##7. 改善する
6で懸念点なども潰しているので、後は決めた解決策で改善していきます。

解決策が本当に効果があるのかは、速度計測を行って判断していきます。

#補足
大きめの速度改善については、ボトルネック箇所が複数あることがあるので計測を行って、対応する優先度をつけます。
時間がかかっている箇所ほど、効果が出やすいのでかかっている時間を優先度にします。
Rubyのコードを書く上で知っていると便利なこと



Rubyのコードを書く上で便利なことを参考書で学びましたので
勉強の記録用として記事にしてみました。
#%記法
##%w

```ruby
> ary1 = ['apple', 'banana', 'orange']
> puts ary1
=> ["apple", "banana", "orange"]

> ary2 = %w(apple banana orange)
> p ary2
=> ["apple", "banana", "orange"]
```
すべての要素が文字列である配列は、通常の配列記法の他に、<strong>「%w」</strong>というキーワード使って書くことができます。

##%i

```ruby
> ary1 = [:apple, :banana, :orange]
> puts ary1
=> [:apple, :banana, :orange]

> ary2 = %i(apple banana orange)
> p ary2
=> [:apple, :banana, :orange]
```
すべての要素がシンボルである配列は、<strong>「%i」</strong>というキーワード使って書くことができます。

%記法を使うことでソースコードに記述する文字数を少し減らすことができ、可読性が良くなります。
自主制作ゲームで使用した処理

今回は初投稿と言うことで初心者ながらこの前開催された
ぷちコンジャムで制作したゲームの処理について話していきます
#ゲームの動作確認はしっかりとしよう!!
![Sunsun - Unreal Editor 2020_12_05 1_09_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/849038/aff7b3a4-c875-8be5-161c-cdc6e81d1384.png)
私自身ue4を触り始めて1年ほどなのですが友人に完成したゲームを遊んでもらうと
実装したものと違う動作をしてしまいとても困っていました
原因は**フレームレートの違い**でした
解決方法を調べた結果フレームレートを固定すればいいとのことなのですが
どうやらそれができないようなので
今のところは無理やりですがこういう処理で乗り切っています
上の画像の処理はゲーム開始時にコマンドを呼び出すのですがこのコマンドは
**フレームレートの上限を30にする**コマンドです
この処理を挟むことで疑似的にですがフレームレートを固定することができます
これをすることでパッケージ化後に変な動作をしなくて済むようになります![Sunsun - Unreal Editor 2020_12_05 1_24_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/849038/aa1099a1-2c91-9965-2c41-45714d5d446e.png)
この動作がおかしくなる影響を受ける処理は主にTickのように
**連続で呼び出す処理**が影響を受けるようです
皆さんもゲームを作る際におかしな動作をしたと思ったら試してみてください!!
【ESET】が原因！Dockerでlocalhostに繋がらないエラー(Mac)

## 事象
Dockerの環境構築後、Chromeで[http://localhost/](http://localhost/ ) にアクセスするも15秒ほど固まった後、「このページは動作していません」というエラーが出てしまいました。
色々調べたところ、どうやらウイルスソフトのESETが原因だったようです。


## 環境

- MacBook Pro(Retina, 15-inch, Mid 2015)
macOS Mojave(10.14.6)


- docker desktop community
Version 2.5.0.1(49550)


- eset CYBER SECURITY PRO
バージョン6.6.8.300.0


- Dockerの環境構築で参考にさせていただいた記事
[最強のLaravel開発環境をDockerを使って構築する【新編集版】 - Qiita](https://qiita.com/ucan-lab/items/5fc1281cd8076c8ac9f4)



## 解決法

※自身のメモとして記録しております。
セキュリティソフトを設定を変更する為、以下の方法を試す場合はくれぐれも自己責任でお願いします。

<br>

まずESETを開きパーソナルファイヤーウォールの設定を`有効`→`無効`に変更し、再度[http://localhost/](http://localhost/ )へ接続。

これで無事接続が確認できました。
しかしESETのパーソナルファイヤーウォールを無効にし続けたり、開発するタイミングだけ無効にするのはセキュリティー的にも手間的にも良くありません。

そこで以下の記事の方法でESETの設定に追加をしてパーソナルファイヤーウォールの設定を有効の状態のままlocalhostに接続ができるようになりました。
[ESETのファイアウォールが動作しているとDockerで立ち上げたlocalhostのページがブラウザで確認できない問題 - Qiita](https://qiita.com/miriwo/items/207de4783a88abd11c71)


他の設定方法での記事もありましたが、私のPCではこちらの記事の設定方法でのみ接続ができました。



### 余談

過去にPHPをMAMPを使いローカル環境で動かそうとした際にも、ESETが原因でlocalhostに繋がりませんでした。
その時は、一時的にESETのパーソナルファイヤーウォールを無効にしてやり過ごしてました。
MAMP環境で同様のエラーが出る方も、有効である可能性がありますので参考になれば幸いです。
[初心者向け]Windows10でのApacheのVirtualHost化について


駆け出しエンジニアの私が、ずっと理解ができず困っていたVirtualHost化についてメモ程度に残させていただきます。
また超初心者向けの内容になるので、詳しい内容については省いて説明します
至らない点等多数あると思いますが、優しく見守っていただければ幸いです。

#VirtualHost化とは？
ローカル環境で指定のドメイン設定ができることです。
例：●●.com
みたいな感じです。
ちなみに、複数設定可能です。

##VirtualHost化をするメリット。
これに関しては、私個人的な意見にはなりますが、

1.本番を即したルーティングができる。
2.指定したドメイン名を打てば開けるので、都度ドキュメントルートを変更する必要がない。

こんなところです。

##Apacheの設定


###各種環境

xamppのインストール等はしているものと仮定しています。

 ● Windows10
 ● Apache/2.4.43 (Win64)
 ● Xampp(PHP 7.4.6)


###今回設定するフォルダ

 ● C\xampp\apache\conf\extra\httpd-vhosts.php
 ● C:\Windows\System32\drivers\etc\hosts




###Apacheフォルダの設定


```php:xampp\apache\conf\extra\httpd-vhosts.php
<VirtualHost *:80>
    DocumentRoot "C:/xampp/htdocs/****"
    ServerName ****.com
 
    <Directory "C:/xampp/htdocs/****">
        AllowOverride All
        Require all granted
    </Directory>
    
</VirtualHost>
```

このような記述を、コードの一番下に記載します。
また
```<Directory "C:xampp/htdocs/***>```
の部分には開きたいファイルを指定してあげましょう。
ちなみに****.comの部分は自分で設定したいドメイン名を記載します。

###Windowsフォルダの設定

```C:\Windows\System32\drivers\etc\hosts

# localhost name resolution is handled within DNS itself.
	127.0.0.1       ***.com
#	::1             localhost
```

このように先ほどの指定したドメイン名を指定すれば完成です！
また、記載時に管理者権限のアラートがでますので、許可してあげましょう。
ここまで出来たら、Apacheを再起動させ、指定ドメイン名を叩いたら表示されます！

###補足

また、```C:/xampp/apache/conf/httpd.conf```の
175行目くらい
● ```#LoadModule vhost_alias_module modules/mod_vhost_alias.so```
508行目くらい
● ```#Include conf/extra/httpd-vhosts.conf```
の先頭に#が付いている場合はのけてやりましょう。

[参考]
https://www.granfairs.com/blog/staff/apache-vhost-2017
https://qiita.com/TanukiTam/items/e11222751fe7ff70b07f
【BtoBシステムあるある】特別対応する場合のモデルについて考察する

この記事は　[ZOZOテクノロジーズ #2 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/zozo_tech2) 5日目の記事になります。

昨日は[kotatsu360](https://qiita.com/kotatsu360)さんの[AWS SSOのユーザx権限一覧をつくる](https://qiita.com/kotatsu360/items/d8efa36580f976e3f62d)でした。（棚卸し大事！）

# はじめに

BtoBのシステムを運用していくと、よくあるケースとして、「このお客様はこの箇所を現状のとおりでなく、特別な運用としたい」ということがよくあると思います。

接続する基幹システムの都合であったり、会社のルールの都合であったりサービスを使っていただくために避けられない壁を超えるために対応することが多々あるかと思います。

例えば、
・　システムは電話番号がハイフンありだが、お客様側の基幹システムでは数字のみのバリデーションが走っておりハイフンが使えない

・　システムで自動で作成されるIDがあるが、お客様側の基幹システムで別のID付与ルールがあるため基幹システムで使っているIDを使用したい

・　システムではAPIで連携しているが、お客様側で使っている連携システムの方が拡張できないためファイルで連携して欲しい。。。
などなど、よくある話かと思います。


このようなケースでやりがちなパターンと問題点、改善パターンを紹介します。

# やりがちなパターン

よくある対応の仕方として、単純にこのお客様の場合処理を分けるということをするかと思います。

```java
class あるクラス
  String ある変数;

  Boolean validFormat(Client client){
    if(client.name == "B社"){
      // B社用のチェック
    }else{
      // 既存のチェック
    }
 }
 
```
改修も数行で済んで良いですね（？？？）。


## 対応後によくあること

さて、このような対応を何箇所かに設定して、無事B社向けにリリースできました。

その後、順調にサービスも成長して導入企業様も増えていきます。そんななかで、別の特別対応が色々と入っていくのが世の常であります。

そんなある日、営業からこんな問い合わせが・・・

**「今検討中のF社がB社と同じ基幹システム使ってるけどB社の時どんな対応したっけ？」**
とか、
**「以前特別に○○対応したと思うんだけどどのお客様で対応したっけ？」**

さてこんな時どうします？
多くの対応が既に入ったソースコードの中から ```if(client.name == "B社")``` とある箇所を全部検索するか？
または、開発当時のスプレッドシートやスライドの資料を探しまくるか？

いずれもちょっと面倒かつ、正確に割り出せる気がしませんね。

こういうケースは、BtoBなビジネスをしているシステムのあるあるかと思いますので、あらかじめ追いやすいソースコードを書いておきたいものです。

# 改善策

どういうソースコードなら良かったか？要件は2つです。

1. **特別に対応した箇所のソースを探しやすいこと。IDEで1回ソースの参照をしたら全部抜き出せたらいいですね。**

2.  **特別対応したお客様の一覧が容易に抜き出せること。顧客のマスターから辿れれば良さそうです。**

であれば、こんなクラス構成でどうでしょうか？

![blog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150455/85559feb-c6a5-134a-7cab-989df9875b4a.png)


「Client」は「〇〇対応」をしているかどうかを知っている。
「あるクラス」はClientが○○対応をしているかどうかで、「通常あるクラス」か、「特別あるクラス」かになる。
といった感じです。（※ かなり簡略化した図なので諸々汲み取ってください・・・特に名前は慎重に）

ポイントは3つ。
・「〇〇対応をしている」クラスから **IDEで参照箇所を検索するだけで該当の箇所がわかる**。
これは営業からの問い合わせに容易に答えられるだけでなく、実際に他社展開して導入することも、その後のバグFixも容易になる、ソースコードも追いやすいということです。

・Clientのマスターから**対応しているお客様一覧が容易に検索できる。SQL一発**ですね。

・**クラス図で表現できる** から資料化しやすい。意外とここがポイントで、こういう特別に対応した箇所は大体運用でも重要な箇所になってきます。メンテが入りがちだったり、バグが出やすかったりするところです。
だから資料に起こすことがよくあることかと思いますが、これが文章で残ってても大概分かりにくく、資料作った人に結局聞くということになりがち。これが、図でソースの中身を説明できれば分かりやすい資料もできると思います。

# 終わりに

こういう特別対応したケースというのは、開発中から、リリース後日々システムを運用していくなかでも頻繁に話題に上がってくるものだと思います。
つまり、注目すべきドメインであって、ソースコード、特にドメインモデルとして表現されていてしかるべき内容であったりします。

将来こうなりそうだ、こういう問い合わせが来そうだとか、こういう改修をしそうだという予測はなかなか難しいものですが、どういうドメインがビジネスの中心になるかどというのを考えておくことでこのような対応ができるのはないでしょうか？

・・・・・というのを「やりがちなパターン」のような実装をやってしまった後、振り返ったときに気がついたのでこのブログに記録しておこうと思ったのでした。

明日は[sesta](https://qiita.com/sesta)さんへバトンタッチです！
HTML チェックボックスでfalseも判定する

# 目的

- HTMLのinput要素にてtrueだけでなくfalse（チェックされていない）状態を受け取る方法をまとめる

# 詳細

- 下記のようにinput要素のチェックボックスの前に同じnameでinput要素をhiddenで記載する。同じnameで指定することによりチェックボックスにチェックが入っているとnameの値に紐付いてvalueの値が更新される。

    ```html
    <form action="" method="post">
        <input type="hidden" name="test" value="0">
        <input type="checkbox" name="test" value="1">
        <button type="submit">送信</button>
    </form>
    ```
- 直線のinputはtype="hidden"なので表示されない。
- 仮にチェックボックスにチェックが入ったらvalueが1に更新される。
- チェックボックスにチェックが入らなかったらinput type="hidden"で指定されたままなのでvalueは0となる。
Power Appsでお手伝いアプリを作成してみた1

#概要
Power Appsを使って、お手伝いアプリを作成しました。
今回は、画面の構成やテーブルの構成を書こうと思います。

##画面の構成
・お手伝い項目
・ポイント表示
・お手伝い報酬
　何かがもらえるって思うと頑張れるよね？？？

項目にあるお手伝いをするとポイントがもらえるルールにして、ポイントが増えるごとに買ってもらえるものも多くなる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404009/11d26df7-d859-5cff-3d08-ebea900cac80.png)

##テーブルの構成
今回は、MicrosoftDataverseを使用します。

|列|データ型|
|:-:|:-:|
|お手伝い項目|テキスト|
|ポイント|整数|
|報酬|テキスト|
|報酬ポイント|整数|
|ポイント履歴|テキスト|

これで、テーブルの構成ができた！

#次回
Power Appsの画面作成に行くよー
今回はすんごく短くなっちゃったけど…次は長いよ！
まだVBAを知らない君たちへ。なんだかんだ我々はVBAを愛している（と思う）

##まえおき
今年はほとんどコードを書くことがない1年だったのですが、最近久しぶりにVBAに触れる機会があったので、個人の備忘録として雑多にまとめておこうかと思います。

##諸君、VBAはいいぞ
環境構築が簡単であるので個人的には非エンジニア・プログラマの方がプログラミング的なものに触れる最初の入り口としてもちょうどいいのかなと思います。
普段Excelを使う仕事をしているなら、業務を効率化するチャンスがあるかもしれません。
もし複数回、同じことを行う機会があるのであれば、ボタン１つでできるようになったほうが効率的です。
VBAがめちゃくちゃできるとすごい！とかはあんまりないけれど、使えたほうが間違いなくいいです。ちょっとした紳士の嗜みってやつです。

VBA、ここがいい

* リファレンスや用法・用例が調べればいくらでも出てくる。
* セルの処理を行う場合に処理結果が目に見えるので動作が確認しやすい。
* 凝ったものを作ろうと思えばいくらでもこだわれる。


##VBAを書くときはここを意識しろ
保守性・汎用性の担保ができているか。
これにつきます。（VBAに限ったことではないけれど）
「昨日の自分が書いたコードは他人のコード」であり、修正や追加の機能に対して伸びやかな柔軟性を持ったコードは未来の誰かを助けてくれます。
とりあえず動けばいいよね！という他人が書いたVBAを修正することは苦痛なものです。

コピペにより実装されたまとまりのないコード、特定のセルを動作させる部分がハードコーディングになっているため少しフォーマットを直すだけでも影響範囲が読めずに大工事が必要となる膨らんだプロシージャ、先祖代々秘伝のソース…

高い可読性を持ち、各処理毎にプロシージャを分けてコードを書くことで再利用可能な部品としてプロシージャを使うことができます。
次に自分が書いたVBAをメンテする人のことを思いながらコードを作成していきましょう。

##おそらく人生で役に立つことはないだろう。変態的なVBAたち
過去に話題になってきたけれど、実際に使ったことは残念ながらない変態VBAたち。
VBAでその気になればここまでやれるんだぜ…という人生の肥やし。

 [Excelでハリケーンの進路を可視化](https://qiita.com/keisuuuuke/items/1f614484ac27fbc3faae)
 [「Excel上で動くドラムマシン」を作成した猛者が登場する](https://gigazine.net/news/20191107-drum-machine-in-excel/)
 [集中線を作成するしょうもないマクロの作り方【Excel VBA】](https://tdyu.hatenablog.jp/entry/2020/10/24/225059)
 [数式や関数を打ち間違えるとニコニコ動画風に煽ってくるExcel VBAマクロの作り方](https://tdyu.hatenablog.jp/entry/2020/05/26/001420)

【番外編】
[Excelで「ドラゴンクエストIII」をマクロ言語なしで再現した猛者が登場](https://gigazine.net/news/20201104-excel-dragon-quest-3-no-vba/)



##Tips
ほとんどが個人的なメモレベルですが…何かの足しにでもなれば幸いです。

#####処理軽量化
```vb
'処理している動作の描画を出すと重くなるので、ディスプレイの更新をFalseに
Application.ScreenUpdating = False
'処理が終わったらディスプレイの更新を戻すこともお忘れなく
Application.ScreenUpdating = True
```

```vb
'一時的にオペレーティングシステムに制御を移し、イベントの処理を行わせる
'重めの処理の合間に入れることで応答なし状態を防ぐことができる
DoEvents 
```

#####ファイル処理系
```vb
'PDFファイル出力
'ブックのあるフォルダ内にPDFフォルダを作成する場合
Dim outputDir As String: outputDir = ThisWorkbook.Path + "\PDF\" '保存先フォルダパス
'出力先が存在しない場合は作成
If Dir(outputDir, vbDirectory) = "" Then
    MkDir outputDir
End If

Dim outputFileName As String 'ファイル名
outputFileName = outputDir + "PDFファイル名.pdf"

'出力
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, outputFileName :=outputFileName 
```

```vb
'CSVファイルを選択して取得する
Dim csvFileName As String '選択されたファイル名用変数
Dim buff As String 'ファイルの中身を文字列として格納する変数
csvFileName = Apprication.GetOpenFilename(FileFilter:="CSVファイル(*.csv).*.csv", _
                                          Title:="CSVファイルの選択")
Open csvFileName For Input As #1
    Line Input #1, buff
Close #1

Dim lineArr As Variant '1行分を一時的に格納するための配列
Dim tmpArr As Variant  'カンマで分割した1行分のデータを一時的に格納するための配列

lineArr = Split(buff, vbLf) '改行コードで分割
For i = 0 To UBound(lineArr) - 1
    tmpArr = Split(lineArr(i), ",") 'カンマで分割
    'セルへ出力するため、カンマで分割されたサイズ分の範囲にリサイズして値を出力
    Cells(i + 1, 1).Resize(1, UBound(tmpArr) + 1).Value = tmpArr
Next i
```

##おわりに
今回まとめた内容は本当にさわりの部分だけになりますが、VBAに興味を持っていただけると嬉しく思います。
今後、より実務的なVBAのコードをまとめたりもできたらいいな、とぼんやり考えているので機会があればまたお会いしましょう。
算譜言語の神様の計算機の神様

計算機体系の保守と、計算機言語による設計を長らく行ってきた。

何度か、算譜言語の神様が降りてきたと思う瞬間と、
計算機の神様が見守ってくれていると思う瞬間があった。

早い話、神懸かり体験の告白である。

# 算譜言語の神様が降りて来た時1

博士論文の公聴会の前日、つい先日購入したGPSシステムを携えて大学に泊まった。
博士論文用のデータが主にPHSのもので、質問として他のシステムではどうかというのに答えるためのデータ取りのをするためである。データをとるためには、測定システムを取得するか、プログラムを組む必要があった。測定システムを取得しても、その測定システムの精度、品質を評価する必要があるため、どっちにしろプログラムは組む必要が生まれそうだ。
それなら最初からプログラムを組もうと思った。言語はC。GPSシステムにAPIを開示しているAPIがあった。
夕食を食べたあと、プログラムに取り組んだ。プログラムができても、論文の主題である複数経路の遅延差で、経路選択に必要なデータを取得できるとは限らない。
プログラムを組み始めて、数時間、１０時間に到達する前に、プログラムは動作しはじめ、データを取得しはじめた。いくつかやり方を変えて

# 算譜言語の神様が降りて来た時2
VZエディタのN5200への移植を行っていた時の話である。
移植自体は、割り込みベクタテーブルを試験するプログラムをPC-VANに掲載してくださった方がいて、割と容易に実現できた。
PC-9801とN5200の割り込みベクタ処理でそのまま使える機能と、修正が必要になる機能の確認と差し替え後の確認の作業効率が十倍くらい楽になった。
本当に感謝している。
基本機能が移植でき、動作確認を行いながら行ったのが、すべてのアセンブラの命令を註釈にして動作確認を行う方法である。
なぜ、この方法を取ろうと思ったかには３つの要因がある。
第一に、VZエディタはアセンブラのソースコード付きのソフト絵わである。
Vim ネタプラグイン集

# 概要
役に立つのかわからない。
でも入れていたら楽しみが増えるかもしれない。
ネットの奥深くから見つけ出したVimプラグイン集。
すべて動作することを確認済みである。

# [nyancat.vim](https://github.com/kato-k/nyancat.vim)
## 概要
とにかく画面いっぱいにNyancatがでてくるプラグイン。
目がチカチカしてうっとおしいがタピオカの次にこのプラグインが流行ると思う。
コードを書いて疲れた脳みそに栄養を補給しよう。

## サンプル
![nyanvim.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185747/ec3504d7-fade-face-0146-6227773623f8.gif)

# [VimGameSnake](https://github.com/johngrib/vim-game-snake)
## 概要
ヘビゲームという餌を目指してヘビを動かすゲームをプレイすることができる。
とてもたのしい？のでvimの上下左右の操作を覚えられない初心者にはこれで体になじませるのがオススメ。

## サンプル
![snake.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185747/6bf35ba6-1135-2efb-f44d-dae14523df37.gif)

# [longcat.vim](https://github.com/anekos/longcat.vim)
## 概要
長い猫が画面に表示される。
ちょうど猫を描画したい気分だったときにすごく役立つ。
長さが調節可能なのもしっかり実装済み。

## サンプル
![longcat.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185747/5c391cd1-9685-94f1-fee6-342b75b6e5d9.gif)


# [vim-gotham](https://github.com/whatyouhide/vim-gotham)
## 概要
> It's the colorscheme we set that defines us. (Batman)


だれもやらないなら俺が作るとして作成されたカラースキーマ。
ゴッサムシティをイメージしていて非常にダークな色合いが特徴となっている。
このカラースキーマを入れれば声がダミ声になること請け合い。
[ガンダムっぽいカラースキーマもあるよ](https://qiita.com/hann-solo/items/1ca7c995c6a1f256653e)
## サンプル
![gotham.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185747/9310f788-1dcf-6e12-30c1-eb661cb7827d.png)

# [super_unko.vim](https://github.com/unkontributors/super_unko.vim)
## 概要
う〇こを深く追求し、コマンドに落とし込んだプラグイン。
小学生が入れてバカうけ間違いなし。

> super_unko.vim project is the one of the awesome, clean and sophisticated OSS vim plugin project in the world. Let's create shit plugin!

上記のコメントが記載されている通り、高い情熱のもと製作された。

## サンプル
このプラグインはサンプルとして残しておくのはやめておこう
せっかくなので製作者のブログを残しておこう
https://jiroron666.hatenablog.com/entry/2019/07/06/000735

# [vim-game-code-break](https://github.com/johngrib/vim-game-code-break)
## 概要
ブロック崩し。
かなりStarがついていて有名なのかもしれない。
また、ゲーム系のプラグインは
https://vimawesome.com/?p=2&q=game　
こちらから色々と探すことができます。

## サンプル
![codebreak.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185747/c68e9af3-87cb-5e02-0d25-65d6aaffc83e.gif)


# まとめ
ユーザに寄り添った素晴らしいプラグインは、必ずしもユーザの利便性を追求したものではないかもしれない。
BigQueryのパーティション分割テーブルでカラムの型変更を行う

# サマリ

- BigQueryには、RDBMSでよくある、ALTER TABLE等でのカラムの型変更の機能がありません(2020年12月現在)
- そのため、カラムの型の変更を行う場合は多少工夫が必要になります。
- 具体的には、該当カラムが変更後のテーブル(table_b)を別途用意し、元のテーブル（table_a)からtable_bにInsertする形になります。
- ただ、パーティショニングテーブルの場合には、Insert時に_PARTITIONTIMEを指定するなどの工夫が必要です。
- このやり方で、型の変更だけでなく、当然カラム追加、削除も可能。

# 具体例

- 要件
    - テーブルAのvalueカラム(INTEGER)をSTRINGにしたい。
    - テーブルAは日付でパーティショニングされたテーブルである。
        - timePartitioning
            - requirePartitionFilter : true
            - type : DAY
- やりかた
    - STEP1. valueカラムをSTRINGにした（それ以外のスキーマ構造はtable_aと同じの）table_bを作成する
    - STEP2. table_aをSELECTして、table_bにINSERT
    - STEP3. table_aをrenameしてcopyないしremove、table_bをtable_aと同じ名前に変更。

## STEP1. insert先のtable_bの作成

```json:table_a
[
  {
    "mode": "NULLABLE",
    "name": "id",
    "type": "INTEGER"
  },
  {
    "mode": "NULLABLE",
    "name": "value",
    "type": "INTEGER"
  }
]
```

```json:table_b.json
[
  {
    "mode": "NULLABLE",
    "name": "id",
    "type": "INTEGER"
  },
  {
    "mode": "NULLABLE",
    "name": "value",
    "type": "STRING"
  }
]
```

table_bの作成

```bash

bq mk --table --schema table_b.json --require_partition_filter --time_partitioning_type=DAY 'foo-project:bar-dataset.table_b'
```

## STEP2. table_aをSELECTして、table_bにINSERT

- ポイント
    - `INSERT INTO` で `_PARTITIONTIME` を指定してあげることにより、元テーブルと同じパーティションにINSERTすることができる。
    - `INSERT INTO ~` のところで、 `_PARTITIONTIME` の代わりに、 `_PARTITIONDATE` などは使えない。 `_PARTITIONTIME` のみ。


```sql
INSERT INTO
  `foo-project:bar-dataset.table_b` (_PARTITIONTIME,
    id,
    value)
SELECT
  _PARTITIONTIME,
  id,
  CAST(value as STRING)
 FROM
  `foo-project:bar-dataset.table_a`
 WHERE
  _PARTITIONTIME >= TIMESTAMP("2020-01-01")
```

## STEP3. table_aをrenameないし削除、table_bをtable_aと同じ名前に変更。

table_aはrenameしてbackupするなり、削除するなりする。

```
bq cp "foo-project:bar-dataset.table_a" "foo-project:bar-dataset.backup_table_a"
bq rm -f "foo-project:bar-dataset.table_a"
```

table_bをtable_aとしてcopyし、table_bは削除。

```
bq cp "foo-project:bar-dataset.table_b" "foo-project:bar-dataset.table_a"
bq rm -f "foo-project:bar-dataset.table_b"
```

ここまでやってやっとおしまい。
マンガでわかる溶岩流アンチパターン

![9A395489-9DA9-4CD9-975B-419B1FC9DC0F.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11525/e4ff6ae0-2763-68cf-aaa6-a0ee1a1ee181.png)
http://wiki.c2.com/?LavaFlow

火山噴火の溶岩流は、熱く煮えたぎって流れている部分に目を奪われますが、その山の裾野では、溶岩が自然に冷えて固まり、ゴツゴツして地形と癒着した溶岩石の層を作っています。噴火が長く続くと、目立たない山のふもとにさらに次の溶岩流が層を積み、いびつな岩石の地形を生み出します。

短期的な見積もりでエキサイティングな開発を指向すると、時間の経過とともに、この溶岩流のように、作り込んだはずのものが保守されず、ひどく硬直したモジュールが残っていく現象が起きます。この技術的負債から目を背けて新たな技術で保守性の問題をカバーしようとすると、溶岩流がさらに層を積み上げてしまいます。こうなるともう、ほとんど使われなくなった後も、捨てるに捨てられない依存関係のしがらみに居座っていたりします。がんばって解体するにも、当時ほどの熱量はもう誰にもありません。

長期的に見てコードが健全な一生を過ごせるよう、作るという行為で技術を誇示しようとせず、技術の強さとチームのキャパとを天秤にかけて謙虚に選択することが、良いプロダクトにつながると私は思います。多くの技術を使いこなせるかではなく、実際にうれしい結果につなげられるのが、本当に優秀なエンジニアですね。
【Kaggle】読みやすいKernelを書くために意識している4つのTips

# はじめに
KaggleのPublic Kernelには有用なものが多いが、時折超縦長のNotebookに遭遇することがある。

![縦長notebook.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327040/a15e95b2-d114-11b8-ca74-2b966f248d1d.png)
（▲スクロールバーの小ささに絶望する）

こういったKernelを作ると後々見返すのがツライので、Public Kernelをうまく活用しつつ、自分流で見通しのよいKernelが書けるよう意識していることを紹介してみる。

# 結論
1. 可視化を最小限にする
2. 処理の中心となるオブジェクトを明らかにする
3. キーを意識する
4. 処理を関数にまとめる

# 1. 可視化を最小限にする
可視化はEDA用のKernelに書き、学習用のKernelでは可視化を最小限にしている。

Public Kernelの中には特徴量を生成する根拠を残しておくため、可視化と特徴量生成が同じKernelに書かれていることが多く第三者がKernelを読む上では非常に重要なのだが、[データ加工]と[可視化]という目的の違うコードが混じってしまう & 出力される図表がかなりの行数をとってしまうため。

# 2. 処理の中心となるオブジェクトを明らかにする
特徴量生成でよくあるのが、処理の中心となるオブジェクト(DataFrame)があり、そこに他のDataFrameを結合して情報を付与していくことで列が増えていくパターン。

処理の中心となる(=後続に繋がる)DataFrameと、その場しか使わないDataFrameを見分けるようにするとデータの流れを捉えやすい。

以下の例では```sales_df```が処理の中心で、```shops_df```や```item_category_df```からそれぞれ情報を付与している。

![Flow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327040/24caeea6-b69d-cc0b-8aff-1b636352e116.png)

```python
# Input: sales_df
#        date item_id  num shop_id
# 0  20201201     500    1     100
# 1  20201202     501    2     101
# 2  20201203     502    5     102

# Input: shops_df
#   shop_id shop_name
# 0     100    shop-1
# 1     101    shop-2
# 2     102    shop-3

# Input: item_category_df
#   item_id category
# 0     500     food
# 1     501    drink
# 2     502    cloth

# 店の情報を付与
sales_df = sales_df.join(shops_df.set_index('shop_id'), on='shop_id', how='left')
# 商品カテゴリの情報を付与
sales_df = sales_df.join(item_category_df.set_index("item_id"), on="item_id", how="left")

# Output: sales_df
#        date item_id  num shop_id shop_name category
# 0  20201201     500    1     100    shop-1     food
# 1  20201202     501    2     101    shop-2    drink
# 2  20201203     502    5     102    shop-3    cloth
```

# 3. キーを意識する
pandas.DataFrameのメソッドはSQLライクな操作を行うので, キーを指定して処理することが多い。キーを意識して読むとやりたいことが分かる。

- 主キー
- 集約キー(groupby)
- 結合キー(join, merge)

例えば以下の例では```sales_df```に```shops_df```から情報を付与するため```join```を使用する。キーは```on="shop_id"```を指定しているので、店ごとの情報を付与していることがわかる。

```python
# 例. "shop_id"列をキーに結合する場合
sales_df = sales_df.join(shops_df.set_index("shop_id"), on="shop_id", how="left")
```

# 4. 関数にまとめる
比較的長い処理や繰り返し使う処理は関数にまとめてしまうとよい。
全ての処理を関数化する必要はないのでお好みで。

- 処理のinput/outputが明確になる
- 同じ処理を使い回しやすい
- 中間DataFrameをいちいち削除しなくてもメモリを圧迫しない

といったメリットがある。

```python
# 例. 店の情報を付与する関数
def add_shops(df, shops_df):
    return df.join(shops_df.set_index('shop_id'), on='shop_id', how='left')

sales_df = add_shops(sales_df, shops_df)
```
【JavaScript】PlayCanvasを使ってブラウザ上で動くオンラインの展示会場を作ろう！【WebGL / JavaScript】

この記事の内容はブログに移行されました。
こちらを御覧ください

[https://support.playcanvas.jp/hc/ja/sections/360011154354](https://support.playcanvas.jp/hc/ja/sections/360011154354)
じゃんけんフィーバーをFlutter+Neumorphismで実装してみた。

# はじめに
この記事は、[最近流行のNeumorphism（ニューモーフィズム）と代表的なアプリデザインを超簡単に説明する✍️](https://qiita.com/naro143/items/67ae13b9ff48de2e525a)　の続きです。ぜひ前回の記事を読んでからこの記事を読んでください。
今回はじゃんけんフィーバーをFlutterとNeumorphism（ニューモーフィズム）を使用して実装してみます。実際に触れてNeumorphism（ニューモーフィズム）を感じてください🙌

# Neumorphism（ニューモーフィズム）を使用するとこんなアプリになります
まず2020年7月に作ったアプリを見ていただきたいです。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">QR決済アプリを研修の最後の自由制作課題で作りました🎉<br><br>最近話題のニューモフィズムデザインを採用して、Figmaでデザインしました。<br><br>クライアントはFlutterを採用。<br>サーバサイドはGoを採用。<br>インフラはAWSを採用。<br><br>左がエミュのiosで店舗モード（赤）<br>右が実機のandroidで顧客モード（青） <a href="https://t.co/DDQztqe6gL">pic.twitter.com/DDQztqe6gL</a></p>&mdash; naro 20新卒のエンジニア (@naro143) <a href="https://twitter.com/naro143/status/1279376718629724161?ref_src=twsrc%5Etfw">July 4, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

新卒の技術研修で作成したアプリです。シンプルで余白が多いですがNeumorphism（ニューモーフィズム）のおかげで寂しくなっていません。ボタンなどの押し心地が良いアプリになりました。

## どうやって実現したか
まずNeumorphism（ニューモーフィズム）の原則に沿ってデザインをしました。初めてのFigmaを使って慣れないながら、それっぽく仕上げました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">figmaを初めて2日目。<br>NeumorphismがTLで話題になっていたので、調べながら作った。<br><br>デザインの知識がないのを痛感しながらも楽しい作業だった🎉<br><br>個人的には情報量が少ないフラットデザインの方が好き。 <a href="https://t.co/dHNW06IMw7">pic.twitter.com/dHNW06IMw7</a></p>&mdash; naro 20新卒のエンジニア (@naro143) <a href="https://twitter.com/naro143/status/1271895152659853312?ref_src=twsrc%5Etfw">June 13, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

大事なポイントは3つ
1. 明るい影と暗い影を使って浮き沈みを表現する。
2. 背景色から輝度を変えた色を影の色に使う。
3. 浮き沈みさせた範囲の背景色は変えない。

これを守るだけでNeumorphismになります。詳しい内容は[Neumorphism in user interfaces](https://uxdesign.cc/neumorphism-in-user-interfaces-b47cef3bf3a6)を読むと良いです。

次にFlutterの話です。Flutterはマテリアルデザインのコンポーネントは簡単に利用できます。マテリアルデザインは影（奥行き）があるため浮かせるということは苦労しません。ただ、沈める（凹ませる）には少し工夫が必要でした。当時はBoxPainterを使用して影を描き込むことで表現をしました。お手製の沈めるコンポーネントを作成して利用しました。詳しいコードは解説しません。次の見出しが理由です。

# 便利なライブラリ
Neumorphism（ニューモーフィズム）のコンポーネントを簡単に利用できるライブラリができていました🎉
ありがとう世界のエンジニア！
今回はこちらのライブラリを使ってアプリを作成します。

https://github.com/Idean/Flutter-Neumorphic

![](https://github.com/Idean/Flutter-Neumorphic/raw/master/medias/playground.gif)

# 作ったアプリ
![rpcf.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222499/7c0c67ed-c970-e540-ac88-06001825276e.gif)

ライブラリのおかげで簡単にますNeumorphismを使用することができました。思いつきで実装してみましたが、無条件にお洒落になるので面白かったです。

詳しいコードはリポジトリをご覧ください。
[Github rock_paper_scissor_fever](https://github.com/naro143/rock_paper_scissor_fever)


# 触れて体験

[iOS Apple Store](https://apps.apple.com/jp/app/rock-paper-scissors-fever/id1543602449)
[Google Play Store](https://play.google.com/store/apps/details?id=com.naro143.RPSFever)
【CSS小ネタ】画像サイズを変えずに拡大表示する。

WEBデザインで画像をホバーしたら画像がズームアップするような機能を実装しましたのでご紹介します。

【完成イメージ】

![完成イメージ.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420031/dd0c4989-9ae9-2860-67ab-25c27480f218.gif)

ポイントは画像サイズを変えることなくズームアップ表示できることです。

使用画像はトリミングしたのがこちらにあるので、そのまま使っていただいても構いません。

![image1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420031/a4e457ba-48f0-708f-c39e-cf2850e50436.jpeg)

## 実装
まずHTMLを用意します。ポイントとしてimgタグをそのまま使うのではなく<font color="red">**親要素で囲います。**</font>

```html:html
<div class="img-frame">
  <img src="./img/image1.jpg" alt="サンプル画像">
</div>
```

そしてCSSです。今回は幅高さ300pxに固定します。

```css:css
img{
  width: 300px;
  height: 300px;
}
```

ホバーアクションも書いていきましょう。今回は変形プロパティで拡大縮小表示ができる、`transform: scale();`を使用していきます。

```css:css(imgの下に追加して下さい)
img:hover{
  /* transformは変形プロパティ。値にscaleを指定すると拡大縮小することができる。 */
  transform: scale(1.3);
}
```

これで画像をホバーした際に、画像が1.3倍で表示されるようになります。

![scale.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420031/e92440cd-bc17-e939-a9da-15bd6c8dcd90.gif)

みたまんまで、画像そのものが1.3倍になっています。流石にこのままの状態でWEBページに表示させるのはないですよね？なので、<font color="red">**幅高さを固定して中の画像だけズームアップ**</font>させます。

そのためには、まず親要素に対して幅高さの固定値を設定し、<font color="red">**子要素のはみ出た部分を非表示にする**</font>必要があります。図解化するとこんな感じです。

![図解化1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420031/fe2e3920-7643-cac2-7905-a3a50c3b3eea.png)

では実際に実装していきます。

```css:css
.img-frame{
  /* 縦横300pxにがっちり固定 */
  width: 300px;
  height: 300px;
  /* 固定した幅からはみ出たものは隠してしまう */
  overflow: hidden;
}
```

動作を確認します。

![hidden使用後.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420031/471ea1bc-33b0-fa0b-56d8-8a28d32ef42b.gif)

どうでしょう？目的は果たせたかと思います。ただ動きがカクカクしてるのでちょっとダサいです。なので`transition `を追加しヌルッと動くようにします。それで【完成イメージ】通りの機能が実装できたかと思います。

```css:css(完成形コード)
.img-frame{
  /* 縦横300pxにがっちり固定 */
  width: 300px;
  height: 300px;
  /* 固定した幅からはみ出たものは隠してしまう */
  overflow: hidden;
}
/* 画像スケール */
img{
  width: 300px;
  height: 300px;
  /* ヌルッと動くように */
  transition: 0.3s;
}
/* ボバー時のアクション */
img:hover{
  /* transformは変形プロパティ。値にscaleを指定すると拡大縮小することができる。 */
  transform: scale(1.3);
}
```

最後に今回やった実装を簡単に図解化したので添付しておきます。是非参考にして下さい。お疲れ様でした。

![工程図解化.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420031/4338edaf-4225-6774-327c-7ef28ef7c854.png)
SysVinitのこと調べてみたよ

## 勉強前イメージ

systemdの勉強したくて調べてたらSysvinit出てきた。
initと何が違うのか？
カーネルの後に起動する各プロセスを立ち上げるなにかってイメージ
最近はsystemdに変わった

## 調査

### SysVinitとは

- SysVinitの概略

Unix系OSで広く使われてきたOS起動の仕組み。
最近のOSではUpstartやsystemdに変わっている。

- SysVinitとは起動の順番でいうとどこか

下記の順番でいくと、5番目のプロセス実行の際に稼働するのがSysVinitになります。

1. 電源を入れる
2. BIOS/UEFIの起動
3. ブートローダーの読み込み
4. カーネルの読み込み
5. プロセス実行 ←ココ！！！
6. ログイン可能

### SysVinitについて中身を見ていく

#### 特徴

SysVinitでは、一番最初に `initプロセス` を開始します
`initプロセスは` プロセスIDが1番を持っています。
実際にCentOS5で確認してみると `init` が PID(プロセスID)が1になっています。

```
[root@localhost ~]# ps aux | grep [i]nit
root         1  0.1  0.0  10372   732 ?        Ss   20:48   0:00 init [3]    
```

initプロセスは、 `/etc/inittab` に書かれたプロセスを順番に起動しますが、
並列ではなく直列でしか起動できないので、時間がかかるというデメリットがありました。

#### SysVinitの実行順序

1. initプロセスが開始される(pid=1)
2. /etc/inittabファイルを読み込む
	1.システムの初期化のシェルを起動

	`/etc/rc.d/rc.sysinit` は
	ホスト名や、ネットワークの設定をしたり起動に必要な初期化処理を行います。

	```text:/etc/inittab
	# System initialization.
	si::sysinit:/etc/rc.d/rc.sysinit
	```

	2.rcスクリプトの実行

	デフォルトランレベル確認。
	下記だったら デフォルトランレベル3
	ランレベルについては [こちら](https://qiita.com/miyuki_samitani/items/bb2505209a81cfdee274)

	```text:/etc/inittab
	# Default runlevel. The runlevels used by RHS are:
	#   0 - halt (Do NOT set initdefault to this)
	#   1 - Single user mode
	#   2 - Multiuser, without NFS (The same as 3, if you do not have networking)
	#   3 - Full multiuser mode
	#   4 - unused
	#   5 - X11
	#   6 - reboot (Do NOT set initdefault to this)
	# 
	id:3:initdefault:
	```

	デフォルトランレベルに合わせたスクリプトの実行

	```text:/etc/inittab
	l0:0:wait:/etc/rc.d/rc 0
	l1:1:wait:/etc/rc.d/rc 1
	l2:2:wait:/etc/rc.d/rc 2
	l3:3:wait:/etc/rc.d/rc 3 ← これ！
	l4:4:wait:/etc/rc.d/rc 4
	l5:5:wait:/etc/rc.d/rc 5
	l6:6:wait:/etc/rc.d/rc 6
	```

#### そもそもinitプロセスって何よ？

`initプロセス` は他のプロセスを起動させる、親プロセス。
Linuxカーネルの起動後一番最初に起動されるので、↑で書いたとおりPIDは1が付与される

```text:pstree

[root@localhost ~]# pstree
init─┬─acpid
     ├─anacron
     ├─atd
     ├─auditd─┬─audispd───{audispd}
     │        └─{auditd}
     ├─automount───4*[{automount}]
     ├─crond
     ├─dbus-daemon───{dbus-daemon}
     ├─dhclient
     ├─events/0
     ├─gam_server
     ├─gpm
     ├─hald───hald-runner─┬─hald-addon-acpi
     │                    ├─2*[hald-addon-keyb]
     │                    └─hald-addon-stor
     ├─hcid
     ├─hidd
     ├─2*[iscsid]
     ├─iscsiuio───2*[{iscsiuio}]
     ├─khelper
     ├─klogd
     ├─...
     ├─...

```

## 勉強後イメージ

initが起動していく順序とかを決めたようなやつって感じか...
systemdだったら並列になってるし
イメージはなんとなく合ってたけど、ちゃんと分かったかも
/etc/inittabの中身見るためにCentOS5をインストールしたけど、インストール画面おしゃんだった


## 参考

- [【初級者向け】Linuxシステムの起動 ～ SysVinit、Upstart、systemd ～](https://tech.pjin.jp/blog/2020/11/11/linux-system-boot-2/)
- [initまとめ(ざっくり)](https://qiita.com/h_tyokinuhata/items/26b7dd3526e7061596b9)
- [Linuxシステム起動スクリプト(inittab、rc.sysinit、rc)を読んでいく](http://www.osssme.com/doc/funto76.html)
本番環境で動作している（はずの）selectを叩いてサービスを落とした話

この記事は[本番環境でやらかしちゃった人アドベントカレンダー2020](https://qiita.com/advent-calendar/2020/yarakashi-production)5日目の記事です。

去年の投稿を見て自分も過去色々やらかしてしまったなあという反省と懺悔の元今回参加させていただきました。

# TL;DR
当時新卒1~2年目だった自分にあるミッションが課せられました。

当時関わっていたサービスに
いわゆる一覧画面 + ページングで表示機能を実装している箇所がありまして、表示速度改善に取り組みました。 
特に特定のカテゴリページの2ページ目以降の表示速度がかなり遅く、タイムアウトが頻発していたという状況でした。

Qiitaでいうところのタグフィードのようなものと思っていただけるとありがたいです。

![スクリーンショット 2020-11-29 12.15.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152938/bcdfa3f9-212c-91b2-48a9-febe9d9efb4c.png)


# 何をしたか
どの程度遅いかをまず調べようと、APIからDBに流れているはずのタイムアウトしているselect文をAPIと同様に`Read Replica`にたたきました。

ちなみにデータベースは`MySQL`でした。

# 何が起こったか

すると、index的にきついクエリだったので、tmpファイルがあふれるという自体が発生した。
どうきつかったかというと、規模的には数百万規模のレコードに対して、`Using temporary; Using filesort`が発生している状態だった。

その結果、サービスを数分の間停止させるという自体を招いた。

[2020年12月5日12時追記]
ちなみに、クエリに関してはGUIアプリケーションから実行して、2~3分程待って、データベースのレスポンスが悪化しはじめたのでやめた記憶です。

![science_hakase_shippai.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152938/0044f572-e0f5-46aa-fc1a-f08fc9e0da53.png)



# どう対応したのか

tmpファイルの削除などでディスクを開けることで解消した記憶です。
当時の環境はオンプレだったので、インフラチームの方々にはご迷惑をおかけしました。

[2020年12月5日12時追記]
本番環境のAPIがたたいているクエリそのものではあったのですが、
APIクライアントがタイムアウトしてくれていたので、tmpファイルがあふれる前に処理が中断しているという状態でした。


# 今回の問題の原因

* カジュアルに本番環境にselect文を流すことが日常的にあった。
 * 本番でないと再現しないDBのパフォーマンス的問題を当時はそれなりに抱えていた記憶。
 * 当時のテーブルの構成的にクエリ最適化が限界にきていた点も大きかった。 
 
* 実行計画に対する審美眼が自分になかった。
 * 遅いクエリの認識はあったが、本番のユーザーアクセス時に動いていたSQLなのでまさかサービスを止めるほどやばいクエリだとは思わなかった。 
 * select = 読み込み操作という認識で、副作用がある認識をあまり持てていなかった。

# 再発防止策

全部が当時できたわけではないですが、以下が挙げられるかなと思います。

## 安全に壊せる環境を用意する
本番でなく開発環境で状況が再現すると理想ではあるのですが、
データの規模などで本番準拠のDBでしか再現しない問題は実際あると思います。

今回の事象はread処理のパフォーマンスの問題だったので、外部からのLBから外した`Read Replica`を用意することで改善をしました。最悪そいつが死んでもサービスへの影響が少ないものを用意して、安全に本番準拠のクエリを試すための環境としました。

一番の理想は、本番環境準拠の環境が別にあると良いのかなとは思います。予算の問題があるので難しい問題ではありますが。

## チームの認識を揃える
本番環境に流すときのselect文は実行計画を含めてレビューするようにはなりました。
「このクエリはやばいから、whereで〇〇を追加して範囲を絞ろう」みたいな議論が生まれました。

また、select文を本番に流す際もレビューを通してチームの共通認識になってたりしたので、
フォローに回ったり回ってもらったりも容易になった記憶もあります。

## ペアオペを実施する
特に現代だと、リモートワークで自宅作業中心になりがちなので、
本番作業は画面共有しながら先輩社員と一緒にやるのが理想かなと思います。

1人だとどうしても漏れが発生しがちなのと、ターミナル操作のようにコード上に現れにくいものを
チームで共有できる良い機会なのかなと思います（良いツールとかこのとき教えてもらうことが多かった記憶）

# 余談（本来の目的のパフォーマンス改善に関しての対処に関して）
もともとの目的のパフォーマンス改善に関しては元のクエリがデータベースのテーブル的にほぼ絶望的だったので、ユーザーアクセス時に実行させない方針を取りました。

暫定対応としては、基本的にキャッシュを永続化し、定期実行するバッチで強制的にキャッシュを作り変えるようにしてユーザーアクセス時にスロークエリが流れないようにしました。

最終的にはRDBからデータを取得することをやめて、全文検索エンジン経由のデータ取得に切り替えることで他にも問題を抱えていた複雑なクエリ事情の解消としました。

# おわりに
当時の関係者の方見てたら、ほんとすみませんでしたという謝罪の念でいっぱいです。

他にも色々やらかしてしまった思い出はありますが、その分チャンレンジさせていただいた感謝の念しかありません。

失敗した自分がいうのもあれですが、失敗しないとなかなか人間学べないと思います。
安全に失敗できる環境づくりを構築して、スピード感をもって良いプロダクト作りに貢献していきたいですね。

明日は@yutakatayさんの[俺TUEEE系エンジニアが本番サーバーを0.1秒で落とした話](https://zenn.dev/yutakatay/articles/yarakashi-reboot)とのです。
どんなRTAが待っているのか楽しみですね。
OCaml Upcoming Changes 2020: Allow to name existentials in pattern-matching

この記事は[ML Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ml) 5日目の記事です。

OCamlにそろそろ入りそうな機能を紹介します。

今回は、[Allow to name existentials in pattern-matching by garrigue · Pull Request #9584 · ocaml/ocaml](https://github.com/ocaml/ocaml/pull/9584) を紹介します。

----

OCamlでは（他の言語でも同じように？）、言語機能が追加されたときに、処理系は正しく型づけするが、ユーザーが項の型を書けなかったり、かなりまわりくどい書き方をしないと型を明示できないことがたまに起こる。過去に第一級モジュールが追加されたときにも、何かユーザーがうまく型を書けないケースがあったような気がする（あやふや）。

今回紹介する[Allow to name existentials in pattern-matching by garrigue · Pull Request #9584 · ocaml/ocaml](https://github.com/ocaml/ocaml/pull/9584)は、パターンマッチ時にGADTで導入される存在型を参照するための構文を追加する。

具体例で説明しよう。

OCamlには存在型を扱う構文がふたつある。

ひとつはモジュールで、「ある型`t`と、その値`value`」をシグネチャで表現すると次のようになる。

```ocaml
module type S = sig
  type t
  val value : t
end
```

もうひとつはGADTで、同様のものを表現すると次のようになる。

```ocaml
type t = Value : 'a -> t
```

前者から後者への変換は簡単で、次のような関数で書ける。

```ocaml
let module s_to_t (module M : S) = Value M.value
```

逆はけっこう面倒だ。

単純に考えると次のようになりそうだが、これは型チェッカーに文句を言われる。

```ocaml
let t_to_s = function
  | Value (v : 'a) ->
    (module struct
      type t = 'a
      let value = x
    end : S)
(*
11 |   | Value (v : 'a) ->
               ^^^^^^^^
Error: This pattern matches values of type 'a
       but a pattern was expected which matches values of type $Value_'a
       The type constructor $Value_'a would escape its scope
*)
```

これは、 `v` の型は `Value` の分岐でしか使えないはずなのに、 `'a` は `function` 全体がスコープになることが原因だ。

今はこんな風に書く必要がある。

```ocaml
let t_to_s = function
  | Value v ->
    let f (type a) (x : a) =
      (module struct
        type t = a
        let value = x
      end : S)
    in
    f v
```

ここでは、一旦ローカル関数で局所抽象型 `a` を導入し、それを使って第一級モジュールをつくっている。

これはあまりにも面倒なので、[Allow to name existentials in pattern-matching by garrigue · Pull Request #9584 · ocaml/ocaml](https://github.com/ocaml/ocaml/pull/9584)では、次のように書ける構文を導入する。

```ocaml
let t_to_s = function
  | Value (type a) (v : a) ->
    (module struct
      type t = a
      let value = x
    end : S)
```

ちょうど、最初のプログラムと局所抽象型を使ったプログラムの間の子のような感じで、GADTで導入される存在型を `(type a)` の形でバリアントタグのあとに書けるようになる。

次のOCaml 4.12は既にfeature freezeされているので、この機能は4.13あたりで入るだろう。
「Microsoft Print to PDF」でPDF出力

# 「Microsoft Print to PDF」でPDF出力

Windows 10 には、「Microsoft Print to PDF」が搭載され、手軽にPDF生成できますが、Delphiでも、この機能を使い、「印刷結果を名前を付けて保存」ダイアログを出さずにPDF生成できないかな・・と思っていたら、
[Microsoft Print to PDF で C/C++ コードから出力ファイル名を指定する方法](https://perce-neige.hateblo.jp/entry/2018/09/14/180047)
の記事を見つけたので、これを参考に、コードを書いてみたいと思います。

## 印刷プログラムを書いてみよう

まずは、
[Delphi Tips - TPrinter オブジェクト](https://support.embarcadero.com/article/35957/)
にある例を参考にして、印刷プログラムのコードを書いてみます。

uses節に Printers (最近のDelphiだと、Vcl.Printers)を追加し、
フォームにボタンを追加し、OnClickイベントに以下のコードを入力します。

```pascal:Unit1.pas
procedure TForm1.Button1Click(Sender: TObject);
begin
  with Printer do
  begin
    Title := 'プリントテスト';

    BeginDoc;
    Canvas.TextOut(10, 10, 'プリントテスト ページ１');
    NewPage;
    Canvas.TextOut(10, 10, 'プリントテスト ページ２');
    EndDoc;
  end;
end;
```

コンパイル後、ボタンをクリックして、印刷されるのを確認します。

## 「Microsoft Print to PDF」を使い、PDF出力するように修正しよう

プリンタを「Microsoft Print to PDF」に指定し、出力するPDFファイルを指定して、「印刷結果を名前を付けて保存」ダイアログを出さずにPDFファイルを生成します。

ボタンのOnClickイベントにコードを追加します。

```pascal:Unit1.pas
procedure TForm1.Button1Click(Sender: TObject);
var
  idx: Integer;
  PdfFileName: String;
  DeviceName, DriverName, PortName: array[0..MAX_PATH - 1] of Char;
  DeviceMode: THandle;
begin
  PdfFileName := ExtractFilePath(Application.ExeName) + 'test.pdf';

  with Printer do
  begin
    idx := Printers.IndexOf('Microsoft Print to PDF');
    if idx < 0 then	exit;
    PrinterIndex := idx;

    GetPrinter(DeviceName, DriverName, PortName, DeviceMode);
    SetPrinter(DeviceName, DriverName, PChar(PdfFileName), 0);
  end;

  with Printer do
  begin
    Title := 'プリントテスト';

    BeginDoc;
    Canvas.TextOut(10, 10, 'プリントテスト ページ１');
    NewPage;
    Canvas.TextOut(10, 10, 'プリントテスト ページ２');
    EndDoc;
  end;
end;
```

コンパイル後、ボタンをクリックすると、実行プログラムがあるフォルダにPDFファイルが出力されているのを確認します。

## 生成したPDFファイルを確認してみよう

生成したPDFファイルを、Adobe Acrobat Readerで表示してみます。
![q1_reader.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318490/46f2c623-b72d-5d42-76e0-b44bfa21d01c.jpeg)

メニュー[ファイル]-[プロパティ]で「文書のプロパティ」を表示します。
![q2_property.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318490/996d1ea8-1233-ae4b-96d4-910f927da83b.jpeg)
PrinterのTitleプロパティに格納した文字列が、タイトル欄に表示されるのですが、
日本語だと文字化けするのは、仕様みたいです。

## 最後に
「Microsoft Print to PDF」が表示する「印刷結果を名前を付けて保存」ダイアログの、最初に表示するフォルダは、プログラムから制御できないみたいですが、今回のやり方を使うと、TSaveDialogを使って「名前を付けて保存」ダイアログを使用することで、最初に表示するフォルダを設定する場合などにも使えそうです。

また、LightReport2など、TPrinterを使用しているコンポーネントでも、今回のやり方を使って、PDF出力機能を追加したりできそうですね。

2020/12/08 追記
Windows 10の設定で、「Windows で通常使うプリンターを管理する」がONの場合、これを実行した後、（別のアプリなどで）印刷するとき、プリンターが「Microsoft Print to PDF」になってしまうので、対策が必要かもしれません。
ゼロから始めるQAチーム立ち上げの話（スタート編）

この記事は[クラスター Advent Calendar 2020 - Qiita](https://qiita.com/advent-calendar/2020/cluster)の4日目の記事です。

# はじめに
こんにちは、[okan](https://qiita.com/okan)です。
今年の7月にクラスターに入社して、半年目がスタートいたしました。

本日は、QAチーム立ち上げ時、どんなことを行ったか書いてみたいと思います。
まだまだスタートしたばかりですので、スタート編ということでお願いいたします！

# QA（Quality Assurance）とは
QA（Quality Assurance）とは、品質保証という意味になります。
QAはデバッガー！みたいな感覚の方が、まだまだ多い世の中なのですが、実はかなりのスキルを要求される職種です。
その話はまたの機会にするとして、QAは、ユーザーへ届けたい価値になっているかどうかを検証することを軸としています。
「バグを取り除くこと」はユーザーへ届けたい価値の中の1つにしかすぎません。

# QAチーム立ち上げ開始時
少し簡単に弊社の2つの事業部をご紹介させていただきます。

**◆プラットフォーム事業部**
ゲームやイベントを作って遊べるプラットフォーム、[バーチャルSNS cluster（クラスター）](https://cluster.mu/)の開発運営を行っています。

**◆エンタープライズ事業部**
法人からイベントを受注し、企画運営やCG制作を行っています。

どちらの事業部も開発を行っておりますのでQAは必要不可欠ですが、最初はプラットフォーム事業部しかQAが存在しておりませんでした。
そのため、QAとは何者なのか、デバッガーさん？といった感じで知らない方が大半を占めており、「QAとは何者なのか？」「どんな立ち回りをするのか、したいのか」の話を限られた時間でたくさん行いました。
今も発信し続けています。

# この5カ月で行ったこと
まず、入社したての私が行うミッションは、自身のことを皆様にQAとして認識してもらうことでした。
「おかん」というあだ名が強烈すぎるのか、「おかん」というあだ名はかなりの方に認識されていますが、実は、実名はあまり認識されていません。
自己紹介の時、名字で名乗るとキョトンとされ、あだ名を伝えると「あ～！いつもQAありがとうございます！」な展開になります。

そんなわけで、5カ月で0⇒1にするために以下のことを行いました。

####◆半年以内でギリギリ実現出来るか否かの厳しめのゴール設定をした
これは私個人の問題ですが、厳しめのゴールを設定するにあたって、「QAチームに必要なものは何か」を常に考え、常に優先順位を付けて取捨選択することになるため、本当に必要なことだけを行うように自身を追い込みました。
2つの事業部の横断組織としてQAを組織化するために日々奮闘中です。

具体的に行ったことは以下の通りです。

#####QAが検証に入るためのワークフローを改善する取り組みを行った
QAがいない組織は、ワークフローにほぼQAが存在していません。
安定したテストが出来るように、QAがどのタイミングで入るとよいのか、どんな環境にして欲しいのか、どれくらいの期間が欲しいのか等を話し改善を行い、皆様の協力のもと運用に至れました。
今は更なる改善に向け進んでいるところです。

#####QAメンバーの採用や教育（スキルアップ）を行った
採用においては、残念ながら本日時点ではまだ決まっておりませんが、具体的には以下を行いました。
まだ種まき段階ですので、開花するのはもう少し先になりそうです。

- マニュアル作成（まだまだ現在進行形）
- 1on1を実施し、各メンバーの目標と振り返りを実施
- ワークショップ（勉強会）を実施

#####外部協力会社様との契約を進めた
開発を加速させるにあたり、物理的にもQAメンバーが必要になってまいりますが、だからといって、誰でもQAとして採用するわけにはいきません。
安定したクオリティを担保する上でも、外部協力会社様の力は必要不可欠となります。

まだまだ連携はスタートしたばかりで、他社だからこそ出来ないことも発生しており、改善すべき点も多いですが、その都度、打ち手を考え進行している状況です。

# 特に心掛けていたこと
相手を尊重し、チームの輪を大事にすることを心掛けていたに尽きます。
その中で特に心掛けていたことを3つご紹介させて下さい。
#####今までのやり方を肯定した上で新しいことを取り入れるよう心掛けた
新しい取り組みを行う際、今までのワークフローを「正しいもの」と、信じていたメンバーも少なからずいます。
真っ向否定されたかのように感じないよう、変化に対応しきれないQAメンバーも一緒に並走出来るよう、話す機会を増やし、理解を得たうえで少しずつ変化を取り入れるようにしました。
#####自立自走への取り組みを心掛けた
チームを立ち上げるにあたって、「今の状況をどうしたら打破できるのか」を考える機会をチームメンバーにも与えることが大事だと考えています。
そのため、質問されても「～～さんならどうしたい？どうする？」と敢えて答えを言わず、よく質問返しで投げかけております。
毎度びっくりされますが、考えることは自立自走への第一歩でもあります。
#####QAから発信する機会を増やすことを心掛けた
開発時のウィークポイントをバグを項目別にして発信したり、JIRAの起票においては、これは困った等を発信することで、チームの弱点克服へ少しでも貢献できるよう取り組んでいます。
QAだからこそ見える世界がありますので、QAならではのアプローチを行っています。

近々「weekly okan」というQA通信を開始する予定です。
「monthly okan」と書かない強い心。

# 最後に
まだまだ始まったばかりのQAチームですが、まずは土台となる取り組みを行っています。
組織を立ち上げる上で大事なのは、まずは多くの方と話し、自身の話に耳を傾けてもらうことからスタートな気がいたします。
同じように入社直後にゼロから組織立ち上げで悩んでいる方。
まずは全社員、もしくはプロジェクト全員と話すことを目標に話をしてみて下さい。
きっとそこでQAの歴史を知り、何かしらの打ち手が生まれてくるはずです。
と、偉そうなこと書いてますが、まだまだ奮闘中です。
これを機に、同じQA組織の立ち上げで奮闘されている方ともつながれたら嬉しいです。

# 告知！
共にQAチームを盛り上げていただけるメンバーを募集いたしております！
少しでもご興味のある方は[コチラ](https://www.wantedly.com/projects/403915)より、ご応募お待ちしております！

そんなわけで、4日目は以上となります！
明日もお楽しみにっ！
RxJSをSubscribeなしで使う / AsyncPipe

## 前置き
AsyncPipe使った方が良いよ！っていうことを最近教えてもらったので、色々調べてまとめてみました。
AngularとかAsyncPipeとかRxJSについて一応知ってはいるけど、まだあまり使ったことないっていう方向けなので、
RxJSって何？Observableって何？って方は、先に [RxJS公式ドキュメント](https://rxjs-dev.firebaseapp.com/guide/overview)などをご参照ください🎅

## なんでSubscribe使わないの？
> "NO SUBSCRIBING MEANS... NO UNSUBSCRIBING!" ([参考動画](https://www.youtube.com/watch?v=Z76QlSpYcck))

(SUBSCRIBEしないってことは... UNSUBSCRIBEしないでいいってことじゃん！)
AsyncPipeを使うと自分でUnsubscribeする必要がなくなるので便利＋Unsubscribeし忘れもなくなります🎅🎄

## もうちょっと説明します
まずはsubscribeを使って書いてみます。

```subscribe.component.ts
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { UserService } from '../user.service';

@Component({
  selector: 'app-subscribe',
  template: `
    ng-container(*ngFor="let user of users")
      h1 {{ user.name }}
      h2 {{ user.email_address }} 
  `,
})
export class SubscribeComponent implements OnInit {
  users: User[];
  private subscription: Subscription;

  constructor(private userService: UserService) {}

  // AngularのComponentインスタンスが作成されるタイミングと、
  // 実際にComponentがビューに配置されるタイミングは一致しないため、
  // subscribeはconstructor内ではなく、ngOnInit以降で呼び出した方が良いそうです🤶
  ngOnInit() {
    this.subscription = this.userService.users$.subscribe((userData) => this.userData = userData);

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}
```

## 次に、AsyncPipeありバージョン

```async-pype.component.ts
import { Component } from '@angular/core';
import { UserService } from '../user.service';

@Component({
  selector: 'app-async-pype',
  template: `
    ng-container(*ngIf="users$ | async as users") 
      div(*ngFor="let user of users")
        h1 {{ user.name }}
        h2 {{ user.email_address }}
  `,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class SubscribeComponent {
  users$: Observable<User[]> = this.userStoreService.users;

  constructor(private userService: UserService) {}
}

```
すっきりしましたね！
AsyncPipeを使った場合、ngOnInitライフサイクルフックは必要なく、必要なObservableデータをプロパティに置くだけでOKです！(データの変更検知、反映も同じようにしてくれます！)

> **Subscribeをすると、Unsubscribeをしないとメモリリークが起きる可能性があるみたいなんですが、AsyncPipeを使うとコンポーネントが破棄されるタイミングで自動的にUnsubscribeしてくれるので、手動でUnsubscribeする必要がなくなります🤶🎄**


> **また、ChangeDetectionStrategy.OnPushというものが使えるようになり、下記項目発生時のみ変更を検知するようになるため、Change Detectionサイクルを最小限に抑えることができ、パフォーマンスが上がるそうです。
- @Inputプロパティに変更があった時
- イベント発生時
- 指定したObservableが流れた時(今回の場合は"users$")**


## 参考記事
[combineLatestドキュメント] (https://rxjs-dev.firebaseapp.com/api/index/function/combineLatest)
[AsyncPipeドキュメント](https://angular.jp/api/common/AsyncPipe)

🎅🎄🎅🎄メリークリスマス🎅🎄🎅🎄
Laravel 8のexplainをLaravel7以下で使う

# 何がしたいか
Laravel8 でexplainメソッドが追加されました。

```php
User::where('id',1)->explain()->dump();
DB::table('id',1)->where('id',1)->explain()->dump();
```

https://www.amitmerchant.com/using-mysql-explain-for-queries-in-laravel-8/

Laravel8未満でも使いたいなーと思いやってみることに

# 環境
下記環境で動作を確認してます。
Laravel 7.x

# やり方

macroで拡張できるので、メソッドを追加して、[マージされたプルリク](https://github.com/laravel/framework/pull/34969/files
)の内容を`AppServiceProvider`にペタリ

```php:AppServiceProvider
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder as QueryBuilder;


    public function boot(): void
    {
        QueryBuilder::macro('explain', function () {
            $sql = $this->toSql();

            $bindings = $this->getBindings();

            $explanation = $this->getConnection()->select('EXPLAIN ' . $sql, $bindings);

            return collect($explanation);
        });
        EloquentBuilder::macro('explain', function () {
            $sql = $this->toSql();

            $bindings = $this->getBindings();

            $explanation = $this->getConnection()->select('EXPLAIN ' . $sql, $bindings);

            return collect($explanation);
        });
    }
```

これでとれるようになった。

```php
User::where('id',1)->explain()->dump();
DB::table('id',1)->where('id',1)->explain()->dump();
```

# ログに出す

そもそも、ログ出すのに使う必要ないので、explainメソッドいらない子かもしれない...
サービスプロバイダの`boot`に下記を追加([参考](https://gist.github.com/emahiro/f29503fc7c37386dcce1601419c90b5b))

```php:AppServiceProvider
DB::listen(function ($query) {
    if (!preg_match("/^EXPLAIN/", $query->sql)) {
        $explain = DB::select("EXPLAIN  {$query->sql}", $query->bindings);
        Log::info($explain);
    }
});
```
htmlどれがタグでどれが要素か、各名称

htmlのタグとか要素、cssのプロパティー、プロパティーの値とか何が何かよくわからなくごちゃごちゃになると思うのでまとめました。

要素

```
//要素
<head>
　<meta>
　<title>
　<link>
　<style>
</head>

<body>
 <footer>
 <header>
 <main>	
　<nav>
　<section>
```

タグ

href
class

など要素の次に書くのをタグという

```
<a href="`"></a>
<div class="#"></div>
```

フッタータグは

```
<footer>
 <small>
 @ 2020 example.com
</small>
```


セレクター、プロパティ、規則セット


セレクター
プロパティー：　プロパティー値；

div {
coloer: red;
font-size: 80px;
右左２つセットで宣言
3つセットで規則セット

```
div {
 color: red;
 font-size: 80px;
}
```
Godotでアプリの横画面/縦画面を固定する方法

ProjectSettingsを変えるだけ。
# 設定箇所
- ProjectSettings -> Display(左メニュー) -> Window(左メニュー) -> Handheld -> Orientation
  - 横画面: landscape
  - 縦画面: portrait

![setting_location.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/931128/a5709d27-5c85-c868-0348-0374f035960b.png)
他の項目は試してない。iOSも試してない。Androidだけ。
一旦はこれだけで、備忘録。
# 参考
- https://esthersoftware.hatenablog.com/entry/android-screen-orientation
Laravel5.5  Eloquentモデルでupdated_atカラムがないテーブルを使うとき

Laravelの便利な機能``Eloquent``を使う際に、使い勝手がいいけど、困ったな〜っと感じたこととその対応。

テーブルにupdated_atカラムが必要ない時ってありますよね。
updated_atがないテーブルにEloquentを使って、DBに新規登録するとエラーが出ます！

カラムがないよ！ってアラートです。
しかし！！出てきても大丈夫！

```php:モデル
 const UPDATED_AT = null;
```
これを、新規登録するテーブルのモデルにかけばOKです〜！

以上になります！
今回、updated_atに少し翻弄されてしまったので備忘録として書きました。
LGTM大好物なんで、ポチッと投げ銭感覚でおねがいします〜！ :sunglasses:
【Rails】Gemを初公開しました。何月なのかを月名で確認するメソッドを生成

# Gemを初公開しました

[ask_year_month](https://rubygems.org/gems/ask_year_month)という、
 
**レシーバが何月なのか、**

月名でスマートにチェックできるメソッドを生やすGemを公開しました。

<br>

月名で確認できなくて地味にモヤッとしたんですよね。

<br>

例えば、

```rb
Time.current.month == 12
#=> true
```

よりも、

```rb
Time.current.december?
#=> true
```

のが見やすいよなーという。

<br>

ご興味がある方は良かったら使ってみてください。

<br>

## RubyGems
https://rubygems.org/gems/ask_year_month

## GitHub
https://github.com/mah666hhh/ask_year_month

## 参考記事

[RailsプラグインGemの作成方法、RSpecテストまで含めたrails pluginの作り方](https://easyramble.com/create-rails-plugin-gem.html)

[【Ruby】gemの作り方から公開まで](https://qiita.com/9sako6/items/72994b8b1c00af4e61fe)

[gem install に失敗するので https://rubygems.org/ を source に追加した](https://blog.fkoji.com/2013/07310054.html)

[activesupport/lib/active_support/core_ext](https://github.com/rails/rails/tree/9b6008924d527b61b11677a78542a7b0fd4d80bf/activesupport/lib/active_support/core_ext)
[Python] BFS (幅優先探索)　ABC146D

#[ABC146D](https://atcoder.jp/contests/abc146/tasks/abc146_d)
当内容は、他サイトを参考に自分用に編集したものです。
# はじめに
* 次数 (つながる辺の本数) が最大の頂点がボトルネックになる
* 次数の最大値を d とすると、d 色で塗り分けられそう

もし「具体的な塗り分け方を求めよ」と言われなければ、最大次数を出力してしまって良さそう。でも今回は、具体的な塗り方を求めることも要求されている。それは証明も込みで要求されているのに等しい。

# [木](https://ja.wikipedia.org/wiki/%E6%9C%A8_(%E6%95%B0%E5%AD%A6))なので
今回は一般のグラフではないので割と考えやすい。ちなみに今回の問題、一般のグラフの場合は最大次数色では塗りきれないケースが存在する (最大次数色 + 1 で塗ることは可能)！！！！

それはさておき、木を扱うときに定番となる考え方は「根を一つテキトーに決めてしまう」というのがある。これをすると木の頂点にある種の順序付けができるのだ。下図の左側のグラフで青い矢印で示したように、頂点を 1 つ選んで根にすると、下のグラフのような根付き木になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568274/d1625df5-71b2-ae61-1aa1-acd2acd70073.png)
そうすると、根頂点から順番に、その隣接辺の色を決めていけば良さそうに思えてくる (DFS でも BFS でもよい)。ここで注目したいのは

新たな頂点について、その隣接辺たちに色を塗ろうとするとき
その隣接辺たちのうち、すでに色が塗られてしまっているのは一本だけ
ということだ。その一本というのは「親頂点」に他ならない。よって、その一色を避けるように色付けすればよいだけだ。

# DFS でも BFS でも
木の探索の仕方は、DFS でも BFS でもどちらでもいい。重要なことは、根付きにおいて、どの 2 つの頂点 u, v についても、

* u が v の先祖 (v が u の子孫) であるとき
* u が先に処理されていて、その後 v を処理する

という風にすることだ。計算量はいずれにしても O(N) となる。

サンプルコードは、BFSによるもの。

参考
[BFS (幅優先探索) 超入門！ 〜 キューを鮮やかに使いこなす 〜](https://qiita.com/drken/items/996d80bcae64649a6580)

```python:サンプルコード
from collections import deque

# 辺数
n=int(input())
# 辺
G=[[] for i in range(n+1)]
G_order=[]
for i in range(n-1):
  a,b=map(int,input().split())
  # a,(<)bを紐付け
  G[a].append(b)
  # 頂点bをリスト
  # 頂点bと行数と辺は１対１対応（∵木に閉路はない）
  G_order.append(b)

# BFSのデータフレーム
q=deque([1])     # 頂点1を始点とした[訪問キュー]
color=[0]*(n+1)  # 頂点の上にある辺の色[フラグ]

# BFS 開始 (キューが空になるまで探索を行う)
while q:
  cur=q.popleft() # キューから先頭頂点(現在地)v取得
  c=1             # 頂点を移動したら色を初期化
  # 現在点から伸びる辺に色を付ける
  for nx in G[cur]:
    # 現在点の上辺と同じ色なら変更
    if c==color[cur]:
      c+=1
    color[nx]=c
    c+=1
    q.append(nx)  # 訪問先（頂点）を追加
 
print(max(color)) # 使用色数
for i in G_order:
  print(color[i])
```