OmniAICreator/Qiita-1.07M huggingface dataset:
４０代おっさんPythonを勉強する（データ構造と組み込み関数④）

## 本記事について

この記事はプログラミング初学者の私が学んでいく中でわからない単語や概要を分かりやすくまとめたものです。
もし不正などありましたらコメントにてお知らせいただければ幸いです。

## データ構造と組み込み関数

前回の記事
<https://qiita.com/kou1121/items/4c3beb902e72fdd3b8d2>
<https://qiita.com/kou1121/items/1bce9187dc6fa94d3ed1>
<https://qiita.com/kou1121/items/d04e5d865a82f893018a>

### 辞書型

- 辞書型の作り方
- 基本的な代入

```python
dic1 = {1:'a', 2:'b', 3:'c' } # 辞書型は{}
print(dic1)
```

- リストやタプル型から

```python
pairs = [(1, 'a'),(2, 'b'),(3, 'c')]
dic1 = dict(pairs) # dictの変換関数で辞書型を作成
print(dic1)
```

- 内包表記を使って生成

```python
pairs = [(1, 'a'),(2, 'b'),(3, 'c')]
dic1 = {x : y for (x , y) in pairs}
print(dic1)
```

- 2つのリストからzipを使って

```python
keys = [1,2,3]
values = ['a','b','c']
dic1 = {x : y for (x , y) in zip(keys, values)}
print(dic1)
```

- enumerateを使って、キーを振る
  - enumerate()関数を使うと、forループの中でリストやタプルなどのイテラブルオブジェクトの要素と同時にインデックス番号（カウント、順番）を取得できる。

```python
values = ['a','b','c']
dic1 = dict(enumerate(values))
print(dic1)
```

- 辞書型に新しいエントリーを入れる

```python
dic1 = {1:'a', 2:'b', 3:'c' }
print(dic1)
dic1[4] = 'd' # 4: bが加わる
print(dic1)
```

- dict内の関数updateを使って、他のdictから入れる

```python
dic1 = {1:'a', 2:'b', 3:'c' }
dic2 = {24: 'x', 25: 'y', 26: 'z'}
dic1.update(dic2)
print(dic1)
```

- 辞書型にエントリーを更新する

```python
dic1 = {1:'a', 2:'b', 3:'c', 4:'d'}
dic1[4] = 'としき'
print(dic1)
```

- 別の辞書にコピーする
  - 参照値のため、コピーするにはcopyを使う

```python
dic1 = {1:'a', 2:'b', 3:'c', 4:'d'}
dic2 = dic1.copy()
print(dic2)
```

- エントリーを取り出す

```python
dic1 = {1:'a', 2:'b', 3:'c', 4:'d'}
print(dic1[4])
print(f'key: {4} value: {dic1[4]}')
```

＊ただしキーが存在しないときはエラーを起こす！

```python
dic1 = {1:'a', 2:'b', 3:'c', 4:'d'}
print(dic1[5])
```

```python
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
セル34 を c:\Users\toaik\OneDrive\デスクトップ\python\enPiT\.ipynb_checkpoints\seigyo-checkpoint.ipynb in <cell line: 2>()
      1 dic1 = {1:'a', 2:'b', 3:'c', 4:'d'}
----> 2 print(dic1[5])

KeyError: 5
```

- dict内のキーを取り出す

```python
dic1 = {1:'a', 2:'b', 3:'c', 4:'d'}
keys = dic1.keys()
for i in keys:
    print(f'key: {i} value: {dic1[i]}')
```

- dictをリストとして取り出す

```python
dic1 = {1:'a', 2:'b', 3:'c', 4:'d'}
pairs = []
for i in dic1.keys():
    pairs.append((i, dic1[i]))
print(pairs)

#  内包表記を使って
pairs = [(i, dic1[i]) for i in dic1.keys()]
print(pairs)

#  dictの関数を使って
pairs = list(dic1.items())
print(pairs) 
```

- dictの要素を削除

```python
dic1 = {1:'a', 2:'b', 3:'c', 4:'d'}
del dic1[2] # キー2の要素を削除
print(dic1)
val = dic1.pop(1) # キー0の要素を排除
print(dic1)
dic1.clear() # 全ての要素を削除、dic1 = {}にしても良い
print(dic1)
```

## 参考

https://www.kitakyu-u.ac.jp/news/2022/08/003215.html
OpenCV(cv2)を使ってJupyter上で動画をシーク

# フレーム番号を指定して、Jupyter上に動画を表示する

ありそうで、見つからなかったので、メモとして残す。


```python
import cv2
from ipywidgets import HBox, IntSlider, Label, Output, interactive
from io import BytesIO
from PIL.Image import fromarray
from IPython.display import Image
import matplotlib.pyplot as plt

cap = cv2.VideoCapture('hoge.avi')
assert cap.isOpened(), 'Could not open video device'
cnt = cap.get(cv2.CAP_PROP_FRAME_COUNT)

frame_slider = IntSlider(min=0, max=cnt-1)
msec_label = Label()


def f(frame_idx=frame_slider):
    cap.set(cv2.CAP_PROP_POS_FRAMES, frame_idx) # フレーム番号を指定
    ret, frame = cap.read() # フレームを取得
    msec_label.value = f"{cap.get(cv2.CAP_PROP_POS_MSEC):,.1f}ms" # 指定したフレームのmsを取得
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # OpenCVの画像はBGRなので、RGBに直す
    
    # jpegとしてフレームを保存し、表示。
    f = BytesIO()
    fromarray(frame).save(f, "jpeg")
    display(Image(data=f.getvalue()))
    # matplotlib.pyplot.imshow を使うほうが簡単かも
    # ただし、目盛等がついてくる
    # plt.imshow(frame)
    # plt.show()

# スライダーとラベルを画像の下にしたかったので、interactive のout(画像)のみを表示
w = interactive(f)
display(w.out)
display(HBox([frame_slider, msec_label]))
```
【Salesforce】【資格】Salesforce 認定 JavaScript デベロッパー 合格までのあれこれ

当記事は受験体験記です。
※2022年9月時点(Summer ’22)の情報です。
※あくまでもぴえさん個人の考えです。

# Salesforce 認定 JavaScript デベロッパー とは　（ざっくり）
・webassessor試験の合格とTrailheadのスーパーバッジの達成で資格が付与される
・スーパーバッジはLWCの課題が課される
・試験はJavaScript アプリケーション開発の知識が問われる
　　受験資格：なし
　　受験料：税込22,000円
　　105分60問（合格基準は65％以上）
　　選択式（ソースコードを書くような出題はない）

# ぴえさんの受験記録
【受験日程とバージョン】
日時：2022/9/25　13:00
受験方法：オンサイト受験（最寄りの会場）
バージョン：Summer ’22

【受験データ】
ウェブアセッサーのスクショ↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/2c96eb59-f901-69ac-1c7e-3465715f0240.png)

分かりにくいので表にしました↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/fc160c02-5e69-d927-bb5a-8c8995971c3c.png)

スーパーバッジは試験後に挑戦しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/82d9c2e2-0d09-2937-c47e-b054ec735d19.png)

【感想】
・オンライン試験恐怖症のため、オンサイト試験一択でした。
・3連休の1日目・2日目・3日目午前で試験勉強をしました。
・試験はSalesforceの知識が問われないので苦労しました。
・対策で解いた過去問と同じ出題がいくつか出たので正答率が上がったと思います。
・スーパーバッジが予想していた以上に難しくかなり時間がかかりました。

