OmniAICreator/Qiita-1.07M huggingface dataset:
TypeScriptのinterfaceとtypeの違いについて

## はじめに
業務でTypeScriptを使用する機会がありますが、型定義をする際に前任者と同じようにinterfaceで型定義を行なっていました。typeとの違いを理解せずにinterfaceを使用していたため、今回違いを自分の中で明確にするために記事を書きます。

## interface
interfaceは、オブジェクト・クラスの構造を決めるためのものになり、型に名前をつけることができます。

```typescript
interface Member {
  name: string;
  age: number;
}

const member: Member = {
  name: "太郎",
  age: 30,
};

// string型のnameに数字を入れようとすると、エラー
member.name = 50; // Type 'number' is not assignable to type 'string'.
```

## type
typeはTypeScript独特の構文で型エイリアスと呼ばれ、同じくオブジェクトの型に名前をつけることができます。

```typescript
type Member = {
  name: string;
  age: number;
};

const member: Member = {
  name: "太郎",
  age: 30,
};

member.name = 50; //Type 'number' is not assignable to type 'string'.
```

## interfaceとtypeの違い

#### 1. 宣言方法
下記コードを比較していただければわかりますが、interfaceは宣言のみでtypeは代入になります。（＝が必要）interface構文はブロック{}で終わる文なのでセミコロンが不要になります。

``` typescript
interface Member {
  name: string;
  age: number;
}

type Member = { // =が必要
  name: string;
  age: number;
}; //セミコロンが必要
```

#### 2. 使用できる型の種類
union型やタプル型はtypeでないと型定義することができません。

```typescript
// Union型
type Fruit = "apple" | "remon";

// タプル型
type Member = [number, string];
```

このような場合は、interfaceを使用することができず、typeを使用する必要があります。

#### 3. interfaceはマージされる
interfaceは、同じ名前の型を定義すると自動的に一つの定義にマージしてくれます。

```typescript
interface Member {
  name: string;
}

// 同じ名前の型を定義すると、マージされる
interface Member {
  age: number;
}

const member: Member = {
  name: "太郎",
  age: 30
};
```

typeで同じ名前の型を定義すると、エラーが出ます。

```typescript
type Member = {
  name: string;
};

type Member = {
  age: number;
};
// Duplicate identifier 'Member'.
```


#### 4. 継承
interfaceはextendsで継承可能です。

```typescript
interface Name {
  name: string;
}

interface Member extends Name {
  age: number;
}

const member: Member = {
  name: "太郎",
  age: 30
};
```

一方、typeは継承を行えませんが交差型（&）で継承と似たようなことができます。
```typescript
type Name = {
  name: string;
};

type Age = {
  age: number;
};

// intersection型
type Member = Name & Age;

const member: Member = {
  name: "太郎",
  age: 30
};
```

## まとめ
どっちを使うかはプロジェクトによって違うと思いますが、インターフェイスの場合同じ名前で型を定義すると自動的にマージされるのでそこは気をつけたいと思いました。今回interfaceとtypeの違いを明確に整理をすることができました！

## 参考記事
https://yutaro-blog.net/2021/10/08/typescript-interface-type/

https://zenn.dev/luvmini511/articles/6c6f69481c2d17
【PHP】参照渡しの配列の要素をunsetしても参照は解除されない

タイトルの通りです。
参照渡し（参照の代入）が推奨できるかはさておき、挙動の一例として参考にしてください。

# テストデータの作成
配列``$foods``を作成し、``$ref_foods``へ参照を代入します。

```php
$foods = [
    'fruits' => [
        'apple',
        'orange'
    ],
    'vegetables' => [
        'carrot',
        'tomato'
    ]
];

$ref_foods = &$foods;
```

代入後、``$ref_foods``と``$foods``は同じ内容を指します。
```php
var_dump($ref_foods);
/*
array(2) {
  ["fruits"]=>
  array(2) {
    [0]=>
    string(5) "apple"
    [1]=>
    string(6) "orange"
  }
  ["vegetables"]=>
  array(2) {
    [0]=>
    string(6) "carrot"
    [1]=>
    string(6) "tomato"
  }
}
*/

var_dump($foods);
/*
array(2) {
  ["fruits"]=>
  array(2) {
    [0]=>
    string(5) "apple"
    [1]=>
    string(6) "orange"
  }
  ["vegetables"]=>
  array(2) {
    [0]=>
    string(6) "carrot"
    [1]=>
    string(6) "tomato"
  }
}
*/
```
# 配列を丸ごとunsetした場合
unsetされた配列``$ref_foods``は未定義の状態になります。
代入元の配列``$foods``は変更されません。

unsetのタイミングで参照が解除されることが分かります。
```php
unset($ref_food);

var_dump(isset($ref_food)); // bool(false)
var_dump(isset($food));     // bool(true)

var_dump($foods);
/*
array(2) {
  ["fruits"]=>
  array(2) {
    [0]=>
    string(5) "apple"
    [1]=>
    string(6) "orange"
  }
  ["vegetables"]=>
  array(2) {
    [0]=>
    string(6) "carrot"
    [1]=>
    string(6) "tomato"
  }
}
*/
```

# 配列の要素をunsetした場合
unsetされた配列の要素``$ref_foods['fruits']``だけでなく、代入元の配列の要素``$foods['fruits']``も未定義の状態になります。

```php
unset($ref_foods['fruits']);

var_dump(isset($ref_foods['fruits'])); // bool(false)
var_dump(isset($foods['fruits']));     // bool(false)
```

``$ref_foods``へ要素を代入すると``$foods``にも反映されます。
参照が解除されていないことが分かります。
```php
$ref_foods['fruits'][] = 'grape';

var_dump($ref_foods);
/*
array(2) {
  ["vegetables"]=>
  array(2) {
    [0]=>
    string(6) "carrot"
    [1]=>
    string(6) "tomato"
  }
  ["fruits"]=>
  array(1) {
    [0]=>
    string(5) "grape"
  }
}
*/

var_dump($foods);
/*
array(2) {
  ["vegetables"]=>
  array(2) {
    [0]=>
    string(6) "carrot"
    [1]=>
    string(6) "tomato"
  }
  ["fruits"]=>
  array(1) {
    [0]=>
    string(5) "grape"
  }
}
*/
```

