OmniAICreator/Qiita-1.07M huggingface dataset:
Leetcode 30 天挑戰, Week 2 Day 7, Perform String Shifts, in Swift

資料結構或演算法： `String` `Math`

- 挑戰頁面 - <https://leetcode.com/explore/challenge/card/30-day-leetcoding-challenge/529/week-2/3299/>

這一題好像是新的，還沒有原先題目頁面。

## 思維

這題應該算是數學歸納的問題，步驟說明、演算法有更好解或是複雜度分析有問題的話都請留言告訴我。

### 步驟

- 算出最終移動的方向（概念和前一天的題目相同，題目筆記之後再補）
  - 往左就 -1 ，往右就 +1
- 總部數是 0 就直接回傳
- 因為移動超過字串長度後就會開始循環做同樣的事情，於是除以字串長度取得餘數
- 根據分析會發現 (往左 + 字串長度) 會和 往右 會有同樣的效果，因此如果是負值的話將它加上字串長度
- 接著一個一個把最後一個字元往前移動到前面
- 生成字串物件回傳

## 程式碼

``` swift
class Solution {
    func stringShift(_ s: String, _ shift: [[Int]]) -> String {
        if s.count <= 1 { return s }
        
        var moves = 0
        
        // 取得算出所有移動後的最終步數
        for pair in shift {
            var direction = pair[0]
            var steps = pair[1]
            switch direction {
                case 0: moves -= steps
                case 1: moves += steps
                default: break
            }
        }
        
        // 為零就直接回傳
        if moves == 0 { return s }

        // 必要之惡
        var characters = Array(s)
        var length = characters.count

        // 把步數正規化到 -length + 1 到 length - 1 之間
        moves %= length
        
        // 若步數為負值，把它轉換成相對應的正值
        if moves < 0 {
            moves += length
        }

        // 移動...移動...移動...
        while moves > 0 && moves <= length {
            characters.insert(characters.removeLast(), at: 0)
            moves -= 1
        }
        
        return String(characters)
    }
}
```

### 高階函數

如果熱愛高階函數的話，可以把算出最終步數的地方改成這樣

``` swift
var moves = shift.reduce(0) { $0 + ($1[0] == 0 ? -1 : 1 ) * $1[1] }
```

想要把程式碼整體變短還有更激進的做法，不過會大大降低程式碼的可讀性在這邊就不繼續做了。

## 複雜度分析

- 時間複雜度： O(max(s.length, shift.length))
  - 全部執行都是單層迴圈，因此就看誰的數量比較多。
- 空間複雜度： O(s.length)
  - 轉成 characters 應該是必要之惡（翻白眼）

## 結果

寫的時候樣本數不足因此無法知道在幾趴的地方 :older_man_tone2:

``` text
Runtime: 8 ms
Memory Usage: 21.6 MB
```

改成高階函數的運行結果如下（是壞掉了？）

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41979/2ada2737-add6-1138-457c-e9e655a12f1d.png)


## 自己的 Testcase

直接貼到他提供的框框裡面即可

``` text
"abc"
[[0,1],[1,2]]
"abcdefg"
[[1,1],[1,1],[0,2],[1,3]]
"wpdhhcj"
[[0,7],[1,7],[1,0],[1,3],[0,3],[0,6],[1,2]]
```
TensorFlow 2 で module 'tensorflow' has no attribute 'app' エラーが出る

git clone してきたプログラムを、tensorflow 2 で動かそうとすると、`module 'tensorflow' has no attribute 'app'` エラーが出たときの解消（してない？）方法です。

# エラー
とあるプログラムを Github からクローンして動かそうとするとエラーが出るので、試しに手で打ってみても同じくエラー。

```
>>> import tensorflow as tf
>>> tf.app.flag
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'tensorflow' has no attribute 'app'
```

ちょっと調べてみたら原因はすぐにわかった。

# 原因：V２ ではすでに削除されている・・・

>  in this tensorflow 2 guide, https://www.tensorflow.org/guide/effective_tf2, it says tf.app is removed. 

https://github.com/tensorflow/tensorflow/issues/34431

# 解決方法
アンインストールして、バージョン１の新しそうなのを入れました、解決（違う）。

```
pip uninstall tensorflow
pip install tensorflow==1.15
```
Typescript&VueでのPropsで値を渡す方法

子のコンポーネントはこんな感じで書くと割と便利

```typescript
<template>
// 省略
</template>
<script lang="ts">
import { Vue, Prop } from 'nuxt-property-decorator';
// 省略
export default class Hoge extends Vue {
  @Prop(Number) readonly hogeNum!: number;
  @Prop(String) readonly hogeStr!: string;
  @Prop(Array) readonly hogeAry!: string[]; // 文字列が入る配列の型
  @Prop(Object) readonly hogeObj!: { [key: string]: number }; // 適当な文字列をkeyに数値が入る型
  @Prop({ type: Boolean, default: true }) readonly hogeBool!: boolean; // 何も親コンポーネントから渡されない場合はtrueが入る

  hogeFunc(): void {
    console.log(this.hogeNum); // thisで呼び出す
  }
}
</script>
```
浮動小数点と固定小数点の表現について

固定小数点と浮動小数点の求め方について備忘録代わりに簡単に書いておく。
詳しい内容が知りたい場合は適宜調べてください。


# 固定小数点

* 固定小数点は整数型を小数として扱う事が出来る
* 小数を固定する位置は__ソフト(ハード)の実装__によって決まる。

つまり、16bitの場合こう表現することもできるし


![固定小数点](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112253/e26b60b3-8d07-f1b4-7bd3-36c98967ffd5.png)


このように表現することも可能。

![固定小数点](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112253/21881096-ac0d-85df-3ac8-5f4b87237f67.png)



## 固定小数の構造
2 進数の場合、小数では桁が下がるにつれ 0.5 の乗数 ( 2 のマイナス乗) を表します。

![小数点以下の値](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112253/5ce0376b-8394-9978-726a-a8088487980f.png)



例では**0.9**の表現を求めてみる。
10進数の小数を二進数に変換するには小数部分に2を掛けて行き1.0になるまで繰り返せば良いです。
1.0を超えたら1を引いた値に2を掛けていく。
![計算方法](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112253/f4aa324f-3884-b351-6c03-35e82d6ea36a.png)


上から順に左→右に埋めていけばよい

小数部8bitなら0.8984375となります
![小数部8bit](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112253/73bc3392-e520-875d-a0ce-4037f44d3e63.png)


小数部3bitなら0.875となります
![小数部3bit](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112253/7ce2f713-d358-d3fc-7368-b9334e05be68.png)


結論：表現できるbit数が少ないと誤差が大きくなる。


# 浮動小数

IEEE754 という方式に準拠した 半精度浮動小数点(16bit)について書いてみます。
今回は0.0015を二進数の半精度浮動小数点(16bit)で表現してみたいと思います。
手順は以下の通りです。

1. 仮数部の値を求める(やり方は固定小数と同じ)
2. 1.xの形にする
3. 1を外した値を仮数部として扱う
4. 2の時に移動した数をバイアス値(16bitなら15)に足した値を指数部として扱う
以上。

## 浮動小数点の構造

半浮動の浮動小数点では 16 ビットを以下のように 3 つに分割します。
![浮動小数点(16bit)](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112253/b0c1568d-6afb-e467-2986-ecf0f9fc7cd8.png)


## 仮数部の求め方



