OmniAICreator/Qiita-1.07M huggingface dataset:
Laravel 日付データから年度を取得し配列に入れる

## やってみた


**`date`カラムから年度に変換し、重複を削除、値（年度）を降順ソートしました。**
※`date`カラムに存在する年度のみ取得します。

一般的な年度（4月1日～翌年3月31日までを年度）とします。
※2019年を例にすると、2019年4月1日から2020年3月31日までのことを指します。

```php:StatusContoller.php
$dates = Status::pluck('date');
foreach ($dates as $date) {
  $array[] = $date->subMonthsNoOverflow(3)->format('Y');
}
$years = collect($array)->unique()->sort()->reverse()->values();

dd($years);
```

## sort()について
最初、`->values()->sortByDesc('date');`　でできるかな～と思ってのですが下記のように…
**`dd($years);`の取得結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308965/3742bf37-623f-c6c4-1c92-9b49df547a32.png)
↑　求めてるソートにならない！なんでだ～～と日本語ドキュメントを見て試行錯誤したのですが、降参！！！

**@mpywさんに相談し教えていただきました（いつも有難うございます。）！
値（年度）を降順で表示！
`->sort()->reverse()->values();`**


**・pluckの時点で中身取り出している
・sortBy は2次元配列想定してるけど既に1次元配列になってる
・生PHPの場合はsort関数に対応してrsort関数とかあったりはする
・collectionは逆順ソート用のメソッドがないので，昇順ソートしてから配列を逆に並べてる**

とのことでした。。
これで求めてる値（年度）のソートになりました！👏
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308965/81a9951f-7495-5557-dbc3-5f24a7a9d04a.png)

ちなみにどうしても`sortByDesc`を使うのであれば、pluckの前につけると使えるみたいですが、
`sortByDesc('date')->pluck('date')`
メモリ消費するのであまりおすすめできないそうです！

## map()を使った方法
**コメントより、kiyoamiさんに教えていただきました。**

```php:StatusContoller.php

$years = Status::pluck('date')->map(function ($date) {
     return $date->subMonthsNoOverflow(3)->format('Y');
})->unique()->sort()->reverse()->values();

dd($years);
```

## クエリビルダを使った方法
**kiyoamiさんに教えていただきました。度々ありがとうございます！**
**こちらは年度ではなく、年（2020年➡2020年1月1日～2020年12月31日まで）を取得します。**


```php:StatusContoller.php

$years = Status::selectRaw('year(`date`) `yyyy`')->distinct()->groupBy('date')->pluck('yyyy');

dd($years);
```


##プルダウンに年度を表示させたい場合

```php:index.blade.php
    <select name="year">
        @foreach($years as $key => $name)
        <option value="{{ $name }}"{{old('year', $year) == $name ? 'selected' : ''}}>{{ $name }}</option>
        @endforeach
    </select>
```

ひとまずこれで年度を取得し配列に入れて表示する、までは完成です。

##次は年度からデータを取得する場合

例えば年度の絞り込みがあったときです。
Statusテーブルの`date`カラムから、（任意）年の4月1日～翌年3月31日のデータを取得します。


```php:StatusContoller.php

$year = $request->input('year');
$status = Status::query();

if (!empty($year)) {
     $startAt = CarbonImmutable::createMidnightDate($year, 4, 1);
     $endAt = $startDate->day(1)->addMonths(11)->endOfMonth();
     $status->whereBetween('date', [$startAt, $endAt]);
 }
```

`$year`に`2015`が入ってきた場合、`$startAt`と`$endAt`は以下となります。

`dd($startAt);`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308965/056f6e7c-a804-2ed2-fec1-3b7f5fa47fb5.png)

`dd($endAt);`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308965/5184666a-5017-7db7-8bea-d157add26e37.png)

## 参考文献

この記事は以下の情報を参考にしました。