# まとめ
公式マニュアルを確認しましたが、根拠になりそうな情報が見つかりませんでした(-_-;)
[PHP公式マニュアル: リファレンス渡し](https://www.php.net/manual/ja/language.references.pass.php)
[PHP公式マニュアル: リファレンスの解除](https://www.php.net/manual/ja/language.references.unset.php)

参照渡しはコードの見通しが悪くなるので使いたくありませんが、動作を知ることは役に立ちます。
注意点をまとめました。
- どのように参照が代入されているか（変数をそのままか、一部の要素だけか）
- 処理の途中でunsetが実行されているか
- 処理の途中で参照が解除されていないか

# 2022/03/24追記
記事中のコードでは配列の要素に参照は無いためタイトルの挙動になります。
参照に不慣れだとハマりやすい箇所だと思うので、記事は公開当初のままにしておきます。

参照については、こちらも参考にしてみてください。
Xdebugによる検証方法も掲載されているので、手を動かしながら学べます。
[PHP公式マニュアル: 参照カウント法の原理](https://www.php.net/manual/ja/features.gc.refcounting-basics.php)

# 採用PR
弊社で一緒に働く仲間を募集しています。
全てのオタクを幸せにしたい方、是非ご覧ください！

https://hrmos.co/pages/vivion/jobs/0000191
2022　とにかくこれから知識を深堀したいキーワード集

# ご挨拶
皆さんこんにちは。
外資クラウドベンダーで働く、Kazuyaです。

この記事は・・・

先に謝っておきます。。
ただただ、僕が今後調べたい（知識を深堀したい＆いろいろ物を作ってスキル習得したい）領域の
キーワードだけ並べています。

これ押さえておかないとね！っていうだけです。。
誰のためにもならない記事で本当に申し訳ないのですが、
「あれ、なんだったっけ？」というときの備忘録には役立つかもしれません。。。

# エッジコンピューティング
基地局側で作動するアプリの開発。Lambda@Edgeとか実は経験ないのでやってみる。

# ５Ｇ開発
５Ｇを活かした開発。といっても５Ｇに特化した何ができんの、今までと何が違うのとかとか、
開発者目線で４Ｇというか旧来の回線と、何か気にしなければいけないところあるの？
ってのは把握していきたい。
4K/8Kのライブ配信、没入感マックスのVR・AR、スポーツ観戦の多角化。
遠隔技術やら、自動運転推進、IoT化の加速、働き方改革。うーんいろいろ入っていきたいところありすぎ。。

自宅の有線 光（マンションタイプ）って、VDSLのせいで、100Mbsなんですよね。。。
4Gやら、5Gにすら劣ってる。。。まずは引っ越しかな。。

# Quantum
量子コンピューティングの領域って、どうにもハードルが高いんすよねぇ。
どこまで理解できる＆どこまでそれを使った開発やモノづくりができるのか試したい。

# ラズパイ
最近触ってないから、知識がさようならしている。
今一度１からやり直したい。

# OpenShift / RedHat Ansibleなどなど
あの辺理解しておきたい。
Kubernatesを商用で使うのはさすがにきついなぁと。
だからマネージドなAKSやらEKSやら。
加えてRedHatのOpenShift。この辺もだよなぁと。

で、DevOpsにAnsibleがかなり使える（OpenShiftのOperatorも開発できるし）らしいので、
実際に使っていきたい。


と、本日はただただ自分が今後取り組んでいきたいところをまとめました！
他にも、Cloud関連のものがありますが、あまりに細かすぎるので、
今日はこの辺で！

Thank you for reading!
See you next time!!
Ubuntuの管理




:::note warn
下記のコマンドを**端末**で実行してください。
「端末ってなに？」という方は以下の記事をご覧ください。
:::



https://linuxfan.info/ubuntu-open-terminal-emulator

## 環境
- Distributor ID:	Ubuntu
- Description:	Ubuntu 20.04.4 LTS
- Release:	20.04
- Codename:	focal


# アップデート
|目的|コマンド|
|:---: |:---: |
|ローカルパッケージインデックスの更新|sudo apt update|align center|
|ポイントリリースの適用|sudo apt upgrade|

:::note info
「update」は、ポイントリリースの最新情報をネット上から取得し、ローカルパッケージインデックスに記録します。そして、「upgrade」は、ローカルパッケージインデックスの内容にしたがって、実際にアップデートを実行します。
:::

# 削除
|目的|コマンド|
|:---: |:---: |
|アップデートに伴い不要になったパッケージを削除|sudo apt autoremove|
|パッケージを削除|sudo apt remove {パッケージ名}|
|パッケージを**完全削除**|sudo apt remove --purge {パッケージ名}|

# バージョン確認
|目的|コマンド|
|:---: |:---: |
|バージョン確認|lsb_release -a|


# Anaconda 関連
|目的|コマンド|
|:---: |:---: |
|Anaconda 起動|anaconda-navigator|
|Jupyter Lab 起動|jupyter lab|

「もう少し詳しく知りたいよ！」という方はこちらの記事もぜひご覧ください！！

https://qiita.com/Mira_332/items/42d738ddbbd4a38e5400





















## 参考文献




https://linuxfan.info/ubuntu-open-terminal-emulator


https://snowtree-injune.com/2020/10/09/ubuntu-upgrade-dj007/


https://qiita.com/SUZUKI_Masaya/items/1fd9489e631c78e5b007


https://www.delftstack.com/ja/howto/linux/how-to-check-the-version-of-ubuntu/
【クエリビルダ】作成したクエリを実行してみる

[Sharperlight](https://sharperlight.jp/)製品群共通のクエリ設計ツール**クエリビルダ**には、クエリのデバッグツールとして**プレビュー**機能が備わっています。クエリを設計したあと[プレビュー]ボタンを押すことで機能します。
![2022-mm-dd Figure 01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/5d2b254b-fa85-0065-07e7-275d2f1d592c.png)
このようにクエリにより抽出されたデータを見ることができます。クエリ設計画面に戻る場合は[クエリに戻る]ボタンを押します。
![2022-mm-dd Figure 02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/8c604741-2ab0-c54e-3b11-2d789414e984.png)
:postbox:[Sharperlight](https://sharperlight.jp/)
心理的安全性を確保するために新人がやってよかったこと-分報大事！-

# はじめに
在宅勤務という単語が当たり前になった昨今ですが、未だにリモートでの仕事に難しさを感じてしまう方多いかなと思います。
この記事では、コロナ渦に入社し在宅勤務がほとんどの私がスクラムチームで開発をする中で、心理的安全性確保のために日々の業務の中で実践していることをシェアできればと思います。

# 簡単自己紹介
まずは私自身について少しだけ。
・社会人2年目
・大学は4年制大学の文系出身(未経験で入社)
・スクラムチームで開発を担当させてもらって約1.5年

# 心理的安全性とは
『チームメンバーがリスクをとることを安全だと感じ、お互いに対して弱い部分もさらけ出すことができる。』
【参照】[Google re：Work「「効果的なチームとは何か」を知る」](https://rework.withgoogle.com/jp/guides/understanding-team-effectiveness/steps/introduction/)

と書かれています。

個人的には、「気兼ねせず自分の意見を言いやすい環境。チャレンジを認めてくれ、必要であればサポートしてくれる環境」かなと思います。
もちろん外的要因が大きいとは思うのですが、自分からのアクションでも変えられる部分があるのではないかなと思います。

# 分報について
自分自身のアクションでより心理的安全性を高めるために有効だなと私が感じているのが、「分報」です。
やり方としては、良き頃合いでTeamsに投稿をしています。投稿することにあまり制限を設けてハードルを高くしたくないので、タイミングや頻度については特に細かいルールは設定していません。
どんな内容を投稿しているかといいますと、これもまた特に細かいルールは決めていません。バックログを引き取った際に「これやります！」と宣言したり、仕様検討のメモ書きを残したり、はたまた煮詰まったのでおやつとってきます宣言をしたりとかなり自由に投稿しています。(投稿というよりもボヤキに近い…)

# 個人的な分報のいいところ
1つ目は、自分の作業メモとして活用できることです。
「あれ、どうしてこの仕様にしたんだっけ」や「(月曜朝に)先週どこまで作業したんだっけ」という場面でとても重宝しています。書き出すことで自分の頭の整理にもなるので、少なくとも私には合っているかなと感じています。また、過去の分報を見返すことで、自分自身の成長も確認することができるので、成長記録(黒歴史ともいう)としても活用しています。

2つ目は、一人で抱え込まない環境ができることです。
在宅勤務がほとんどなので、どうしても1人で作業していることが多くなってしまいます。また、なにか悩んでいたり壁にぶち当たっていても当然自分から声を上げていく必要があります。自分から声を上げることの大切さは重々承知しているのですが、それでも「先輩忙しそうだな」と躊躇してしまうことがあります(今でも)。そんな場面で、「これA案かB案かどちらにしようかな」「こんなエラーが出てて動かないなwithスクショ」みたいな投稿をすると助けてもらえることが多々あります(ありがとうございます。。。)。
また、分報することで先輩としても作業状況を把握しやすく、声もかけやすいと何度かほめていただいています。作業状況の把握、コミュニケーション機会の創出という面でも分報は有用なのかなと感じています。

# 最後に
ここまで読んでいただきありがとうございました。
未熟ながらも、また色々とシェアしていければと思いますので、よろしくお願いします。
【VSCode拡張機能】Color Highlight の機能設定一覧とおすすめ設定


# Color Highlight の機能設定一覧とおすすめ設定

## 目次
- はじめに
- Color Highlightとは
- 機能設定一覧
- おすすめ設定

## はじめに
こちらの記事は、VSCodeの拡張機能`Color Highlight`の機能設定一覧とおすすめ設定について記載したものになります。

詳しくは下記サイトを参照してください
[Color Highlight](https://marketplace.visualstudio.com/items?itemName=naumovs.color-highlight)

## Color Highlightとは
ソースコード内のカラーコード(または色として認識される文字)に実際の色付けで強調表示する拡張機能です。

## 機能設定一覧

| 名前 | 説明 |  既定 | 
| :----: |:----:| :----:|
| color-highlight.enable | プラグインが有効かどうかを制御します | true |
| color-highlight.languages | カラーハイライトで強調表示する必要のある言語IDの配列、`*`は任意の言語でトリガー、言語IDの前に`！`をつけると除外(`！typescript`、`！javascript`など) | * |
| color-highlight.matchWords | すべてのファイルの色の単語を強調表示(`grey`、`green`など) | false |
| color-highlight.matchRgbWithNoFunction | `rgb()`など関数に含まれないrgb表記のものを強調表示するか(`255,255,255`、` [255, 255, 255]`、`255 255 255`など) | false |
| color-highlight.rgbWithNoFunctionLanguages | `rgbWithNoFunction`のパターンで強調表示する言語IDの配列 | * |
| color-highlight.markerType | ハイライトのスタイル、'dot-before', 'dot-after', 'foreground', 'background', 'outline', 'underline'のいずれかになる | background |
| color-highlight.markRuler | スクロールバーの色を強調表示する | true |
| color-highlight.sass.includePaths | 検索する絶対パスの配列 |  |

## おすすめ設定
私個人が設定しているおすすめ設定です。
`"markerType": "underline"`にする理由としては`background`にすると文字色と被り見えないケースがあるからです。
しかし`underline`を利用すると警告等の下線に近い形に見えるので、人に寄っては煩わしいかと思います。
その場合は`dot`系のスタイルでも良いと思います。
```
{
	// ...その他拡張機能

  // Color Highlight
  "color-highlight": {
    // すべてのファイルの色の単語を強調表示(grey、greenなど)
    "matchWords": true,
    // rgb()など関数に含まれないrgb表記のものを強調表示するか
    "matchRgbWithNoFunction": true,
    // ハイライトのスタイル、'dot-before', 'dot-after', 'foreground', 'background', 'outline', 'underline'のいずれかになる
    "markerType": "underline",
  }
}
```
アプリ全体のレビューをプルリクでもらう方法

### はじめに
現在開発しているアプリがあるのですが、先輩エンジニアの方に、アプリ全体のコードレビューをもらうことになりました。

どのような形式でレビューをいただくかをすり合わせる中で、当初、レビュー結果をSlackで共有していただくことを検討しました。
しかし、それだとお互い実際のコードを見ながら書いたりするのが結構大変だということで、空のブランチを用意し、その空のブランチに対して、プルリクをmainから出すという方法に決めました。
こうすることで、差分が生じ、通常のレビューと同じ体制が取れ負担が少ないと考えました。


### 空ブランチの作成を試みる
空ブランチの作り方で技術記事を探すと、以下の方法がよく紹介されていました。

```
git checkout --orphan [ブランチ名]
git reset --hard
```

こうすることで、空のブランチはすぐに作成ができました。

実際にこれをリモートにpushしレビュー用ブランチに向けてmainからプルリクを作成しようとすると問題がおきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1935678/1f120de0-ee4c-6455-8ca8-b1778d866899.png)


比較できるコードがないよということで、プルリクが作成できませんでした。

なるほど、本当にまっさらだと比較すらできないからプルリクが出せないのか。。。と理解。

### アプリ開発の最初のブランチからレビューブランチの作成を試みる

そこで、次に思いついたのは、リポジトリに最初に作成したブランチであれば、差分が出ていけるのでは？ということでした。

さっそくトライ。

```
git checkout [最初のブランチ]
git checkout -b [レビュー用ブランチ名]
git push origin HEAD
```

おおお！差分ができた！　これでバッチリと思いきや、妙に削除や更新の差分が存在していました。

たしかに、初回のブランチでは、eslintなどいくつかの設定をざっとやっているので、その差分のようです。

これだとfile changedが見づらくてレビューしづらそうだな。。。

### 最初のコミットからの作成を試みる

待てよ、もしかしたら本当のfirst-commitからブランチ作成ができたら開発に関わる部分のファイルはないからきれいに差分が発生してくれるのでは？
ついに、うまく行く方法を思いつきました。

![スクリーンショット 2022-03-18 8.02.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1935678/1c2cc79f-e28b-4d25-f67a-d3ae7ae49a29.png)

コミットからブランチの作成方法を調べるとありました。
実際のやり方は以下の記事を参考に進めさせていただきました。
ありがとうございます。とても助かりました！

https://qiita.com/wnoguchi/items/dabe6e05388faf75f00c

```
git checkout [指定したいコミット] -b [ブランチ名]
```



![スクリーンショット 2022-03-18 8.12.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1935678/324a30e2-70b8-7916-5560-00d688a7afc5.png)


できた！！！！

これで先輩エンジニアにレビューをプルリクベースで依頼できそうです。よかった！
WioLTEでSDカードを使う方法

# 経緯
WioLTEでSDカードを使う時にはSDforWioLTEを利用する例が多い。
しかし手元のWioLTEでは**上手く動かなかった**。
Wio LTE JP Version v1.3b
Arduino v1.8.19
SeeedJP STM32 Bords v1.8.0
WioLTEforArduino v2.13.0
SDforWioLTE v1.0.0
microSDHCカード32GB

```SDReadWrite.inoの実行結果
--- START ---------------------------------------------------
### I/O Initialize.
### Power supply ON.
### Initialize SD card.
### ERROR! ###
```
SD.begin()がエラーを返すので調べた。

# 配線
SDカードへの配線は次の通り。
|Adruino Pin #|STM32 Pin|線名|SD card Pin|Pin説明|
|:-:|:-:|:-:|:-:|:-:|
|42|PC10|SDIO_D2|DAT2|N.C.|
|43|PC11|SDIO_D3|CD/DAT3|CS|
|48|PD2|SDIO_CMD|CMD|MOSI|
|44|PC12|SDIO_CK|CLK|CLK|
|40|PC8|SDIO_D0|DAT0|MISO|
|41|PC9|SDIO_D1|DAT1|N.C|
|15|PA15|SDIO_POWR|VDD|3.3V|

# 原因
```Arduino/libraries/SDforWioLTE-master/src/utility/Sd2Card.h
/** SPI Master Out Slave In pin */
uint8_t const SPI_MOSI_PIN = 50; //11;
```
MOSIの番号を48に修正。
```修正後 Sd2Card.h
/** SPI Master Out Slave In pin */
uint8_t const SPI_MOSI_PIN = 48; //50; //11;
```

# 結果
```SDReadWrite.inoの実行結果
--- START ---------------------------------------------------
### I/O Initialize.
### Power supply ON.
### Initialize SD card.
### Writing to test.txt.
### Reading from test.txt.
test.txt:
testing 1, 2, 3.
### Setup completed.
```

動いた。めでたしめでたし。

# 余談
ボードマネージャv1.7.0ではPD2のPin番号は50だったが、v1.8.0では48に変わった。

Pin番号は以下のファイルで定義されている。
C:\Users\\{ユーザ名}\AppData\Local\Arduino15\packages\SeeedJP\hardware\stm32\1.8.0\variants\WIO_LTE\variant_WIO_LTE.cpp
JavaScript基礎概念勉強ノート2

## 簡単なプログラムの仕組み（自分なりの解説）

**input → conditional(loop, if, function) → output**


## シチュエーション：レストランの注文システム

### 疑似コード(Pseudocode)

NotionのMermaidで書いてみました。
![menupseudocode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2477698/61f04ecf-4876-4e3f-2e26-cf4c74bd7bce.png)


### コード
```
// step1 データ設置
const menus = ['ビーフバーガー', 'ダブルビーフバーガー', 'ビーフサンドイッチ']

function order(menu) {

  // step2 もし引数のmenuが当てはまったら、その条件式の関数式を行う
  if (menu === 'ビーフバーガー') {
    makeBeefBurger();
  } else if (menu === 'ダブルビーフバーガー') {
    makeDoubleBeefBurger();
  } else if (menu === 'ビーフサンドイッチ') {
    makeBeefSandwich();
  } else {

    // step3 どれも当てはまらないときエラーを出す
    console.log('メニューに載ってないんです！');
  }
}

// 分岐条件に入ったとき、値段を示す
function makeBeefBurger() {
  console.log('ビーフバーガー, price: 500')
}
function makeDoubleBeefBurger() {
  console.log('ダブルビーフバーガー, price: 600')
}
function makeBeefSandwich() {
  console.log('ビーフサンドイッチ, price: 450')
}

// step4 注文を受ける（関数式を呼び出す）
order('ダブルビーフバーガー') // ダブルビーフバーガー, price: 600
order('ビーフサンドイッチ') // ビーフサンドイッチ, price: 450
order('チキンバーガー') // メニューに載ってないんです！

//毎回字を入れるには面倒なので、データの配列を利用する
order(menus[0]) // ダブルビーフバーガー, price: 600
order(menus[2]) // ビーフサンドイッチ, price: 450
```


## 小まとめ
今回の作業はほぼノート1のまとめとしてやってみました。
最近は簡単なものコーディングしながら考えてましたが、プログラムではデータの扱い方を通して欲しい機能に対応していくものを作るような、ある順序に沿っている感じがします。
書く前にとにかくこの三つを考えています。
**どんな結果が欲しい？
入れるデータは何？（データ型、ページ？DB?どこからアクセス？）
開始条件と終了条件はどう設定する？またはどんな条件で分岐する？**
あとは書くとき、const/letで宣言の違い, ==/===（またはtruthy&falsy value）について細心を払って、すべての条件や変数は、ハードコードを避けるように念頭におくなど。
機能を作り出したら、次はアレンジに入る（コードの簡潔化、可読性など）。まだ簡単なものしか書けませんが。。
[StripeUpdates] StripeのPaymentIntentで、カード情報の保存と保存できない決済情報の処理を同時に行う方法

Stripeで支払いを処理する際に利用するPayment Intentでは、決済時に利用したカード情報を保存することができます。

これによって、ECサイトでの２回目以降の購入処理や、「手付金を請求し、後で残額を請求する」ビジネスモデルなどへの対応が可能になります。

支払い情報を保存するには、`setup_future_usage: 'off_session'`を設定しましょう。

```diff_javascript
      const pi = await stripe.paymentIntents.create({
        payment_method_types: ['card'],
+        setup_future_usage: 'off_session',
        amount: 120,
        currency: 'jpy',
      });
```

## 「保存できない」支払い方法

Stripeがサポートしている決済方法の中には、支払い情報を保存して次回以降の決済に利用することができないものも存在します。

例えばコンビニ決済は、２回目以降の注文でも顧客がコンビニで支払いを完了させる必要があるため、利用することができません。


```diff_javascript
      const pi = await stripe.paymentIntents.create({
-        payment_method_types: ['card'],
+        payment_method_types: ['card', 'konbini'],
        setup_future_usage: 'off_session',
        amount: 120,
        currency: 'jpy',
      });
```

そのため、保存できない支払い情報が含まれたPayment Intentを作成しようとすると、以下のエラーが発生します。

```log
StripeInvalidRequestError: `setup_future_usage` cannot be used with one or more of the values you specified in `payment_method_types`. Please remove `setup_future_usage` or remove these types from `payment_method_types`: ["konbini"].
```

## 保存できない支払い方法も混えて処理する方法

「保存できない決済方法もサポートしつつ、カードの情報は保存したい」ケースでは、`setup_future_usage`の設定場所を以下のように変更しましょう。

```diff_javascript
      const pi = await stripe.paymentIntents.create({
        payment_method_types: ['card', 'konbini'],
-        setup_future_usage: 'off_session',
        amount: 120,
        currency: 'jpy',
+        payment_method_options: {
+          card: {
+            setup_future_usage: 'off_session',
+          },
+        },
      });
```

`payment_method_options`側で、カード決済の時のみ保存する設定ができます。

こちらのコードであれば、APIがエラーを返さず、PaymentIntentを作成することができます。

これによって、保存できない決済情報も処理するためだけに、PaymentIntentを複数作成する必要がなくなります。

## 参考記事

https://stripe.com/docs/payments/save-during-payment

[今後の支払いのためにカードを最適化する | Stripe](https://stripe.com/docs/payments/payment-intents#future-usage)


# [PR] Stripe開発者向け情報をQiitaにて配信中！

- [Stripe Updates]：開発者向けStripeアップデート紹介・解説
- ユースケース別のStripe製品や実装サンプルの紹介
- Stripeと外部サービス・OSSとの連携方法やTipsの紹介
- 初心者向けのチュートリアル(予定)

など、Stripeを利用してオンラインビジネスを始める方法について週に２〜３本ペースで更新中です。

-> [Stripe Organizationsをフォローして最新情報をQiitaで受け取る](https://qiita.com/organizations/stripe)
OSSを組合わせた業務フロー効率化

# 内容
いろいろと課題がありましたがOSSを導入して業務フロー効率化を実施しました。
高度なプログラミングスキルがなくても導入可能な内容となっております。
![kaizen2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/8a3b5d63-da36-1cb2-2796-1c2719895dcc.png)


# 受付・作業管理
* 作業管理
まず基本的な所で作業進捗管理のためにRedmineを導入しました。
新規依頼などが発生するとRedimineにチケットを作成してタスク管理を行います。

* 作業受付
他部署からの依頼等は所定のメールフォーマットで依頼してもらうように調整。
このメールフォーマットで受け付けるとRedmineの所定のプロジェクトにチケットが自動登録される仕組みを構築しました。以後のメールやり取りも自動的にチケットに情報が追記されます。
メール内容を都度チケットに登録するという手間を効率化しました。
Cronで定期的にRedmineサーバからIMAPでメール取り込みを行う仕組みを導入しています。
[Redmineガイド-メールによるチケット登録](http://guide.redmine.jp/RedmineReceivingEmails/)

![kaizen4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/2e7894cc-a844-21da-9e98-2517e577033c.png)

# 定常作業
* 繰り返し作業自動化
ネットワーク機器の設定変更、監視設定変更など定期的に発生する作業をAnsible AWXを導入し自動化しました。内容によってはAnsibleのモジュールがなく、Shellモジュールを使用しているものもあります。PlayBookから単にShellをキックする構成は本来Ansibleを使用する必要はないかもしれませんが、作業の入り口をAWXのコンソールに揃えるためにこの構成にしました。
この作業はこのフォルダのこのshellをキックするなど作業場所を分けると手順が煩雑化するため1箇所で全ての処理を開始出来る運用としました。

![kaizen1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/5a066992-ab84-d02a-2e33-467f50ea4875.png)

* 構成管理自動化
ネットワーク機器のConfig取得などを自動化しました。GitLabと連携して変更があった際に差分を通知する仕組みを構築しました。意図しない変更が行われた際の監視の役割も兼ねています。
実施内容は[Ansible AWXとGitLabを組合わせて構成管理の仕組みを構築](https://qiita.com/Toru_Kubota/items/3742e85687361bcd410c)を参照下さい。

* 申請書自動取り込み
他部署からの依頼書の情報をPleasanter（データベース）に取り込む運用としました。
依頼書にマクロを作成しワンクリックでPleasanterに取り込む仕組みを導入しました。
また反対にPlesanterの内容から依頼書を作成する仕組みも用意しました。
仕組みはVBA内で[Pleasanter - API](https://pleasanter.org/manual/api)を使用しています。

![kaizen3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/a9425427-ade1-349f-d263-7d3c33dabf25.png)


# 情報管理
* 各種情報管理
顧客情報管理、ナレッジ管理、構成情報管理、コード管理等に使用しています。
主に構造化データはPleasanter、非構造化データはMediaWikiを使用しています。
Pleasanterはインシデント管理ツールとしても使用しています。
GitLabはAnsibleのPlayBook管理に使用。「構成管理自動化」の出力先もGitLabにしています。

* 全文検索
ツールの区分けは行っていますが、必要な情報の検索に手間がかかることがあります。対応スピードupのためRedmine,MediaWiki,Pleasanterを一括で検索する仕組みとしてFESSを導入しました。
実施内容は[Redmine/MediaWiki/Pleasanter/S3/ファイルサーバを全文検索](https://qiita.com/Toru_Kubota/items/b45d1f751c9de0733414)を参照下さい。

# まとめ
短期間でいろいろとツールをいれて改善してきました。
新しいやり方を受け入れてくれたチームメンバーに感謝しています。
引数同士での同値パターンマッチ


Elixirのコードにて2つの引数同士のパターンマッチが使われてるところがあり、そこの挙動がどうなるかがわからなくて混乱したので整理

### tl;dr

- whenと同名変数の２つのパターンマッチの方法がある

- 同名変数を使うよりも `when` を使ったほうが明示的で事故しにくいので、whenを使うべきかと思う
- ただ、構造によっては同名変数によるパターンマッチも機能するかも

### 1) 同名変数：`<val>, <val>`で同名変数を使う

```elixir
defmodule M do
  def v3(val1, val1), do: IO.inspect val1, label: "val1"
  def v3(_, _), do: raise "Cannot catch"
end

# iex ----------------------
iex> M.v3 "v1", "v1"
val1: "v1"

iex> M.v3 "v1", "v2"
** (RuntimeError) Cannot catch
    (exampe_exlixir 0.1.0) lib/exampe_exlixir.ex:17: M.v3/2
```

- つまり`v1 == v2` のチェックをしているわけなので、whenを使ったコードと同値になる。
- 変数名を変えたらパターンマッチのロジックが壊れるので、変数名がロジックに関わっている。変数名を整理するリファクタで事故する可能性があって怖い

### 2) when構文: `when v1 == v2`

```elixir
defmodule M do
  def v4(val1, val2) when val1 == val2 do
    IO.inspect(val1, label: "val1")
  end
  def v4(_, _), do: raise("Cannot catch")
end

# iex ----------------------
iex> M.v4 "v1", "v1"
val1: "v1"
"v1"

iex> M.v4 "v1", "v2"
** (RuntimeError) Cannot catch
    (exampe_exlixir 0.1.0) lib/exampe_exlixir.ex:12: M.v4/2
```

- 明示的に２つの要素が同値であることがわかる
- 変数名にロジックが依存しない
- 異字同訓になる。va1/val2という２つの変数があるが同じ値を無駄に作ってしまう

### 3) 同名変数: `%{ <key> => <val> }, <val>`のケース

ほぼ1) と同じだけど、構造が複雑になってるときも一応確認しておく

```elixir
# 変数 val を同じ名前で２箇所で利用
defmodule M do
  def v(params = %{"key" => val}, val) do
    IO.inspect val, label: "val"
    IO.inspect params, label: "params"
  end
  def v(_, _), do: raise "Cannot catch"
end

# iex ----------------------
iex> M.v %{ "key" => "my_val"}, "my_val"
val: "my_val"
params: %{"key" => "my_val"}

iex> M.v %{ "key" => "my_val"}, "next_val"
** (RuntimeError) Cannot catch
    (exampe_exlixir 0.1.0) lib/exampe_exlixir.ex:12: M.v/2
```

### 4) when：`%{ <key> => <val> }, <val> when <val> == <val>`のケース

ほぼ2) と同じだけど、構造が複雑になってるときも一応確認しておく

```elixir
defmodule M do
  def v5(params = %{"key" => val1}, val2) when val1 == val2 do
    IO.inspect(val1, label: "val1")
    IO.inspect(params, label: "params")
  end

  def v5(_, _), do: raise("Cannot catch")
end

# iex ----------------------
iex> M.v5 %{"key" => "v"}, "v"
val1: "v"
params: %{"key" => "v"}

iex> M.v5 %{"key" => "v"}, "vx"
** (RuntimeError) Cannot catch
    (exampe_exlixir 0.1.0) lib/exampe_exlixir.ex:15: M.v5/2

iex> M.v5 %{"key_x" => "v"}, "v"
** (RuntimeError) Cannot catch
    (exampe_exlixir 0.1.0) lib/exampe_exlixir.ex:15: M.v5/2
```


## 終わり

終わりです
C++でC++のコードをコンパイルして実行する。

## 目的
コンパイラをその場で起動して実行してもそれはJust In Timeなコンパイルと呼べる。
g++を `system` で呼んで `dlopen` で開いて関数を探して呼んでも目的は達成できる。
C++のコードを書いて吐き出してコンパイルするまでのオーバーヘッドは大きいが、代わりに定数などをJITコンパイル対象のコードの中に埋め込めるので関数が充分に重い場合にはペイすることもある。

## コード
```c++
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <functional>
#include <dlfcn.h>

int main() {
  std::string code = R"(
#include <iostream>
extern "C" int hello() {
  std::cout << "This function is JIT compiled\n";
  return 128;
}
)";
  std::ofstream of;
  of.open("tmp.cpp");
  of << code;
  of.close();

  system("g++ -std=c++11 -c -O2 tmp.cpp -o tmp.o -fPIC && g++ -shared -o tmp.so tmp.o");
  void* dll = dlopen("./tmp.so", RTLD_LAZY);
  if (!dll) {
    fprintf(stderr, "%s\n", dlerror());
    exit(EXIT_FAILURE);
  }

  int (*hello)() = (int(*)())dlsym(dll, "hello");

  if (char* error = dlerror()) {
    fprintf(stderr, "%s\n", error);
    exit(EXIT_FAILURE);
  }
  std::cerr << "result: " << hello() << std::endl;

  dlclose(dll);
}
```

## 実行結果

```text:
result: this function is JIT compiled
128
```
tailwindcss導入

割と自分用メモ的要素が強め

postcssとかいっぱいクラス名理解しなきゃとかでビビってましたが重い腰を上げて手を付けました。
**導入自体は思ってたより100倍簡単だった。**
クラス名覚えたり使いこなすのはまだ大変そう。

出力されるcssを読み込むって手順は同じだと思うのでhtmlでもたぶんReactとかでも全部同じ感じです、たぶん。
この記事ではExpress+pugで書いています。

公式サイトのインストール方法はこちら↓

https://tailwindcss.com/docs/installation/

**目次**
- [導入](#導入)
- [補足](#補足)


## 導入

Expressのプロジェクト作成は省略。
`npx express-generator`かなんかで作成してください。

### 1. インストール
```
npm install -D tailwindcss
npx tailwindcss init
```

`npx tailwindcss`を実行すると`tailwind.config.js`が生成されます。

### 2. 設定
生成されたconfigファイルの`content`に読み込む対象のファイルを書く。
詳しくは[こちら](https://tailwindcss.com/docs/configuration)。

```js:tailwind.config.js
content: [
  './views/**/*.{pug,html}'
],
```

### 3. 読み込みファイル作成
今回は入力のファイルを`public/styles/tailwind/main.css`に作成する。

```css:public/styles/tailwind/main.css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

### 4. 出力
次のコマンドで実際に使うcssを出力する。
```
npx tailwindcss -i ./public/styles/tailwind/main.css -o ./public/styles/tailwind/tailwind.css
```
`package.json`の`scripts`に入れておくと便利。
`--watch`オプションでホットリロードできる。

`-i`オプションのパスが先ほどの入力ファイル、`-o`オプションのパスに出力される。

あとは出力された方のcssファイルを読み込む。
※publicフォルダは静的ファイルフォルダに指定されてます。

```js:index.js
app.use(express.static(path.join(__dirname, 'public')));
```

```pug:layout.pug
//- 生成されたcssを読み込む（htmlでも同様）
link(rel='stylesheet', href='/styles/tailwind/tailwind.css')
```

```pug:index.pug
p.text-orange-300 オレンジのテキストです
p.bg-lime-200 緑の背景です
```

## 補足
tailwindcssの仕組み的なことの補足です。

tailwindcss自体はpostcssのプラグインらしい。
postcssは入力のcssファイルをもとにcssファイルを出力する仕組み。
cssを読み込んで中間処理とか独自の処理とかを通してcssを出力する。
入力の`@tailwind`はここで何か処理されるんだと思う。

tailwindcssの出力ファイルには、読み込み対象（configのcontent）の中で使用されているクラス名（とリセットcss的な内容）だけが記載されたcssが出力される。

もちろん出力ファイルは出力コマンドを実行するたび、ホットリロードならpugとかを書き換えるたびに更新され、使用されなくなったクラスはその時に削除される。

[追記]
pugとtailwindは相性よくないかも。
pugの

```
.container.card
  span.nantoka-class 赤いテキストです
```

みたいな書き方が疑似要素を付けようとするとできなくなる。
`hover`とかの疑似要素を指定したい時はtailwindcssでは

```html
<span class="hover:gb-blue-500">ホバーで青い背景になる</span>
```

のように書くけどpugではコロン `:` でエラーとなる。
tailwindの`:`を使った処理を使いたい時は

```
span(class="hover:bg-blue-500") ホバーで青い背景になる
```

って括弧でくくる必要がある。
基本のレイアウト作るくらいなら影響ないし括弧使えばいいだけだけど。
plotlyでリニア対数表示をドロップダウンで切り替えるhtmlを生成する最も簡単な例

# はじめに

plotly を用いて、簡単なhtmlを作成したいだけだが、リニアとログの切り替えまではボタンで簡単にできるようにしたい場合に、簡単な例が見つからなかったので紹介してみます。縦軸と横軸の log or linear に変換するためのドロップボックスのボタンを付けたシンプルなな例です。plotlyが動く環境であれば、下記のコードのコピペで動くはず。

## 概要

最低限の２つの関数を用意した。

- setdata(): 簡単なデータ(x,y)を作成し、それを用いて go.Scatter のリストを作成する。
- writehtml(): setdata()で作成した data を用いて、レイアウトと、dropdownボタンを設定し、html で書き出す。

データを生成し、plotlyのグラフのオブジェクトのリストを生成し、レイアウトやボタンの調整をして、html を書き出す、というだけの機能です。

## 実装例

```python  plotly_xydata.py:
#!/usr/bin/env python 

import plotly.graph_objects as go
import numpy as np

def setdata():
    # fill data
    data = []
    for i in range(5):
    
        x = np.linspace(1,12,1024)
        y = np.abs(np.exp(-x) * np.sin(i*x) + 1.0) # y = |exp(-x)*sin(nx)+1|
    
        trace = go.Scatter(
                x=x,
                y=y,
                visible=True,
                line=dict(width=2),
                name=str(i)
                )
        data.append(trace)
    return data

def writehtml(data,htmlname="checkploty.html"):
    # set layout
    layout = go.Layout(title="plotly test",xaxis=dict(title="Time (s)"),yaxis=dict(title="a.u.")) 
    fig=go.Figure(layout=layout,data=data)
    fig.update_yaxes(type="log")
    fig.update_xaxes(type="log")
    fig.update_yaxes(exponentformat='none')
    fig.update_xaxes(exponentformat='none')
    
    # add dropdown
    fig.update_layout(
    updatemenus=[
            dict(
                buttons=list([
                        dict(
                            args=[{"xaxis.type": "log"},{"yaxis.type": "log"}],
                            label="xlog-ylog",
                            method="relayout"
                            ),
                        dict(
                            args=[{"xaxis.type": "linear"},{"yaxis.type": "linear"}],
                            label="xlin-ylin",
                            method="relayout"
                            ),
                        dict(
                            args=[{"xaxis.type": "log"},{"yaxis.type": "linear"}],
                            label="xlog-ylin",
                            method="relayout"
                            ),
                        dict(
                            args=[{"xaxis.type": "linear"},{"yaxis.type": "log"}],
                            label="xlin-ylog",
                            method="relayout"
                            ),
                        ]),
            direction="down")
            ])
    
    # write html 
    fig.write_html(htmlname)
    print("[Save]", "save as ", htmlname)

data = setdata()
writehtml(data)
```

## 実行例

### log-log の例

![スクリーンショット 2022-03-18 3.35.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179652/3a211134-ff4a-4aa5-32f6-5afc6e720f23.png)

### linear-linear の例

![スクリーンショット 2022-03-18 3.49.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179652/6e3b1e7e-3c71-0e7e-c231-aee71fac1d07.png)


### plotly の legend の使い方について

plotly の html は、legend を一回クリックすると、そのデータが見えなくなり、ダブルクリックすると、そのデータ以外は見えなくなります。たくさんデータあっても、クリックすれば取捨選択できるのでとっても便利です。
高速な素数判定法

```c++
#include <math.h> 

bool IsPrime(int num)
{
    if (num < 2) return false;
    else if (num == 2) return true;
    else if (num % 2 == 0) return false; // 偶数はあらかじめ除く

    double sqrtNum = sqrt(num);
    for (int i = 3; i <= sqrtNum; i += 2)
    {
        if (num % i == 0)
        {
            // 素数ではない
            return false;
        }
    }

    // 素数である
    return true;
}
```
最小全域木問題

[問題](https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_12_A&lang=jp)

確定済みの頂点の中から最短ルートを見つけるのを繰り返すプログラムである

```c++
//プリム法 (計算量: O(|V|^2))
vector<vector<int>> G; 

struct Prim {
    const int INF = 1e9;
    int sum;              // 重みの総和
    int n;                // 頂点数
    vector<int> mincost;  // 既に確定した頂点からの最小コスト（確定済みから行けない時は INF）
    vector<bool> used;    // 既に確定したかどうか
    Prim(vector<vector<int>> const& Graph) {
        init(Graph); //最小全域木
    }
    void init(vector<vector<int>> const& Graph) {
        n = (int)Graph.size(); //頂点数
        mincost.assign(n, INF); //コスト
        used.assign(n, false); //確定済みか
        sum = 0;
        mincost[0] = 0;  // 始め頂点0からスタートさせる
        while (true) {
            int v = -1;
            for (int u = 0; u < n; u++) {  //未確定 && (最初 || 最小値)
                if (!used[u] && (v == -1 || mincost[u] < mincost[v])) v = u;
            }
            if (v == -1) break;  //全頂点確定済み
            used[v] = true;
            sum += mincost[v];
            for (int u = 0; u < n; u++) {  // 確定した頂点から行ける頂点について、最小コストを更新
                if (Graph[v][u] != -1) //つながっているなら
                  mincost[u] = min(mincost[u], Graph[v][u]);
            }
        }
    }
};

int main() {
    int n;
    cin >> n; // 頂点数
    G.assign(n, vector<int>(n));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {//(i==jの時は-1)
            cin >> G[i][j]; //重み
        }
    }
    Prim prim(G);
    cout << prim.sum << endl;
    return 0;
}
```
UIRefreshControlを使ったPullToRefreshでrefreshのタイミングを変えたい

## はじめに
https://developer.apple.com/documentation/uikit/uirefreshcontrol

を参考にしたUIRefreshControlに
`addTarget(self, action: #selector(refresh), for: .valueChanged)`
するやり方だとrefreshのタイミングに違和感があったので別のタイミングでrefreshを行いたかった

## 結論

UIScrollViewのdelegateの任意のタイミングでrefreshの処理を呼び出しましょう
個人的にはscrollViewWillEndDraggingかscrollViewWillBeginDeceleratingぐらいで
refreshするのがsafariやtwitterのPullToRefreshに近くてしっくりきました

```
class XXXViewController: UIViewController, UIScrollViewDelegate {
    
    @IBOutlet weak var webView: WKWebView! {
        didSet {
            webView.scrollView.delegate = self
            webView.scrollView.refreshControl = UIRefreshControl()
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    private func refresh() {
        reload()
    }
    
    private func didRefresh() {
        webView.scrollView.refreshControl?.endRefreshing()
    }
    
    // 指を離してスクロール位置が上まで戻った時
    func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
        guard let isRefreshing = webView.scrollView.refreshControl?.isRefreshing else { return }
        if isRefreshing {
            webView.refresh()
        }
    }
    
    // 指を離した時
    func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        guard let isRefreshing = webView.scrollView.refreshControl?.isRefreshing else { return }
        if isRefreshing {
            webView.refresh()
        }
    }
    
}

```


## おまけ
addTargetするやり方も一応記載しておきます
下に引っ張ると閾値(50ptぐらい？)を超えたタイミングでrefreshが呼び出されます

```
class XXXViewController: UIViewController {
    @IBOutlet weak var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        webView.scrollView.refreshControl = UIRefreshControl()
        webView.scrollView.refreshControl?.addTarget(self, action: #selector(refresh), for: .valueChanged)
    }
    
    @objc
    private func refresh() {
        reload()
    }
    
    private func didRefresh() {
        webView.scrollView.refreshControl?.endRefreshing()
    }
    
}
```
100日でSQLの達人になる@LeetCode! Day46 <要復習: UNIONの代わりにORでできる？>

## 1412. Find the Quiet Students in All Exams （問題レベル: Hard）要課金
今日の問題はこれ。
複数の試験があり、どの試験でも最高点あるいは最低点を取っていない生徒をリストアップするという問題。
ただし、どの試験も受けていない生徒は除外する。

少し試行錯誤しましたが自力で`Accept`されました。

提出した解答は下記。`WITH`句で最高点あるいは最低点を取った生徒IDををリストアップして、`NOT IN`で欲しい生徒IDを選び出すという考え方。
```:SQL
WITH cte AS
(SELECT DISTINCT student_id
FROM exam e
JOIN (
SELECT DISTINCT exam_id, MIN(score) OVER(PARTITION BY exam_id) AS score
FROM exam
UNION　ALL
SELECT DISTINCT exam_id, MAX(score) OVER(PARTITION BY exam_id) AS score
FROM exam
) s
ON e.exam_id=s.exam_id
WHERE e.score = s.score)

SELECT student_id, student_name
FROM student
WHERE student_id NOT IN (SELECT student_id FROM cte) AND student_id IN (SELECT student_id FROM exam)
```
`Discuss`を見ると`UNION`は使わず`OR`を使った良いという意見がありました。また、`ROW_NUMBER`を使った解答が高評価を得ていました。
```:SQL
-- ORの使用例
WHERE e.score=s.max_score or e.score=s.min_score
```
今日のポイントは`UNION`の代わりに`OR`が使えるかを考慮しようとしました。

追記：自分の記事を見返したらDay4で同じこと言っていますね！成長しよう。

* [LeetCode](https://leetcode.com/)の問題は、`MS SQL Server`で解いています。
MATLABで行うFFT ~1行でパワースペクトル解析~


# Table of contents
- [はじめに](#はじめに)
- [前準備](#前準備)
- [パワースペクトル解析＆図示](#パワースペクトル解析＆図示)
- [おわりに](#おわりに)
- [おまけ：記事作成について](#おまけ：記事作成について)

# はじめに

[MATLABで行うFFT ~ 時系列データ生成から片側スペクトルの正規化まで ~ ](https://qiita.com/Hernia_Baby/items/9ad96a7a046671911711)では長々とFFTをかけて~~パワースペクトル~~最大振幅を求めて図示していました。

それがなんと1行でできちゃうんです!
それもめっちゃいいかんじに…

  

今回はそんな神関数 [pspectrum](https://jp.mathworks.com/help/signal/ref/pspectrum.html) を使って正弦波のパワースペクトルを解析します。

  
# 前準備

まずは信号を作りましょう。

時間等の設定をおこないます。

```matlab:Code
dt = 0.001;
L  = 5000;
t = 0:dt:dt*(L-1);
Fs = 1/dt;
```

15Hzの振幅2の正弦波です。実効値は$V_{rms} =\frac{V_{max}}{\sqrt{2}}$です。

```matlab:Code
f1 = 15;
x = 2*sin(2*pi*f1*t);
```

図示します。

```matlab:Code
figure
plot(t,x,'Color',[.6 .6 .6])
hold on
yline(max(x)./sqrt(2),'--r');
yline(0,'k');
ylim([-1 1].*2.5)
xlim([0 1])
xlabel '時間[s]'
ylabel '信号V'
hold off
```
![figure_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/781521/54d680f1-17df-20ba-79d1-6fdc200ef0dd.png)


  
# パワースペクトル解析＆図示

ここからは一瞬です。

```matlab:Code
[p,f] = pspectrum(x,Fs);
```

ここで出力される p はパワースペクトルです。

時系列信号を $x(t)$ として、その周波数表現を $X(f)$ とすると、パワースペクトル$P(f)$ は以下のようになります。

$P(f) = X(f)^2$

振幅の実効値の二乗ですね。

$f$ は片側スペクトルになってます。

つまり、もう**計算おしまい**です。

![image_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/781521/359a5462-fffe-3647-e7a0-03e5dfb609f9.png)

それでは図示しましょう。

```matlab:Code
figure
plot(f,p,'--');
xlabel '周波数[Hz]'
ylabel '平均パワーP(f)/Hz'
ylim([0 2.5])
hold on
idx = knnsearch(f,f1);
scatter(f(idx),p(idx),'o')
name = round(p(idx),3);
text(f(idx),p(idx)+0.1,cellstr(num2str(name)));
xlim([0 50])
hold off
```

![figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/781521/d04e251d-59c2-8dc4-6331-93a6e41426bc.png)


リークなども補正されており、かなりいい感じになっています。

  
# おわりに

実はこの関数、オーバーラップ量や窓の調整、stftまでできてしまいます。や、やりたかったことが…すべて…

ただ位相は見ることができないので、そこは自分で作らなければいけないかも知れないですね。

位相は [こちら](https://jp.mathworks.com/help/matlab/ref/angle.html) に書かれています。

  
# おまけ：記事作成について

今回は[Table of Contents の追加：Live Script から Markdown への自動変換](https://qiita.com/eigs/items/ad27da605753cdce0a3e) を参考に作成しました。

非常に助かっております。
【Docker】Rails API + Reactの環境構築

## はじめに
　本記事は、プログラミング初学者、学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。
　そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。
　間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。

## DockerでReactの開発環境を構築する方法
### Docker-compose.yml

```docker-compose.yml
version: '3.9'
 
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: passwordadmin
      MYSQL_DATABASE: mydb
      MYSQL_USER: root
      MYSQL_PASSWORD: passwordadmin
      TZ: 'Asia/Tokyo'
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    volumes:
      - ./docker/db/data:/var/lib/mysql
      - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./docker/db/sql:/docker-entrypoint-initdb.d
    ports:
      - 3306:3306
  api:
    build: 
      context: ./api/
      dockerfile: Dockerfile
    command: /bin/sh -c "rm -f /myapi/tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    image: rails:dev
    volumes:
      - ./api:/myapi
      - ./api/vendor/bundle:/myapi/vendor/bundle
    environment:
      TZ: Asia/Tokyo
      RAILS_ENV: development
    ports:
      - 3000:3000
    depends_on:
      - db
  front:
    build: 
      context: ./front/
      dockerfile: Dockerfile
    volumes:
      - ./front:/usr/src/app
    command: sh -c "cd reactapp && yarn start"
    ports:
      - "8000:3000"
volumes:
  mysql_data:
    driver: local

```

### Rails側のDockerfile

```Dockerfile:Dockerfile
FROM ruby:2.7.1
 
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
 
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs yarn
 
RUN mkdir /myapi
WORKDIR /myapi
COPY Gemfile /myapi/Gemfile
COPY Gemfile.lock /myapi/Gemfile.lock
RUN bundle install
COPY . /myapi
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
 
CMD ["rails", "server", "-b", "0.0.0.0"]
```

```entrypoint.sh
#!/bin/bash
set -e
 
# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapi/tmp/pids/server.pid
 
# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
```

```Gemfile:Gemfile
source 'https://rubygems.org'
gem "rails", "6.0.2.1"
```

### React側

```Dockerfile:Dockerfile
FROM node:14.15.4-alpine  
WORKDIR /usr/src/app
```
EC2にcronで定期タスクを実行させる

# 概要
日常の仕事で、タスクやスクリプトを定期実行すると言うシーンがございますでしょうか。
Amazon EventBridgeとLambdaの組み合わせで一般問題を解決する事ができると存じますが。
Lambdaに対して、最大実行時間が15分という制御がございます。
実行時間が長いタスクに対して、相応しくないと存じます。
EC2は計算時間を制御してないです。
今回EC2にcronの設定方法をご紹介させて戴きます。

# 手順

## EC2に接続

```
sudo su --login ec2-user

```

 
# 定期pythonタスクを定義
```
import slackweb
import time
slack = slackweb.Slack(url="xxxxxxxxxxxxx")

flg = True
while flg:
    time.sleep(60)
    now = time.strftime("%a %b %d %H:%M:%S %Y", time.localtime())
    print(now)
    slack.notify(text=now)
```
無限ループを定義します。
ループに1分ごとを待って、サバーの時間を取得して、slackに投稿します。

#  時間を取得
```
$ date
Thu Mar 17 15:15:21 UTC 2022
```

# cronによる定期実行

```
crontab -e
```
↑のコマンドでcrontabファイルを編集します。

```
17 15 * * * /usr/bin/.pyenv/shims/python /home/ec2-user/ec2-cron-test/test.py
20 15 * * * kill -9 $(ps -ef | grep "test.py" | grep -v grep | awk '{print $2}')
```
crontabファイルに以上のコードを定義します。
UTC 15:17分から、pythonファイルを実行させます。
15:20になったら、pythonファイルの実行をkillします。

# ログ確認
```
sudo tail -f /var/log/cron

Mar 17 15:17:01 ip-xx-xx-xx-xx CROND[21458]: (ec2-user) CMD (/usr/bin/.pyenv/shims/python /home/ec2-user/ec2-cron-test/test.py)
Mar 17 15:20:01 ip-xx-xx-xx-xx CROND[21500]: (ec2-user) CMD (kill $(ps -ef | grep "test.py" | grep -v grep | awk '{print $2}'))
```
cronのログファイルに実行のコマンド履歴を確認できます。

# 結果確認

![截屏2022-03-18 00.22.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2531066/f57ed080-f3ce-66c3-a0e1-29406d5b69bf.png)


EC2にcronの設定方法紹介は以上となります。
pretty_midiのget_piano_rollを使ってみる

# はじめに
pythonでMIDIを扱うパッケージである，pretty_midiの中にピアノロールを取得できるメソッドがあるので使ってみます．

# pretty_midi.PrettyMIDI.get_piano_roll
example.midというファイルをピアノロール表示したい場合，
```python:サンプルコード
midi = pretty_midi.PrettyMIDI("example.mid")
piano_roll = midi.get_piano_roll()
print(piano_roll)
```
という感じで使えます．

[pretty_midiのドキュメント](https://craffel.github.io/pretty-midi/index.html?highlight=piano#pretty-midi-prettymidi)によると
get_piano_rollの引数には，
サンプリング周波数，時間，ペダルの閾値を設定できます．
## サンプリング周波数
これはpiano_rollの行（時間方向）の１秒間あたりの区切りの数を表しています．

デフォルトは１００となっているので，テンポ６０の曲なら，1拍が１００分割で表され，テンポ１２０なら１泊が５０分割で表されます．

もし，テンポ６０の曲でサンプリング周波数を４に設定すると，１６分音符で分割した時を表しています．

## 時間
これはサンプリングされた各要素がはじますタイミングを秒数で示した行列になります．

言葉で説明するのは難しいので例を出すと，
このデフォルト値は`np.arange(0, get_end_time(), 1./fs)`と書かれています．

get_end_time()もPrettyMIDIのメソッドで，曲が終わる時間を取得します．

fsは先ほど説明したサンプリング周波数です．

曲が終わる時間を100sとして，サンプリング周波数が10の場合，
`[0, 0.1, 0.2, ・・・ 99.7, 99.8, 99.9]`
のように表されます．

これは，piano_rollが曲の0秒の時点，0.1秒の時点，0.2秒の時点・・・で区切られているということを表しています．

なので，この時間をうまく変更すれば，
シャッフルビートの入っている曲を８分音符として表す，みたいなこともできそうです．

上記二つの引数の情報から，get_piano_rollは，秒数指定を元にしているので，
拍の情報からピアノロールを取得する訳ではないみたいです（テンポも計算しないとできない）．


## ペダルの閾値
これはサステインペダルがオンになっているかどうかを判断するためにあります．
ペダルのオンオフは，音の持続時間に影響してきます．
ペダルの情報はコントロールチェンジというMIDIの情報に含まれているようです．

デフォルトでは64となっているので
コントロールチェンジの情報が64以上でペダルオン，63以下でペダルオフとなります．

ドキュメントを見て少し混乱したのが，
コントロールチェンジにはコントロール番号というものがあり，
コントロール番号によってサステインペダルの他にもさまざまな情報を管理しています．
サステインペダルに関するコントロール番号は64となっています．
これは，デフォルトの閾値である64とは関係がないのですが，
最初はごっちゃになってしまって混乱しました．

## 出力（piano_roll）
出力である，np.ndarrayのシェイプは音高×曲の長さです．
音高は１２８で表されています．
曲の長さは上記で説明した時間の長さと等しいです．

複数楽器の場合は，全てまとめて表されているので楽器の区別はできないみたいですね．

内部の数値はおそらく音量が表されています．

ただ，実際データを使って見てみると，
楽譜でみると無いはずの音が，0ではないところもあったのでもう少し使い方について検討しようと思います．

※追記
もう一度確認してみたところ，↑の問題はなぜか直っていました．
おそらく，midiのテンポとサンプリング周波数のずれによってこの問題が起こっていたのではないかと思います．
pretty_midiにはestimate_tempoやget_tempo_changesというメソッドも用意されていて，midiのテンポ推定も行うことができたので，それも駆使すればテンポと絡めてピアノロールを得ることができそうです．
get_tempo_changesに関しては，テンポが変わる秒数と，テンポが返ってきます．
estimate_tempoは推定されたテンポから最も良いものを取ってきます．
ただ，このestimate_tempoの精度があまり良くない気がします・・・．
実際はテンポ120の曲ですが，このメソッドの結果では215となりました．
なのでget_tempo_changesのテンポの方の返り値を用いた方が良いと思います．


# （余談） Pathlibやglobと併用した場合

余談ですが，PrettyMIDIオブジェクトの作成の際に，
私の場合はpathlib.Pathとglobと併用して使っていたのですが，
```python:pathlibを使った場合（間違い）
dir = pathllib.Path("./data/midi/")
files = dir.glob("*.mid")

for file in files:
    midi = pretty_midi.PrettyMIDI(file) //ここでエラーが出る
    piano_roll = midi.get_piano_roll()
    print(piano_roll)
```
上記のように書くとエラーが出ました．
```python:エラー文
AttributeError: 'PosixPath' object has no attribute 'read'
```
下のように変更すると直りました．
```python:pathlibを使った場合（修正版）
dir = pathllib.Path("./data/midi/")
files = dir.glob("*.mid")

for file in files:
    midi = pretty_midi.PrettyMIDI(str(file)) //文字列に変換してから
    piano_roll = midi.get_piano_roll()
    print(piano_roll)
```
PrettyMIDIがPathLikeオブジェクトに対応していないのが原因らしいです．

# 終わりに
個人的には，秒数指定ではなく，
拍や小節単位で使えたら良いなと思っていたので，少し残念です．
cancancanのテストをRSpecで書く

cancancanを使った際、テストに学びがあったので投稿します。

# 前提：cancancanとは

権限による制御が簡単にできるgemです。
- [cancancan](https://github.com/CanCanCommunity/cancancan)
- [Rails|CanCanCanの使い方解説](https://weseek.co.jp/tech/1211/)
↓私も1つ記事を書きました。
- [cancancanでモデル名に紐づかない制御をする方法](https://qiita.com/m-ito27/items/784f22bec151cc2f1e28)

# cancancanのテスト
requestスペックなどで特定の権限が各アクションを実行できるかどうかをテストする方法もあると思いますが、今回はcancancanが用意しているmatcherを使ってテストする方法を紹介します。

- 参考
https://github.com/CanCanCommunity/cancancan/blob/develop/docs/testing.md

```ruby:ability_spec.rb
require "cancan/matchers"

describe "User" do
  describe "abilities" do
    subject(:ability) { Ability.new(user) }
    let(:user) { nil }

    context "when is an account manager" do
      let(:user) { create(:account_manager) }

      it { is_expected.to be_able_to(:manage, Account.new) } 
    end
  end
end
```
コード例は、上記ドキュメントに書いてあるままです。
ポイントは、`cancan/matchers`をrequireすることで`be_able_to`というmatcherを使えるようになるというところだと思います。

# 注意点

複数の権限をテストするときは注意が必要です。
例えば、下記のようなかたちで権限を設定しているとします。

```ruby:ability.rb
def initialize(user)
  can :read, Profile
  can :read, Job
  cannot :read, Account
end
```

この時、RSpecを以下のようなかたちにすると、テストが通ります。
```ruby:ability_spec.rb

let(:user) { create(:user) }

it { is_expected.not_to be_able_to(:read, [Profile.new, Account.new]) }  # => テスト通る
```
この結果は、私の直感に反していました。
Profileには**can: readを設定しているので、テストは失敗するのではないか**と思ったからです。
一方で、以下のテストは失敗します。
```ruby:ability_spec.rb
let(:user) { create(:user) }

it { is_expected.to be_able_to(:read, [Profile.new, Job.new]) } # => テスト通らない
```
どちらもreadにはcanを設定しているのですが、失敗してしまいます。

どうやら`be_able_to`の第２引数には配列を渡してもまとめてチェックしてくれるわけではないみたいです。
（権限設定側では、`can :read, [Profile, Job]`のかたちでまとめて権限付与できます）

したがって、最適解かどうかはわかりませんが、`aggregate_failures`などを使って１行ずつ書いていくといった方法が良いのかなと思いました。
```ruby:ability_spec.rb
let(:user) { create(:user) }

it 'テスト内容' do
  aggregate_failures do
   is_expected.to be_able_to(:read, Profile.new)
   is_expected.to be_able_to(:read, Job.new)
  end
end
```

ちなみに、`be_able_to`の第１引数はまとめて記載できます。
```ruby:abitliy.rb
def initialize(user)
  can [:create, :read], Profile
end
```
上記の設定をしているとき、以下のテストはコメントに書いてある通りの結果になるので、第１引数は配列のかたちでまとめて書いてしまって問題なさそうです。
```ruby:ability_spec.rb
let(:user) { create(:user) }

it { is_expected.to be_able_to([:create, :read], Profile.new) } # => テスト通る
it { is_expected.to be_able_to([:create, :update], Profile.new) } # => テスト通らない（updateはcanの設定をしていないので期待通り）
```

間違いなどあったらご指摘ください。
Unityで作ったゲームをOculus Quest2で実行したい


# 開発環境
Unity: 2020.3.30f1
Device: Oculus Quest2
Oculus Integration: Version 37.0
mac OS Big Sur: Version 11.6

# 手順
1. シーンの追加
1. プラットフォームの切り替え
1. XR Pluginのインストール
1. Build & Run!

# 1. シーンの追加
メニューバーの```File```→```Build Settings```を開きます。
```Add Open Scenes```を押し、作成したScene（今回は```Scenes/SampleScene```）を追加しましょう。

# 2. プラットフォームの切り替え
次に、```Platform```で```Android```を選択し、右下の```Switch Platform```でプラットフォームを切り替えます。。。結構時間かかります。。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805717/3793effd-ce3e-d02d-7200-661f69d5827e.png)

いくつかウィンドウが出てきますが、Upgrade→RestartでOKです。

# 3. XR Pluginのインストール
再度Unityが立ち上がったら、Build Settingウィンドウの左下にある```Player Settings```を押します。

Project Settingsウィンドウが開くので、左下にある```XR Plugin Management```を選び、```Install XR Plugin Management```。。。少し時間がかかります。。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805717/77a4d509-a9ad-6705-959c-ded97c8df274.png)

```Plug-in Providers```で```Oculus```を選びましょう。。。さらに時間がかかります。。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805717/66d05ce4-5d1d-4e24-931e-8eb32084f939.png)

# 4. Build & Run!
完了したら、Project Settingsウィンドウは閉じ、Build Settingsウィンドウの```Build and Run```で終わり！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805717/333d9991-64bc-b90e-5a04-2a844bda9b67.png)