OmniAICreator/Qiita-1.07M huggingface dataset:
最尤推定と交差エントロピーの関係

最尤推定と交差エントロピー誤差(クロスエントロピー誤差、logloss)の最小化が同じことだということについて、毎回同じことを思い出しているような気がしたのでメモします。

# 最尤推定

例えばコインの表が出る事象X=1、裏が出る事象をX=0として、コインを3回投げたところ次のような結果になったとします。

| 1回目 | 2回目 | 3回目 | 
| ----- | ----- | ----- | 
| 1     | 0     | 1     | 

このとき、コインの表の出る確率は直感的に$2/3$となりそうですが、これを最尤推定で推定してみます。

コインの表の出る確率を$p$したとき、このような結果が得られる確率は

```math
\begin{aligned}
P&=p(1-p)p\\
&=p^2(1-p)
\end{aligned}
```

となります(同時確率)。

そして(厳密には違うのですが)尤度関数$L$は同時確率と同じ形をしているので、次のようになります。

```math
L=p^2(1-p)
```
この対数を取った対数尤度関数は次のようになります。

```math
\begin{aligned}
l=2\log{p}+\log{(1-p)}
\end{aligned}
```

最尤推定ではこれを最大化する$p$を求めます。それには微分して$0$になる$p$を求めればいいので、

```math
\begin{aligned}
\frac{\partial l}{\partial p}&=\frac{2}{p}-\frac{1}{1-p}\\
&=\frac{2-3p}{p(1-p)}=0
\end{aligned}
```
よって$p=2/3$と推定できました。

## 最尤推定についてまとめ

尤度関数と同時確率は同じ形をしていたので、尤度関数を最大化するということは、その事象が起きる同時確率を最大化するということになります。ある事象が起こった後で、コインの表の出る確率$p$を推定するとき、その事象が起こる確率を最大化する$p$がもっともらしい$p$だろうという論理です。

まとめると、最尤推定とは、ある事象が観察され、その事象の分布を仮定(今回の場合コインの表の出る確率は$p$となり、その値は一定と仮定)したとき、尤度関数を最大化することで、そのパラメータをもっともらしく求める方法と言えます。

(余談ですが、尤度の「尤」は「尤もらしい」と書いて「もっともらしい」と読みます。なので昔の人は英語の「likehood」を「尤度」と訳したのでしょうね。)

# 2クラス分類問題

ある2クラス分類問題をモデルで予測したいとき、次のような3つのデータがあったとします。

|          | 1   | 2   | 3   | 
| -------- | --- | --- | --- | 
| 説明変数 | $x_1$ | $x_2$ | $x_3$ | 
| ラベル   | 1   | 0   | 1   |


説明変数$x$は1変数かもしれないですし、多変数かもしれないとします。

皆さんご存じの通り、モデルによってラベルを予測したいときラベルが$1$である確率$p$を予測する予測式$f$を機械学習によって求めることがよく行われます。

この予測式$f$は$i$番目のデータの説明変数$x_i$を入力として与えると、そのデータのラベルが$1$である確率$p_i$を出力します。式で表すと次のようになります。

```math
p_i=f(x_i)
```

このとき、モデルに使う手法が決定木にしろ、ニューラルネットワークにしろ、SVMにしろ、データから学習して求めるのは予測式$f$を決めるパラメータです。このパラメータを$\theta$とし、$\theta$によって定まった予測式を$f_\theta$と表すことにします。

このパラメータを先ほどのコインの表の出る確率$p$と同じように最尤推定で求めると、尤度関数は次のようになります。


```math
\begin{aligned}
L(\theta)&=f_\theta(x_1)(1-f_\theta(x_2))f_\theta(x_3)\\
&=\prod_{i=1}^3[f_\theta(x_1)]^{t_i}[1-f_\theta(x_1)]^{1-t_i}
\end{aligned}
```

ただし$t_i$は$i$番目のデータの正解ラベルとします。

また、対数尤度関数は次のようになります。

```math
l(\theta)=\sum_{i=1}^3\left\{t_i\log{[f_\theta(x_1)]}+(1-t_i)\log{[1-f_\theta(x_1)]}\right\}
```

この$l(\theta)$にマイナスをつけ、データ数で割ったものが交差エントロピー誤差となります。$l(\theta)$を最大化するには、交差エントロピー誤差を最小化するようにモデルを学習すればいいことになります。

# 最尤推定と交差エントロピー誤差について

以上から、最尤推定と交差エントロピー誤差の最小化が同じことだということが分かりました。

さきほど、「最尤推定とは、ある事象が観察され、その事象の分布を仮定したとき、尤度関数を最大化することで、そのパラメータをもっともらしく求める方法」だと述べましたが、

これに対し、クラス分類問題を学習する場合、「データとそれに対するラベルがあり、そのデータを説明するモデル$f$を仮定したとき、交差エントロピー誤差を最小化することでそのモデル$f$のパラメータをもっともらしく求める」ことができると言えます。

さらに一歩踏み込んでいえば、データがあった時、そのデータが何らかのモデル(決定木、ニューラルネットワーク)によって生成されたとき、そのデータが生成される同時確率を最大化するようにパラメータを求めていると言えそうです。

(ただ現実のデータが生成されるモデルというのが決定木やニューラルネットワークそのものであるとは言えなさそうです。例えば、タイタニックの事故で生き残るかどうかを完全再現するには、それこそ映画マトリックスのような仮想世界が必要になるレベルだと思います。)
備忘録_よく使うスクリプト

# よく使うスクリプト
- 頻繁ではいけど、比較的よく使うスクリプトの備忘録

## よく使うコマンド
### ファイル授受(SCP)
* user：loginuser

```
# SCP - 送信
scp 20210504101453_linux.zip p12_rds.dmp loginuser@xx.xx.xx.xxx:/home/loginuser/
# SCP - 受信   "login情報 user@ip:コピー元ディレクトリ コピー先(ローカル)"
scp loginuser@xx.xx.xx.xxx:/home/loginuser/20210504101453_linux.zip　./
```

## シェル
### 特定ファイルを移動
- 使用する要素
   - ディレクトリは以下のファイル一覧出力、特定文字列を含む判定、IF文、For文 

```
FILES="/mnt/mnts3/working_dir/*"
for FILE in $FILES; do
	if echo $FILE | grep "mst_product";then $(cp $FILE/mnt/mnts3/mst/prd);fi
	if echo $FILE | grep "mst_supplier";then $(cp $FILE /mnt/mnts3/mst/sup);fi
	if echo $FILE | grep "trn_sales";then $(cp $FILE /mnt/mnts3/trn/sal);fi
done
```

### 標準入力を改行(tr)して出力
- 使用する要素
   - 改行、置換

```
$ printenv PATH | tr  ':' '\n'
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/mnt/c/app/maven/apache-maven-3.6.3/bin
/mnt/c/Program Files/Git/cmd
/mnt/c/Program Files/Azure Data Studio/bin
/mnt/c/Program Files/nodejs/
/mnt/c/Program Files/Java/jdk1.8.0_221/bin
/mnt/c/Program Files/Java/jdk1.8.0_221/jre/bin
/mnt/c/Program Files/Docker/Docker/resources/bin
/mnt/c/ProgramData/DockerDesktop/version-bin
/mnt/c/Windows/system32
```

### 特定のファイル削除
- IF連携ファイルのバックアップ後の掃除や環境構築に使用

```
# 特定ディレクトリ下のファイル全消し(フォルダは残す)
$ find /mnt/s3/. -type f | xargs rm 

# xlsxファイルを特定して削除
$ find ./ -name "*.xlsx" | xargs rm
```

### 特定のファイルをリネーム(xargs)
```
$ find ./ -name "before.txt" | xargs -I %% mv %%  "after.txt"
```

### 接続確認
- WSL2から外に行くとき、Windows10にインストールしたリバースPROXY(Cntlm)の接続確認に使用

```
# Bash
nc -zv localhost 3128

# PowerShell
Test-NetConnection -ComputerName google.co.jp -Port 443
```

### メモリ監視
```
# 実行
$ nohup vmstat -t 300 --unit M >> /tmp/oslogs.210630.txt &
$ cat /tmp/oslogs.210630.txt

# 停止
$ kill $(pidof "vmstat")

# 停止確認は前後に以下のcmdで
$ ps -a
```
Unity ScalerPanelベースサイズに応じたサイズ変更


### パネルのサイズを固定にして、その配下に固定で、画像やテキストを配置。

パネルのスケールを変更するのみで、比率に応じた倍率にする。
ここでは640x480に固定。倍率は小さい方に合わせる。画面いっぱいに黒画面などを置いて、縦の空きや横の空きをごまかす。

```C#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PanelScaler : MonoBehaviour
{
    void Awake()
    {
        //Application.targetFrameRate=20;
        ScaleChange();
    }
    void ScaleChange(){
        const float fixed_width=640f;
        const float fixed_height=480f;
        var sw=Screen.width/fixed_width;
        var sh=Screen.height/fixed_height;
        var scale=Mathf.Min(sw,sh);
        Debug.Log(scale);
        gameObject.transform.localScale=new Vector3(scale,scale,1);
    }
}
```