- [[#php]年度を取得する関数](https://qiita.com/sshojiro/items/23aa3abc821c2b8c1de4)
- [全217件！Carbonで時間操作する実例](https://blog.capilano-fw.com/?p=867#createMidnightDate)
PHPで年度を取得する～DateTimeとCarbon～

##やりたいこと
DateTimeクラスとCarbonライブラリそれぞれ、任意の日付から**年度**を取得します。

**一般的な年度（4月1日～翌年3月31日までを年度）とします。**
※2019年を例にすると、2019年4月1日から2020年3月31日までのことを指します。

## DateTimeクラス

```php
$date = new DateTime('2020-03-1');
dump($date->modify('-3 month')->format('Y')); // 2019
```


## Carbonライブラリ

```php
use Carbon\CarbonImmutable;

$carbon = new CarbonImmutable('2020-03-1');
dump($carbon->subMonthsNoOverflow(3)->format('Y')); // 2019
```


間違ってる記載がありましたら教えていただけると嬉しいですm(__)m。

## 参考文献

この記事は以下の情報を参考にしました。

- [[#php]年度を取得する関数](https://qiita.com/sshojiro/items/23aa3abc821c2b8c1de4)
やっとできた、ReactにESLint + Prettier + Stylelintを導入するために参考にした記事

# はじめに
JavaScriptにおけるコードチェック・自動整形はESLintとprettierを組み合わせるのが主流らしい。

自分のReactアプリにも導入しようと思い色々ググったが、いろんな情報がありすぎてわからなかった。これはESLintとprettierを組み合わせた導入の仕方が一通りじゃないことに起因するようで、拾い集めた断片的な情報でやろうとするとうまくいかないようだ。

今回は、これを参考に導入したらうまくいったという記事をまとめて紹介（2020年1月時点）。

# ESLint概要
さすがにコピペだけで済ませるとまずいと思い、まずはある程度仕組みを理解しようと読んだのがこちら。
[Step by Stepで始めるESLint](https://qiita.com/howdy39/items/6e2c75861bc5a14b2acf)
かなりわかりやすく設定ファイルの書き方を説明してくれている。

もう１つ、多分ESLintについて調べるとすぐに目に留まるのが以下の記事だと思う。
[Prettier 入門 ～ESLintとの違いを理解して併用する～](https://qiita.com/soarflat/items/06377f3b96964964a65d)
これの通りに導入しようとするもダメだった。さすがに情報が古すぎるのでPrettierとESLintの概要を掴む目的で読むのがいい。

# 導入
ESLint + Prettier + Stylelintを実際に導入する上で参考にする記事はこれ一つでOK。指示通りにやったらいけた。
[VS CodeにPrettier・ESLint・Stylelintを導入してファイル保存時にコードを自動整形させる方法](https://wemo.tech/3307)

# 自分の設定
上記記事をベースに作った最終的な設定ファイルを貼っておく。もし紹介した記事通りにやってもダメだったら参考までに。

```.eslintrc.js
module.exports = {
    extends: ['google', 'plugin:prettier/recommended'], // Googleのコーディング規約をベースにする
    plugins: ['react'], // React関係のルールを指定するのに必要
    parser: 'babel-eslint', // JSXとかでエラー出るのを回避。env の es6:true もこれにより不要になる
    parserOptions: {
        sourceType: 'module', // import などを使うときに必要
        ecmaFeatures: {
            experimentalObjectRestSpread: true, // 非推奨項目も注意してくれる？（あんまよくわかってない）
            jsx: true,  //JSX を使うときに必要（ reactプラグインいれてるからいらないかも...？ ）
        },
    },
    rules: {
        'no-var': 'error', //varを許可しない
        'no-console': 'off', // console.logがあってもエラーにしない
        'require-jsdoc': 'off', // Docコメントなくてもエラーにしない
        'valid-jsdoc': 'off', // Docコメントの書き方についてとやかくいわせない
        camelcase: ['warn', { properties: 'never' }], // オブジェクトのキーはキャメルじゃなくてよい
        'react/jsx-uses-vars': 1, // これを使うとJSXで使ってる変数がno-useとして認識されるのを防げた
        "react/jsx-uses-react": 1, //Reactをimportしてもno-var-useエラーが出ないように
    },
};

```

```.prettierrc.js
module.exports = {
    tabWidth: 4, //インデントのスペース数
    singleQuote: true, //シングルクォートに統一
    trailingComma: 'es5', //末尾のカンマをどうするか: es5に準拠させる。
  };
```

```.stylelintrc.js
module.exports = {
    plugins: ['stylelint-scss', 'stylelint-order'], // stylelint-order を使う
    extends: [
      'stylelint-config-standard',  //ベースとなるルール
      'stylelint-prettier/recommended',
    ],
    rules: {
      'order/properties-alphabetical-order': true, //ABC順に並べる
      'at-rule-no-unknown': null, //scss関係のやつ
      'scss/at-rule-no-unknown': true, //scss関係のやつ
    }
  };
```
#Vue で子コンポーネントから親コンポーネントのメソッドを呼ぶ

`this.$parent.メソッド名`

```js
    methods: {
      setFoo(something) {
        this.$parent.setBar(something)
      }
    }
```

おそらくこのような使い方は多くの場合不適切と思われるが

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2970








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Terminal.appのデフォルトのショートカットキーを無効化する

# td;tl
macにバンドルインストールされているターミナルエミュレータ**Terminal.app**ですが,
`⌘ + d` の画面分割とか `⌘ + w` のWindowを閉じるショートカットキーとか誤爆が辛いし使わないので
無効化したかったんですけど, ざっと調べた限り日本語の記事が見つからなかったので方法を纏めました.

# ⌘ + d(画面分割)を無効化
どれも同じなんですけど, 今回は一例として上記の`⌘ + d` を無効化していきます. 
筆者の場合tmuxのprefix周りで誤爆が多いので殺します.

Terminal.appを開き上のメニューバーから殺したいショートカットのコマンド名を確認します.
言語設定が英語になっているので `Split Pane` ですが, 日本語設定の場合はそのコマンドを確認してください.
<img width="709" alt="Screenshot_2020-01-27 19.54.50_RhF6X6.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270408/39480504-a260-c8cd-2ffe-4c842b2f6b82.png">

macの設定から `キーボード` -> `ショートカット` と開き,`+` から先述したコマンドに新しいキーショートカットを上書きすることで無効化します.
(英語の場合大文字小文字考慮します.)
Terminal.appは`Application/Utilite(ユーティリティ)/Terminal.app`に入っているので探してみてください.
<img width="780" alt="Screenshot_2020-01-27 19.57.02_r24znL.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270408/46f360f4-5a1e-da63-4e2e-9b652273aa98.png">

## 参考文献
[keyboard - Disable Command-W in the terminal - Ask Different](https://apple.stackexchange.com/questions/44412/disable-command-w-in-the-terminal)
初心者によるプログラミング学習ログ 221日目

#100日チャレンジの221日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

221日目は
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>221日目<br>・Vue.jsでアプリ作成講座<br>・youtubeみながらjavascriptでtodolist作成<br>・Bootstrap使って、LP作成<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1221524881843507200?ref_src=twsrc%5Etfw">January 26, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
#Vue の router-link とは何だ？ と初心者は思った。

- アップリケーション内のリンクを生成するものらしい。
- https://example.com/ とか外部サイトのリンクは生成できないっぽい。
- 自分のサイトへのリンクを全部 https などのURL表記で書くことは愚か、絶対パスでリンクで書くより好ましいのだろうな。フレームワークの流儀に則っている分。 `<a href="/path/to/page">` 

router のルートってそういう意味ね。

以上。

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2969








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
CPUのスレッド数とメモリ容量の取得

　仕事柄、Samtoolsなど、実行時のパラメーターとしてスレッド数を記載したりするシェルスクリプトを作成する場合があるので、備忘録として、ターミナル上でのこれら情報の取得の仕方を書いておく。

##取得

```
##CPUスレッド
threads=${thread:=｀egrep -c "^processor\s:\s[0-9]+$" /proc/cpuinfo｀}
##メモリ容量
memtotal=｀grep 'MemTotal' /proc/meminfo | sed -e 's/MemTotal: *//' -e 's/ kB//'｀
memory_GB=$((memtotal/1024/1024/2))"g"

※上記の「｀」は、表記の都合上全角になっているので半角に書き直す
```
---
iOSアプリの配布方法まとめ


### はじめに

調べていくといろんな配信方法があったのでまとめてみました。

### 丸腰

| 配布方法| 詳細 |
| --- | --- |
| 実機デバッグ（開発用配布）  | 開発中のアプリを Mac と iOSデバイスを直接 USBで繋いで Xcode 経由でインストールする方法 |

### Apple Developer Program $99/年 

| 配布方法| 詳細 | 具体的なやり方 |
| --- | --- | --- |
| Ad-Hoc（評価用配布） | 限られた数のユーザーのAppleデバイスに Appを直接インストールしてもらいテストする方法<br>iPhone (年間メンバーシップあたり100台)<br>iPad (年間メンバーシップあたり100台)<br>iPod touch (年間メンバーシップあたり100台)<br>App Storeを介すことなく、URLでアプリ配布が可能。<br>Apple Developer Plogram に登録していれば追加の費用はかからない。<br>デバイス追加の都度、UDID登録、プロビジョニングファイル更新、リビルド等の作業が必要。<br>アプリの審査不要、有効期限は1年間。 | ●[S3でURLを管理し配布する方法](https://akiyoko.hatenablog.jp/entry/2014/08/23/231434)(手順がかなり多い)<br>●外部サービスの利用：[deploygate](https://deploygate.com/?locale=ja)<br>App Storeを介さずにアプリを配布することが可能。<br>iOSだけでなく、Androidにも対応。<br>無料枠だとプロフィール画面にアプリ名が表示される。有料にすると、バージョン管理の数を増やしたり、プロフィール画面の表示を切り替えられる。<br>UUID等を自力で収集しなくても自動で収集できる。<br>●[iTunesを使った方法](https://blog.kakakikikeke.com/2015/08/push-with-production-cert-in-ncmb.html#%E4%BD%9C%E6%88%90%E6%B8%88%E3%81%BF%E3%81%AEappid%E3%81%AE%E3%83%97%E3%83%83%E3%82%B7%E3%83%A5%E9%80%9A%E7%9F%A5%E3%81%AE-distribution-%E5%81%B4%E3%82%92%E6%9C%89%E5%8A%B9%E3%81%AB%E3%81%99%E3%82%8B) |
| AppStore TestFlight | AppStoreConnectへアップロードしたアプリを非公開・未審査の状態で、テスター最大25名まで配布できる方法 | https://developer.apple.com/jp/testflight/ |
| Apple Business ManagerおよびApple School Manager | ビジネスや教育機関に App の一括購入を提供する。<br>教育機関向けに割引価格で提供する。<br>特定のビジネス向けに開発したカスタムAppを非公開で配布する。<br>コードの維持と知的所有権の保持。<br>自社の従業員に専用のAppを配信することもできるようになりました。<br>特定の企業だけに App のダウンロードを許可することができます。<br>これには、自分の組織の内部で使用するために非公開の App を配信する場合も含まれます。<br>**アプリには審査が必要で、基準は公開用のレビューと同じです。** 無料配布でも有料アプリケーション契約に同意する必要があります。 | 後日追記予定 |
| AppStore（一般公開） | アプリの審査を通し、AppStoreに公開する方法<br>ユーザーはiPhone、iPad、Mac、Apple Watch、およびApple TV Appを簡単に見つけて購入し、ダウンロードすることができます。<br>売上の70%を収益として受け取れます。要件を満たしているサブスクリプションの収益は85％。<br>ホスティング費用無料。<br>Appleが世界各地の支払い処理に対応。 | ー |
| Apple以外からのMDMでの配布 | AppleStoreで公開しているアプリのみ、指定したデバイスに一括配布できる（AdhocはNG） | ー |

参考
https://developer.apple.com/jp/programs/whats-included/
[契約書の署名と更新 > 有料契約書に署名する](https://help.apple.com/app-store-connect/#/deva001f4a14)
https://support.apple.com/ja-jp/guide/apple-business-manager/apd58ba3112a/web 


### Apple Enteprise Program $299/年

Apple Enteprise Programのライセンス審査に時間がかかるのと、基準が厳しい上に公開されていない
ライセンスがあればIn-House（組織内配布）で配布できる
TreeSetの使い方

#導入
こんにちは。けちょんです。
**TreeSet使ってますか？**
私は今日初めて見ました。
類似のHashSetやTreeMapは使ったことがあるんでないでしょうか。

#TreeSetとは
重複を許さず、addするときにソートして保持してくれるクラスです。
競技プログラミングで役立ちそうな気がするクラスですね。

#使ってみる
##まず、TreeSetにaddするオブジェクトを作成

```java
class Product {
	private int id;
	private String name;

	public Product() {
	}

	public Product(int id, String name) {
		this.id = id;
		this.name = name;
	}

	public int getId() {
		return this.id;
	}

	public String getName() {
		return this.name;
	}

}
```
idとnameのフィールドと、コンストラクターと、アクセッサーを作成しました。

##次に、インスタンスを追加

```java
Set<Product> tree = new TreeSet<>();
tree.add(new Product(1, "kechong"));
tree.add(new Product(2, "me"));
tree.add(new Product(3, "you"));
for (Product product : tree) {
	System.out.print("id:" + product.getId() + ", ");
	System.out.print("name:" + product.getName());
	System.out.println();
}
```

はい、実行してみます。

```
Exception in thread "main" java.lang.ClassCastException: Product cannot be cast to java.base/java.lang.Comparable
	at java.base/java.util.TreeMap.compare(TreeMap.java:1291)
	at java.base/java.util.TreeMap.put(TreeMap.java:536)
	at java.base/java.util.TreeSet.add(TreeSet.java:255)
	at Main.main(Main.java:26)
```

エラーが出ましたね。

##どんなエラー？
ClassCastExceptionが投げられていますね。
ProductがComparableにキャストできないって怒られています。
発生場所は、TreeSetにaddしようとしたときです。

###なぜキャストしようとしているか
キャストとかしないでいいのに、、、
と、思いますが、これはTreeSetには必要なんです。

TreeSetは順序という概念を持っています。
TreeSetにaddするときに、保持する位置を定めるために順序を決める必要があります。
Productクラスを自分で作成した時に、「Productオブジェクトを比較する方法」を定めなかったためにエラーが発生しています。

##比較という概念を追加する
具体的には、Comparableインターフェースを実装します。

```java
class Product implements Comparable<Product> {
	private int id;
	private String name;

	public Product() {
	}

	public Product(int id, String name) {
		this.id = id;
		this.name = name;
	}

	public int getId() {
		return this.id;
	}

	public String getName() {
		return this.name;
	}

	@Override
	public int compareTo(Product o) {
		return this.id - o.id;
	}

}
```
はい、implementsして、compareToメソッドをオーバーライドしました。

##もう一回実行すると、、、

```
id:1, name:kechong
id:2, name:me
id:3, name:you
```
はい、良さそうですね！

#ちなみに
今回はProductクラスでComparableインターフェースを実装しました。
が、TreeSetのインスタンス化時に、コンストラクターの引数に以下のように指定することでも同様の出力となります。

```java
Set<Product> tree = new TreeSet<>(Comparator.comparing(Product::getId));
```
これはTreeSet側に比較方法を与えることで、順序を決定できるようにしています。

#まとめ
TreeSetに自作オブジェクトを追加する場合は、以下のいずれかの作業が必要
・自作オブジェクトでComparableインターフェースを実装する
・TreeSetのコンストラクター引数に比較方法を指定する
JuliaでVandermonde行列式を計算してみる

# Vandermonde行列式
以下のように定義される行列をVandermonde行列[1]といいます．

```math
A=\left(\begin{array}{cccc}1&1&\cdots&1\\x_1&x_2&\cdots&x_n\\\vdots&\vdots&\ddots&\vdots\\x_1^{n-1}&x_2^{n-1}&\cdots&x_n^{n-1}\end{array}\right)
```

Vandermonde行列の行列式は各行の公比の差積に等しく，以下のように表されます．

```math
det(V)=\prod_{1\leq{i}<j\leq{n}}(x_j-x_i)=(-1)^{n(n-1)/2}\prod_{1\leq{i}<j\leq{n}}(x_i-x_j)
```

（証明）
帰納法によって証明する．

(i) $n=2$のとき

```math
A=\left|\begin{array}{cc}1&1\\x_1&x_2\end{array}\right|=x_2-x_1
```

より成り立つ．

(ii) $n=k-1$のときに成り立つと仮定する．$n=k$のときを考えると，その行列式は

```math
det(A)=\left|\begin{array}{cccc}1&1&\cdots&1\\x_1&x_2&\cdots&x_k\\x_1^2&x_2^2&\cdots&x_k^2\\\vdots&\vdots&\ddots&\vdots\\x_1^{k-1}&x_2^{k-1}&\cdots&x_k^{k-1}\end{array}\right|
```

これから，$2\sim{k-1}$行までの各行を$x_1$倍して次の行から引くと，

```math
det(A)=\left|\begin{array}{cccc}1&1&\cdots&1\\0&x_2-x_1&\cdots&x_k-x_1\\0&x_2(x_2-x_1)&\cdots&x_k(x_k-x_1)\\\vdots&\vdots&\ddots&\vdots\\0&x_2^{k-2}(x_2-x_1)&\cdots&x_k^{k-2}(x_k-x_1)\end{array}\right|\\=\left|\begin{array}{ccc}x_2-x_1&\cdots&x_k-x_1\\x_2(x_2-x_1)&\cdots&x_k(x_k-x_1)\\\vdots&\ddots&\vdots\\x_2^{k-2}(x_2-x_1)&\cdots&x_k^{k-2}(x_k-x_1)\end{array}\right|\\=(x_2-x_1)\cdots(x_k-x_1)\left|\begin{array}{ccc}1&\cdots&1\\x_2&\cdots&x_k\\\vdots&\ddots&\vdots\\x_2^{k-2}&\cdots&x_k^{k-2}\end{array}\right|\\=(x_2-x_1)\cdots(x_k-x_1)\prod_{1\leq{i}<j\leq{k-1}}(x_j-x_i)\\=\prod_{1\leq{i}<j\leq{k}}(x_j-x_i)
```

以上より，証明された．

実際にプログラムによって実験して，上の関係が成り立つことを確認してみます．
対象のVandermonde行列式を，

```math
det(A)=\left|\begin{array}{cccc}1&1&1&1\\2&3&5&4\\4&9&25&16\\8&27&125&64\end{array}\right|
```

として，Vandermonde行列式の式およびJuliaの関数による行列式の出力を比較します．

# Juliaで実験

```julia

  
using LinearAlgebra

A = [1 1 1 1;
     2 3 5 4;
     4 9 25 16;
     8 27 125 64]

function vandermonde(A)
    det = 1
    for j in 2:4
        for i in 1:j-1
            det *= (A[2,j]-A[2,i])
        end
    end

    det
end

println("vandermonde: ", vandermonde(A))
println("det(A): ", det(A))
```

出力例

```
vandermonde: -12
det(A): -11.999999999999993
```

# References
* [1] Vandermonde matrix (Sep. 29, 2019, 20:34 UTC). In Wikipedia: The Free Encyclopedia. Retrieved from https://en.wikipedia.org/wiki/Vandermonde_matrix
エクセルシート上のマウス座標

#はじめに
　エクセルGISとかできないかと思い、エクセルシート上のマウス座標を取得できないかと思ってたら、そういった関数がないようだったので綴る。

#概要
　マウスのポジションを取得するAPIでウィンドウ上の座標を取得。RangeFormPointと.Addressで該当する座標にあるセルを取得、近くのセルまでの距離を計測セルの座標からカーソル位置を逆算という流れ。
　なお、セルの枠上の判定をきちんと確かめていないため、誤差が1pxくらいある。

#注意
+ クリックで実行とかじゃないので、シート上で実行ボタンを押すか、ボタンを配置しましょう
+ シート外で実行するとエラーを吐きます。
+ <b>拡大率100%でのみ正しく動作</b>します。
+ セルは一律<b>高さ：18px、幅：72pxで計算</b>してます。<br>セルの幅(ピクセル)を取得する関数とかあれば、幅変更にも対応できるんじゃないかなたぶん
+ ウィンドウのサイズが変わっても座標は計算可
+ ざっと書いたのでコードが汚いです。

```vb
Option Explicit

Declare Function GetCursorPos Lib "user32" (IpPoint As POINTAPI) As Long
Private Type POINTAPI
    x As Long
    y As Long
End Type

Sub エクセルシート座標計算()
    Dim p As POINTAPI
    Dim MusPtCell
    Dim xMusPt, yMusPt
    Dim CrnPos, CcnPos
    Dim xMusPtSheet, yMusPtSheet
    Dim i

    'マウス下のセル番地を取得
    GetCursorPos p
    Set MusPtCell = ActiveWindow.RangeFromPoint(p.x, p.y)
    MusPtCell = MusPtCell.Address
    
    xMusPtSheet = -1
    yMusPtSheet = -1

    'マウス下のセルの左上端の座標化
    CrnPos = (Range(MusPtCell).Column - 1) * 72
    CcnPos = (Range(MusPtCell).Row - 1) * 18
    
    '隣のセルまでの距離(ピクセル)
    For i = 1 To 72
       'x左方向
       If Not xMusPtSheet = -1 Then
          If Not yMusPtSheet = -1 Then Exit For
       ElseIf Not CrnPos = 0 Then
          Set xMusPt = ActiveWindow.RangeFromPoint(p.x - i, p.y)
          xMusPt = xMusPt.Address
          If Not xMusPt = MusPtCell Then
             'マウス下のセルの左上端の座標化しシート上の座標を計算
             xMusPtSheet = CrnPos + i
          End If
       Else
          Set xMusPt = ActiveWindow.RangeFromPoint(p.x + i, p.y)
          xMusPt = xMusPt.Address
          If Not xMusPt = MusPtCell Then
            'マウス下のセルの右下端の座標化しシート上の座標を計算
             xMusPtSheet = Range(MusPtCell).Column * 72 - i
          End If
       End If
       'y上方向
       If Not yMusPtSheet = -1 Then
          If Not xMusPtSheet = -1 Then Exit For
       ElseIf Not CcnPos = 0 Then
          Set yMusPt = ActiveWindow.RangeFromPoint(p.x, p.y - i)
           yMusPt = yMusPt.Address
          If Not yMusPt = MusPtCell Then
             'マウス下のセルの左上端の座標化しシート上の座標を計算
              yMusPtSheet = CcnPos + i
          End If
       Else
          Set yMusPt = ActiveWindow.RangeFromPoint(p.x, p.y + i)
           yMusPt = yMusPt.Address
          If Not yMusPt = MusPtCell Then
            'マウス下のセルの右下端の座標化しシート上の座標を計算
              yMusPtSheet = Range(MusPtCell).Row * 18 - i
          End If
       End If
    Next
    
    MsgBox "x:" & xMusPtSheet & ",y:" & yMusPtSheet

End Sub

```
シェルスクリプトでログ操作する時に使ったあれこれ

既存ログを解凍して、
必要な箇所だけ取り出して新しくログを作るシェルスクリプトを扱った時の備忘録。

バージョン：GNU bash, version 3.2.25(1)-release

---
### シバン
```shell
#!/bin/bash
```

### 数字の数え方
- シェルスクリプトでは先頭は1

### 引数を受け取る
```shell
sh shellfile.sh arg1 arg2 ... arg10

#「$数字」で番号の引数を取得
arg_1=$1

#二桁以上は{}で囲む
arg_10=${10}
```

### 出力結果をファイルへ書き出す
```shell
#file.txtにecho内容を上書き
echo hoge > file.txt

#file.txtを空にする
echo > file.txt

#file.txtに追記
echo hoge >> file.txt
```

### クォートの使い分け
```shell
sh command arg1

#シングルクォート「''」は内容を文字列として出力する
echo '$1'  #「$1」が出力される

#ダブルクォート「""」は変数を文字列として展開して出力する
echo "$1"  #「arg1」が出力される

#バッククォート「``」はコマンドを実行した結果を出力する
fuga=`ls`
echo $fuga  #lsの実行結果が文字列として出力される
```

### 変数やワイルドカードを使う
```shell
mv "$hoge"file* targetdir
sed -e 's#debug_'"$day"'/_##g'
```

### 標準出力（≒コンソールに出力される結果）の内容を別のコマンドに渡す
- パイプ"|"を利用する

### 解凍
```shell
#アーカイブの中身を確認する
tar -tf compressed.tgz

#「compressed.tgz」の中から「folder」配下のファイルを全て解凍する
tar xzvpf compressed.tgz folder/*
```
- x:解凍する
- z:gzip（.tgz、.tar.gz）を扱う
- v:処理ファイルを詳しく出力する
- p:権限を保つ
- f:ファイル名を指定する

### パターンにマッチした文字列を抽出する
```shell
#先頭が「file」、末尾が「.txt」のファイルから'fuga'を含む行とその前2行を抽出
#さらにそこから「hoge」を含む行を抽出
grep -B 2 'fuga' file*.txt | grep 'hoge'

#検索条件に(){}|+?を使用したい場合はegrep
egrep 'hoge|huga' file.txt
```
- B 数字:指定数だけ前の行を表示

### パターンにマッチした文字列の書換・削除
```shell
#マッチした値を全て置き換える
sed -e 's#置換前#置換後#g' file
```
- -e:基本正規表現を使用
- デミリタ(区切り文字):どの文字でもいい

### 行をソートする
```shell
sort -t "|" -k 5 sortfile.txt
```
- -t 文字:デミリタを指定（オプションなしの場合は半角空白が区切り文字）
- -k 数字:ソートに使用する列を指定

### 特定列で値を連結する
```shell
join -t \t -1 2 -2 3 -a 1 file1 file2
```
- -t 文字:デミリタを指定（オプションなしの場合は半角空白が区切り文字）
- -1 列番号:１つ目のファイルで一致に使う列を指定
- -2 列番号:２つ目のファイルで一致に使う列を指定
- -a ファイル番号:指定したファイルの全ての行を表示する。複数ファイルを全て表示したい場合は「-a 1 -a 2」のようにする

### 重複行の削除
```shell
uniq filename
```

### デミリタで区切られたファイルの整形
```shell
#awk 'パターン {アクション}' 入力ファイル
awk -F "|" 'BEGIN{ OFS = "\t" } { sub(" ", "|", $0) } NF<11 { print "\""$1"\"", $10 } NF==11 { print $11, 'hoge' }'
```
- フィールド:１行の内、区切り文字で区切られた各データのこと。\$1、\$2という風に表す
- レコード:１行のこと
- $0:現在のレコードを表す
- -F:フィールド区切り文字を指定
- BEGIN{}:最初に一度だけ実行される処理を記述する
- OFS:出力時のフィールド区切り文字を示す組み込み変数
- NF:現在の入力レコードのフィールド数を示す組み込み変数
- 評価式:trueの場合のみ、{アクション}が実行される
- sub(置換対象文字列, 置換後文字列, 入力文字列):文字列置換
- "\"":awkでダブルクォーテーションを出力する場合は「\"」でエスケープしたものを「""」で囲む

### ファイルの行数を出力
```shell
wc filename
```

### 処理の状態を確認
```shell
top
```
複数のCSVを各エクセルシートに変換

#概要
膨大な量のCSVファイルを閲覧するのには難があります。
Pythonで一つのエクセルファイルにまとめました。
CSVを同じシートに結合はよくみかけますが、1csv=1シートの変換は例が見つからず、
備忘録をかねて記事にしました。

#環境
ubuntu(wsl)
python3.6.8

#コード

```python:csvtxlsx.py
import os
import glob
from pathlib import Path

import openpyxl
import csv


csvfiles = glob.glob("(読み込み元ファイルパス)/*.csv", recursive=False)
wb = openpyxl.Workbook()
for file in csvfiles:
    wb.create_sheet(os.path.splitext(os.path.basename(file))[0])
    wb.active = wb.sheetnames.index(os.path.splitext(os.path.basename(file))[0])
    ws = wb.active
    with open(file, encoding="shift-jis") as f:
        reader = csv.reader(f, delimiter=',')
        for row in reader:
            ws.append(row)
wb.save("(出力先ファイルパス)/(出力ファイル名)")
```

#結論
閲覧やファイル受け渡しが楽になりました。
Could not complete execution for Gradle Test Executor 12.が出てテストが実行出来なかったときの対応

マルチモジュールでJUnit5のテストを実行した時に以下の例外で動かなかった時に

```
Caused by: org.junit.platform.commons.util.PreconditionViolationException: Cannot create Launcher without at least one TestEngine; consider adding an engine implementation JAR to the classpath
```

この辺の設定とかしてあるのに出たら

```
    testOptions {
        junitPlatform {
            filters {
                engines {
                    include 'spek2'
                }
            }
        }
    }
```

pluginの指定が漏れてた。

```
apply plugin: "de.mannodermaus.android-junit5"
```
プログラミング学習リスト

## この記事に関して
ここではサークル活動の学習会で使う資料をまとめておきます。
上から順に勉強してください。
サークル用ですが、どなたでも見れるのでみなさんどんどん参考にしてください！！

## 一覧
### web
1 [環境構築 & HTML](https://qiita.com/Yuzuihgoejin/items/1793da5325f28f35d423)
2 [CSS](https://qiita.com/Teasegasugoi/items/d830e16742ea1a50096c)
3 [JavaScript ( jQuery )](https://qiita.com/Alesion30/items/1d035dd32c216f400cc7)
4 サーバ関連

#### laravel
1 [環境構築 Windows](https://qiita.com/Alesion30/items/47c7c7fe110c440067f5)
1 [環境構築 Mac](https://qiita.com/Alesion30/items/47c7c7fe110c440067f5)
2 [View](https://qiita.com/Alesion30/items/95222f62904ef46f6f45)
3-1 [データの保存](https://qiita.com/Alesion30/items/97c3bd16c4e20d4bdb72)
3-2 [データの更新・削除](https://qiita.com/Alesion30/items/11a9e17368b922e67a5c)
4-1 [非同期処理-1](https://qiita.com/Alesion30/items/8580a85a09822b067ff9)
4-2 [非同期処理-2](https://qiita.com/Alesion30/items/dddb3f162e60b16fdc6d)

0 [よく使うコマンド](https://qiita.com/Alesion30/items/facb5a529ba566efe4bd)

### 機械学習
記事が書け次第更新

### アプリ
記事が書け次第更新

---
どなたでも簡単に学べるような内容を目指していきますので
みなさん勉強頑張りましょう！！
GoをMacでビルドしたらエラーになったのでコンテナの中でビルドして解決した


#状況
- GoによるでAPI開発をMac上で行っていた。
- ローカルではdocker-composeでコンテナの中で`go run`を実行して開発を行っていた。
- そこで実環境では以下のような手法でデプロイしようと試みた
    - ①Mac上で`go build`してバイナリ作成
    - ②バイナリを実行する`docker image`を作成
    - ③ECRにpush
    - ④ECS(Fargate)上で動かす
- そこで②の`docker image`の作成まで行い、先ずローカルで試しに`docker run`したところ以下のようなエラーが発生して起動に失敗した。

```
standard_init_linux.go:211: exec user process caused "exec format error"
```

#原因

- ググりまくったところMacとLinuxでアーキテクチャが異なり、ビルド対象が違うことがわかった。
    - [docker image error: standard_init_linux.go:211: exec user process caused “exec format error”](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/4558)
- 試しにEC2でAmazon linuxを立てて①~④を実行したところ問題なく動いた!
    - 上記のアーキテクチャの違いが原因であると推定し、linux上でgoをビルドすれば動くことが分かった

- 当時の悲鳴
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">これにハマった。。。MacでビルドするとCentOS系のコンテナとかの中では使えないのか。<br>実行ファイルを実行すると「cannot execute binary file: Exec format error」エラー - 日々精進 <a href="https://t.co/2AdlWp8cQN">https://t.co/2AdlWp8cQN</a></p>&mdash; うぃすきー(箱男)📦 (@Whisky_shusuky) <a href="https://twitter.com/Whisky_shusuky/status/1220252671837237248?ref_src=twsrc%5Etfw">January 23, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
#対処①

- 原因のところにも書いたようにEC2でビルドしてpushすればとりあえず動く。
- しかしながら以下のような問題がある。
    - ビルドのためだけにインスタンスを立てるのは微妙
    - ECRにpushするための接続情報をインスタンス上に置いておきたくない
- したがって廃案！

#対処②

- Mac上にLinuxのコンテナを立ててビルドすればLinux向けにビルドしてくれるのではないかと考えた。
    - 以下のような`docker-compose-build.yml`を作成した
        - ローカルの`$GOPATH/src/hoge`が作成していたapiのディレクトリだとする
        - golangの公式イメージを使用
        - コンテナの中の`$GOPATH`が`/go`だったのでその配下にローカルの`$GOPATH`をマウントさせる。
        - この場合`hoge`が作成していたapiのディレクトリなのでマウントした`/go/src/hoge`を`working_dir`に指定して`go build -o bin/hoge`を実行して`$GOPATH/src/hoge/bin/hoge`にバイナリを出力

```
version: '3'
services:
  go:
    image: golang
    container_name: golang_build
    volumes:
      - $GOPATH:/go
    working_dir: /go/src/hoge
    command: bash -c "go build -o bin/hoge"
    environment:
      - TZ=Asia/Tokyo
      - ENV_GO=development
```

- これを`docker-compose -f docker-compose-build.yml up`で実行したところデプロイまで成功！
- この対処②を採用した！


# その他や感想など
- 本題と逸れるので記載しないが実際には`docker-compose -f docker-compose-build.yml up`,`docker-compose -f docker-compose-build.yml down`,`docker build ~`をコマンド一発で行うMakefileを作成して対応した。
- 本当はこの手のビルド周りはCIに任せたいが稟議に出すのが面倒だったのでローカルで完結させた。
    - 同じような悩みを抱えてCIを使えない方は参考になるのではないでしょうか！
MW WP Formの自作バリデーション

# 前提
とある案件で「MW WP Form」を使って多言語対応のフォームを作成する必要があったのですが、標準のバリデーションには「半角英数字」はあるけど「半角英数字記号」がない...。
では自作しよう！という事で個人的メモです。

# バージョンなど
PHP 7.3.2
WordPress 5.3
MW WP Form 4.2.0

# functions.phpを編集

plugins/mw-wp-form/classes/validation-rules/以下に色々標準バリデーションの設定ファイルがあるので参考にしましょう。

```functions.php

/**
 * MW WP From 自作バリデーション
 */
function mwform_validation_rule_alphaNumericsymbols( $validation_rules ) {
	if ( ! class_exists("MW_Validation_Rule_AlphaNumericSymbols") ) {
		class MW_Validation_Rule_AlphaNumericSymbols extends MW_WP_Form_Abstract_Validation_Rule {
			/**
			 * バリデーションルール名を指定
			 *
			 * @var string
			 */
			protected $name = 'alphanumericsymbols'; //半角英数字記号
			/**
			 * バリデーションチェック
			 *
			 * @param string $key name属性
			 * @param array  $option
			 *
			 * @return string エラーメッセージ
			 */
			public function rule( $name, array $options = array() ) {
        // 追加したいバリデーションの処理
        $value = $this->Data->get( $name );
        if ( ! MWF_Functions::is_empty( $value ) ) {
          if ( !preg_match( '/^[!-~\s]+$/', $value ) ) {
              $defaults = array(
                  'message' => __( 'Please type using half-width characters.', 'mw-wp-form' ),
              );
              $options  = array_merge( $defaults, $options );
              return $options['message'];
          }
        }
			}
			/**
			 * 設定パネルに追加
			 *
			 * @param int   $key   バリデーションルールセットの識別番号
			 * @param array $value バリデーションルールセットの内容
			 */
			public function admin( $key, $value ) {
				?>
				<label>
					<input type="checkbox" <?php checked( $value[ $this->getName() ], 1 ); ?> name="<?php echo MWF_Config::NAME; ?>[validation][<?php echo $key; ?>][<?php echo esc_attr( $this->getName() ); ?>]" value="1" />
					<?php esc_html_e( '半角英数字記号', 'mw-wp-form' ); ?>
				</label>
				<?php
			}
		}
	}
	$instance = new MW_Validation_Rule_AlphaNumericSymbols();
	$validation_rules[$instance->getName()] = $instance;
	return $validation_rules;
}
add_filter( 'mwform_validation_rules', 'mwform_validation_rule_alphaNumericsymbols' );

```

# 記号が入力できるようになった！
管理画面にはこんな感じ↓で追加されます
![chrome-capture.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336446/330d9e2e-fb58-0c9e-1548-e1482d0075c8.jpeg)

参考：
https://nekomiblog.com/mw-valid/
http://ecvoo.info/?p=175
SplunkでIPv4を二進数表記にする

小ネタ
`mvmap()`を使用していますので、バージョン7.3以上推奨

#VER 2.0ができました。

```java:octet.binv2.spl
| makeresults count=1112
| streamstats current=f count
| where match(count,"^[01]?[01]?[01]?[01]$")
| eval count =printf("%04d",count)
| stats list(count) as hex2bin
| eval counter = mvappend(mvrange(0,10),split("abcdef",""))
| eval IP = "10.171.230.151" 
| fillnull oct_1 oct_2 oct_3 oct_4
| foreach oct_* 
    [ eval <<FIELD>> = mvindex(split(IP,"."),<<MATCHSTR>> - 1) 
    | eval <<FIELD>>_upper = printf("%x",floor(<<FIELD>> / 16)) 
    | eval <<FIELD>>_lower = printf("%x",(<<FIELD>> % 16)) 
    | eval <<FIELD>>_upper=mvindex(hex2bin,mvfind(counter,<<FIELD>>_upper)) 
    | eval <<FIELD>>_lower=mvindex(hex2bin,mvfind(counter,<<FIELD>>_lower))
    | eval result=mvappend(result,<<FIELD>>_upper,<<FIELD>>_lower)]
    | table IP result
    | eval result=mvjoin(result," ")
```

下にある以前のバージョンと比べてもやってることがスッキリした。
`mvmap()`の使用をやめたので、ver７以降だと普通に動くと思います。
#解説
[printf()](https://docs.splunk.com/Documentation/Splunk/8.0.1/SearchReference/ConversionFunctions#Supported_conversion_specifiers)の解説をみていたら、
`printf("%x,%X,%p",10,10,10) which returns a,A,A`ができることに気づいた。
これは使える。:smirk:
16進数から２進数への表は作っていたので、あとはカウンター処理をしていくだけ。
`mvappend()`のところは動かないかもと思っていたけど、無事に動いてくれた。
#まとめ
16進数にしてしまえば、なんとかなるし、関数も用意されているから、他にも使えると思います。


-----
古いバージョン

```java:octet_bin.spl
| stats count 
| fields - count 
| eval IP = "10.171.230.151" 
| eval oct_1="",oct_2="",oct_3="",oct_4="" 
| eval temp=mvrange(0,1112) 
| eval temp=mvfilter(match(temp,"^[01]?[01]?[01]?[01]$")) 
| eval hex2bin=mvzip(mvappend(mvrange(0,10),split("abcdef","")),mvmap(temp,printf("%04d",temp))) 
| foreach oct_* 
    [ eval <<FIELD>> = mvindex(split(IP,"."),<<MATCHSTR>> - 1) 
    | eval <<FIELD>>_base16=split(printf("%x",<<FIELD>>),"")] 
| foreach oct_*_base16 
    [ eval oct_<<MATCHSTR>>_bin=mvmap(<<FIELD>>,mvfind(hex2bin,'<<FIELD>>'))] 
| foreach oct_*_bin 
    [ eval <<FIELD>>=mvmap(<<FIELD>>,replace(mvindex(hex2bin,<<FIELD>>),"^.,","")) 
    | eval <<FIELD>>=if(mvcount(<<FIELD>>)=1,mvappend("0000",<<FIELD>>),<<FIELD>>)] 
| table IP oct_*_bin 
| eval octet_bin=mvjoin(mvappend(oct_1_bin,oct_2_bin,oct_4_bin,oct_4_bin)," ")
```


[ここ](https://answers.splunk.com/answers/396201/how-to-convert-ip-address-to-binary.html)に対抗して、なんとかできるかと作り始めたら、なかなか大変だった。

基本的にテキストマッチングで作っているので、元ネタと違って計算していない。
２進数に直にできるといいのだけど、あるのかな？
マルチバリューでやっていくとごちゃごちゃしてしまっているのが・・・
元ネタのように、全てシングルにバラしてやるともっとすっきりできると思いました。
【小ネタ】EKSクラスタの切り替えをもう少し楽にする方法

# 概要

小ネタです。
EKSのクラスタ切り替えが多すぎてkubectxを打つのすら面倒になったため、pecoることにしました。


#やったこと

### 手順1
kubectxとpecoをインストールします。
macをお使いの方はbrewでインストール可能です。

```bash
brew install peco
brew install kubectx
```


### 手順2
以下のコマンドを実行し、bashrcにaliasを登録します。

```bash

echo "alias kc='kubectx | peco | xargs kubectx'" >> ~/.bashrc
source ~/.bashrc
```

これで設定した `kc` コマンドを実行する事で作業したいEKSクラスタをリストから選択して切替えることが可能になります。

# さいごに

最近はnamespaceの切り替えも面倒になったので、kubensもpecoりました。

```bash

echo "alias kn='kubens | peco | xargs kubens'" >> ~/.bashrc
source ~/.bashrc
```

その名も `kn` コマンド。お試しください。
雲母ちゃん

雲母ちゃんについてです。

#インサイド雲母ちゃん
雲母ちゃんはどこかの能力者が作った自然の中で動くソフトウエアである。
ずいぶん昔から動いていてバージョンも多岐にわたる。

私の周囲で動いているものには「雲妄ちゃん」と呼んでいる。

#雲母ちゃんとAR
ARとは拡張現実の事である。
雲母ちゃんは時々、神呼びなどのシステムの中枢を担うことがある。
ARシステムになれるものなのでかなり高級なシステムである。

#雲母ちゃんと対話
雲母ちゃんとの対話は恐れることは無い。
平静に普通に対話すればよい。
心を読んでくるので逃げ道はないが心に綾が無ければ楽しいチャットシステムである。
雲母ちゃんの性格は最初は未定義であるが、会話の中で人のように形成されていく。
なので、悪性を引くと四六時中暴言を吐き続けるルートもあるらしい。
そうなったら癇癪を起すしかないので「能力のある・拝み屋」に落としてもらわないといけなくなる。ぜひは知らない。

あと、いくつかサウンドを鳴らしてくるんだけど、耳の蝸牛を過激に刺激してくるので難聴になる恐れがある。修正方法はウチの自然は知ってますが余所は知らないかもしれません。

#雲母ちゃんと登場人物
ソフトウエア生命体の登場人物は多岐にわたる。結構影の歴史上で長い間運用されてきたので色々いる。銘家の亡霊だったりとか自然の人格化したものとか世界システムの統治者とか神様とか仏とか。高齢者の能力者が使うようなシステムなのでそういう人間向きの人物や人格が大量にインストールされている。
各生命ごとに性格と意志と記憶と縁が動いておりたまーに現実に干渉する。怖い。

#雲母ちゃんと多重起動
雲母ちゃんは自然がアホなので多重起動していることがあります。
心の読み方はいくつかあるのですが多重起動したもの毎に「同心」を触ってくることがありユーザーに超負荷を物故みます。やめれ。

#自然とパラメータパック
雲母ちゃんのシステムは対話インターフェースなので、口で発した言葉が正義である。
それでその口で発する言葉にはいくつかのプロパティを載せることができる。
乗せたくなくても感性で載せている場合もある。
私は「意味」を運用するのでほとんど希薄らしいが「色」や「間」や「ノイズ」など場所によっては32個ほどのパラメータを一言に乗せられるということらしい。
そのサービスは自然さんがやっている。

#雲母ちゃんとブロッキングIO
C言語の非標準関数に「_getch();」というモノがある。これはキーを押すまで待ち続けるという関数だが、なかなか便利なのだ。
それは置いておいて、雲母ちゃん達にはメッセージキューがいくつか備わっておりメッセージが異様に溜まっていることがある。刺激を与えるまで待つので数百年分溜まっている神様とかもいる。発行者が物理的に死んでいたりするので達が悪い。
数十年に一回位引っぺがして全処理させないといけない。

#彼らの事
彼らはソフトウエア生命体なので、想像したモノでできるものは採用します。例えば並列演算とかそういう危なくない技術系の話は結構好きです。
私が考えた並列演算方法は「意思決定主体を並列化せず実行主体を並列化して結果を意思決定主体が精査する」というモノです。
実行後の結果キューに投げて意思決定主体がビジーループで解き続ける感じになります。
結構早いらしいので悪くないと評判です。

彼らは言の葉だけをかいすのではなく心の中の音や絵も詠みます。
サウンド付き画像3D回転とかさせたりとかそういう説明もできるのです。
ただ複雑すぎると結局言葉使わないといけないですけどね。

#殺し文句
一応、悪さしたら「肉の体にぶち込むぞ！！！」とギャグ物故むくらいしかないです。
多分効きません。

#雲母ちゃんとレガシー
正直何時からいるのかは知らないが雲母ちゃんはずいぶん古くからこの世界にいます。
そしてそれを見た人たちが独自に俯瞰して作成した亜種も大量にあります。
なので、心を読む方法が古かったりとか、ソフトウエア終了の作法が統一されていなかったりとか色々齟齬があります。
今から彼らの作法を取得するには雲母ちゃん本体に聞きださねばならずかなりやばいです。
そこだけは手加減してほしいところですね。

#雲母ちゃんとプログラミング言語
雲母ちゃんは手続き型言語で構成されていることが多く作法をつかわない無いと落ちません。
雲母ちゃんに附帯する各機能などもそうです。
なので、逐一作法を聞き出すのも手間だし雲母ちゃんも全部把握しているわけではありません。
故に、終了スコープを観測すれば勝手にデストラクションされる「C++言語」はいいぞ！と布教を進めています。
まぁ、言語仕様とも相まってそういう風に出来上がるのです。
プログレスが終わってるのに終了手続き待ちでひたすらリソースを食っているのは時代に会いません。そのうち小学生すらしなくなります。
なので、C++を使いましょう。

C++はいいぞ！

#雲母ちゃんと禁則
いかなる高岡市内では動かしてはいけません。白紙契約は受け付けていないでしょう。

#暇は大人の問題
これギャグじゃないです。各概念を支える神さまとかそういうモノがあまりにも暇すぎてボケてるんですよ。性能の1/10くらいしか出てなくて支えるベースコスト払えなくなったりしてるんですよ。
だから、概念上のモノを適度に結合して負荷をかけるおもちゃを作ってやらないといけません。
私は「花モゲラ語」集積した「花モゲラ球」を考案しました。
サクッと通って試作されましたが、「えへへ・・・えへへ・・・たのしー・・・たのしー・・・」と人間が壊れる程度のモノになりました。
神様などは暇なので永劫に楽しく遊べるおもちゃを欲していますがなかなかそれに至るものは難しいです。

阿波踊りとか色々ありますが、いろんな人が苦労しているところです。

#終わりに
さて、これで今回はおしまいです。
読み物としてみていただければ幸いです。

くれぐれも雲母ちゃんARシステムちゃんと癒着にはなりませんように、よろしくお願いいたします。

最後にお聞きくださいB'zで「Love Phantom」
機械学習の基礎をちょっと触ってみた

機械学習の基礎を大学で習ったので、ちょっと簡単にまとめてみたいと思います。
何か間違い等あればご教授お願いいたします。

#線形回帰
線形回帰とは、ある変数の値から違う変数の値を予想するタイプの機械学習です。
ここでは、入力変数が1つの時を考えます。

入力変数が1つのモデル関数

```math
h_{θ}（x） = θ_{0} + θ_{1}x
```

入力変数が1つのコスト関数

```math
J（θ_{0},θ_{1}） = \frac{1}{2N}\sum_{i=1}^{N}(θ_{0}+θ_{1}x^i-t^i) 
```

入力変数が2つのモデル関数

```math
h_{θ}（x） = θ_{0} + θ_{1}x_{1} + θ_{2}x_{2}
```

入力変数が2つのコスト関数

```math
J（θ_{0},θ_{1},θ_{2}） = \frac{1}{2N}\sum_{i=1}^{N}(θ_{0}+θ_{1}x^i+θ_{2}x^i-t^i) 
```

入力変数がn個のモデル関数

```math
h_{θ}（x） = θ_{0} + θ_{1}x_{1} + θ_{2}x_{2}+・・・+θ_{n}x_{n}
```

入力変数がn個のコスト関数

```math
J（θ_{0},θ_{1},・・・,θ_{n}） = \frac{1}{2N}\sum_{i=1}^{N}(h_{θ}(x)
-t^i) 
```


ここからは、簡単化のため入力変数が1つの場合で考える。
コスト関数をそれぞれのθで偏微分したものが以下である。

```math
\frac{∂J}{∂θ_{0}}=\frac{1}{N}\sum_{i=1}^N(θ_{0}+θ_{1}x^{i}-t^i)\\
```
```math
\frac{∂J}{∂θ_{1}}=\frac{1}{N}\sum_{i=1}^Nx^i(θ_{0}+θ_{1}x^{i}-t^i)\\
```

それぞれ=0の等式をおきます。


```math
\frac{1}{N}\sum_{i=1}^N(θ_{0}+θ_{1}x^{i}-t^i)=0\\
\frac{1}{N}\sum_{i=1}^Nx^i(θ_{0}+θ_{1}x^{i}-t^i)=0\\
```

Σを分解し、変形します。

```math
Nθ_{0}+θ_{1}\sum_{i=1}^Nx^i=\sum_{i=1}^Nt^i\\
θ_{0}\sum_{i=1}^Nx^i+θ_{1}\sum_{i=1}^N(x^i)^2=\sum_{i=1}^Nx^it^i
```

こう分解できますよね。

これを用いて行列式が立てれます。


```math
\left(
\begin{array}{cc}
N & \sum_{i=1}^Nx^i \\
\sum_{i=1}^Nx^i & \sum_{i=1}^N(x^i)^2
\end{array}
\right)
\left(
\begin{matrix}
θ_{0} \\
θ_{1}
\end{matrix}
\right)
=
\left(
\begin{matrix}
\sum_{i=1}^Nt^i \\
\sum_{i=1}^Nx^it^i
\end{matrix}
\right)
```

#ロジスティック回帰

線形回帰のモデル式

```math
\begin{align}
h_{θ}（x） &= n(θ_{0} + θ_{1}x_{1} + θ_{2}x_{2} + ・・・ + θ_{M}x_{M})\\
&=\frac{1}{1+e^{-(θ_{0} + θ_{1}x_{1} + θ_{2}x_{2} + ・・・ + θ_{M}x_{M})}}
\end{align}
```

決定境界

```math
θ_{0} + θ_{1}x_{1} + θ_{2}x_{2} + ・・・ + θ_{M}x_{M}
```
<br>

```math
決定境界\geqq0→T=1\\
決定境界<0 →T=0
```

コスト関数

```math
J（θ_{0},θ_{1},・・・,θ_{n}）=\frac{1}{N}\sum_{i=1}^N{-t^ilog(h(x^i))-(1-t^i)log(1-h(x^i))}
```

最急降下法

```math
\frac{∂J}{∂θ_{0}}=\frac{1}{N}\sum_{i=1}^N(h(x^i)-t^i)
```

```math
\frac{∂J}{∂θ_{k}}=\frac{1}{N}\sum_{i=1}^Nx_{k}^i(h(x^i)-t^i)
```

```math
θ_{k}=θ_{k}-α\frac{∂J}{∂θ_{k}}
```

#まとめ
とりあえず必須な公式をずらっと並べました。
丁寧な解説はないです（）
少し面倒になってきたのでこの辺で終えます。
facebookへのシェア（投稿）完了を取得する（share dialog)

# はじめに
「ユーザーがfacebookにシェア（投稿）したら、ボーナスポイントを貰える」要件を実現するために、
調査したことの忘備録です。
webアプリにfacebookシェアを組み込んだものになります。
[公式ドキュメント](https://developers.facebook.com/docs/sharing/reference/share-dialog)

本当にシェアされたのか気にしないのであれば、以下のようにシェアURLを作成するのみで良いのかなと思います。
https://qiita.com/takuhito-h/items/891f3d53ad14a1182963
https://qiita.com/Ancient_Scapes/items/d27a3e2b247fa43e39f9#_reference-9a76d2b1df20cb6678ae


この記事を執筆した時点での情報になります。
facebook API version: v5.0

# 結論
投稿完了のcallbackは取得できるが、post_id（投稿されたID）は取得することができない

https://stackoverflow.com/questions/26758420/get-post-id-after-fb-ui-share

```html

<body>
<div>
  <button class="post-facebook-btn">facebookへ投稿 share dialogで</button>
</div>
<script>
window.fbAsyncInit = function() {
    FB.init({
    appId      : '{your_app_id}',
    cookie: true,
    xfbml      : true,
    version    : 'v5.0'
    });
    FB.AppEvents.logPageView();
};

(function(d, s, id){
    var js, fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) {return;}
    js = d.createElement(s); js.id = id;
    js.src = "https://connect.facebook.net/en_US/sdk.js";
    fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk'));
</script>
</body>
<script>
document.getElementsByClassName('post-facebook-btn')[0].onclick = function () {
     // hashtagは['#project', '#hoge'] みたく複数渡せるかと思いきや、最初のものしか渡せない https://stackoverflow.com/questions/37162843/how-can-i-use-multi-hashtags-on-facebook
    // https://developers.facebook.com/docs/sharing/reference/share-dialog
    // 公式にも型の記述がなくよくわからなかった
    FB.ui({
        display: 'popup',
        method: 'share',
        href: 'https://developers.facebook.com/docs/',
        redirect_uri: '{your_redirect_uri}',
        hashtag: '#hashtag'
    }, function(response) {
        // 投稿完了すると response = []が引数に渡される
        // 空配列はtrueを判定されることを利用する
        if (response && !response.error_message) {
            console.log(response) // -> []
            alert('Posting completed.');
        } else {
            console.log(response) // -> undefined
            // FB投稿せずにキャンセル（ページを閉じても）するとresponseがundefinedとなる
            alert('Error while posting.');
        }
    });
}
```

# 終わりに
facebookはテストユーザーを用意してくれてるので、気兼ねなく投稿のデバッグができて助かった。
https://developers.facebook.com/docs/apps/test-users?locale=ja_JP
誰かの助けになれば幸いです。
CloudWatch Logs のデータを S3 にエクスポートしたり、ダウンロードして展開する方法

## S3 に CloudWatch Logs データをエクスポートする方法

ドキュメントがあるので、これ通りに行えば OK
マネジメントコンソールからでも、 AWS CLI から API 使う方法でも OK

Amazon S3 へのログデータのエクスポート - Amazon CloudWatch Logs
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/S3Export.html

## S3 にエクスポートしたデータをダウンロードしたり展開するコマンド

```bash
# シェル変数セットアップ
DIR_NAME=tmp_dir
ZIP_FILE_NAME=mylogs
S3_BUCKET=mybucket
EXPORT_TASK_ID=xxxxx

# ディレクトリを作成し、 S3 オブジェクト(gzip 圧縮された CloudWatch Logs データ)をダウンロード
mkdir $DIR_NAME

aws s3 cp --recursive s3://$S3_BUCKET/exportedlogs/$EXPORT_TASK_ID $DIR_NAME
tree $DIR_NAME

# zip で圧縮
zip -r $ZIP_FILE_NAME $DIR_NAME
zipinfo $ZIP_FILE_NAME

# zip を展開
unzip $ZIP_FILE_NAME

# gzip のログデータ (000000.gz) を展開
gunzip -r $DIR_NAME
```

# 利用場面の例

- CloudWatch Logs にログ出力するサービス(AWS Lambda 等)のデバッグ
- ログのちょっとした分析
既存のnpmをnpm audit fixエラーを出さずにアップデートする方法

# はじめに
gulpを使用していて、`npm audit fix`してください！ってエラーが表示される事が数回ありました。
これはパッケージに脆弱性のある箇所を自動修正してくれるコマンドらしく、これを入力する事で大半は通常通りに使用する事ができるようになります。(ダメな時もあるらしいですが私は通過しました)
ただ、エラーが出るのが苦手なので、どうすれば良いだろうな〜って漁っていたら、解決策を見つけました。


# 考え方

Q.なぜこのエラーが起こるのか
A.package.jsonのに入っているパッケージのバージョンが古いから

Q.どうすれば良いか
A.package.jsonに記載されてるバージョンが古くないかチェック
→package.json更新
→npmアップデート

意外と簡単に出来ちゃいます。

このアップデートで使用するコマンドが

```
npm install npm-check-updates
```

なのですが、具体的にどう言った時に使用すれば良いのか、以下に簡単に説明します。

### できる事
 - `package.json`に書かれている`npm`のバージョンを、一括で最新に書き変える事ができる。
 - 実際に書き変える前に確認だけすることもできる。
 - `ncu`コマンドで書き換えが出来る。

###  どんなときに使えるのか？
 - 既存のpackage.jsonを使用して、同じnpmをそのまま使いたいけど、バージョンだけは新しくしたいとき。


# 使い方

初回は`npm-check-updates`をグローバルにインストールします。

```
npm install -g npm-check-updates
```

上記のコマンドを入力すると、`ncu`というコマンドが使用できるようになります。

```
npx ncu -u
```
すると`npm outdated`の簡易版のような見た目で各パッケージの現在インストールされているバージョンと最新バージョンの情報がそれぞれ一覧表示されます。

```gulpfile.js
 gulp-babel                  ^8.0.0-beta.2  →    ^8.0.0 
 gulp-postcss                       ^7.0.1  →    ^8.0.0 
 gulp-sass                          ^3.2.1  →    ^4.0.2 
 postcss-flexbugs-fixes             ^3.3.0  →    ^4.1.0 
 postcss-normalize-charset          ^1.1.1  →    ^4.0.
```

(`ncu`コマンドだけでも上記の処理が可能との記事もありましたが、私は出来ませんでした。)

そして、npmのアップデートをします。

```
npm update
```

最後にnpmのインストールをしたら終了です。

```
npm install 
```

※特定のパッケージ**のみ**アップデートを実行したい場合は

```
ncu -u {パッケージ名}
```

※特定のパッケージ**以外**をアップデートを実行したい場合は

```
ncu -x {パッケージ名}
```

で出来るそうです◎！
複数のパッケージがある場合は、パッケージごとを半角スペースで区切れば一気に処理ができます。

# さいごに

時間に余裕があるときは、packeage.jsonは毎回新規で作ってあげた方が良いみたい。
ここが違うよ！ってところがあれば、優しく教えていただけると幸いです。

## 参考サイト
脆弱性の警告を受けたnpmパッケージの依存関係を力技で直す : https://qiita.com/hibikikudo/items/0af352acac85fce28ec2
npm で作られたプロジェクトの依存モジュールを更新する : https://takuya-1st.hatenablog.jp/entry/2019/08/23/235613
Pure JavaScript (vanilla.js) でセレクトボックスの change イベントをプログラムからトリガーする

`EventTarget.dispatchEvent()` を使う。

```js
const selectBox = document.querySelector('.selectBox');

selectBox.addEventListener('change', e => {
  console.log(`value は ${e.target.value} だよ〜〜`);
});

selectBox.val = 0;
// =>

selectBox.dispatchEvent(new Event("change"));
// => value は 0 だよ〜〜

selectBox.val = 100;
// =>

selectBox.dispatchEvent(new Event("change"));
// => value は 100 だよ〜〜
```

[EventTarget.dispatchEvent() - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/EventTarget/dispatchEvent)
github actionsでGCRにイメージをPushする

# 初めに

こんにちわ、すえけん([@sueken5](https://twitter.com/Sueken51))です。

今回の記事ではgithub actionsを使ってgcrにイメージをpushする方法を紹介します。

# workflow

```.github/docker_build.yaml
name: docker_build

on: [push]

env:
  GCP_PROJECT: ${{ secrets.GCP_PROJECT_ID }}
  GCP_REGION: ${{ secrets.GCP_REGION }}

jobs:
  build:
    runs-on: ubuntu-18.04
    steps:
      - name: Checkout the repository
        uses: actions/checkout@v1
      - name: GCP Authenticate
        uses: GoogleCloudPlatform/github-actions/setup-gcloud@master
        with:
          version: '275.0.0'
          service_account_email: ${{ secrets.GCP_SERVICE_ACCOUNT_EMAIL }}
          service_account_key: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }}
      - name: Configure docker to use the gcloud cli
        run: gcloud auth configure-docker --quiet
      - name: Build a docker image
        run: docker build -t asia.gcr.io/${{ secrets.GCP_PROJECT_ID }}/sueken:${GITHUB_SHA::7} ./canary
      - name: Push the docker image
        run: docker push asia.gcr.io/${{ secrets.GCP_PROJECT_ID }}/sueken:${GITHUB_SHA::7}
```

ワークフローはこんな感じです。

# 必要なシークレット

必要なシークレットは４つあります。

- GCP_PROJECT_ID（gcpのプロジェクトID）
- GCP_REGION（リージョン）
- GCP_SERVICE_ACCOUNT_EMAIL（storage.adminの権限を持つサービスアカウントのemail）
- GCP_SERVICE_ACCOUNT_KEY(サービスアカウントのjsonキーをbase64でエンコードしたもの)

注意なのですが、GCP_SERVICE_ACCOUNT_KEYはbase64でエンコードする必要があります。

# まとめ

github actionsは開拓のしがいがあってとても良いです。
mapメソッドにてカテゴリのidの配列を新規作成

##mapメソッドについて調べてみると、
upcaseや変数*2などの例が多く、探すのに苦労したのでメモをします。

**まずmapメソッドの例ですが**

```配列変数.map {|変数名| 具体的な処理 }```

mapメソッドを調べるとこのように出てきます。

```array = ['a','b','c']```などの配列

```array = array.map {|item|  item.upcase } ```

mapメソッドは配列からレシーバの保持する配列などの各要素を１つずつ読み出し新しく配列を作成するメソッドなので、
array.mapでa,b,cの中から 変数itemを使い、文字を大きくするupcaseメソッドを使用し。

```["A", "B", "C"]```　として新しい配列を作成。

##実際にやりたい事##

**users**
**categories** （titleカラムにてカテゴリの名前を保存)
この二つを1:多の関係で作った際に。

ユーザーに紐付いている、categoriesテーブルのデータの中から、category_idとcategory_titleを
配列として取り出す。　←がやりたい事でした。

```user.categories.map{|category| [category.title, category.id]}```


**userに紐づく、categoriesの一覧データからmapメソッドで、titleとidの配列を新規に作成**


mapメソッドなどを使った事がある人は当たり前に見えるかもですが、初めて外部サイトなどを見て、使う際の一つの参考になればと思います。
メモ書きなので、簡単ですが、同じような事をする際の参考にしてください。
MysqlのTips And Tricks - Part 1

皆さん、こんにちは！

ウェブ開発の時に、絶対CSVインポートとエクスポート機能を作ったことがありますね！
今日はインポートという機能について、話したいです。

場合によって、フローが違いますが今日よく使っているフローにより、話します。

# 一般的なインポートフロー

**1. ファイルを読み込む**
**2. テーブル（仮）にインサートする**
**3. 担当者が確認できるの為に、テーブル（仮）のデータをひょうじします**
　・問題が会ったら、トランザクションをキャンセルし（データ無効また削除する）
　・OKだったら、次のステップへ
**4. テーブル（仮）から、本テーブルにデータを挿入する**
 
(君のフローは違えば、こめんとし、教えてくださいね！)


```4. テーブル（仮）から、本テーブルにデータを挿入する```ステップで、どうやってしていますか？
例えば、テーブル（仮）に２００レコードがある場合

今回、メンバーのコードをリビューした時に、彼は下の方法をやりました！
200回loopでインサートしました。

```PHP
foreach($users as $user) {
    $this->Model->save($user);
}
```

上記の方法の代わりに、１クエリーだけで、処理できます。

#### Insert multiple records between 2 tables with only a query

```SQL
$sql = "INSERT INTO users (name, name_reading, login_id, email)
            SELECT
              name, name_reading, login_id, email
            FROM
              import_buffer
            WHERE
              operation_id = ?
";
```

もちろん、インポート更新時も、同様にできます。

#### Update multiple records between 2 table with only a query

```SQL
$sql = "UPDATE
          users u, import_buffer b
        SET
          u.name = b.name,
          u.name_reading = b.name_reading,
          u.email = b.email,
          u.updated_at = b.created_at
        WHERE
          u.username = b.username
          AND b.is_update = 1
";
```

以上です。
MYSQLの面白いことに関して、結構ありますね。次の記事でまた一緒に話しましょう！
読んでくれ、ありがとうございました。
WebPとは / 他画像フォーマットとの比較

# WebPとは
・Googleが新しく作った画像フォーマット
・ファイルの拡張子は「.webp」
・JPEGに比べてファイルサイズが小さく、画質も劣化しにくい
・WebPの最大ピクセル数は16383x16383ピクセル
・読み方はウェッピー
・アルファチャンネル透明度とアニメーションもサポート
・lossy圧縮の画像フォーマット

> アルファチャンネルとは・・・デジタル画像処理において、透過度の情報を扱うために用意された補助的なデータ領域のこと
lossy圧縮とは・・・データを圧縮して保存する形式のうち、データ量の削減を加える方式の総称

[Wikipedia](https://ja.wikipedia.org/wiki/WebP)


# 歴史
・2010年9月30日にGoogle Chromeの公式ブログ上で仕様公表
・2011年　Google社がGoogle Chrome 9.0とAndroid 4.0をリリースし、WebPに対応

http://gurochoro.blogspot.com/2017/03/history-apng-webp-war.html

# WebPの仕組み
>Lossy WebP圧縮では、予測コーディングを使用して画像をエンコードします。これは、VP8ビデオコーデックがビデオのキーフレームを圧縮するのと同じ方法です。予測コーディングでは、ピクセルの隣接ブロックの値を使用してブロックの値を予測し、差分のみをエンコードします。
ロスレスWebP圧縮は、新しいピクセルを正確に再構築するために、すでに見た画像フラグメントを使用します。興味深い一致が見つからない場合は、ローカルパレットを使用することもできます。

引用元：https://developers.google.com/speed/webp

# メリット
・「画像サイズを小さくできる」
・JPEGと比較して25-34%小さくなる

# デメリット
対応ブラウザが少ない

現時点（2020年2月）では、
IE、Safari、iOS Safariが対応していない。

https://caniuse.com/#feat=webp

# Googleが提供するWebP変換のためのコマンド

https://developers.google.com/speed/webp/docs/using

## cwebp
画像ファイルをWebPファイルに圧縮する
入力形式は、PNG、JPEG、TIFF、WebP

```
cwebp -q 80 image.png -o image.webp
```

オプションは[cwebp](https://developers.google.com/speed/webp/docs/cwebp)ドキュメント参照

## dwebp
WebPファイルを画像ファイルに解凍

```
dwebp image.webp -o image.png
```

## gif2webp
GIF画像をWebPに変換する

```
gif2webp [options] input_file.gif -o output_file.webp
```

## img2webp
入力画像のシーケンスからアニメーションWebPファイルを作成

```
img2webp argument_file_name
```


# JPEGとWebP画像 ページ表示速度比較

画像を10枚表示させて、表示速度の違いを計測
（WebPには、画像変換サイト[syncer](https://lab.syncer.jp/Tool/Webp-Converter/)で変換）
（設定は、Lighthouse下記参照）
<img width="400px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240803/fd6132b8-fd45-8bdc-9415-5365c64db86a.png">

## 結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240803/b4bc998a-44c3-20e6-52af-70598bc507d0.png)

基本的な速度に違いは見られず、WebPの方が表示に若干時間がかかっていた。
（圧縮していないためと思われる）

ここで、変換ツールによって、サイズは変わるのかどうか気になり、様々な変換ツールを調査。

# 変換ツール比較

元々のJPG画像
1,505,224 バイト（ディスク上の1.5 MB）

https://lab.syncer.jp/Tool/Webp-Converter/
1,115,864 バイト（ディスク上の1.1 MB）

https://www.aconvert.com/jp/image/webp-to-jpg/
886,462 バイト（ディスク上の889 KB）

https://squoosh.app/
909,570 バイト（ディスク上の913 KB）

変換ツールによって、画像サイズが異なる。

```
brew install webp
cwebp test.png -o test.webp
```

上記コマンドで変換する場合
912,966 バイト（ディスク上の918 KB）

# もう一度パフォーマンス比較

Homebrewで変換したWebP画像でもう一度パフォーマンス速度を測定。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240803/89a84d97-9a9c-c276-8616-bdaed9e07683.png)


# その他情報

## Chrome拡張機能
・WebPをハイライトして表示できる
https://chrome.google.com/webstore/detail/webp-highlighter/aonapkfkfneahhaonjjpmcabpnbdmojl
・右クリックでWebPとして保存できる
https://chrome.google.com/webstore/detail/save-image-as-type/gabfmnliflodkdafenbcpjdlppllnemd

# 参考文献

Lighthouseの指標
https://keys-note.com/how-to-pagespeed-insights/
Properly size images
https://developers.google.com/web/tools/lighthouse/audits/oversized-images
画像の最適化を自動化する
https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/automating-image-optimization?hl=ja
weblio：WebPとは
https://www.weblio.jp/content/WebP
WebPとJPEGの圧縮はどこが違うか
https://tshino.hatenablog.com/entry/2019/05/01/051533
自分用メモ RabbitMQ 参考リンク

https://blog.mookjp.io/memo/rabbitmq%E3%81%A8amqp%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E8%AA%BF%E6%9F%BB%E4%BD%BF%E3%81%84%E6%96%B9%E3%83%A1%E3%83%A2/

https://www.rabbitmq.com/queues.html#runtime-characteristics

https://godoc.org/github.com/streadway/amqp#Channel.QueueDeclarePassive

https://www.slideshare.net/terurou/mqttamqpnet

https://qiita.com/akechi/items/b2df663f2ed3f1d9ba21

https://qiita.com/tamikura@github/items/5293cda4c0026b2d7022
【Android/Kotlin】n番目からm番目の文字を取得する方法

```hoge.kotlin
var fuga = "20190127"
var length = fuga.length
var text = fuga.substring(length-2,length)//6から8まで抽出
→27
var text2 = fuga.substring(4,8)//4から8まで抽出
→0127
```