# 勉強方法
１．受験ガイドを読む
　　　いつの間にかQuipになっていた[試験ガイド](https://quip.com/OIpYAdobQMUk)を読みます。※以前までpdfの配布でした。
２．無料ウェビナーを受ける
　　　[Salesforce資格の無料ウェビナー開催情報](https://www.salesforce.com/jp/campaign/trailhead-academy/certification-days/)で確認できます。
　　　私が受けた回ではサンプルコードをVSCodeで実行して基礎やよく出る問題の説明をしていました。
３．webに出ている練習問題を解く
　　　今回はこちらの練習問題にお世話になりました。

https://www.jpnshiken.com/exam/JavaScript-Developer-I-salesforce-certified-javascript-developer-i-exam-11977.html

４．分からない問題はリファレンスを読む

https://developer.mozilla.org/ja/docs/Web/JavaScript

５．勉強メモを書く
Qiitaに勉強メモを投稿して受験前に読み直しをしました。

https://qiita.com/piepie1231/items/7b535c827489da4795e0



# その他のSalesforce資格について
他資格についてはこちらの記事にまとめています↓

https://qiita.com/piepie1231/items/78a0dd6bdfa2c64568cd
人事のおじさんプログラミングを学ぶ Day15「小数点第〇位で切り捨てる」

書籍『確かな力が身につくJavaScript「超」入門 第2版』に沿って、
小数点を任意の位取りで切り捨ててみた。
細かな記述内容はさておき、考え方を大事に学習を進めます。![2022-10-10 (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2783084/bec72ad0-6da1-d871-f7f6-fca5eef32f30.png)
![2022-10-10 (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2783084/86d5af6b-f87c-e15d-eac1-a94389428976.png)
![2022-10-10 (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2783084/ac494754-6b01-d168-4586-620ad3d70eb0.png)
WindowsServer（2016）でRDSライセンスを適用しても反映されないときの対処

WindowsServer2016の環境にSPLAでRDSライセンス（複数ユーザーログイン）を
適用したのですが、すぐに反映されなかったのでその対処を書きます。

## 対処
再起動すればよい👨‍💻

## 起こったこと
ライセンスを適用すると、複数ユーザーログインうんぬんの前に
RDSでログインができないという恐怖の退化が起こりました。これやばくね？ってなりますが、
これはログイン時に**IP /admin**（管理用セッション）で対処（ログイン）可能です。

## 原因
レジストリの
HKEY_LOCAL_MACHIN\SYSTEM\CurrentControlSet\Control\Terminal Server\RCM
に**X509**が即時生成されないことが原因でした。

※参考
https://social.technet.microsoft.com/Forums/exchange/ja-JP/39562fea-d335-4b41-98aa-6f6da68dd504/124561252112540-82201252112452124751253112473?forum=Wcsupportja

調べてみると、**KB2955164**をあてろと...
簡単にKBとかあてられる環境ではなかったので、えーってなりました。
とりあえず再起動や！！で、レジストリにX509が生成されました。

再起動してダメならKBあてるしかないのだと思います😇
Amazon ComprehendとLambdaを利用した感情分析APIを作成する

## はじめに

- AWSを利用してのテキスト分析が何か出来ないか？と思い、調べていたところ、Amazon Comprehendの存在を知りました。
- POSTリクエストで「特定の文書」を送ると、文書内の感情分析を行うAPIを作成してみた記事です。
- とりあえずAPIを作って動かしてみたい方向けです。

![comprehend-lambda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411902/b3898142-e251-dd35-a653-8629f7fc43de.png)

## 感情分析とは？

- Amazon Comprehendではドキュメントの感情を4つの値から判断します。
- 「Positive（肯定的）」「Negative（否定的）」「Mixed（混合）」「Neutral（ニュートラル）」の4つの値が結果として返ってきます。

例えばAmazon Comprehendのコンソール上からInput textに適当な値を入れて「Analyze」を押すと、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411902/6b9e58d2-86cd-c52a-9993-04edd124721b.png)

`Sentiment`として以下の結果が返ってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411902/1a79803b-e7fb-856d-4e4f-560809ae2004.png)

少し文言を変えてみると、`Positive`の信頼度の数値が増えていることが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411902/06e19cb9-398d-4528-6295-928aeb6ba189.png)

Comprehend全般についてはこちらの記事がとても参考になりました。

https://qiita.com/JJ33/items/eaa51a0f954889d04f4c

## 早速APIを作成してみる

Comprehendの感情分析の大まかな内容が分かりましたので、早速Lambda関数を作成していきます。

今回は名前通りEmotionalAnalysisAPIと名付けました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411902/cb393b8b-f116-c2a8-90db-ff6bcce008d7.png)

新規ロール`EmotionalAnalysisAPIRole`を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411902/63230c85-27e9-7b32-5f1c-b532ca407c6b.png)

お試し作成なので認証タイプは`NONE`とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411902/e5a86dfc-3328-be3c-5108-4e8d246d7167.png)

関数作成後、ロールに`ComprehendFullAccess`ポリシーをアタッチします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411902/aca94c6a-818c-d004-85bb-08069cd3b73b.png)

以下のコードを記載します。

```python
import json
import boto3

def lambda_handler(event, context):
    comprehend = boto3.client(service_name='comprehend', region_name='ap-northeast-1')
    data = json.loads(event.get("body"))
    return json.dumps(comprehend.detect_sentiment(Text=data["Text"], LanguageCode='ja'), sort_keys=True, indent=4)
```

POSTリクエストでエンドポイントに対してAPIコール。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411902/f69e6ff0-0feb-d4e2-6a7c-d4e186d96832.png)

画面右側がAPIの返却値です。先程のコンソールでの操作と同様に、文書内の感情分析の結果をJSON形式で返却してくれます。

※VSCodeの拡張機能`REST Client`でAPIの動作確認をしています。

## 参考文献

<https://docs.aws.amazon.com/ja_jp/comprehend/latest/dg/API_DetectSentiment.html>

<https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/comprehend.html#Comprehend.Client.detect_sentiment>
systemdおためし

# systemd

### コマンド一覧

|コマンド  |説明  |
|---|---|
|systemd-analyze plot  |  SVG 形式で起動時 unitの開始・終了を図にする  |
|systemd --test --system  |unit や設定を読んで実行 job を計算する |
|systemctl get-default  |デフォルトターゲット確認 |
|systemctl list-dependencies  |依存unit一覧を出力 |
|systemctl daemon-reload | ユニットファイルリロード |
|systemctl status [unit] | unitの状態確認
|systemctl show [unit] | unitパラメータ確認
|systemctl list-units | ユニット一覧 |
|systemctl list-unit-files| ユニットファイル一覧 |
|systemctl cat [unit] |ユニットファイルの内容出力 |


### コマンド例

#### systemd-analyze plot
```
$ systemd-analyze plot > plot.html
```
prot.htmlをブラウザで開くと図が表示される


#### enable / disable
```
$ systemctl enable [service]
$ systemctl disable [service]
```
prot.htmlをブラウザで開くと図が表示される

#### systemctl list-dependencies
```
$ systemctl list-dependencies multi-user.target
$ systemctl list-dependencies multi-user.target -a
$ systemctl list-dependencies multi-user.target --after
$ systemctl list-dependencies multi-user.target --before
```
注意したいのはこのコマンドで表示されるツリーは「起動順序」は示していないこと。
必要とされるunitを示しているだけ。
-a サービスが依存しているユニットも表示
--after/--before 依存関係を表示

#### systemctl daemon-reload
systemdはunitファイルを読み込みメモリ上にunitを作成する
```
$ systemctl daemon-reload
```

## unit file定義

#### service基本フロー
上から順に実行されていく。failの場合はExecStopPostが実行され終了する
ExecStartPre
ExecStart
ExecStartPost
ExecStop(正常終了の場合のみ)
ExecStopPost
ExecReload(リロード)

#### After Requires
After=はサービスの順序を設定し、Requires=は依存関係を示します。順序を指定しない場合、依存するサービスと同時に依存するサービスが開始されます。
Requiresは必要とするものを指定する。必要なので必ずアクティブになっている。Requiresを指定してAfterを指定していない場合は最終的にどちらも起動すればよいので、順序は補償されない。だから必ず指定すること。
Wantsはほしいものを指定する。（してほしい、されてほしい）なので必ずアクティブになっているとは限らない

#### RequiredBy
指定したサービスがアクティブになると自身もアクティブになる。
指定したサービスが失敗すると自身も停止する。


#### Type
simple: 実行されたプロセスが直接サービスを提供するタイプのプログラム。
forking: 実装プロセス側でdaemon 化する場合
oneshot: 初期化など1発実行する

## 既存ユニットのカスタマイズ方法

drop-inに書く
以下例：
unit：/lib/systemd/system/httpd.service
drop-in: /etc/systemd/system/httpd.service.d/xxx.conf
(拡張子は*.confにすること)
*.confに書いた設定が上書きされる

## 試してみる

#### RequiredBy / WantedByがうまくいかない

試してみると RequiredByを指定しているのになぜか依存先が失敗しているのに起動してしまう。
その理由は、RequiredBy / WantedByのシンボリックリンクの作成はsystemctl enableにしたときに作成されるから。
つまりRequiredBy / WantedByを書き換えると、disable enableが必要になる。（面倒くさい）
シンボリックリンクは例えば「/etc/systemd/system/test1.service.requires」ディレクトリに作成される。

以下マクロで行う
```
#!/bin/bash

sudo systemctl disable test1.service
sudo systemctl disable test2.service

sudo systemctl enable test1.service
sudo systemctl enable test2.service

sudo systemctl daemon-reload

sudo systemctl list-dependencies test1.service --after
```

#### After Beofreが逆？

```
test1.service
[Unit]
Description = test2
[Service]
Type = simple
[Install]
WantedBy = multi-user.target

test2.service
[Unit]
Description = test2
After = test1.service
[Service]
Type = simple
[Install]
WantedBy = multi-user.target

```

test2.serviceのAfter=test1.serviceなので
test1.service→test2.serviceだと思うのだが、なぜか逆の意味になってる。