まず最初に仮数部を二進数で求めます(仮数部の求め方は固定小数の時と同じです）
色んな数を計算してみる分かると思いますが1.0で収束する事の方が稀です。

![仮数部の求め方.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112253/ddb5f898-c0a8-4a47-ae1c-82d312749d20.png)

結果はこうなります。
**00000000011000100100 …**(以下省略)


次に小数点の位置をずらし1.xの形にします(小数点を右に10個分移動させます)

**1.1000100100 …**(以下省略)

最初の1を除いた先頭10bitの値が仮数部になります
1000100100

### 指数部の求め方

仮数部を1.xの形にする際に小数点を右に10個分移動させたので
指数は2E-10なのでバイアス値から-10します。
16bitは15なので、二進数にすると 01111ここから1010を引きます。
結果、指数は‭*00101‬*になります。


**0 00101 1000100100**
↑が半精度浮動小数で表した時の0.0015になります。



参考
https://www.macnica.co.jp/business/semiconductor/articles/intel/133327/
SqliteでDBの中身を確認

参考
-
[Macで使うSQLite3入門編](https://www.task-notes.com/entry/20140720/1405845794)
[sqlite コマンドラインでのテーブル内容の確認コマンド](https://kekaku.addisteria.com/wp/20170618054842)

### 起動
```
sqlite3 DBのpath
```

###終了
```
sqlite> .quit 
```

###テーブル一覧
```
sqlite> .table
```

###データベース情報
```
sqlite> .table
```

###テーブルの中身を表示
```
sqlite> select * from table名;
```

###テーブルの要素一覧
```
sqlite> .schema
```
Flutterエラー Gradle build failed to produce an .apk file. It's likely that this file was generated under プロジェクトディレクトリbuild, but the tool couldn't find it.

Androidの実機でデバッグビルドしようとしたところ、掲題のエラーに遭遇した。
`build.gradle` でFlavorを追加したのに、実行コマンドが対応していなかったのが原因。
以下のようにflavorを指定した起動設定にすれば解決。

<img width="1059" alt="figure.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18273/eaf31622-8ec2-c669-05fd-3f29456c8fb5.png">
Ansibleの環境設定ファイル

#1.Ansible.cnf (環境設定ファイル)について

ansibleコマンドやansible-playbookコマンドを実行するときに参照される各種設定ファイルです。
いろいろな設定がありますが、今回はその一部を紹介します。
　
# 2.設定可能なパラメータについて

ansible.cfgのパラメータは初期状態ではすべてコメントアウトされています。
デフォルトの状態では無効になっているため、設定変更を行うためには、コメントアウトを解除し、
設定を行う必要があります。
ansible.cfgで接続可能なパラメータは多岐にわたりますが、最低ライン知っておくとよいかと思われる
物をピックアップして記載します。

詳細は以下を参照してください。
https://docs.ansible.com/ansible/latest/reference_appendices/config.html#ansible-configuration-settings


基本書式
　(パラメータ名)=(値)
　※コメントアウトするには、#を頭につけます。

・通信に関わる設定

| 概要 | パラメータ名 | セクション | デフォルト値 |値|
|:-----------:|:-----------:|:-----------:|:-----------:|:-----------:|
|接続先の<BR>SSHポート|remote_port| [default] |22|ポート番号|
|接続先の<BR>ユーザー|remote_user|[default]|ローカル<BR>ユーザー|ユーザー名|
|SSHの引数|ssh_args|[ssh_connection]| なし |sshコマンドの引数|


・ログの設定
ansible、ansible-playbook コマンド実行時に標準出力に出力されるメッセージを保存します。
実行時のエビデンスとして利用できます。

| 概要 | パラメータ名 | セクション | デフォルト値 |値|
|:-----------:|:-----------:|:-----------:|:-----------:|:-----------:|
|ログ出力先|log_path| [default] |なし|フルパス指定|

※log_pathはコメントアウト状態の初期値では、/var/log/ansible.logが
　指定されています。これだとrootユーザー以外で実行した場合は出力エラーになるため、
　ansibleの環境ディレクトリにlogディレクトリを作るなど、別のディレクトリを選択するることをお勧めします。


・接続後のユーザー変更

| 概要 | パラメータ名 | セクション | デフォルト値 |値|
|:-----------:|:-----------:|:-----------:|:-----------:|:-----------:|
|変更実行？|become|[privilege_escalation]| しない|true/false|
|ユーザー変更方法|become_method|[privilege_escalation]|なし|su/sudo|
|変更ユーザー|become_user|[privilege_escalation]|なし|ユーザー名|
|変更時のパスワード確認|become_ask_pass|privilege_escalation]|なし|true/false|

※become_ask_passをfalseにした場合、最初に接続したユーザーと同じパスワードにしておく、
　接続先の/etc/sudoers設定などの方法でユーザー切り替え可能にしておく必要があります。

#3.環境設定ファイルの読み込み場所と優先順位
デフォルトではansible.cfg というファイルになります。
ansible、ansible-playbookコマンドを実行する際、環境変数で指定されたパス、/etc/ansible/ansible.cfg の順に見つけられたものを読み込みます。
（参照）[Ansibleの環境設定](https://qiita.com/m_t_/items/0f2b8855b2ec0840eb0f#3%E7%92%B0%E5%A2%83%E8%A8%AD%E5%AE%9A%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E8%AA%AD%E3%81%BF%E5%8F%96%E3%82%8A%E5%84%AA%E5%85%88%E9%A0%86%E4%BD%8D)


(参考)https://docs.ansible.com/ansible/latest/cli/ansible-config.html


#4.ansible.cfg で記載された設定値の上書きについて
状況により、ansible.cfgで記載された設定値を変更したい場合がありえます。
こういった場合、ansible.cfgを変更する方法もありますが、一時的であれば以下の方法でも変更できます。

 ①コマンド引数に変数として定義
　ansible、ansible-playbook の引数 -e "変数名" "値" として追記
　また、sshの接続ユーザーなどは -U などのオプションで置き換えられます。
 ②環境変数に定義
　export ANSIBLE_(環境変数名英大文字)=(値)で定義
 ③playbookに記述
　すべての項目ではありませんが、実行ユーザーなどの一部の項目については、playbookに記述して指定できます。
　（これは自動化処理個別の設定であり、環境変数の変更かといわれると微妙ですが）

以上
ABC156「Bouquet」

# [Bouquet](https://atcoder.jp/contests/abc156/tasks/abc156_d)

## 考えたこと

- よくわからんから実験した
  - a, b考えずに全部足すと2^n本になる（これ、実験しなくても普通に考えて2^nだった）
  - だから、そこからnCaとnCbを引けばよさそう
  - 答えは2^n - nCa - nCb - 1となる。-1は0本の分
- あまりの計算を考える
  - 2^nは繰り返し二乗法でいける
  - nCaはaの制約が10^5までだから掛け算でできそう。割り算が発生するから、フェルマーの小定理で逆元かけるやつをする。
  - はい天才
- なんかバグる
  - ふて寝した



## 解法

1. 求めるもの何か？
   - $2^n - 1$が全体本数
   - そこからa本選ぶ場合とb本選ぶ場合を考えれば良い
   - つまり、求めるものは$2^n - 1 - nCa - nCb$
2. $2^n-1$を求める
   - nは非常に大きいが、繰り返し二乗法でにより$O(logN)$で求められる
3. nCkを求める
   - $nCk = \frac{n(n-1)...(n-k+1)}{k(k-1)...1}$となる
   - 計算量は$O(k)$だから大丈夫。
   - 計算自体は、「分母×分子の逆元」で計算できる
   - 逆元はフェルマーの小定理で求まる
4. 負の剰余について
   - [負数の剰余を計算してはならない](https://shunirr.hatenablog.jp/entry/20120409/1333993409)っていう記事によると、負の剰余をプログラムで計算するときはちょっとめんどい
   - 記事の内容を完全理解したわけじゃないけど、とりあえず剰余の計算は正の値で計算すればよさそう



## [コード](https://atcoder.jp/contests/abc156/submissions/11927729)

```cpp
#include <bits/stdc++.h>
using namespace std;

const long long mod = 1e9+7;

// a^bを返す
long long Pow(long long a, long long b) {
	long long ret = 1;
	while (b > 0) {
		if (b & 1) {
			ret = (ret % mod) * (a % mod) % mod;
		}
		a = (a % mod) * (a % mod) % mod;
		b /= 2;
	}

	return ret % mod;
}

// nCkを返す
long long nCk(long long n, long long k) {
	long long bunbo = 1, bunshi = 1;
	for (int ki = 1; ki <= k; ki++) {
		bunbo *= ki;
		bunshi *= n - ki + 1;
		bunbo %= mod;
		bunshi %= mod;
	}

	return bunshi * Pow(bunbo, mod - 2) % mod;
}

int main() {
	long long n, a, b;
	cin >> n >> a >> b;

	// 全体の本数
	long long ans = Pow(2, n) - 1;

	// nCaの分を引く
	ans -= nCk(n, a);
	ans %= mod;

	// nCbの分を引く
	ans -= nCk(n, b);
	ans %= mod;

	// ansをmodの範囲に収める → modを足して正の値にする → %modを計算する
	ans = ((ans % mod) + mod) % mod;

	cout << ans << endl;

	return 0;
}
```





## 感想

- mod上で$\frac{a}{b}$するの、Pとbが互いに素であればバグらないと思ってたけど違った
  - $\frac{a}{b}$が整数にならない場合、バグる。
  - mod上では整数しか扱わないっぽい
  - だから、mod上では普通に割るんじゃなくて逆元をかけた方が良さそう
- 負の剰余を計算すると面倒なことになるから、とりあえず正の値にしてから剰余計算するとよさそう
- modintっていう便利なライブラリあるっぽいけど、剰余の理解が微妙な状態で使うとだめそう
IntelliJ IDEAでKotlinのcoroutineに触れてみる（ための準備）

# はじめに

今ごろですが、Kotlinの環境を最新バージョン(1.0.0 → 1.3.71)にアップしたので、**coroutine** [^1] に触れてみたいと思い、IntelliJ-IDEAで新規プロジェクトを作成しましたが、ビルドを通すまでに手こずったのでまとめておきます。

[^1]: [Kotlin 1.3をサクッと学ぶ - CoroutineとKotlin/Nativeを触って理解しよう](https://employment.en-japan.com/engineerhub/entry/2020/02/04/103000)

執筆時の環境は以下の通り；
- macOS Catalina version 10.15.3
- IntelliJ IDEA 2020.1 (Community Edition)
- Kotlin version 1.3.71-release-431 (JRE 11.0.6+10)
- Java openjdk version "11.0.6" 2020-01-14

# Gradle Kotlin DSL [^2]

[^2]: [Gradle Kotlin DSL入門](https://qiita.com/toliner/items/8b1ed6ed3cc04c22d63d)

**coroutine**を使うためには、**kotlinx-coroutines-core**のライブラリが必要で、gradle [^3] に依存関係を追加するのですが、gradle未経験であったため、ネットの情報を参考にして試行錯誤の末、下記の内容でやっとビルド及び実行ができました。
ポイントは**kotlinx-coroutines-core**の依存設定の書き方です。


```gradle:bulid.gradle.kts
plugins {
    kotlin("jvm") version "1.3.71"
}

group = "org.example"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath(kotlin("gradle-plugin", version = "1.3.71"))
    }
}

dependencies {
    implementation(kotlin("stdlib"))
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.5")
}

tasks {
    compileKotlin {
        kotlinOptions.jvmTarget = "11"
    }
    compileTestKotlin {
        kotlinOptions.jvmTarget = "11"
    }
}
```

# サンプルソース

下記が**coroutine**を使ったの最小限のソースコードになります。今後、いろいろ付け加えてみて、理解を深めていきます。

```kotlin:Test.kt
import kotlinx.coroutines.*
fun main() = runBlocking {
    println("Hello!")
    GlobalScope.launch {
        println("CoRoutine!!")
    }.join()
    println("end!")
}
```


### 以上

[^3]: [IntelliJ+Gradleのプロジェクト作成方法メモ](https://qiita.com/WK6_8B/items/77f3b49fc0b7d4c4ff27)
lnコマンドめっちゃ便利。

皆さんこんにちは。

今日は**lnコマンド**と出会い、とても便利だなと感動しておりました。

## 今回の流れ
- lnコマンドとはなんぞや
- リンクとは
- ハードリンクとシンボリックリンク
- シンボリックリンクの使用例

## lnコマンドとは？
lnコマンドは、**リンクを貼るコマンド**です。

## リンクとは？
Linuxのファイルシステムでは**ファイルに別名をつける**ことが出来、この機能を**リンク**という。別名をつけることを**「リンクを貼る」**という。

例を出すならば、
「りんご」という物体に、アップルやりんごちゃん、赤い果物など一つの物体に対して別名をつけることです。

またリンクには**「ハードリンク」****「シンボリックリンク」**の２種類存在する。
現在は「シンボリックリンク」が主流になっている。

##lnコマンドの使い方
```
ln [オプション] <リンク元ファイル名> <リンク名>
```

##ハードリンクとシンボリックリンク
### ハードリンク
ハードリンクとは、1つのファイルの実態に複数の名前を付ける機能。ハードリンクで追加されたファイル名は、どちらが本物名前で仮の名前などの区別が存在しない。

以下は、appleというファイルを作成し、そのファイルに対して、red_fruitsというハードリンクを作成する例です。

```
$ touch apple
$ ln apple red_fruits
```

上記の例により、このディレクトリーには**apple**と**red_fruits**というファイルが存在し、二つともappleの内容が表示されます。
つまりappleの中身が変わると、red_fruitsの内容もそれに応じて変わるということです。（同じファイルを指しているため。）

rmコマンドでハードリンクを作成したファイルを削除すると、指定したファイル名だけが取り除かれ、ファイルの実体は残ります。
全てのハードリンクが無くなったときに、ファイル実体も削除される。


### シンボリックリンク
シンボリックリンクとは、リンク先の**パス名**が書かれた小さな特殊ファイルです。
ハードリンクとは違い、**リンク先がファイルの実体**です。

以下は上の例と同じく、appleというファイルを作成し、そのファイルに対して、red_fruitsというシンボリックリンクを作成する例です。

```
$ touch apple
$ ln -s apple red_fruits
```

シンボリックリンクを作成するには、lnコマンドに**-s**オプションを付けます。
シンボリックリンクのリンク先を確認するには、**[ls -l]**コマンドを指定します。

```
$ ls -l
-rw-r--r--  1 eiji  staff  0  4 14 16:45 apple
lrwxr-xr-x  1 eiji  staff  5  4 14 16:45 red_fruits -> apple
```

上記を見ると、*apple*はただのファイルですが、***red_fruits***は***apple***を指す特殊ファイルであることがわかります。
つまりシンボリックリンク（*red_fruits*）をrmコマンドで削除してもファイルの実体（*apple*）は消えませんが、先に*apple*を先に消してしまうと*red_fruits*のファイルはcatコマンドで見ることは出来ません。
ここが大きな違いですね。

実に面白いですね。

## シンボリックリンクの使用例
このリンクを学んで一つ使い道を学びました。
それは、**長いパス名**の省略です。
どういうことでしょうか？
以下のコードを見てください。

```
eiji@MacBook-Pro scrayping_new % ls
README.md	data.csv	scrayping.py	yahoo.py
__pycache__	newsPicks.py	venv		yomiuri.py
```

汚いですが、このようなPythonのプロジェクトが入っているフォルダがあるとします。
この時に、このプロジェクトの仮想環境に入るためには、

```
$source venv/bin/activate
```
と毎回打たなければなりませんでした。

ここで、シンボリックリンクです。
venv/bin/activateに対して、*activate*というシンボリックリンクをカレントディレクトリで作成するのです。
つまりコードで表現すると、

```
$ ln -s venv/bin/activate activate
$ ls
eiji@MacBook-Pro scrayping_new % ls
README.md	activate	newsPicks.py	venv		yomiuri.py
__pycache__	data.csv	scrayping.py	yahoo.py
```

上記を見たらわかるように、*"activate"*という特殊ファイルが生成され、

```
eiji@MacBook-Pro scrayping_new % ls -l ac*
lrwxr-xr-x  1 eiji  staff  17  4 14 22:17 activate -> venv/bin/activate
```
このファイルは"*venv/bin/activate*"のシンボリックリンクである事がわかります。

これで何が便利か？

```
source activate
```
それは、仮想環境に入るために長いパスを書く必要がないのです！

## 最後に
今日はlnコマンドについて書きました。
ニュースを集めてくるプログラムや、日常的に使うプログラムはシンボリックリンクとしてデスクトップに置くのはとても便利だなぁ。と使い道がどんどん湧き上がりました！

最後までありがとうございました。
【Day53】積み上げ日記

##予定
■Udemy（有料教材）
Swift一から学習
−カウントアップアプリ作成

##完了
■Udemy
−クラスについてまで

##学習時間
5h

##学習ポイント
■画面に対してプログラムファイルが1つ
→新しく追加したview controllerは、プログラムファイルを持っていないため、新たに作成する必要がある。
※画面遷移のみであればOK

■メソッドを作る時
func メソッド名（役割名）（）
{
　　//処理内容
}

■メソッド＝役割
メソッドは呼び出さないと、永遠に機能しない。

■if
If (条件式）{
処理内容
} else{
処理内容
}

■キャッシュを消す場合　
Controllキー押しながら、View controller
 
##疑問点
■メソッドと変数の関係が混乱している。

##計画通り進んだか？
進んでいない。現在1からAPI、データとのやり取りまで学習できる動画で一貫して学び直しているため、一旦はその教材に委ねてみる。今まで、メソッドの書く位置や呼び出し方が全く理解できていなかったが、この動画である程度理解できた。
5歳娘「パパ、秒速でYouTubeコンテンツを作る方法を教えて」

#5歳娘「パパ、秒速でYouTubeコンテンツを作る方法を教えて」（やめ太郎リスペクト風）
##ある日の我が家
やめ太郎リスペクト風
娘（5歳）「パパ、YouTubeコンテンツを作る方法を教えて」
ワイ「今日はその質問か。ええでええで。パパが教えたるで〜」
娘「わ〜い！」

##準備
ワイ「まずどうすればいいんかな」
娘「何がいるの」
ワイ「初心者は（ワイも初心者やけど）まずPowerPointくらいが無難でいいやろ。あとはAviUtlとAudacityで十分や。動画はMicrosoftフォトから始めようか」
（ワイ「AviUtlの画面開いて再生ウィンドウがないといって泣いてたのは内緒な」）
ワイ「そうそう、Snap Cameraがいるな。Lens Studioも忘れんように」
（ワイ「Snapchatの登録が失敗してサポートに泣きついたけど体よくあしらわれたのも内緒な」）

##コンテンツ
娘「まずどうすればいいの」
ワイ「なんと言ってもコンテンツや。まずコンテンツを作る。PowerPointや。PowerPoint　初心者でぐぐればいいやろ」
娘「わ〜い」
ワイ「次は作ったコンテンツの各ページを適当に何枚かコピーして言いたいことをハイライトするんや」
娘「ハイライトって何？」
ワイ「字を赤くするんや」
（しばらく娘、格闘）
娘「できた！」
ワイ「いい子や。それを名前を付けて保存とする、全スライドとすれば、全部画像になる」
娘「かんたんだ！」
ワイ「そうやそうや。パパはかんたんなことしかしないんや」

##画像並べ
娘「次は？」
ワイ「5歳なら、Microsoftフォトで十分だろ。ビデオプロジェクトを作って、今の画像を全部流し込むんや」
娘「できた！」

##タイトルページ
ワイ「パパ、次はちょっとむずかしいことをするぞ。タイトルベージだ。このタイトルページというところを押して、テキストにタイトルをコピペするんだ。」
娘「これでいいの？」
ワイ「そうや、イフェクトはジョイだな。パパはいつもジョイ一点買いや」
娘「できた！」
ワイ「タイトル長さはデフォルトの3秒でいいやろ」

##オープニングとエンディングの動画
ワイ「次は、先頭と最後にオープニングとエンディングの顔見せ動画を撮るんや。10秒もあれば十分や。人間、話しかけは重要だから。」
娘「後ろの汚いカーテンはどうするの？」
ワイ「そんなものはSnap Cameraで背景Lensでいれてとればちょいちょいちょいや」
娘「パパ、すごーい！」
ハスケル子「3日前までバーチャル背景のことなんか何も知らなかったくせに」

##音入れ
ワイ「あとはAudacity起こしてスライドに合わせてしゃべって音量調整すれば材料は完璧や」
娘「わーい！」
（しかし、娘は注意散漫なので録音にえらく手間取る）

##超簡単編集
ワイ「最後はMicrosoftフォトに「カスタムオーディオ」ではめ込んで、音にあうように画像の表示秒数を調整すればおしまいや」
娘「わーい！」

##文章でわからない時はYouTube
ワイ「言葉ではわからんだろうから、ワイの秒速動画コンテンツ術でも寝る前に見とけ」
娘「YouTubeを『秒速企業内動画コンテンツ術』で検索？」
（ワイ「YouTubeを『初心者用企業内動画の作り方』で検索するとそれの前フリも見られるけどな」）
ワイ「秒速といっているけど、1分42秒の動画作るのに2時間半もかかったのは、幼稚園のお友達には内緒やで」
ハスケル子「Markdownの書き方も知らんと、四苦八苦しているのがバレバレやで」

〜おしまい〜
謎解き用メモ＃１　パスワード

##脱出ゲームの謎解きでよくある、3つの数字を入れると進めるやつ

```nazotoki.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="nazotoki.css">
    <title>謎解きWEB</title>
</head>

<body>
    <div id="app">
        <input type="text" v-model="keyWord">
        <button v-on:click="onclick">ボタン</button>
        {{message}}
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="nazotoki.js"></script>
</body>
</html>
```
```vue.js
new Vue({
    el: '#app',
    data: {
        message: 'hello',
        keyWord: ''
    },
    methods: {
        onclick: function(){
            if (this.keyWord === '000'){
                this.message = 'good';
            }else{
                this.message = 'bad';
            };
        }    
    }
});


```
生JavaScriptでFizzBuzz問題とナベアツ問題を解く方法【jQuery未使用】

JavaScriptで分からないことを調べてもjQueryを使用した例ばかりしか出てこずに困った経験があったので、生のJavaScriptでナベアツ問題を解く方法についてまとめます。

## FizzBuzz問題
JavaScriptを使って1から100までの数字を順番にconsole.logで出力する。
ただしその数が3で割り切れるなら"Fizz“、5で割り切れるなら"Buzz“、両方で割り切れるなら"FizzBuzz"をそれぞれ数字の代わりに出力する。

### FizzBuzz問題の解答コード
```javascript
function fizzbuzz() {
    for (let i = 1; i <= 100; i++) {
        if(i % 3 === 0 && i % 5 === 0) {
            console.log("FizzBuzz");
        } else if(i % 3 === 0) {
            console.log("Fizz");
        } else if(i % 5 === 0) {
            console.log("Buzz");
        } else {
            console.log(i);
        }
    }
}
fizzbuzz();
```


## ナベアツ問題
ナベアツ問題とは、FizzBuzz問題のように1-100までの数字で、3がつく数字と、3の倍数のときに「!」を表示させる学習のための練習問題です。

### ナベアツ問題の解答コード
まずは解答となる生JavaScriptでのコードをお見せします。

なんでもそうですが、コード記述方法は他にもありますので、あくまでも一例としてご参考ください。


```javascript

'use strict'
const nabeatsu = () => {
    for (let i = 1; i <= 100; i++) {
        if(i % 3 === 0) {
            console.log(i + "!");
        } else if(i.toString().match(/3/)) {
            console.log(i + "!");
        } else {
            console.log(i);
        }
    }
}
nabeatsu();
```
GitHub PagesでGSuiteで取得したドメインのHTTPS化が半年かかった話

# GitHub Pagesで独自ドメインのサイトを公開する方法

https://qiita.com/foobaron/items/cd9cfc403defa706372b
https://hackernoon.com/how-to-set-up-godaddy-domain-with-github-pages-a9300366c7b

去年の11月ぐらいからずっと上記の記事などを参考にGSuite(GoDaddy)で取得した独自ドメインにGitHub Pagesのサイト公開しようと頑張っていました。
他の記事などを読むとわかりますがすぐにはHTTPS化する事ができません。
嫌ですよね。HTTP。

##HTTPS化できない
なので最初は2～3日待ってから試したりしておりましたが、一向にチェックが入れられません。
![githubpages-https.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128561/b384da02-838c-d6ee-382d-98bebddb0013.png)

色々試しているうちにGitの設定がおかしくなってしまって7～8回ぐらいリポジトリを作り直しております。
リポジトリの名前を変えたり色々やりました。結果半年経ってもHTTPS化する事が出来ていませんでした。

# 結論
出来ました。やったね。
![HttpsPegionChest.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128561/d92341ad-381c-85fc-5e54-12c96d677bde.png)

やったことは以下の通りです。
## やったこと
GitHubの自分のリポジトリのSettingsの中の「Cutom Domain」の所にwww無しの

```
pegionchest.net
```

を設定しておりましたが、

```
www.pegionchest.net
```

とwwwを付けることで無事チェックが入れられるようになりました。

## 理由
www無しのドメイン名に

```
dig pegionchest.net
```
とすると、Aレコードに

```
185.199.108.153
185.199.109.153
185.199.110.153
185.199.111.153
xxx.xxx.xxx.xxx
```
一つ余計なIPアドレスが含まれている事が分かりました。
つまりpegionchest.netでアクセスした際に1/5の確率でGSuiteだかGoDaddyのアドレスになってしまっていたわけです。

www付の方を試すと

```
dig www.pegionchest.net
```

```
185.199.108.153
185.199.109.153
185.199.110.153
185.199.111.153
```
と登録したGitHubのIPアドレスのみが4つ表示されており、無事HTTPS化できたというわけです。
ですのでHTTPSにならないよーって方はAレコードのチェックをしてみることをお勧めします。

### GoDaddyの設定の謎
GoDaddyのDNSコンソールを見ると、Aレコードに編集できないForwardedという項目が設定されておりました。
おそらくこいつがどこかに転送していたのでしょう。
![GoDaddy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128561/e60ceac5-e313-be5f-57d1-cd2725987be1.png)

### GSuiteの転送設定
![管理コンソール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128561/b959ca25-67ac-d424-72c5-d32755369638.png)
GSuiteのドメイン設定で赤枠の状態になっていないと、GSuite内のサイトに転送されてしまっていたようです。
あらためて赤線の部分から変更を保存としたところ無事Forwardedのランダムさがなくなりました。

そういえば、以前、知り合いにサイトの確認してもらった時に古いGSuiteのサイトが開くことがあったらしく、キャッシュ消して！と強い口調でゲキ詰めした事がありましたが、たぶんこれのせいですね。ごめんなさい。
インターネットは難しすぎます。

### GitHub PagesのSourceの設定
完全に余談ですが、いろいろリポジトリをいじっているうちにSourceが設定できなくなりました。
以前はDocsディレクトリ以下を公開するという事が出来たのですが。
そもそもドロップダウンすら表示されません。誰か教えてください。。。
MySQL5.7 で AUTO_INCREMENT の値が突然 1に戻る怪奇現象を追ってみた。

![KT3WlrL_bsg.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425581/612880ad-3578-7fa5-82f7-5fd073f5a129.jpeg)

実装中に奇妙なことが起きました。
ローカルの開発環境内で構築した MySQL5.7での出来事です。

AUTO_INCREMENTを設定したidを持つテーブルに、INSERT処理を実行しました。
すると、100近くまでカウントされていたidが突然1に戻っていたんです。
そのテーブルは他のテーブルとの関係を多く持っており、これ本番（AWS RDS）もバグっちゃうのでは！？と焦り散らかしましたが、過去そのような事例は起きてなかったみたいなんです。

ガクブルの僕は恐る恐る調査を始めることにしました。

# ■発生条件の調査
どのタイミングで発生するのだろう。全く予想できない。
約20個近くあるテーブル全てにAUTO_INCREMENTを設定したidが存在するのですが、毎度 1にリセットされてしまうテーブルは決まって1つのテーブルのみ。

何が他のテーブルと違うかなーと考えた時に、1点大きな違いがありました。
それは、 **「データ削除の方法」** です。

基本的には「論理削除」を採用しているのですが、とても流動性が高いテーブルだったので、どうやらこのテーブルだけは **「物理削除」** を採用しています。

> 僕「まさか、、、こいつが関係しているのか？」

いやでも待てよと。何のための AUTO_INCREMENTなんだいと。
その辺を自動で採番してくれるから便利なんだろ AUTO_INCREMENTさんよぉ　と。

正直この疑惑は信じたくなかったです。一気にAUTO_INCREMENTの信用が下がってしまうじゃないかと。
でも違いがこれしかないんです。そこで僕はようやく Google先生に力を借り始めました。

# ■原因究明
> 検索ワード：`mysql` `autoincrement` `id` `リセット`

ほとんどが `「AUTO_INCREMENTをリセットする方法」` という検索結果の中、輝く一件を見つけました。

<img width="1036" alt="スクリーンショット 2020-04-14 21.44.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425581/4a997e63-4184-7f42-6c0d-19c96b3ee414.png">

> 僕「ピンポイントすぎるうぅぅぅぅ！！」

真っ白に輝くこちらの記事。僕が求めていた内容が載っていました。

こちらの記事を見てみると、

> MySQLが再起動されると連番の一番大きい値にカウンターがリセットされるという実装になっています。
つまり、最大値のレコードが物理削除された後に再起動されると、その値が再度使用されてしまうということです。AUTO INCREMENTカウンターをシーケンスであると完全に信頼して設計していたので、拍子抜けしましたし、実装を理解せずに使用して恥ずかしいです。

、、、嘘でしょ？
信じたくなかったことが起きました。やはり物理削除がAUTO_INCREMENTに大きく関係していました。

再起動をするたびに、AUTO_INCREMENTは連番の最大値にカウンターがリセットされていたんです。
ということは、 **もしも物理削除を実施してすっからかんになったテーブルのAUTO_INCREMENTカウンターが「100」だったとしても、MySQLを再起動するとそのテーブルには1件レコードは入っていないので、「1」からスタートしてしまう** ということです。

# ■対策
こちらの記事に掲載されている対策として、3つ紹介がありました。

1. MySQL8へのバージョンアップ
2. 論理削除にする
3. 採番用のテーブルを作る

この3つの中でどれを採用しようかというところなのですが、私が関わっているサービスは、つい先日ローンチしたばかりです。
この初期段階でMySQLのバージョンアップは提案しづらいというのと、まだまだissueが残っているなかで採番用のテーブルを用意して、約20近くのテーブル群の採番を一つにまとめるのも重たいかなと感じました。

そのため、今回はそのテーブルを物理削除から論理削除に切り替えて、その周辺の処理を修正することになりました。（バグも少なそうだし）

# ■まとめ
- 新規開発するなら、MySQL8を採用しようね。
- もしもMySQL5系を採用した新規開発をするなら、AUTO_INCREMENTには十分気をつけて、設計段階でシーケンステーブルを用意しようね。
- とはいえやっぱり物理削除って本当に怖いから、論理削除を採用しようね。
- 「まっしろブログ」さんの記事が的確すぎて本当に感謝だね。（以下の参考文献にリンク貼ってますので、そちらも是非）

# ■追記
書き洩れましたが、なぜ本番環境（AWS RDS）で起きていないかというと、可能性が2点あります。
1. 常に最新の一件が存在した時に再起動が実行されていた。
2. 再起動が実施されなかった。

１ は、神的すぎるタイミングなので、おそらく可能性は薄いかと。
2 は、可能性高いです。
https://go-journey.club/archives/9869
こちらの記事によると、数ヶ月に一回セキュリティパッチの適用があって、自動アップデートが走っちゃうこともあるみたいなのですが、まだそれに当たっていないだけかと。。。
遅かれ早かれ起きていたことなので、ローンチしてすぐ発覚してよかった。。。

# ■参考文献
https://masshiro.blog/mysql-auto_increment-reset/
https://go-journey.club/archives/9869
シェルスクリプトのreadを末尾改行なしやWindows改行コードに対応させる方法

# はじめに

シェルスクリプトの `read` を使ってファイルを読み込む場合、対象のファイルの最後の行は末尾に改行がなければ読み込めないというのはある程度シェルスクリプトを書いてる人なら一度はハマったことがあるかと思います。一般的には改行で終わらせましょうという話ですが、対応せざるを得ない場合もあるかと思います。その場合の対応のさせかたです。なお（いつもどおり）POSIX 準拠かつ外部コマンド呼び出しなしでシェルスクリプトの機能だけで実装します。

:::note warn
ファイルの末尾に改行が必要なのは「POSIXの仕様」だとする説がありますが、これは間違いで POSIX は標準規格で使用している「テキストファイル」の用語を定義しているだけです。

POSIX では「テキストファイル」という用語を、0行以上の行で構成されたファイルと定義しており、行とはヌル文字がを含まず末尾に改行がある `LINE_MAX` バイト（一般的に2048バイト）以内の文字列のことです。

詳細は以下を参照してください。

[「POSIXがファイルの末尾に改行が必要と決めた」はガセネタ](https://qiita.com/ko1nksm/items/3aea7fb8ac7e0396c10f)
:::

## 実装

### 末尾改行なしに対応させる

しばしば勘違いされていると思いますが `read` は最後の行は末尾に改行がなければ読み込めないというのは正確ではなく、読み込んではいます。ただ `read` 関数が正常終了になっていないだけです。なので判定方法を工夫すれば読み込めます。

```sh
# これだと最後の行は改行がなければならない
while IFS= read -r line; do
  echo "$line"
done

# これならOK。最後の行は実は読み込まれてるので $line に何かしら入っている
while IFS= read -r line || [ "$line" ]; do
  echo "$line"
done

# 最後の行が改行で終わってない場合を区別したい場合
while IFS= read -r line; do
  echo "$line"
done
if [ "$line" ]; then
  # 最後の行が改行で終わってない場合
  echo "$line"
fi
```

### Windows改行コードに対応させる

Linux / Unix / macOS の改行コードは `LF` ですが、Windowsの改行コードは `CR` `LF` です。余計な `CR` があるのでこれを削除するだけです。

```sh
CR=$(printf '\r')

while IFS= read -r line && line=${line%"$CR"} || [ "$line" ]; do
  echo "$line ${#line}"
done
```

## 関数化

ここまでの話ならただの雑学。ここからが本題です。上記のコードを何度も書くのは面倒ですよね？そこで関数化したいと考えます。`read` 関数が少し特徴的なのもあってぱっと思い浮かばないのではないでしょうか？まあ引っ張る話でもないのでさくっと実装です。

```sh
readline() {
  IFS= read -r "$1" || eval "[ \"\${$1}\" ]"
}

line='' # shellcheck に未定義の変数を使用していると怒られないようにするため
while readline line; do
  echo "$line"
done
```

次はWindowsの改行コードに対応です。先程の応用です。

```sh
CR=$(printf '\r')

readline() {
  # shellcheck が SC2015 の警告を出すので { } でくくる
  { IFS= read -r "$1" && eval "$1=\${$1%\"\$CR\"}"; } || eval "[ \"\${$1}\" ]"
}

line='' # shellcheck に未定義の変数を使用していると怒られないようにするため
while readline line; do
  echo "$line"
done
```

## pdksh, loksh ワークアラウンド

基本的には上記のコードで良いのですが、pdksh と [loksh](https://github.com/dimkr/loksh)でバグがあります。（loksh は Alpine Linux にパッケージがあります。loksh には *loksh is a Linux port of OpenBSD's ksh* と書いてあり、[OpenBSD の ksh](https://man.openbsd.org/ksh) は *public domain Korn shell* と書いてあるので同じバグなのだと思います。）

pdksh, loksh は `set -e` した状態だと途中でスクリプトが終了してしまいます。以下はそれを再現する簡単なコードです。本来ならば FALSE と END が表示されなければいけないはずですが `eval` の中で `[ ]` を使用すると途中で中断してしまうのです。（TRUE も表示されません。）

```sh
set -e
eval "[ ]" && echo TRUE || echo FALSE
echo END
```

ワークアラウンドは簡単で `eval` の中の `[ ]` の後ろに `&&:` (`&& true`) をつけるだけです。

```sh
set -e
eval "[ ] &&:" && echo TRUE || echo FALSE
echo END
```

ということで関数化したコードにも追加します。

```sh
# 末尾改行なし対応
readline() {
  IFS= read -r "$1" || eval "[ \"\${$1}\" ] &&:"
}

# 末尾改行なし + Windows改行コード対応
readline() {
  { IFS= read -r "$1" && eval "$1=\${$1%\"\$CR\"}"; } || eval "[ \"\${$1}\" ] &&:"
}
```

以上で完成です。
MacBook Pro で TensorFlow を import しようとしたらエラーが出た

MacBook Pro で TensorFlow を import しようとしたらそれだけでエラーが出た話。

# tensorflow を import しようとしたら

```
> pip install tensorflow
> python
(略)
>>> imoprt tensorflow as tf
```

ってやったら、

# エラーが発生
抜粋１号。

```
Library not loaded: @rpath/libcublas.8.0.dylib
```

抜粋２号。

```
Reason: image not found
```

# やったこと
無駄に入れていた gpu版をアンインストールした上で、tensorflow を再インストールした。
（gpu 版をアンインストールしただけでは解決しなかった）

```
pip unisntall tensorflow-gpu
pip uninstall tensorflow
pip install tensorflow
```

# 補足
エラーを頼りに参考にあるURLを見ていて気が付いたのだが、CUDA?? MacBook Proだから今回は要らないんだけどって思ったときに、かっこつけて GPU版を入れたことを思い出してアンインストールしたという顛末でした。

## 参考
* [macOS+pyenv+TensorFlowでGPUを使おうとしてハマった](https://qiita.com/Ryuichirou/items/3477fb47580d824aa4d7)
* [issues](https://github.com/tensorflow/tensorflow/issues/6729#issuecomment-279483546) で同じことを言っている人もいて内容を見てここで気が付いた
ド素人がLINE botを公開してみた

プロトアウトスタジオという、プログラミングスクールではなく、プロトタイピングをアウトプットするというスクールに参加し始めた人の記事です。

授業にて、「heroku」というPaaSサービスにソースコードをのせて動かす体験をしました。
サーバとかOSとか、プログラムを動かすための環境づくりに必要な知識をすっ飛ばしていきなりサービスを無料で動かせる時代になっているのですね。

今回の宿題は「HerokuでNode.jsの仕組みをURLを公開しチャットボットを移植しアウトプットする」です。以前の宿題「LINEbot＋API」に挑戦した際のコードに少し手を加えて、「いぬ」とリクエストすると犬の画像をレスポンスするLINEbotをherokuに乗せて公開します。

![QR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599091/49cbcf1c-e51b-5053-87a9-c259a15e6df9.png)



```js
'use strict';

const express = require('express');
const line = require('@line/bot-sdk');
const axios = require('axios');
const PORT = process.env.PORT || 3000;

const config = {
    channelSecret: 'ここにはLINEbotのチャンネルシークレットを書く',
    channelAccessToken: 'ここにはLINEbotのチャンネルアクセストークンを書く'
};

const app = express();
let requetText='';

app.post('/webhook', line.middleware(config), (req, res) => {
    requetText=req.body.events[0].message.text;
    Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});

const client = new line.Client(config);

function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }
  
  let mes = 'ちょっとまってね'; // 待ってねってメッセージだけ先に処理

  getQiitaTag(event.source.userId , event.message.text); // スクレイピング処理が終わったらプッシュメッセージ

  return client.replyMessage(event.replyToken, {
    type: 'text',
    text: mes
  });
}

const getQiitaTag = async (userId,tag) => {
    let mes = '';
    try {
        if(requetText==="いぬ"){
        const res = await axios.get('https://random.dog/woof.json');
        const item = res.data.url;
        mes = item;
        }else if(requetText==="しばいぬ"){
        const res = await axios.get('http://shibe.online/api/shibes?count=1&urls=true&httpsUrls=true');
        const item = res.data[0];
        mes = item;
        }else{     
        mes = "いぬしかわかりません";
        }
        

    } catch (error) {
        // 該当しないものは404でエラーになる
        const {
            status,
            statusText
        } = error.response;
        console.log(`Error! HTTP Status: ${status} ${statusText}`);
        if( status == 404 ){
            mes = 'Qiitaのタグ「' + tag + '」の記事はありませんでした';
        } else {
            mes = `Error! HTTP Status: ${status} ${statusText}`;
        }
    }

    await client.pushMessage(userId, {
        type: 'text',
        text: mes,
    });
}

app.listen(PORT);
console.log(`Server running at ${PORT}`);
```
リクエストが「しばいぬ」だった場合には柴犬APIを呼んで柴犬画像をレスポンスするif文も入れてみました。

今回授業にて、ExpressにおいてHTTPSのpostリクエストを投げる際の処理を学んだことから、LINE上で何か打ち込まれた際それがwebhookに対するpost通信であるため、

```js
app.post('/webhook', line.middleware(config), (req, res) => {
    requetText=req.body.events[0].message.text;
    Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});
```
という関数が実行されるのだと気づきました。
一方で「Promise～」以降のコードが何を表しているのかサッパリなので、Promiseについて調べてみます。
MATLABでMeCabの品詞細分類を活用する：その2

# はじめに
在宅勤務で通勤時間の分だけ時間があるせいか，MATLAB遊びに費やす時間が増大している今日この頃です．
さて，以前の記事，[MATLABでMeCabの品詞細分類を活用する](https://qiita.com/h583/items/2ea83d734043dd0d76f2)では```mecabOptions```の```POSExtractor```オプションを使いましたが，__もっと簡単で効果的な__方法が見つかったのでご紹介します．それは，```mecabOptions```のオプション```LemmaExtractor```を使う方法です．（前の記事を見て，試してみてくださった皆さん__ごめんなさい__．こっちの方がはるかに簡単で便利です・・・）

#とにかくやってみよう

必要な呪文は１行だけ．

```matlab
mecabOpt = mecabOptions("LemmaExtractor",@(~,info) info.Feature);
```
これだけです．では，これで何が起きるか見てみましょう．

```matlab

>> str = "吾輩は猫である．名前はまだない";
>> tkns = tokenDetails(tokenizedDocument(str,'TokenizeMethod',mecabOpt));
>> tkns(:,{'Token','PartOfSpeech','Lemma'})

ans =
  10×3 table
    Token      PartOfSpeech                          Lemma                      
    ______    ______________    ________________________________________________
    "吾輩"    pronoun           "名詞,代名詞,一般,*,*,*,吾輩,ワガハイ,ワガハイ"        
    "は"      adposition        "助詞,係助詞,*,*,*,*,は,ハ,ワ"                     
    "猫"      noun              "名詞,一般,*,*,*,*,猫,ネコ,ネコ"                   
    "で"      auxiliary-verb    "助動詞,*,*,*,特殊・ダ,連用形,だ,デ,デ"              
    "ある"    auxiliary-verb    "助動詞,*,*,*,五段・ラ行アル,基本形,ある,アル,アル"     
    "，"      symbol            ""                                              
    "名前"    noun              "名詞,一般,*,*,*,*,名前,ナマエ,ナマエ"               
    "は"      adposition        "助詞,係助詞,*,*,*,*,は,ハ,ワ"                     
    "まだ"    adverb            "副詞,助詞類接続,*,*,*,*,まだ,マダ,マダ"             
    "ない"    adjective         "形容詞,自立,*,*,形容詞・アウオ段,基本形,ない,ナイ,ナイ" 
```
　
```tokenDetails```出力の```Lemma```（原形）の列が，MeCabの出力に置き換わっています．これでMeCabの品詞情報69種全てが活用できます．簡単ですね！自分としてはこのモードで使うのがデフォルトになりそうです．

# からくり
何をしたかというと，MeCabの出力から「原形」を抜き出して```Lemma```に割り当てる関数（LemmaExtractor, デフォルトは ```textanalytics.ja.mecabToLemma```）を自前のものにして，MeCabの出力全体を返すようにしたのです．（↓↓↓自前の関数）

```matlab

@(~,info) info.Feature
```
LemmaExtractorはMATLABのMeCabから２つの変数を受け取りますが，ここでは１つ目は使わずに，２つ目にわたされる構造体（```info```）を受けとり，そのフィールド```Feature```を返しています．フィールド```Feature```にはMeCabの出力が文字配列として格納されているので，上に示したように```Lemma```の列にMeCabの出力が現れるというわけです．

こうすると，元々Lemmaに割り当てられるべきだった情報がなくなってしまうように思えますが，実はそうではありません．デフォルトのLemmaExtractorは,フィールド```Feature```の各文字列をカンマで分けて，前から７番目の文字列をLemmaとしているだけなので，必要な情報はしっかりと残っていることになります．

# おわりに
この方法を使うと，```tokenDetails```で得られるテーブルを少々加工するだけで，情報量が極めて豊富な形態素解析結果を出力することができますね．```myTokenDetails```みないなWrapperを作って，'Lemma'の他にも'Rubi'とか'Phonetic'という列をつくるとかするとよさそうです．
【試験合格記】AWS 認定 機械学習 – 専門知識(MLS-C01)

お疲れさまです。
表題の試験に合格したため記録として残したいと思います。

# 結果
合格(902点)

|分野|名称|割合|
|:-----------------|:-------------------|:-------------------|
|1|データエンジニアリング|20%|
|2|探索的データ解析|24%|
|3|モデリング|36%|
|4|機械学習の実装と運用|20%|

# 所有資格

| 資格名       |取得年月日 |
|:-----------------|:-------------------|
|AWS Certified Solutions Architect - Associate (SAA)|2018-06-14|
|AWS Certified SysOps Administrator - Associate (SOA)|2018-06-22|
|AWS Certified Developer - Associate (DVA)|2018-06-25|
|AWS Certified Solutions Architect - Professional (SAP)|2018-07-19|
|AWS Certified DevOps Engineer - Professional (DOP)| 2020-02-19| 
|AWS Certified Big Data - Speciality (BDS)| 2020-03-23| 
|AWS Certified Security - Speciality (SCS)| 2020-04-01| 
|AWS Certified Machine Learning - Speciality (MLS)| 2020-04-13| 

# 事前知識
機械学習にガッツリ取り組んだ経験はありません。
GCPのデータエンジニア試験を受けた際に機械学習に関する一般的な知識は重点的に学んだ経験があります。

# 所感
他の方の合格記事を見られた方はなんとなく理解されてると思いますが、出題範囲はほぼ機械学習モデルとSageMakerに集中しています。
ですので、この領域が完全に未経験の場合は回帰や分類、教師ありなし学習などがどのような意味か、というところから書籍などで理解する必要があります。
一部、データレイクやETL周りのアーキテクチャも出題されますが、これはSAPやDOPを取得していれば理屈で答えられると思います。

# 受験者に向けたアドバイス
- 予測や分類、アルゴリズムやハイパーパラメータなどは幅広く固有名詞とどういうパターンに当てはまるか整理する
- 正規化、非正規化、トレーニングセットやテストセットの精度に異常がある場合の改善方法を理解する
- SageMakerと親和性の高いAWSサービスの理解と組み合わせ方を学ぶ
- ノートブックインスタンスの特徴を把握しておく
- Transcribe、Comprehend、Translate、Polly、Lexなどの機械学習関連サービスの特徴を理解する
- KinesisとGlueの使い方を理解する

# まとめ
これで専門知識資格を3つ取得できました。
月内にネットワークを受けられればいいなと思いながら地道に試験対策を進めていこうと思います。
あとはこの試験について学習したことで機械学習の具体的な使い方やワークフローについて理解できたので社内データをなんとか活用したいというモチベーションが上がったことが収穫でした。
pipを直で使うのは非推奨っぽい？

# エラーメッセージが出てました。

いつものように、新規に建てたインスタンスに`python3-pip`をインストールした後、`pip`を使おうとするとエラーメッセージが出ました。

```
$ pip3 install pip
WARNING: pip is being invoked by an old script wrapper. This will fail in a future version of pip.
Please see https://github.com/pypa/pip/issues/5599 for advice on fixing the underlying issue.
To avoid this problem you can invoke Python with '-m pip' instead of running pip directly.
```

["please see"と書いてあるリンク](https://github.com/pypa/pip/issues/5599)を見てみると、pipのアップグレード後に色々と問題が発生してるみたいです。

`--user`をつけてインストールした方が、不具合が発生しにくくなるとか色々ありつつも、一番確実な方法は`python -m pip`でインストールすることみたいです。


私はいつもpipは最新版にしてから使うので、いつものように`--upgrade`してみます。

```
$ python3 -m pip install --upgrade pip
Collecting pip
  Cache entry deserialization failed, entry ignored
  Using cached https://files.pythonhosted.org/packages/54/0c/d01aa759fdc501a58f431eb594a17495f15b88da142ce14b5845662c13f3/pip-20.0.2-py2.py3-none-any.whl
Installing collected packages: pip
Successfully installed pip-20.0.2
```
正常に、最新版へのバージョンアップができました。

```
$ python3 -m pip --version
pip 20.0.2 from /home/ubuntu/.local/lib/python3.6/site-packages/pip (python 3.6)
```

今後はこの方法で使おうかなと思います。

## 補足
> `pip` が Python に付属するのは 3.4 以降です。
https://docs.python.org/ja/3.6/installing/index.html

そのため、python3.4より前の場合は上記の方法は使えません。今までどおりpipをインストールして使いましょう。
Git で、トラッキングしていないファイルをまとめて一括で .gitignore に追加する

## 目的

簡単なプロジェクトで、バージョン管理が必要なファイルが少なく、IDE が吐き出した管理不要なほとんどのファイルを無視したい、といった場合に。

## 手順

先ずはじめに、バージョン管理が必要なファイルだけ、ファイル名を指定した上で git commit しておきます。

残りは、管理する必要がないファイルなので無視しても良いのですが、git status するたびに出てきてしまうので、.gitignore に入れてしまいたい。でも、手作業でそれをするのは敗北を意味する。

そこで、以下のコマンドを実行します。

```bash
git status --porcelain | grep '^??' | cut -c4- >> .gitignore
```

## 参考

何度かお世話になっているワンライナーですが、どうも毎回 Web 検索に苦労しているような気がするので、検索が容易になりそうなタイトルで投稿しておきます。

元ネタは以下です。

[github - How can I revert this command "git status --porcelain | grep '^??' | cut -c4- >> .gitignore"? - Stack Overflow](https://stackoverflow.com/questions/56385308/how-can-i-revert-this-command-git-status-porcelain-grep-cut-c4)
人気記事というか、参照が多いと思われる記事


# OUTLOOK
[Outlook VBA オブジェクト まとめ](https://qiita.com/Q11Q/items/ac14d96c00e707de5d13)
なぜか「OutlookでVBAを使うときは一度目を通しておいた方がいい」という記事になっています。しかし、その評判は下記の２つに譲りたいと思います。
というかOutlook研究所
https://outlooklab.wordpress.com/about/
さんとか
三流君さん
http://www.ken3.org/cgi-bin/group/vba_outlook.asp
があればこそです。
とくに
Outlook でやってはいけない 10 のこと
https://outlooklab.wordpress.com/2008/06/01/outlook-%e3%81%a7%e3%82%84%e3%81%a3%e3%81%a6%e3%81%af%e3%81%84%e3%81%91%e3%81%aa%e3%81%84-10-%e3%81%ae%e3%81%93%e3%81%a8/
は必ず頭に入れておきましょう。これを頭に入れると、メールのテンプレートを共有するためにVBSでメールを作れるようにすることが重要になります。



しかし、この記事が読まれる理由は、仕事が多すぎてメールがあふれて処理しきれないからです。にもかかわらずOUTLOOKは多数の人にメールを送ったり、個別にメール本文を設定したりすることが非常に見づらいです。このため、Excelで一覧にしたいということを誰もが考えるため必要とされているのです。
　本当はこういう役目は実はVBScriptやWordやAccessが担っています。これはObjectの解説を読むとわかります。しかし公式の解説では全く分からない、なんとかしたいという切実な願いがアクセス数につながっていると思われます。人気どころか、深刻で過酷な労働環境とOUTLOOKのUIがダメダメでVBAの処理を想定していないところが原因であり、何一つ喜べる要素がありません。
　それはさておき、演算誤差には注意してください。ExcelからWordで演算誤差が起きる以上、ExcelやAccessからOutlookに流し込んでも起きる可能性があります。
[2022/07/25] 日本標準時2022年7月24日夜から25日午前中にかけて累計閲覧数が200000Viewを突破しました。

# ACCESS
 - [Access 2016(64 bit +win10Home)でmdbファイルは開ける MS Access 2013 Later can Open mdb file](https://qiita.com/Q11Q/items/a554aa07f1c25fbeb3f8)
元のマイクロソフトの記事が消されているので、この記事も私もいつ消されるのか、恐怖に震えています。
なんとなく、mdbは開けないように思っているかもしれませんが、実はPowershellを使えばできます。
しかし、ここで32bit版のPowershellを使う必要があります。

 - [Accessで必ず使うVBA ほぼ完全なエクスポート 全オブジェクト+参照設定リストをエクスポート](https://qiita.com/Q11Q/items/99caf05417f1c3af850c)
これはVBSCriptの方がメインになっていますが、バックアップを取りたいという要望が本当に多いので、この記事が読まれています。

 - [Access VBA 日本語リファレンスリスト目次](https://qiita.com/Q11Q/items/e8e381cad7a3358529cf)
DOCSの見出しは一向に展開しないうえに見づらい。さらに検索が効かないか遅いので需要があります。

 - [Access Null値の整理と判定方法、Null値によるエラーの抑止方法 IsNull VarType Nz](https://qiita.com/Q11Q/items/459171d80a42184a5f9e) 2022/07/28実はこれが82960viewになっていました。もちろんNull値、空文字を許可しないほうが早いはずですが、世の中そうは参りません。

# Excel
 - [【悲報】“達人”芳坂和行氏に学ぶ、エクセル「演算誤差」対策講座がPC Onlineから消えていた](https://qiita.com/Q11Q/items/84b380b20ef51eca929c)
実は最近になってExcelとWordの連携で小数点以下がおかしくなる現象を察知して、演算誤差が単にExcelだけにとどまらないことがわかりました。これを追加しています。
それにしてもAIとか機械学習とか言ってますが、なぜ演算誤差一つ解決できないのでしょうか。演算誤差の発生すら予測ができないとMSは解説しています。その程度も予測がつかないくせに人類の未来など予測できるわけないじゃん。
0埋めされていない年月日を、正規表現でdatetime型に変換

pythonのdatetimeには、文字列型をdatetime型に変換する関数`strptime()` があるが、0埋めされていない文字列は変換できない。
（`2020/04/03`は変換できるけど`2020/4/3`はできない）

その簡単な代替方法があったのでメモ。

全角が含まれる場合は、何らかの方法で全角を半角にしてから実行。
方法はいろいろあるのでお好みのものを。


## コード
`strptime()`の代わりに、datetimeのコンストラクタを用いる。
https://docs.python.org/ja/3/library/datetime.html#datetime.datetime
> class datetime.datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)


```python
import datetime
import re

# 文字列に含まれる数字のリストを取得
l = re.findall(r"\d+", text)

# 文字列のリストを数値のリストにする
l = [int(s) for s in l]

# datetime型のコンストラクタで、日時を指定（リストを展開して渡す）
date = datetime.datetime(*l)
```

## サンプル
```python
import datetime
import re

text = "2020/4/2"
l = re.findall(r"\d+", text)
# l : ["2020", "4", "2"]

l = [int(s) for s in l]
# l : [2020, 4, 2]

date = datetime.datetime(*l)
# date = datetime.datetime(2020, 4, 2)
```

## おまけ
和暦 to 西暦の変換にも使えるかも
（"元年"に対応させる必要はあり）

```python
import datetime
import re

text = "令和2年4月3日"

diff = 0
if text[:2]=="令和":
    diff = 2018
else:
    # hoge
    pass

l = re.findall(r"\d+", text)
l = [int(s) for s in l]

l[0] += diff
date = datetime.datetime(*l)

```
[記事]Discord Pythonボットを２４時間起動します。

# 何が必要

- [Repl.it](https://repl.it/)のアカウント

必要なのはこれだけです。

# ステップ１

"+new repl"をクリックします。

![0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571953/41be5a18-ecaa-e81d-74c6-27ec583d6383.png)

# ステップ２

新しいreplを作成します。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571953/950e9b6f-ec6f-86da-5b14-cdf932572056.png)

# ステップ３

"main.py"を作成します。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571953/e6d89955-500c-6107-83c8-3e4f7b668884.png)


```python
# 最初はこれが必要です。
import os
import keep_alive

# client.runの前はこれが必要です。
keep_alive.keep_alive()

# そしてclient.runはこのようです。
client.run(os.getenv('TOKEN'))
```

```python
import discord
import os
import keep_alive

# 接続に必要なオブジェクトを生成
client = discord.Client()

# メッセージ受信時に動作する処理
@client.event
async def on_message(message):   
    if message.content == 'Ping':
        await message.channel.send('Pong!')


# Botの起動とDiscordサーバーへの接続
keep_alive.keep_alive()
client.run(os.getenv('TOKEN'))
```

# ステップ４

"help.txt"を作成します。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571953/d09982fc-982a-49a8-3bd3-f4c24b5776b3.png)

```python
discord.py
flask
```

# ステップ５

"keep_alive.py"を作成します。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571953/626c4b50-051e-65f1-6207-04684ed3ba02.png)

```python
from flask import Flask
from threading import Thread

app = Flask('')

@app.route('/')
def main():
	return 'Bot is aLive!'

def run():
    app.run(host="0.0.0.0", port=8080)

def keep_alive():
    server = Thread(target=run)
    server.start()
```

# ステップ６

".env"を作成します。


![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571953/a7fde214-9f7f-1329-4312-0f445296b3a5.png)

```python
TOKEN = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```

# ステップ７

最後は"run"をクリックします。

# その他

"poetry.lock"と"pyproject.toml"は自動的に生成します。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571953/c6d8083d-a243-3fbf-d3ac-8548ea156a75.png)
開発・運用環境について (E資格対策)



では書きます。



#Adversarial Examples
人の目ではわからないごくわずかな摂動（変化）を加えただけで結果が大きく変わるデータ、生成手法を指します。
自動運転やセキュリティでは影響がとても大きく、対策はDefensive Distillation(蒸留を使う手法)、Gradient Masking(最後の出力だけ渡す手法)がありますとても難しいです。
下図がAdversarial Examplesの例です。

<img width="681" alt="ostrich.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/f8574f53-362f-2235-8e7a-5e65d26cf65e.png">



引用：https://elix-tech.github.io/ja/2017/10/15/adversarial.html


次に手法の紹介をします。

##FGSM
高速に生成できますが、特定のクラスへの誘導ができない手法



##JSMA
任意のクラスに誤認識できる手法。

##Blackbox Attack
モデルそのもの(oracle)が入らなくても攻撃できる手法の総称。




#深層学習ライブラリ

##フレームワークランキング
シェア1位：Tensorflow(+Keras)
シェア2位：PYTORCH(Chainerを参考にして作った)

です。

##開発環境、ライブラリ

画像：OpenCV
文章の前処理:gensim
コンテナ（仮想環境):docker
形態素解析:Mecab,Juman++
サブワード:SentencePiece

フレームワークの互換性を持たせる(アプリにDeployできる):ONNX

などなど


#軽量化技術
スマホなどにモデルを載せる場合も含め、Deep Learningでは基本的にサイズを小さくしたい。
そこで軽量化や、早くなる技術を紹介します。


##量子化
通常DeepLearningではfloat32で計算していますが、これを1bitで計算できれば容量は1/32でかつビット演算で計算できるので高速化ができます。
つまり容量のbit数を下げる手法を指し、1bitの場合binarization(2値化)といいます。

1bitの内積計算はXNOR（掛け算）＋POPCNT（CPUの命令で足し算）でできるので数十倍の高速化が見込まれています。

###BinaryConnect
確率p(σ(w))で+1,1-p(σ(w))で-1にする手法。
なぜかうまくいきます。（正則化として寄与するらしいです）


###Binarized Neural Networks
活性化関数も二値化する手法。
ですがこの場合勾配も計算できなくなってしまいます。
そこで以下の関数(STE:Strate Threw Estimator)を用いて計算します。

![straight-through-estimator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/987c96cc-7b22-c74e-9e98-0d47e90758dd.png)


引用：https://developer.smartnews.com/blog/2017/03/neural-network-quantization/





##蒸留
大きいモデル(教師モデル）の出力を教師データにして別のモデル（生徒モデル）を学習させる手法。
生徒モデルは教師モデルと同じサイズか小さいサイズで行い、性能の向上やサイズの削減などが見込まれます。

なぜ性能が向上するのか、教師モデルでは正解データを0と1(Hard Target)でしか受け取れませんが、生徒モデルでは犬0.09,猫0.91(Soft Target)のようにクラス間の類似度を正解データとして受け取れるのでモデルの性能が上がるからです。

![スクリーンショット-2018-08-27-20.25.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/24c2a466-7d54-58f6-dfbb-3d335b982da0.png)


引用：http://ai.deepx.co.jp/2018/09/25/%E8%92%B8%E7%95%99-%E7%AC%AC2%E5%9B%9E/

##プルーニング(pruning 枝刈り)
重みが小さいものを0にする手法。

学習とpruningを繰り返すと小さいモデルでも性能を維持できます。

#分散処理
大きなモデルを複数のプロセスで計算する手法を分散処理といいます。

分散処理ではデータ並列とモデル並列という2通りのアプローチがあり、
データ並列では、全プロセスに同じモデルのコピーして訓練することでバッチサイズをプロセス数倍し、学習を高速化させる手法です。例えばImageNetもあげられます。
一方でモデル並列では、1つのモデルを分割して複数のプロセスに配置し、全プロセスで協調して1つのモデルを訓練する手法です。例えば超解像度を入力とするCNNなど、1プロセス上に載りきらないサイズのモデルを訓練したい場合に用いられます。

![parallelism.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/f0582669-7e60-835d-3295-9ecfb53e7df4.png)


引用：https://tech.preferred.jp/ja/blog/model-parallelism-in-dnn/


##GPU
DeepLearningの演算で使うハードウェア、並列処理が得意です。





参考文献
https://tech.preferred.jp/ja/blog/model-parallelism-in-dnn/
【Angular】あなたのasync pipeは {{ 安全 | async }}ですか？

# aysnc pipeとは

PromiseやObservableな非同期オブジェクトをそのままtemplateで表示できるようにしたpipeで
コンポーネントが破棄される時に自動でunsubscribeしてくれる便利なものです。



# アンチパターン

```html:oya.page.html
<div>
　親の中で子コンポーネントを呼ぶ
  <app-kodomo [name]="name$ | async">
   私が子コンポーネントです。
  </app-kodomo>
</div>

```

親コンポーネントでObservableな値を子コンポーネントに渡す

```ts:oya.page.ts

name$ = new BehaviorSubject('Hello');

```

子コンポーネント側でnullを考慮せずに処理している

```ts:kodomo.component.ts

@Input() name:string;

ngOnInit(){
 this.name.slice(0, 1);
}

```




この場合、実行時エラーがでることがあります。

例として、子コンポーネントに渡すときの話をしましたが
以下のように親側でnullを考慮せずに表示しようとする場合も実行時エラーが発生することがあります。


```html:oya.html
   <div>
      {{ name$.slice(0, 1) | async}}
   </div>

```


# 原因


AsyncPipeは購読したObservableが最初の値を流す前に、必ず一度 null を返すようにできているからです。

もとのObservableが Observable<State> だったとしても、 AsyncPipeを通すと State | null となってしまいます。

# 対処方
* *ngIf や *ngForでnullをガードする

```html:oya.html
   <div *ngIf="name$ | async as name">
      {{ name.slice(0, 1) | async}}
   </div>

```

* 子コンポーネント側でnullを考慮した実装をする（これするくらいならAsyncPipe使わない方がいいです。）


# 参考資料

lacolacoさん
https://blog.lacolaco.net/2020/02/async-pipe-initial-null-problem/

Angular質問箱
https://youtu.be/LVa68EI9NSw?t=990
M5AtomをUIFlowで書き込んだあとにWiFiでUIFlowに接続するモードに戻す方法

# はじめに

M5Atom Matrixを使って、ネットワーク経由のUIFlowでプログラムを書き込んだ時に

**「書き込み後にUIFlowへ接続に戻したいのに方法がわからない」**

というのにハマったのでメモ。
M5Stackなどでは画面があるのでそこで選択すればいけるんですが、M5AtomにはLEDしかないため、表示上よくわからなく、どうしたらいいのか動揺したので。
公式ドキュメント読めばわかる話なんですが、ね…
https://docs.m5stack.com/#/en/quick_start/atom/atom_quick_start

# セットアップ作業
以下のページを参考にすると良いので割愛します。
https://raspberrypi.mongonta.com/howto-use-uiflow-with-m5atom/
ちなみにAPIKeyを調べるのは個人的にはシリアル通信(Macならscreen)で接続して起動時に出てくるのを確認するのがベターかと思います。状態も表示されて理解しやすいです。
※通信速度は、115,200ですのでお忘れなく。

# UIFlowで書き込んだあと
電源を再度いれてもUIFlowで書いたプログラムがずっと動いています。これではUIFlowから書き込みができません。

## 起動時にモードが切り替えれる状態で立ち上げる

本体の正面のボタン[A]を最後までずっと押しっぱなしにしながら、側面のボタン[reset]を押して、再起動させるとカラフルに光る状態で起動します。この状態になっても[A]は離さないでください。
![VID_20200414_195944_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58795/f3d90fe9-4574-4f4c-4007-f9e50060a2a8.gif)
そして、LEDの色をみながら以下のようなタイミングで[A]を離すと指定のモードで立ち上げれます。

- 緑： **UIFlow Online mode**
 - M5Burnerで設定したWiFiに接続しインターネット上の書き込み状態になるモード
- 青： **UIFlow desktop IDE Program**
 - USB接続してIDEから書き込みができるモード
- 黄： **WIFI Configuration mode**
 - WiFiのAPになりSSID/PASSをブラウザ画面からセットアップできるモード
- 紫： **Run the Last Downloaded Program**
 - 書き込まれたアプリを起動するモード（通常に電源を入れた時と同様)

※シリアル通信で見てると、どのモードに入ったかはログが出ますが、上記のドキュメントの名称と違うので注意してください。

# まとめ

これでUIFlowと自分の作ったプログラムを簡単に切り替えできるようになりました。

p.s.
[A]ボタンをリセットスイッチ側で押すと、リセットボタンが干渉して押せないことがあります。リセットスイッチの逆側を押すようにすると押せます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58795/dd7b8f1c-e609-d01f-8de7-b51428ff98d4.png)
Webを使った新人研修　～SQL基礎編・SELECTクエリでデータ検索～

######[Webを使った新人研修　～SQL基礎編～](https://qiita.com/fujisystem/items/ed3236c0e73907cf3942)

#SELECTクエリでデータ検索

細かい説明をしていては果てしないので、「習うより慣れろ」の精神で
まずは、「実践」してみましょう。

##実践する

[Ideone](https://ideone.com/l/sqlite)をブラウザで開いてみましょう。

右下の緑色ボタン「Run」を押してみましょう。

```sql
create table tbl(str varchar(20));
insert into tbl values('Hello world!');
select * from tbl;
```

[これ](https://ideone.com/tnBMEM)をforkしてみても良いです。

##解説


例題を示して記憶の定着を図ってみます。

##例題
１．〜

```sql
```

<br>

～本日はここまで
業務でよく使うコマンドをまとめてみた

#はじめに
業務でログ調査を行うので、その際よく使うコマンドをまとめてみました。


#grepコマンド

ファイル中の文字列を検索するコマンドです。


###基本的な使い方


```
grep オプション "検索文字列" ファイル名 
```

###オプション
| オプション名 | 説明 |  
|:-----------------|:------------------|
| -v           |    一致しないものを検索する         |
| -e             |    一致処理に指定した正規表現を使う           |


#cutコマンド
テキストファイルを横方向に分割するコマンドです。

###基本的な使い方
必要なバイト数で指定したり、区切り文字でファイルの内容を取得することができます。

```
cut オプション ファイル名  
```

###オプション
| オプション名     | 説明 |  
|:-----------------|:------------------|
| -v           | 区切り文字を指定できる |
| -e             | 必要な項目を項目数で指定できる |


#sortコマンド

データを昇順で並べ替えできるコマンドです。

###基本的な使い方
```
sort ファイル名
```

#uniqコマンド
sortであらかじめ並べ替えされた状態で重複行を削除できるコマンドです。

###基本的な使い方
```
uniq ファイル名
```

#scpコマンド

リモートマシンとローカルマシン、またはリモートマシン間でファイルをコピーする際に使用するコマンドです。

###基本的な使い方

```
scp ユーザ名@リモートのホスト名:コピーしたいリモートのファイル ローカルのコピー先
```