OmniAICreator/Qiita-1.07M huggingface dataset:
[Python] Webサイトに自動ログイン

## はじめに
大学の健康管理システムに毎日ログインして健康と入力する作業が面倒と感じたので今回基本となるWebサイトへの自動入力に関する記事を書こうと思いました。
会社員や学生の方にもこういうルーティンワークがある人が参考となると嬉しいです。

## 開発環境
|OS|使用言語|ブラウザ|
|:---:|:---:|:--:|
|Windows10|Python|Google Chrome|

## 事前準備
### まずはGoogle Chromeのversion確認
Google chromeの右上にある3つの点々→「ヘルプ」→「Google Chromeについて」をクリック
![スクリーンショット (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729175/faa372d5-adf6-76f7-b210-c7c38272bac7.png)

__自分の場合はバージョン：103.0.5060.66と確認__

### バージョンに沿ったChromedriverのインストール
以下のサイトから自分のバージョンにあったdriverをインストール
[Chromedriver-binary](https://pypi.org/project/chromedriver-binary/#history)
自分の場合は以下のバージョンをインストールした。
```
pip install chromedriver-binary==103.0.5060.53.0
```
　　　　　　
　　
バージョンが異なると以下のようなエラーが表示されるので注意
```
selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 104
Current browser version is 103.0.5060.66 with binary path
```



### seleniumのインストール
SeleniumはWebブラウザで行うクリック操作やキーボード入力などをプログラム上から自動で操作できるようにしたライブラリ
```
pip install selenium
```

### 以上で準備完了

## コード
### ブラウザの起動
自分が自動ログインしたいウェブサイトの起動確認

```python
import time
import chromedriver_binary
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome import service

#WEBブラウザの起動
driver = webdriver.Chrome() 

#自動ログインしたいウェブサイトのURLをコピペ
driver.get('https://hms.hc.nagasaki-u.ac.jp/menulogin.php') 

#ウェブサイトの起動を確認するため
time.sleep(1)
````
このコードを動かすとこのように表示される。
![スクリーンショット (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729175/b68626cf-acb3-d8b9-5b2f-ec10ae2bfa40.png)

### IDとパスワードの自動入力
```python
#例を参照して、属性name,classの値を入力
my_id = driver.find_element(By.NAME, "UID")
password = driver.find_element(By.NAME, "PW")
submit = driver.find_element(By.CLASS_NAME, "btn_style1")

#入力欄を空にする
my_id.clear()
password.clear()

#自動入力したIDとパスワードを入力
my_id.send_keys("自分のID")
password.send_keys("自分が設定したパスワード")

#ログインボタンを自動入力
submit.click()

#ログインの確認のための５秒停止
time.sleep(5)

#ブラウザを閉じる
driver.close()
```
※seleniumのバージョンによってコードの書き方が変わるらしい
　2022/07/02の段階では上のコードで実装できる
　　

自動入力するにあたり、ウェブサイトのソースが必要となる。
サイトを右クリック→「検証」をクリック
![スクリーンショット (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729175/871b4277-896b-afab-d9f5-df14fcd94571.png)
サイトのHTMLコードが表示されるので、IDとパスワードを入力するタグを探す。
　　
例として、IDを入力するタグを表示した。
ID入力欄の属性nameがUIDとなっているので上の例のコードのように入力する。

パスワード、ログインボタンも同様に行う。

以上のコードを動かせば、自動でログインログアウトが行われる。
   
  
  
__自動ログインを毎日行いたい場合はこのサイトを参照してください。__
https://otona-life.com/2022/06/09/121565/

## さいごに
今回はログインの自動化のみの記事であるがこの機能を応用すれば、毎日のルーティン作業が自動化が可能となり、かなりストレス軽減されると思う。
実際に健康管理システムの自動入力を実装して以来大学からの催促メールが来なくなり、気が楽になった。
この記事を閲覧していただいた方にはぜひ実装してもらいたい。

----終----
iOS Simulatorが起動しない時の対処法

時折、Flutterアプリの実行をする際に溜まったキャッシュなどでiOS Simulatorが起動しなくなるので、その対処法を残します！

# 対処法
以下の手順で試していくと、解決します！
手順を試す→iOS Simulatorの動作確認、の流れで動作確認失敗した時に
以下の手順を進めていきましょう🔥
1. [iOS Simulator関連の削除](#1-ios-simulator関連の削除)
1. [coreSimulator/cacheの削除](#2-coresimulatorcasheの削除)
1. [DerivedDataの削除](#3-deriveddataの削除)
1. [iOS DeviceSupportの削除](#4-ios-devicesupportの削除)
1. [Library/Cachesの削除](#5-librarycachesの削除)

## 1. iOS Simulator関連の削除
iOS Simulatorの表面的なキャッシュを削除します。
```zsh
# シミュレーターの一覧表示
xcrun simctl list devices

# 使えないシミュレーターを削除
xcrun simctl delete unavailable

# キャッシュの削除
xcrun --kill-cache
```

## 2. coreSimulator/casheの削除
Simulatorに保存されているキャッシュを削除します。キャッシュはこれまでに使用したデータを素早く使うためのものですが、余計なお世話をする時もあります。例えば、昭和のステレオタイプなお話を令和に持って来られても通じませんよね？それと同じで、過去の全く関係のないデータを使おうとしてしまい、バグることがあります。そのバグを解消するのが以下のコマンドです。
私は、このコマンドで解消できました🙌
```zsh
rm -rf ~/Library/Developer/CoreSimulator/Caches/*
```

## 3. DerivedDataの削除
### DerivedDataとは
ソースコードはテキストファイルなので、基本的にデータサイズで困ることは少ないです。しかし、コンパイル後のオブジェクトファイルやライブラリのサイズは、気をつけていないとあっという間に増えてしまいます。そして、そのオブジェクトファイルやライブラリはDerivedDataとして、キャッシュに保存されます。ブラウザのキャッシュと同じでかさみ、Xcodeが動作しにくくなることがあります。そのキャッシュを削除するには、以下のコマンドを実行します。
```zsh
rm -rf ~/Library/Developer/Xcode/DerivedData/*
```

## 4. iOS DeviceSupportの削除
iOS Simulatorのサポート自体を削除します。
```zsh
rm -rf ~/Library/Developer/Xcode/iOS\ DeviceSupport/{要らないver.}
```

## 5. Library/Cachesの削除
Macのライブラリに保存されるキャッシュ全てを削除します。
```zsh
rm -rf ~/Library/Caches/*
```

## XCode　v15.0.1について : 2023/11/10追記
もしXCodeを15.0.1のバージョンにしている場合、
XCodeの「デバイスとシミュレータ」タブから「プラットフォーム」に移動して
「iOS17.0」をインストールして、過去の「iOS 17.0 Simulator」のようなものを
消すと、使えるようになるかも知れません！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017749/8ceff7fd-9c7c-03f9-7675-ff86005a85e8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017749/5eb97e83-ef82-6b60-a378-6450637b1912.png)
VisualStudioでC#のコーディングにおいて、よく使う「機能・ショートカット」

# １．マルチキャレット機能　その１
複数個のキャレット(｜←文字の入力箇所で点滅してるあいつ）を同時に操作できる機能ですね。

こんな感じの動きになる
↓
![マルチキャレット_説明.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139166/4d71d4c1-d700-9cb8-281f-ea487701f519.gif)

### なにがうれしいの？　使用例
クラスにプロパティで定義していたけど...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139166/b85424e5-f562-ad62-8770-65cce5e94073.png)
privateのreadonlyにしたいなぁ...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139166/c68c7b81-6aa7-e421-d9f5-fba84dd1a9f5.png)
操作画面.gif
![マルチキャレット.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139166/b63f704c-1a04-fb3c-820d-b2c24c88b4da.gif)

<details><summary>操作の解説(長いので見たい方だけ)</summary><div>

1. publicという単語をダブルクリックで選択
1. 「shift + alt」を押しながら「.」を二回押して、下の二つのpublicも選択されマルチキャレット状態になる。
1. その状態でprivate readonlyを入力
1. 「fn + →」で行末へ移動
1. 「shift + ctrl」を押しながら「←」でget;まで選択して、delete
1. 「ctrl」を押しながら「←」でPropertyの先頭に移動
1. deleteキーで先頭を消して、文字を衆力

:::note warn
fnはキー設定によっては効かないかもしれないです。
:::
</div></details>

### 操作方法
* 「shift + alt」を押しながら「.」を押すと現在選択中の単語と一致する、単語をファイル内で検索して最初に見つかったものを選択し、キャレットが増えます。

* 「shift + alt」を押しながら「,」を押すと選択を一つ取り消し、キャレットが減ります。

# ２．マルチキャレット機能　その２
その１では単語を選択することでキャレットを増やしますが、それ以外でもキャレットを増やすことができます。

こんな感じの動き
↓
![マルチキャレット_説明２.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139166/59bac8b1-0a02-168f-20a5-9ab8201ca49a.gif)

### 何がうれしいの？　使用例
手続き型の書き方されているけど...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139166/b3e21c4b-2814-5bf2-6842-c75fe1340f97.png)
宣言型に変えたいな...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139166/0b4bec15-a763-d3ac-e7fe-30769ec74617.png)
操作画面.gif
![マルチキャレット_2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139166/8886b8dd-d543-dbfa-9ea7-f6ccb3d947dd.gif)

<details><summary>操作の解説(長いので見たい方だけ)</summary><div>

1. p.Aの前を選択状態で「shift + alt」を押しながら「↓」を押すとキャレットが下に伸びます
1. 「shift + fn + →」で行末へ移動と同時に選択して切り取る
1. 中括弧を入れたら中を選択して、貼り付け
1. shift + alt」を押しながら「↑」を押してキャレットを上に伸ばす
1. キャレットがずれてますが、「fn + ←」で先頭にキャレットを揃えて、不要な部分をdelete
1. 「fn + →」で末尾に移動して、不要な部分をdelete
1. 最後に「ctrl + K,D」でインデントを揃えて完了 

</div></details>

### 操作方法
* 「shift + alt」を押しながら「↑」または「↓」を押すと上下にキャレットが伸びます。
* 「shift + alt」を押しながらマウスクリックでも可能です。


# ３．インデント揃えるショートカット
先にマルチキャレットの時に使ってましたが、「ctrl」押しながら、Kの次にDを押すとそろいます。

# ４．不要なnamespaceを削除するショートカット
visual studioはクラスファイル内で使用されていないnamespaceの色が薄くなりますが、
「ctrl」を押しながらRの次にGを押すと削除できます。
OutSystemsの認定試験（Associate Reactive Developer）を受けました

今回Outsystemsの認定試験である「Associate Reactive Developer」を受験したため、試験を受けた結果どう感じたかなどを書いてみようと思います。

Qiitaに記事を書くことやMarkdownで書くこと自体初めてなので、汚いと思いますが大目にみていただきたいです...
# Outsystems とは
ローコード開発ツールです。
詳しくは[こちら](https://www.outsystems.com/ja-jp/) からどんなものなのかは見てみてください。
# Associate Reactive Developer とは
下の写真のReactiveの下から３番目のもの。
OutsystemsでReactiveWeb,Mobileアプリを開発する上で、知っておきたい機能などの知識があるかを判定する試験です。 
試験場所：テストセンター又はオンライン
テスト時間：120分
合格判定基準：100点中70点（50問中35問）

本人かどうかを確認するために常にカメラで撮られているみたいです。
テストセンターで受けたのですが、見られていると思って試験中ずっとそわそわしていました笑
![outsystems.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2709582/f3ad4c41-89b9-3086-d933-8753fcc9403c.png)
# 行った勉強
#### 公式が提供しているTraining動画
すでに開発している人にとっては「知ってるよ！」という内容も多々あるとは思いますが、改めてどういう機能があるかを振り返れるので見ておいて損はないと思います。

https://www.outsystems.com/ja-jp/training/paths/18/becoming-a-reactive-web-developer/
#### サンプル試験問題
サンプル試験問題は２０問あるのですが、一般的な開発知識やOutsystemsを使う上で知っておきたい機能を問題として提供しているイメージです。
下記サイトから該当試験のファイルをダウンロードしていただければ、その中にサンプル問題が入っています。

https://www.outsystems.com/ja-jp/certifications/home.aspx
# 試験結果
結果は、100点中80点で無事合格！！！！！
日頃Outsystemsを使って開発をしている身としてもっと取れよ！という声が聞こえる気もしますが、結果がすべて！100点での合格も70点での合格もどちらも同じ合格なので受かればオッケー！

時間は120分用意されていましたが、実際は50分で終わりました。
また、合格かどうかはテストセンターの場合はその場でわかります（オンライン受験だとどうなるかは不明）
# 最後に
日頃Outsystemsで開発をしている方にとっては、そこまで難しい試験ではないと思います。
ただ、思ったよりも細かい部分（日頃開発をする上で気にしない部分）が出題されて「わからん..」ってなる場合があるので、動画だけでも見ておくことをお勧めします。
以上、最後まで見ていただいてありがとうございました！
重回帰分析の状況を3次元表示で見てみる

2 変数 `x`, `y` を使って `z` を予測する重回帰判別を行い，その結果を3次元表示してみる。
rgl で表示されるグラフィックスはマウスでグリグリ回転できる。
黒のデータがオレンジ色の平面で分割される様子が観察できる。

![スクリーンショット 2022-07-02 21.34.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611739/b1f14a5a-a4b5-c3e6-72cf-6a0a1a53e778.png)

```R
library(rgl)
library(MASS)
set.seed(123)
n <- 2000
r12 <- r21 <- 0.6
r13 <- r31 <- 0.7
r23 <- r32 <- 0.8
d <- mvrnorm(n, mu=rep(0, 3), Sigma=matrix(c(1, r12, r13, r21, 1, r23, r31, r32, 1), 3),  empirical=TRUE)
d <- data.frame(d)
colnames(d) <- c("x", "y", "z")
a <- lm(z ~ x + y, d)
rx <- range(d$x)
ry <- range(d$y)
density <- 150
x2 <- seq(rx[1], rx[2], length=density)
y2 <- seq(ry[1], ry[2], length=density)
d2 <- data.frame(expand.grid(x2, y2))
colnames(d2) <- c("x", "y")
d2$z <- predict(a, newdata=d2)
plot3d(d, xlab="Var-x", ylab="Var-y", zlab="Var-z")
points3d(d2$x, d2$y, d2$z, col="#ffaa00", cex=0.5)
```
主成分分析の状況を3次元表示で見てみる

3変数 `x`, `y`, `z` を使って，主成分分析を行い，その結果を3次元表示してみる。
rgl で表示されるグラフィックスはマウスでグリグリ回転できる。
3次元空間におけるデータの散らばりを，二次元空間に射影してみると，データの散らばり（情報の大きさ）が目に見える。

![スクリーンショット 2022-07-02 21.27.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611739/96514c6f-b6be-6071-6c39-0f7275ff04c9.png)

```R
library(rgl)
library(MASS)
set.seed(123)
n <- 4000
r12 <- r21 <- 0.4
r13 <- r31 <- 0.7
r23 <- r32 <- 0.8
d <- mvrnorm(n, mu=rep(0, 3), Sigma=matrix(c(1, r12, r13, r21, 1, r23, r31, r32, 1), 3),  empirical=TRUE)
d <- data.frame(d)
colnames(d) <- c("x", "y", "z")
a <- lm(z ~ x + y, d)
rx <- range(d$x)
ry <- range(d$y)
density <- 150
x2 <- seq(rx[1], rx[2], length=density)
y2 <- seq(ry[1], ry[2], length=density)
d2 <- data.frame(expand.grid(x2, y2))
colnames(d2) <- c("x", "y")
d2$z <- predict(a, newdata=d2)
plot3d(d, xlab="Var-x", ylab="Var-y", zlab="Var-z")
#points3d(d2$x, d2$y, d2$z, col="#ffaa00", cex=0.5)
```
Codility lesson4 FrogRiverOne

Lesson4のFrogRiverOneは位置1から位置Xまでいく最短の時間を求めるというものです。具体例で確認してみましょう。

例えば長さ4の配列[4,1,2,3]について、4に行く(X=4)には時間はどのくらいかかるでしょうか？
今回の問題設定では各配列の要素が位置を表し、0,1,2…インデックス番号が時間を表していると考えてください。

つまり、
時間0（インデックス番号0の時）の時は4の位置が現れ、
時間１（インデックス番号1の時）の時は1の位置が現れ、
時間2（インデックス番号2の時）の時は2の位置が現れ、
時間3（インデックス番号3の時）の時は3の位置が現れます。

時間3の時になって初めて1~4の全てと数字が登場するので4秒後になって初めて位置4まで移動できます。なので今回の場合、最短で位置4まで行くための時間は3であることがわかります。

つまり今回考える設定は至ってシンプルであり、
『初めて1~Xまでの全てが登場するのは配列の何番目の時か』を問われているのです。


今回の場合ポイントとなるのは、いかに二重ループを回避してコードを書くかということでした。
アルゴリズムはいくつか思い浮かびますが
例えば、1~Xが出きった時点で終了にすることから

1 　空リストを用意する（以下num_listと称する）
この空リストが1~Xの値でいっぱいになったらその時点を返す

2　値A[0]を空リストnum_listに追加していく
3　値A[1]をnum_listに追加する。ただし、num_listにすでにA[1]の値が含まれていたら重複してしまうので、num_listにA[1]が含まれているかを判定する必要がある。

この時点で、二重ループが避けられないことがわかる。
ではどのようにしたら二重ループは回避できるのでしょうか？

ヒントはカウントしていくということです。

アルゴリズムは以下の通りです。 1~Xの間の値が出現したら、カウントする。カウント回数がXになったら、つまりX個の数字が登場したことになるのでその時点のインデックス番号を返す。

また重複(例えば2が重複して登場する場合)に関して回避する方法としては、
あらかじめ全要素0からなる長さXの配列を用意しておき1~Xの間の値が登場した場合は『その値番目』に1を代入する。
そうすることで、あるか、ないかの判定が可能となる。

コードは以下の通りです。


     def research_zero(A): すでに1~Xの中の値が登場しているかを判定する 0があれば登場していない数字があるということ
        len_A = len(A)
        for i in range(len_A):
            if A[i] == 0:
                return True

    def solution(A,X):
        nums_list = [0]*(X)
        len_A = len(A)
        i = 0
        count_num = 0   #1~Xまで存在することを確認するための変数

        while i < len_A and count_num < X:  
            if nums_list[A[i]-1] == 0 and A[i] <= X: #すでにその数字が確認用リスト内にあるか調べる 確認用のリストになく、
                nums_list[A[i]-1] += 1 
                count_num +=1
            i +=1
    
        if research_zero(nums_list) or count_num > X:
            return -1

        return i-1

さて結果は。。。。？

![スクリーンショット 2022-07-02 21.22.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667538/bc7bd5c4-b816-7ad3-7a15-2e4f016fffb2.png)


やったー、100%です！二重ループはカウントを使うと回避できるんですね！
判別分析の状況を3次元表示で見てみる

3変数 `x`, `y`, `z` を使って，2群判別を行い，その結果を3次元表示してみる。
rgl で表示されるグラフィックスはマウスでグリグリ回転できる。
赤と黒のデータがオレンジ色の平面で分割される様子が観察できる。

![スクリーンショット 2022-07-02 21.18.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611739/52e3d5ba-aa2a-c7ce-9a37-c677e321c4ca.png)


```R 
library(rgl)
library(MASS)
set.seed(123)
n <- 2000
r12 <- r21 <- 0.6
r13 <- r31 <- 0.7
r23 <- r32 <- 0.8
d <- mvrnorm(n, mu=rep(0, 3), Sigma=matrix(c(1, r12, r13, r21, 1, r23, r31, r32, 1), 3),  empirical=TRUE)
dz <- 3
d <- data.frame(rbind(d, t(t(d)+c(1, 2, dz))))
d$g <- rep(1:2, each=n)
colnames(d) <- c("x", "y", "z", "g")
a <- lda(g ~ x + y + z, d)
rx <- range(d$x)
ry <- range(d$y)
density <- 150
x2 <- seq(rx[1], rx[2], length=density)
y2 <- seq(ry[1], ry[2], length=density)
d2 <- data.frame(expand.grid(x2, y2))
colnames(d2) <- c("x", "y")
coef <- coefficients(a)
d2$z <- -(coef[1]*x2+coef[2]*y2)/coef[3]+dz/2
plot3d(d, xlab="Var-x", ylab="Var-y", zlab="Var-z", col=d$g)
points3d(d2$x, d2$y, d2$z, col="#ffaa00", cex=0.5)
```
fishでbashの<<EOFと同じことをする



## bash
```
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: httpbin-gateway
spec:
  selector:
    istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "httpbin.example.com"
EOF
```

## fish
```
echo "apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: httpbin-gateway
spec:
  selector:
    istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "httpbin.example.com"
" | kubectl apply -f - 
```


## 参考
https://stackoverflow.com/questions/30357270/what-is-fish-equivalent-for-eof-in-bash
UbuntuでApache2とPHPとMySQLを入れて連携させてみた

Ubuntu22.04でWebサーバを立てるたくて、Apache2とPHPとMySQLを入れました。入れ方を忘れないようにメモとして残します。

# Apache2のインストール

下のコマンドでインストールできます。

```
$ sudo apt install apache2
```

インストール後は、バージョン確認を行います。

```
$ apache2ctl -V
Server version: Apache/2.4.52 (Ubuntu)
```

apache2が起動していない時は、下のコマンド実行します。

```
$ sudo service apache2 start
```

再起動後にapache2を起動させたい場合は、下のコマンドを実行します。

```
$ sudo systemctl enable apache2
```

FirefoxのURLに`localhost`と入れ、動作確認を行います。正常にであれば下の画面が出ます。
![apache2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593076/05d97119-3a10-bd07-295c-6c34c7124042.png)

設定ファイルを変更した時は、下のコマンドで設定が正しいか確認できます。

```
$ apache2ctl configtest
```

設定ファイルを変えただけではすぐに反映されないので、apache2の再起動も忘れずに行います。

```
$ sudo service apache2 restart
```

# PHPのインストール

下のコマンドでPHPをインストールできます。

```
$ sudo apt install php
```

インストール後には、バージョン確認を行います。

```
$ php -v
PHP 8.1.2 (cli) (built: Jun 13 2022 13:52:54) (NTS)
```

apacheからphpが起動できているの確認をします。まず`/var/www/html/`に`index.php`を作ります。

```php:/var/www/html/index.php
<?php
phpinfo();
?>
```

その後、FirefoxのURLに`localhost\index.php`と入れます。正常に動作していれば、以下の画面が出ます。
![php.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593076/d49baece-6e7b-071f-5342-51ad24a4c08f.png)

# MySQLのインストール

下のコマンドでMySQLをインストールできます。

```
$ sudo apt install mysql-server
```

インストール後には、MySQLのバージョンを確認します。

```
$ mysql -V
mysql  Ver 8.0.29-0ubuntu0.22.04.2 for Linux on x86_64 ((Ubuntu))
```

MySQLを起動します。

```
$ sudo service mysql start
```

再起動後に起動しない場合は、下のコマンドを実行します。

```
$ sudo systemctl enable mysql
```

# PHPとMySQLをPDOで連携する

ただPHPとMySQLを入れただけでは、PHPからMySQLを使用できません。PDOを使って使用できるようにします。

```
$ sudo apt install php-mysql
```

インストールしただけでは設定が反映されませんので、apache2を再起動します。

```
$ sudo service apache2 restart
```

動作確認のため、FirefoxのURLに`localhost\index.php`と入れ、下の画面が出ているか確認します。
![pdo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593076/d4fb7c86-de24-e4de-25a5-7d89b7ff15cf.png)

以上でインストールは終わりです。
【論文読み】平均画像に対するVAE異常検知の適用による道路落下物検出

## はじめに

こんにちは。論文を読んだ結果の紹介記事です。  
今回紹介するのは、「平均画像に対するVAE異常検知の適用による道路落下物検出」という論文です。  

- タイトル：平均画像に対するVAE異常検知の適用による道路落下物検出  
- 出典：山本健生, et al.; 人工知能学会, 2021   
- URL：https://www.jstage.jst.go.jp/article/pjsai/JSAI2021/0/JSAI2021_2F1GS10f03/_pdf/-char/ja  


## 概要

既存手法では、以下の課題がある。  
- 多種多様な落下物を教師ありで学習することは困難    
- 背景差分法は、光の当たり方、影など、誤検出してしまう  

関連研究の手法は以下。  
- 背景差分法＋時間差分法  
- MRF(Markov Random Field)モデルで車両奇跡を活用  
- 混合ガウス分布  　

今回、VAEによる異常検知を行う。落下物が存在しない画像のみをVAEに学習させたとき、落下物が映りこんだ画像から抽出した潜在変数は分布から離れると仮定。
画像から抽出した潜在変数と原点のマハラノビス汎距離を異常スコアとして、閾値以上の場合に落下物が存在すると判定。  
画像データは約3200枚、学習:評価=3:1で分割。明るい時間と暗い時間の両方を含む。  
評価方法は、落下物データ（異常データ）に対する検出可否と、誤検出率（誤って検出した枚数／全枚数）。VAEが、背景差分法より、検出可能数が多く、誤検出率が低くなった。  

今回、照明変動の検証はできたが、季節、天候などの変動については今後の課題。  


## 技術的特徴
- VAEを使用  
- CNN   
- 教師なし異常検知  
- 時系列に並べた画像の平均画像  


## 想定される適用例
- 画像データでの異常検知全般  


## 参考
- [平均画像に対するVAE異常検知の適用による道路落下物検出](https://www.jstage.jst.go.jp/article/pjsai/JSAI2021/0/JSAI2021_2F1GS10f03/_pdf/-char/ja)
【Python】エクセルの入力内容の読み込みと書き出しをしてみた

## 概要
pythonでエクセルに入力された内容の読み込みと書き出しの処理を作ってみました。

## 前提条件
Pythonが既にインストールされていること。

## openpyxlの導入
コンソールを開いて下記のコマンドを実行して「openpyxl」をインストールする。
```
pip install openpyxl
```

## エクセルの読み込み/書き出し処理の実行
作成したエクセルの読み込み/書き出しのプログラムは下記になります。
「テスト用.xlsx」の「シート1」シートを参照するように設定しています。

```py
import openpyxl

# 「テスト用.xlsx」を開く
wb = openpyxl.load_workbook('./テスト用.xlsx')

# 開くシートを指定
sheet = wb['シート1']

#2行、1列目のセルに入力されている内容を読み込む
value = sheet.cell(row=2, column=1).value
print(value)

#2行、2列目のセルに「書き込みテスト」を書き込む
sheet.cell(row=2, column=2).value = '書き込みテスト'

# 「テスト用.xlsx」に書き込んだ内容を保存する
wb.save('./テスト用.xlsx')

# 「テスト用.xlsx」を閉じる
wb.close()
```
## 実行結果
実行した結果は下記になります。
２行A列に記入されている「読み込みテスト」が出力され、２行B列に「書き込みテスト」がエクセルに書き込まれました。

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2056482/e49181ca-c2b7-f205-6568-f46609fce749.png)
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2056482/96c5ba3c-474e-065d-0262-9aaf9383d978.png)

## 余談
次はwebスクレイピングができたら良いなと思っています。
あと、明日のBUMPのライブが楽しみです。
rust で複数ファイルに分割したら、main.rs 以外の rust-analyzer 補完機能が効かなくなった話

rustのプロジェクトを進めるうえで、main.rs 以外に、.rs ファイルを作成したとき、補完が効かなかったのでメモ。
本当に初歩のところで躓いてしまった。

# 結論
**main.rs から mod を使ってファイルをモジュールとして読み込ませれば良い。**

# 環境
Ubuntu 22.04 (Virtual Box)

# 状態
```
├── Cargo.toml
└── src
    ├── main.rs
    └── my_module.rs
```

のようなプロジェクトの構造にしたとき、``main.rs`` では補完機能が効くが、``my_module.rs`` では、補完が効かなかった。

# 解決方法

```rust:main.rs
mod my_module; // これを追加する

fn main() {
    println!("Hello, world!");           

}

```

```rust:my_module.rs
pub fn mymodule{
    println!("called from main");
}
```

上のようなファイルを作成したとき、``main.rs``から ``mod`` を使って、``my_module.rs`` をモジュールとして読み込ませる必要がある。(たとえモジュールの関数等を main から呼び出していなくても。)

モジュールとして読み込ませれば、``rust-analyzer`` での補完機能が効くようになった。

**rust のコンパイラは、 mod で指定されて、初めてファイルをモジュールとして読み込む**のだがそれが拡張機能の補完にも繋がるとは思わなかった。先に struct だけ作るときなどは注意されたし。
PostgreSQLのTablePlusへのローカルの接続

# 今回の趣旨
自身のメモとして記しますので、
この接続がベターでないと思います。
参考資料に載っているのでかなり割愛して載せます。
PostgreSQL Connectionの設定のみ。

# PostgreSQL Connectionの設定
私が入力したところのみ水色で記載しています。

![スクリーンショット 2022-07-02 18.02.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468139/3a5ea0e5-1cd2-4a47-5dd4-24a6fcdaa205.png)

・Name
分かりやすくアプリ名にしました。

・Host
　127.0.0.1 又は localhost にしました。どちらを入力したか記憶が曖昧です。
どちらにしてもローカルを指定しています。
　
・Port
はじめに既に示されていた5432で指定。

・User/Password/Database それぞれの項目

ターミナルで
~~~
＄　psql -l
~~~
で対象のユーザー名とデータベース名を確認し、
PostgreSQL Connectionのそれぞれの項目に入力。
パスワードは自身で設定したものを。

上記を入力してConectボタンを押下。
無事接続できました。

# 参考
https://qiita.com/Masashi9410/items/328283cd5af332bebdb5

https://itmaroblog.com/tool-tableplus/

https://tech-blog.s-yoshiki.com/entry/59#%E6%8E%A5%E7%B6%9Asql%E5%AE%9F%E8%A1%8C
Django Rest Framework + nginx で 「connect() to /hoge.sock failed (13: Permission denied)」が発生した時の対処法 

# 発生事象
Amazon EC2 上のUbuntuでDjango Rest Frameworkのデプロイ作業を行った際、
アクセス時に以下のエラーが発生してしまった。

![image-100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398463/d655e9f2-2cf3-17dc-8fad-11ae101322a2.png)

# nginxおよびgunicornの起動確認
```
$ systemctl status nginx
# 以下のような記述があれば問題なし
Active: active (running) since Sat 2022-07-02 10:13:05 UTC; 21min ago

$ systemctl status gunicorn
# 確認点は同上
```

# nginxのログ確認
`$ tail /var/log/nginx/error.log`
※一部改行

```/var/log/nginx/error.log
2022/07/02 06:20:03 [crit] 6037#6037: 
*368 connect() to unix:/home/ubuntu/hoge/hoge.sock failed (13: Permission denied) while connecting to upstream, 
client: xxx.xxx.xxx.xxx, server: xxx.xxx.xxx.xxx, request: "GET / HTTP/1.1", 
upstream: "http://unix:/home/ubuntu/hoge/hoge.sock:/", host: "35.79.89.205:80"
```

Permission denied ということなので、
`/etc/nginx/nginx.conf` でnginx側の実行ユーザーをroot(or DRFの所有者)に変更する。


```/etc/nginx/nginx.conf 
user www-data;
```
↓
```/etc/nginx/nginx.conf 
user root;
```

修正後、`$ sudo systemctl restart nginx`でnginxを再起動すると正しく表示された。
STM32G031と温度センサーMCP9701で温度をシリアル出力(浮動小数点使用)


x MCP9701-E/TO 販売コード 103199

x PA2をGPIOにがわかる人むけ

目的
安価に温度を測る。

センター　400mV
ステップ　19.5mV 1℃

1 ADC
2 VDD
3 GND
4 Serial

8 SWD
7 SWD
6 未使用-未接続
5 未使用-未接続


![o_con552.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/e6482350-836f-36ea-0486-bf8fd38f974d.jpeg)


```c++


//SER_MCP9701_float_031_1

#include <Arduino.h>

//初期化処理
void setup()
{

  delay(3000); //not delete

  //シリアルの初期化
  Serial.setTx(PA2_ALT1);
  Serial.setHalfDuplex();
  Serial.begin(9600);

} //setup

//メインループ
void loop()
{

  //センサーの値を読み込む
  analogReadResolution(12); // ADC 12bit mode
  int s = analogRead(A9);   // PB7  PIN1 031 センサーの読み取り値

  //センサーのADC値を電圧に変換
  float v = s * ( 3.3 / 4096.0 );

  //センサーの電圧を温度に変換
  float t = (v - 0.4) * (1.0 / 0.0195);

  //温度の表示
  Serial.println(t);

  //1秒の待ち
  delay(1000);

} //loop



```
メモリーリークに関して

一般的な定義は、
「**オブジェクトがメモリに格納されているが、実行中のコードからアクセスできない**」
という誤ったメモリ管理の結果。

#Segmentation Fault

メモリの特定の領域に対するアクセス違反が検出された時に発生する例外(割り込みと言ったほうがいいかもしれません)の総称

以下のような場合に起こる。

- メモリが割り当てられていない領域にアクセスしようとした(*)
- 書き込みが禁止されている領域に書き込もうとした
- 実行が禁止されている領域のコードを実行しようとした

スタックオーバーフローはSegmentation Faultの原因の大きな一つですが、Segmentation Faultはそれとは独立した概念です。

#スタックトレース

エラーが発生したときに表示される内容で、そのエラーが発生するまでの過程（どんな処理がどの順番で呼び出されたかの流れ）を、ざっくりと表示したもの

メモリのスタック領域の内容が表示されているのでスタックトレースと言います

```
-fno-omit-frame-pointer
```

コンパイル時にこのオプションをつけると、スタックトレースが改善されます。

-fno-omit-frame-pointer

引用　
MacにおけるGCCとClang
https://zenn.dev/mu/articles/f0b6f07bf6b397
ChromeOS Linux開発環境でbullseyeに上げたら一部アプリケーションで日本語入力が使えない

ChromeOS Linux開発環境で`fcitx-mozc`をインストールしてMozcを使う方法について調べると、`/etc/systemd/user/cros-garcon.service.d/cros-garcon-override.conf`に設定を記述しようという情報がいくつか出てきます。

- [【西川和久の不定期コラム】Chrome OS Flexと最新版Wine 7\.0の組み合わせでWindowsアプリを動かしてみる \- PC Watch](https://pc.watch.impress.co.jp/docs/column/nishikawa/1401328.html)

ですがChrome OS 103で実際に`cros-garcon-override.conf`を見てみると、非推奨であり将来的に削除されると書いてあります。

```
$ cat /etc/systemd/user/cros-garcon.service.d/cros-garcon-override.conf 
# This file has been deprecated and could be removed in the future.
# Environment variables in the container can be set session-wide by systemd.
# See environment.d(5) or the following URL for more information:
# https://chromium.googlesource.com/chromiumos/docs/+/main/containers_and_vms.md#Can-I-set-environment-variables-for-my-container
```

書いてあるとおり、[environment\.d](https://www.freedesktop.org/software/systemd/man/environment.d.html)に同様の設定をすれば大丈夫です。

```
$ cat /etc/environment.d/fcitx.conf 
GTK_IM_MODULE=fcitx
QT_IM_MODULE=fcitx
XMODIFIERS=@im=fcitx
GDK_BACKEND=wayland
```
DRFのModelSerializerを通して新規登録、更新(create / update)

以下のような構成のTable、ModelSerializerで新規登録、更新する実現するための実装サンプル
![Table.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591553/459b8fdc-b5b1-22ab-b656-a3256b5bda28.png)
![ModelSerializer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591553/88fca6ef-63c1-46c5-2b2a-6d4b2e588ce7.png)
+ Table_A_Serilaizer で create、updateをオーバーライドする
  + オーバーライドした create、update で validated_data から table_b を抜き出す
  + create() では先にTable_A へvalidated_data で createを行い、id を生成してから Table_Bへの save を行う
  + update() はTable_A へvalidated_data で update、抜き出した data で Table_Bへの save を行う
+ view で Table_A_Serilaizer を生成する際、`partial=True` を付ける
  +  新規登録時に validation で エラーになることを避けるため
```python: view
# 登録するデータ
data = {
    'value_1': 100
    'table_b': {
        'value_2': 200
    } 
}
# 新規登録時
serializer = Table_A_Serilaizer(data=data, partial=True)
# 更新時
before = Table_A.objects.get(id=id)
serializer = Table_A_Serilaizer(instance=before, data=data, partial=True)
# 登録処理
serializer.is_valid()
serializer.save()
```
```python: serializer
class Table_B_Serilaizer(ModelSerializer):
    class Meta:
        model = Table_B
        fields = '__all__'

class Table_A_Serilaizer(ModelSerializer):
    table_b = Table_B_Serilaizer()
    class Meta:
        model = Table_A
        fields = '__all__'

    def create(self, validated_data):
        # validated_data から table_b を抜き出す
        data = validated_data.pop('table_b')
        # Table_Aのcreate
        table_a = super().create(validated_data)
        # Table_Bのsave
        table_a.table_b = self.__save_table_b(table_a, data)
        return table_a

    def update(self, instance, validated_data):
        # validated_data から table_b を抜き出す
        data = validated_data.pop('table_b')
        # Table_Bのsave
        self.__save_table_b(instance, data)
        # Table_Aのupdate
        return super().update(instance, validated_data)

    def __save_table_b(self, instance, data):
        data['id'] = instance.id
        if hasattr(instance, 'table_b'):
            table_b = Table_B_Serilaizer(instance=instance.table_b, data=data)
        else:
            table_b = Table_B_Serilaizer(data=data)
        table_b.is_valid()
        table_b.save()
```
```python: model
class Table_A(models.Model):
    id = models.AutoField(primary_key=True)
    value_1 = models.IntegerField()

class Table_B(models.Model):
    id = models.AutoField(primary_key=True)
    table_a_id = models.OneToOneField(Table_A, on_delete=models.CASCADE)
    value_2 = models.IntegerField()
```
Rails Ruby scssをページごとに実装したい時

ポートフォリオを実装していた際に、scssをtop header footerそれぞれに分けて、実装をしていきたいと思ったので、その実装方法を書かせて頂きます。
ネットで調べると色々な方法が書かれていて、どれで実装すれば良いのか、よく分からなかったため、今回僕なりの実装の方法でうまくいった方法を書かせて頂きます。

手順は主に4つです。
１、まずはscssで実装したいviewファイルに以下を記述します。

app/views/shared/_header.html.erb
```
<%= stylesheet_link_tag 'header', :media => "all"%>
```
※一番上に記述します。


２、次にapp/assets/stylesheets/内にscssファイルを作成します。
今回は1で  [[stylesheet_link_tag 'header']]としているので
header.scssを作成します。


3、次にconfig/initializers/assets.rb内に読み込みたい、scssファイルを書きます。

```
Rails.application.config.assets.precompile += %w(
  header.scss
)
```

4、最後にターミナル上で
rails assets:precompile 
とコマンドを打つと、viewファイルとscssファイルがそれぞれ紐づいて読み込めるようになります。

意外とすることが多くて大変ですが、僕はこれで今の所100発100中実装できています。
【LANアナライザ・パケットキャプチャー】wiresahrk使ってみた

#パケットキャプチャドライバについて
wireshark単体ではパケットを自由に取得できない。ネットワークを流れるパケットを得るためには、パケットキャプチャドライバが必要。

**ドライバの種類**

| ドライバ | 説明 |
|:-:|:--|
|winpcap   | 以前wiresharkに同梱されてたwindows用ドライバ  |
| airpcap  |  windows用の無線LANパケットキャプチャドライバ |
| libpcap  |  UNIX/Liux用のパケットキャプチャドライバ |
|  Npcap | Nmapプロジェクトが作成したNDIS互換のwindows用のパケットキャプチャドライバ（wiresharkに同梱されている 21/10/20現在）  |
|win10pcap|winpcapを基に、NDIS 6.Xに対応したパケットキャプチャドライバ|

###Nmapとは
ネットワーク調査およびセキュリティ監査を行うためのオープンソースのツールである。ポートスキャナが有名。

ポートスキャナとは、インターネットなどのTCP/IPネットワークに接続されたコンピュータにアクセスし、どのポートでサービスが提供されているか（接続可能か）を調べるソフトウェア。 このような探索行為のことは「ポートスキャン」（port scanning）という。

###NDIS
network driver interface specificationのライブラリを使用しており、ループバックインターフェースを利用できる点があげられる。

ループバックインターフェースは、ループバックアドレスが割り当てられている。

###ループバックアドレスとは

ループバックアドレスとは、ネットワークカードなどに割り当てられた特殊なIPアドレスで、そのコンピュータ自身を示すIPアドレスのこと。あるコンピュータがネットワークを通じて提供している機能に自身で動作する別のソフトウェアからアクセスする場合や、ネットワークを利用するソフトウェアのテストなどに用いられる。
ループバックアドレスはネットワーク上において自分自身を表す**仮想的なアドレス**であり、<strong>IPv4においては「127.0.0.1」、IPv6においては「::1」（0:0:0:0:0:0:0:1）が使われる</strong>。また、ホスト名としては慣用的に「**localhost**」が用いられる。

IPv6ではループバックアドレスは「::1」しか用いることができないと定義されているが、IPv4の「127.0.0.1」は慣習的に決められたもので、正式なものではない。このため、OSによってはこれ以外のIPアドレスをループバックアドレスとして使用できる場合もある（が、通常は別のアドレスは使わない）。

##なぜパケットキャプチャドライバが必要?
ソケットを経由してパケットを送受信するが、ソケットを経由するとネットワークを流れるデータを直接キャプチャできなくなる。
なので、ドライバを導入すると、ソケットをバイパス（回避、迂回路）し、直接wiresharkなどのLANアナライザなどでネットワークを流れるパケットを操作可能になる。

パケットキャプチャドライバは、**プロミスキャスモード**と呼ばれる特殊な設定で動作させることができる。普通のネットワークインターフェースカード（LANカード）では、基本的に自分に関係しているパケットしか受け取らない。なので、ほかのPCの通信はキャプチャできない。それを、プロミスキャスモードにLANカードの設定を変更し、すべてキャプチャできる状態にすることができる。

引用
https://e-words.jp/w/%E3%83%AB%E3%83%BC%E3%83%97%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9.html
プロセスのメモリマップとは

Linuxでは、/procというディレクトリがある。
Linux上の現在稼働中のプロセスのための疑似ディレクトリである。

このディレクトリ下にある数字のディレクトリは、PIDに対応するものである。
カーネルにあるプロセス制御テーブルをマップしたもの。
よってこのサイズはディレクトリ上のものではない。

これらの疑似ファイルは、カーネルの管理下にあり削除できない。プロセスが終了すると/procからもなくなる。
サブネットマスクとサブネットワーク

サブネットマスクとは識別子である。従来はクラスを使っていたが、使われないアドレスもあり、無駄が多くインターネットの発展に伴い、ネットワークの数がたりなくなり、その無駄をなくすため、サブネットマスクが導入された。

現在は、ネットワーク部とホスト部はクラスに依存しない。

各クラスごとに決まるホスト部を、サブネットワークアドレス部として使うことで、複数の物理ﾈｯﾄﾜｰｸに分割できるようにする仕組み。


https://www.youtube.com/watch?v=FEpKHykG8Vw
2022年折り返し

月単位で考えると、７月１日が、2022年の折り返し点になる。

日単位で考えると、７月２日が、2022年の折り返し点になる。
2022年は閏年ではなく、2月29日はない。
１年が365日で、折り返しは183日目。

2022年6月269記事書いたはず。＆7月予定。

https://qiita.com/kaizen_nagoya/items/e8eee223460ee4d3deb4

に書いた表に、7月1日、7月2日を足す。

|月|合計|日数|日平均|
|:----|:----|:----|:----|
|1|91|31|2.93|
|2|100|28|3.57|
|3|98|31|3.16|
|4|106|30|3.53|
|5|308|31|9.93|
|6|269|30|8.96|
|7.1|6|1|6|
|7.2|22|1|22|
|合計 |1001|183|5.46|

今年は質を追いかけずに、量だけ追いかけてみるかもしれない。

ごめんなさい。

# 参考資料

DoCAP（ドゥーキャップ）って何ですか？

https://qiita.com/kaizen_nagoya/items/47e0e6509ab792c43327


あなたはシステム全体を書き下せますか？

https://qiita.com/kaizen_nagoya/items/0b69dec55790dadd9f48

NASAを超えるつもりがあれば読んでください。

https://qiita.com/kaizen_nagoya/items/e81669f9cb53109157f6


2022年4月106記事書いたはず。＆5月予定。

https://qiita.com/kaizen_nagoya/items/b61f12621cb4d38e6bb0

2022年5月308記事書いたはず。＆6月予定。

https://qiita.com/kaizen_nagoya/items/0f9e6cc3dcb51690dbf4

５月病にならないで

https://qiita.com/kaizen_nagoya/items/6b9b1f00937cb8b106c9

タグから読む。Qiitaの読み方。新人プログラマ応援

https://qiita.com/kaizen_nagoya/items/625a47d19752ebacf664

「@kazuo_reve 新人の方によく展開している有益な情報」確認一覧

https://qiita.com/kaizen_nagoya/items/b9380888d1e5a042646b

こんなにfollow順番が似てるのってどういう現象＝偽識別子

https://qiita.com/kaizen_nagoya/items/ea0de85a2e5fbcbdd06e

新しい記事７割、過去記事更新３割。

https://qiita.com/kaizen_nagoya/items/82138c13d957dd1300af

遊興競技(game)断ちしてもうすぐ半年

https://qiita.com/kaizen_nagoya/items/88a3acf17f54a9c0c500

AUTOSAR 21-11, 335文書読んだ。2022年6月初旬にFO, AP, CP全部到達。

https://qiita.com/kaizen_nagoya/items/4043e8414f850ce266a4
STM32G031と温度センサーMCP9701で温度をシリアル出力(map文,使用)


x MCP9701-E/TO 販売コード 103199

x PA2をGPIOにがわかる人むけ

目的
安価に温度を測る。

センター　400mV
ステップ　19.5mV 1℃

1 ADC
2 VDD
3 GND
4 Serial

8 SWD
7 SWD
6 未使用-未接続
5 未使用-未接続


![o_con551.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/ef93a488-0373-9408-72c9-6ea537f42dcb.jpeg)


```c++

//SER_MCP9701_MAP_031_1

#include <Arduino.h>

//初期化処理
void setup()
{

  delay(3000); //not delete

  //シリアルの初期化
  Serial.setTx(PA2_ALT1);
  Serial.setHalfDuplex();
  Serial.begin(9600);

} //setup

//メインループ
void loop()
{

  //センサーの値を読み込む
  analogReadResolution(12); // ADC 12bit mode
  int s = analogRead(A9);   // PB7  PIN1 031 センサーの読み取り値

  //センサーのADC値を温度に変換
  int t = map(s, 0, 4096, -205, 1487);

  //温度の小数点以上の表示
  Serial.print(t / 10);

  //小数点の表示
  Serial.print('.');

  //温度の小数点以下の表示
  Serial.println(t % 10);

  //1秒の待ち
  delay(1000);

} //loop



```
初めてのRailsチュートリアルに挑戦！第2章

# 学習内容
## 1.Usersリソース
1. Usersリソースの作成
1. ユーザーの情報変更
1. MVCの挙動を理解

## 2.Micropostsの関連付け

1. マイクロポストの作成
1. ユーザーの関連付け
1. 継承
1. アプリケーションをherokuにデプロイ


# 学習時のエラー内容
## herokuの本番環境でアプリが起動しない
herokuからアプリを起動すると、ブラウザ上で以下のエラーが発生。
![スクリーンショット 2022-07-02 18.09.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/4b1a667b-b568-5952-4b92-62033ebbcc65.png)

エラーの指示通りに`heroku logs --tail`を実行すると、以下のようなエラーが多数発生。
```
2022-07-02T08:53:13.849617+00:00 heroku[router]: at=error code=H10
desc="App crashed" method=GET path="/" host=kinder-donair-11533.herokuapp.com 
request_id=bda9e15b-ede2-4c97-8924-31a543775630 fwd="1.75.251.161" 
dyno= connect= service= status=503 bytes= protocol=https
```
このエラーコードから、アプリがクラッシュしたエラー(H10)であることがわかった。
しかし、色々調べて対応したが、解決せず。
そこで、herokuのコンソールを確認する方法があったので、実行
```
＄ heroku run console
```
すると、app/models/user.rbにゴミのコードを発見。
これを削除し、再度デプロイすると成功した。

# 学習を終えて
scaffoldジェネレータでアプリケーションを本番環境で実行できたので、全体的な概要を理解することができた。
ただし、細かい部分の理解ができていないので、3章以降もしっかり取り組んでいきたい。
Bundlerとは

Bundlerとは一体なんなのか？
ふと気になっていたので、色々と調べた結果を書かせて頂きます。

結論を述べると
Bndlerとはそのプロジェクト内でのgemを一括で管理するものである。

railsの開発現場では大量のgemを使うことになる。
その大量のgemのバージョンは同一バージョンのgemをインストールする必要がある。bundlerを使うと、一つのコマンドで大量のgemをどの環境でも同一のバージョンをインストールすることができる。
ということらしいです。

今まで、適当にbundle installとかしちゃってたけど、こういう意味だったのかと、改めて勉強になりました。



参考記事　参考文献
プロを目指す人のためのRuby入門　改訂2版　著書　伊藤　淳一
Ruby on Rails | formからハッシュの配列をパラメータとして送信する

実務の要件ではform_withの枠組みから外れて、送るパラメータの構造を設計しなければならない場面に直面することもあります。
今回はそんな時に覚えておくとちょっと役立つかもしれないテクニックを3つほど紹介していきます。
この記事を最後まで読むことで、下記のようなパラメータを自在に設計できるようになります。

```ruby
users: [
    {
        id: 10, name: "山田太郎", email: "test@email.com", phone_number: '024-111-11',
        action_histoires: [
            {id: 10, action_datetime: "2022-05-13T00:00:00", description: "外出"},
            {id: 20, action_datetime: "2022-05-13T00:00:00", description: "直帰"},
            {id: nil, action_datetime: "2022-05-13T00:00:00", description: "時間休 13:00~"},
        ],
    },
    {
        id: 20, name: "山田太郎", email: "test@email.com", phone_number: '024-111-11',
        action_histoires: [
            {id: 30, action_datetime: "2022-05-13T00:00:00", description: "外出"},
            {id: nil, action_datetime: "2022-05-13T00:00:00", description: "直帰"},
            {id: nil, action_datetime: "2022-05-13T00:00:00", description: "直帰"},
        ],
    }
]
```

この例はユーザーとそれに紐づくユーザーの行動履歴をネスト形式で送るという想定です。
usersという配列の中に各ユーザーの情報がハッシュとして格納されており、その中で更に関連する行動履歴をaction_historiesというハッシュの配列として持ち合わせています。このような構造のparamsを作るための方法を以下の順で追っていこうと思います。

1. フォームからデータをハッシュ形式で送る方法
2. フォームからデータを配列形式で送る方法
3. フォームからデータをハッシュの配列形式で送る方法


## データをハッシュ形式で送る
htmlのinputでname属性に **user[name]** のように指定すると、指定したパラメーター名でハッシュが作成されます。（ブラケット内のワードをキーに、inputに入力された値がバリューになる）

#### Rails（viewファイル）

```ruby
<%= form.text_field 'user[name]' %> 
<%= form.email_field 'user[email]' %> 
```

form_withにモデルのインスタンスが指定されていれば以下と同義です

```ruby
<%= form_with(model: User.new, local: true) do |form| %> 
	<%= form.text_field :name %> 
	<%= form.email_field :email %> 
<% end %>
```

form_withにmodelオプションが指定されている場合、formヘルパーの第一引数にモデルが持つ属性をシンボルで指定することが可能です。
このように指定した場合、復元されたhtmlでは **モデル名[属性名]** の形式のname属性がinputタグに自動でセットされます。

#### 復元されるhtml

```html
<input type="text" name="user[name]" value="山田太郎" >
<input type="email" name="user[email]" value="yamada@email.com" >
```

#### 送信されるparams

```ruby
user => {
  name: '山田太郎',
  email: 'yamada@email.com'
}
```

## データを配列形式で送る
htmlのinputでname属性に **user[]** のように指定すると、同じnameを持つinput valueの配列が作成されます。

#### Rails（viewファイル）

```ruby
<%= form.text_field 'user[]' %>
<%= form.email_field 'user[]' %> 
```

#### 復元されるhtml

```html
<input type="text" name="user[]" value="山田太郎" >
<input type="email" name="user[]" value="yamada@email.com" >
```

#### 送信されるparams

```ruby
user => ['山田太郎', 'yamada@email.com']
```

## データをハッシュの配列形式で送る
上記二つを合わせるイメージ。htmlのinputでname属性に users[][name]のように指定すると、usersというキーに配列が作成され、その配列の中に複数のハッシュが内包される構造を作ることが可能です。

#### Rails（viewファイル）

```ruby
<%= form.text_field 'users[][name]' %>
<%= form.text_field 'users[][email]' %>
```

#### 復元されるhtml

```html
<input type="text" name="users[][name]" value="山田太郎" >
<input type="email" name="user[][email]" value="yamada@email.com" >
<input type="text" name="users[][name]" value="佐藤次郎" >
<input type="email" name="user[][email]" value="sato@email.com" >
```

#### 送信されるparams

```ruby
users => [
	{ name: '山田太郎', email: 'yamada@email.com' },
	{ name: '佐藤次郎, email: 'sato@email.com' },
]
```
Socery でundefined method 'after_save' for {:if=>...}のerrorが出てきた時の対処法

sorceryでログイン機能実装時にタイトルのような、undefined method 'after_save' for {:if=>...}のエラーが出てはまってしまったため、その解決策を書かせて頂きます。
![D8A42207-B968-430B-AE82-814F5B8D48FA.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358181/72eb0aeb-5da4-adfc-2546-2172d2386a47.jpeg)

結論を言うと、sorceryのversionを最新にすることで解決しました。


私の環境はと言うと
ruby 3.1.2
rails 6.1.5
で実装をしていました。

いつも通りrails newしてログイン機能をsorceryで実装しようとしたら、上の写真のようなエラーが出てきました。
色々な記事を見てきて、そのうちの解決策の一つに、rubyのversionを2系に落とすと良いという記事がありました。
rubyのversionを2系に落として実装したところ写真のようなエラーは無くなりました...

しかし、rubyの3系で実装したいと思っていたので、このままでは意に反することになる、

そこでsorceryのversionを確認してみると
0.14.1
になっていました。
どうやらsoreceryのversionが古いとこのようなエラーが発生するみたいです。

最新版をgoogleで検索すると 0.16.3と書いてあったのでversionを指定してinstallするとこのエラーは解決しました。


```
gem 'sorcery', '0.16.3'
```
と記述を直し、bundle installするとエラーが解決しました。
【AWS】Lambda + API Gatewayを触ってみる【API Gateway編】

LambdaとAPI Gatewayを使って簡単なAPIを作成してみます。
AWSはほとんど触ったことがないため、内容としては初歩の初歩となります。
今回はAPI GatewayでAPIを作成して、APIを呼び出すとLambda関数が実行されるようにしていきます。
使用するLambda関数については以下の記事で作成しております。

https://qiita.com/Hamoto/items/bd486937de142a589f8f

# HTTP APIを作成
マネジメントコンソールでAPI Gatewayのページを開くとAPIのタイプを選択する画面が表示されるので、今回はHTTP APIを選択します。
![画像10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2300564/2176922f-50e6-6652-592f-2d36e964e877.png)

APIの設定を行います。
統合とAPI名の設定が表示されるので、「統合を追加」を押下して、追加されたセレクトボックスで「Lambda」を選択します。
![画像11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2300564/3b62f8e4-ef0b-f097-6fba-0e447539240b.png)

Lambda関数のテキストボックスをクリックすると、Lambda関数の一覧が表示されるので紐づけたい関数を選択します。
AWSリージョンとバージョンはデフォルトのままとします。
API名を入力して「次へ」を押下します。
![画像12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2300564/5b6ca8cd-a4c7-388c-eaf8-6bc585eae3c1.png)

ルートの設定が表示されます。
メソッドはGETだけでいいので、「GET」を選択して「次へ」を押下します。
![画像13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2300564/77667bb1-39d6-ba66-190b-987bcca80b8f.png)

ステージの設定が表示されるので、これはデフォルトのままで「次へ」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2300564/b705fb67-bbe0-561a-a7bd-fd4329b6bdf8.png)

最後に間違いないか確認し、「作成」を押下してAPI作成完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2300564/c3b3c18f-0880-dc00-a40e-9616f5cbc9a3.png)

紐づけたLambda関数のページを開くと、作成したAPIがトリガーとして正常に紐づいていることが確認できます。
![画像16_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2300564/f3394b3a-8b49-ecfd-b03f-e3e045d085d2.png)

# APIを呼び出す
作成したAPIの呼び出しURLの末尾に、「/(紐づけたLambda関数名)」を追加したURL(※)をブラウザに入力して呼び出します。
※紐づけたLambda関数のページで表示されていたAPIエンドポイントと同じです。
![画像17_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2300564/c34e6fad-90fc-8ada-6abd-25e36a4a0b1a.png)

正常に "Hello from Lambda!" が表示されました！
![画像18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2300564/b310f48f-a5e2-2491-20a3-42e4720a7ece.png)

# まとめ
Lambda + API Gatewayで簡単にAPIが作成できました。
今回はLambdaとAPI Gatewayだけでしたが、他のサービスも触っていこうと思います。
Ruby %　使う方

# Ruby %　使う方

### %q
> シングルクオートで囲う場合と同等（どうとう）、シングルクオートなので、変数や定数の展開はされない
```ruby
language = "ruby"
str = %q(Programming language is "#{language}")
puts str
# => Programming language "#{ruby}"
```

### %Q
> ダブルクオートで囲う場合と同等（どうとう）　変数や定数の展開はできます
```ruby
language = "ruby"
str = %Q(Programming language is "#{language}")
puts str 

# => Programming language is ruby
```

### %w
>　配列を作る　、式の展開はされない
```ruby
arr = %w(apple orange banana)
puts arr
# => ["apple","orange","banana"]
```

### %W
```ruby
PYTHON = 'python'
arr = %W(#{PYTHON} ruby)
```


### %i
> 要素がsymbol配列を作る
```ruby
array = %i(Ruby Python PHP)
p array
# => [:Ruby, :Python, :PHP]
```

### %I
> 要素がsymbol配列を作る 式の展開はできます
```ruby
ruby = "Ruby"
array = %I(#{ruby} Python PHP)
p array
# => [:Ruby, :Python, :PHP]
```


### %s
> symbol
```ruby
res = %s(ruby)
put res
# => :ruby
```

### %x
> コマンド出力を行おう
```ruby
puts %x(date)
# => 2022年 7月 2日 土曜日 17時40分31秒 CST
```
【入門】【コピペ可】Dart でcsvファイルを読みこむ

# やりたいこと
このようなcsvを、List\<List<>>型のオブジェクトとして読み込みたい
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348026/3abba608-2ec0-1d2d-f3c7-b188c38538e7.png' width=256>

# csvを読み込み、List\<List>として取得する
以下は、test.csv というパスに当該のcsvがあることを想定しています。
もちろん、必要に応じてこちらのパスは変更してください。

```main.dart
// Import a csv flie
Future<List<List>> csvImport() async {

  final String importPath = 'test.csv';
  final File importFile = File(importPath);
  List<List> importList = [];

  Stream fread = importFile.openRead();

  // Read lines one by one, and split each ','
  await fread.transform(utf8.decoder).transform(LineSplitter()).listen(
    (String line) {
      importList.add(line.split(','));
    },
  ).asFuture();

  return Future<List<List>>.value(importList);
}

void main() async {
  final csv = await csvImport();
  print(csv);
}

```

実行結果
```
% dart run main.dart
[[apple, orange]], [[ape, lion]]
```

## 参考
https://algorithm.joho.info/dart/file-read-write-dart/

https://stackoverflow.com/questions/54319498/dart-csv-writing
【Chef】Berksfileでのcookbookの取得先設定

## はじめに
Berksfileでcookbookの取得先を設定する方法について記事を書きます。

Berksfileについては、以下の記事でも紹介しているので併せてご覧下さい。

https://qiita.com/masato930/items/87ba1c9c11ae3ccd9f03

## 今回使用するChefのバージョン

```zsh:バージョン
% knife -v
Chef Infra Client: 17.10.0
%
```

## それぞれの取得先に応じたBerksfileの設定

### supermarketから取得したい場合

```zsh:Berksfile
source 'https://supermarket.chef.io'

cookbook 'td-agent', '~> 3.2.0'
cookbook 'nginx', '~> 12.0.12'
```

※supermarketは、オープンソースのcookbookの共有を行うサイトになります。

https://supermarket.chef.io/


### GitHubのリポジトリから取得したい場合
以下のようにcookbookが格納されているGitHubのリポジトリを設定することも可能

```zsh:Berksfile(リポジトリ指定)
cookbook "apache2", git: "git@github.com:masuwa9028/apache2.git"
```

```zsh:Berksfile(ブランチ指定)
cookbook "apache2", git: "git@github.com:masuwa9028/apache2.git" , branch: "update-metadata-rb"
```


## cookbookを取得するコマンド
「はじめに」でご紹介した記事に記載していなかったので、こちらに記載しておきます。

```zsh:コマンド
berks vendor
```

```zsh:実行例
% berks vendor
Top level ::CompositeIO is deprecated, require 'multipart/post' and use `Multipart::Post::CompositeReadIO` instead!
Top level ::Parts is deprecated, require 'multipart/post' and use `Multipart::Post::Parts` instead!
Resolving cookbook dependencies...
Using apache2 (1.0.8) from git@github.com:masuwa9028/apache2.git (at update-metadata-rb)
Using apt (7.4.2)
Using nginx (12.0.12)
Using yum (7.4.0)
Using td-agent (3.2.0)
Vendoring apache2 (1.0.8) to /Users/ma-sato/Code/chef-repo/berks-cookbooks/apache2
Vendoring apt (7.4.2) to /Users/ma-sato/Code/chef-repo/berks-cookbooks/apt
Vendoring nginx (12.0.12) to /Users/ma-sato/Code/chef-repo/berks-cookbooks/nginx
Vendoring td-agent (3.2.0) to /Users/ma-sato/Code/chef-repo/berks-cookbooks/td-agent
Vendoring yum (7.4.0) to /Users/ma-sato/Code/chef-repo/berks-cookbooks/yum
%
```

以下のようにそれぞれの取得先からcookbookを取得することができていることを確認

```zsh:ディレクトリ確認
% pwd
/Users/ma-sato/Code/chef-repo : Chef関連のファイルが保管されているプロジェクトのルートディレクトリ
%
% ls -la | grep berks-cookbooks
drwxr-xr-x   7 ma-sato  staff   224  7  2 18:14 berks-cookbooks : 取得したcookbookが保管されているディレクトリ
%
```

`berks-cookbooks`の中身に取得したcookbookが保存されていること

```zsh:取得したcookbook
% cd berks-cookbooks
% ls -la
total 0
drwxr-xr-x   7 ma-sato  staff  224  7  2 18:14 .
drwxr-xr-x  15 ma-sato  staff  480  7  2 18:14 ..
drwxr-xr-x  10 ma-sato  staff  320  7  2 18:14 apache2
drwxr-xr-x  14 ma-sato  staff  448  7  2 18:14 apt
drwxr-xr-x  11 ma-sato  staff  352  7  2 18:14 nginx
drwxr-xr-x  12 ma-sato  staff  384  7  2 18:14 td-agent
drwxr-xr-x  13 ma-sato  staff  416  7  2 18:14 yum
%
```

## 参考情報
[About Berkshelf](https://docs.chef.io/workstation/berkshelf/)
サプライチェーンセキュリティのリンク集

# 規格

## SBOM

- 概略
    - [Software Bill of Materials (SBOM) | CISA](https://www.cisa.gov/sbom)
- フォーマット
    - OWASP
        - [CycloneDX](https://cyclonedx.org/)
    - Linux Foundation
        - [SPDX](https://spdx.dev/), [ISO/IEC 5962:2021](https://www.iso.org/standard/81870.html): ISOに採用された
    - NIST
        - [Software Identification (SWID) Tagging](https://csrc.nist.gov/projects/Software-Identification-SWID)

## SAST

- CISQ
    - [ISO/IEC 5055:2021 - Information technology — Software measurement — Software quality measurement — Automated source code quality measures](https://www.iso.org/standard/80623.html)

## アップデート

- CNCF
    - [TUF: The Update Framework](https://theupdateframework.io/)


## その他

- [Supply-chain Levels for Software Artifacts (SLSA)](https://slsa.dev/)

# 組織

- Linux Foundation
    - [OpenSSF: Open Software Security Foundation](https://openssf.org/)
- [CNCF: Cloud Native Computing Foundation](https://www.cncf.io/)
    - [Technical Advisory Group on Security](https://github.com/cncf/tag-security) (TAG security)
- [Continuous Delivery Foundation](https://cd.foundation/) (CDF)
  - Parent of Tekton (see above)
  - [Special Interest Group Software Supply Chain](https://github.com/cdfoundation/sig-software-supply-chain) (SIG Software Supply Chain)
  - [Special Interest Group Best Practices](https://github.com/cdfoundation/sig-best-practices) (SIG Best Practices)

# ツール

- CNCF
    - [in-toto](https://in-toto.io/)
- Linux Foundation / OpenSSF
    - [Sigstore](https://www.sigstore.dev/)
        - [Gitsign](https://docs.sigstore.dev/gitsign/overview): git のコミットに署名するためのツール
        - [Cosign](https://docs.sigstore.dev/cosign/overview): コンテナに署名するためのツール
    - [Scorecard](https://github.com/ossf/scorecard): セキュリティレベルを評価するツール
        - [OSSF Scorecard action | GitHub Actions](https://github.com/marketplace/actions/ossf-scorecard-action)
- anchore
    - [syft](https://github.com/anchore/syft): コンテナのSBOMを生成するためのツール(docker sbomコマンドに採用された)
【TypeScript入門 #13】Type Guard(型ガード)


# 概要
オンラインサロン IT_KINGDOM で、typescript について学んだことを備忘録としてメモしていきます。

# 学習内容

- Type Guard とは
- typeof を使った TypeGuard
- JS メソッドを使った TypeGuard
- in 演算子を使った TypeGuard
- タグ付き UnionTypes を使った TypeGuard

# TypeGuard とは

条件式を用いて型を制限すること。型チェックを強化することで型に関する予期せぬエラーを防ぐ。

# typeof を使った TypeGuard
`typeof`で変数の型を制限する

```typescript
export const foo = (value: string | number | boolean) => {
  if (typeof value === "string") {
    return value; // stringのみ
  } else if (typeof value === "number") {
    return value; // numberのみ
  }
  return value; // booleanのみ
};
```

# JS メソッドを使った TypeGuard

JS で準備されている型取得機能を用いて、型を制限する（例：`isArray`）

```typescript
export const foo = (value?: string | string[]) => {
  if (Array.isArray(value)) {
    return value; // string[]のみ
  } else if (!value) {
    return value; // string または undefined
  }
  return value; // stringのみ
};
```

# in 演算子を使った TypeGuard

型のプロパティの型の違いを用いて、型を制限する

```typescript
type UserA = { name: string };
type UserB = { name: string; nickName: string };

export const foo = (value: UserA | UserB) => {
  if ("nickName" in value) {
    return value; // nickNameを持つUserB
  }
  return value; // nickNameを持たないUserA
};
```

# タグ付き UnionTypes を使った TypeGuard

- 型のプロパティの値を UnionTypes で識別し、型を制限する

```typescript
type UserA = { name: string; lang: "ja" };
type UserB = { name: string; lang: "en" };
type UserC = { name: string; lang: "fr" };

export const foo = (value: UserA | UserB | UserC) => {
  switch (value.lang) {
    case "ja":
      return value; // jaを持つUserA
    case "en":
      return value; // enを持つUserB
    case "fr":
      return value; // frを持つUserC
    default:
      return value; // こもこもnever
  }
};
```

# 参考

[TypeScript Deep Dive](https://typescript-jp.gitbook.io/deep-dive/type-system/typeguard)
【useState】オブジェクトの中のオブジェクトを更新する


<h3>特定のプロパティを更新する</h3>

こういったオブジェクトがあるとする

```react
  const [obj, setObj] = useState({
    gender: "男",
    age: 20,
    height: 170,
  });

```

特定のプロパティを更新する

```react
setObj({ ...obj, gender: "女" });
```

<h5>失敗例</h5>

```react
setObj({  gender: "女" });
```

こうかくとすべて更新されてしまい、オブジェクトは

```react
{
  gender:"女"
}
```

となってしまう。
そもそも TypeScript を使用していれば、エラーをはいてくれると思う。

<h3>オブジェクトの中のオブジェクトのプロパティを更新する</h3>

次にこのようなオブジェクトがあるとする

```react
const [data, setData] = useState({
    title: "国名",
    countries: {
      values: ["日本","アメリカ"]
    }
});
```

この values の中を更新するには

```react
setData({ ...data, countries: { values: ["韓国", "中国"] } });
```

さらにネストしていたら、更新関数もネスとさせてやればいい