```
sudo systemctl list-dependencies test1.service --after
test1.service
● tqsystem.slice
● tqsystemd-journald.socket
● tqbasic.target
● x tq-.mount
● x tqsystemd-ask-password-plymouth.path

sudo systemctl list-dependencies test2.service --after
test2.service
● tqsystem.slice
● tqsystemd-journald.socket
● tqtest1.service
```
[Go] 構造体の変換と比較

Goの構造体間で変換できる条件と比較できる条件について書きます。

## 構造体の変換について

Goの構造体の変換はフィールドの名・型・順番・数が一致していることが前提で変換することができます。例えば以下の様に, AとBでは構造体間の変換が可能です。

```go
package main

import "fmt"

type A struct {
	aa int
	bb int
}

type B struct {
	aa int
	bb int
}

func main() {
	a := A{
		aa: 1,
		bb: 2,
	}
	var b B
	b = B(a) // 変換可能
	fmt.Println(b) //=> {1 2}
}
```

逆に以下の様に、フィールド名が異なる・フィールドの型が異なる・フィールドの順番が異なる・フィールドの数が異なる、等の状態だと変換することができないです。

```go
package main

type A struct {
	aa int
	bb int
}

type DifferentFieldName struct {
	aa int
	cc int
}

type DifferentFieldType struct {
	aa uint
	bb int
}

type DifferentFieldOrder struct {
	bb int
	aa int
}

type DifferentFieldNum struct {
	aa int
	bb int
	cc int
}

func main() {
	a := A{
		aa: 1,
		bb: 2,
	}
	var d DifferentFieldName
	d = DifferentFieldName(a) // 変換不可: フィールド名が異なる

	var d2 DifferentFieldType
	d2 = DifferentFieldType(a) // 変換不可: フィールド名の型が異なる

	var d3 DifferentFieldOrder
	d3 = DifferentFieldOrder(a) // 変換不可: フィールドの定義順が異なる

	var d4 DifferentFieldNum
	d4 = DifferentFieldNum(a) // 変換不可: フィールドの数が異なる
}
```

## 構造体の比較について

Goの構造体が比較可能である条件は、同じ構造体の型であり、かつ全てのフィールドが比較可能である場合は比較できます。 フィールドが比較可能ということは、フィールドにsliceやmapなどが含まれていた場合は同じ構造体であっても比較することができません。

```go
package main

import "fmt"

type A struct {
	aa int
	bb int
}

type B struct {
	aa int
	bb int
}

type C struct {
	aa int
	bb int
	cc []int
}

func main() {
	a := A{aa: 1, bb: 2}
	a2 := A{aa: 1, bb: 2}
	fmt.Println(a == a2) // => true(比較可能)

	b := B{aa: 1, bb: 2}
	fmt.Println(a == b) // 比較不可: 構造体の型が異なる

	c := C{aa: 1, bb: 2, cc: []int{1, 2}}
	c2 := C{aa: 1, bb: 2, cc: []int{1, 2}}
	fmt.Println(c == c2) // 比較不可: 比較できないフィールドが含まれている
}
```

しかし、ある構造体と無名構造体の比較に関しては型が異なっていても、フィールドの名前・順番・型が同じであれば比較可能です。

```go
package main

import "fmt"

type A struct {
	aa int
	bb int
}

func main() {
	a := A{aa: 1, bb: 2}

	b := struct {
		aa int
		bb int
	}{
		aa: 1,
		bb: 2,
	}
	fmt.Println(a == b) //=> true

	a2 := A(b) // 型変換も可能
}
```
【AWS】CloudTrailでS3特定バケットの動作をTrailする

S3の特定バケット動作をTrailしたかったのでやってみました🔥
## ①S3バケットを作成する
Trailしたいバケットとログを吐き出したいバケットの２つを作成します。
（既にあるなら不要です）

test：ログをおいたいバケット
output：ログをはきたいバケット
![スクリーンショット 2022-10-10 20.03.52.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984662/f035bf66-6723-da79-4201-fde07da374c0.jpeg)

## ②CloudTrailを設定をする
**1.保存先バケット（output）の指定**
![スクリーンショット 2022-10-10 20.05.59.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984662/8f313aaf-80a5-70f4-b9f2-41b9acdc4dcc.jpeg)
KMSキーも必須なのでここも入力しておきます。

**2.ログイベントの設定**
イベント→イベントタイプでデータイベントのみを選択し、イベントをS3に設定します。
現在および将来...の読み書き両チェックを外し、
①で作成したバケット「test」を設定、読み書き両方にチェックします。
なお、さらに深い階層を指定したい場合はここで/プレフィックス指定ができます。
![スクリーンショット 2022-10-10 20.08.32.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984662/c97f33d3-888c-0c37-adf5-d7a3c03777ed.jpeg)

## ③実際にTrailしてみる
testバケットへ、てきとうなファイルをおいてみます。
![スクリーンショット 2022-10-10 20.30.33.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984662/ad0ee827-382a-0ec7-ae2d-dfdc43a967a6.jpeg)

ちょっとまつと、②で指定したバケット配下に新しいオブジェクトができて、
その中にファイルが出力されます✨（出力先はCludTraillの画面から確認できます）
![スクリーンショット 2022-10-10 20.16.07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984662/2225e881-d3ad-4f33-9a9a-2d7a193ac9ed.jpeg)


S3の操作ログおいかけるなんて、
それなりにセキュアな変態気味環境じゃないとやらないですよね😇
GitHubとDiscordを連携するときのWebhook設定で、400エラー起きたときの対処法

これはDiscordに限った話じゃないかも知れないのですが、GitHubのcommitイベントをDiscordに通知する設定をしたときに、少しだけつまづいたので対処法を公開しておきます。

## TL;DR
Recent Deliveryタブで失敗したDeliveryを選択して、「Redeliver」ボタンを押してください。


## 基本手順
設定の手順はこちらのサイトを参考にさせていただきました。

https://mekurun.com/tips/discord-github/

主な手順は、以下の通りで非常にシンプルです。

1. Discord側でWebhook URLを発行する
1. GitHubの設定画面でWebhook URLと通知したいイベントを設定する
1. 動作確認

これだけ簡単なので、間違えようがないんですが、設定した後にエラーマークが表示されており、なぜかHTTPステータス400が返ってきています。

## 対処方法
解決方法はこちらに書いてありました。同じ境遇の人がいたみたいです。

https://gist.github.com/jagrosh/5b1761213e33fc5b54ec7f6379034a22?permalink_comment_id=4246303#gistcomment-4246303

Webhookを登録して、Webhook一覧ページに戻ると、エラーマークが表示されており、連携が正常に動作していません。
そうなった場合は、 隣タブの"Recent Deliveries"を選択すると、連携のログみたいなものが確認できます。
このハッシュ値みたいな部分をクリックすると、詳細が表示され、そこに「Redeliver」ボタンがあるので、クリックしましょう。
![Frame 14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2731282/e2e64ec0-3bd3-1632-473e-52dfabcb6a33.png)

そうすると、今度はDiscordとの疎通が成功し、HTTPステータス200が帰ってくるようになります。

現場からは以上です。
【初学者】MVCモデルについてまとめてみた

# はじめに
自分の備忘録用として記事にしてみました。
初学者の知識整理の一助になれば幸いです。

# MVCモデルとは
「Webフレームワークで一般的に取り入れられているアプリケーション設定を整理するための概念の一つ」
これだけでは、整理？なんぞや？となると思います。
MVCとあるように、Webシステムの持つ機能を役割ごとに大きく3つに分けて開発を進めていく方法のことです。
3つの役割とは、
・Model(モデル)
・View(ビュー)
・Controller(コントローラー)
です。
これらを合わせて、MVCモデルと言います。

# MVCのそれぞれの役割とは
### Model
データを扱う部分です。データベースにアクセスをして、必要なデータを取り出します。

### View
画面表示のための部分です。レイアウトや操作性に関わる部分です。

### Controller
ModelとViewに指示を出します。
プログラムの制御を行う部分で、クライアントからの要求に対して、必要に応じてModelやViewを呼び出して処理を行い、結果となるWebページを用意してブラウザに返信をします。

# MVCモデルを使うメリット
1. アプリケーション開発を効率的に行える
役割や機能別でコードを分けることにより、開発するときも、変更するときも、保守するときも、「このコードはどこの関連か？」と迷うことがなくなります。
また、MVCそれぞれを分業して開発することができるので、それぞれに対してアプローチが可能となります。

2. 保守性の確保、新しい機能の追加を簡単にできる
各モジュールで役割分担していることにより、保守性が上がります。
Viewにバグが発生したとしても修正はViewだけに止まり、ModelやControllerにはほとんど影響がありません。
影響を少ない範囲で留めることができます。
また、独立性が高いため、コードの追加が容易にできます。

# MVCモデルの概略図
![Group 30.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738285/77e71e8f-8ddb-9f8d-789d-8c15bce21b3c.jpeg)