### パッケージ
```
https://github.com/gnjo/UnitySamples
```
度分秒(DMS)表記を十進数(Decimal)に変換する雑なやり方


[追記] もっと簡潔に書ける方法を教えてもらったので、コメント欄を参照してください。

--- 

`"北緯35度39分31秒 東経139度44分44秒"`や`"35°39′31″N 139°44′44″E"`などの表記を十進数表記に雑に変換する。

```js
function dms2decimal(dms) {    
    return dms.split(/\D/).filter(d => d != "").reduce((a, c, i) => {
        const opt = {
            1: 60,
            2: 3600
        }
        const na = +a;
        const nc = +c;
        return na + (nc / opt[i])
    })
}
```

```js
> dms2decimal("北緯35度39分31秒");
<- 35.65861111111111

> dms2decimal("東経139度44分44");
<- 139.74555555555554

> dms2decimal("35°39′31″N");
<- 35.65861111111111

> dms2decimal("139°44′44″E");
<- 139.74555555555554

```

実に雑なので、誤作動するときがあるかも。
WordPress REST APIを.htaccessで外部非公開化

#やりたいこと
/wp/v2/users
でまるっとユーザ一覧取得されたくない
でも内部では使いたい

#やること
DocumentRootの.htaccessに下記を追加

```apache 
 <FilesMatch "wp-json">
   Order deny,allow
   Deny from all
   Allow from 127.0.0.1 #許可するIP
 </FilesMatch>
```
ラズパイのパッケージ更新

#本記事の内容
- ラズパイにインストールされているパッケージのアップデートを行う。


#実施環境
- Windows 10
- TeraTarm Version 4.9.4
- Raspberry Pi 2 Model B
- PLANEX 無線LAN子機 GW-USNANO2A ※Raspberry Pi 2はWi-Fi通信モジュールがないため、無線LAN子機をUSBに接続しWi-Fi通信を行う。
- 家庭内の無線LANネットワーク環境にて実施

#手順の流れ 
1. TeraTarmでsshログインする
2. アップデート可能なパッケージリストの更新
3. パッケージのアップデートの実行

## 1. TeraTarmでsshログインする

WindowsにてTeraTarmを起動して、ラズパイにSSH接続する。

## 2. アップデート可能なパッケージリストの更新

`sudo apt-get update`コマンドを実行する。

こちらのコマンドを実行することでパッケージををアップデートする前に、パッケージリストが更新される。


## 3. パッケージのアップデートの実行

`sudo apt-get full-upgrade`コマンドを実行する。

こちらのコマンドを実行することでインストールされている全てのパッケージが最新バージョンにアップグレードされる。

	Do you want to continue? [Y/n]
途中で上記の確認コマンドが出た場合は、`Y`を入力する。

手順は以上。

