OmniAICreator/Qiita-1.07M huggingface dataset:
Aurora Serverlessのデフォルト値が不親切な件

最近AWSを使っていて「Aurora Serverless」というRDBなのにサーバーレスアーキテクチャーというサービスがあることを知り使ってみました。しかし、デフォルト値に罠があったのでそのことのメモです。

#Aurora Serverlessとは
1. AWSのRDBフルマネージドサービスであるAuroraのサーバーレス版
- リソース調整が自動で急激な負荷増加に耐えられる
- 使っていない時に止まってくれる

ちょっとテストで使ってみる場合、3.の機能がお財布にやさしいわけです。

#ところが
実際にAurora ServerlessのRDSを作り、少しSQL実行して何日か放置しました。SQL実行していた時間は1,2時間くらいだったのでその時間分だけ課金されるものと思っていました。しかし、何日かしたところで請求ページを見たところ想定以上に課金されていました。

#原因
Aurora Serverlessを作成する際にオプション選択で以下のようにキャパシティを指定する箇所があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191613/50f78532-22fa-1a57-ffc9-d82e4bc0265c.png)

「スケーリングの追加設定」は閉じられてますが、これを開くと以下のように「数分間アイドル状態のままの場合コンピューティング性能を一時停止する」という項目があるのです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191613/34b45e13-d6f6-179e-8169-93a16ab18015.png)

この設定をデフォルトのままAurora Serverlessを作ってしまうと、アイドル状態でも一時停止されない常時起動RDSの完成です。当然、想定以上に課金されます。

#対策
作成時に「スケーリングの追加設定」を開いて、アイドル状態で一時停止する設定を入れておけば大丈夫です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191613/7cafc115-62b7-55aa-d055-e5dc3070ad52.png)
ojichatのPerl版を作ってみました