①クライアントからのリクエストをControllerが受け取ります。
②Modelにデータを取り出すように指示を出します。
③データベースからデータを取り出します。
④データベースから取り出したデータをControllerに送信します。
⑤受け取ったデータをViewに渡します。
⑥データを受け取ったViewが、HTMLなどを生成します。
⑦クライアントの画面に返します。

Modelがデータを扱い、Viewが表示画面を作成します。
それを制御しているのがControllerとなります。

# さいごに
ここまで読んでくださりありがとうございました。
記事を書くことで、MVCモデルについて少しは理解できたかなと思います。

ご指摘事項がありましたら、ご連絡ください。


### 参考サイト
https://www.geekly.co.jp/column/cat-technology/1911_040/
https://www.rstone-jp.com/column/93102/
https://qiita.com/riku-shiru/items/2bed096e106e72e0b58a
【Linux】xargsコマンドの使い方

## 基本的な使い方
`xargs`は以下のように記述することで前のコマンドの実行結果を標準入力から受け取って、次のコマンドの引き数に渡して実行できます。

```zsh
find . -name "*.log" | xargs rm -fv
```

上記の場合には`find`コマンドで取得したすべてのファイルパスに対して`rm`コマンドが実行されます。

以下のようなコマンドが実行されます。

```zsh
rm -fv ./path/to/sample1.log ./path/to/sample2.log ./path/to/sample3.log
```

## コマンドライラン
`-p`をつけると実際にはコマンドは実行されず実行される予定のコマンドの内容が出力されます。

```zsh
$ find . -name "*.log" | xargs -p rm -fv
rm -fv ./path/to/sample1.log ./path/to/sample2.log ./path/to/sample3.log?...
```

## 引数の位置を指定
以下のように記述することで引数の位置を指定できます。

```zsh
find . -name "*.log" | xargs -i cp {} /exampledir/
```

以下のようなコマンドが実行されます。

```zsh
cp ./path/to/sample.log /exampledir/
```

また以下のように記述しても上記と同様のことが実現できます。

```zsh
find . -name "*.yml" | xargs -IXXX cp -f XXX ./exampledir/
```

## 引数の最大数を指定
`-L 数値`を追記するとコマンドに一度に渡す引数の最大数を指定できます。

```zsh
find . -name "*.log" | xargs -L 1 rm -fv
```

上記の場合に`find`コマンドで3つのパスを取得したとすると以下のように実行されます。

```zsh
$ rm -fv ./path/to/sample1.log
$ rm -fv ./path/to/sample2.log
$ rm -fv ./path/to/sample3.log
```

なお`-L 数値`は改行ごとに1つの引数として扱います。

`-n 数値`でも引数の数を指定できますがこちらは`xargs`がコマンドに渡す引数の最大数を指定します。

```zsh
$ seq -s ' ' 10 | xargs -L 2 echo T
T 1 2 3 4 5 6 7 8 9 10

$ seq -s ' ' 10 | xargs -n 2 echo T
T 1 2
T 3 4
T 5 6
T 7 8
T 9 10
```

## 同時実行の最大数を指定
`-P 数値`を追記すると同時実行の最大数を指定できます。

```zsh
find . -name "*.log" | xargs -L 1 -P 2 rm -fv
```

上記の場合に`find`コマンドで3つのパスを取得したとすると1つ目と2つ目が同時実行されその後に3つ目が実行されます。
node-configのlocal.json

# はじめに
[node-config](https://github.com/node-config/node-config) が `NODE_ENV` の言うことを聞いてくれなくて困ったことがあったので記録しておく。


# 起こったこと
`NODE_ENV` の値は `dev` になってるのに、どうしても`local.json`の値が読み込まれてしまう

# 原因
仕様だった。local.jsonとかlocal-xxx.yamlとかそういうのを設定ファイルに含めると、`NODE_ENV`の値に関係なく必ずそいつを読み込むらしい → https://github.com/node-config/node-config/issues/685

「この仕様のおかげで、ローカルではテスト通ってたのにプッシュしたらテスト通らない みたいなことがなくなるよ」などと言っている → https://github.com/node-config/node-config/wiki/Configuration-Files#local-files 


# おわりに
https://github.com/node-config/node-config/issues?q=local.json でissueのぞいてみたら同士がいっぱいいたけど、どれに対しても「バグじゃないよ、仕様だよ！wikiちゃんと読んでね」って返してるから変えるつもりはないんだろうなあ。

ちなみに、「`NODE_ENV` が設定されてなかった場合は`development` がデフォルト値として使われる」仕様も今回初めて知った。`default.json` じゃないのか。
【Python】CSVファイルに出力する時系列データを更新させない方法

# 現状
 Arduinoを使ってセンサのデータを取得し，取得したデータをPythonで受け取ってCSV形式で保存したい．実装したところ，CSVファイルで時系列データが更新されてしまう．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/e62a4ff8-3bc3-4a09-a634-548bf43256ff.png)

```python:該当プログラム
    date = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
with open('./data.csv', 'w' , encoding= 'utf-8' ) as f:
    print('{},{}'.format(date,data),file=f)
```

# 解決方法
　`open(ファイル名, モード)`でファイルをモードに従って開く．モードを`a`に変えることで解決できた．`w`は書き込み専用で，ファイルへの書き込みは，同じファイル名のファイルがあった場合は，新しく上書きされる．（既存ファイルに書き込みがあった場合，内容は削除される）
　`a`にした場合，ファイルへの追記となり，同じファイル名のファイルがあった場合は既存のファイルに追加する．そのためモードを`a`に変更することで解決する．

```python:該当プログラム
    date = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
with open('./data.csv', 'a' , encoding= 'utf-8' ) as f:
    print('{},{}'.format(date,data),file=f)
```



# Pythonのファイル入出力のモード
　ファイルの入出力時に使用するモードをいくつか紹介する．

| モード | 意味 | 注意事項・補足 |
|:--:|:--:|:--:|
| 'r' | 読み込み専用 | ファイルが存在しない場合はエラーになる |
| 'w' | 書き込み専用 | 既存のファイルがある場合上書きされる |
| 'a' | ファイルの末尾に追記 | ファイルがない場合は新規作成 |
| 'r+' | 更新（読み取りと書き込み） | 'r'と同様に，ファイルが存在しない場合はエラーになる |
| 'w+' | ファイルを空にして，そのファイルを読み書き用に開く | 'w'と同様に，既存のファイルがある場合上書きされる |
| 'a+' | ファイルを読み書き用に開いて，ファイルの末尾に追記 | 'a'と同様に，ファイルがない場合は新規作成 |
| 'b' | ファイルをバイナリモードで開く | 他のオプションと合わせて指定する |
E資格受験記録

# はじめに
E資格（2021#1）の受験記録を残します。

# 概要
一般社団法人日本ディープラーニング協会によるエンジニア向けの試験です。
応用数学、機械学習、深層学習、開発・運用環境について問われます。