## 参考文献
本記事の作成に当たり、以下の情報を参考にさせて頂きました。
- [Updating and Upgrading Raspberry Pi OS](https://www.raspberrypi.org/documentation/computers/os.html)
【ソースコード付き】ラズパイでスマホ自動タップ装置を自作する

# 目次
[材料](#材料)
[ラズパイの初期設定](#ラズパイの初期設定)
[作業手順](#作業手順)
[完成動画](#完成動画)

# 材料

|No.|部品名|個数|値段|備考|
|:-:|:-:|:-:|:-:|:-:|
|1|Raspberry Pi Zero WH|1|2000円ぐらい|https://akizukidenshi.com/catalog/g/gM-12958/|
|2|TOSHIBA マイクロSDカード 16GB|1|500円ぐらい|秋葉原のメイドリーミンの下にある電気屋(あきばおー)で購入|
|3|リレータッチボード(ドライバ有り)|1|680円|https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=EEHD-5LCG|
|4|ジャンプワイヤ オス-メス|3|0円|家にあったやつ|
|5|ジャンプワイヤ メス-メス|3|0円|家にあったやつ|
|6|ACアダプタ|1|0円|家にあったやつ|
|7|マイクロUSBケーブル|1|0円|家にあったやつ|
|8|はんだ|1|100円|ダイソーで購入|
|9|はんだこて|1|330円|ダイソーで購入|

合計で3000~4000円ぐらい。もっと安く作るなら他にも方法はある(https://ch.togetter.com/2018/10/09/58290 )。

# ラズパイの初期設定
このサイトを参考に設定したよ。

https://tool-lab.com/raspberry-pi/

# 作業手順
## ①リレータッチボードをはんだ付けする
ジャンプワイヤ オス-メス のオス部分とリレータッチボードをはんだ付けする
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526938/5158bee7-e487-299f-0c5d-aa1574764fa1.jpeg">
## ②リレータッチボードをラズパイと接続する
<b>PIN表</b>

|ラズパイのピン番号|リレータッチボード|
|---|---|
|2|5V|
|39|GND|
|40(GPIO21)|EN|


<b>回路図</b>
![PastedGraphic-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526938/52fd2ccb-c30a-2299-b830-e9244dc75256.png)

## ③ソースコードを用意する
auto.py
↓

```
#!/usr/bin/python
# coding: utf-8

# モジュールをインポートする
import RPi.GPIO as GPIO
import time


# GPIO指定をGPIO番号で行う
GPIO.setmode(GPIO.BCM)

# GPIO21ピンを出力モードに設定
GPIO.setup(21, GPIO.OUT)

try:
    while True:
        # GPIO21番ピンを3.3Vに設定
        GPIO.output(21, 1)
        time.sleep(1)
        GPIO.output(21, 0)
        time.sleep(1)
except KeyboardInterrupt :
    # GPIO21番ピンを0Vに設定
    GPIO.output(21, 0)
    pass

# GPIO設定をリセット
GPIO.cleanup()
```

## ④ラズパイの電源を起動して、上記のソースコードを実行するだけ！

# 完成動画
1→スマホをタップしている状態
0→スマホをタップしていない状態

https://twitter.com/gwanryong/status/1437650453282521095?s=21
[Rails]active_hashについて

##初めに
####なぜこの記事を書きたかったのか
・変化しないデータを繰り返し使いたいヒト

####環境
・Macbook Air (Retina, 13-inch,2019)
・プロセッサ 1.6GHz デュアルコアIntel Core i5
・メモリ　8GB 2133 Mhz LPDDR3
・MacOS Big Sur　バージョン 11.5.2

####記事の目次
**１）どういうときに使う？**
**２）何ができる？**
**３）どうやって使う？**
**４）最後に**

##どういうときに使う？
####変更されないデータを繰り返し使いたいとき！
（例えば、都道府県、市区町村、動物の名前、商品の部類、栄養素など）

##何ができる？
・事前に登録したデータをプルダウン形式で使用することができる。
（イメージ）

##どうやって使う？
####(1)Gemfileファイルに"active_hash"というgemをインストール

```erb
(Gemfile)
gem 'active_hash'

(ターミナル)
bundle install
```
####(２)app/model/ココに新しくモデル名.rbファイルを作り、ActiveHash::Baseを使い、変更されないデータベースを作る。

**※ActiveHash::Baseで、activeRecordと同じようなメソッドを使用することができる。今回は、NutritionモデルにActiveHash：：Baseを継承したので、Nutritionモデルに定義したデータに対してActiveRecordのようなメソッドが使用できる。**

**※self.dataでプルダウンのデータを入れることができる**

```rb
（書き方）
class モデル名　< ActriceHash::Base
  self.data = [
    { id: 数字,　name: '表示させたいテキスト'},
    { id: 数字,　name: '表示させたいテキスト'},
    { id: 数字,　name: '表示させたいテキスト'}
  ]
end


class Nutrition < ActiveHash::Base
 self.data = [
   { id: 1, name: '--' },
   { id: 2, name: 'タンパク質' },
   { id: 3, name: '脂質' },
   { id: 4, name: '炭水化物' },
   { id: 5, name: '食物繊維' },
   { id: 6, name: 'その他' }
 ]
 end
```
####(３)db/migrate/ooooooxxxxx_create_genre.rb(*今回はgenreというテーブル)にカラムを追加する。

```
（追加カラム）
t.integer :nutrition_id  , null: false

（追加後、ターミナルで反映）
rails db:migrate
```

####(４)つなげたいモデルとアソシエーションを設定x
**※belongs_toを設定するときは"extend"を、has_manyを設定するときは"include"をActiveHashの後ろに下記のように追加する。**
**モデル：nutrition(栄養素)と、モデル：genre（ジャンル）の場合、栄養素がhas_many: genre、ジャンルがbelongs_to:nutritionとなるので下記のような書き方になる。**

```rb
(app/models/nutrition.rb)
class Nutrition < ApplicationRecord 
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to :genre
end
```
```rb
(app/models/genre.rb)
include ActiveHash::Associations
  has_many :nutritions

```
####(５)つなげたモデルのバリデーションを設定
####(nutritionで栄養素の選択が「ーー」のときは保存しないようにする)
**※numercalityとは、数字を検知して保存してくれる役割を持っています。下記のように"other_than:1"以外の数字を検知して保存してくださいと命令できる。**

```rb
(app/models/nutritions.rb)
  validates:nutrition_id, numercality: {other_than:1}
```

####(6)viewで表示する(form_with内に追加)
####書き方
**<%= f.collection_select(：activehashのモデル名_id、activehashのモデル名.all、DBに保存するとき値、viewに表示させたい値、html用オプション)>**

```erb
<%= f.collection_select(:nutrition_id, Nutrition.all, :id, :name, {}, {class:"nutrition-select}) %>
```

##最後に、今回の記事を書いて思ったこと。。
言語化ってやっぱり難しいと思った。いつもよりかなり時間がかかった。どうしても誰かに対して説明という感覚より機械的にこうしたあとはこうするというふうな説明の仕方になってしまう。

ココまで読んでくださいましてありがとうございます！読みづらいと感じたり、指摘がございましたら成長への励みにもなりますのでコメントお願いします！☺
Laravel＋vue.jsでFontAwesomeを使うメモ

# はじめに
Laravel8＋Vue3でFont Awesomeを使用する際に
少し苦戦してしまったので
忘れないようにメモしておきます

開発環境は
DockerでLaravel vue.jsの環境を構築してます

## FontAwesomeをインストールする

プロジェクトに移動して
FontAwesomeをインストールします

```docker
$ npm install --save @fortawesome/fontawesome-svg-core
$ npm install --save @fortawesome/free-solid-svg-icons
#Using Vue 3.x
$ npm install --save @fortawesome/vue-fontawesome@prerelease
```
https://www.npmjs.com/package/@fortawesome/vue-fontawesome

上記にもあるのですが
vue 3.x ~はvue-fontawesomeの後ろに@prerelease(事前公開)が付くみたいです
vue 2.x ~は@latest (最新)をつけるみたいです

インストールし終わったら

package.jsonを見に行って
インストールしたものがあるかチェックしておきましょう

```json
  "@fortawesome/fontawesome-svg-core": "^1.2.36"
  "@fortawesome/free-brands-svg-icons": "^5.15.4"
  "@fortawesome/vue-fontawesome": "^3.0.0-4"
```

## 実際に使用する

インストールが終わったのであとは使用するだけです！

今回はこいつを使いましょう
https://fontawesome.com/v5.15/icons/angle-right?style=solid

よく見るやつです

まず、表示したいvueファイルのscript内で

```vuejs
<script>
import { library } from "@fortawesome/fontawesome-svg-core";
import { faAngleRight } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";

library.add(faAngleRight);

export default {
  components: {
    FontAwesomeIcon,
  },
</script>
```

上記のようにimportとexport をしてあげます

library.addでは使いたいアイコンを追加する。（使用する宣言をしてあげます）

今回の場合はfaAngleRightを使用すると宣言します。

---
また、アイコンを追加する際は

**fa-angle-righ**　のように　ハイフンで繋げてあるケバブケースから
**faAngleRight**　のように　キャメルケースにして使用してください！

script 内の記述が終わったので
次はtemplateです

```vuejs
<template>
<FontAwesomeIcon icon="angle-right" />
</template>
```

上記のように使いたい箇所に記載すれば　アイコンが使用できます！

またしてもここで<font color="Red">注意</font>が必要なのですが

icon="" の中身は　angle-rightのように　
ケバブケースにしてあげないと動きません！

少し面倒ですがお忘れなく！！


---

以上　自分のメモ用に記載しました。
間違い等ありましたら　優しくご指摘くださいませ。
【個人開発】Youtubeの企画をテーマにしたアプリ「〇〇王！！ - quiz about me -」をリリースしました！

#はじめに
この度「私のことをどれだけ知ってる？」をコンセプトにした、問題の作成、回答ができるクイズアプリ、「〇〇王！！ - quiz about me -」をリリースしました！

知ってる方も多いかと思いますが、実はこのアプリ、Youtuberさん達の間で人気の企画「〇〇王」からインスピレーションを受けています！
<iframe width="560" height="315" src="https://www.youtube.com/embed/hLuPbMkBvlU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" ></iframe>



この企画、見てるだけでも面白いですが、私たち視聴者も参加したいと思いませんか？？

そんな時に使っていただきたいのがこのアプリです。
Youtuberさんが問題を作成し共有することで、視聴者さんも問題に回答できるようになります！

もちろん、友達同士で問題を出し合っても楽しそうですね！

<https://quiz-about-me.herokuapp.com/>


#使い方・機能紹介
###**1. トップページ**
若者受けしそうなデザインを意識しました。
ニックネームを入力することで問題を作成できます。
<img src="https://i.gyazo.com/c9207c9d855825fbbf639ef801df7330.jpg" alt="Image from Gyazo" width="300" height="200">

###**2. 問題作成する**
こちらの画面で問題の作成、削除ができるようになっております。
また、デフォルトで問題をいくつか用意させていただきました。
<img src="https://i.gyazo.com/e0fbe5c60c1d5d7597da8f50ebe2cedf.gif" alt="Image from Gyazo" width="300" height="200">

作った問題はSNSで共有してみてください。
<img src="https://i.gyazo.com/359d90ab5d5ade460ffe1e986e2878df.jpg" alt="Image from Gyazo" width="300" height="200">

###**3. 問題に回答する**
ニックネームを入力することで問題に回答できます。
<img src="https://i.gyazo.com/68fec03421093ae16b50f0f2838f50db.gif" alt="Image from Gyazo" width="300" height="200">

また、クイズをより楽しくするため、ランキング機能を設けました。
回答結果もSNSで共有してみてください。
<img src="https://i.gyazo.com/b0029036399da2ecc8bc18764087293e.jpg" alt="Image from Gyazo" width="300" height="200">

#使用技術
####**バックエンド**
・ Rails 6.0.4.1
・ Ruby 2.6.6
・ RSpec 5.0.2

####**フロントエンド**
・ HTML
・ CSS (SCSS)
・ JavaScript (jQuery)
・ Bootstrap4

#こだわった点
####テーブル設計
問題の選択肢を増やせるように実装しました。
詳しくは以下の記事でまとめています。
https://qiita.com/ykemoemo/items/9b351c0293eef781ded5

####**ユーザーのストレスをできるだけ減らした**
このアプリはじっくり使うというモノよりかは、サクッと気軽に遊べるような作りにして、ユーザーのストレスを減らすような作りが良いと考えました。
具体的には問題回答時、問題を1問ずつ表示するのをAjaxを使いページの遷移をさせないような作りにしました。
また、問題作成の際、作成や削除をページ内で完結させたかったため、同じようにAjaxを使いました。

ログイン機能もユーザーに対する１つの壁となる気がしたのであえて用意しませんでした。

問題を1問ずつ表示させる方法は下記の記事にまとめています。
https://qiita.com/ykemoemo/items/de8195a261233cb8a997

####**デザイン面**
できるだけシンプルかつ、ポップで若者(特にJK)に受けそうなデザインに仕上げました。
問題を表示する箇所はインスタのストーリーで使われている問題機能を参考にしました。
Youtubeをテーマにしてることから、ユーザーのほとんどはスマホでアクセスすると思ったので、デザインはスマホに寄せております。

#おわりに
自分自身Youtubeで「〇〇王」という企画を見るたびに、これ友達同士でもやれたらいいなと思っていたので、形にできたのがすごく嬉しいです。

サービスをデプロイ後たくさんのユーザーさんに、「バズりそー！」などと感想をいただきました。
正直このサービスを思いついた時は、自分天才だな？なんて思ってしまいました（笑）

また、感想以外にもご指摘など、ありがたい言葉をたくさんいただきました。ありがとうございます🙏

今後ご意見を参考にしつつ、サービスをよりよいものにしていけるように頑張っていきます！
最後までご覧いただきましてありがとうございました！
【PHP】多次元配列の重複を削除

```PHP

<?php
$rows = [
    0 => [ 'id' => 10, 'language' => 'PHP',        'ｆramework' => 'Laravel'],
    1 => [ 'id' => 20, 'language' => 'Java',       'ｆramework' => 'Spring'],
    2 => [ 'id' => 30, 'language' => 'JavaScript', 'ｆramework' => 'Vue.js' ],
    3 => [ 'id' => 40, 'language' => 'Ruby',       'ｆramework' => 'Ruby on Rails' ],
    4 => [ 'id' => 40, 'language' => 'Ruby',       'ｆramework' => 'Ruby on Rails' ],
    5 => [ 'id' => 50, 'language' => 'Ruby',       'ｆramework' => 'Flutter' ]
];


$size_list = array_unique($rows, SORT_REGULAR);

var_dump($size_list);


```
#結果
```
array(5) {
  [0]=>
  array(3) {
    ["id"]=>
    int(10)
    ["language"]=>
    string(3) "PHP"
    ["ｆramework"]=>
    string(7) "Laravel"
  }
  [1]=>
  array(3) {
    ["id"]=>
    int(20)
    ["language"]=>
    string(4) "Java"
    ["ｆramework"]=>
    string(6) "Spring"
  }
  [2]=>
  array(3) {
    ["id"]=>
    int(30)
    ["language"]=>
    string(10) "JavaScript"
    ["ｆramework"]=>
    string(6) "Vue.js"
  }
  [3]=>
  array(3) {
    ["id"]=>
    int(40)
    ["language"]=>
    string(4) "Ruby"
    ["ｆramework"]=>
    string(13) "Ruby on Rails"
  }
  [5]=>
  array(3) {
    ["id"]=>
    int(50)
    ["language"]=>
    string(4) "Ruby"
    ["ｆramework"]=>
    string(7) "Flutter"
  }
}
```
Laravel blade + vue.js でユーザー入力に対応する

#きっかけ

Laravel blade + vue.js という環境でユーザーの入力を扱う際にいろいろ苦戦したので、備忘録として記載します。

#blade 記法で値を置くと

コントローラから渡したデータを blade 記法で書く際はすぐに以下の記載を行うと思います。

```
{{ $var }}
```

一般的なデータについてはこの入力で渡せるので良いと思いますが、もしこのデータ自体がユーザー入力等で`{{ 何らかの入力 }}`を含んでいる場合、

1. blade テンプレートのレンダリング
* vue.js のコンパイル
* 画面の表示

という順序の内、1 番目の blade のレンダリング後にユーザーが入力した`{{ 何らかの入力 }}`がページソース上に載った状態で 2 番目のレンダリングに回されます。

この際、2 番目のコンパイルで vue.js 側は真面目に`{{ 何らかの入力 }}`の中身を解釈しようとするので、大抵の場合はコンパイル時のエラーが出ることになります。

#回避方法１

データを置く部分の親要素に`v-pre`を付ける。

```
例
<div v-pre>
    {{ $var }}
</div>
```

用途：ユーザーの入力をただ表示するだけの場合
（内容を確認する画面等）

`v-pre`はついている要素とその子要素のコンパイルをスキップするものであり、結果的に子要素であるユーザー入力内の`{{ 何らかの入力 }}`のコンパイルもスキップされ、表示できるようになります。

#回避方法２

script 内でデータを渡し、vue.js の data から参照する。

```
<textarea v-model="message"></textarea>

(中略)

var app = new Vue({
  el: '#app',
  data: {
    message: {{ $var }}
  }
})
```

用途：ユーザーの入力を vue.js 側でも利用する場合。
（input や textarea などの入力が絡む場合）

実際の入力部分に`v-pre`を付けると、入力された内容に対しての vue.js の一切の処理が行えない状況になります。
入力内容に対して何らかの vue.js の処理を行う場合、blade 記法で入力部分にデータを渡すのは諦めて、vue.js の data に blade 記法で渡す必要があります。

この際、実際には、改行を含む際の対応や vue.js の data から参照する際の記法など、javascript, vue.js, html 間のお約束に沿った書き方に気を付ける必要があります。
Terraform環境構築（Windows編）

# Terraform環境構築（Windows編）

## Terraformとは
HashiCorp社が提供するIaC（インフラをコード化して管理する）を実現してくれるツールです。
クラウド上のサーバーやネットワークなどのインフラ構築を自動化してくれます。
HCL記法でコードを記述し、インフラ管理していく。
AWSや、Azure、Google Cloudなどの複数のプロバイダーに対応しているので、HCLの記述さえ慣れれば、神ツールです。

今回はAWS環境にTerraformを使ってVPCを作成してみることについて解説します。
※AWS Cliの設定済みの前提で話を進めます。


## Terraformのバージョン管理ツール（tfenv）のインストール

Terraformの公式ページから、直接ダウンロードしてきてもいいですが、
TerraformのHCLの記法がv0.13以降、大幅に変わったこともあり、今からはじめるなら
バージョン管理できた方がいいねということで、tfenvをインストールしていきます。
今回はWSL2＋Ubuntuの環境にインストールしていきます。

Ubuntuのターミナル上で以下を実行していきます。

```
# tfenvのツールが置いているリモートリポジトリから、クローンしてきます
$ git clone https://github.com/tfutils/tfenv.git ~/.tfenv

# コマンドが実行できる/usr/local/bin にシンボリックリンクを設定
$ sudo ln -s ~/.tfenv/bin/* /usr/local/bin

# tfenvコマンドが使えるかテスト
$ tfenv --version

# Terraform使えるバージョンを確認
$ tfenv list-remote

# 使いたいバージョンのTerraformをインストール
$ tfenv install <使いたいバージョン>

# 指定したバージョンがインストールされているか確認
$ tfenv list

# インストールしてきたバージョンを設定する
$ tfenv use <使いたいバージョン>

# 指定したバージョンが設定されているか確認 
$ terraform --version
```

以上で環境構築は完了！お疲れさまでした。

では、早速でAWS上にVPCをサクッと作成してみます。

プロジェクトフォルダを作成し、その中に以下のVPCをつくるファイルを配置します。
※Terraform v0.13.0以降のバージョンが対象

```main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
}

# AWSプロバイダーの設定
provider "aws" {
  region = "ap-northeast-1"
}

# CIDRが10.0.0.0/16のVPCを作成
resource "aws_vpc" "example" {
  cidr_block = "10.0.0.0/16"
}
```

※Terraform v0.12.0以前のバージョンを使っている方はこちらを使ってください

```main.tf
# プロバイダー（AWS）の設定
provider "aws" {
  version = "~> 3.0"
  region  = "us-east-1"
}

# CIDRが10.0.0.0/16のVPCを作成
resource "aws_vpc" "example" {
  cidr_block = "10.0.0.0/16"
}
```

プロジェクトフォルダを作成したら、その中に、main.tfを配置。
再びUbuntuターミナルに戻り、以下を実行

```
# Terraform の初期化
$ terraform init

# コードを反映してリソースを作成する前に、あらかじめ変化を確認
$ terraform plan
Plan: 1 to add, 0 to change, 0 to destroy.

# 設定を反映
$ terraform apply
  
Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value:yes

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

```


AWSのマネジメントコンソールに入ってリソースが反映されているか確認
![VPC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306043/65399619-257d-1320-b7d5-7c3a99d390d1.png)


しっかり、反映されていますねー

最後はお片付け。作ったリソースを削除していきます。

~~~
# リソース削除
$ terraform destroy
~~~

再度マネジメントコンソールから確認してみると消えてます

## まとめ

今回は、IaC化に向けた第一歩として、Terraformの実行環境構築からTerraformのコードからAWS上にVPCを作成してみました
細かい記述の仕方などはまた今度！それでは、皆様の快適なIaCライフを～☆
【Ruby】S3にCSVデータを出力する

## はじめに
- CSVファイルのデータをAWSのS3に保存するロジックを実装したので、よかったら参考にしてみてください。
- `Rails: 5.2.6`
- `Ruby: 2.7.2`

## 実装したコード
- S３のバケットに 例: `2021_10/2021_10_01.csv` といったファイル名で出力されます。
- こちらは毎日バッチで実行することを想定して作成おります。

```export_csv.rb
# frozen_string_literal: true

require 'csv'
require 'aws-sdk-s3'

class ExportCsv
  def self.execute(params)
    output = CSV.generate do |csv|
      csv << params['headers']
      params['values'].each do |value|
        csv << value
      end
    end

    export_csv_to_s3(output, params)
  end

  def self.export_csv_to_s3(data, params)
    s3_client = Aws::S3::Client.new(stub_responses: Rails.env.test?,
                                    access_key_id: params['access_key_id'],
                                    secret_access_key: params['secret_access_key'],
                                    region: params['region'])
    bucket_name = params['bucket_name']
    folder_name = Time.current.yesterday.strftime('%Y_%m').to_s
    file_name = "#{Time.current.yesterday.strftime('%Y_%m_%d')}.csv"

    file_full_path = "#{folder_name}/#{file_name}"

    # バケットの存在確認とアクセス権の確認
    if bucket_exists_and_accessible?(s3_client, bucket_name)
      Rails.logger.info "Bucket '#{bucket_name}' exists and is accessible to you."
    else
      Rails.logger.info "Bucket '#{bucket_name}' does not exist " \
        'or is not accessible to you.'
    end
    
    # ファイルアップロードが完了したか確認
    if file_uploaded?(s3_client, bucket_name, file_full_path, data)
      Rails.logger.info "Object '#{file_full_path}' uploaded to bucket '#{bucket_name}'."
    else
      Rails.logger.info "Object '#{file_full_path}' not uploaded to bucket '#{bucket_name}'."
    end
  end

  def self.bucket_exists_and_accessible?(s3_client, bucket_name)
    s3_client.head_bucket(bucket: bucket_name)
    return true
  rescue StandardError
    return false
  end

  def self.file_uploaded?(s3_client, bucket_name, path, data)
    response = s3_client.put_object(
      bucket: bucket_name,
      key: path,
      body: data,
      content_type: 'text/csv'
    )
    return true if response.etag
  rescue StandardError => e
    Rails.logger.info "Error uploading object: #{e.message}"
    return false
  end

  private_class_method :export_csv_to_s3,
                       :bucket_exists_and_accessible?,
                       :file_uploaded?
end
```
HTML 備忘録

## 複数クラス指定
```
<div class="sample1 sample2"></div>
```
|ポイント|説明|備考|
|----|----|----|
|sample1 sample2|クラスとクラスの間を<b>半角スペース</b>で区切ること||


## 表
### 見出しが横向きの表
```
<table border="1">
    <thead>
        <tr>
            <th>見出し1</th>
            <th>見出し2</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>内容1</td>
            <td>内容2</td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
            <td>フッタセル1</td>
            <td>フッタセル2</td>
        </tr>
    </tfoot>
</table>
```
### タグの説明
|タグ|説明|備考|
|----|----|----|
|\<thead\>|「table header」表の行（水平方向）をグループ化するタグです。\<thead\>～\</thead\>で囲まれた内容は、表のヘッダ部分としてグループ化され、\<table\>の中はヘッダ部分を表す\<tread\>～\</tread\>部分、ボディ（表の本体）部分\<tbody\>～\</tbody\>、フッタ部分\<tfoot\>～\</tfoot\>に分けられます。このように分けることでブラウザはヘッダとフッタを先読みして表示したり、ヘッダとフッタを固定表示したままボディ部分だけをスクロールさせたりすることができます。ただし、これらのタグに対応していないブラウザの場合は、フッタをボディより上に表示してしまうことがあります。<br>https://html-coding.co.jp/annex/dictionary/html/thead/||
|\<tr\>|「table row」の略で表の行部分（横方向）を指定するタグです。<br>https://html-coding.co.jp/annex/dictionary/html/tr/||
|\<th\>|「table header」の略で、表の見出しやタイトルとなるヘッダセルを作成するタグです。<br>https://html-coding.co.jp/annex/dictionary/html/th/||
|\<td\>|「table data」の略で、テーブルセルの内容を指定します。<br>https://html-coding.co.jp/annex/dictionary/html/td/||


### 条件一致で表示
```
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<!--中略-->

 <!--一覧表示-->
  <div th:if="${sampleList} !=null">
    <table class="table" border="1">
      <thead>
      <tr>
        <th>名前</th>
        <th>年齢</th>
        <th>趣味</th>
      </tr>
      </thead>
      <tbody>
      <tr th:each="entity:${sampleList}" th:object="${entity}">
        <td><a th:href="@{/hoge(sampleName=*{sampleName})}" th:text="*{sampleName}"></a>名前にはリンク</td>
        <td th:text="*{age}">年齢</td>
        <td th:text="*{hoby}">趣味</td>
      </tr>
      </tbody>
    </table>
  </div>
```

### 見出しが縦向きの表
```
<table border="1">
    <thead>
        <tr>
            <th>見出し1</th><td>内容1</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th>見出し2</th><td>内容2</td>
        </tr>
        <tr>
            <th>見出し3</th><td>内容3</td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
            <th>見出し4</th><td>フッタセル1</td>
        </tr>
    </tfoot>
</table>
```
### テーブル内で列の結合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637823/f95936fb-41eb-1380-275d-6d1165059c5a.png)

```html
<td colspan="5">
```

|ポイント|説明|備考|
|----|----|----|
|colspan|自分の列も含めて5列結合する|表・テーブル・マージ・merge|

## タグに複数のクラスを設定 
```
<div class="sample1 sample2"></div>
```
|ポイント|説明|備考|
|----|----|----|
|複数classの設定|クラスとクラスの間を半角スペースで区切る||
選択式クイズの実装 (html) (js)

#実装内容
選択式問題の実装と、正解or不正解を判定する回答ボタンを実装します。
その他の仕様は以下となります。
・問題にはラジオボタン、チェックボックス（複数回答）どちらも使用
・全て回答で、回答ボタンを活性化
・回答ボタン押下で回答結果を表示

<p class="codepen" data-height="400" data-default-tab="html,result" data-slug-hash="BaZdVEZ" data-user="amo_sh" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/amo_sh/pen/BaZdVEZ">
  選択式クイズの実装</a> by amo_sh (<a href="https://codepen.io/amo_sh">@amo_sh</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

```html:html
<div>
 <p>Q1</p>
 <input type="radio" name="q1" id="q101"><label for="q101">答え（正解）</label>
 <input type="radio" name="q1" id="q102"><label for="q102">答え</label>
 <input type="radio" name="q1" id="q103"><label for="q103">答え</label>
</div>
<div>
 <p>Q2（複数選択）</p>
 <input type="checkbox" name="q2" id="q201"><label for="q201">答え（正解）</label>
 <input type="checkbox" name="q2" id="q202"><label for="q202">答え（正解）</label>
 <input type="checkbox" name="q2" id="q203"><label for="q203">答え</label>
</div>
<button class="btn">答え合わせをする</button>
<p class="answer">回答：</p>
```

```javascript:js
$(function(){
     $('input').change(function() {
        //チェックされた項目のnameを取得
        const checked = $('input:checked').map(function(){
            return $(this).attr('name');
          }).get();
        //全て回答されたら回答ボタンを活性化
        if (/^q1.*q2/.test(checked)) {
            $('.btn').addClass('on');
        } else {
             $('.btn').removeClass('on');
        }
    });
    $('.btn').click(function() {
        //チェックされた項目のidを取得
        const answer = $('input:checked').map(function(){
            return $(this).attr("id");
          }).get();
        //答え合わせ
        if ($(this).hasClass('on')) {
            if (answer =='q101,q201,q202') { 　
              $('.answer').text('回答：正解');
            } else {
              $('.answer').text('回答：不正解');
            }
        } else {
            return false;
        }
    });
  });
```
#すべて回答されているかチェック
.map()で、「チェックされているinputのnameを取得」します。
.test()で、取得したnameを正規表現で比較します。
q1とq2があればtrueを返します

```js:js
const checked = $('input:checked').map(function(){
            return $(this).attr('name');
          }).get();
//取得例：q1,q2

/^q1.*q2/.test(checked)
//checkedの値が　q１　の場合　＝　false
//checkedの値が　q１,q2　の場合　＝　true
//checkedの値が　q１,q2　,q2の場合　＝　true
```
#答え合わせ
.map()で、「チェックされているinputのidを取得」します。
回答があっているか比較します。

```js:js
const answer = $('input:checked').map(function(){
            return $(this).attr('id');
          }).get();
//Q1の答え（q101）をチェックした場合　＝　q101
//Q1の答え（q101）と、Q2の答え（q201）、をチェックした場合　＝　q101,q201

answer =='q101,q201,q202'
//checkedの値が　q101,q201　の場合　＝　false
//checkedの値が　q101,q201,q202　の場合　＝　true

```

#最後に
私自身まだまだ初心者のため、非効率な組み方があるかもしれません。
ご指導ご鞭撻のほどお願いいたします。
エラー'NotNullViolation'

1. エラー内容
2. 状況
3. 原因
4. 注意点

以前にも出くわした
エラーなのですが
解決法を忘れてしまったので
記録も兼ねて記事に書きます。

# 1.エラー内容

エラー内容は以下の通り。
[![Image from Gyazo](https://i.gyazo.com/a141b96da05eff4fb061ecd86f94fc8b.png)](https://gyazo.com/a141b96da05eff4fb061ecd86f94fc8b)

"ActiveRecord::NotNullViolation in Users::RegistrationsController#create_as_leader"

"Mysql2::Error: Field 'compose_style_id' doesn't have a default value"

# 2.状況

今回は
初歩的なケースなのでコードを割愛します。

ウィザード形式で追加した二ページ目で
sessionに保存していたデータごとsaveしようとしたところ
エラーが出てしまう、という状態。

エラー文によるとcompose_style_idカラムがエラーを起こしており
このカラムについてはアクティブハッシュを利用しています。

# 3.原因

正解から書いてしまうと
エラーの原因は
バリデーションとストロングパラメーターの
スペルミスでした。

（他に同じエラーの原因として考えられるのは
・password等、deviseにデフォルトである値をマイグレーションファイルで書き足してしまい、重複しているケース
・Nullになってはいけない箇所がnullになっているケース

...等々のようです。）

# 4.注意点

原因を探し当てるのに一つの障害となるのは
バリデーションそのものは正常に作動して見えることです。

以下、binding.pryで原因調査時のコード。

```ruby:ターミナル
   22: def create_as_leader
    23:   @user = User.new(session["devise.regist_data"]["user"])
    24:   @as_leader = AsLeader.new(as_leader_params)
    25:     unless @as_leader.valid?
    26:       render :new_as_leader and return
    27:     end
    28:     @user.build_as_leader(@as_leader.attributes)
 => 29:     binding.pry
    30:     @user.save
    31:     session["devise.regist_data"]["user"].clear
    32:     sign_in(:user, @user)
    33:   end

[1] pry(#<Users::RegistrationsController>)> @user.valid?
  User Exists? (0.2ms)  SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 's@s.s' LIMIT 1
  ↳ (pry):1:in `create_as_leader'
=> true
```

trueで返されてしまっています。

おそらくデータそのものは
バリデーションによって止められていないからと思われ、
逆の考え方をすると
バリデーションのfalseは
paramsの通過可否の確認しかできず
バリデーションそのものの記述の正しさを反映しません。

また、mysql関連のエラーは
基本的にバリデーションなどの
データベースに関する処理になるので
その辺りを確認していくのが
原因を探り当てる近道になりそうでした。

今回は以上です。

お読みくださりありがとうございました。
TensorFlowでGPUを使えるようにする(Windows編）

# CPUだと遅すぎ
画像解析系のモデルはCPUでも動作しますが、処理にかなり時間がかかります。
以下TensoFlowでGPUを使えるようにするまでの手順です。

# 環境
Windows10での動作確認です。他のOSは下のリンクから
 - [Linux](https://qiita.com/yusukem99/items/d5871d4f325fad4c5f85)
 - [コンテナ](https://qiita.com/yusukem99/items/6d3a586fc481ade20a1c)

# 使えるGPU
主要なメーカとしてNvdiaとAMDがありますが、今のところNvdia(Tesla/Geforce/Quadro/etc...）だけのようです。
AMDとかSoCとかはダメみたいですね。使えたという記事を見たことないです。
自作のコンパイラでSocのグラフィックボードを使えるようにする猛者はいるらしいです。

[このリンク](https://developer.nvidia.com/cuda-gpus)からCudaが使えるGPUの一覧が見れます。

## Compute Capability
[Compute Capability](https://developer.nvidia.com/cuda-gpus)という性能を表す指標があります。
自分のは**GeForceGTX 750Ti**で**5.0**でした。2014頃のハイエンドですがもうミドルに落ちてますね。

# Tensorflowのインストール
昔のバージョン(<=1.15)ではTensoflow-gpuというGPU用の別パッケージがありました。最近のコードではあまりみないですね

```bash:tensorflow最新版インストール
pip install tensorflow==2.6.0
```

# 依存関係インストール
GPUを差しただけではダメで、**NVdiaのGPUドライバー**と**Cuda**、**CuDNN**をインストールする必要があります

## NVdiaのGPUドライバー
https://www.nvidia.com/download/index.aspx

## Cuda Toolkit
https://developer.nvidia.com/cuda-downloads

インストーラーになっているので指示に従って進めるだけです。自分は推奨インストールにしました。

関連の依存があるようでVisualStdio C++がなければインストールするよう警告がでることがあります

## cuDNN
https://developer.nvidia.com/rdp/cudnn-download

こっちは畳み込みネットワークとかMaxPoolingとかDNNを使うために必要らしいです。面倒ですがDLするためにデベロッパー登録する必要があります。

ダウンロードしたzipを展開して適当な場所に配置してください

## cuDNNのパスは手動で

パスはインストーラーが勝手に登録してくれるという情報がありましたが、自動で設定してくれるのは`CUDA_PATH`と`CUDA_PATH_V[バージョン]`だけです。

CuDNNは↓のどちらか
1. `CUDNN_PATH`を手動で設定
2. `CUDA_PATH`と同じフォルダにbin,lib,includeの中身をすべてコピー（これがベストかもしれません。）

## 検証
```py:リストの中が空でなければOK
import tensorflow as tf
tf.config.list_physical_devices('GPU') 
>>> [PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
```

# エラーと対処
```powershell:Could not find the DLL(s) 'msvcp140.dll or msvcp140_1.dll'
ImportError: Could not find the DLL(s) 'msvcp140.dll or msvcp140_1.dll'. TensorFlow requires that these DLLs be installed in a directory that is named in your %PATH% environment variable. You may install these DLLs by downloading "Microsoft C++ Redistributable for Visual Studio 2015, 2017 and 2019" for your platform from this URL: https://support.microsoft.com/help/2977003/the-latest-supported-visual-c-downloads
```

[ここ](https://support.microsoft.com/help/2977003/the-latest-supported-visual-c-downloads)からDLLをインストール

```powershell:cudart64_110.dll not found
W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'cudart64_110.dll'; dlerror: cudart64_110.dll not found
```
[Cuda ToolKit](https://developer.nvidia.com/cuda-downloads)を入れる

```powershell:cudnn64_8.dll not found
W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'cudnn64_8.dll'; dlerror: cudnn64_8.dll not found
```
[CuDNN](https://developer.nvidia.com/rdp/cudnn-download)を入れる

## 学習済みモデルで試してみました
https://qiita.com/yusukem99/items/23a17c7502c326e6911f
ChaliceのCDパイプラインをシンプルに構築する

# What is chalice?
AWSが提供するPythonのサーバーレスフレームワークで、flaskみたいな書き心地でLambdaなどにデプロイできます。
今回はこのChaliceのCDを構築するお話。

# TL;DR
Chaliceは自動でCDパイプラインを構築する機能がある。でもなんか難しくて結局自分で作った。


# 使用バージョン
- chalice==1.24.1

# Deploy Command
公式ドキュメントの[Quickstart](https://aws.github.io/chalice/quickstart.html#deploying)ではローカル環境からCLIでデプロイする方法が紹介されています。

```
$ chalice deploy --stage dev
```
１コマンドで簡単！
しかしこれだとチームで開発している場合は問題になります。
Chaliceは作成したAWSリソースを把握するため、`.chalice/deployed/`配下に下記のようなJSONを作成します。

```json:deployed.json
{
  "resources": [
    {
      "name": "foo_role",
      "resource_type": "iam_role",
      "role_arn": "arn:aws:iam::...",
      "role_name": "foo"
    },
    {
      "name": "foo_lambda",
      "resource_type": "lambda_function",
      "lambda_arn": "arn:aws:lambda:ap-northeast-1:..."
    },
    {
      "name": "foo_event",
      "resource_type": "s3_event",
      "bucket": "foo-dev",
      "lambda_arn": "arn:aws:lambda:ap-northeast-1:..."
    }
  ],
  "schema_version": "2.0",
  "backend": "api"
}
```

ローカルでデプロイする際にこのJSONがチームで共有できていないとリソースの作成・更新・削除がうまくできないわけです。
このあたりはterraformのtfstateに似てる。

# CI/CD pipeline generation
そのため、ChaliceはCodePipelineによるCDパイプラインを自動的に構築する機能を持っています。
→ https://aws.github.io/chalice/topics/cd.html

```
$ chalice generate-pipeline --pipeline-version v2 pipeline.json
```

このコマンドを打つとCloudFormation用の設定ファイルが吐き出されます。
吐き出された設定ファイルを元にCloudFormationを使うことでCDパイプラインが出来上がるという二段構えです。ややこしい

# CloudFormation??
CDパイプラインのための設定が自動で出来上がっていいじゃないか。最初はそう思いました。
デフォルトの設定で十分な方はこれでもいいかもしれません。しかしドキュメントにはこんなワードがありました。
> Chalice can generate a CloudFormation template that will create a starter CD pipeline.

そう**starter**なのです。
プッシュしたら自動的にデプロイしてほしい。デプロイしたら通知がほしい。そういうオマケは自前で作る必要があります。
「でも実は私、CloudFormation使ったことない。」

さあ困った。CloudFormationがわかる方は生成された設定をいじればいいと思います。
以降は私のようなCloudFormationワカラナイ人向けです。

# Be Simple
そもそもローカルでデプロイするときは`chalice deploy`の1コマンドで済んだのに、CDになると複雑すぎない？という疑問もあり、勝手知ったるCodeBuildで`chalice deploy`させる方針を取ります。
問題になるのは状態を持っている`deployed.json`ですが、tfstateのようにS3に入れてしまいましょう。

```yaml:buildspec.yml
version: 0.2

phases:
  install:
    runtime-versions:
      python: 3.8
    commands:
      - python -V
  pre_build:
    commands:
      - echo Install dependencies...
      - pip install -r requirements.txt
      - aws s3 cp s3://chalice-deployed/${STAGE}.json .chalice/deployed/${STAGE}.json || true
  build:
    commands:
      - echo Deploy ${STAGE}...
      - chalice deploy --stage ${STAGE}
  post_build:
    commands:
      - aws s3 cp .chalice/deployed/${STAGE}.json s3://chalice-deployed/${STAGE}.json
      - echo Build completed at `date '+%Y-%m-%d %H:%M:%S'`
```

うん。シンプル。
初回は`${STAGE}.json`がなくダウンロードに失敗するので`|| true`でごまかしてます。
念の為、CodeBuildの同時ビルド制限を1にしておきます。
完成！

# ハマったところ
今回Chaliceで作成したLambda関数は一部Layerでpyodbcを入れていました。
`requirements.txt`に入れてもChaliceがパッケージングできないライブラリだからです。

こうした`requirements.txt`に書いていないライブラリがあるとCodeBuildで`chalice deploy`したときに「pyodbc入ってないよ」というエラーが出ます。
とりあえずインポートエラーを補足するワークアラウンドでしのぎました。

```python:app.py
import warnings

try:
    import pyodbc
except ImportError:
    warnings.warn("pyodbcをインポートできません。CD環境の場合はこの警告を無視できます。")
```

# まとめ
ローカルでもCDでも同じ方法でデプロイすることができました。
CloudFormation版では何をしたかったのかを読み解けておらず、まずい点があったら教えていただきたいです。
Wi-Fi通信におけるラズパイのIPアドレス固定

#本記事の内容
- Wi-Fi通信においてルータから払い出されるラズパイのIPアドレスを固定する

#実施環境
- Windows 10
- TeraTarm Version 4.9.4
- Raspberry Pi 2 Model B
- PLANEX 無線LAN子機 GW-USNANO2A ※Raspberry Pi 2はWi-Fi通信モジュールがないため、無線LAN子機をUSBに接続しWi-Fi通信を行う。
- 家庭内の無線LANネットワーク環境にて実施

#手順の流れ 
1. TeraTarmでsshログインする
2. 設定ファイルの編集
3. Raspberry Piの再起動
4. TeraTarmで再度sshログインする
5. 設定の反映確認

## 1. TeraTarmでsshログインする

WindowsにてTeraTarmを起動して、ラズパイにSSH接続する。

## 2. 設定ファイルの編集

ネットワークの設定ファイルである"/etc/dhcpcd.conf"の編集を行う。
`sudo vi /etc/dhcpcd.conf`コマンドを実行し、ファイルの末尾に以下を追記する。wlan0がWi-Fiの通信モジュールである前提。

	interface wlan0
	static ip_address="XXX.XXX.XXX.XXX"/24        #Wi-Fiルータのネットワーク内のIPを指定。重複しないように注意。
	static routers="YYY.YYY.YYY.YYY"              #デフォルトデートウェイのIPを指定する(私の環境では、Wi-FiルータのIPを指定）
	static domain_name_servers="ZZZ.ZZZ.ZZZ.ZZZ"  #DNSサーバのIPを指定する(私の環境では、Wi-FiルータのIPを指定）

(記述例)

	interface wlan0
	static ip_address=192.168.3.29/24
	static routers=192.168.3.1
	static domain_name_servers=192.168.3.1

## 3. Raspberry Piの再起動
`sudo reboot`コマンドを実行し、ラズパイの再起動を行う。
この時、TeraTarmのコンソールは終了する。

## 4. TeraTarmで再度sshログインする

WindowsにてTeraTarmを起動して、設定の反映確認のために再度ラズパイにSSH接続する。

## 5. 設定の反映確認

`ifconfig`コマンドを実行し、設定が反映されていることを確認する。

	pi@raspberrypi:~ $ ifconfig
	
	(～途中省略～)
	
	wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
	        inet 192.168.3.29  netmask 255.255.255.0  broadcast 192.168.3.255
	(～途中省略～)
	
	pi@raspberrypi:~ $

手順は以上。

## 参考文献
本記事の作成に当たり、以下の情報を参考にさせて頂きました。
- [固定IPアドレスの設定（Wi-Fi（無線LAN）の場合）](https://www.hiramine.com/physicalcomputing/raspberrypi3/wlan_howto.html)
【Python】時間とファイル名を加えたうえでprintする関数

車輪の再発明してる気がするけど、便利。


```Python:op.py
def log(*args) -> None:
    '''
    最初に時間とファイル名を加えたうえでprintする
    '''
    nowtime = datetime.now().strftime('%H:%M:%S')
    filename = __file__.split('/')[-1]
    print(nowtime, filename, *args)

log(['##'], '######################################################')
# 12:34:56 op.py ['##'] ######################################################
```
【Redshift】CASE式の入れ子はできるか？

### 実験

表題に書いたように、CASE式の中のWHEN句の中でさらにCASE式を書いても正常に動作するかどうかを実験

### 結果

下記クエリで実験し、正常に動作することを確認。

```sql
select
    case
        when a = 1 then
            case
                when b = 2 then 'a'
                else 'b'
                end
        else 'c'
        end
from (
    select
        1 as a,
        2 as b
)
```

### 結論

表題の結論：可能
【Vue.js】ディレクティブについて

#はじめに
こんにちは。
Vue.jsのディレクティブについてアウトプットしていきます！

##ディレクティブとは
>ディレクティブとは、 DOM 要素に対して何かを実行することをライブラリに伝達する、マークアップ中の特別なトークンです。

> 参照：https://012-jp.vuejs.org/guide/directives.html

タグに付与する属性のことで、冒頭に`v-`が付きます。
いくつか紹介していきます。

<br>

###v-bindディレクティブ
属性へのデータバインディングのときに使用する。

```html:HTML
<div id="app">
  <input type="text" v-bind:value="message">
</div>
```

```javascript:Vue.js
var app = new Vue({
  el: '#app',
  message: 'Hello!'
})
```
<br>

###v-ifディレクティブ
要素の表示や非表示を「真偽値」を使用して切り替えることができる。

```html:HTML
<div id="app">
  <p v-if="toggle">
    Hello!
  </p>
</div>
```

```javascript:Vue.js
var app = new Vue({
  el: '#app',
  data: {
    toggle: true  //trueまたはfalse
  }
})
```
trueの場合は、`Hello!`が表示される。
falseの場合、`toggle`で指定したpタグはDOMごと非表示になる。

<br>

###v-showディレクティブ
要素の表示や非表示を「真偽値」を使用して切り替えることができる。
v-ifディレクティブとの違いは、falseの場合CSSの`display:none`を適用させる。

```html:HTML
<div id="app">
  <p v-show="toggle">
    Hello!
  </p>
</div>
```

```javascript:Vue.js
var app = new Vue({
  el: '#app',
  data: {
    toggle: true  //trueまたはfalse
  }
})
```
trueの場合は、`Hello!`が表示される。
falseの場合、`toggle`で指定したpタグは`display:none`で非表示になる。

<br>

###v-forディレクティブ
オブジェクトの繰り返しを行う際に使用する。
`<タグ名 v-for="変数 in データの配列"> {{変数}} </タグ名>`で記述する。

```html:HTML
<div id="app">
  <ol>
    <li v-for="color in colors"> {{ color }} </li>
  </ol>
</div>
```

```javascript:Vue.js
var app = new Vue({
  el: '#app',
  data: {
    colors: ['red','blue','yellow']
  }
})
```
配列`colors`の値がv-forディレクティブにより繰り返されて、全てリスト表示される。

<br>

###v-onディレクティブ
クリックイベントなどの処理を行いたい場合に使用する。

```html:HTML
<div id="app">
  <button v-on:click="onclick">
    Click!
  </button>
</div>
```

```javascript:Vue.js
var app = new Vue({
  el: '#app',
  methods: {
    onclick: function(){
      alert('onclick');
    }
  }
})
```
ボタンをクリックするとアラートが呼ばれる処理を実行する。

<br>

#最後に
ここまでディレクティブについてまとめました。
まだ一部のディレクティブしか紹介しきれていないので、これからもまとめていきたいと思います！
Sassで画像が見つからず404 (Not Found)がでる

#404 (Not Found)がでる
```
Failed to load resource: the server responded with a status of 404 (Not Found)
```
sassで記述するときパスがわかりづらい

#統合先のstyle.cssからの相対パスを入力
記述中のVSCodeの補完機能のパスは、各scssからの相対パスになっているので、惑わされず統合先のstyle.cssの階層からの相対パスを入力する


#もしくはHTMLのタグに記述する
背景系はこちらの方がわかりやすかったりする

###背景色
```
<body style="background: url(images/yellow.jpg);">
```

###divタグにも
```
<div class="animal" style="background-image: url(images/dog.jpg)"></div>

```

###デメリット
*記述箇所が多いとHTMLコードの見た目が煩雑になる


#それでも適用されない場合
HTMLで記述したタグ名内に余分スペースがないか確認する
（気づかないときは本当に気づかない）
1時間ハマった

```
#タグ名のあとに半角スペースが２つある
<body 　style=
<div 　class="animal"
```
スプレッドシートで時間のコロン表記 (H:i:s) を分数や時間数に変換するやり方

業務ソフトから出力される形式だと足し引きの計算がしにくいため数字に変換したかったので調べたときのメモ

## 挿入する数式

### 分数

```
=(A1)/("0:01")
```

### 時間数 

```
=(A1)/("1:00")
```

## 例

|  | A | B  ... =($B1)/("0:01") | C ... =($B1)/("1:00")  |
|---|---:|---:|---:|
|1 | 元の表記 | 分数 | 時間数|
|2 | 1:00:00  | 60 | 1 | 
|3 | 4:50:00 | 290 | 4.83|
STM32L010をVSCのcubeideでLチカ


目的
軽量化
物凄く雑な方法で非推奨
初期ブート環境で無理やりLチカさせる。

mainは下記の内容

適当にコピー
main.h
stm32l0xx_hal_conf.h
stm32l0xx_it.h

ヘッダー


https://os.mbed.com/users/caa45040/code/f303_h_p1/


![h_con71.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/58f8fc5b-f0f1-2f92-8e46-30519c826241.jpeg)



```c++



#include"main.h"

int main() {

  __HAL_RCC_GPIOA_CLK_ENABLE();

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  GPIO_InitStruct.Pin = GPIO_PIN_4;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


    //HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);


    while(1) {
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
        
        for(int ii=0;ii<10000;ii++) for(int jj=0;jj<50;jj++){}

        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
        
        for(int ii=0;ii<10000;ii++) for(int jj=0;jj<50;jj++){}


    }

}



```
SPSS Modelerの分類ノードをPythonで書き換える。購入商品カテゴリの統合

SPSS Modelerで、カテゴリデータを統合したり、表記ゆれのあるカテゴリデータを統合したりする「分類ノード」をPythonのpandasで書き換えてみます。

#0．加工前のイメージ
■加工前
誰（CUSTID）がいつ（SDATE）何（PRODUCTID、L_CLASS商品大分類、M_CLASS商品中分類）をいくら（SUBTOTAL）購入したかが記録されたID付POSデータを使います。

L_CLASSにはBAG,COSMETICS,SHOESの３つのカテゴリが含まれています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/f18cf2fd-a0ab-c920-3c51-ec9b300de97d.png)

カテゴリが多すぎる場合にいくつかのカテゴリをまとめて一つのカテゴリにしたり、「バッグ」「bag」「鞄」などの表現が複数ある同じカテゴリを一つの「BAG」というカテゴリにまとめたり、ということにこの分類ノードは使います。

#1m．①商品カテゴリの統合。Modeler版


■加工後イメージ
商品大分類（L_CLASS）の「BAG」と「COSMETICS」を「雑貨」という一つのカテゴリにまとめます。

分類ノードを使うためには、まずカテゴリデータを「データ型」ノードでインスタンス化する必要があります。
データ型ノードで「値の読み込み」を行い、L_CLASSにあるカテゴリがBAG,COSMETICS,SHOESであることを読み込みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/d43b5601-bfdd-a8bc-d4b5-9df60cb28bcb.png)

次にデータ分類ノードを接続します。
「データ分類先」は「既存のフィールド」に設定すると既存のカテゴリ列を入れ替えることができます。
「データ分類フィールド」に「L_CLASS」を選択します。
そして「取得」ボタンをクリックし、さらに「コピー」ボタンをクリックします。
そうすると以下のように元の値と新しい値としてBAG,COSMETICS,SHOESが入力されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/657c1f45-5115-4a49-43c6-303d1f269b76.png)

そして、新しい値のBAG,COSMETICSを「雑貨」に書き換えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/9225b3d1-de56-b04a-e43c-405957e11ce3.png)

テーブルノードをつないで、再分類した結果を確認します。
BAG,COSMETICSが「雑貨」に変換されていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/2b6d3995-aa43-9bfc-e3c4-f1ec3be0e9a5.png)

#1p．①商品カテゴリの統合。pandas版

pandasでカテゴリ値を置き換える場合はreplace関数を使います。

分かりやすくするために置換するカテゴリ値のマッピングをコレクションで用意します。
そしてreplace関数の引数として、｛列名:マッピング・コレクション｝を引数として指定します。

```python
mapping={'BAG': '雑貨', 
         'COSMETICS': '雑貨'}
df1=df.replace({'L_CLASS': mapping})
df1
```
以下のようにBAG,COSMETICSを「雑貨」に変換されていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/987773d3-b962-fb64-3726-24522be2a3a9.png)

replace自体は上記でできるのですが、Modelerのように、既存のカテゴリ値から初期値としてのマッピングのコレクションを作れると便利です。
df['L_CLASS'].unique()でカテゴリ値を抜き出しコレクションを作り、pprintでwidth=1を指定することで元の値と新しい値の組合せの初期値が表示できます。

```python
mapping2={}
for val in df['L_CLASS'].unique():
    mapping2[val]=val
import pprint
pprint.pprint(mapping2, width=1)
```

```結果
{'BAG': 'BAG',
 'COSMETICS': 'COSMETICS',
 'SHOES': 'SHOES'}
```

この結果からマッピングのコレクションを作れば作りやすいと思います。

#2. サンプル
サンプルは以下に置きました。

ストリーム
https://github.com/hkwd/200611Modeler2Python/blob/master/reclassify/reclassify.str?raw=true
notebook
https://github.com/hkwd/200611Modeler2Python/blob/master/reclassify/reclassify.ipynb
データ
https://raw.githubusercontent.com/hkwd/200611Modeler2Python/master/data/sampletranDEPT4en2019S.csv

■テスト環境
Modeler 18.3
Windows 10 64bit
Python 3.8.10
pandas 1.3.0

#3. 参考情報
pandas.DataFrame, Seriesの要素の値を置換するreplace

https://note.nkmk.me/python-pandas-replace/

データ分類ノードのオプション設定 - IBM Documentation

https://www.ibm.com/docs/ja/spss-modeler/18.3.0?topic=node-setting-options-reclassify
praatとかパラ言語情報処理

#Praatとか
音声認識よりは、音声合成と会話分析用の音声処理にはある程度興味がある。
後者は、最近では楽曲とボーカル音を分離させる処理で一般化されつつある。

https://www.researchgate.net/profile/Nikki-Mirghafori
OpenStreetMapでジオコーディングして緯度・経度から降水予報を取得する。

住所から手軽に緯度・経度を取得して天気を取れないかなと思い、OpenStreetMapで緯度・経度を取得して、KCCSAPIから天気を取得してみる事にしました。

###OpenStreetMapについてはこちら
https://wiki.openstreetmap.org/wiki/JA:Nominatim

田町駅を指定してcurlを投げてみます。

```
curl 'https://nominatim.openstreetmap.org/search?format=json&q=田町駅'
```
```json
[
  {
    "place_id": 126250412,
    "licence": "Data c OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
    "osm_type": "way",
    "osm_id": 154232005,
    "boundingbox": [
      "35.6450685",
      "35.6462419",
      "139.7464858",
      "139.7487187"
    ],
    "lat": "35.64564675",
    "lon": "139.74745073974765",
    "display_name": "田町駅, 36, なぎさ通り, 芝浦三丁目, 麻布, 港区, 東京都, 105-0014, 日本",
    "class": "building",
    "type": "train_station",
    "importance": 0.111
  }
]
```

認証情報やアクセスキーもなく取れました！
合ってるのか試しにOSMのGUIで見てみると合っていそう！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1525729/60b6ee15-6de9-a0f9-652b-c5ff6446c853.png)

田町駅
緯度：35.6450685
経度：139.74745073974765
の降水情報を取得してみます。
今回は、こちらのドキュメントより、

https://www.energy-cloud.jp/documents/

データ配信サービス仕様書
2.10. 降⽔短時間予報データ配信機能（REST API） 

```
curl -X GET 'https://<アクセスキーID>:<シークレットアクセスキー>@rest.energy-cloud.jp/api/v1/rain-forecast/short?latitude=35.64564675&longitude=139.74745073974765'
```
```json
{
  "datetime": "2021-09-14 13:00:00",
  "timezone": "+09:00",
  "request_info": {
    "latitude": 35.64564675,
    "longitude": 139.747450739748
  },
  "mesh": {
    "latitude": 35.6458332941352,
    "longitude": 139.743750000005
  },
  "values": [
    {
      "time": "2021-09-14T13:00:00+09:00",
      "value": 0
    },
    {
      "time": "2021-09-14T14:00:00+09:00",
      "value": 0.4
    },
    {
      "time": "2021-09-14T15:00:00+09:00",
      "value": 0.4
    },
    {
      "time": "2021-09-14T16:00:00+09:00",
      "value": 1
    },
    {
      "time": "2021-09-14T17:00:00+09:00",
      "value": 1
    },
    {
      "time": "2021-09-14T18:00:00+09:00",
      "value": 1
    }
  ]
}
```
これを見ると。
datetime
2021-09-14 13:00:00
の気象庁の予報で

|予報時刻|降水量(mm)|
| ---- | ---- |
|2021-09-14T13:00:00+09:00|0|
|2021-09-14T14:00:00+09:00|0.4|
|2021-09-14T15:00:00+09:00|0.4|
|2021-09-14T16:00:00+09:00|1|
|2021-09-14T17:00:00+09:00|1|
|2021-09-14T18:00:00+09:00|1|

という予報になり、午後から雨がふりそうです！

__※後で気づきましたが、openstreetmapでジオコーディングした場合に、複数候補が出てきたり、ピンポイントでの地点情報が取れない可能性があるようで、そちらは工夫が必要そうです。__