OmniAICreator/Qiita-1.07M huggingface dataset:
MaixCubeでArduino/Maixduinoする

# はじめに

MaixCubeの基本はMicroPythonのMaixPyの利用です。MaixPyは画像のライブラリーがあったり便利な反面、メモリーの制約、現時点ではMaixCubeのサウンドがサポートされていないなど発展途上の面もあります。

# Maixduino

MaixCubeでも、Maixシリーズ用のArduino開発環境Maixduinoを使ってみましょう。

PlatformIOを使う場合、「+ New Project」新規プロジェクトを作成を選択し、

![20200612_pio1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555397/aed93749-a355-54e1-4065-78b58bf3d371.png)

ボードに「Sipeed MAIX GO」を選択すれば、MaixCubeでもOKです。

![20200612_pio2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555397/c579aa8e-0ac9-9ca5-2686-7d3e3c8b8871.png)

# サンプルアプリ

MaixPy版の[MaixCubeでAIを体験する（顔認識）](https://qiita.com/fukuebiz/items/4e25f3ef60aaea6c98de)のArduino版はこちら、

- [顔認識アプリのArduino版](https://github.com/fukuen/maixcube-face-detect-demo)

# Kboot

loborisのKbootも使えます。レバースイッチの左はピン11です。

```c:bootloader_hi/main.c
// Constants
/*
 * Pin used to enter interactive mode and request the user
 * to select which application to load
 * Any valid and not used K210 gpio can be used except gpio#16 (0 ~ 15 & 17 ~ 47)
 */
#define BOOT_PIN            18 <-- ここを11に修正する
#define GPIO_KEY            2
```

参考

- [Maixduinoでマルチブートする①](https://qiita.com/fukuebiz/items/f5ee98dbd1ab5055a50b)
- [Maixduinoでマルチブートする②](https://qiita.com/fukuebiz/items/e1170a8e798c20ac1feb)

# Ktool

Ktoolでフラッシュメモリに書き込む場合の、platformio.iniの設定はMaix-Goなどと同じです。

```ini:platformio.ini
; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:sipeed-maixcube]
platform = kendryte210
board = sipeed-maix-go
framework = arduino

monitor_speed = 115200
upload_flags =
    -a
    2621440
    -p
    COM4
    -B
    goE
upload_command = $PROJECT_PACKAGES_DIR/ktool/ktool.py $UPLOAD_FLAGS $SOURCE

```

# まとめ

MaixCubeでもArduino互換の開発環境ができました。
アセンブリ言語(CASL2)を学習＃１

#はじめに。
　今回は基本情報技術者試験に使われるCASL2/COMET2をやります。
簡略化されたものであり、アセンブリ言語の基本を学習するために行います。
#CASL2/COMET2のインストール
 1. [Visual Studio Code](https://code.visualstudio.com/)をインストールする。
 2. [CASL2/COMET2](https://marketplace.visualstudio.com/items?itemName=MaxfieldWalker.vscode-casl2-comet2)をインストールする
 
#CASL2について
　アセンブリ言語にはレジスタ、メモリがあります。
レジスタには凡用レジスタ(GR0~GR7)、フラグレジスタ(ZF,SF,Of)、プログラムレジスタ(PR)、スタックポインタ(SP)があります。<br>メモリにはプログラム領域、データ領域、スタック領域があります。
（図や説明があり、わかりやすいです。→https://arcanum.work/contents?id=10#3-1）
#CASL2を実際に書いてみる

```HELLO.cas
HELLO     START                 ; プログラムの開始
          OUT     BUF2, LEN2    ; 文字列の出力
          RET
BUF       DC      'Hello world' ; 文字列 
LEN       DC      11            ; 文字列の長さ
          END
```
　CASL2のファイルの拡張子は.casです。ラベル、命令、オペランド、コメントはそろえていますが見やすくするためであって意味はありません。<br>(注 : ラベル、命令、オペランドの間に一つ以上のスペースは必要です)
## コードの説明
###START命令、END命令
　START命令でプログラムが開始し、END命令で終了を意味します。ラベルはこの間の中でのみ有効です。
###DC命令
　DC命令はデータ領域を確保し、初期値を入れる命令です。
###OUT命令
　OUT命令はオペランドに文字列と長さを指定します。<br> ただし、直接文字列、長さを入れることはできません。なので、正しくは文字列を格納するアドレスと文字列の長さを格納するアドレスをオペランドに指定します。

```
〇  OUT     BUF2, LEN2    ; 文字列の出力
☓　OUT     "hello world", 11
```
###RET命令
RET命令はスタックにある値をPCに移し、スタックポインタの値を１増やす命令です。

#なぜ、RET命令が必要なのか。
　アセンブリ言語には疑似命令という言葉があります。疑似命令とは、アセンブル(コンパイル)のときに必要であり、実際はメモリには書かれません。命令はプログラムレジスタを進めることでどのメモリを実行するかを決めます。つまり、終わりがどこのかはわかりません。そのため、RET命令を書くことでスタックに格納されている値を読み取り終了しているわけです。
#終わり
　記事を書いた本人もアセンブリ言語を始めたばかりなので間違いがあると思います。なにかあれば、ご指摘ください。今後、少しずつアセンブラを投稿しようと思います。
np.whereで特定の要素を含む行を取得

私はpythonのnumpyを使ってよくテキストログを整形する機会がよくあるのですが、その際、１度つまずいたことのある内容について何度も調べることがあるのですが（１度解決したらどうでも良いやと思っている点は直したい…）、その際調べても出てきづらいnp.whereの返り値の使い方について備忘録として残しておきます。内容がチープなのは許してください…
##np.whereで特定の要素を含む行を取得

そもそものnp.whereの返り値はindexの情報を取得できます。そのことを２次元のnumpy配列を使って見ていきましょう。

```python:test1.py
import numpy as np 

array = np.array([["a","b","c"],["d","e","f"],[1,2,3]])

print(np.where(array == "d"))
```
```console:実行結果
$ python test1.py
(array([1]), array([0]))
```

この実行結果は視覚的には` d `という文字列は numpy 配列`array`の`array[1][0]`にあるよ、ということを示しています。実際この返り値をどう扱うかは以下を見ていきましょう。

```python:test2.py
import numpy as np 

array = np.array([["a","b","c"],["d","e","f"],[1,2,3]])

print(np.where(array == "d"))
print(type(np.where(array == "d")))
print(np.where(array == "d")[0])
print(np.where(array == "d")[1])
print(np.where(array == "d")[0][0])
print(np.where(array == "d")[1][0])
```
```console:実行結果
$ python test2.py
(array([1]), array([0]))
<class 'tuple'>
[1]
[0]
1
0
```
ということで `np.where` の返り値は tuple になっていて欲しい値によって適切にindexの指定をする必要があります。

今回は文字列`d`がある行(=1)を指定したいので`np.where(array == "d")[0][0]` を利用します。

```python:test3.py
import numpy as np 

array = np.array([["a","b","c"],["d","e","f"],[1,2,3]])

print(array[np.where(array == "d")[0][0]][:])
```
```console:実行結果
$ python test3.py
['d' 'e' 'f']
```


##おまけ

np.where を使って色々試したことも書いておきます。


```python:test4.py
import numpy as np 

array = np.array([["a","b","c"],["d","e","f"],[1,2,3]])

print(array[np.where(array == "d")])
```
```console:実行結果
$ python test4.py
['d']
```
numpy配列のindex指定の際に直接入れると指定した要素が配列に入った状態で返ってきます。

しかし、これでは、`d`という値を得られたわけではありません。

`d`自体を得るには以下のように、返ってきた配列のindexを指定しなければなりません。

```python:test5.py
import numpy as np 

array = np.array([["a","b","c"],["d","e","f"],[1,2,3]])

print(array[np.where(array == "d")][0])
```
```console:実行結果
$ python test5.py
d
```

ここまでは、そもそも np.where を使う目的が特定の要素を含む index の取得であるのでこうした使い方はしねぇよって感じなんですが、おまけなのでご容赦ください…
ゲッター、セッターなんかやめてまえ

クラスにゲッター、セッターを作るのは
時間と資源の無駄やし、何の意味もない。
1. カプセル化になってへん
2. それを作っただけで仕事した気になってる
3. 2. のせいで、ほんまに必要な機能を実装してへん
統計検定2級を受けた

# はじめに
先日統計検定2級をCBT方式で受けました。勉強したことを備忘録として残しておきます。
同じように統計検定を受けようとしている人の役に立てれば幸いです。

# 受験決意から合格まで
本当は6月の準1級試験を受けようと思っていました。しかし、新型コロナウイルスの影響で早々に統計検定の公式で中止が発表され、いつ受けられるか不透明な状況に...

そこで、CBT方式（PCで受ける方式）でいつでも受けられる2級をひとまず受けてみることにしました。受けようと決めたのは4月上旬くらい。

そこから6月の初めに受けるまでが勉強期間ですが、そこまでガッツリやっていたわけではないです。
最終的に合格時の点数は77/100でした。


# 勉強内容

### 当時の自分のレベル
  * 大学院1年生（情報工学系の専攻）
  * 確率や統計については大学在学時の授業で扱った程度であまり覚えていない。

受けようと決めたときには統計検定2級の範囲もよく知らなかったので、まず一番新しい過去問を解いてみました。（統計検定の公式HPに最新の過去問だけは公開されています）

このときは正答の数は7割くらいで、かかった時間が75分くらい。このとき、前半の基本的な問題は結構できていましたが、後半の推定・検定の問題は合っていてもたまたまだったということが多く、理解は全然できていませんでした。

## ①マセマの『統計学』
![51GXaa-bU8L._SX353_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526744/44b923e1-e4b2-c845-acbf-908cb98578ee.jpeg)
統計学の基本からやり直そうと思いましたが、研究室には入れないし本屋も閉まっている...
とりあえず手元にあったマセマの統計学をやり始めました。二項分布から正規分布・ポアソン分布の導出などの式変形も一度は手で追うようにして、演習問題も一部解きました。

この本には導出がきちんと書かれているので、数学力が必要になる一方で理解は深まる気がします。でも、統計検定をうけるだけならここまでやらなくてもいい気はします。
推定・検定についても、母平均の検定・母平均の差の検定・母分散の比の検定など基本的なものは出てきますが、統計検定2級だとたまに出てくる、適合度検定や一元配置分散分析などは出てきません。

## ②『基本統計学』
![ダウンロード.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526744/a9fc3481-8039-ba26-b799-1f3aac1bc8de.jpeg)
マセマの次に、たまたま研究室から借りていた『基本統計学』という本をやりました。これも最初から式を手で追いつつ説明を読んで、章末問題を一部解きました。

こちらは初学者にもわかるように、現実の身近な例を統計学の手法に落とし込む、というような説明をされていてわかりやすいです。各章の章末問題も問題数が多いので、演習量もこなせます（※章末問題の解説はないです）。
ただ、数学的な背景は一部カットされている（ex.二項分布から正規分布の導出、などは書かれていない）ので、多少天下り的に説明がされている感はあります。自分は逆に、このあたりはマセマをやっていたおかげで特に疑問もなく読み進められたと思います。
この本には適合度検定や分散分析や回帰パラメータの検定なども載っていたので、統計検定の広い範囲をカバーできていると感じました。

## ③統計検定の過去問
![511s3vTO3+L._SX351_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526744/8973363b-4a37-9a8e-dd4e-1f75b06548b1.jpeg)
最後に過去問演習に入りました。といっても『基本統計学』をやってからかなり間があいてしまい、始めたのは試験の直前です。ひとまず1回分解いてみましたが、このときは言葉の定義（標本の抽出法やフィッシャーの3原則など）と回帰分析の結果の解釈（t値やP-値の解釈）の問題がさっぱりでした。
統計学の用語については、「[統計学の時間|統計web](https://bellcurve.jp/statistics/course/)」を参照しました。統計検定に出てくる単語はここを調べればとりあえずOKではないでしょうか。
回帰分析の結果の解釈は、自分はネットで色んな記事を当たって調べましたが、これはRを使ったことがある人なら実際にやってみるのもいいと思います。

その後、各試験回で難しそうな問題or見たことないテーマの問題だけをピックアップして解いて本番に臨みました。明らかに過去問演習不足だと思うので、本来はもっとやるべきだと思います...

# 本番の話
CBT方式の場合、申し込み期限は会場によると思います。自分は5日前くらいに予約しました。しかし、都心部だと埋まるのが割と早いので、余裕を持っておいた方が良いです。

他の多くの試験と同じく、会場についたら受付をして荷物を預けて、ブース型のスペースでパソコン見ながら問題を解く、というスタイルです。自分以外に4人いて、みな統計検定2級を受けているようでした。

問題はプールされているものからランダムに出されるらしいので、人によって感想は違うと思いますが、自分は思ったより難しく感じました。終わったのも90分ギリギリで、紙ベースの過去問と少し違うな～と思っていました。

CBTを受けるなら過去問は手広くやって、広範囲をカバーするような勉強がより求められるような気がしました。

# さいごに
明らかに演習不足なのに合格できたのはよかったです。
いつ開催されるのかわかりませんが、チャンスがあれば準1級も受けてみたいと思います。
Ubuntu 18.04でOpenGLが使えるリモート接続環境を構築

# 環境
### サーバー
- OS
    - Ubuntu 18.04 LTS
- CPU
    - Core i9 10980XE 3.0GHz
- GPU
    - GeForce RTX 2080Ti 11GB x3

### クライアント
- OS
    - Ubuntu 18.04 LTS
- CPU
    - Ryzen 9 3900X 3.60GHz
- GPU
    - GeForce GTX 1080Ti 11GB x2


# 大まかな手順
1. サーバーにVirtualGLをインストール
2. サーバーにTurboVNC(Server)をインストール＆設定
3. クライアントにJDKをインストール
4. クライアントにTurboVNC(Client)をインストール

# サーバー側の手順
### VirtualGLの導入
参考：http://www.yasunaga-lab.bio.kyutech.ac.jp/EosJ/index.php/VNC%E3%81%A7%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97
#### ダウンロード
[こちらのサイト](https://sourceforge.net/projects/virtualgl/files/)から最新版のdebパッケージをダウンロード

#### インストール
```
sudo dpkg -i virtualgl_2.X.X_amd64.deb
```

### VirtualGLの設定
参考[2]：https://qiita.com/exthnet/items/dcb0bd94f09a2b4c9835#virtualglturbovnc%E3%81%A7%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88opengl

```
sudo /opt/VirtualGL/bin/vglserver_config
```
`1` → `y` → `y`　→ `y` → `x` の順で選択

下記のコマンドはエラーが帰ってくるが、結果的に成功したのでとりあえずスルー

```
sudo rmmod nvidia
```
```
sudo rmmod nvidia_modeset
```
```
sudo rmmod nvidia_modeset_drm
```

### TurboVNCの導入
[こちらのサイト](https://sourceforge.net/projects/turbovnc/files/)から最新版のdebパッケージをダウンロード

```
sudo dpkg -i turbovnc_2.X.X_amd64.deb
```

### TurboVNCの起動
```
/opt/TurboVNC/bin/vncserver -depth 24 -geometry 1920x1080
```
その後、パスワードを2回入力して完了

# クライアント側の手順
参考：http://www.yasunaga-lab.bio.kyutech.ac.jp/EosJ/index.php/VNC%E3%81%A7%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97
### JDKのインストール
参考：https://www.codeflow.site/ja/article/how-to-install-java-with-apt-on-ubuntu-18-04

```
sudo apt install -y default-jre && default-jdk
```

### TurboVNCの導入
[こちらのサイト](https://sourceforge.net/projects/turbovnc/files/)から最新版のdebパッケージをダウンロード

### TurboVNC Viewerを起動
アプリケーション一覧から`TurboVNC Viewer`を起動

### TurboVNCで接続
```
192.168.X.XXX:1
```
サーバーのIPアドレスを入力して`Connect`


# トラブルシューティング
## DockerでNVIDIA GPUが使えなくなる
参考：http://www.yasunaga-lab.bio.kyutech.ac.jp/EosJ/index.php/Docker%E3%83%88%E3%83%A9%E3%83%96%E3%83%AB%E3%82%B7%E3%83%A5%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0
参考：https://github.com/NVIDIA/nvidia-docker/issues/752

```
sudo vim /etc/modprobe.d/virtualgl.conf
```

`NVreg_DeviceFileMode=0660` を `NVreg_DeviceFileMode=0666` に書き換える

```
sudo update-initramfs -u
```

その後再起動
Vue3におけるローディング/ロード状態管理の一例

## 追記
fix: enumの代わりにオブジェクトを使用することにしました(2020/07/04)

## 背景
よくローディング画面中にスピナーだったり「ローディング中」みたいな文字列などを使ってユーザにロード状態を知らせますが、このスピナーなどの制御はリアクティブ変数として`isLoading`のようなbooleanでコントロールしていました。
ただ正直`isLoading`とBooleanだけでコントロールするのはどうかなぁ、ロード完了みたいな状態も欲しいと思っていて、現在は以下のように使用しています。備忘録的にこれを記事に残しておきます。


## コード
`request`という変数をリアクティブにして、ここでエラーと状態を管理しています。
ただし取得したデータは別の変数に渡します。自分のユースケースではマイクロサービス構成が多く、しばしば複数のAPIに並列でつなぐ可能性があるので、一つの変数にいろんなデータを入れるとややっこしくなる可能性があるので、ロード状態管理とデータ用配列を別に管理しています。

``` utils/index.ts
export const RequestState = {
  UNINITIALIZED: 'UNINITIALIZED',
  LOADING: 'LOADING',
  LOADED: 'LOADED',
  COMPLETE: 'COMPLETE',
  FAILURE: 'FAILURE'
}
```
enum風オブジェクトによる状態変更をします。

```vue:index.vue
<template>
  <article>
    <span v-if="request.state == RequestState.LOADING ">...loading</span>
    <span v-if="request.state == RequestState.COMPLETE">{{ data }}</span>
    <span v-if="request.error">{{ request.error }}</span>
  </article>
</template>
<script lang="ts">
import { ref, reactive, onMounted } from 'nuxt-composition-api'
import axios from 'axios'
import { RequestState } from '~/utils'
export default {
  name: 'Index',
  setup() {
    const data = ref({})
    const request = reactive({
      state: RequestState.UNINITIALIZED,
      error: ''
    })

    onMounted(async () => {
      try {
        request.state = RequestState.LOADING
        const res = await axios.get('https://api.github.com/zen')
        data.value = res.data
        request.state = RequestState.COMPLETE
      } catch (e) {
        request.error = e
        request.state = RequestState.FAILURE
      }
    })

    return { data, request, RequestState }
  }
}
</script>

```

以上、シンプルにまとめられました😄
実際のコードではaxiosのラッパーみたいなものでAxiosPromiseオブジェクトを返してvueコンポーネントで使用していますが、プロセスとしては以上のようなものです。
requestsでダウンロードした画像を直接S3にアップロードする

# 目的
ローカルに保存された画像ファイルををS3にアップロードする手順は見かけるのですが、本記事は表題の通り、ダウンロードした画像をファイルに保存することなく直接アップロードすることを目的としています。

# 方法

`requests.get`で取得したバイナリデータを`io.BytesIO`に渡すことでファイルオブジェクトとして扱います。

```python
import requests
import io
import boto3

# 画像をダウンロード
res = requests.get('画像のURL')
res.raise_for_status()

# 取得したバイナリデータをファイルオブジェクトに変換
img = io.BytesIO(res.content)

# S3にアップロード
s3 = boto3.client('s3')
s3.upload_fileobj(img, 'bucket_name', 's3/path')
```
MacにMySQLを入れる方法 （Homebrewを使用）

MacBook AirにMySQLを入れた手順を備忘録として残しておこうと思い記事を書きました。

環境
--------------
今回のOSのバージョンはOS Catalina バージョン10.15.3です。

手順
--------------
###Homebrewをインストールする
Homebrewを入れるため、下記のコマンドをターミナルで実行します。

``` 
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```
※本記事投稿後にコマンドが変わっている場合があるので[公式サイト](https://brew.sh/index_ja.html)にアクセスして最新のコマンドを利用するようにしてください。

####MySQLをインストールする
次にMySQLをインストールするために下記のコマンドをターミナルで実行します。

```
brew install mysql
```
するとMySQLがインストールされます。

####MySQLの起動と設定手順
・起動
MySQLのインストールが完了したらMySQLを起動させてみましょう。
下記のコマンドをターミナルへ入力し実行します。

```
mysql.server start
```
SUCCESSと表示されれば起動成功です。
mysql>を止めたい場合はexitを入力することでコマンドモードを解除できます。
MySQLを停止させたい場合は下記コマンドをターミナルへ入力し実行します。

```
mysql.server stop
```

・設定
次にMySQlのセキュリティ設定を行います。
MySQLを起動した状態で下記のコマンドをターミナルに入力し実行します。

```
mysql_secure_installation
```
すると下の画像のようにパスワードを設定するかどうか聞かれるので```y```を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653932/8f3d79b3-5de0-290d-91aa-0a0dce30b9db.png)
次にパスワードの強度を3段階で設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653932/b1f1ee49-fba4-b1dc-ca4b-0d3ee7d00326.png)
パスワードを設定し、入力したパスワードで作業を進めて良いかの確認がされるので```y```を入力して設定を続けましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653932/70ac585e-0649-58eb-6aa6-19b53dc047a3.png)
anonymousユーザを削除するかの確認が行われます。
anonymousユーザを削除したい場合は```y```を入力してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653932/3b490597-4108-a125-e1e2-cda4c07f37b4.png)
次にrootユーザがリモートサーバからログインできないようにするかの確認が行われます。
リモートサーバーからrootユーザーへのアクセスを遮断したい場合は```y```を入力してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653932/17dac34a-0b79-01aa-4367-e289f2890851.png)
そしてテスト用のデータベースを削除するかどうかの確認が行われます。
データベースを削除したい場合は```y```を入力してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653932/cea6c666-efcf-03d7-53d8-569e9232a668.png)
最後にこれまでの設定内容をデータベースに反映するかの確認が行われます。
反映漏れをなくすためにも特に理由がない場合は```y```を入力しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653932/928c7236-61b5-1077-cd41-c578564434cb.png)
上記の画像のようにAll done!が表示されれば、セキュリティ設定が完了です。

####ログインの方法
パスワード設定後にログインをする場合は下記のコマンドをターミナルへ入力して実行してください。

```
mysql -uroot -p
```
パスワードを入力し、MySQLでのコマンド入力モードになっていたらログイン成功です。

参考にさせていただいた記事
--------------
[Mac環境にMySQLをインストールしてみよう！初期設定までの手順を徹底解説！](https://style.potepan.com/articles/19020.html)
【Rails】form_withを使用すると画面が固まってしまう！？

# 経緯
プログラミング歴３ケ月の初心者です。
先日、個人的にアプリケーションを作成しておりまして…
**「form_with」**を用いてメッセージ投稿フォームを実装していた時のこと。。

```haml:ビュー
= form_with model: @post, url: posts_path, method: :post, html:{ class: "post" } do |f|
  = f.text_area :post
  = f.submit "投稿する"
```
あれ、、「投稿する」ボタンを押してもビュー（画面）が推移しないぞ？？

モデルやパスを確認しても間違ってはなさそう…
なのに、コントローラーで処理されない。。

そう、私はform_withを**わかったふりして完全に舐めていた**のです。（もちろんそんな気はありませんでしたが）
なぜなら、今まで勉強してきたのは form_for、form_taｇ だったので、**書き方が変わるだけで同じことができる**だろうと思っていました。


# 原因
早速答えを言っちゃうと、form_withは**自動的にajax処理（非同期通信）**をしてしまうんです！！
もちろん、 form_for、form_taｇ にはそんな仕様ありませんでした。

# 解決策

```haml:ビュー
//form_withの最後に local: true を記載してあげます。 
= form_with model: @post, url: posts_path, method: :post, html:{ class: "post" }, local: true do |f|
  = f.text_area :post
  = f.submit "投稿する"
```

上記のように記載したら、普通に投稿できるようになりました。

ajax処理をし**たい**場合…そのまま
ajax処理をし**ない**場合…local: true

# まとめ
以上になります。

某スクールや○○gateでは form_for、form_taｇ で勉強することが多いので、
私以外にも今回のような状況に陥ってしまう方がいるのでは？
と思い、今回書いてみました。

form_for、form_taｇ はとても勉強になるのでform_withに慣れてしまう前に一度勉強してみることを
お勧めしますが、やはり別物なので、form_withもしっかり勉強が必要だなと感じた今日この頃でした。
Promiseとasync/awaitでの非同期処理

# 非同期処理
毎回理解できた気になるけど、他人のコード見るたびに「こんな書き方あるんだ…」、「これなんのための記述…」ってなる…

もう書き尽くされたお題だと思いますが、自分のためにアウトプットします。すみません。

# とりあえずやってみたいこと

test1.txtを読み込んでファイル名を取得して、次のファイルを読んで…を繰り返して最終的にtest3.txtの内容を出力してみる。

```:test1.txt
./test2.txt
```
```:test2.txt
./test3.txt
```
```:test3.txt
Hello World!
```


実行結果は全部これです。

```:実行結果
> node .\index.js
./test2.txt
./test3.txt
Hello World!
```


# コールバック

昔からあるコールバックで実現しようとすると

```javascript
function func() {
    // 1つ目のファイルの読み込み
    fs.readFile('./test1.txt', 'utf-8', (err1, data1) => {
        console.log(data1);

        // 2つ目のファイルの読み込み
        fs.readFile(data1, 'utf-8', (err2, data2) => {
            console.log(data2);

            // 3つ目のファイルの読み込み
            fs.readFile(data2, 'utf-8', (err3, data3) => {
                console.log(data3);
            })
        })
    })
}
```

コールバックが深くなると見づらくなる

# Promise
処理をまとめて、Promiseを返すようにしてみる

```javascript
function func(file) {
    return new Promise((resolve, reject) => {
        fs.readFile(file, 'utf-8', (err, data) => {
            console.log(data);
            resolve(data);
        })
    });
}

func('./test1.txt')
    .then(func)
    .then(func);
```

Promiseが解決してresolveが返ってくると、thenが実行される
thenメソッドの引数は関数
そしてその関数の第一引数にはresolveの値が入る

けど、2回目以降のfuncに引数がなくて違和感がすごい

# ちなみに

```javascript
function func(file) {
    return new Promise((resolve, reject) => {
        fs.readFile(file, 'utf-8', (err, data) => {
            console.log(data);
            resolve(data);
        })
    });
}

Promise.resolve('./test1.txt')
    .then(func)
    .then(func)
    .then(func);
```

使い分けがよくわかっていない

以下の記事に`new Promise()`と`Promise.resolve()`の使い分けが書いてあるが、まだいまいち理解できていない
[return new Promise()とreturn Promise.resolve()使い分け](https://qiita.com/hey1you1/items/a9b144c94f84cd1d91b8)


# 混ざってむちゃくちゃ

```javascript
function func(file) {
    return new Promise((resolve, reject) => {
        fs.readFile(file, 'utf-8', (err, data) => {
            console.log(data);
            resolve(data);
        })
    });
}

func('./test1.txt')
    .then(async (data1) => {
        let data2 = await func(data1)
        return data2
    })
    .then(data2 => {
        func(data2)
    });

```

thenの中でいろいろしたい時はこれでもいいのかも

# async/await

```javascript
function func(file) {
    return new Promise((resolve, reject) => {
        fs.readFile(file, 'utf-8', (err, data) => {
            console.log(data);
            resolve(data);
        })
    });
}

(async () => {
    let data1 = await func('./test1.txt');
    let data2 = await func(data1);
    func(data2)
})();
```
圧倒的に理解しやすい

# まとめ

書いてるときは理解できた気になるけど、他人のコード解読するのは難しい
Githubの使用言語比率に表示させたくない言語を消す

# 背景
Githubのレポジトリは、コミットされたファイルに使われている言語を自動判別して使用言語の比率を表示してくれる。

ところがどっこい、私のポートフォリオのレポジトリは、JavaScriptとRubyで構成されるはずなのにどこかのタイミングで90%近くがpythonと表示されてしまった。
![使用言語比率](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531430/921d44ab-a574-96cf-beb9-61947913c8ba.jpeg)

しかもpythonの項目をクリックしてみても何のファイルが反映されているのか内訳が表示されない！
![比率詳細](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531430/d27ca4c0-aa21-cd39-add3-c5fabac5ad41.jpeg)

恐らく外部のライブラリが悪さしているんだろうがファイルが特定できないので困った。

# 対応
## どのファイルかわからない場合
1. レポジトリのルートディレクトリに`.gitattibutes`というファイルを作成する。
2. 作成した.gitattributesに以下を記載する。

```.gitattributes
*.py linguist-vendored
```
__※今回python関連のファイルを認識させたくないので*.pyとしているが、他の言語の場合は適宜変更する。__
3. リポジトリにコミットして反映させる。

![修正後](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531430/04b984eb-a8c3-019a-ec03-e28aba4c3a30.jpeg)

直った！

## どのファイルかわかっている場合
作成した.gitattributesに、.gitignoreを書くときと同じ記述ルールで使用言語として認識させたくないファイルを指定していくだけ。
ベンダーファイルとして認識させたいなら`linguist-vendored`, ドキュメントなら`linguist-documentation`などの属性が指定できる。
詳しくは公式Docをどうぞ: https://github.com/github/linguist#overrides

# 参考
_公式Doc:_ https://github.com/github/linguist#overrides
_GitHubによる主要認識言語を切り替える:_ https://qiita.com/shin_t_o_/items/aba1df5d499c69042162
react-hooks useReducerメモ

# useReducer
[公式doc](https://ja.reactjs.org/docs/hooks-reference.html#usereducer)

# 位置づけ
> 通常、useReducer が useState より好ましいのは、複数の値にまたがる複雑な state ロジックがある場合や、前の state に基づいて次の state を決める必要がある場合です。また、useReducer を使えばコールバックの代わりに dispatch を下位コンポーネントに渡せるようになるため、複数階層にまたがって更新を発生させるようなコンポーネントではパフォーマンスの最適化にもなります。

ということで、場合分けの記述が出来たり、dispatchを下位コンポーネントに引き渡すことも可能とのこと。

## よく見かけるreduce関数と違う
Javaとかのreduce関数とはちょっと違う。

## useReducerの処理イメージ
useReducer関数により、管理対象のstate、stateを更新するdispatch関数を生成する。
dispatch関数の動作は、useReducerの第一引数reducerにて定義する。
管理対象のstateは、useReducerの第二引数、第三引数で初期値を与える/導出させる。
dispatch関数は任意のany型引数を受け取れる（＝reducer関数で利用できる）。

### 何が良いのか
デザインパターンの[ストラテジーパターン](https://ja.wikipedia.org/wiki/Strategy_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3)を実現できる。
wikiの言葉を借りれば、
> 設計に優れた柔軟性をもたせることができ、かつ拡張に対して開放的であり変更に対して閉鎖的であるべきとする開放/閉鎖原則 (Open/Closed Principle, OCP) とも調和を保つことができる

言い換えれば、

* useReducerの第一引数であるreducerにstateに対する処理が閉鎖的に記述できる
* dispatch(action:any)により、どんな引数もreducerに渡せるという意味で拡張に開放的である

さらに
dipacth関数を子コンポーネントに渡せる。


## useReducerの仕様

```typescript

type useReducer = (reducer: reducer, initialArg: any, initializer: initializer) => dispatch: Function
type reducer = (state: object, action: any) => newState: any
type initializer = (initialArg: any) => initialState: any
```
※こんな書き方は出来ないがイメージ。

### useReducer関数のシグネチャ
#### 引数
1. reducer関数のシグネチャを持つ関数。
2. 初期state。
2. オプション。初期化関数。第二パラメータを引数として起動し、初期stateを返却する関数。

#### 返り値
1. state
2. dispatch関数

### reducer関数のシグネチャ
#### 引数
1. 現在のstate。
2. actionと呼称するanyオブジェクト。

#### 返り値
reducerにて、計算した新たなstate

### dispatch関数のシグネチャ
actionおよび現在のstateを引数にreducer関数が実行される。
#### 引数
1. actionと呼称するanyオブジェクト。

#### 返り値
void

# 実装例

addとdeleteのactionを受け取れるreducerを定義してみた。

[codesandbox](https://codesandbox.io/embed/usereducer2-kh1rk?fontsize=14&hidenavigation=1&theme=dark)

```react

import React, { useReducer } from "react";
import "./styles.css";

export default function App() {
  const initialState = { data: [] };
  const [state, dispatch] = useReducer((state, action) => {
    if (action.type === "add") {
      return { data: state.data.concat(Math.random().toPrecision(2)) };
    }
    if (action.type === "delete") {
      const newData = Array.from(state.data);
      newData.splice(action.index, 1);
      return {
        data: newData
      };
    }
    return { data: state.data };
  }, initialState);

  return (
    <div className="App">
      <button onClick={() => dispatch({ type: "add", index: 0 })}>Add</button>
      <br />
      {state.data.map((e, index) => {
        return (
          <div key={"div_" + index}>
            <label>{index + ":" + e}</label>
            <button
              onClick={() => {
                dispatch({ type: "delete", index: index });
              }}
            >
              delete
            </button>
            <br />
          </div>
        );
      })}
    </div>
  );
}

```
ループ処理

##繰り返し処理の種類
Rubyの繰り返し処理の種類として、**each**メソッド、**for**文、**whil ,until**文、**times**メソッド、**up_to**メソッドなどがあるそうです。paizaのアルゴリズムで繰り返し処理を行う際にどの処理を使えば良いかイマイチ理解していないので、使い方、特徴をまとめる。

##まず前提
繰り返し処理は、配列(複数のデータを順番に並べて格納できるオブジェクト(Arrayクラス))、ブロック(メソッドの引数として渡すことができる処理のかたまり)と一緒に使うことが多い。Rubyは、eachメソッドを使って反復処理を行う場合が大半。※多言語では、for,foreach構文を使うことが多い。

##eachメソッド
Rubyが言語機能として繰り返し処理を実行しているのではなく、配列のeachメソッドが繰り返し処理を実行している。
eachメソッドの役割は、配列の要素から最後までを順番に取り出すことができる。その取り出したものをどのように扱うかは**ブロック**に記述する。

```
#例(配列の要素を加算していく処理)
numbers = [1, 2, 3, 4]
sum = 0
numbers.each do |n|
  sum += n
end
sum #=> 10
```
###ブロックとは
ブロックは先ほどのコードの中の以下の部分。|n|のnは**ブロック引数**(名前は自由)といい、eachメソッドから渡された配列の要素が入る。

```
#ブロック部分

             do |n|
  sum += n
end
```
###ブロック(改行なしバージョン)

```
#do .. endの代わりに{}を使う

numbers.each {|n| sum += n}
```

##timesメソッド
配列を使わず単純にn回処理を繰り返したい、という場合はIntegerクラスのtimesメソッドを使う。

```
sum = 0
#処理を5回繰り返す。nには0,1,2,3,4が入る。
5.times {|n| sum += n}  or  5.times{sum += 1}
sum #=> 10
```
##uptoメソッドとdowntメソッド
nからmまで数値を1つずつ増やしながら何かを処理したい場合は、Integerクラスのuptoメソッドを使う。逆に、1つずつ減らすdowntoメソッド。

```
#uptoメソッド
a = []
10.upto(14) {|n| a << n}
a #=> [10, 11, 12, 13 ,14] 

#downtoメソッド
a = []
14.doentown(10){|n| a << n}
a #=> [14 ,13 ,12 ,11 ,10]
```

##while文とuntil文

繰り返し処理用の構文。
whileの後の条件式が真であれば実行。untilの後の条件式が偽であれば実行。
※whileの後にtrueを使うと無限ループの処理を行える。脱出するにはbreakを使う。

```
#while文
a = []
while a.size < 5
  a << 1
end
a #=> [1 ,1 ,1 ,1 ,1]

#until文
a = [10 ,20 ,30 ,40 ,50 ]
until a.size <= 3 #配列aの要素が3つ以下でない限り最後の要素を消し続ける。
  a.delete(-1)
end
a #=> [10 ,20 ,30]
```

##for文

for文はeachメソッドと使う用途は同じと考えて良い。しかしRubyはeachメソッドを使うほうが一般的らしい。

```
numbers = [1 ,2 ,3 ,4]
sum = 0
for n in numbers 
  sum += n
end
sum #=> 10

#doを入れて1行で書くことも可能。
for n in numbers do sum += end
```


##まとめてみての感想
とりあえず、eachメソッドをベースに他のmapメソッドなどを使って、メソッドを色々覚えていくことが良さそう。
AWSのEC2にサーブレット(Servlet)環境を構築するメモ

## 1.Javaインストール

### Java8の検索
```
yum search java-1.8.0-openjdk-devel
```

### Java8のインストール
```
sudo yum install java-1.8.0-openjdk-devel
```

## 2.Apachのインストール

### Apachのインストール
```
sudo yum -y install httpd
```

### Apachの起動
```
sudo service httpd start
```

### 再起動時に自動起動
```
sudo systemctl enable httpd.service
```

## 3.インバウンドルールの作成
1. セキュリティグループ
2. インバウンドルールを編集
3. 「`HTTP　TCP　80(ポート範囲) 0.0.0.0/0`」を作成
4. ルールを保存

## 4.Tomcatインストール

### Tomcatインストール
```
sudo amazon-linux-extras install tomcat8.5
```

### Tomcat-Webappsのイントール
```
sudo yum install tomcat-webapps tomcat-admin-webapps
```

### Tomcatの開始
```
sudo systemctl start tomcat
```

## 5.MySQL

### mariadbの削除
```
sudo yum list installed | grep mariadb
sudo yum remove mariadb-libs
```

### MySQLのインストール
```
sudo yum -y localinstall http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm
```

### MySQLサーバー
```
sudo yum install mysql-community-server
```

### キャッシュ消去
```
sudo yum clean all
sudo rm -rf /var/cache/yum
```

### インストール確認
```
yum repolist enabled | grep "mysql.*-community.*"
```

### MySQL version確認
```
mysql --version
```

### MySQL起動
```
sudo /bin/systemctl start mysqld.service
```

### MySQLの起動確認
```
systemctl list-units | grep mysqld.service
```

### 現状の状態確認（disabled表示時のみ）
```
systemctl is-enabled mysqld.service
systemctl enable mysqld.service
```

### rootパスワード確認
```
sudo cat /var/log/mysqld.log | grep root
```

### root初期パスワード変更
```
SET GLOBAL validate_password_length=4;
SET GLOBAL validate_password_policy=LOW;
ALTER USER root@localhost IDENTIFIED BY 'root';
```

### 文字コード変更（[viエディタの使い方](https://prev.net-newbie.com/linux/commands/vi.html)）
```
vi /etc/my.cnf

i : インサート

「Esc」
「:wq」
or
「Esc」
「:w !sudo tee %」
「:q!」
```
```:my.cnf
[mysqld]
character-set-server=utf8

[client]
default-character-set=utf8
```

### MySQL再起動
```
sudo systemctl restart mysqld
```

### MySQL停止
```
sudo systemctl stop mysqld
```

### MySQLアンインストール
```
sudo yum remove mysql*
```



## 6.サーバーにアップ

### Tomcat Webappsにアップ
```
sudo cp ファイル名.war /usr/share/tomcat/webapps
```

### Tomcat Webapps内のファイル削除
```
sudo rm /usr/share/tomcat/webapps/ファイル名.war
```
java(多態性のメリット)

#多態性と配列の組み合わせ
###配列を組み合わせていないコード

```java
public class Main {
  public static void main(String[] args) {
    Hero h1 = new Hero();
    Hero h2 = new Hero();
    Thief t1 = new Thief();
    Wizard w1 = new Wizard();
    Wizard w2 = new Wizard();
    //冒険開始！
    //まず宿屋に泊まる
    h1.hp += 50;
    h2.hp += 50;
    t1.hp += 50;
    w1.hp += 50;
    w2.hp += 50;
  }
}
```

###配列を組み合わせたコード

```java
public class Main {
  public static void main(String[] args) {
    Character[] c = new Character[5];
    c[0] = new Hero(); 
    c[1] = new Hero(); 
    c[2] = new Thief(); 
    c[3] = new Wizard(); 
    c[4] = new Wizard(); 
    //宿屋に泊まる
    for (Character ch : c) {      //１名ずつ順に取り出し
      ch.hp += 50;                //HPを５０回復
    }
  }
}
```

#引数との組み合わせ

```java
public class Hero extends Character{
  public void attack(Monster m) {               //モンスターなら全部攻撃
    System.out.println(this.name + "の攻撃！");
    System.out.println("敵に10ポイントのダメージ");
    m.hp -= 10;
  }
}
```
モンスタークラスを継承していれば全てに攻撃する


#同じ指示で異なる動作をさせる


```java
public class Main {
  public static void main(String[] args) {
    Monster[] monsters = new Monster[3];
    monsters[0] = new Slime();
    monsters[1] = new Goblin();
    monsters[2] = new DeathBat();
    for (Monster m : monsters) {
      m.run();                    //同じ指示を繰り返す
    }
  }
}
```
実行結果
スライムは逃げ出した
ゴブリンは逃げ出した
地獄コウモリは逃げ出した

呼び出す側　　　逃げろ　　　　　　　　逃げろ　　　　　　　　逃げろ
呼び出される側　スライムは逃げ出した　ゴブリンは逃げ出した　地獄コウモリは逃げ出した
Dagger Hilt + Roomでbuildが通らない問題を解決する

# はじめに

Android/Javaプロジェクトの依存性注入フレームワークのひとつに[dagger](https://dagger.dev/)があります。
このdaggerの冗長なボラープレートや学習コストの高さを改善する新しいフレームワークが[Dagger Hilt](https://dagger.dev/hilt/)です。

[Room](https://developer.android.com/topic/libraries/architecture/room)は[JetPack](https://developer.android.com/jetpack)の一部として提供されているライブラリです。
SQliteにアクセスする処理をより簡潔に書くことができます。

# Dagger Hilt と Room を併用するとbuildに失敗する

Roomはコンパイル時、データベースのスキーマ情報をJSONファイルにエクスポートします。
このJSONファイルをgitなどで管理することで、テストやデータベースのマイグレーションに役立てることができます。
スキーマをエクスポートするには、build.gradle ファイル内に room.schemaLocation アノテーションプロセッサプロパティを設定します（[参考](https://developer.android.com/training/data-storage/room/migrating-db-versions)）。

```gradle

    android {
        ...
        defaultConfig {
            ...
            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
                }
            }
        }
    }
```

しかしこのアノテーションプロセッサプロパティの書き換えは、dagger hiltのアノテーションプロセッサにも反映されてしまい、その結果buildが通りません。

```
> Task :app:kaptDebugKotlin FAILED
/Users/hiroyukitamura/StudioProjects/dagger-hilt-example/app/build/tmp/kapt3/stubs/debug/com/github/aakira/hilt/ui/second/SecondActivity.java:7: エラー: [Hilt]
public final class SecondActivity extends androidx.appcompat.app.AppCompatActivity {
             ^
  Expected @AndroidEntryPoint to have a value. Did you forget to apply the Gradle Plugin?
```

# 解決方法

そこで前述のようにアノテーションプロセッサプロパティを書き換えず、追加することで対応します。

```gradle

    android {
        ...
        defaultConfig {
            ...
            javaCompileOptions {
                annotationProcessorOptions {
                    // "="ではなく"+="にすればargmentが追加されるだけで書き換わりません！
                    arguments += ["room.schemaLocation": "$projectDir/schemas".toString()]
                }
            }
        }
    }
```

# 最後に

既に[PR](https://github.com/google/dagger/pull/1884)がdaggerにあがっているので、そのうちdaggerのドキュメントが更新されるかと思います。

##### 参考記事

- [Hilt build fails if set annotationProcessorOptions in gradle](https://github.com/google/dagger/issues/1902)
git備忘録

##gitで困ったときに更新する記事
gitで分からなかったことを残しています。

##git管理の対象外にしたい　少なくとも３つの方法
自分のパスワードを記載した設定ファイル（`database.yml`など）をGitHubなどにプッシュしたくなかった。
方法は少なくとも3つ。

###①`.gitignore`や`.git/info/exclude`に書き込む
これらのファイルに書き込むと、記載した特定のファイルがgit管理の対象外となる。

`.gitignore`に書き込むと`.gitignore`自身の差分ができるから、プッシュするとGitHubの`.gitignore`も反映される。
`.gitignore`の更新を反映したくなければ、後述する`git update-index --skip-worktree`を使用すれば反映されずに済む。

`.git/info/exclude`はGitHubにプッシュされないので、対象外にしたファイルを知られたくないときや、余計な変更をプッシュしたくないときなどに使える。
なお、`.git/info/exclude`は以下のように記載すれば反映される。

```:(railsアプリ名)/.git/info/exclude
en.yml
ja.yml
test.txt
```
`config/locales/en.yml`のようにパスを指定する必要はなく、そのままファイル名だけを書けばgit管理から除外される。

なお、`.gitignore`と`.git/info/exclude`は新規作成したファイルはgit管理から除外してくれるが、既にgit管理にあるファイルは、このファイルに書き込むだけではgit管理の対象外にならないと思われる。

実際にGitHubから`git clone`した`database.yml`はファイルに書き込むだけでは対象外にはならなかった。

差分を追跡されたくない特定のファイルがあれば（自分用にファイルを変更したいが、プッシュ時にはクローンされた当時の状態でプッシュしたいファイルがあるときなど。）、まずその追跡を解除する必要がある。

以下のコマンドを使った後、コミット・プッシュすれば、ファイルを削除せずにステージングを解除できるので、追跡を解除できる。
ただし、GitHubのリポジトリからは、当然`.gitignore`などに記載してgit管理から除外したファイル自体が消える。
「自分が変更した内容が反映されていない状態」でファイルが残ることはない。

.gitignoreに記載したのに反映されない件
https://qiita.com/fuwamaki/items/3ed021163e50beab7154

```
$ git rm -f --cached .
$ git rm -f --cached ファイル名
```

上段は全てのファイルのインデックスを削除、下段は特定のファイルのインデックスを削除。
場合によっては`-f`ではなく`-rf`を付けないと削除できなかったり、`--ignore-unmatch`を付けないと削除できなかったりする場合も。
`--cached`を`cached`にして実行すると、存在するファイルを削除することがあるので注意。
オプションの意味はきちんと理解して使う。

上段は全てのステージングを解除しているので、それらをステージングせずにGitHub等にプッシュすると、当然ステージングされなかったファイルはプッシュされない。

以下は`git rm -f --cached .`を実行して`git add .`でステージングせず、`package.json`だけをステージングしてプッシュした状態。
当然GitHubには`package.json`しかない。

![github.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/7b35be23-72c0-5e33-39ee-235c924bd1db.png)


Gitのrmコマンドについて
https://git-scm.com/docs/git-rm
「Git の基本 - 変更内容のリポジトリへの記録」の後半にも`cached`について触れている。
https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E5%9F%BA%E6%9C%AC-%E5%A4%89%E6%9B%B4%E5%86%85%E5%AE%B9%E3%81%AE%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%81%B8%E3%81%AE%E8%A8%98%E9%8C%B2

###②`git update-index --skip-worktree ファイル名`でファイルを更新しない
指定されたファイルは、変更してもgitでは更新されなくなる。
ただし、ステージングしているファイルが対象なので、新規作成してステージングしていないファイルには使えない。
使うためにはそのファイルがいるがステージングしている必要がある。

例）クローンした中にAファイルがあるとする。Aファイルに変更を加えたいが、プッシュするときリモートリポジトリにはその変更を反映させたくない。そんなときにこのコマンドを使えばいい。
実際のファイルを変更してもgitでは更新されなくなるので、ステージング候補としても上がってこない。`git add`してもそのファイルはステージングされない。

git-update-indexについて
https://git-scm.com/docs/git-update-index

###③注意してaddせずにいる
ステージングをしなければ追跡されないので、GitHubにプッシュしても、そのステージングされていないファイル（差分）がGithub上には反映されることはない。しかし面倒。
この方法でするなら、`git add .`で全ての変更をステージングした後、コミットする前に`git reset HEAD ファイル名`でステージングしたくないファイルだけを除外する方法もある。
FIWAREとは

XACMLについて調べていたら突然出会った"FIWARE(ファイウェア)"という単語について調べてみます。

FIWAREが解決する課題
---
スマートシティの仕組み作りにおいて、各システムごとに異なる形式のデータをどう共有するかが課題
→FIWAREとは分野横断的なデータ流通のためのオープンソース・プラットフォームである。

7カテゴリー、約40種のモジュール群で構成され、用途に合わせて自由に組み合わせて利用できる。
各モジュールが従うべきインターフェースが定められているため、異なるシステム間のデータを共有できる。
また、各モジュールはOSSをベースとしているため、低コストで組み合わせやすい。

モジュール群の7カテゴリー
---
・DATA/CONTEXT：コンテキスト管理、データ・メディア統合
・Internet of Things：IoTデバイスのサポート
・Advanced UI：3DやAR機能付きWeb UI等
・Security：セキュリティ・モニタリング認証、アクセス管理
・Interface to Networks and Devices (I2ND)：ネットワーク、ロボット制御等
・APPS：可視化、ダッシュボード、データセット/サービスの公開
・Cloud：クラウド環境

認証認可やってる人のひとこと
---
Securityのカテゴリの中にID管理、アクセス管理が含まれているようです。
↓ツアーガイドアプリの構成
<img width="674" alt="スクリーンショット 2020-06-11 23.32.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499170/c1e6a426-3dbc-69ca-bcea-71010d53df4a.png">


---
[Let's FIWARE](https://www.letsfiware.jp/)
PoetryでもPython3.8を使いたい！

# はじめに

そろそろ`Python3.8`がリリースされて、半年以上が経ちます
（最初のリリース日は 2019 年 10 月 14 日（[参考](https://www.python.org/downloads/))です）。
`Python3.8`が使えていません。

[面白そうな新機能](https://qiita.com/ksato9700/items/3846e8db573a07c71c33)がたくさんあるのにです。

と言うことで、`Mac OS`に`Python3.8`を入れていきます。

ただ、巷にあふれている`pyenv`を利用する方法ではなく、
`homebrew`で入れられる`Python@3.8`を利用する方法です。
（`pyenv`アレルギーなので）

# 手順

## 1. `homebrew`にて`python@3.8`をインストール

`homebrew`を入れてない場合は、`homebrew`のインストールから行いましょう
`Python@3.8`のドキュメントは[ここ](https://formulae.brew.sh/formula/python@3.8)にあります。

```zsh
$ brew install python@3.8
```

インストール先は`(brew --prefix)/opt/python@3.8/bin/python3`になります。


## 2. `PATH`を通す

`homebrew`で`Python@3.8`がインストールできたら、[ここ](https://stackoverflow.com/questions/60453261/how-to-default-python3-8-on-my-mac-using-homebrew)を参考に`PATH`を通します。

`Catalina`からデフォルトのシェルは`zsh`なので、`~/.zshrc`に以下を追記します。
私の環境では、`(brew --prefix)`は`/usr/local`なので、以下のパスになります。

```zsh:.zshrc
# pathを通す
export PATH="/usr/local/opt/python@3.8/bin:$PATH"
```

```zsh
# ターミナルの再起動
$ zsh -l
# パスが通っているか確認
$ which python3.8
/usr/local/opt/python@3.8/bin/python3.8
```

## 3. poetryのenv変更

最後に、`poetry`の利用する`Python`バージョンの変更です。
[ここ](https://github.com/python-poetry/poetry/issues/1735)を参考に
`poetry`を作成した環境直下にて以下コマンドを打ちます。

```zsh:.../someproject/
# 環境の切り替え
$ poetry env use 3.8

# packageのupdateしないとimport errorになります
$ poetry update

# shellの起動
$ poetry shell

# python shellの起動
$ python
Python 3.8.2 (default, Mar 11 2020, 00:29:50)
[Clang 11.0.0 (clang-1100.0.33.17)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
```


# 終わりに

と言うことで、念願の`Python3.8`を使えるようになりました。
皆さんも良き`Poetry` + `Python3.8`ライフを。
ターミナルが動かないだって？？？

<img width="1103" alt="スクリーンショット 2020-06-10 22.28.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650686/8560b700-804c-a7a2-5e25-dd7e752d452d.png">

環境
Mac OS 10.15.5
AWS cloud9

railsチュートリアルを進めていたら、cloud9のターミナルが突然動かなくなった。
全くコードが書けない。
どうやら、直前に起きた容量オーバーも原因の一つになっているみたいだが、よく調べてみても解決策は出てこない。
どなたかアドバイスいただけないでしょうか？
Laravel make コマンド

# Laravel make コマンド
## マイグレーションファイル作成
```
php artisan make:migration create_[table name]_table
```
### マイグレーション実行
```
　php artisan migrate
```

### リセット
```
php artisan migrate:reset
```

### ロールバック（降順でx番目まで戻す）
```
php artisan migrate:rollback --step=x
```

## コントローラーファイル作成
```
php artisan make:controller [folder]/[name]Controller
```
AOJ 2370 RabbitWalking

##問題
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2370
##見た感じ
奇数長のサイクルができなければいいので、グラフが二部グラフである限界まで辺を足せばいいということだと思った。
だから、与えられたグラフ$G$の隣り合う点が違う色になるように白と黒を塗っていって、連結成分$G_\alpha$ごとに白と黒の個数$(a_\alpha , b_\alpha)$を確認して、最後に白と黒の点の個数を$a,b$として、孤立した点の個数を$c$としたときに、
全体で引ける線の数は、$max(a*(b+c),(a+c)*b)$か$|G|=n$として$\lceil n/2 \rceil *(n-\lceil n/2 \rceil )$なので、ここから元の引いてあった線の数を引けばいい。
ここで、最後の$a$と$b$をいかに求めるかという話で$a<b$として、$\lfloor n/2\rfloor -a$を最小化するように各$\alpha$ごとに$a_\alpha , b_\alpha$を$a$に割り振っていく。
これはdpすればいけるので、するべしするべし。
不安として、$0<n<100000$なので間に合うかどうかが怪しい。。
##解法
グラフに２色を塗っていき、奇数サイクルがあれば-1を返し、なければ上でいうた意味でのええ感じに二部グラフ化して、かけてひいて返す
##ソースコード
```c++
const int N_MAX=100005;
ll n,m,col[N_MAX];
vector<int> v[N_MAX];

ll solve(){
    ll ano=0;
    vector<pair<ll,ll>> res;
    rep(i,n){
        if(col[i]!=0)continue;
        if(v[i].size()==0){
            ano++;
            continue;
        }
        ll blo=0,whi=0;
        queue<int> que;
        que.push(i);
        col[i]=1;
        while(que.size()){
            int now=que.front();que.pop();
            col[now]==1?blo++:whi++;
            for(auto w:v[now]){
                if(col[w]==0){
                    col[w]=-col[now];
                    que.push(w);
                }else if(col[w]==col[now])return -1;
            }
        }
        res.pb({max(blo,whi),min(blo,whi)});
    }
    ll blo=0,whi=0;
    bitset<N_MAX> a,b;a[0]=1;
    for(auto w:res){
        rep(i,(1+(n+1)/2)-w.first){
            if(a[i])b[i+w.first]=1;
        }
        rep(i,(1+(n+1)/2)-w.second){
            if(a[i])b[i+w.second]=1;
        }
        rep(i,(1+(n+1)/2)){
            a[i]=b[i];
        }
        b.reset();
    }
    vrep(i,1+(n+1)/2){
        if(a[i]){
            blo=i;
            break;
        }
    }
    whi=n-blo-ano;
    /*debug(blo);
    debug(whi);
    debug(ano);*/
    if((n+1)/2<max(blo,whi)){
        blo>whi?whi+=ano:blo+=ano;
        return whi*blo-m;
    }else{
        return ((n+1)/2)*(n-((n+1)/2))-m;
    }
}

int main(){
    int x,y;
    //入力
    cin>>n>>m;
    rep(i,m){
        cin>>x>>y;
        v[x-1].pb(y-1);
        v[y-1].pb(x-1);
    }
    //処理
    auto ans=solve();
    //出力
    cout << ans <<endl;
}
```
2020/06/11 勉強 GitHub

#Docker

#GitHub
　■コマンドラインでGitを使用する

```
・Gitをインストール
　　　http://git-scm.com/
　　　参考サイト：https://qiita.com/taiponrock/items/632c117220e57d555099
　　
　　・Gitコマンド
　　　・Gitのバージョン確認
　　　　　・Git --version
　　　・ローカルにクローンを作成（SVNではCheckOut）
　　　　　・git clone リポジトリパス
　　　　　例）git clone git@github.com:aa/bb.git
　　　　　　　aa:リポジトリ名 bb:ディレクトリ名
　　　・SSH公開鍵作成
　　　　　・ssh-keygen -t rsa -b 4096 -f .ssh/[filename]
　　　　　・passphraseはなんでもOK（5文字以上）
　　　　　参考サイト：https://qiita.com/coffee_g9/items/e1b9ab28cfa54f854308

　　　・ブランチ確認
　　　　　・git branch　　(ローカル)
　　　　　・git branch -r (サーバー)
　　　・ブランチ作成
　　　　　・git branch aaa
　　　・ブランチに移動
　　　　　・git checkout aaa
　　　・ブランチ削除
　　　　　・git branch -d aaa
　　　・変更ファイル一覧
　　　　　・git diff --name-status(or only) 
　　　・コミット
　　　　　・git commit       
　　　・コミット時、VIが起動する
　　　　　・抜けるときESCボタンを押下後、:wqでVIを抜ける
　　　・origin：ベースのブランチ
　　　・追加・変更ファイルのコミット（全体のコミットの前に追加ファイルの編集を確定）
　　　　　・git add aaa
　　　・一括コミット
　　　　　・git add .
　　　・ブランチの状態確認
　　　　　・git status
　　　・サーバーに反映
　　　　　（新規）
　　　　　・git push --set-upstream origin develop
　　　　　（修正）
　　　　　・git push
　　　・最新取得
　　　　　・git pull
　　　・変更を元に戻す
　　　　　・git checkout .
　　　・特定のファイルを元に戻す
　　　　　・git checkout aaa
　　　・ブランチのマージ
　　　　　・マージするブランチに移動
　　　　　　　・git checkout aaa
　　　　　・aaaブランチにbbbをマージ
　　　　　　　・git merge bbb
```

#PHP（Laravel）
　　　・ログ出力
　　　　Log::debug("aaa");
　　　　参考サイト：https://laraweb.net/practice/4298/
汎用app,model exporter(習作)

車輪の再発明感が否めないけど…自分で探した限り、ぴったりの検索結果が出てこなくてひねり出してみたので備忘録。

あるappのあるmodelを指定したsuffixに対応したファイル形式でexportするコードを書いておくと楽かも、と思ったのでちょっとやってみた。
つまり``https://<domain>/shop/items/csv`` みたいなURLで、shop_items.csv というファイルが落ちてくる感じ。
`urls.py` のイメージはこんな感じ。

```python:urls.py
urlpatterns = [
    path('modelexport/<str:appname>/<str:modelname>/<str:suffix>', exportModel.as_view(),name='modelexport'),
]
```
で、コードはこちらのイメージ。

```python:views.py
from django import apps
from django.http import Http404
from django.views.generic import View
from dicttoxml import dicttoxml
import datetime,mimetypes
import pandas as pd

class exportModel(View):
    supported_types = ('csv','xlsx','xml',)
    values = None
    
    def get(self,request,*args,**kwargs):
        appname,modelname,suffix = kwargs['appname'],kwargs['modelname'],kwargs['suffix']
        if not suffix in self.supported_types:
            raise Http404('{suffix} is not supported.'.format(suffix=suffix))

        filename =  '{appname}_{modelname}.{suffix}'.format(appname=appname,modelname=modelname,suffix=suffix)
        content_type,_ = mimetypes.guess_type(filename)
        values = self.values or apps.apps.get_model(appname,modelname).objects.values()
        data = [{ k:v if type(v)!=datetime.datetime else v.astimezone().strftime("%Y/%m/%d %H:%M:%S") for k,v in record.items() }
                for record in values]

        response = HttpResponse(content_type=content_type,charset='utf-8')
        if suffix == 'csv':
            response.write('\ufeff')
            pd.DataFrame(data).to_csv(response,index=False,sep=',')
        elif suffix == 'xlsx':
            pd.DataFrame(data).to_excel(response,index=False,sheet_name=modelname)
        elif suffix == 'xml':
            response.write(dicttoxml(data,attr_type=False))

        response['Content-Disposition'] = 'attachment; filename={filename}'.format(filename=filename)

        return response
```
説明を書くまでもない気もするけど、一応ちょっとしたポイントだけ確認。

- apps.apps.get_model(appname,modelname)で任意のappの任意のmodelが取得できる
- csv, xlsxはpandasをwrapperとして使用。xmlはdicttoxml
- `data = ..` のところは、Excelはtimezone awareなdatetimeを扱えないモジュールを使っているので、予めdatetime型をtzのローカルタイムの文字列に直している。Excel以外でも放っておくとUTCで文字列化されるので、ここで一括で文字列化しておく
- csvの場合、BOM付にしておかないと直接クリックしてExcelが起動すると文字化けするので、`response.write('\ufeff')`しておく
- xmlの場合、`attr_type=False`にしないとスキーマ定義が必要になるので、これで逃げておく。Excelでインポートする場合、お任せで普通にテーブルになってくれる
- `values = None` は、絞り込みとかしたくなったときに、継承先でurls.pyから取ったパラメータでvaluesを入れておけば上書きできるかな、というつもり。`...../<str:term1>/<str:cond1>`のように書いておいて、継承したクラスを指定し、`.filter(**{kwargs['term1']:kwargs['cond1']})`みたいにやると絞り込んだ結果のexportもできるかな(ごめんなさい、ここは検証してません)

うーん、なんかやっぱり記事にするまでもない気もしてきたけど、個人的備忘録ということで。
【学習メモ】JavaScript入門 変数宣言　オブジェクト　インスタンス化

#JavaScriptの基礎学習

###＜エラーについて＞
例

```JavaScript
<script>
  document.write('<p class="date">20xx/01/23</p>');
</script>
```

デベロッパーツールの「✖︎」を見れば、"〜 is not a function"」と書かれていることがある。これは、JSが準備している機能ではないことを意味している。まずは、打ち間違いがないか確認すること。

###＜先ほどのコードの意味＞

```
document.write('...');

document：オブジェクト（対象）
→documentは表示しているものという意味

write:メソッド（命令）
→write:書いて欲しい（＝表示して欲しい）

('...'); :パラメーター（何を）
```

###＜学習ポイント＞
**各オブジェクト、各メソッド、各パラメーターの種類を組み立てて文章を作るイメージで学習・チャレンジしくこと（講師曰く）**

###＜JSの変数宣言＞
JSは変数宣言が必要（var, let）
しかし2回目は、var(let)が不要。

###＜加算・減算＞
answer = answer + 1;
answer += 1;
answer ++; ⇦このような記法をincrement（加算）と言う。
-- の場合は、decrement（減算）

###＜命名規則＞
1文字目はアルファベットかアンダースコア、ドル記号
2文字目以降はそれに加えて数字も使ってOK
大文字・小文字は区別される

###＜オブジェクト＞
オブジェクトは、基本インスタンス化しないと使えない
instance（実体＝実際のもの＝オブジェクト）
他の観点で言うと、instanceを生成する、変数は設計図のようなもの

###＜Dateオブジェクトを用いたView作成＞
例

```JavaScript
    <script>
      var today = new Date();
      var todayHtml = today.getFullYear() + '/' + (today.getMonth()+1) + '/' + today.getDate();

      document.write('<p class="date">' + todayHtml + '</p>');
    </script>
```

var today = new Date();
→**「Dateオブジェクトを新しく生成する」機能を持った、変数「today」を定義する（Rubyで言えばControllerのdef）**

document.write('<p class="date">' + todayHtml + '</p>');
→.write（）の（）について記述せよ

<img width="497" alt="スクリーンショット 2020-06-11 23.09.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606290/eee96355-748a-e094-49ec-5c36e0337f01.png">
PHP Docker で  composer require linecorp/line-bot-sdk がコケる

# 状況

Docker Image : php:7.4.6-fpm-alpine3.11

# ログ

```
# composer require linecorp/line-bot-sdk
Using version ^4.4 for linecorp/line-bot-sdk
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - linecorp/line-bot-sdk 4.4.1 requires ext-sockets * -> the requested PHP extension sockets is missing from your system.
    - linecorp/line-bot-sdk 4.4.0 requires ext-sockets * -> the requested PHP extension sockets is missing from your system.
    - Installation request for linecorp/line-bot-sdk ^4.4 -> satisfiable by linecorp/line-bot-sdk[4.4.0, 4.4.1].

  To enable extensions, verify that they are enabled in your .ini files:
    - 
    - /usr/local/etc/php/conf.d/docker-php-ext-pdo_mysql.ini
    - /usr/local/etc/php/conf.d/docker-php-ext-sodium.ini
  You can also run `php --ini` inside terminal to see which files are used by PHP in CLI mode.

```

> the requested PHP extension sockets is missing from your system.

socketsが無いよというお話でした。

# 対処

Dockerfile内でsocketsをインストールするだけ。

```
~略~
RUN docker-php-ext-install sockets
~略~
```

# 結果

無事、インストール完了

```
 # composer require linecorp/line-bot-sdk
Using version ^4.4 for linecorp/line-bot-sdk
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing linecorp/line-bot-sdk (4.4.1): Downloading (100%)         
linecorp/line-bot-sdk suggests installing apigen/apigen (Install with roave/better-reflection:dev-master to generate docs)
linecorp/line-bot-sdk suggests installing roave/better-reflection (Required by apigen/apigen:dev-master)
Package jakub-onderka/php-console-color is abandoned, you should avoid using it. Use php-parallel-lint/php-console-color instead.
Package jakub-onderka/php-console-highlighter is abandoned, you should avoid using it. Use php-parallel-lint/php-console-highlighter instead.
Writing lock file
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
Discovered Package: facade/ignition
Discovered Package: fideloper/proxy
Discovered Package: laravel/tinker
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Package manifest generated successfully.
34 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
```
【学習メモ】Gitの一部メモ

Git学習のメモ

j:下に下る
k:上に上る
q:ログを終了させる
-n X(X=number):最新のcommitからX番目までのログを表示
-p:何のファイルのどこを変更したか確認
-p (file_name):そのファイルのどこを変更したかを確認


```terminal
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
# Your branch is up to date with 'origin/master'.
#
# Changes to be committed:
#       deleted:    second.txt
#
# ------------------------ >8 ------------------------
# Do not modify or remove the line above.
# Everything below it will be ignored.
diff --git a/second.txt b/second.txt
deleted file mode 100644
index 3690247..0000000
--- a/second.txt
+++ /dev/null
@@ -1 +0,0 @@
-新規作成したファイル
\ No newline at end of file
```
Laravel5.8でFIND_IN_SETを使って、1カラム内のカンマ区切りデータを取得する


タイトルの通りです！！

## こんな感じのテーブル
menusテーブル

|    id    |    menu    |    material    |
|:------------------:|:------------------:|:------------------:|
|        1        |オムライス|卵,ご飯,チキン
|       2       |厚焼きたまご|卵
|        3        |唐揚げ定食|ご飯,チキン



## 環境
Laravel5.8
mysql5.7

## やってみよう

materialに「卵」が入っているmenuを取得する！

```php
$query = DB::table('menus')
         ->whereRaw('FIND_IN_SET("卵",material)')
         ->get();
```

出力する！

```php
dd($query);
```

確認する！

<img width="432" alt="スクリーンショット 2020-06-11 22.35.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564758/59b4efb3-a4dc-92e5-abf5-46af149f1194.png">


オムライスと厚焼きたまごをGET！！！


## エスケープしてみる
```php
$colname = '卵'
$query = DB::table('menus');
         ->whereRaw('FIND_IN_SET(?,material)', [$colname])
         ->get();
```

同様に取得できました。

## 参考サイト
[[MySQL]1カラムに登録されたカンマ区切りデータを検索・抽出する方法（FIND_IN_SET）](http://www.searchlight8.com/mysql_find_in_set/)
[find in set in laravel ? example
](https://stackoverflow.com/questions/35594450/find-in-set-in-laravel-example)