[詳細はこちら](https://www.jdla.org/certificate/engineer/)

# 受験のきっかけ
G検定を受けた際に仕組みをもっと深く知りたくなった事、
データ分析の手法を知っておけば今後役立つ事があるだろうと考えたからです。

認定プログラムの費用も安くなってきていた事もあり、
趣味と割り切って認定プログラムに申し込みました。

# 認定プログラム
受験にはJDLA認定プログラムの修了が前提となりますが、
どれが良いのか情報がほぼ無いので迷います。

私が選んだのは安い部類のプログラムでした。
全てオンラインの講座です。
値段相応なのか、資料は統一性が無く、突貫でかき集めたような内容。
講師もちょっと頼りない感じ。

という事で、講座の資料をベースに自分でネットで調べつつ、
自分なりの資料として別途まとめ直しながら学習を進めました。



# 勉強方法
講座と並行し、主に下記4冊を用いました。

#### ①人工知能プログラミングのための数学がわかる本
<img src= "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883732/31d4af38-c3be-587f-2e48-129237f19d1e.jpeg" width=25%>

基礎数学、微分、線形代数、確率統計が学べます。
講座を開始する前に準備として一通り読みました。
事前に読んでおいて良かったです。
[リンクはこちら](https://www.amazon.co.jp/dp/4046021969)

#### ②ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装
<img src= "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883732/02c00770-3118-4a50-5c7c-4ac8b9f64ecd.jpeg" width=25%>

ディープラーニングの基礎的な仕組みが分かり易く学べます。
解説が丁寧で、講座よりもこちらの本の方が役に立ちました。
E資格を受ける方にお薦めしたい1冊です。
[リンクはこちら](https://www.amazon.co.jp/dp/4873117585)

#### ③ゼロから作るDeep Learning 2 ―自然言語処理編
<img src= "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883732/129f271d-7029-6b32-1aa9-ea7650f6527a.jpeg" width=25%>

『ゼロから作るDeep Learning』の続編です。
word2vec、RNN、LSTM、GRU、seq2seq、Attention等、こちらも受験範囲を網羅しています。
一通り実装した後、何度も読み返しました。
[リンクはこちら](https://www.amazon.co.jp/dp/4873118360)


#### ④徹底攻略ディープラーニングE資格エンジニア問題集
<img src= "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883732/4bf4cf9d-0e3a-ece2-42f1-423d99a5bfde.jpeg" width=25%>

講座や他の本で学習した後に腕試しで解きました。
解説がとても詳しく記載されています。
本試験より難易度が高い印象です。
この問題集が理解できていれば、合格ラインに達しているのではと思います。
[リンクはこちら](https://www.amazon.co.jp/dp/B096YB4WLQ)

#### ⑤機械学習（ディープラーニング）関連の記事
アルゴリズムの解説等はQiitaの記事もよく参考にさせて頂きました。
記事をアップしてくださっている方々に感謝です。

# 試験当日
> 試験時間：120分
> 知識問題（多肢選択式・100問程度）
> 各地の指定試験会場にて受験

ピアソンで申し込んで最寄りの会場で受けました。

開始早々にPCが固まり再起動してもらったり、
渡されたメモ用のペンが2本ともインク切れだったりと、不運に見舞われました。

気を取り直して試験を開始。
計算問題は後回し、その他（コードやアルゴリズム関連、知識問題）から解きました。
途中、悩む問題で時間を費やしてしまう事もありましたが、
もっと考えたい気持ちを抑えてその問題は諦め、次の問題へ進みました。

それでも時間に余裕はなく、計算問題を短時間で解く羽目に。
時間配分に失敗しましたが何とか最後まで解きました。

# 結果
■分野別の得点率
応用数学：83 ％
機械学習：92 ％
深層学習：85 ％
開発環境：100 ％

合格でしたが、合格ラインは開示されていないので不明です。
強化学習は難しい。
理解が足りていませんでした。

# 感想
E資格の合格に必要なのは、理論やアルゴリズムなどに関する知識であり、
実装スキルはそれほど無くても合格できる気がします。

ただ、E資格の学習を進めることで、
ライブラリを用いる際にハイパーパラメータがどう作用するのか、
その理論や意味を知ることが出来たのが有意義でした。

あとは様々なアルゴリズムを知るのが面白かったです。
GAN（敵対的生成ネットワーク）を考えた人すごいなとか。

実際のデータ分析に活かすには別の取り組みも必要になると思いますが、
今回の学習はその礎くらいにはなったと思うので、
それだけでも学習を進めて良かったです。
Python 構文エラーについて

# はじめに
構文エラー(SyntaxError)は、
使用しているプログラムコードが、言語の構文に違反している場合に起こるエラーのことです。
```
print("pythonで書いています。"
  Cell In [90], line 1
    print("pythonで書いています。"
                          ^
SyntaxError: incomplete input
```
この場合は、
カッコの閉じ忘れでエラーが起きています。

上記のようなエラーはよく起こるため、気をつける必要があります。
他にもいくつか代表的な構文エラーがあるので紹介していきます。

# 構文エラーの紹介
代表的なものとして以下が挙げられます。

### クォートのつけ忘れ
```
print("pythonで書いています。)
Cell In [91], line 1
    print("pythonで書いています。)
          ^
SyntaxError: unterminated string literal (detected at line 1)
```


### カッコの閉じ忘れ
```
print("pythonで書いています。"
  Cell In [90], line 1
    print("pythonで書いています。"
                          ^
SyntaxError: incomplete input
```

### コロンのつけ忘れ
```
def m()
    return ("pythonで書いています。")
  Cell In [97], line 1
    def m()
           ^
SyntaxError: expected ':'

```
### インデントの崩れ
```
def m():
return ("pythonで書いています。")
  Cell In [98], line 2
    return ("pythonで書いています。")
    ^
IndentationError: expected an indented block after function definition on line 1
```


### 全角スペースの利用
```
def m():
　return ("pythonで書いています。")
Cell In [99], line 2
    return ("pythonで書いています。")
    ^
SyntaxError: invalid non-printable character U+3000
```

### == の代わりに = を使う
```
def f(x):
    if x = 1:
        return x
Cell In [110], line 2
    if x = 1:
       ^
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?
```

# 構文エラーの対処法

エラーの対処としては、
- エラーメッセージをよく読む
- 原因を推察
することが必要です。

例として以下の場合で構文エラーになったと仮定して対処します。


```
print("pythonで書いています。"
  Cell In [90], line 1
    print("pythonで書いています。"
                          ^
SyntaxError: incomplete input
```
1. エラーが起こると 
    - SyntaxError 
    - IndentationError 
    などと出力されるので確認します。
ここでは、「SynatxError」と出力されています。
 
2. それに付随するメッセージが、
構文エラーの具体的内容とおおよその位置を説明してくれます。
ここでは、「incomplete input」と出力されており、
翻訳すると、不完全入力とでています。
文章を見返すと、カッコのつけ忘れがありました。

3. 訂正し再度実行
```
print("pythonで書いています。")

pythonで書いています。
```
エラーを解消できました。
 
今回の例のように、
エラーメッセージの説明は、必ずしも分かり易くない場合があります。
ですが、原因の位置を絞りこむには有用です。

# 終わりに
初めはエラーメッセージが出ると焦ったり、イライラすることがあります。
ですが、今回のように対応していくことで冷静に対応できるかと思います。
PHPでコードゴルフ

<h2>はじめに</h2>

コードゴルフって面白いですね。
あれこれ考えていると普段見かけないソースが生まれたりして新鮮な気持ちになれました。
日頃PHPを書かない人もいると思いますので、敷居が下がればと思い使いそうなものをざっくりまとめておきます。
（比較に関することは例によって
闇が深い
書いていないため、<a href="https://www.php.net/manual/ja/types.comparisons.php">公式ページ</a>を参照してください）
<h2>公式</h2>


すべてここに書いてあります

https://www.php.net/manual/ja/langref.php


<h4>変数宣言</h4>

```php
// 変数名は必ず$をつけます。
$hoge = '1';

// 数字から始まる以下のような変数名は無効です。
$1 = '1';
$1_hoge = '11';

// 大文字小文字違いは別の変数として扱われます。
$hoge = 'あ';
$HOGE = 'い';
echo $hoge;// あ
echo $HOGE;// い
```

<h4>配列生成</h4>

```php
// 以下は同じ配列が得られます。
$a = [1, 2, 3];
$a = array(1, 2, 3);

// 多次元配列の場合は変数化した方が短くなります。
$a = [[1, 2, 3], [4, 5, 6]];
$a = array(array(1, 2, 3), array(4, 5, 6));

// array()にListとMapの区別はないものと思ってもらって大丈夫です。
// 一部だけkeyを指定することもできます。
$a = array(
  1,
  'hoge' => 2,
  3
);

// 型の制約がないので以下のような配列も作れます。
$a = array(1, 'a', true, '1');
// これをimplode（to_sのような文字列表現）に渡すと以下のような結果になります。
echo implode($a); // 1a11
```

<h4>ループ処理</h4>

```php
// 普通のfor
for ($i = 0; $i < 10; $i++) echo $i;

// 普通のwhile
// インクリメントの前置後置の扱いは一般的な他言語と同じです。
$i = 0;
while ($i < 10) echo $i++; 

// 拡張for
// インデックスが不要な場合、$i=>を削ります。
foreach (array('a', 'b', 'c') as $i => $n) echo $n;// abc
```

<h4>出力</h4>

```php
// 文字列連結に.を使います。
$s = 'hoge'.'fuga';

// ダブルクォートで変数展開します。
echo 'hoge\nfuga';
// hoge\nfuga
echo "hoge\nfuga";
// hoge
// fuga

// 出力するだけならechoで足ります。引数で渡す必要がないため短くなります。
echo 'hoge';
echo('hoge');// 上と同じ

// printfでフォーマット出力になります。
// 第一引数がフォーマッタ、以降は可変長です。
$n = 1000;
$u = '円';
printf("%d%s", $n, $u);//1000円
```

<h2>さいごに</h2>

途中で確認する時は以下のコマンドを使いました。
<pre>// 半角スペースとLFを除去
sed -e 's/ //g' ファイル名.php | tr -d '\n'</pre>
バイト数が欲しい時は`wc -c`
文字数は`wc -m`
をつなぎます。

また、PHPタグ`<?PHP`は実行環境により`<?`に縮められることがあります。
開始タグを削れない場合でも行末の終了タグ`?>`は削れるかもしれません。
こういったことも詰めていくと、だんだんコードゴルフしてる感じになります。
Ruby on Railsの基本概念【基礎】

# Ruby on Railsの基本概念1[DRY]
Ruby on Railsの基本概念の１つ目はDRY(Don’t Repeat Yourself)です。
これは同じ情報を繰り返さないという考え方になります。
つまり、同じコードは繰り返し記述しないことが、Rubyで守るべき１つ目のルールになります。
このルールを守ることによって、コードの修正が必要になった際に、何箇所もある同じような記述を一つづつ修正していくのではなく、まとめた１箇所を修正するだけで済むので、保守・管理がしやすくなります。

# Ruby on Railsの基本概念2[CoC]
2つ目がCoC(Convention Over Configuration)です。
これは設定よりも規約を優先するという考え方です。
個々の開発者がそれぞれ違った設定を持ち、違った規約の下で開発をおこなっていれば、途中から参加した開発者は混乱してしまいます。
そういった事を防ぎ、効率的な開発を行うために、ファイル名の命名方法やRailsで既に定義されている処理をしっかりと守る事で、開発者同士の共通認識がはっきりとし、効率的に開発を進められます。

## 基本概念を知る意味
Ruby on Railsの基本概念を知ることはRailsで開発をする上で、Railsを使う意味として重要なものです。
基本概念を守ることは、ミスの発生やコミュニケーションの齟齬が生まれづらくなるため、初心者であっても守るように開発を進めていきましょう。
ROCm で Stable DreamBooth 動きます(現状解像度に制約あり)

ふえぇ... DreamBooth 極めたいよぉ...

## 環境

* ROCm 5.3(Docker)
* Ubuntu 20.04
* RX6800 (16GB)

ROCm で Stable Diffusion 動きます
https://qiita.com/syoyo/items/5d361ef5ff95d8ca70ee

あたり参考にして ROCm 環境整えます.


## 方法

https://github.com/huggingface/diffusers/tree/main/examples/dreambooth

オフィシャル? は huggigngface diffusers にありますが, これでは 16GB 版つかっても RX6800(16GB) では GPU メモリ不足になります.

https://github.com/huggingface/diffusers/issues/684

を参考に 

https://github.com/ShivamShrirao/diffusers/tree/main/examples/dreambooth

を使います.

- `fp16` on
- `use_8bit_adam` off
- `gradient_checkpointing` on
- 解像度は 384

あたりで学習できます!
class images の生成に 1 時間くらいかかります.
また, class images 生成のパスでは解像度 512 でもメモリ不足はおきずらいようです. その後の最終処理(?)でメモリ不足エラーがおきやすいです. class images 生成まで 512x512 というのもできるかもはしれません.

## 制約

bitsandbytes(8bit)は動かないため, 解像度を下げて対応します.
384x384 行けました.
408x408 もいけるかもはしれません.

## 結果

huggingface のオフィシャル?のワンちゃんデータセットを instance-images に使います.

![Screenshot from 2022-10-10 17-53-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36275/6fee16b2-9ee5-fa5a-2b5f-f0c1dd9d7b62.png)

Mars と Moon にバケツで降り立つワンちゃんを生成します!

![Screenshot from 2022-10-10 18-17-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36275/6e8e188a-789e-c4c6-234c-7ff58c36e86a.png)

![Screenshot from 2022-10-10 18-17-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36275/24e102ed-d439-6afb-043a-0f414a348a2b.png)


Voila! ちょっとワンちゃんの顔つきが違うきもするが... とりあえずヨシ!



## その他

参考までに,

https://github.com/XavierXiao/Dreambooth-Stable-Diffusion

こちらもメモリ不足で動きませんでした.


DreamBooth, DreamFusion を GPU メモリ 16 GB or 24 GB で動かしたいメモ
https://qiita.com/syoyo/items/8fc5906db4730a2651c9




## TODO

* メモリ or NVMe 必要だが VRAM 8GB で学習できる版をためす https://github.com/huggingface/diffusers/tree/main/examples/dreambooth#training-on-a-8-gb-gpu 
* bitsandbytes(LLM.int8)の ROCm 移植をする
  * そんなにめんどうでは無いはずだが, 他の誰かが先にやってくれるかもはしれません https://github.com/TimDettmers/bitsandbytes/issues/47
【Unity】WebRequestでいい感じにGetパラメーターを設定する

# 初めに
UnityからLINEのAPIを叩こうとした際にいい感じにGetパラメーターを設定する方法が中々見つからなかったためメモを残します。
（と言ってもC#の機能を使っているだけです）

# コード
```c#:LineManager
	private async UniTaskVoid LineLogin()
	{
		// Getパラメーター部分の作成
		var queryString = System.Web.HttpUtility.ParseQueryString("");
		queryString.Add("response_type", "code");
		queryString.Add("client_id", "id");
		queryString.Add("redirect_uri", "http://redirect.com");
		queryString.Add("state", "123abc");
		
		// URIとクエリストリングをマージ
		var uriBuilder = new System.UriBuilder("https://api.line.me/oauth2/v2.1/token") {
			Query = queryString.ToString()
		};
		
		Debug.Log(uriBuilder.Uri);
		
		// Getの実行
		UnityWebRequest request = UnityWebRequest.Get(uriBuilder.Uri);
		await request.SendWebRequest();
		Debug.Log(request.downloadHandler.text);
	}
```
DreamBooth, DreamFusion を GPU メモリ 16 GB or 24 GB で動かしたいメモ

# 背景

DreamBooth https://dreambooth.github.io/, DreamFusion https://dreamfusion3d.github.io/ 動かしたいよぉ...
(しかし G 社のネーミングセンスは相変わらずよくないですね...)


- RTX 3090(24GB)
- Tesla P100(16GB)
- RX6800(ROCm. 16GB)

で pytorch 実装のを試しました.

# DreamBooth

https://github.com/XavierXiao/Dreambooth-Stable-Diffusion

3090 でも動かず.

https://github.com/huggingface/diffusers/tree/main/examples/dreambooth

こちらの huggingface diffusers 版は 16 GB 版で Tesla P100, 3090(CUDA 11.8) で動作しました.
(最近(2022/10/10 頃) CUDA 11.8 対応した)


ROCm はそのままでは 16 GB 版スクリプトでもメモリ不足.

https://github.com/huggingface/diffusers/issues/684 を参考にメモリ削減版の fork を使えば 408x408 で動作
(メモリに余裕あるなら DeepSpeed を使う 8 GB で動作すると思われる)

https://github.com/gammagec/Dreambooth-SD-optimized

T.B.W.

# DreamFusion

https://github.com/ashawkey/stable-dreamfusion

こちらは 3090, P100 動作.

3090 は 100W(!) に powerlimit して 1s/it(150,000 steps だとおよそ 4 時間).

P100 は 125W に powerlimit + コアクロック落として, デフォルト設定で 1.95s/it(150,000 steps だとおおよそ 8 時間). ただ生成されるのはどうも 3090 で生成したのより劣る感がある(RT コアがないから NeRF の計算が荒いため?)

RX6800 でも少し修正して処理自体は進むが, 結果がおかしい(収束しない). どこか CUDA 特有のコードパスがあるやもしれません.
Unityで大冒険 -主人公の町-

これはUnityという世界に転生した物語である。

## 1. 君の名は？
・・・
・・・・・・
こけし「ここどこだ！？」

こじゅろう「ここは<b>Unity</b>という世界じゃ」

こけし「Unity！？」

こけし「そして、あなたは誰？」

こじゅろう「わしは、こじゅろうじゃい。はて、君は誰じゃ？」

こけし「・・・・」
こけし「・・・記憶が・・・ないです・・・」

こじゅろう「じゃ、そこに<b>スクリプト</b>というのがあるんじゃ取ってくれんか？」

こけし「<b>紙みたいなもの</b>ですね、はいどうぞ！」


こじゅろう「まぁそうだわい、スクリプトに書けばプログラミングができるじゃけ」

こけし「このUnityの世界でプログラミングするために必要ってわけですね」


こじゅろう「Unityの世界だけじゃなく、もっと広い世界でも活躍できるんじゃ」
こじゅろう「スクリプトはTryCodeでいいかのう、<b>名前はわかりやすいもの</b>が一番じゃ」

```TryCode.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TryCode:MonoBehaivour
{
    void Start()
    {
        //ここのこと
    }
    void Update()
    {

    }
}
```
こけし「いったい何をしているんですか？」

こじゅろう「まぁいいから見とれ、おまえさん名前がわからないんだろう」

こけし「転生したのか、やっぱり記憶がないみたいです」

こじゅろう「そうかい、じゃったらここにStartって書いてあるじゃろ」
こじゅろう「<b>gameObject.name</b>と書いてみんかい」

こけし「わかった、ここだね」
こけし「・・・<b>gameObject.name</b>っと、これでよし！」
```TryCode.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TryCode:MonoBehaivour
{
    void Start()
    {
        //とりあえず、こけしは書いてみた
        gameObject.name
    }
    void Update()
    {

    }
}
```
こじゅろう「・・・そうか、言い忘れておったわ」
こじゅろう「<b>Debug.Log()という呪文</b>を使うんじゃったな」

こけし「呪文ですか！？」


こじゅろう「そうじゃ、<b>第一の術デバッグログ！！</b>みたいな感じじゃよ」
こじゅろう「カッコの中に書くんじゃ」
こじゅろう「あと、呪文のあとに<b> ;(セミコロン)</b>が必要だけん」

こけし「なるほど、こうですね」
```TryCode.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TryCode:MonoBehaivour
{
    void Start()
    {
      Debug.Log(gameObject.name);
    }
    void Update()
    {

    }
}
```
こじゅろう「うん、これでよかろう」

こじゅろう「そのスクリプトを君が大切に持ってなさい」

こけし「わかりました、持っていればいいんですね」

こじゅろう「じゃ、始めるぞ！」
こじゅろう「<b>Unityデポチットナ！！</b>(Unityで再生ボタンを押します)」


こけし「・・・」
こけし「何も起こきませんね」

こじゅろう「よく見んかい、ここに名前が出てるじゃろ」

こけし「<b>こけし</b>って書いてあります」

こじゅろう「それが君の名じゃ、こけし」


こけし「これが自分の名前かぁ、俺こけしに転生したの！？」

---つづく---
Pythonをpyenvを用いて管理する（Mac向け）

## はじめに
ローカルマシンで複数のプロジェクトを開発する時にバージョンの異なるPythonを使うことは往々にしてあると思います。
単一バージョンをインストールしていると、毎回インストールとパスを通す作業が発生しますが、
pyenvの場合はコマンドだけでPythonのバージョンの切り替えが可能です。
（最近はDockerを使うのでホストマシン側のPythonに依存することは少ないかもしれませんが。。）

今回はpyenvのインストールとバージョン変更手順を説明します。

## Homebrewのインストール
ターミナルを開き、以下のコマンドでMacのパッケージ管理ツールのHomebrewをインストールします。
```
% /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
参考
https://brew.sh/index_ja

## pyenvのインストール
ターミナルで以下のコマンドを実行します。
```
% brew install pyenv 
```
以下のコマンドを実行してバージョンが表示されれば成功です。
```
$ pyenv -v

pyenv 2.3.5
```

## パスを通す

#### /bin/zshの場合
以下のコマンドを実行してパスを通します。
```
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
```
```
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
```
```
$ echo 'eval "$(pyenv init -)"' >> ~/.zshrc
```
上記のパスが.zshrcに追記されているか確認します。
```
$ cat ~/.zshrc
```
追記されていることを確認したら、以下のコマンドでシェルの設定を反映します。
```
$ source ~/.zshrc
```

#### /bin/bashの場合
以下のコマンドを実行してパスを通します。
```
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
```
```
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
```
```
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
```
上記のパスが.zshrcに追記されているか確認します。
```
$ cat ~/.zshrc
```
追記されていることを確認したら、以下のコマンドでシェルの設定を反映します。

```
$ source ~/.bash_profile
```

## Pythonのインストール
以下のコマンドでインストール可能なPythonのバージョン一覧を表示できます。
```
$ pyenv install --list
```
現時点（2022/10/10）で最新版をインストールします。
```
$ pyenv install 3.10.7
```
インストール済みのバージョンを確認する。
```
$ pyenv versions
* system (set by /Users/user/.pyenv/version)
  3.10.7
```
または、
```
$ pyenv global
system
```

## バージョンの切り替え
以下のコマンドを用いてインストールしたバージョンの切り替えます。
```
$ pyenv global 3.10.7
```
バージョンが切り替わっているか確認します。
```
$ pyenv versions
  system
* 3.10.7 (set by /Users/shsh/.pyenv/version)
```
上記の通り、指定したバージョンに切り替わっていることが確認できます。
SoapUIでendpoint explorerウインドウが閉じれない時の対処法

環境：Mac
チップ：M1 Pro

SoapUIをインストールぅッ！したはいいものの![スクリーンショット 2022-10-10 17.42.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955588/5b08ec15-f5a3-4a63-74ef-3dcc49ae648d.png)
こいつが最初に出てきて右下のClose押しても消えず、それどころかフリーズする件についての解決方法。

/Applications/SoapUI-5.7.0.app/Contentsのvmoptions.txtをいじります。

最後の行に

`-Dsoapui.browser.disabled=true`

を追加すればウインドウは出てくるものの閉じれるようになります。
あとは目的に応じて使ってください。

全然日本語の情報が無く英語で調べてもかなり時間がかかったので共有。
TypeScript でライブラリを使わずに簡易 throttle, debounce

凝ったオプションを使いたい場合は lodash を使いましょう

```typescript:throttle.ts
function throttle(fn: (...args: any[]) => void, wait: number) {
  let timerId: number | null = null;
  return (...args: any[]) => {
    if (timerId !== null) {
      return;
    }
    timerId = window.setTimeout(() => {
      timerId = null;
      return fn(...args);
    }, wait);
  };
}
```

```typescript:debounce.ts
function debounce(fn: (...args: any[]) => void, wait: number) {
  let timerId: number | null = null;
  return (...args: any[]) => {
    if (timerId) {
      clearTimeout(timerId);
    }
    timerId = window.setTimeout(() => {
      fn(...args);
    }, wait);
  };
}
```
制御構文

# if

条件分岐の結果をそのまま代入できる。

```jsx
fn main() {
    let a = 10;
    let b = if a > 5 {
        println!("a > 5");
        a + 10
    } else {
        println!("a <= 5");
        a - 10
    };
    println!("{}", b);
}
```

# 繰り返し

## Loop

breakした値が戻り値になる。

```jsx
fn main() {
    let mut i = 0;
    let result = loop {
        println!("count: {}", i);
        if i == 10 {
            break i * 2;
        }
        i += 1;
    };
    println!("{}", result);
}
```

## While

```rust
fn main() {
    let mut i = 0;

    while i < 10 {
        println!("count: {}", i);
        i += 1;
    }
    println!("{}", i);
}
```

## for

```jsx
fn main() {
    // 繰り返し回数が決まっている場合
    for i in 0..10 {
        println!("{}", i);
    }

    // 繰り返す要素が決まっている場合
    let array: [i32; 10] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    for i in array {
        println!("{}", i);
    }
}
```

### range型

`for i in 1..10`の`1..10`のような書き方はRange型が返る。

```jsx
fn main() {
    let a = 1..10;
    println!("{:?}", a);
}
```

### Iterator

繰り返し処理が適用できるのはIteratorトレイとが実装されているため。

自作した型にもIteratorトレイトを適用すればforループで繰り返し処理ができる。

```jsx
// 自作の型を定義
struct Iter {
    current: usize,
    max: usize,
}

// 繰り返しょ処理の内容を定義
impl Iterator for Iter {
    type Item = usize; // 出力する型を紐付け

    // 次の要素に進む場合の処理next()を実装
    fn next(&mut self) -> Option<usize> {
        self.current += 1;
        if self.current < self.max {
            Some(self.current)
        } else {
            None
        }
    }
}

fn main() {
    let it = Iter {
        current: 0,
        max: 10,
    };
    for num in it {
        println!("{}", num);
    }
}
```

# パターンマッチング

## 値を見る場合

```jsx
fn main() {
    let i = 1;
    match i {
        1 => println!("one"),
        2 => println!("two"),
        _ => println!("other"),
    }
}
```

## 型を見る場合

enumを使う場合はenumの要素を網羅する必要がある

```jsx
// 型の場合
fn main() {
    enum Color {
        Red,
        Blue,
        Green,
    }
    let c = Color::Red;
    let _1 = Color::Blue;
    let _2 = Color::Green;
    match c {
        Color::Red => println!("red"),
        Color::Blue => println!("blue"),
        // Color::Green => println!("green"), // Greenをコメントアウト
        // _ => println!("other"), // otherもコメントアウト
    }
}
```

結果↓

```jsx
error[E0004]: non-exhaustive patterns: `Green` not covered
  --> src/main.rs:15:11
   |
7  | /     enum Color {
8  | |         Red,
9  | |         Blue,
10 | |         Green,
   | |         ----- not covered
11 | |     }
   | |_____- `Color` defined here
...
15 |       match c {
   |             ^ pattern `Green` not covered
   |
   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
   = note: the matched value is of type `Color`
```
Laravelの基礎知識のまとめ（コマンドなど）

※随時追加中


### ルーティング設定
以下のファイルにルルーティングを設定
```
routes/web.php
```
``` php
Route::get('item', 'App\Http\Controllers\HelloController@index');
```
ちなみにAPIの場合は以下に設定
```
routes/api.php
```
設定方法は同じだがルーティングが異なる
``` php
Route::get('hello', 'App\Http\Api\Controllers\HelloController@index'); //コントローラーに遷移
// ⇒http://localhost:8000/api/hello
```


### コントローラー作成コマンド
``` shell
$ php artisan make:controller コントローラー名
```
以下にファイルが作成される
app\Http\Controllers\作成したコントローラー


### モデル作成コマンド
``` shell
$ php artisan make:model モデル名
```
以下にファイルが作成される


### テンプレート
Bladeテンプレートを使用する
『resources』内の『view』フォルダの中に配置します。
例：index.blade.php


### DBの利用手続き
例としてローカルのxamppを利用する
config/database.php
``` php
    'default' => env('DB_CONNECTION', 'mysql'),

    'connections' => [

        // 省略

        'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', '作成したDB名'),
            'username' => env('DB_USERNAME', 'root'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],

        // 省略

    ],

```
Map<String, dynamic> data = document.data()! as Map<String, dynamic>;は何をしているのか

### わからなかったこと調べてみた

flutter大学の動画で勉強中に、
下記コードが何をしているのかわからなかったので自分なりに調べて考えてみたというお話。
```dart
Map<String, dynamic> data = document.data()! as Map<String, dynamic>;
```

### そもそもMap型って何??
「Map型とはkeyと呼ばれる値とvalueと呼ばれる値を紐付けて格納するオブジェクト。
keyは上記のコードで言うStringでありvalueはdynamicにあたる。」
とのこと。

```dart
void main() {
  Map<String, String> frameworks = {
 'Flutter' : 'Dart',
 'Rails' : 'Ruby',
};
  
  frameworks.addAll(
 {
   'Laravel' : 'PHP',
   'Bootstrap' : 'CSS',
 }
);
  
  print(frameworks.length); // 5
  
  frameworks.forEach((key, value) {
 print('$key --- $value');
});
}


```

### 左辺のお話
上記のコードのMapは右辺で得た情報をdataという変数に格納している。
さらに言うとkeyをString型にしvalueの部分をdynamic型にしている。

では右辺は何をしているのか。。。

### 右辺のお話

```dart
final List<Book> books = snapshot.docs.map((DocumentSnapshot document) {
		Map<String, dynamic> data = document.data()! as Map<String, dynamic>;
```

document変数にはfirebaseのドキュメントから得た情報が入っており、dataプロパティを使うことにより抽出している。

```
flutter: {title: マチネの終わりに, author: 平野啓一郎}
```

上記のprint結果のtitleとauthorの部分がkeyにあたり、
マチネの終わりに、平野啓一郎がvalueにあたる。
![スクリーンショット 2022-10-08 16.34.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1949840/48875427-2be1-351f-a125-051186ac78cc.png)

firebaseでフィールドを入力する際の「フィールド」がkeyにあたり、
「値」の部分がvalueになっているのだと思う。

document.data()!で取得したデータをasでMap<String,dynamic>として型変換している。
それを左辺のdata変数に格納しているのだと思う。

ちなみに！はnullじゃないよという意味。

以上！

### 最後に

初めて記事を投稿してみました。
ここの解釈違うよ、などなどございましたらご指摘いただけると幸いです。

最後までお読みになっていただきありがとうございました！

### 参考にしたサイト

https://zenn.dev/hatchout_school/articles/d6f8662d313f3a

https://blog.gogodiet.net/dart/ope/

https://qiita.com/takahi5/items/a07cc77f6f11c1bd973c
フリーのCT画像表示ソフトで良かったもの(備忘録)

# 概要
とある機会でCTデータを扱うことがあり，そのときいただいたファイル形式がDICOMファイルでした．
このDICOM形式は専用ビューワーが必要で，フリーのもので良かったものを備忘録的紹介します．
# SonicDICOM Media Viewer
https://ja.sonicdicom.com/downloads/

SonicDICOM PACSという統合ソフトのビューワーだけがフリーでDLできます．
もらったDICOMファイルを見る分には十分です．
2D表示のみ．
ローカルサーバを立ち上げてブラウザで見るタイプです．
# Aliza MS DICOM Viewer 
https://www.aliza-dicom-viewer.com/

こちらもAliza Medical Imaging & DICOM Viewerというソフトのビューワー版．
3D表示も対応しており，時間経過とともに撮影した画像をパラパラ漫画みたいに再生する機能もあります．
Laravel9で作成したアプリをAWSにデプロイする

# 前書き
今回は、作成したポートフォリオをAWS上に作成した本番環境にデプロイしてみました。

# 環境

https://qiita.com/ucan-lab/items/56c9dc3cf2e6762672f4

上記記事に準じて環境構築を行っています、


また、VPC・EC2インスタンス・RDSの作成については省略します。


# 実現したいこと
・AWS上にデプロイし、作成したアプリを公開

# 対応方法

## ①EC2インスタンスに各種インストール

○各種アップデート
```
sudo yum update -y
```

○webサーバーインストール→今回はnginx
```
sudo amazon-linux-extras enable nginx1
sudo yum install nginx -y
```

○phpインストール
→php8.1のインストールにはamazon-linux-extrasコマンドが使用不可
→eoel(Extra Packages for Enterprise Linux)を使用して導入する
```
# php8.1と関連するモジュールのインストール
sudo yum install php81 php81-php-mbstring php81-php-mysqlnd php81-php-gd php81-php-xml php81-php-fpm -y

# phpコマンドの変更
sudo alternatives --install /usr/bin/php php /usr/bin/php81 1

# インスタンス再起動で自動立ち上げ
sudo systemctl enable php81-php-fpm

```

○EC2インスタンスにMYSQLをインストール
```
sudo yum -y install mysql

# RDSへの接続確認
mysql -u ユーザー名 -p -h RDSのエンドポイント

```

○composerインストール

https://getcomposer.org/download/


## ②設定ファイル内容変更 php-fpmとnginx
○php-fpm設定変更
```
sudo vim /etc/opt/remi/php81/php-fpm.d/www.conf

# /etc/opt/remi/php81/php-fpm.d/www.conf記載を修正
user = nginx
group = nginx
listen = /var/opt/remi/php81/run/php-fpm/www.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660

```

○nginx設定変更（一部省略）
```
sudo vim /etc/nginx/conf.d/laravel.conf

server {
    listen 80 default_server;
    listen [::]:80;
    server_name hogehoge.com;
    root /var/www/src/public;
    
    ~~~
```

root の記載は publicディレクトリまでのルートをすべて記載する
今回の場合は、/var/www　ディレクトリを作成し、その直下に展開するため /var/www/src/public としています。

## ③リポジトリからgit clone

○gitインストール
```
sudo yum install git -y 
```
gitにSSH接続できるように公開鍵・秘密鍵の登録しておく

https://docs.github.com/ja/enterprise-server@3.3/authentication/connecting-to-github-with-ssh

```
ssh -T git@github.com

# 下記の通り帰ってくればSSH接続成功
> Hi username! You've successfully authenticated, but GitHub does not
> provide shell access.
```

○アプリ配置用のディレクトリ作成
```
sudo mkdir /var/www

# 作成した/var/wwwに移動
cd /var/www

# 書き込み権限付与
sudo chown ec2-user /var/www
```

○gitからアプリをclone
```
# .　をつけることで今いるディレクトリの直下に展開される
git clone git@github.com:「アカウント名」/「アプリ名」.git .
```

○Laravel初期設定
```
# Laravelをインストールするディレクトリに移動
cd /var/www/src

# Laravelインストール
composer install

# .envファイルがないため、コピーして本番環境用に変更する
cp .env.example .env
```

○.envファイルの修正(一部省略) 
```.env

APP_NAME=Laravel

#　本番環境なのでlocalから変更
APP_ENV=production 

# php artisan key:generate でセットする
APP_KEY=

#　falseだとエラー詳細が出なくなる、本番環境なのでtrueから変更
APP_DEBUG=false 

# アプリURLを記載
APP_URL=http://hogehoge.com


DB_CONNECTION=mysql
DB_HOST= 作成したRDSのエンドポイントを記載
DB_PORT=3306

# 作成したデータベース名を指定
DB_DATABASE=laravel

# RDS作成時のユーザー名
DB_USERNAME=hogehoge

# RDS作成時のパスワード
DB_PASSWORD=secret

~~~

```

○その他
```
# データベースのマイグレーション
php artisan migrate

# vue.jsを使っていたので表示させるために、node.jsインストールとコンパイル
curl -sL https://rpm.nodesource.com/setup_14.x | sudo bash -

sudo yum install -y nodejs

npm install

npm run dev

```


# 最後に
ALBを利用したhttps化の実装についても、後日まとめたいと思います。
学習中のため、記載内容に誤りがある場合はご指摘いただけると幸いです。


# 参考

https://qiita.com/shomffl/items/2b49f3d156a3d9cba82d

https://qiita.com/pi-ma/items/c757e97679f60ac75105

https://qiita.com/H-Toshi/items/cbaebbb75e92f7eae5b4