こちらは[Perl Advent Calendar 2019](https://qiita.com/advent-calendar/2019/perl)の22日目の記事になります。昨日は、Morichanさんによる、[PerlだけでWebサイトを作る](https://qiita.com/Morichan/items/7ae26fcff6c725761c2e) でした。

# はじめに
今年もPerl Advent Calendarに勢いだけでエントリーしてしまったのですが、何かCUIネタ的なものを書きたいと思ってネタを考えてみたものの、前日まで良いアイデアが浮かばず困り果てて慌ててこちらのojichatネタにしてみました。
ネタの性質的にもし気分を害された方などいらっしゃいましたら一旦アドベントカレンダーからエントリを分けさせていただきます🙇‍♂️

# なぜ今ojichatなのか？

約半年前に[トレンドになったojichat](https://togetter.com/li/1387648)ですが、なぜ今こちらを選んだのかと言いますと数日ほど前に久々におじさんの姫版である [himechat-cli](https://github.com/gyozabu/himechat-cli) が界隈で盛り上がっており、
またPerlの移植版は見たところまだ出ていなかったのでせっかくなのでこの機会にネタにしてみようと選んでみました。

# 移植の流れ
自分はGo言語については仕事で使っておらず、これまでまともに読んだ事が無かったのでオリジナルのコードを追いながら処理の流れ・クラス構成などを把握していきました。

まず目につくのが

`Onara ... Ojisan NArikiri Randomized Algorithm: おじさんなりきり乱択アルゴリズム`

というもので、おじさんの会話パターンのアルゴリズムがある事がわかりました。

と、それ以降の説明を書いて行こうと思ったんですがこのあたりの詳細は同時に参考にさせていただいた、ojichatのJS版、
[Goで実装されたojichatのJS版、ojichat.jsを作りました](https://qiita.com/kaibadash@github/items/936a8b45e7d849ac7345)
を読んで頂くとその処理の流れが掴めるかと思います。

## Perl化にあたって

まずは一本のperlスクリプトで雑に書いていって、そこから無理やりクラスっぽい感じにロジックを移動させていきました。

- オリジナルの[ojichat](https://github.com/greymd/ojichat)の構成になるべく合わせる
- 標準モジュールしか使わないようにする
  - …と思ったんですが、今後拡張出来るようにCartonだけは入れておくように変更
- [gimei](https://github.com/mattn/go-gimei)のPerl実装が無かったので、さきほどの記事を参考にランダムに100個をお借りしました
- 句読点を挟む処理ですが、形態素解析を使うまでの体力が持たなかったので、おじさんの後ほどの課題とさせていただいております😜😘😆(^_^;

…という感じでひたすら写経しながら書いていきました。

本当は自分なりの何かをしたかったのですが、アドベントカレンダー的に時間切れなので、一旦ここまでとさせていただいただきます💕😃✋😋

# 成果物
https://github.com/teckl/ojichat.pl

# 悲惨なデモ

<img width="654" alt="スクリーンショット 2019-12-22 22.22.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28477/90eaced6-1c16-ff06-38f5-f983abe6b13a.png">


```sh
$ for x in $(seq 10) ;do ./ojichat.pl ; done;
藤佳ﾁｬﾝ、ヤッホー😘😆😊😃☀ 何してるのかい✋❓❓（￣ー￣?）⁉藤佳ﾁｬﾝも今日も2時までお仕事かな✋❓❓（￣ー￣?）⁉ゆっくり、身体休めてね😘😆😊😃☀ オヤスミナサイ😙😒🛌😎
しえちゃん、オハヨウ〜💗😊（笑）😍今日はもう寝ちゃったのかな😪💤(^^;;✋月曜日、会社がお休みになったよ💗😊（笑）😍しえちゃんは都合どうかな（￣ー￣?）🤔❗❓😜⁉️ドライブ🚗どう💗😊（笑）😍なんてね💗😊（笑）😍
透心ちゃん、そっちも台風🌀なのかな⁉（￣ー￣?）❗❓✋❓出張で沖縄に行ってきたよ😃☀ 😋(^з<)😃✋観光でも、行きたいなぁ😃☀ 😋(^з<)😃✋モチロン、透心ちゃんとね
律楽ﾁｬﾝは、スタイルがいいね😘😃♥ (^_^)😆ホント可愛すぎだよ〜😘😃♥ (^_^)😆マッタクもう😘😃♥ (^_^)😆
るあちゃん、髪の毛、切ったのかな🤔❗❓（￣ー￣?）✋❓似合いすぎだよ😍😃♥ 😚😃☀ こんなに可愛く😍😃♥ 😚😃☀ なっちゃったら天使みたいで小生困っちゃうよ😓^^;💦(-_-;)
ゆっくり、身体休めてね（笑）😘(^o^)😁オヤスミナサイ🛌😙😌（￣▽￣）俺は留亜チャン一筋だよ🛌😙😌（￣▽￣）
りなちゃん、愛しいなぁもう😂😚😍(^з<)可愛すぎてﾎﾞｸお仕事に集中できなくなっちゃいそうだよ(・_・;(◎ ＿◎;)😥(-_-;)どうしてくれるんだ😂😚😍(^з<)
よしえちゃん、会社をサボるなんて、悪い子だなぁ😋(^з<)🎵😊今日は楽しい時間をありがとうね😋(^з<)🎵😊すごく、楽しかったよ😋(^з<)🎵😊
ヤッホー(^з<)😚💗❗はやねﾁｬﾝ、元気かな✋❓😜⁉️🤔❓今日は楽しい時間をありがとうね(^з<)😚💗❗すごく、楽しかったよ(^з<)😚💗❗
奈南チャンは、スタイルがいいね💕😄(^_^)(^o^)こんなに可愛く💕😄(^_^)(^o^)なっちゃったらお姫様みたいでおじさん困っちゃうよ(◎ ＿◎;)😰😖💔

```

うーん、これは地獄ですね…👴

# 感想
Go言語の処理をはじめてまともに読んでみる良い機会になりました。文字列操作とかの練習としてはちょうど良い題材だなぁ、と。
自分は普段Perlばかりしか見てないのですが、やはり全然文化が違っていてそれぞれの良さがあるんだなぁ、と。でも個人的にはやっぱりPerlで書きたいですねぇ。
ついでに先ほどの記事の @kaibadash さんの [ojichat.js](https://github.com/kaibadash/ojichat.js) のコードも参考にさせていただいて、TypeScriptのコードも初めて読んで雰囲気を味わうことができました。

あと、この年末の押し迫った時期の休日にひとり孤独におじさんの会話を読んで、いろいろとやるせない気持ちになったりしました。休憩の合間の究極エビルプリースト氏だけが心の支えとなりました…
でもまぁこれもまた良い経験になりました…！ﾅﾝﾁｬｯﾃ😍(^з<)😚

明日は、mp0liiuさんによる、[Perlのスタックトレースを見やすく扱う方法](https://qiita.com/mp0liiu/items/1c2822a7caa99a028305)です！
[AWS] EKSでFargateが使えるようになったらしいので試してみた

### はじめに
少し前に開催されたre:Inventで
「EKS(Elastic Kubernetes Service) 上のPodをFargateで実行できるようになった」
と発表されました。
https://aws.amazon.com/jp/blogs/news/amazon-eks-on-aws-fargate-now-generally-available/

ということで試してみました。

### 先にまとめ
- ワーカーノード無し (コントロールプレーン + Fargateのみ) でPodが実行可能

### EKS + Fargate 構築
ちなみに、以下の内容は基本的に[公式](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/fargate.html)を簡略化したものですので、実際にやる場合は公式をご覧ください。
#### 1. eksctlでクラスタを作成
今回は東京リージョンでクラスタを作成していきます。
EKS + Fargate に対応していないリージョンだとエラーになります。
(2019年12月現在 東京リージョンを含む4つのリージョンしか対応していません)

```bash
eksctl create cluster --name my-cluster --version 1.14 --fargate --region ap-northeast-1
```

`--fargate` を指定することでFargateプロファイルなるものが作成され、PodをFargateで実行できるようになります。
なおこのとき、実行するIAMユーザーに `eks:CreateFargateProfile` 等の権限が無いとエラーになります。
その後の削除等も含めると `eks:*FargateProfile*` の権限を付けた方が良いかと思います。

#### 2. 作成したクラスタにPodをデプロイ
普通にkubectlで作成するだけで、自動的にFargateで実行されます。
特にEKS/Fargate用の設定等は必要ありません。(Dockerイメージの取得元をECRにする等はあるかもですが)

```bash
kubectl apply -f deployment.yaml
```

#### 3. デプロイしたPodがRunningになるのを待つ
今回 `replicas: 2` の Deployment で試しましたが、
1つのPodは30秒くらいで `ContainerCreating` になったのに対して
もう1つは80秒くらいまで `Pending` のままでした。
このあたりはFargateの機嫌次第だと思われます。

というわけで、ワーカーノードを追加することなくFargateでPodが実行できました。

### その他
Fargateで稼働しているPodに対してALBを設定しようとしたのですが
alb-ingress-controller 内でエラーとなりうまくいきませんでした。
また別途調査しようと思います…
【開発環境】Operation not permittedでphp artisan migrateできないときは権限周りを確認！

![permission.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250884/12113346-fcc0-3261-0a3c-906d3295f0d9.png)


どうも、たかふみです。

現在携わっているシステムの開発が終わり、「さぁそろそろステージング環境の準備をしようかなぁ」と思い、テーブルを作成するコマンド `php aritisan migrate` を実行しようとしたそのとき。

```
Operation not permitted
```

「migrateができない！」

今日の記事は、AWSのEC2を使って用意したステージング環境でmigrateができない問題を解決します！

# 解決策
自分が所有ユーザーになる＆所有グループに書き込み権限を与える

# やったこと
## 1. まずエラーメッセージを読む。

```
UnexpectedValueException  : The stream or file "/var/www/mcfhfs/storage/logs/laravel-2019-11-20.log" could not be opened: failed to open stream: Permission denied
  at /var/www/mcfhfs/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php:111
    107|             restore_error_handler();
    108|             if (!is_resource($this->stream)) {
    109|                 $this->stream = null;
    110|
  > 111|                 throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened: '.$this->errorMessage, $this->url));
    112|             }
    113|         }
    114|
    115|         if ($this->useLocking) {
  Exception trace:
  1   Monolog\Handler\StreamHandler::write()
      /var/www/mcfhfs/vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php:120
  2   Monolog\Handler\RotatingFileHandler::write()
      /var/www/mcfhfs/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php:42
  Please use the argument -v to see more details.
```

エラーメッセージを見てみると「ログファイルへの書き込み権限がありません。」となっていました。どうやらログファイルへの書き込み権限が無いようです。

## 2. ログファイルの権限を確認＆変更

`ls -la` で権限を確認すると、`rw- - r -- - r --`となっていました。

この場合「所有ユーザ(読/書) - 所有グループ(読) - その他のユーザ(読)」であり、
僕は所有ユーザーではなく、所有グループに属するので読み取り権限しかありません。

「そしたら、所有グループの権限に書き込み権限(w)を追加すれば良いのでは？」

ということで`chmod 664 laravel-2019-11-20.log` を実行。
結果、 `Operation not permitted` が表示されました。

調べてみると、ファイルの権限はファイル所有者でないと変更できないようです。
（参考：https://marunouchi-tech.i-studio.co.jp/3341）

## 3. ファイルを作り直す
「そしたら、自分がファイルの所有ユーザーになればいいのでは？」

該当のログファイルを一旦削除して再度作成。
ファイル所有者が自分になっていることを確認した後、再度migrateを実行。

```
php artisan migrate:fresh
Dropped all tables successfully.
Migration table created successfully.
```

「成功！」

## 4. webサーバーからも書き込みができるように権限を変更

これで解決だと思い、ブラウザからステージング環境に接続してページを表示しようとしたところ、再び「ログファイルに書き込み権限がありません」との表示がされました。
どうやらwebサーバーからの書き込み権限を与える必要があるようです。

```
chmod 664 laravel-2019-11-20.log
ls -la
-rw-rw-r--
```

これで所有ユーザー、所有グループに書き込み権限を付与できたので再度サイトへアクセス。無事に表示されていました！

## ■まとめ
・権限はファイル所有者でないと変更できない。
・webサーバーからの書き込み権限付与を忘れずに！
・「Operation not permitted」「Permission denied」のときには権限を確認！

今まで権限でエラーが起きたことがなかったので、これを機に知ることができて良かったです。これでPermission deniedが出ても安心ですね。それでは！
ほぼオンプレしか触ったことがないインフラエンジニアがAWS SAAを取得するまで

#はじめに
ほぼインフラしか触ったことがないインフラエンジニアでしたが、
一か月半くらいの勉強で合格出来ましたので備忘録がてらメモです。
同じようにオンプレの経験しかない方の参考になれればいいと思います

#私のスキルセット
業界３年（最初の会社で取ったCCNAが失効した。。。）
Linuxなんとなく操作できる（LPICレベル３はもってる）
IAサーバならなんとなく構築できる
OSの動作とかコンピュータアーキテクチャがなんとなくわかる
ラッキングとか物理作業もなんとなくできる

AWSの勉強を始めた直後ぐらいにAWSの案件にぶち込まれたので
AWSの業務経験としては1か月くらいです。（右も左もわからんのにTerraformな感じでした）

#勉強方法

##参考書を読む

以下の本を2周読みました。

[この1冊で合格! AWS認定ソリューションアーキテクト - アソシエイト テキスト&問題集](https://www.amazon.co.jp/%E3%81%93%E3%81%AE1%E5%86%8A%E3%81%A7%E5%90%88%E6%A0%BC-AWS%E8%AA%8D%E5%AE%9A%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88-%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-%E5%95%8F%E9%A1%8C%E9%9B%86/dp/4046042036/ref=sr_1_7?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=AWS&qid=1577017785&sr=8-7)
[AWS認定資格試験テキスト AWS認定 ソリューションアーキテクト-アソシエイト](https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-AWS%E8%AA%8D%E5%AE%9A-%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88-NRI%E3%83%8D%E3%83%83%E3%83%88%E3%82%B3%E3%83%A0%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE/dp/479739739X/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=AWS&qid=1577017785&sr=8-1)
[Amazon Web Services 業務システム設計・移行ガイド](https://www.amazon.co.jp/Amazon-Services-%E6%A5%AD%E5%8B%99%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E8%A8%AD%E8%A8%88%E3%83%BB%E7%A7%BB%E8%A1%8C%E3%82%AC%E3%82%A4%E3%83%89-Informatics-IDEA/dp/4797392568/ref=sr_1_13?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=AWS&qid=1577017785&sr=8-13)

以下の本も買いましたが、上記で分からなかった部分だけ読みました

[Amazon Web Servicesインフラサービス活用大全 システム構築/自動化、データストア、高信頼化 (impress top gear] (https://www.amazon.co.jp/Amazon-Services%E3%82%A4%E3%83%B3%E3%83%95%E3%83%A9%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E6%B4%BB%E7%94%A8%E5%A4%A7%E5%85%A8-%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E6%A7%8B%E7%AF%89-%E8%87%AA%E5%8B%95%E5%8C%96%E3%80%81%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B9%E3%83%88%E3%82%A2%E3%80%81%E9%AB%98%E4%BF%A1%E9%A0%BC%E5%8C%96-impress/dp/4295006653/ref=sr_1_2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=AWS&qid=1577017785&sr=8-2)

#  Black Belt を読み漁る

[AWS クラウドサービス活用資料集トップ](https://aws.amazon.com/jp/aws-jp-introduction/)

動画はあまり見てません、、、1時間ぐらいかかってしまうので

# AWS各サービスのよくある質問を読み漁る

※一番大事だったかもしれません。**一次情報なので**
~~そもそもベンダー試験なので公式ドキュメントを暗記すれば解けるはず~~

[よくある質問](https://aws.amazon.com/jp/faqs/)

#試験結果
788点で合格でした。

結構ひっかけというか単純に暗記してるだけだと間違えるような問題が結構ありましたので、
暗記でなく、実際の構成例とかも見ないと厳しいかもしれません。

[日本国内のお客様の導入事例](https://aws.amazon.com/jp/solutions/case-studies-jp/)

#最後に
オンプレの設計構築経験があるサーバエンジニアであれば
1か月くらいの実務期間とそれに並行して勉強すれば問題なく合格できるレベル感だと思います。
exeへの引数処理

練習とメモ用
定期的に機能増やす予定

機能
引数１つの場合のみ対応
コンソールとドロップで実行可能
絶対パスとファイル名、拡張子が取得可能
.lnkの時に参照元のパスを取得
""で引数を渡されなくても実行可

注意点
Windows Script Host Object Modelを参照しなければならない

```cs:Program.cs
using System;

namespace FileGet
{
    class Program
    {
        static void Main(string[] args)
        {
            GetFile getFile = new GetFile(args);
            Console.ReadKey();
        }
    }
}
```

```cs:GetFile.cs
using System;
using System.Linq;

namespace FileGet
{
    class GetFile
    {
        private IGetFileProcess pro;
        public GetFile(string[] args)
        {
            string[] Path = Environment.GetCommandLineArgs();
            if (args.Any())
            {
                pro = new FileArgument(args);
            }
            else if (Path.Length > 1)
            {
                pro = new FileDrop(Path);
            }
            else { Console.WriteLine("引数とドロップはありませんでした。"); return; }
            Console.WriteLine("FilePath:{0}", pro.FilePath);
            Console.WriteLine("FileName:{0}", pro.FileName);
            Console.WriteLine("FileType:{0}", pro.FileType);
        }
    }
}
```

```cs:IGetFileProcess.cs
namespace FileGet
{
    public interface IGetFileProcess
    {
        string FilePath { get; set; }
        string FileName { get;}
        string FileType { get;}
    }
}
```

```cs:FileDrop.cs
using System.IO;
using IWshRuntimeLibrary;

namespace FileGet
{

    class FileDrop : IGetFileProcess
    {
        public string FilePath { get; set; }
        public string FileName 
        {
            get { return Path.GetFileName(@FilePath); }
        }
        public string FileType
        {
            get { return Path.GetExtension(@FilePath); }
        }
        public FileDrop(string[] arg)
        {
            FilePath = arg[2];
            if (Path.GetExtension(@FilePath) == ".lnk")
            {
                WshShell Shell = new IWshRuntimeLibrary.WshShell();
                IWshShortcut Shortcut = (IWshShortcut)Shell.CreateShortcut(FilePath);
                FilePath = Shortcut.TargetPath.ToString();
            }
        }
    }
}

```

```cs:FileArgument.cs
using System;
using System.IO;
using IWshRuntimeLibrary;

namespace FileGet
{
    class FileArgument : IGetFileProcess
    {
        public string FilePath { get; set; }
        public string FileName 
        {
            get { return Path.GetFileName(@FilePath); }
        }
        public string FileType
        {
            get { return Path.GetExtension(@FilePath); }
        }

        public FileArgument(string[] arg)
        {
            FilePath = String.Join(" ", arg);
            if (FilePath.Contains("\""))
            {
                FilePath = FilePath.Replace("\"", "");
            }
            if (Path.GetExtension(@FilePath) == ".lnk")
            {
                WshShell Shell = new WshShell();
                IWshShortcut Shortcut = (IWshShortcut)Shell.CreateShortcut(FilePath);
                FilePath = Shortcut.TargetPath.ToString();
            }
        }
    }
}

```
2019年を振り返ってみる

この記事は、[Rails Girls アドベントカレンダー2019](https://qiita.com/advent-calendar/2019/railsgirlsjapan)  22日目の記事です。

今年はざっくり振り返りと来年の抱負を・・・

## いちおう自己紹介(ほぼ毎年恒例)
* Rails Girls Nagoya 1st〜4th オーガナイザー
* Rails Girls JPメンバー
* クマ好き。特にくまモンが好き。
  * ふるさと納税で、熊本県に「くまモン応援分」として納税するくらいは・・・

## 2019年、自分が関わったRails Girls関係の振り返り
* 今年コーチとして、お手伝いしたRails Girls
  * Rails Girls Kobe 4th
  * Rails Girls Nagano
* Rails Girls 関連の オンライン勉強会継続中
   * Rails Girls Nagoya more!を継続開催中。
   * Rails Girls Nagano more!(旧Shiojiri more!)など、オンライン勉強会に参加中。
* Rails Girls Nagoya 5th準備
    * 来年1/31-2/1にやります！（詳しくは後述）

## 今年の総括と来年の抱負
* 勉強会は継続したい・・・！
* あとはRailsGirlsのドキュメント関係の諸々に貢献したい・・・！

## 2020年のRailsGirls（宣伝）
2020年、最初のRails Girlsは、2020/1/31-2/1に、名古屋で開催します！
名古屋での開催は２年ぶり５回目です！
[Rails Girls Nagoya 5th](http://railsgirls.com/nagoya) 
お申し込みは[こちら](https://railsgirls-nagoya.doorkeeper.jp/events/101526)から！
この記事を読んでいる皆様の周りにプログラムに興味を持っている女性の方がいらっしゃったら、
勧めていただけると幸いです。

また、名古屋以外の他の地域でも
* 愛媛(2nd) 2/07-08
* 東京(13th) 2/14-15
の開催がすでに決まっています。今後も続々開催される（はず）なので、
最新情報は、http://railsgirls.jp をチェックしてください！
LIVA Q2にCentOS7をインストールする

# はじまり
IoT用に通常のPCくらいの使い勝手がある小さな安鯖みたいなものが欲しかったので[LIVA Q2](https://www.links.co.jp/item/liva-q2-pro-64g/)を購入。とりあえずLinuxを動作させてみる。

# メモ
いろいろと備忘録的に記録。

## 本体について
本体の縦横はRaspberry Pi Zeroの横幅と同じくらいでPCとしてはかなり小さい。
![qiita_IMG_0044.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63695/baaf59e9-6f96-6b2b-314d-439760f98385.jpeg)

## BIOS設定
LIVAロゴが表示されている間にDELキーでBIOS設定画面に入れる。
変更後の画面だが、初期状態では**Windows 10**用として設定されているため、**Linux**に変更して再起動する。
![qiita_IMG_0073.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63695/101f5ce6-b8e2-e9a2-5da1-f24e9f062a71.jpeg)

## Windows 10のバックアップ
後でWindows 10で利用したくなった場合に困らないようにストレージの内容をバックアップ。
![qiita_IMG_0070.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63695/5699bd6c-43be-553e-ad13-1ede53166b20.jpeg)

## CentOS 7のインストール
CentOS 7.4 mininalのISOでインストール。
eMMCの認識がCentOS 8でないとNGかと思っていたが問題なかった。
![qiita_IMG_0071.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63695/77429056-0a0f-9352-eebd-9117a689434c.jpeg)

インストール時に有線・無線LANのどちらも認識していることを確認。
![qiita_IMG_0072.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63695/4431f93a-775e-3ae0-c479-ea8a4c8e2da6.jpeg)

# その他
## インストール中の解像度の問題
ディスプレイのせいかCentOS 7.4だと解像度が異常に低いが、CentOS 7.7であれば正常にディスプレイ解像度に合わせて表示された。

## eMMCのベンチマーク
eMMCのfioベンチマークをやってみた。[過去のSDカードでのベンチマーク結果](https://qiita.com/papillon/items/852da1cc8ff77661a960#sd%E3%82%AB%E3%83%BC%E3%83%89%E3%81%A7%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88%E7%B5%90%E6%9E%9C)と比較すると、期待していた以上に高速だった。

```
job, bandwidth, iops
seqread, 268907, 262
seqwrite, 174268, 170
seqread4, 298890, 291
seqwrite4, 184471, 180
randread512k, 254473, 497
randwrite512k, 170382, 332
randread4k, 19781, 4945
randwrite4k, 43512, 10878
randread4k32, 61416, 15354
randwrite4k32, 129024, 32256
```

## eMMCの寿命を調べる
HDDやSSDであれば``smartctl``でステータスを確認することが可能だが、eMMCでは利用できない。``mmc``コマンドを試してみようと思いソースをcloneしてmakeするもエラーでコンパイルできなかったため、調べてみると``/sys/class/mmc_host/mmc0/mmc0:0001/``以下に有用そうな情報があるらしい。[このへん](https://www.kernel.org/doc/Documentation/mmc/mmc-dev-attrs.txt)とか、[このへん](http://dtsheet.com/doc/1384294/tn-fc-32--e.mmc-device-health-report)、[このへん](https://ja.osdn.net/users/faxiang1230/pf/kernel/scm/commits/bc5b6dd5dfd838f7338e8d1ae42f670adc1a4d03)を参考にする。

```
# cat /sys/class/mmc_host/mmc0/mmc0\:0001/life_time
0x01 0x01
# cat /sys/class/mmc_host/mmc0/mmc0\:0001/pre_eol_info
0x01
```

この結果だと、SLCエリア、MLCエリアともに新品同様で、Pre EOLステータスも問題ない健康なeMMCとなっている。・・・数時間しか稼働していないPCなので当然だが。
とりあえず将来的に値がどのように変化するかを確認したい。
Xcodeで使えるフォント

#はじめに
私はiOSのアプリを作っています。
仕事中気になったことが、Xcodeはどんなフォントの種類があるのか気になって調べてみました。
余り使うことないかもしれませんが、温かい目で見てください。。。

#フォント一覧
今回はstoryboardのLabelで使えるフォントを調べます。Attributes InspectorでText: Plain、font: customのfamilyで選択できるフォントです。
文字サイズはすべて17です。端末はiPhone XS Maxです。
結果↓
１枚目
![Simulator Screen Shot - iPhone XS Max - 2019-12-22 at 19.58.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221940/cb69b1c9-8ff9-1735-0029-e54d60911b7f.png)

２枚目
![Simulator Screen Shot - iPhone XS Max - 2019-12-22 at 21.01.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221940/2669d679-ebb0-5eb4-180e-1e6544f7b5dd.png)

３枚目
![Simulator Screen Shot - iPhone XS Max - 2019-12-22 at 21.15.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221940/2e46fac8-d1b1-3ad4-082f-92d97e76ed40.png)

４枚目
![Simulator Screen Shot - iPhone XS Max - 2019-12-22 at 21.17.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221940/e3d77d20-02da-7dce-871d-5d4bb2649181.png)

#まとめ&最後に
こんな結果になりました。
１枚目の赤枠はBodoni Ornamentsというフォントです。使うときあるんですかね。。。笑
３枚目の赤枠はMishafi Regularと入力したんですが空白が無視されるフォントがあるの初めて知りました。

いろんなフォントがあるんですね！やってて勉強になりました。
いつかいろんなフォントでアプリ作るときに参考になれば幸いです。最後までご覧いただきありがとうございました！
PHPで「大石・泉・すき」をランダムに表示して「大石泉すき」が完成したら大石泉すき

## この記事について
本記事は、[「大石泉すき」 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/ohishi-izumi-suki)の23日目です。

プログラム言語「PHP（PHP: Hypertext Preprocessor）」を使い、「大石泉すき」が完成するまで「大石・泉・すき」をランダム表示するプログラムを作成します。

## 大石泉とは
>「大石泉」（おおいし いずみ）とは、Mobageにて配信されているバンダイナムコエンターテインメントのソーシャルゲーム『アイドルマスター シンデレラガールズ』に登場するロジックアイドルである。

（引用：[ニコニコ大百科](https://dic.nicovideo.jp/a/%E5%A4%A7%E7%9F%B3%E6%B3%89)より）

私の担当アイドルである[二宮飛鳥](https://dic.nicovideo.jp/a/%E4%BA%8C%E5%AE%AE%E9%A3%9B%E9%B3%A5)とは出身地が同じ（静岡県）で歳が近いということでいつか公式でユニット組んでくれないかなーと思ってるんですが、中々その機会が訪れなくて泣けますね。


## PHPで「大石泉すき」を表示するには
まず最初に、PHPで「大石泉すき」と単純に表示するだけのプログラムを作る場合について考えます。
PHPでは以下のように記述することで、「大石泉すき」と表示することができます。

```php
大石泉すき
```

冗談抜きでこれで終わりです。
PHPは、以下のようにHTMLの中に埋め込んで使うことができる言語です。

```php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title><?php echo $title; ?></title>
</head>
<body>
    <?php
        // <?php ～ ?> で囲った部分のみがPHPの記述として解釈される
        echo $content;
    ?>
</body>
</html>
```

この場合、「<?php ～ ?>」で囲われていない部分はHTMLとして普通に表示されます。
なので、一番最初の例のように単純に文字列を表示したい場合、PHPのタグを記述せず表示したい文字列を書けばそれで終わりなのです。
ね、簡単でしょう？

勿論、以下のようにプログラムっぽく書くことも可能です。

```php
<?php
    echo '大石泉すき';
```

これで終わるとあまりにもあっさりしすぎなので、ちょっと捻ったことをやってみましょう。

## #「大石泉すき」が完成するまで「大石・泉・すき」をランダム表示する #って何？

「大石泉すき」が完成するまで「大石・泉・すき」をランダム表示します。

何年か前に流行った「[「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくる](https://qiita.com/kataware/items/edc8d0f02a16a21c47dc)」を「大石泉すき」でやろうという試みです。

これをPHPで書くと、こんな感じです。

```php
<?php
// 「大石泉すき」を少しずつ区切って配列に格納する
// 「大石泉すき」以外の文字列が紛れ込んでるって？　さあ、何の事ですかね…………
$ooishiizumisuki = [
    '大石',
    '泉',
    '二宮',
    '飛鳥',
    'すき',
];

// 探索対象の文字列リスト
$search_list = [
    '大石泉すき',
    '二宮飛鳥すき',
];

// count関数は配列の要素数を取得する
// そこから1を引くことで当該配列における最大の添字を求めることができる
$max_index = count($ooishiizumisuki) - 1;

// PHPの配列は添字が0から始まる
$min_index = 0;

$text = '';
$appeared_text = '';

while (1) {
    // $ooishiizumisukiの中からランダムに文字列を取得して、文字列結合していく
    $index = random_int($min_index, $max_index);
    $text .= $ooishiizumisuki[$index];

    foreach ($search_list as $search_text) {
        // 結合した文字列の中に、探索対象の文字列が含まれていたらループを抜ける
        if (strpos($text, $search_text) !== false) {
            $appeared_text = $search_text;
            break 2;
        }
    }

}

// 探索対象の文字列が出現するまでに何文字を要したかを記録
$text_length = mb_strlen($text);

?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title><?=$appeared_text;?></title>
</head>
<body>
    <div><?=$text;?></div>
    <div><?=$text_length;?>文字で「<?=$appeared_text;?>」が出現しました。<?=$appeared_text;?></div>
</body>
</html>
```

実際に実行すると、こんな感じになります。

>すき二宮泉すきすき大石すき飛鳥すき飛鳥泉すき泉大石大石飛鳥飛鳥泉飛鳥すきすき二宮泉飛鳥すき飛鳥泉飛鳥二宮大石二宮大石泉すき
61文字で「大石泉すき」が出現しました。大石泉すき

運がよければ以下のように最短で「大石泉すき」できます。

>大石泉すき
5文字で「大石泉すき」が出現しました。大石泉すき

ところで「大石飛鳥」、「二宮泉」ってすごくときめく文字列じゃありませんか？
バンナ○ならびにサイゲ○ムスはいずあすを公式化してね！　しろよ☆
NDLデジコレの古地図をコモンズにアップしてWeb地図として使うまで




# 1 NDLデジコレで古地図を探す
[NDLデジコレの詳細検索画面](http://dl.ndl.go.jp/search/detail)で下記のように入力して検索すると、その地域名に関連のある古地図が出てきます。
キーワード：（地域名）
件名：古地図 地図 絵図（「OR」」に設定）
![](https://i.imgur.com/6FKh6e5.png)
公開範囲欄が「インターネット公開（保護期間満了）」とあるものは少なくとも国内では著作権保護期間が満了していますので自由に使えます。
![](https://i.imgur.com/fNVnu9t.png)
画像出力ボタンで100%のサイズの画像をダウンロードします。
![](https://i.imgur.com/N2ojVP5.png)

# 2 [コモンズにアップロード](https://commons.wikimedia.org/wiki/File:Karaku_Oukozu_1872.jpg)
![](https://i.imgur.com/9gJcoDG.png)
アップロードウィザードで適当なメタデータを入力してアップロードし、編集モードで開くと下記のような内容で{{information}}テンプレートが書き込まれています。これを[{{Map}}テンプレート](https://commons.wikimedia.org/wiki/Template:Map)に書き換えて
|unwarped=yes
というパラメータを追加します。
![](https://i.imgur.com/ksICYuQ.png)
このパラメータは後述の[Wikimaps Warper](https://warper.wmflabs.org/maps/)というツールでまだジオリファレンス（Web地図化）が行われていないことを示し、「Georeference the map in Wikimaps Warper」という青いボタンがコモンズの画像ページ上に表示されます。
![](https://i.imgur.com/HVFX63y.png)
このボタンを押すとWikimaps Warper遷移します。

# 3 [Wikimaps Warper](https://warper.wmflabs.org/maps/)で座標付与
古地図などに座標を与え(georeference)、WebGISで重ね表示可能にするものです。オリジナルは[こちら](http://mapwarper.net/)ですが、今回はコモンズと連携した[Wikimaps Warper](https://warper.wmflabs.org/maps/)を使います。（詳細な操作説明は[こちら](https://docs.google.com/document/d/1c6LkjKhGeUy-ygQHEOlYOytFkOj8uwGKphuz9Z8fgK0/edit)を参照）
![](https://i.imgur.com/3HEtbnC.png)
「Rectify」タブで左右のマップを見比べながら、同一の地点にピンを打ち「WARP IMAGE!」ボタンを押して画像を位置合わせします。（ここではサンプル的にピンは4つだけ打ちましたが、精度を上げるには多いほどベターです）
![](https://i.imgur.com/pRVMDZz.png)
「Preview」タブで下部のスライダーで透過度を変えながら位置を確認します。
![](https://i.imgur.com/IXDDSfd.png)
「Export」タブでタイル配信URLを取得できます。
![](https://i.imgur.com/1bUztL9.png)

# 4 地図タイル利用例([uMap](https://umap.openstreetmap.fr/ja/))
取得したタイル配信URLは背景地図を設定できるツールやアプリで利用できます。ここでは[uMap](https://umap.openstreetmap.fr/ja/)というツールでの利用例を示します。
独自背景欄にタイル配信URLをセットします。
![](https://i.imgur.com/6Odz7rC.png)
保存してタイルを切り替えます。
![](https://i.imgur.com/E6rcUcJ.png)
背景地図として表示されました。
![](https://i.imgur.com/QfnkRNI.png)

# 5 利用できる地図タイルを[マップ上で探す](https://warper.wmflabs.org/maps/geosearch?show_warped=1)
[「Find Maps by Location」タブ](https://warper.wmflabs.org/maps/geosearch?show_warped=1)の右側のマップで日本を表示すると、日本をカバーしている古地図など全体がマップから検索できます。この機能により自分で使うだけでなく、コモンズにある古地図画像のうちWeb地図として使えるものの一覧として、誰もが探しやすくなります。

![](https://i.imgur.com/x0H6Ge7.png)
# 6 [トレース](http://warper.wmflabs.org/maps/2778#Trace_tab)
「トレース」タブを選ぶとマップ編集画面が現れます。
![](https://i.imgur.com/RAzVxmA.png)
これはOpenStreetMapのエディタiDと同じソフトウェアですが、登録データの向き先はOpenStreetMapではなく、別プロジェクトの[OpenHistoricalMap.org](https://www.openhistoricalmap.org/)となっています。
[OpenHistoricalMap.org](https://www.openhistoricalmap.org/)は一言でいえばOSMの歴史的地図バージョンです。OpenStreetMapと同じソフトウェアスタックを使って、OSMの過去版を作成するプロジェクトです。
つまり、Wikimaps Warperの古地図を下絵として地理オブジェクトをiDと同じインタフェースでOpenHistoricalMapに書き込むことができます。（OpenHistoricalMapの詳細は[こちら](https://wiki.openstreetmap.org/wiki/JA:Open_Historical_Map)）これにより例えば江戸の町並みを画像ではなく地理データとして持つことも可能になります。
# 7 さいごに
OpenGLAMの動きの中で日本でも公共博物館や図書館からデジタルアーカイブのデータが公開されることが増えてきています。その活用には個々の所蔵館で公開するだけでなく、ジャパンサーチやコモンズのような領域で形式を揃えて横断的に提供することが重要です。そうすることで二次利用が容易になります。ここで紹介したような流れが広がることを期待しています。
分類の代表的な指標

こんにちは。
今回はちょっと気合を入れて**分類精度**について述べようと思います:relaxed:

#指標って何？
指標とは、データのクラスをどの程度正確に当てられたかを測る基準的なものです。
このモデルが正しい！！！だから採用してください！！と言われても誰も納得しませんよね。

周りの生活での具体的な例としては、**偏差値**。
偏差値は勉強に対するある**基準**の役割を持っています。
偏差値が全てとは全然思いませんが、ある程度の基準は必要になります。
なぜなら、基準がなければ判断は不公平な決断が生まれる可能性があるからです。
また学業の世界では、通知表、履歴書など基準は色々な方法が存在します。またそれぞれの基準は違う軸を持っています。

これは分類の世界でも同じです。
機械学習を用いて構築したモデルの良し悪しを評価する為の指標が沢山存在します。
今回紹介したいのは4つです。
- 適合率　(*precision*)
- 再現率　(*recall*)
- F値 　(*F-Value*)
- 正解率　(*accuracy*)


これらを紹介する前に**混同行列**という存在を説明したいと思います。

# 混同行列
結論から言うと、混同行列とは**分類の結果をまとめた行列**です。
はぁ？って思った人もいると思いますが、今から説明するので安心してください。

## 正例と負例
分類の世界には、「興味がある」と「興味がない」と言う考え方があります。
また
「興味がある」を**正例**といい、
「興味がない」を**負例**をいいます。

例えば、送られてきたメールがスパムであることを予測する場合、
どのメールが**スパム**であることに興味があるので、
正例はスパム、負例は通常のメールです。
大体正例と負例のイメージがつかめましたか？

これを頭に入れた上で以下の画像をみてください。
![IMG_2211.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255565/a0e731cf-7035-090c-cd2c-9eb77e45c6e9.jpeg)

## 混同行列の説明
混同行列は４種類に分かれています。
真陽性（左上）・・・実際のデータが正例で、機械学習自体も正例と分類した場合。（正解）
偽陰性（右上）・・・実際のデータは正例だが、機械学習は負例と分類した場合。（不正解）
偽陽性（左下）・・・実際のデータは負例だが、機械学習も正例と分類した場合。（不正解）
真陰性（右下）・・・実際のデータが負例で、機械学習自体も負例と分類した場合。（正解）

数学的にもこの４種類しかあり得ません。
なぜなら場合の数により、2(実際のデータは２種類（正例OR負例）） * 2(予測も２種類) = **4**


混同行列の説明はこの辺にして、
この図を元に指標の4つを見ていこうと思います。

## 適合率
適合率・・・**機械学習モデルが正例であると予測した内の何%が当たっていたか**（正例であったか）を示す。
上記の図の記号を使って計算式で書くと、

```math
適合率 = \frac{tp}{tp + fp}
```
と書けます。
つまり適合率が高いとは、正例と予測して実際に正例であったデータの割合が高いことを示す。

## 再現率
再現率・・・**実際の正例のデータのうち、正例と予測したものの割合**を示す。
これは適合率ととても似ているがある関係になっている。それは後々説明するとしよう。
先に再現率を数式で書くと、

```math
再現率 = \frac{tp}{tp + fn}
```
つまり再現率が高いとは、正例のデータに対して正例だと予測できたデータの割合が高いことを示します。

## 適合率と再現率の関係
この二つの評価指標は**トレードオフ**の関係にあります。
言い換えるのであれば、再現率を高くしようとすると適合率が低くなり、逆も然りです。

想像が付きにくい人は下記の例を読んでみてください。とてもわかりやすかったです。
[再現りつと適合率の関係](https://aidemy.net/courses/2010/exercises/HJWxt3UiUxz)


# F値
F値・・・適合率と再現率の調和平均
即ち、

```math
F値 = \frac{2}{\frac{1}{適合率} + \frac{1}{再現率}} = \frac{2 \times 適合率 \times 再現率}{適合率 + 再現率}
```
F値は適合率と再現率の調和平均を取ることにより、両方の指標が**バランス**の良い値になることを目指す時に重視する指標。

## 正解率
正解率・・・正例か負例かを問わず、予測と実績が一致したデータの割合を示す。
即ち、

```math
正解率 = \frac{tp + tn}{tp + fp + fn + tn}
```
予測結果全体と、答えがどれぐらい一致しているかを判断する指標。

# まとめ
いかがだったでしょうか？
機械学習のモデルが良いか悪いかを判断するには様々な観点があります。
自分自身がどんなモデルを欲しているかを課題全体を通して見抜く必要がありそうですね。
今回まとめたのは,
- 適合率
- 再現率
- F値
- 正解率
でした。
この世の中には指標は沢山あります。
指標を覚える必要はないと思いますが、知っておく事は大切ですよね。
ありがとうございました。

# 参考文献
[いまさら聞けない機械学習の評価関数](https://data.gunosy.io/entry/2016/08/05/115345)
[混同行列を理解する](https://aidemy.net/courses/2010/exercises/Sy2YnLsLeG)
初めてのVulkanプログラミング step6 グラフィクスパイプライン作成

6章のオブジェクトを組み合わせてグラフィクスパイプラインを作成することができます。
現在あるオブジェクトは以下の通りです。

- シェーダステージ: プログラム可能なパイプラインの機能:フラグメントシェーダや、バーテックスシェーダなど
- 固定機能 パイプラインの固定ステージを定義する機能：アッセンブリー、ラスタライザー,ビューポート、カラーブレンディング
パイプラインレイアウト
- レンダーパス：パイプラインステージによって作成、参照されるデータの使用方法

全て組み合わせてグラフィクスパイプラインを作成するためにvkGraphicsCreate構造体に定義して、createGraphicsPipeline関数で生成します。

```cpp

	VkGraphicsPipelineCreateInfo pipelineCreateInfo;
	pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
	pipelineCreateInfo.pNext = nullptr;
	pipelineCreateInfo.flags = 0;
	pipelineCreateInfo.stageCount = 2;
	pipelineCreateInfo.pStages = shaderStages ;
	pipelineCreateInfo.pVertexInputState = &vertexInputCreateInfo;
	pipelineCreateInfo.pInputAssemblyState = &inputAssemblyCreateInfo;
	pipelineCreateInfo.pTessellationState = nullptr;
	pipelineCreateInfo.pViewportState = &viewportStateCreateInfo;
	pipelineCreateInfo.pRasterizationState = &rasterizationCreateinfo;
	pipelineCreateInfo.pMultisampleState = &multisampleCreateInfo;
	pipelineCreateInfo.pDepthStencilState = nullptr;
	pipelineCreateInfo.pColorBlendState = &colorBlendCreateInfo;
	pipelineCreateInfo.pDynamicState = nullptr;
	pipelineCreateInfo.layout = _pipelineLayout;
	pipelineCreateInfo.renderPass = _renderPass;
	pipelineCreateInfo.subpass = 0;
	pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
	pipelineCreateInfo.basePipelineIndex = -1;

	err = vkCreateGraphicsPipelines(_device, VK_NULL_HANDLE, 1 ,&pipelineCreateInfo, nullptr, &_pipeline);
	if (VK_SUCCESS != err) {
		assert(0 && "Vulkan ERROR: Create Pipeline failed!!");
		std::exit(-1);
	}
```

次の章では、フレームバッファーを設定し、描写コマンドを発行します。これが終わると、画像をモニターに表示することができます。
Javaのswitch文

##Javaを使った条件分岐

###if文を用いると

```

class Main {
  public static void main(String[] args) {
    int number = 12;

  if(number % 3 == 0){
        System.out.println("3で割り切れます");
  else if(number % 3 == 1){
        System.out.println("3で割ると1余ります");
  else
        System.out.println("3で割ると2余ります");
  }

 }
}

```

###swich文を用いると

※ 各caseの最後に、break;をつけるのを忘れずに！
　忘れると、合致したcaseの処理を行った後、その次のcaseの処理も実行してしまう。

```
class Main {
  public static void main(String[] args) {
    int number = 12;
    switch(number % 3){
      case 0:
        System.out.println("3で割り切れます");
        break;
      case 1:
        System.out.println("3で割ると1余ります");
        break;
      case 2:
        System.out.println("3で割ると2余ります");
        break;
    }
    
  }
}
```
C言語でTA-Libを使う

# C言語でTA-Libを使う

[TA-Lib](http://ta-lib.org/)は簡単にテクニカル分析ができるライブラリです。Pythonで使うとすごく便利ですが、実行の速度を追求する場合はC言語で使うことがあるかもしれないので、C言語でTA-Libを使ってみました。

# インストール
Macの場合はHomebrewでインストールできます。

```
$ brew install ta-lib
```

# ドキュメント
[公式のドキュメント](https://ta-lib.org/d_api/d_api.html)がありますが、若干読みづらいかもしれません。
使えるfunctionsとdefinesは [ta_func.h](https://github.com/stoni/ta-lib/blob/master/include/ta_func.h)を参照してください。
（公式ドキュメントのリンクは無効になってるので、githubで適当に拾いました）

# include
`<ta-lib/ta_libc.h>`をincludeすると使えます。

# コンパイル
コンパイルするときは、 `-lta_lib`をつける必要があります。

```
gcc -o sample sample.c -lta_lib
```

# 実装

```c:sample.c
#include <stdio.h>
#include <ta-lib/ta_libc.h>

int main(void) {

  // 計算する元の数値
  const double data[50] = 
  {105.68, 93.74, 92.72, 90.52, 95.22, 100.35, 97.92, 98.83, 95.33,
   93.4, 95.89, 96.68, 98.78, 98.66, 104.21, 107.48, 108.18, 109.36,
   106.94, 107.73, 103.13, 114.92, 112.71, 113.05, 114.06, 117.63,
   116.6, 113.72, 108.84, 108.43, 110.06, 111.79, 109.9, 113.95,
   115.97, 116.52, 115.82, 117.91, 119.04, 120, 121.95, 129.08,
   132.12, 135.72, 136.66, 139.78, 139.14, 139.99, 140.64, 143.66};

  // (結果)ボリンジャーバンドの上のレンジ
  double upper[50];

  // (結果)ボリンジャーバンドの下のレンジ
  double lower[50];

  // (結果)移動平均線
  double middle[50];

  // ボリンジャーバンドの期間 
  int time_period = 20;

  // シグマ値
  int upper_sigma_num = 2;
  int lower_sigma_num = 2;

  // 移動平均線の種類
  TA_MAType ma_type = TA_MAType_SMA;

  // 結果が始まるindex
  // time_periodは20なので、19から始まる
  int res_offset;

  // 結果の数
  int res_count;

  // Ta-libを初期化
  TA_RetCode res = TA_Initialize();
  if(res != TA_SUCCESS) {
    printf("TA_Initialize error: %d\n", res);
    return -1;
  }

  // ボリンジャーバンドを算出
  res = TA_BBANDS(
    0,  // 開始index
    49, // 終了index
    data,
    time_period,
    upper_sigma_num,
    lower_sigma_num,
    ma_type,
    &res_offset, // ポインタ
    &res_count,  // ポインタ
    upper,
    middle,
    lower
  );

  if (res != TA_SUCCESS) {
    printf("TA_BBANDS failed: %d\n", res);
    return -1;
  }

  // 結果をprint
  printf("id\tupper\tmiddle\tlower\n");
  for(int i = 0; i < res_count; i++) {
    printf("%d\t%.2lf\t%.2lf\t%.2lf\n",
           res_offset + i,
	   upper[i],
	   middle[i],
	   lower[i]);
  }

  // Ta-libの終了処理
  res = TA_Shutdown();
  if(res != TA_SUCCESS) {
    printf("TA_Shutdown error: %d", res);
    return -1;
  }

  return 0;
}
```

# 結果
```
id	upper	middle	lower
19	111.50	99.88	88.26
20	111.17	99.75	88.33
21	113.65	100.81	87.98
22	115.07	101.81	88.55
23	116.00	102.94	89.88
24	117.29	103.88	90.47
25	119.31	104.74	90.18
26	120.76	105.68	90.60
27	121.55	106.42	91.30
28	121.37	107.10	92.83
29	120.66	107.85	95.04
30	120.16	108.56	96.96
31	119.61	109.31	99.01
32	118.96	109.87	100.78
33	118.29	110.63	102.98
34	118.61	111.22	103.83
35	119.20	111.67	104.15
36	119.61	112.06	104.50
37	120.34	112.48	104.63
38	121.01	113.09	105.17
39	121.76	113.70	105.64
40	121.90	114.64	107.38
41	124.96	115.35	105.74
42	128.30	116.32	104.35
43	132.00	117.46	102.92
44	135.25	118.59	101.92
45	138.73	119.69	100.65
46	141.58	120.82	100.06
47	144.22	122.13	100.05
48	146.32	123.72	101.12
49	148.53	125.48	102.44
```

# 結論
pythonよりは実装は少し面倒ですが、難しくはなかったと思います。
Git のブランチを学ぶ

[Learn Git Branching](https://k.swd.cc/learnGitBranching-ja/)

初心者は視覚的にも操作的にもここが一番よいです。自分が操作するとどうなるのか？というのが凄くわかりやすいし、自分でコマンドを打つのでドキュメントを読むだけより覚えやすいです。

ずっと英語版しかないと思っていましたが、日本語版もありました。自動翻訳みたいな日本語ですが問題なく読めるので最強です。

## 少し使ってみる

Welcome ページはこんな感じ。右ボタンを選択して進めましょう。

[![Image from Gyazo](https://i.gyazo.com/7adcf652ab638e53ce63d78dd000ce6c.png)](https://gyazo.com/7adcf652ab638e53ce63d78dd000ce6c)

カリキュラムが出てきました。 **まずはここから の 1** をやってみようと思います。

[![Image from Gyazo](https://i.gyazo.com/9a715bb33c1611b55e0294e9ea807cd0.png)](https://gyazo.com/9a715bb33c1611b55e0294e9ea807cd0)

こんな感じで何を学べばよいのか説明が出てきます。

[![Image from Gyazo](https://i.gyazo.com/d82d080817278f0f842299a897622dc2.png)](https://gyazo.com/d82d080817278f0f842299a897622dc2)

[![Image from Gyazo](https://i.gyazo.com/dde0d2ea9cc742fc4f71b53fd4b32e24.png)](https://gyazo.com/dde0d2ea9cc742fc4f71b53fd4b32e24)

[![Image from Gyazo](https://i.gyazo.com/c4cc294e76af3c2be7f66220aa0a3f21.png)](https://gyazo.com/c4cc294e76af3c2be7f66220aa0a3f21)

それではカリキュラム通りに、2 回 Commit をしてみます。画面左側がコマンドのログで、左下がコマンドを打つ部分です。

[![Image from Gyazo](https://i.gyazo.com/af4208ec8c7962a02953bc45e3ebb145.gif)](https://gyazo.com/af4208ec8c7962a02953bc45e3ebb145)

クリアするとチェックマークが付きます。こんな感じでわかりやすく学んでいくことが可能です。

[![Image from Gyazo](https://i.gyazo.com/ca874221dfea0665fb41438804053000.png)](https://gyazo.com/ca874221dfea0665fb41438804053000)

## まとめ

個人的には無料で学べる Git のサービスとしては優秀だと思います。
カリキュラム以外にもデモがあったり、自由にコマンドを打てるので、これをするとどんな感じになるのだろう？みたいなコマンドの確認にも使えると思います。

それと Branch を全面的に押しているので少し分かりづらいですが右下にメニューがあります。 Level を選択したり Reset も出来るので、間違えたときは右下を開くということを覚えておけば学習がスムーズに進むと思います。

最近の IDE やエディターなどは GUI で Git 操作がかなり出来るので、コマンドを好きで打つ人は多くないのかもしれませんが、いざというときや特殊な操作がしたい状況にも対応できるようにコマンドを学んでみてはいかがでしょうか？
三項演算子

学習を進めていて、三項演算子の文法がなかなか覚えられなかったので、ノートにまとめておきます。

```ruby
def show_post
 last_post = posts.last
    if last_post.present?
      last_post.text? ? last_post.text : '画像が投稿されています'
    else
      'まだ投稿はありません'
    end
  end
```
↓この部分を「三項演算子」という.

```ruby
last_post.text? ? last_post.text : '画像が投稿されています'
```

文法は、以下の通り。

```ruby
条件式 ? trueの時の値 : falseの時の値
```
上記の文では、

`条件式:もしlast_postが存在していたら？
trueの時の値:last_post.text
falseの時の値：'画像が投稿されています'というテキスト
`
となっています。
最初の文をifを用いて書き直すとこうなります。

```ruby
def show_post
    if (last_post = posts.last).present?
      if last_post.text?
       last_post.text
      else
        '画像が投稿されています'
      end
    else
      'まだ投稿はありません。'
    end
end
```
使いこなすと色々記述が簡単に書けそうですね＾＾
SIGNATEコンペ　【練習問題】アワビの年齢予測

**追記**
2019/12/23：結果の更新

# はじめに
今後、勉強の一環としてkaggleやSIGNATEのコンペに参加しようと思い、アウトプットの目的でQiitaに内容を投稿したいと思います。

今回はSIGNATEのコンペ、[【練習問題】アワビの年齢予測](https://signate.jp/competitions/106)を行いました。
文字通り練習問題なので、賞金等は特にないです。

# 内容
成果物としては、以下のGitHubにJupyterNotebook形式で残してあります。
[https://github.com/varusvarus/Qiita/blob/master/awabi-qiita.ipynb](https://github.com/varusvarus/Qiita/blob/master/awabi-qiita.ipynb)

基本的な流れとしては、データの前処理⇒モデルの構築といったオーソドックスなものですが、特徴的なやったこととしては以下の４点です。

- 目的変数'Rings'の対数変換
- 新しい特徴量の作成（面積や、面積当たりの各重量）
- モデルはxgboostを使用
- モデルのハイパーパラメータの最適化として、optunaの使用

最適化したハイパーパラメータですが、learning_rateとmax_depthで他はデフォルト通りです。

# 結果
SIGNATEに投稿した結果、2019年12月22日時点で以下のようになりました。

- 順位：81位（193人中）
- スコア(RMSE)：2.11426

あまりいい順位とは言えない結果となりました、、、

**追記**
最後testの'Rings'の値を逆対数変換で出力するときに、今まではその値を整数に直していました。
今回、試しに整数に直さないまま（つまりfloatのまま）結果として投稿したところ、順位が少し上がりました。（2019/12/23時点）

- 順位：59位（193人中）
- スコア(RMSE)：2.09971

うーん、たまたまかな、、、

# 参考にしたサイト
[https://qiita.com/tomo_20180402/items/a519fcc0aba6de03824e](https://qiita.com/tomo_20180402/items/a519fcc0aba6de03824e)
[https://www.kaggle.com/ragnisah/eda-abalone-age-prediction](https://www.kaggle.com/ragnisah/eda-abalone-age-prediction)

# さいごに
今回のことに関して疑問点や改善点がございましたら、気軽にコメントしてください！

また、コンペの勉強にあたって、こうしたほうがいいよというアドバイスがございましたらよろしくお願いしますm(__)m
[Red言語]on-keyイベントのeventにセットされている値の一覧

毎回忘れて確認するので、ほぼ自分用メモ
（ドキュメントにPRすればいいのだが横着）

# eventにセットされているword

|    word    |    説明（推測含む）    |
|:----------:|:------------------:|
| alt-down?  | Altキーが押されているか |
| aux-down?  | 不明 |
| away?      | 不明 |
| ctrl?      | Ctrlキーが押されているか |
| down?      | 不明 |
| face       | 不明（noneだった） |
| flags      | 不明 |
| key        | 押されたキー(char!型) |
| mid-down? | 不明 |
| offset | たぶんキーが発生した時のキャレット位置？ |
| picked | 不明 |
| shift? | Shiftキーが押されているか |
| type | たぶん固定で"key"が入る |
| window | 不明（noneだった） |

## 確認バージョン

Red 0.6.4 for Windows built 13-Dec-2019/15:37:32+09:00 commit #134a2b0
Codeforces Round #609 (Div. 2)（Bまで）

## Div2A. Equation

差が $n$ であるような2数を答える。差が $n$ のもので順番に素因数分解していこうかと一瞬思いましたが，よく考えるとギャグでした。$9n$ と $8n$ を答えてやれば差が $n$ でいずれも合成数になってくれます。


```python:python
n = int(input())
print(9*n,8*n)
```

```cpp:C++
#include<bits/stdc++.h>
int main(){
    int n;
    std::cin >> n;
    std::cout << 9*n << " " << 8*n << std::endl;
}
```

## Div2B. Modulo Equality

まず問題文が分かりづらいです。置換 $p_n$ を用いてどうこう……と書いてありますが，要するに

> 数列 $\{a_i\}$ と $\{b_i\}$ が与えられる。数列 $\{a_i + x\ (\mathrm{mod}\ m)\}$  が $\{b_i\}$ を **適当に並び替えたもの** と一致するような最小の $x$ を答えよ。

という問題です。

さて，まず脳死で思いつくこととして $x$ を全探索したいという気持ちになるでしょう。$\mathrm{mod}\ m$を考えるので $x$ として $m$ を越える分は同一視できます。しかしながらそれでも $m$ の範囲が$1\leq m \leq 10^9$なので，この範囲内をすべて探索するのは時間的に不可能です。

他の制約として，$1\leq n\leq 2000$ すなわち数列 $a$ と $b$ のサイズが2000までというものがあります。じつはこれが大切で，$x$ をすべて探索するという方針はそのままに調べる範囲を少なくすることができます。`a` に x 加算したものと `b` を適当に並び替えたものが一致するためには，**`a[i]+x` の要素の少なくとも1つは`b[0]`と一致**しなければいけません。

そこで，`a`のどれが`b[0]`と対応するかを全探索して，そのうち条件を満たす最小のものを出力してあげましょう。具体的には下のコードを参考にしてください。

```python:Python
import sys
input = sys.stdin.readline

def main():
    n, m = map(int, input().split())
    a = list(map(int, input().split()))
    b = list(map(int, input().split()))
    b.sort()
    answer = []
    for i in range(n):
        x = (b[0] - a[i]) % m  # b[0]とa[i]が一致するようにxを決める
        tmp = list(map(lambda num: (num + x) % m, a))
        tmp.sort()
        if tmp == b:
            answer.append(x)
    print(min(answer))
    return

if __name__ == '__main__':
    main()
```

```cpp:C++
#include <bits/stdc++.h>
using i64 = int_fast64_t;
#define repeat(i, a, b) for(int i = (a); (i) < (b); ++(i))
#define rep(i, n) repeat(i, 0, n)

void solve() {
    int n, m;
    scanf("%d %d", &n, &m);
    std::vector<int> a(n), b(n);
    rep(i, n) scanf("%d", &a[i]);
    rep(i, n) scanf("%d", &b[i]);
    std::sort(begin(b), end(b));
    std::vector<int> ans;
    rep(i, n) {
        int x = (b[0] - a[i] + m) % m;
        std::vector<int> tmp(n);
        std::transform(begin(a), end(a), begin(tmp), [&](int num) { return (num + x) % m; });
        std::sort(begin(tmp), end(tmp));
        if(tmp == b) {
            ans.emplace_back(x);
        }
    }
    std::sort(begin(ans), end(ans));
    printf("%d\n", ans[0]);
}

int main() {
    solve();
    return 0;
}
```
go langでslackと連携 api

```go:main.go
package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
)

var (
	// change token
	IncomingUrl string = "https://hooks.slack.com/services/hogehoge/hogehoge"
)

type Slack struct {
	Text       string `json:"text"`
	Username   string `json:"username"`
	Icon_emoji string `json:"icon_emoji"`
	Icon_url   string `json:"icon_url"`
	Channel    string `json:"channel"`
}

func main() {
	arg := "nekosasa"

	params, _ := json.Marshal(Slack{ //json形式のbinary 数字がいっぱい並んでる

		fmt.Sprintf("%s", arg),
		"arigatou",
		"dossy_bot",
		"http://www.icons101.com/icons/66/NuoveXT_by_Alexandre_Moore/128/slackware.png",
		"#test"})
	//paramsがjson形式の[]uint8のbinary string(params)で中身は見れる
	resp, _ := http.PostForm( //postを整形して実行まで行う
		IncomingUrl,
		url.Values{"payload": {string(params)}},
	)

	body, _ := ioutil.ReadAll(resp.Body)
	//ioutil.Readallはerrがないか確認するもの
	defer resp.Body.Close()
	//respはreadしたらちゃんとcloseすべきである

	println(string(body)) //err == nilならreturn ok
}

```
ほぼ自分用
シェルスクリプトの三項演算子で注意するべきこと

# はじめに
シェルスクリプトは本来、三項演算子というものがありません。
三項演算子のような書き方はできるのですが、注意しないとハマって時間を溶かす可能性があるので気をつけましょう。

実行環境: Bash

### TL;DR
シェルスクリプトの三項演算子もどきで、`&&`の次に書くコマンドは必ず成功するコマンドを書くべきです。
失敗する可能性があるなら、`$(your_command;:)`のように書き換えるか、素直にif文を使いましょう。

# 三項演算子っぽい書き方
繰り返し言いますが、シェルスクリプトには三項演算子はありません。
三項演算子もどきです。
これを下のように書くことができます。

```bash
command1 && command2 || command3
```

注意すべきポイントは、`&&`や`||`という演算子です。

# `&&`、`||`の動作
`&&`と`||`の動作は下の通りです。

```bash
&& : 直前に実行されたコマンドが成功したとき、次のコマンドを実行
|| : 直前に実行されたコマンドが失敗したとき、次のコマンドを実行
```
<font color="Red">直前に実行されたコマンド</font>が成功したかどうかが重要なのです。
では、次の例を見てみましょう。

# 例

```bash
true && false || echo "failed"

# 実行結果：
# failed
```
`true`コマンドは成功ステータスを返す(=必ず成功する)コマンド、
`false`コマンドは失敗ステータスを返す(=必ず失敗する)コマンドです。

これを実行すると、failedと表示されます。
１つ目のコマンドが成功しているにも関わらずです。
これは、`&&`や`||`が<font color="Red">直前に実行したコマンド</font>の終了ステータスを見ていることに由来します。

上の例では、`true`は成功するので、次の`false`も実行されますが、`false`は失敗ステータスを返してしまうので、`||`の次のechoも実行されてしまうのです。

# 対策
上に示したように、`&&`、`||`は直前のコマンドが成功したかどうかで判定しているので、シェルスクリプトの三項演算子もどきは、C言語などの三項演算子とは根本的に動作が違います。
２つ目のコマンドが失敗したときは3つめのコマンドも実行されてしまうので、注意が必要です。
これを鑑み、正しく動作させるためには、２つ目のコマンドは必ず成功させないといけません。
失敗する可能性があるコマンドは入れないようにしましょう。

失敗する可能性があるコマンドをどうしても使う場合は、次のように書けば大丈夫かと思います。

```bash
command1 && $(command2 ; true) || command3
または
command1 && $(command2;:) || command3
```
失敗しそうなら成功ステータスを返せばいいじゃない、とマリーアントワネットになった気持ちで上のように書き換えましょう。
`:`コマンドは`true`と同じように成功ステータスを常に返します。よって、２つ目のコマンドが失敗したとしても、３つ目のコマンドは実行されずに済みます。
(ただし、このような対策は可読性が低くなるのが難点)

# おわりに
シェルスクリプトの三項演算子もどきは気をつけないと想定外の動きをするので気をつけましょう。
個人的には、if文を使えばこういった間違いが無くなるのでif文を使ってます。
AutoFixture: C# でテストデータを自動的に作ってくれるライブラリの紹介

テストデータを手作業で全て作成している人はいませんか？そんなあなたにオススメなライブラリのご紹介です。

使用用途は主に Moq の戻りデータを自動生成したいときや、パラメーターを自動生成したいとき、他には Database のデータを自動生成したいときにも使えます。

## Package Install

Visual Studio の Package Manager 画面か、 Command を使って Install できます。

[![Image from Gyazo](https://i.gyazo.com/a33ed086cd0b7dfe70e1ad48c8a78fbd.png)](https://gyazo.com/a33ed086cd0b7dfe70e1ad48c8a78fbd)

Package Manager

```
Install-Package AutoFixture -Version 4.11.0
```

.NET CLI

```
dotnet add package AutoFixture --version 4.11.0
```

## 試しに使ってみる

モデルのテストデータを作ってみます。 MyModel を用意しました。

```csharp
public class MyModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTimeOffset CreatedAt { get; set; }
    public MyInnerModel MyInner { get; set; }
}

public class MyInnerModel
{
    public string[] Notes { get; set; }
}
```

AutoFixture を使って MyModel を作ってみます。

```csharp
[Fact]
public void MyModelTest()
{
    var fixture = new Fixture();
    var myModel = fixture.Create<MyModel>();

    Assert.NotNull(myModel);
}
```

Breakpoint を設定して中身を見てみるとこんな感じで自動的に設定されています。

[![Image from Gyazo](https://i.gyazo.com/2ca0486c5003bb5a187baa9c10fa674e.png)](https://gyazo.com/2ca0486c5003bb5a187baa9c10fa674e)

## AutoFixture で出来ること

- 自動設定する値をカスタマイズ
- DataAnnotation を自動読み込み
  - E.g. StringLength(3) が付与されている場合、自動的に 3 文字のデータが設定される。
- Entity Framework の小テーブルデータを自動作成
  - きちんと外部キーの設定をしている場合のみ。
  - 親テーブルを fixture.Create したあとに Add すれば子テーブルのデータも全部入る。
  - 可能なら DB First (.edmx) より Code First を使ったほうがよいです。

## リンク

Document: [Cheat Sheet · AutoFixture/AutoFixture Wiki](https://github.com/AutoFixture/AutoFixture/wiki/Cheat-Sheet)

NuGet Gallery: [NuGet Gallery | AutoFixture 4.11.0](https://www.nuget.org/packages/AutoFixture)

GitHub repository: [AutoFixture/AutoFixture: AutoFixture is an open source library for .NET designed to minimize the 'Arrange' phase of your unit tests in order to maximize maintainability. Its primary goal is to allow developers to focus on what is being tested rather than how to setup the test scenario, by making it easier to create object graphs containing test data.](https://github.com/AutoFixture/AutoFixture)

## 似たような機能を持つライブラリ

こっちも使ってみましたが、個人的には AutoFixture のほうが好きでした。

Bogus: [bchavez/Bogus: A simple and sane fake data generator for C#, F#, and VB.NET. Based on and ported from the famed faker.js.](https://github.com/bchavez/Bogus)
PHPでpost_max_sizeやupload_max_filesizeの設定がini_set()で反映されない場合

サーバー上でPHPを利用していると、PHPの設定を`php.ini`を書き換えることなく、
特定のファイルや、ディレクトリないだけで変更したい場合がたまにあります。

つい先日も、自作のPHPファイルだけで有効になるよう、
`post_max_size`と`upload_max_filesize`の値を`ini_set`で値を変更したところ、値が反映されていない・・

`php_info()`で設定値を確認しても、やっぱり変わっていなかったので、
ちょっと調べたところ[PHPマニュアル](https://www.php.net/manual/ja/configuration.changes.modes.php)にがっつり書いていました。

PHPの各ディレクティブ(設定値)は、そのディレクティブのモードによって、
何処で設定出来るかが決まっているそうです。
PHPディレクティブとモードの一覧は[こちら](https://www.php.net/manual/ja/ini.list.php)

`post_max_size`や`upload_max_filesize`は、
モードが<b>PHP_INI_PERDIR</b>だったので、ini_setでの設定変更が不可だったようです。

以下はそのモードについて。

<h3>PHP_INI_USER</h3>
PHPマニュアルを確認しても該当するディレクティブがないため気にしなくて良さそうなモード
PHP5以前は使われていたらしく、以下の３つのみ設定変更可能なモード
・自作のphpファイルないでini_setコマンドを使って設定変更
・[Windowsレジストリから設定変更](https://www.php.net/manual/ja/configuration.changes.php#configuration.changes.windows)
・.user.iniから設定変更(PHP5.3以降の場合)

<h3>PHP_INI_PERDIR</h3>
php.ini、.htaccess、httpd.conf、.user.iniでのみ設定変更

<h3>PHP_INI_SYSTEM</h3>
php.ini、httpd.confでのみ設定変更可能

<h3>PHP_INI_ALL</h3>
自作PHPファイルでini_set、.user.ini、.htaccess、php.ini、httpd.confのどれでもも設定可能

今回の場合、`post_max_size`や`upload_max_filesize`を変更するようの
.htaccessを作成して、自作PHPファイルが格納されているディレクトリに配置したところ、
そのディレクトリだけ設定が反映されてることが確認できました。

<h2>まとめ</h2>

昔、同じ理由で変更出来なかった事をすっかり忘れて、またハマってしまったため、
自分への戒めとして記事に残しときます。
convert m3u8 to mp4

ストリーミングで動画を配信してるサービスでたまに見かけるm3u8をmp4ファイルに変換した時のメモ

## m3u8ファイルってどんなの?
こんなの
https://www.lifewire.com/m3u8-file-2621956

## convert m3u8 to mp4

ffmpeg を使います

```
ffmpeg -protocol_whitelist "file,crypto,http,https,tcp,tls"  -i "<ファイル名.m3u8 or URL>" -c copy -bsf:a aac_adtstoasc "<出力ファイル名.mp4>" 
```

### ディレクトリ内の全m3u8ファイルを変換する

```
for m3u8 in *.m3u8; ffmpeg -protocol_whitelist "file,crypto,http,https,tcp,tls"  -i "$m3u8" -c copy -bsf:a aac_adtstoasc "${m3u8%%.*}.mp4"
```
Elasticsearchでヒットした部分に色を付けたい

[highlight](https://www.elastic.co/guide/en/elasticsearch/reference/7.5/search-request-body.html#request-body-search-highlighting)という機能で実装できます。

https://qiita.com/kaibadash@github/items/4a587336166c6096f835 ここで作ったTwitterのデータで試してみます。

## クエリ
```json
{
  "query": {
    "bool": {
      "should": [
        {
          "match_phrase": {
            "full_text": {
              "query": "犬"
            }
          }
        }
      ]
    }
  },
  "highlight": {
    "fields": {
      "full_text": {}
    }
  }
}
```

日本語の設定をちゃんとしていないのであんまりなのですが…。
1つポイントがありまして、当然と言われればそうなのですが、ハイライト対象は検索しないと設定できません。
例えば、ついでにユーザ名にもハイライトを付けたいとして、 `highlight` だけ追加してもだめです。

## 検索結果

```sh
curl -X POST -H "Content-Type: application/json" http://localhost:9200/tweet20191222/_search\?pretty -d @search.json | jq .hits.hits[].highlight.full_text
```

```json
[
  "@waketi <em>犬</em>、耳ペタ"
]
[
  "<em>犬</em>シュール。塀の上から顔を出す<em>犬</em> https://t.co/Lz8jnRqtUu"
]
[
  "@waketi 賢い<em>犬</em>リリエンタール"
]
[
  "<em>犬</em>の散歩コースなうー。もう<em>犬</em>はいないけども。"
]
[
  "@WG_koro 当方無<em>犬</em>。雑種か大型<em>犬</em>希望。一先ず<em>犬</em>合わせして音楽性を確認したく。"
]
[
  "@yujinko <em>犬</em>プレイでした"
]
[
  "@waketi <em>犬</em>だけにワン"
]
[
  "@BYS777 <em>犬</em>のやつも！"
]
[
  "<em>犬</em>がハンカチ食った＞＜"
]
[
  "@ipusiron <em>犬</em>かわいい"
]
```

雑にHTMLにしてみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21799/4b3e4412-791b-a15f-ab18-51eafc038fc9.png)


## その他、気をつける点

`highlight` はしばしばパフォーマンスが悪くなります。
ハイライト対象のオフセットを制限するなどチューニングが必要になることもあります。

https://discuss.elastic.co/t/highlighting-takes-long-time-for-large-documents/8448

## まとめ

- HTMLが得られるのでそれを使うことになる
- Elasticsearchで探してDBから再取得、というケースだと困る