OmniAICreator/Qiita-1.07M huggingface dataset:
Go言語のモジュール実装

モジュールの実装方法と実装したモジュールを利用したmainモジュールを実行するところをできるだけ簡略化して紹介します。

## モジュール用の作成

### モジュール用のディレクトリを生成

```sh
mkdir greetings
cd greetings
```

### モジュールの初期化

[go mod init](https://go.dev/ref/mod#go-mod-init)コマンドで現在のディレクトリをルートとする新しいモジュールを初期化(go.modファイルを生成)します。
※go.modファイルはまだ存在していてはなりません。

```sh
go mod init example.com/greetings
# go: creating new go.mod: module example.com/greetings
```

### モジュールの実装

```go
package greetings

import "fmt"

// 大文字から始まる関数はpublic扱いになるので、Hello関数はimportしたモジュールから参照できます。
func Hello(name string) string {
    message := fmt.Sprintf("Hi, %v. Welcome!", name)
    return message
}
```

## mainモジュールの組み込み

### mainモジュール用のディレクトリを生成

```sh
mkdir hello
cd hello
```

### mainモジュールの初期化

[go mod init](https://go.dev/ref/mod#go-mod-init)コマンドを実行します。

```sh
go mod init example.com/hello
# go: creating new go.mod: module example.com/hello
```

### mainモジュールの実装

```go
package main

import (
    "fmt"

    "example.com/greetings" // 現時点でこんなパスのモジュールは存在しません。
)

func main() {
    message := greetings.Hello("Gladys")
    fmt.Println(message)
}
```

### ローカルに実装されたモジュールの参照

example.com/greetingsは公開されていないので、importされた時に、ローカルの../greetingsを参照するようにgo.modを書き換える[go mod edit](https://go.dev/ref/mod#go-work-edit)コマンドを実行します。

```sh
go mod edit -replace example.com/greetings=../greetings
```

### モジュールの依存関係の整理

[go mod tidy](https://go.dev/ref/mod#go-mod-tidy)を使ってgo.modファイルがモジュールのソースコードと一致することを確認、現在のモジュールと依存関係を構築するために必要な不足しているモジュールを追加、利用してないモジュールを削除、go.sumに不足しているエントリを追加と不要なエントリを削除します。

```sh
go mod tidy
# go: found example.com/greetings in example.com/greetings v0.0.0-00010101000000-000000000000
```

### 実行

```sh
go run .
```
Ruby 範囲オブジェクトの使い方

# はじめに
先日、範囲オブジェクトを教えていただいたので、使い方を自分なりに学習していこうと思います。

# 環境
ruby 2.6.5

# 範囲オブジェクトの概要

何らかの範囲を表すオブジェクトです。
例えば、
- 数値　　1~10
- 日付　　2022-3-1~2022-3-10
- 文字列　"a"~"z"
などを表すことができます。


Rangeクラス。

```.rb
range = 1..10
puts range.class
```

```ターミナル.
Range
```


# 範囲オブジェクトの書き方
```.rb
Range.new(1, 5) # 1 以上 5 以下
1..5            # 同上
1...5           # 1 以上 5 未満
```
数字部分に「nil」を用いることで、「以上」「以下」というオブジェクトを作成することもできます。

# 範囲オブジェクトの機能
### eachメソッド
範囲オブジェクトの最初から最後までの値を1つずつ取り出し、繰り返し処理を行うことができます。
```.rb
range = 1..10
range.each do |data|
  puts data
end
```
```ターミナル.
1
2
3
4
5
6
7
8
9
10
```

### .to_aメソッド 
範囲オブジェクトを配列に変換することができます。
```.rb
range = 1..10
puts "rangeのクラスと値"
puts range.class
puts range
array = range.to_a
puts "arrayのクラスと値"
puts array.class
puts array
```

```ターミナル.
rangeのクラスと値
Range
1..10
arrayのクラスと値
Array
1
2
3
4
5
6
7
8
9
10
```
変換系のメソッドは、他にも文字列や数値、ハッシュ型に変換するものがあります。

# おわりに
範囲オブジェクトには記載した他にも、最初の要素、最後の要素、最大値、最小値、要素数などを取得するメソッドがあります。
必要に応じて使用していきたいと思います。

# 参考
[公式リファレンス-classRange](https://docs.ruby-lang.org/ja/latest/class/Range.html)
[【Ruby】 to_aメソッドの使い方を理解しよう](https://pikawaka.com/ruby/to_a)
EventBridgeでDescribe*やList*アクションが処理できるようになりました


S3やDynamoDBへの攻撃を検知する一つの方法は、「どのようなデータを対象が持っているか」を攻撃者が知ることができるAPIの動向を確認することです。
例えば`ListBuckets`や`DescribeTable`といったAPIです。

というわけで該当APIが呼ばれたらEventBridge経由でなにかすることを考えました。

>Starting April 3. 2023, EventBridge will process all read-only management events. For more information, see Filtering management events from AWS services.

2023年から、Describeのような特定のキーワードで始まる参照系イベントもすべてEventBridgeで検知できるようになりました。
https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-service-event.html

## 以下は古い情報です

しかし、公式ドキュメントにある通り、`List*`, `Describe*`, `Get*`アクションは無視されます。
https://docs.aws.amazon.com/ja_jp/ja_jp/eventbridge/latest/userguide/eb-ct-api-tutorial.html

>CloudTrail 経由で送信されるイベントはすべて、detail-type の値が AWS API Call via CloudTrail になっています。キーワード List、Get、Describe で始まる API アクションからのイベントは EventBridge によって処理されませんが、以下の AWS STS アクションからのイベントを例外です。

EventBridgeの画面でもイベントパターンを作成する部分で警告がでます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37384/02675405-f970-6e03-20c0-3acdfe9d64b9.png)
[metamask/hardhat] Nonce too high の対処方法


```
  Errors encountered in param 1: Invalid value "0x-21f" supplied to : (QUANTITY | { blockNumber: QUANTITY } | { blockHash: DATA, requireCanonical: boolean | undefined } | "earliest" | "latest" | "pending")/0: QUANTITY, Invalid value "0x-21f" supplied to : (QUANTITY | { blockNumber: QUANTITY } | { blockHash: DATA, requireCanonical: boolean | undefined } | "earliest" | "latest" | "pending")/1: { blockNumber: QUANTITY }, Invalid value "0x-21f" supplied to : (QUANTITY | { blockNumber: QUANTITY } | { blockHash: DATA, requireCanonical: boolean | undefined } | "earliest" | "latest" | "pending")/2: { blockHash: DATA, requireCanonical: boolean | undefined }, Invalid value "0x-21f" supplied to : (QUANTITY | { blockNumber: QUANTITY } | { blockHash: DATA, requireCanonical: boolean | undefined } | "earliest" | "latest" | "pending")/3: "earliest" | "latest" | "pending"

とか

Nonce too high

が出てくるときの対処方法
```

ここで解説されている通り、対象のアカウントのリセットを行う。
- [Solved! “Nonce too high” error with MetaMask and Hardhat - Jake Warren - Medium](https://medium.com/@thelasthash/solved-nonce-too-high-error-with-metamask-and-hardhat-adc66f092cd)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68103/94cb6a3c-94ee-3e1a-7d4a-e34764158ba8.png)
JavaのAPIについてまとめてみた

JavaのAPIについて調べたのでまとめてみます。
そして、今回はその中でもメジャーなものだけを出していきます。


Mathクラスは、様々な計算をするためのメソッドを提供します。

## powメソッド

累乗の値を求める時にやります。
積立の値を求めたい時に使えます。

##やり方(powメソッド)

```
pow(数値, 累乗の値);
```

なので、「2の2乗」を表したいときは

```
pow(2, 2);
```

と書きます。
## sqrtメソッド

Mathクラスの平方根の値を求める、つまり素因数分解をしたい時に使うことができるメソッドです。

## やり方(sqrtメソッド)

```
sqrt(求めたい数字);
```

とすると、結果を求めることができます。


## compareToメソッド

compareTo()メソッドは、比べられる変数とこのメソッドの引数として指定された値のどちらかが大きいかを指定します。

戻り値として

```
−１
０
１
```

があります。
これは、引数として指定された値より大きい場合は１を、同じ場合は0を、小さい場合は-1を指定します。

なので、

```Main.java
class Main {
    public static void main(String[] args) {
        Integer a = 20;
        System.out.println(a.compareTo(30));
    }
}
```

となった場合、戻り値は-1となります。これは、引数として指定されている値よりも、変数として指定されている変数aのほうが小さいからです。

## compareメソッド

compare()メソッドは、第一引数と第二引数の間で比べた時にどちらが大きいかを比較します。
その時に基準としているのは第一引数の値が基準になって戻り値が決定します。

### やり方(compareメソッド)

```Main.java
class Main {
    public static void main(String[] args) {
        // a = 1, b = 2で、aがbより小さいなら「-1」
        System.out.println(Integer.compare(1, 2));
    }
}
```

このようにして、compare()の引数に値を入れれば判定をする処理が走ります。

## sort()メソッド

コレクションの中の要素を、順番に並べ替えるためのメソッドです。
これを使うことで、コレクションの中の最大値を先頭にすることもできます。

ソートするときは、普通自然順という小さいものから先に並べるのがJavaのデフォルトの動きです。
しかし、それをもし逆にしてsortしたい場合は、引数a.sort(引数b, 引数c)の引数aにマイナス(-)を入れることで、逆順でソートできます。

## isAlphabeticメソッド

引数でもらった値がアルファベットかどうかを判定するメソッドです。

## isDigitメソッド

これは、引数で受け取った値が数字かどうかを判定するメソッドです

## isLowerCaseメソッド

これは、引数で受け取った値が小文字であるかどうかを調べるためのメソッドです。
モデルは業務仕切りか実体仕切りか

# モデル化の２つの方法
システム開発の上流で行う*モデル化*で、皆さんは仕切りをどこにしていますか？

### 業務仕切りの例
　受付業務の中に次の実体を包含する
　　ガス実体
　　電気実体
　　通信実体
　サポート業務の中に次の実体を包含する
　　ガス実体
　　電気実体
　　通信実体
　運用業務の中に次の実体を包含する
　　ガス実体
　　電気実体
　　通信実体
### 実体仕切りの例
　ガス実体の中に次の業務を包含する
　　受付業務
　　サポート業務
　　運用業務
　電気実体の中に次の業務を包含する
　　受付業務
　　サポート業務
　　運用業務
　通信実体の中に次の業務を包含する
　　受付業務
　　サポート業務
　　運用業務

### 実体の中身
　実体は「データ」と「処理」で構成されますが、データ自体は業務ごとに異なるものではないため
　業務仕切りの場合は、「データ」が業務ごとに重複します。
　反対に実体仕切りの場合は、実体ごとに業務内容は異なるので、重複にはなりません。

### 実体と業務の普遍性
　データは業務に比べて変化が小さく、業務によって扱い方は変わりますが、本質的な部分はほとんど変化しません。
　業務仕切りの場合は、業務ごとにほぼ同じデータが重複することになります。
　実体仕切りの場合は、実体ごとに扱い方が異なるため、各業務の間の共通性は業務仕切りより小さくなります。

### 優位性
　業務は社会の変化に影響されやすく不安定です。
　不安定な要素を主とする業務仕切りのモデルは不安定なうえにほぼ同じ実体が重複する非効率なモデルになります。
　その点、実体仕切りは、データを主とするので、本質がベースで変化が小さく、かつ、実体ごとに実体に合わせた異なる業務で構成するので、重複がなくなります。

### 実体仕切りの本質
　実体を「主」に、業務を「従」とするこのモデルの本質はデータ中心指向やオブジェクト指向に準じたものになり、そのメリットを享受できます。
Laravel：二度とリレーションの書き方を間違えない

こんにちは。Laravelのリレーション毎回間違えるマンです。

sqlのjoinと同様に結合元のテーブルのキーを毎回左側に書いてしまう癖があります。
*[注意]joinは特に順番は決まってないが一般的に結合元テーブルを左側に書くことが多い気がする。

```User.php ❌
class User extends Model
{
    public function posts()
    {
        return $this->hasMany(Post::class, 'id', 'user_id');
    }

    // こんな書き方をする時もある。
    public function posts()
    {
        return $this->hasMany('App\Models\Post', 'id', 'user_id');
    }
}
```

これらはエラーとなります。ひっくり返せば治るので深く考えたことがなかったのですが、たまたま見た記事に答えが書いてあったので、忘備録として本記事を書きます。
🔽分かりやすい記事
https://qiita.com/saya1001kirinn/items/69e2146691101f92d57b

引用の引用ですがこれが真理
>常に第2引数が Foreign Key で，第3引数が Local Key です。

先ほどの例で言うと
Foreign Key: user_id
Local Key: id
となるので、こうなる。

```User.php
class User extends Model
{
    public function posts()
    {
        return $this->hasMany(Post::class, 'user_id', 'id');
    }
}
```

belongsToも同様に外部キー、ローカルキーの順番

```Post.php
class Post extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class, 'user_id', 'id');
    }
}
```

リーダブルにも書いてあったのです。ちゃんと読もう。自戒。
https://readouble.com/laravel/7.x/ja/eloquent-relationships.html

## ちなみに中間テーブル作ってbelongsToManyする場合
これは当初勘違いしてたsqlのjoinと同じ考え方でいける
第一引数：結合先モデル
第二引数：中間テーブル名
第三引数：中間テーブル・呼び出し元の外部キー
第四引数：中間テーブル・呼び出され側の外部キー
>第３引数はリレーションを定義しているモデルの外部キー名で、一方の第４引数には結合するモデルの外部キー名を渡します。

UserとPostの中間テーブルtagsを想定

```User.php
class User extends Model
{
    public function posts()
    {
        return $this->belongsToMany(Post::class, 'tags', 'user_id', 'post_id');
    }
}
```

```Post.php
class Post extends Model
{
    public function users()
    {
        return $this->belongsToMany(User::class, 'tags', 'post_id', 'user_id');
    }
}
```
ECSでGPUを使うタスクを実行する方法

## 経緯
自分がAWS初心者ということもあり、ECSでGPUを使うタスクを実行するまでに、いくつか詰まるところがあったので共有します。

## やりたいこと
自分がやりたかったことは、下の画像のような流れを作ることです。画像データがS3にアップロードされたタイミングで、LambdaがECSの機械学習関連のタスクを実行して、処理の結果をs3にアップロードするというものです。
![aws_arch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663246/c87ea61e-8bbb-9e17-4038-ac10d2959d0c.png)
今回は、画像の赤枠で囲まれた、ECSでGPUを使うタスクを実行する方法を説明します。

## 手順
以下の手順では、起動タイプがEC2のECSのタスクのやり方です。[こちら](https://github.com/aws/containers-roadmap/issues/88)のやりとりを見てみたところ、現時点では**FargateはGPUサポートされていない**みたいです。

### 1. GPU対応AMIの選択
今回は、amzn2-ami-ecs-gpu-hvm-2.0.20220209-x86_64-ebsというGPU対応のAMIを使用しました。
**なるべく新しいバージョンのAMIを使用してください。**
古いAMIだと、コンテナエージェントのバージョンが低く、タスクの実行時に[ATTRIBUTEエラー](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/api_failures_messages.html)が発生する場合があります。

### 2. インスタンス作成
インスタンスを作成する際に、注意する点は以下の3つです。
- [公式](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ecs-gpu.html)通り、GPU対応のp2、p3、g3、g4インスタンスのいずれかをインスタンスタイプとして選択してください。
- IAMロールにecsInstanceRoleを選択してください。ロールの作成方法は[こちら](https://docs.aws.amazon.com/ja_jp/batch/latest/userguide/instance_IAM_role.html)。
![qiita1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663246/437a934e-6e5b-dc5c-0a2e-8162e5040ce8.png)

- ユーザーデータに以下の行を追加してください。
cluster-nameには、紐づけたいクラスター名を入れてください。
```
#!/bin/bash
echo ECS_CLUSTER=cluster-name >> /etc/ecs/ecs.config
```
![qiita2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663246/5e6640ef-3fcf-4609-eb40-9826a3568e26.png)

### 3. クラスターを作成
クラスターは前の手順でのクラスター名で作成してください。

### 4. タスク定義
起動タイプにはEC2を選択し、タスクとコンテナの定義の設定を行います。
コンテナの定義の**コンテナの追加**ボタンを押し、タスクで動かすコンテナイメージを設定します。
![qiita4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663246/383f4b88-0f0c-1d81-bafb-e430230e1acd.png)
[環境]->[GPU]の項目で、タスクに使うGPU数を入力してください。インスタンスタイプのGPU数を超えない数で設定します。
![qiita3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663246/0983d75b-8d14-057a-f1ba-fb453e205a10.png)
GPU数の選択をしないと、タスクでGPUを使用できないのですが、新しいAWSのUIでは、GPU数の選択の項目が見つけられませんでした。なので、古いUIで設定することをおすすめします。

## まとめ
設定は以上です。あとは、インスタンス起動してタスク実行してみてください。
AWSの日本語の説明、時々わけわからん(笑)。

## 参考文献
- [AWSのECSでGPUを使う方法](https://qiita.com/yujikawa/items/a734a9767ee2ec0d4709)
- [ECS GPU-optimized AMIでECSを構築する](https://blog.jicoman.info/2020/06/ecs-cluster-with-ec2-gpu-optimized-ami/)
Pythonに++や--は使えない。

タイトルのまんまです。

pythonには他の言語でインクリメント、ディクリメント時によくみられる`++`, `--`が使えません。
代わりに`+=1`, `-=1`を使いましょう。

```python
n++ #エラー
n-- #エラー

n+=1
n-=1
```
LMDB With Dupsort

# 背景
データの読み書き速度を求める場合、Key-ValueデータベースのLMDB　([Lightning Memory-Mapped Database](https://lmdb.readthedocs.io/en/release/ "LMDB")) を使うことはよくあります。Key-Valueデータベースは、データをKeyとValueのペアのコレクションとして格納します。Keyは識別子として、単一のKeyに対して複数のデータアイテムをサポートできます。

# キーの重複
Key-ValueデータベースのKeyがユニークな存在だと思っている方が多いかもしれませんが、実は、LMDBはDupsortモードにて重複キーもサポートしています。

###### Dupsort = Flase
| Key | Value |
|:-----------:|:------------:|
| K1       | Data1,Data2,Data3        |
| K2       | Data4,Data5,Data6        |

###### Dupsort = True
| Key | Value |
|:-----------:|:------------:|
| K1       | Data1        |
| K1       | Data2       |
| K1       | Data3        |
| K2       | Data4       |
| K2       | Data5       |
| K2       | Data6        |

# パフォーマンス
大きいデータセットを１つのキーに纏めて保存すると、サイズが大きければ大きいほど、読み書きの時間曲線が宇宙に飛んでいきます。
この場合、Dupsortを使えば、かなり改善できます。

# 関連API
```
open_db(key=None, txn=None, reverse_key=False, dupsort=False, create=True, integerkey=False, integerdup=False, dupfixed=False)
dupsort:
 Duplicate keys may be used in the database. (Or, from another perspective, keys may have multiple data items, stored in sorted order.) By default keys must be unique and may have only a single data item.
```
```
getmulti(keys, dupdata=False, dupfixed_bytes=None, keyfixed=False)
dupdata:
 If True and database was opened with dupsort=True, read all duplicate values for each matching key.
dupfixed_bytes:
 If database was opened with dupsort=True and dupfixed=True, accepts the size of each value, in bytes, and applies an optimization reducing the number of database lookups.
```
```
putmulti(items, dupdata=True, overwrite=True, append=False)
dupdata:
 If True and database was opened with dupsort=True, add pair as a duplicate if the given key already exists. Otherwise overwrite any existing matching key.
```
金属部品の品質不良を検出 with Teachable Machine

<p class="codepen" data-height="600" data-default-tab="result" data-slug-hash="dyZwPEe" data-user="04" style="height: 600px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/04/pen/dyZwPEe">
  Quality Defect Checker</a> by John Doe (<a href="https://codepen.io/04">@04</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

下記の記事をJavaScriptで動くようにしてみました！

https://qiita.com/naruto63/items/ce9a8c2ecd68b22477a2

### 作り方

#### 標準の画像モデルを選択

工場で動かすときは右のモデル

https://teachablemachine.withgoogle.com/train

![Screenshot from 2022-03-02 22-41-57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/c6e303e1-30b1-73e7-f343-fbcc6653c47e.png)


#### 画像をアップしトレーニング

画像をアップしてトレーニング開始！
トレーニングに2分ほどかかります

![Screenshot from 2022-03-02 22-07-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/caaa25bf-b9ae-6b52-8200-c7070cb3cc2f.png)

#### 精度を確認

精度や混合行列を確認

![Screenshot from 2022-03-02 22-13-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/f3968387-1cd4-86bc-6ef8-20fcd2e0ce0a.png)

#### モデルをエスクポート

右上のモデルをエクスポートからモデルをアップロードをクリック

![Screenshot from 2022-03-02 22-13-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/7b1b94dc-f57a-5c31-bc21-736967ff9877.png)

アップロード中...
![Screenshot from 2022-03-02 22-14-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/a20f3b40-c3e2-7a76-64fc-adfd0596ce9b.png)

#### HTMLをコピしてcodepenなどに貼り付け

![Screenshot from 2022-03-02 22-34-39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/f87ded03-ffe4-ec08-6cc9-767262b83444.png)
JSONが正しい文法なのにJSON.parseできない

JSONの文法と、PHPの文法（今回あまり関係ない）と、JavaScriptの文法と、HTMLの文法とでごちゃごちゃに怒られたのでどの部分が明確な原因かわかっていないけど順番にメモする。

## はじめに

APIから吐き出されたJSONをPHPで取得し、それをJavaScriptで加工・処理してHTML上に表示するという組込み作業の過程で、文法チェッカーなどでもJSONの構造に問題はなさそうなのに、JSON.parseがエラーになる。

https://qiita.com/nc30mtd/items/8fbdda2be3601585f08e

検索すると上のような記事が出る。console.logに表示されないが特殊文字がエラーの原因になってるよという話。
上記のコードで対策してみたがそうするとJSON内の改行コードも漏れなく消え失せてしまったので、ちょっと本意でない。HTML上で表示する観点から改行コードには消えてもらうのではなく、最終的に改行タグになってもらう必要がある。別の方法を考える。
（いま思うと二つ目のメソッドから書き始めたせいかもしれない。なんでそんなことしたんだろう）

APIから吐き出されるJSONについても別サーバー上のPHPで自前で整形しているので、その時点から調整できそうだ。

## json_encode()のオプション
https://www.php.net/manual/ja/function.json-encode.php
https://www.php.net/manual/ja/json.constants.php

APIのJSON出力前にjson_encode()を通しているが、その時にオプションをつけると適宜エスケープを調整できる！関係あるか？

```api-変更前.php
echo json_encode($list,JSON_UNESCAPED_UNICODE);
```

```api-変更後.php
echo json_encode($list,JSON_UNESCAPED_UNICODE | JSON_HEX_QUOT | JSON_HEX_APOS);
```
↓
JavaScriptでパースエラーになった。なんで？？？
↓
渡ってきたJSONを受け取り側のPHPで処理するところまでは良いものの、その後JavaScriptに受け渡す際は文字列として扱うことになる。その際、例えばダブルクォーテーションがエスケープされていても、「\u0022」も「"」も文字列であることに変わりはないため、JavaScriptの文法で「そこが文字列の終わり」と見なされてしまうらしい。
（いま思うとJSONデータにこの時点で新たに"を追加して検証していたので、先程と異なる理由でエラーが出ていた可能性アリ）
これに関する記事も見つけたけど見失いました。

JSON自体のエスケープ不足にくわえ、JSONの中身がJavaScript上の文法のエラーにひっかかって先に進めない問題も出てきた。わからん。

見かけた記事の対策に、JavaScript側でJavaScript用のエスケープ処理を行うことが挙げられていたが、二度手間になりそうなのでなんとかPHP側でうまい事できないか。

## replace()
PHP側かつJavaScriptで文法エラーにならないエスケープ処理として、文字参照に変換することにした。

```replace.php
  $es_val = str_replace('\\', '&bsol;', $es_val);
  $es_val = str_replace('"', '&quote', $es_val);
```

こんな風に地道にやっていたけどそういえばもう少し使いやすい関数があることを途中で思い出した。

## htmlspecialcharsとnl2br
htmlspecialcharsは「& (アンパサンド)、" (ダブルクォート)、' (シングルクォート）、< (小なり)、>(大なり)」をエンティティ参照に変換する関数。
nl2brはあらゆる改行コードの手前に改行タグを挿入する関数（そのためその後改行コードを置換削除する必要がある）。

```escape.php
function escape($es_val){
  $es_val = htmlspecialchars($es_val);
  $es_val = nl2br($es_val);
  $es_val = str_replace(array("\r\n", "\r", "\n"), '', $es_val);
  $es_val = str_replace('\\', '&bsol;', $es_val);
  return $es_val;
}
escape($value);
```

あんまり分かっていなかったが、結果的にJSON内の特殊文字を削除することでパースエラーの生じないJSONを生成できたらしい。
単にエスケープして残すよりも、文字参照に変換したり削除したりしたほうがHTML上で取り回しの効くデータになったかも。

## 余談
### Vue.jsとの併用

Vue.js内のデータにタグが含まれていても自動的に無効化され、そのままマスタッシュで出力しようとすると、タグが文字列で出力されてしまう。
v-htmlで出力する必要アリ。
文字参照（&で始まる特殊文字）もマスタッシュではそのまま出力されるので、同じくv-htmlを使う必要がある。
ちょっと難点。

### JSONでエスケープすべき特殊文字

https://shinkufencer.hateblo.jp/entry/2018/08/03/235900
>『"(ダブルコーテーション)』
『\(バックスラッシュ)』
『/(スラッシュ)』
『\b(バックスペース)』
『\f(改ページ)』
『\n(改行)』
『\r(キャリッジリターン)』
『\t(タブ)』

らしい。
ただ今回のJSONはフォーム入力によって生成されたテーブルデータを元に出力・整形する代物なので、バックスペース、改ページ、タブは含まれないだろうと判断した。
そのためダブルコーテーション、バックスラッシュ、改行、キャリッジリターンをエスケープする必要があった。
なおスラッシュに関してはエスケープなしで問題なかった。なんでかわからん。
JavaScript学習 - 準備と文字列

## JavaScript 基礎
JavaScript学習のアウトプット、兼自分用メモとして作成しました。
今回はファイルの準備、反映メインについて書いています。
(記事が溜まってきたら、関連記事リンク設置しようと思います。)

:::note warn
**目次**
[01_ファイルの準備](#01_ファイルの準備)
[02_作成と確認](#02_作成と確認)
[03_文字列について](#03_文字列について)
[次回の予定](#次回の予定)
:::

## 01_ファイルの準備
__<font color="red">別ファイルからの読み込みを前提としたものになります。</font>__
作成するもの
・htmlファイル　　　 ：index.html
・JavaScriptファイル：js/main.js
※フォルダ名「js」の配下にmain.jsを作成すること

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>JavaScript基礎文法</title>
</head>

<body>
  <script src="js/main.js"></script>
</body>
</html>
```

`<body>`タグ内で`<script>`タグを使って上記のようにmain.jsを読み込ませます。
(ディレクトリの記述を間違えると、読み込めないので注意。)

## 02_作成と確認
JavaScriptがちゃんと読み込めているか、確認を行います。
まず、以下の内容をjs/main.jsに記述します。
```JavaScript:js/main.js
'use strict';

console.log('反映テストです。');
```
`'use scrict'`は、エラーチェックをするためのもので、書いておくとエラーが確認しやすくなります。

`;(セミコロン)`は命令の終わりに、忘れずに書くようにしましょう。

記述できたら、ブラウザに**index.html**を反映し、
検証 → console で反映を確認します。
以下のように確認できたら、完了です。
|![スクリーンショット 2022-02-28 22.53.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1142450/db990970-e469-552c-2420-35f5d9ec1214.png)|
|:-:|


## 03_文字列について
上の`02_作成と確認`で、文字を反映させました。
JavaScriptで文字を反映させる場合、
**・シングルクォーテーション ('')**
**・ダブルクォーテーション (" ")**
のどちらかを使用します。
どちらかを使用します、とは言っても、記述する文字列によって使い分ける必要があります。

例えば、`I don't know.`など文中でシングル区ウォーテーションが使われている場合、
文字列を囲っているシングルクウォーテーションの最後と認識されてしまうので、
この場合はダブルクウォーテーションを使って記述します。
```JavaScript:js/main.js
'use strict';

console.log("I don't know.");
```
それか、\（バックスラッシュ）という記号を使って、以下のように記述すると良いでしょう。
```JavaScript:js/main.js
'use strict';
console.log("I don't know.");
console.log('I don\'t know.');
```

cosnoleを確認してみると、どちらも表示されています。
|![スクリーンショット 2022-03-02 22.34.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1142450/74514718-9a76-062b-ce05-098ae172fb76.png)|
|:-:|

文字列がちゃんと表示されない、という場合
文字列として認識される記述になっているか、予め確認しておくと良いですね。

## 次回の予定
次は計算関連の記事を作成しようかと思っています。
(未だに > とか < の使い方で混乱しているので・・・)
mod_wsgiをpipでインストール

## はじめに
flaskをapacheで動かしたいと思ったのですが、
mod_wsgiのインストールに手間取ったのでメモ。

## 本題
「適切なバージョンのwhlファイルをダウンロードしてインストールする」
という情報が多かったですが、自分の環境に合ったwhlファイルが無かったので、
pipでインストールできないか試してみました。
```
pip install mod_wsgi
```
<br>

エラー
`RuntimeError: No Apache installation can be found. Set the MOD_WSGI_APACHE_ROOTDIR environment to its location.`
Apacheのインストールが見当たりません。
MOD_WSGI_APACHE_ROOTDIRに場所を設定してください。との事。

```
set "MOD_WSGI_APACHE_ROOTDIR=C:\xampp\apache"
```
でapacheの場所を設定します。
<br>
もう一度インストール。
```
pip install mod_wsgi
```
またエラー
`error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": https://visualstudio.microsoft.com/downloads/`
Microsoft Visual C++ 14.0 が必要です。
Microsoft Visual C++ Build Tools "で入手してください。との事

下記などからダウンロードしてインストールします。
https://visualstudio.microsoft.com/ja/downloads/
<br>
もう一度インストール。
```
pip install mod_wsgi
```
これでインストール完了です。
ありがとうございます。
Result型のfilter_map時にハマった

## 環境
- rust 1.58.1

## やりたかったこと
`Vec<Result<Hoge>>`型があったとして(Hogeは適当なstruct)、Hogeだけ取得したかった。  
以下ではHogeはStringにしています。
```rust
// こんなデータがあるとして
let v: Vec<String> = vec!["1".to_string(),"2".to_string(),"3".to_string()];
let string_results = v.into_iter()
    .map(|x| Ok(x))
    .collect::<Vec<Result<String, String>>>();

// Vec<Result<String, String>> からVec<String>をつくりたい！

```
## ハマったこと
```rust
let v: Vec<String> = vec!["1".to_string(),"2".to_string(),"3".to_string()];
let string_results = v.into_iter()
    .map(|x| Ok(x))
    .collect::<Vec<Result<String, String>>>();

// これでいけんじゃね？
let inners: Vec<String> = string_results.iter().filter_map(|x| x.ok()).collect();
```
↓
```
cannot move out of `*x` which is behind a shared reference
move occurs because `*x` has type `Result<String, String>`, which does not implement the `Copy` traitrustcE0507
main.rs(25, 61): consider borrowing the `Result`'s content: `.as_ref()`
```
というエラーになってしまってうまくいかない。ok()はselfを消費するからっぽい。

## 解決方法1
所有権を使ってよいなら、into_iter()を使えば大丈夫
```rust
// Vec<Result<String, String>> からVec<String>をつくりたい！
// iter -> into_iterに変更
let inners: Vec<String> = string_results.into_iter().filter_map(|x| x.ok()).collect();
```
ただし、これだと`string_results`の所有権が消費されてしまうため、string_resultsをもう使えなくなってしまう。

## 解決方法2
所有権を消費せずにこれを行うには、上にメッセージででてた`as_ref()`を使う
```rust
// Vec<Result<String, String>> からVec<String>をつくりたい！
// as_ref().ok()にして、中身を参照型で取り出す
let inners: Vec<String> = string_results.iter().filter_map(|x| x.as_ref().ok())
                                   // .map(|x| x.clone()) // 実態にするのは別mapで
                                   .cloned() // 2022-03-06: benki様からご教示いただき、clonedに修正しました。
                                   .collect();
```

## 備考
- なんかもっときれいな方法とかスッキリやる方法あるのではないかという気がする。。
名前について考えたこと

殴り書きでスマソ。

変数の構成要素
* 単語
* 変形(単数形・複数形、過去形・現在形、比較級・最上級など)
* 順番

任意に変化させた単語を特定の順序で並べたもの = 名前

# 単語
単語には動詞、助詞、名詞、形容詞、接続詞、前置詞、副詞がある。

さらに動詞には他動詞、自動詞があり
自動詞には目的語がない。
他動詞は目的語を取り目的語がそのまま名前に使われるか引数になる。

助詞はcanもしくはshouldなどがありできる？やすべき？などのニュアンスを表せる。

副詞は動詞を、形容詞は名詞を修飾する。

基本的にはメソッドはレシーバに対する命令と考えられる。
オブジェクトに対する命令形式であるほうがよい？

副詞に関してはHowを意味づけることが多い?
recursively,safety,once,strict
ただonceやrecursive感覚的にはわかるがsafeと書かれてもどう安全なのかがわからないからそこを補足するかもしくわ使わないほうがいいのか?

基本は関数は動詞、助詞から始まり、変数名などは名詞で終わる。

オブジェクト操作に関してはコマンド、関数、照会形式がある
コマンド(戻り値なしで副作用を生む操作)
関数(戻り値ありで副作用なしの操作)動詞から始める
照会(値を取得するだけ)これは動詞から初めてはいけない

後はさらに分けると引数のオブジェクトに対してコマンドを実行して自身には変化なしで戻り値のないメソッドもあるがそもそもこういうのはよくないのか？。

amount　量数　不可分、不可算なもの　水とか
count　回数　単位が回　クリック回数
number　個数　単位が個　りんごの個数

値のバリエーションを考える必要がある。
postjson がコントローラ内にあったとする、リクエストのボディなの？レスポンスにつかうのというのが一目でわからない気がする。あと他のメソッドのときに意味がわからん。putjson?あとputの過去分詞がputなので受動態にできん。2つの問題がある。あとloginpostjsonはログイン情報をポストするのか、ログインにポストするのかわからん。ログインならいいが他のリソースになると困る?
lginiofoもあるが割れ窓の法則があるので使いたくない。
Login, UserCreate, UserDestroy, UserUpdate(User creationの語順)
Get, Post, Put, Delete
Param, Info, Profile, Args, Request, Json
LoginParameter,UserCreateParameterにする。

helper utilsとの違いはそれがアプリケーションドメインの問題を解決できること。インスタンス化できること
utils 静的メソッドなどで実行しステートなどがあってはいけない。またプロジェクトに依存しない汎用的なものでなければならない。(オブジェクト指向においてあんまり使わんほうがいいかもしれん。使うなら安定した既存ライブラリに限るようにしたいMath.Maxなど)
common 知らん
helper,utils,commonはどれも使わんほうがいいというのも馬鹿が脳死で共通処理を突っ込んでしまう可能性があるから。基本的にはこれらは外部ライブラリとしては問題ないかも知れんが自分で開発するものに入れるのはよくない気がする。

外部リソースにアクセス以外でデータを取得することはあまりしないで引数などでもらうようにする。
入出力はできるだけプリミティブにしnullより既定値を返す。文字や文字列なら空文字を返すとか。
変更できるデータに関しては抽象化が崩れない程度に外に出す。
RustでVecのCloneをする

## 環境
- rust 1.58.1 
## やりたかったこと
`vec`のCloneをしたかった。
## 答え
```rust
let v = vec!["1".to_string(),"2".to_string(),"3".to_string()]; // こんなvecがあったとして
let v2 = v.to_vec(); // これでできる

// 自前structの場合もCloneをつけておけば
#[derive(Debug, Clone)]
struct S1(Result<String, String>);;

let ss1 = v.into_iter()
        .map(|x| S1(Ok(x.to_string())))
        .collect::<Vec<S1>>();
let ss2 = ss1.to_vec(); // こんな感じでCloneできます
```
## 備考
- いろんな方法があるかとは思うが、これが一番簡単そうだった
- 探し当てるのに少し時間かかったのでメモ
ユーザーのホームディレクトリを変更したら Docker Desktop for Mac が起動しなくなった件

## 概要
Mac のホームディレクトリを変更したら Docker Desktop for Mac がぶっ壊れたので、
私のように悩んでしまう方を減らすべく、その原因と解消方法を記事に残します。

### 使用環境
- MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)
- macOS Big Sur 11.5.2

### 前提
- ホームディレクトリ名は以下とします

```
変更前：/Users/name_A
変更後：/Users/name_B
```

- `/User/name_A` で Docker Desktop for Mac をインストール済み

## 結論 (原因)
後述する Docker 設定ファイル (settings.json) に旧ホームディレクトリ名がハードコーディングされていた

## 再現手順
1. [システム環境設定] -> [ユーザーとグループ] を選択
1. Docker Desktop for Mac がインストール済みのユーザーを右クリックし [詳細オプション] を選択
1. ホームディレクトリ名を変更
![change-home-directory-name.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347034/b73ffd10-2ab4-7d93-b51a-e18b272d15d5.png)
1. Mac 再起動
1. 手順 2 のユーザーにログイン
1. Docker Desktop for Mac を起動

## 発生した事象
Docker Desktop for Mac を開こうとすると Fatal Error (以下) が出て一向に起動しない
![docker-desktop-error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347034/ece4d95d-13ac-c4b4-e61d-3c296ea55bff.png)

## 事象発生時に試したこと
- [Reset to factory defaults] の実行 -> そもそも実行が出来ず、不発
- Docker Desktop for Mac の再インストール -> 解決せず
- Docker 関連ファイル (以下) を削除後、再インストール -> 解決せず

```zsh
sudo rm -rf /Library/PrivilegedHelperTools/com.docker.vmnetd
sudo rm -rf /Library/LaunchDaemons/com.docker.vmnetd.plist
sudo rm -rf ~/.docker
sudo rm -rf ~/Library/Containers/com.docker.docker
sudo rm -rf ~/Library/Application Support/Docker Desktop
sudo rm -rf ~/Library/Preferences/com.docker.docker.plist
sudo rm -rf ~/Library/Saved Application State/com.electron.docker-frontend.savedState
sudo rm -rf ~/Library/Group Containers/group.com.docker
sudo rm -rf ~/Library/Logs/Docker Desktop
sudo rm -rf ~/Library/Preferences/com.electron.docker-frontend.plist
sudo rm -rf ~/Library/Cookies/com.docker.docker.binarycookies
```

## 解消方法
- `~/Library/Group\ Containers/group.com.docker/settings.json` の編集

```json
// 変更前
"dataFolder": "/Users/name_A/Library/Containers/com.docker.docker/Data/vms/0/data"

// 変更後
"dataFolder": "/Users/name_B/Library/Containers/com.docker.docker/Data/vms/0/data"
```

- settings.json 編集後 Docker Desktop for Mac を起動

![スクリーンショット 2022-02-28 22.12.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347034/2e2834ca-35fe-445b-fd4d-a67fc6b3c3db.png)

無事に起動できました！！

## 参考記事
タイムリーに `docker / for-mac` の issue にあがっていたので、助かりました。

https://github.com/docker/for-mac/issues/6201
golang-migrateチュートリアル(migration編)

#初めに
　golang-migrateのチュートリアルです。

#環境
PC：Mac(CPUはintel製)
Go：1.17.6 ←Goのver大事。versionは1.16以降をインストールしてください。
開発エディタ：Visual Studio Code

#ディレクトリ構成
```shell:ディレクトリ構成
~/go/src/test $ tree
.
├── db
│   └── migrations
│       ├── 000001_create_users_table.down.sql
│       └── 000001_create_users_table.up.sql
├── docker-compose.yml
└── go.mod
2 directories, 4 files
```

#go-migrateのインストール
```shell:golang-migrateのインストール
brew install golang-migrate
```

#事前準備
①DB用意
postgressを用意し、exampleという名のDBを作成する。
②環境依存情報を設定しておく
```shell:環境依存情報の設定
export POSTGRESQL_URL='postgres://postgres:postgres@localhost:5432/example?sslmode=disable'
```

#マイグレーションファイルの作成
```shell:ディレクトリの準備
~/go/src/test $ tree
.
├── db
│   └── migrations
├── docker-compose.yml
└── go.mod

2 directories, 2 files
```

```yml:docker-compose.yml
version: '3.1'

services:
  postgres:
    container_name: postgres
    image: postgres:13
    ports:
      - 5432:5432
    volumes:
      - ./.data/postgres:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
```

```shell:コマンド実行
~/go/src/test $ migrate create -ext sql -dir db/migrations -seq create_users_table
/Users/kawamurakouji/go/src/test/db/migrations/000001_create_users_table.up.sql
/Users/kawamurakouji/go/src/test/db/migrations/000001_create_users_table.down.sql
```

```sql:createファイルの編集(000001_create_users_table.down.sql)
CREATE TABLE IF NOT EXISTS users(
   user_id serial PRIMARY KEY,
   username VARCHAR (50) UNIQUE NOT NULL,
   password VARCHAR (50) NOT NULL,
   email VARCHAR (300) UNIQUE NOT NULL
);
```
```sql:downファイルの編集(000001_create_users_table.down.sql)
DROP TABLE IF EXISTS users;
```

#migration実行
```shell:migration実行
~/go/src/test $ migrate -database ${POSTGRESQL_URL} -path db/migrations up        
1/u create_users_table (97.462811ms)
```
![スクリーンショット 2022-03-02 21.41.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/632af6fc-3a9a-dd75-d683-c8ea62f951f5.png)
![スクリーンショット 2022-03-02 21.42.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/010d0cc5-fd17-de85-918d-d672f14db003.png)
![スクリーンショット 2022-03-02 21.42.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/50f299cf-f5c9-f6da-5a22-5ceaf16f4ad0.png)
→userテーブルが作成されていることを確認。


https://github.com/golang-migrate/migrate/blob/master/database/postgres/TUTORIAL.md
Vue.jsでDOMの更新を待ってイベントを発火する

と検索するとまず$nextTickに辿り着く。あるいはsetTimeout。

https://jp.vuejs.org/v2/api/index.html#Vue-nextTick

ただこれは「DOMの更新を待つ」のであって、Vueのtransitionコンポーネントのアニメーション完了を待たない。そのためアニメーションして表示/非表示が切り替わるような要素が影響する情報（高さや位置情報）を、アニメーション完了後に取得したい～という場合$nextTickは不向き。

その場合はtransitionコンポーネントのJavaScriptフックを使う。

https://jp.vuejs.org/v2/guide/transitions.html#JavaScript-%E3%83%95%E3%83%83%E3%82%AF

```index.html
<transition :name="navAnime" @after-leave="getAnimated">
...
</transition>
```

```script.js
getAnimated: function(){
...
},
...
```

自分のしたい事について遠回りしてしまうのはドキュメントを網羅的に読むのをぬかってしまうからだなと常々思う。
Herokuでスクレイピングしようとしてハマったこと

## 初めに
Herokuでスクレイピングしてハマったことをまとめてみました。
記事ではGoとagoutiを使用していますが、Pythonとかにも当てはまると思います。
## invalid session id  エラーが多発
### 下記エラーが発生
```
failed to retrieve page HTML: request unsuccessful: invalid session id
failed to retrieve page title: request unsuccessful: invalid session id 
```
### 対策
Chromeのオプションに`--disable-gpu`と`--disable-dev-shm-usage`を指定したら解消しました。
```golang
options := agouti.ChromeOptions(
	"args", []string{
		"--headless",
		"--disable-gpu",
		"--disable-dev-shm-usage",
	})
driver := agouti.ChromeDriver(options)
```
### --disable-gpu
https://developers.google.com/web/updates/2017/04/headless-chrome?hl=ja
> 今のところですが、必要です。--disable-gpu フラグはいくつかのバグを回避するための暫定的な手段です。将来の Chrome のバージョンでは必要なくなるでしょう。詳しくは https://crbug.com/546953#c152 と https://crbug.com/695212 をご覧ください。

必須らしいです。

### --disable-dev-shm-usage
メモリが少ない場合、メモリ不足でクラッシュする場合があります。
このオプションを指定することにより回避することができます。
ちなみにHerokuのプランFree dynoはメモリが512MBです。

## 空のHTMLが返ってくる
```html:
<html><head></head><body></body></html>
```
### スクレイピング先のサイト側で弾かれている可能性が大
海外IPアドレスをブロック対象にしているサイトが多々あります。
ちなみにHerokuのFreeプランでは海外リージョンしか選べず、海外IPアドレスになります。
代わりに国内VPS等を使用するか、HerokuのPrivate SpaceでTokyoリージョンを選べるので回避できるかもしれません。

## 参考文献
[https://qiita.com/yoshi10321/items/8b7e6ed2c2c15c3344c6](https://qiita.com/yoshi10321/items/8b7e6ed2c2c15c3344c6)
[https://developers.google.com/web/updates/2017/04/headless-chrome?hl=ja](https://developers.google.com/web/updates/2017/04/headless-chrome?hl=ja)
git-secretsをwindowsに導入したときの手順

# 1. PowerShellの設定を変更する

- 管理者権限でPowerShellを起動する
- 作業ディレクトリはホームディレクトリ(C:\Users\PC_User とする)
- PowerShellでスクリプトを実行できるよう設定を変更する

```
PS C:\Users\PC_User> Set-ExecutionPolicy RemoteSigned
```

# 2. git-secretsをインストールする

```
PS C:\Users\PC_User> git clone https://github.com/awslabs/git-secrets.git

PS C:\Users\PC_User> cd .git-secrets

PS C:\Users\PC_User\.git-secrets> ./install.ps1
```

# 3. gitの設定ファイルにAWSアクセスキーのパターンを登録する

```
PS C:\Users\PC_User\.git-secrets> cd ~

PS C:\Users\PC_User> git secrets --register-aws --global
```

これで`git secrets --scan`などのコマンドでファイルをスキャンして、AWSアクセスキーを見つけることができるようになった。
次に手動でのスキャンし忘れを防ぐため、コミット時にスキャンするgit hookを追加する。

# 4. git initしたときにgit hookを自動で追加するよう設定する

```
PS C:\Users\PC_User> git secrets --install ~/.git-templates/git-secrets

PS C:\Users\PC_User> git config --global init.templateDir ~/.git-templates/git-secrets
```

# 5. 既存のローカルリポジトリにgit hookを追加する

ローカルリポジトリのディレクトリに移動してから

```
git secrets --install
```

`ローカルリポジトリ/.git/hooks/`に`commig-msg`などのファイルが作成される。

# 参考

<https://github.com/awslabs/git-secrets>
<https://qiita.com/Targityen/items/3d2e0b5b0b7b04963750>
<https://qiita.com/nyokinyoki1848/items/2d2ff297532022108e59>
<https://zenn.dev/kkk777/articles/8f55db1e9678f2>
<https://dev.classmethod.jp/articles/startup-git-secrets>
医(118)歯薬理工系大学の実験系と理論系の違い

大学生、大学院生の書き込みで、医歯薬理工系大学の実験系と理論系の違いを明記すれば、どうということがないことを、医歯薬理工系大学の実験系と理論系の違いを明記せずに何か記述している文章に時々であうような気がする。

私は原則理論系で、博論は実験もしたけど、測定方法の実現方法を示した。実験結果の詳細な比較をしたわけではなく、実験系とは呼べない。無線通信といってもPHSの例を示し、博論の発表の前日から徹夜してGPSを利用して測定するプログラムを書き、同じ構造のデータで、汎用性を確認した程度です。

実験系の方が、実験系だから当てはまるかもしれないことを、大学だから、大学院修士だから、大学院博士だからと書かれているような気がする、

理論系であれば、小学生から議論できるし、中学校、高校で取り組んでもいい。大学じゃなきゃできないこととか、大学院修士じゃなきゃできないこととか、大学院博士じゃなきゃできないことはほとんどない。

自分が知っている実験系だと、大学院生が、大学４年生の実験の指導をしていて、
大学４年生は、自分で実験の設計をさせてもらえないことがあるとお聞きすることがある。

理論系でも、大学院生の修論、博論のテーマを手伝わせるということはお聞きしたことがある。
# 卒論指導
工学系の学生の卒業論文（卒論）指導では、学生が何をやりたいかで決めてもらっていた。
どんなことでも、手持ちの機材でできることなら、理論系、実験系の制約なしに選んでもらっていた。

例えば、音楽活動をしているから、音楽を題材にした卒論を希望されれば、
その時のネットで検索して、興味を持ちそうでなおかつ未発表の題材を選んでもらった。

特に、やりたいことがないという時には、どこの就職したいかで相談していた。
例えば、自宅がカラオケ屋だから、MIDIを扱うという場合もあった。
DIYに就職したいからという場合には、フェリカなどのカードシステムを扱ってもらった。

やりたいことも、勤めたいとこも特にない場合は、
自分たちが過去に発表した学会発表を見てもらって、その続きをやってもらうことにした。

<!--
実験系で、何かの制約条件で部分最適しているやり方を前提として、何か外に文章を書く時点で、
修士論文、博士論文の質に疑問がわくかもしれない。
-->
# 修論指導
大学院の指導では、やる気の維持に焦点を合わせた。
https://www.slideshare.net/kaizenjapan/before-study-gifu-university-2016

修論もいいが、まず、自分のまわりにどういう技術者がいるかを把握することを勧めた。

企業に入ってからも、自分の周りにいる人が、何が得意かわからずにいるのは、実験系か理論系かと関係なくもったいない。

企業に入られた方の学生時代の発表は、なるべくこまめに確認させていただくようにしている。博士論文を含めて。

参考文献駆動執筆(references driven writing)・デンソークリエイト編
https://qiita.com/kaizen_nagoya/items/b27b3f58b8bf265a5cd1

大学４年生ですごいソフトを書いた方もいれば、自分も含めて博論なのに書いたソフトそれっていう方もおみえかもしれない。

# 参考資料
@nekonibox「博士ならではの就職活動のやり方」に付け加えたい一つのこと
https://qiita.com/kaizen_nagoya/items/f07f8ebdc917694dfe9e

「@ohakutsu 新卒2年目から見た達人プログラマーの振る舞い」から学ぶこと
https://qiita.com/kaizen_nagoya/items/2d87b99b096972327c4d

裸の王様にならないために
https://qiita.com/kaizen_nagoya/items/450a66b3d8778fc649ab

卒業論文、修士論文、博士論文は　github/gitlab/bitbacketのprivate利用をお勧め
https://qiita.com/kaizen_nagoya/items/eb9945a2649f6f3eabd0 

＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently belong.

# 文書履歴(document history)

ver. 0.01 初稿　　20220302
ver. 0.02 URL追記 20240414

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

#### Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
vistaでphotoshop その12

# 概要

vistaでphotoshopやってみる。
キャンバス作って、jpg読んで、部分的にフィルターかけて、pngで出力やってみる。

# 写真

![test11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/9383bf90-17ad-9e6a-e3e2-78340dad212f.png)

# サンプルコード

```
preferences.rulerUnits = Units.PIXELS;
var docObj = app.documents.add(640, 480);
var fileObj = new File("/Users/ore/eki.jpg");
open(fileObj);
activeDocument.selection.selectAll();
activeDocument.activeLayer.copy();
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
docObj.paste();
var x = 100;
var y = 100;
var selReg = [[x, y], [x + 400, y], [x + 400, y + 400], [x, y + 400], [x, y]];
activeDocument.selection.select(selReg);
executeAction(charIDToTypeID('Shrp'), undefined, DialogModes.NO);
var pngOpt = new ExportOptionsSaveForWeb();
pngOpt.format = SaveDocumentType.PNG;
pngOpt.optimized = true;
pngOpt.interlaced = false;
pngOpt.PNG8 = false;
var filePath = new File("/Users/ore/test11.png");
activeDocument.exportDocument(filePath, ExportType.SAVEFORWEB, pngOpt);
alert("ok");



```

以上。
【DB設計】マスターとトランザクション

今までDB設計を考える上でマスターテーブルしか必要のない設計ばかりしていたが、
今回初めてトランザクションテーブルが必要になる設計をすることになったのでまとめてみた。

DB設計ではテーブルを考えるときにマスター用のテーブルとトランザクション用のテーブルに分けて考えるとスムーズに設計できる。

# マスター
頻繁に更新しない基本的なデータを扱う。
使い分けて考える上での特徴のひとつ：updated_atカラムが必要

例：ユーザーテーブル、商品テーブル

**ユーザーテーブル**
| ユーザーID | 名前 | メールアドレス |
|:-:|:-:|:-:|
| 1  | 山田太郎  | taro.y@hogehoge.jp  |
| 2 |  佐藤理恵 |  sato_rie@hogehoge.jp |



**商品テーブル**
| 商品ID | 商品名 |単価 |
|:-:|:-:|:-:|
| 1  | hoge農家の卵 | 198  |
| 2 |  おいしい牛乳 |  158 |




# トランザクション
履歴（実行された事実）を残しておく。
使い分けて考える上での特徴のひとつ：updated_atカラムが必要ない

例：注文履歴テーブル

**注文履歴テーブル**
| 注文ID | ユーザーID |商品ID |購入日 |
|:-:|:-:|:-:|:-:|
| 1  | 3| 2  | 2022/3/2  |
| 2 |  8 |  4 | 2022/1/23  |
Stripe Connect 米国で利用する金融番号は

memo.

## 結論

Routing Number ※1 である。

ABA Routing Number, ABA Number とも呼ぶ。

## 理由

Bank Identifier Code (= SWIFT Code) ※2 もあるがこれは用いない。

## 具体的には

1. 米国内の銀行が個別に保有する銀行番号で、連続した 9 桁の数字からなる番号。米国内では一般的。
2. SWIFT（国際銀行間金融通信協会）が定めた金融機関識別コード。ISO 9362 で、8 桁または 11 桁のアルファベットと数字で構成。

https://www.ifinance.ne.jp/glossary/finance/fin081.html

https://www.ifinance.ne.jp/glossary/finance/fin031.html

### 例

https://www.bk.mufg.jp/tsukau/kaigai/kouza/prcb/service.html


## テスト用の口座番号

テスト内容に応じたものが用意されている。

https://stripe.com/docs/connect/testing#payouts

補足：このドキュメントは左下の国旗から対象国を選択できる。

### 日本

金融番号（銀行コード + 支店コード）: `1100000`
口座番号： `0001234`

### アメリカ

金融番号（Routing Number）: `110000000`
口座番号（Account Number）: `000123456789`
vistaでphotoshop その11

# 概要

vistaでphotoshopやってみる。
キャンバス作って、jpg読んで、フィルターかけて、pngで出力やってみる。

# 写真


![test10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/e71171ea-c06a-66ec-1cc0-b81418ec4072.png)

# サンプルコード

```
preferences.rulerUnits = Units.PIXELS;
var docObj = app.documents.add(640, 480);
var fileObj = new File("/Users/ore/eki.jpg");
open(fileObj);
activeDocument.selection.selectAll();
activeDocument.activeLayer.copy();
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
docObj.paste();
activeDocument.activeLayer.applyOceanRipple(9, 9);
var pngOpt = new ExportOptionsSaveForWeb();
pngOpt.format = SaveDocumentType.PNG;
pngOpt.optimized = true;
pngOpt.interlaced = false;
pngOpt.PNG8 = false;
var filePath = new File("/Users/ore/test10.png");
activeDocument.exportDocument(filePath, ExportType.SAVEFORWEB, pngOpt);
alert("ok");

```

以上。
Stripe のクレジットカード決済ステップで 3D セキュアをチェックするには

memo.

## 結論

専用のテストカード番号を利用する。

## 理由

すべてのカードが 3D セキュアをサポートしているわけではないから。

https://stripe.com/docs/testing#regulatory-cards

## 備考

3D セキュア

https://www.veritrans.co.jp/user_support/3d-secure.html
Bootstrap【導入方法】

## Bootstrapの導入方法

RailsにはCSSのデザインテンプレートがありません。
Bootstrapを用いることで、デザインが簡単に整えられます。

導入方法の種類が何個かあります。
- CDNの導入
- ファイルを配置する
- yarnでインストール
- gemでインストール

今回はyarnを用いて導入していきます。

### Bootstrap導入手順

下記コマンドを実行します。
```
$ yarn add jquery bootstrap@4.5 popper.js
```
その後に、config/webpack/enviroment.jsを編集します。
下記を記述します。

```config/webpack/enviroment.js
:
:
const webpack = require('wabpack')
environment.plugins.prepend(
 'Provide',
  new webpack.ProvidePlugin({
    $: 'jquery/src/jquery',
    jQuery: 'jquery/src/jquery',
    Popper: 'popper.js'
  })
)
```
次にapp/javascriptの配下に**stylesheet**フォルダを作成し、配下に**application.scssファイル**を作成して、次のように記述します。

```app/javascript/stylesheets/application.scss
:
:
import "jquery";
import "popper.js";
import "bootstrap";
import "../stylesheets/application" 
```

次にapp/views/layouts/application.html.erbの記述を変更します。

```app/views/layouts/application.html.erb
:
<%= stylesheet_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
:
```

これでBootstrapの導入が終了です。

後は、こちらのBootstrapのサイトから色々試してデザインしてみてください。
https://getbootstrap.jp/docs/4.5/components/forms/

## まとめ
自分もまだまだ初学者ですが、デザインは好きなので色々試してみていきたいと思います。
[Python,Java]pom.xmlからMaven依存ライブラリ一覧を取得する方法 メモ


* Java/Mavenプロジェクト開発の際に、pom.xmlファイルから依存ライブラリの一覧をcsv形式で取得したかった。
* 取得用のPythonスクリプトを作成したため、メモとして残しておく。


## 事前準備
* ライブラリインストール
 ```
 pip3 install lxml
 ```
* テスト用`pom.xml`準備

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.example.test</groupId>
	<artifactId>test</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>test</name>
	<dependencies>
		<dependency>
			<groupId>commons-codec</groupId>
			<artifactId>commons-codec</artifactId>
			<version>1.10</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.9.8</version>
		</dependency>
	</dependencies>
</project>
```

## スクリプト

* `extract_dependencies_from_pom.py`

```python
from lxml import etree

def extractDependenciesFromPom():
    # 出力ファイル
    output = "./dependencies_from_pom.csv"
    f = open(output, "w")

    # 出力ファイルヘッダー 書き込み
    header_string = "groupId,artifactId,version"+"\n"
    f.write(header_string)
    # pom.xml 読み込み
    tree = etree.parse("./pom.xml")
    root = tree.getroot()
    dependencies = root.find('./{*}dependencies')
    for dependency in dependencies:
        # dependency内の各要素を取得
        groupId = dependency.find('./{*}groupId').text
        artifactId = dependency.find('./{*}artifactId').text
        version = dependency.find('./{*}version').text

        # CSV 書き込み
        output_string = groupId \
                            + "," + artifactId \
                            + "," + version +"\n"
        print(output_string)
        f.write(output_string)
    f.close

extractDependenciesFromPom()
```

## 動作確認

※extract_dependencies_from_pom.pyとpom.xmlを同一フォルダに配置する。

* 実行

  ```shell
  python3 extract_dependencies_from_pom.py
  ```

* 出力結果

  ```csv
  groupId,artifactId,version
  commons-codec,commons-codec,1.10
  com.fasterxml.jackson.core,jackson-databind,2.9.8
  ```



## 参考情報

* [Python で XML を CSV に変換する方法](https://www.gis-py.com/entry/py-xml2csv)
* [ElementTreeやlxmlで名前空間を含むXMLの要素を取得する](https://orangain.hatenablog.com/entry/namespaces-in-xpath)
MXEの使い方メモ

Windowsにメインの環境を移したものの、WindowsではMinGWでビルドしてLinuxでGCCでビルドして、というのは幾分面倒くさいのでどうにかならないものかと思ってクロスコンパイル環境について軽く探したら、[MXE](https://mxe.cc/)というものがある事を知った。というわけで、MXEの環境を構築してビルドするまでの覚書。

## MXEの簡単な説明

* M cross environmentの略
* 実体としてはMakefileのコレクションで、用途に合わせてクロスコンパイル環境を構築できるらしい。
    * GTK, SDL, Qtなども対応。
* コンパイラはMinGWを採用しているとのこと。

## インストール

公式のチュートリアルは用途に合わせたビルドから説明しているが、Ubuntuであればaptから結構なバリエーションがインストールできるので今回はそちらを使う。

```
sudo apt-key adv \
    --keyserver keyserver.ubuntu.com \
    --recv-keys 86B72ED9 && \
sudo add-apt-repository \
    "deb [arch=amd64] https://pkg.mxe.cc/repos/apt `lsb_release -sc` main" && \
sudo apt-get update
sudo apt-get install mxe-x86-64-w64-mingw32.{static,shared}-cc
```

/usr/lib/mxe/usr/binがコンパイラのインストール先になるようだ。

### LV2ライブラリのインストール

上記の手順でインストールしたMinGWはヘッダファイルなどが/usr/lib/mxe/usr/の下にインストールされ、そこがヘッダファイルの探索パスになっているようだ。

```
x86_64-w64-mingw32.static-gcc  -x c -v -E /dev/null
```

上記のコマンドを実行した結果は以下のような感じ。

```
(略)
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/mxe/usr/lib/gcc/x86_64-w64-mingw32.static/5.5.0/include
 /usr/lib/mxe/usr/lib/gcc/x86_64-w64-mingw32.static/5.5.0/include-fixed
 /usr/lib/mxe/usr/lib/gcc/x86_64-w64-mingw32.static/5.5.0/../../../../x86_64-w64-mingw32.static/include
End of search list.
# 1 "/dev/null"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/dev/null"
COMPILER_PATH=/usr/lib/mxe/usr/libexec/gcc/x86_64-w64-mingw32.static/5.5.0/:(略)
LIBRARY_PATH=/usr/lib/mxe/usr/lib/gcc/x86_64-w64-mingw32.static/5.5.0/:(略)
COLLECT_GCC_OPTIONS='-v' '-E' '-mtune=generic' '-march=x86-64'
```

LV2のヘッダを/usr/includeなどにインストールしている場合、MXEのヘッダと定義が衝突してしまって上手くビルドできなかった。

恐らく最も好ましいやり方はLV2を含む形でMXEのビルドを行う事なのだろうが、LV2プラグインを作るならヘッダファイルだけあればよいので、[前回](https://qiita.com/c_kuwata/items/2cdf46445ac473761517)書いた通りソースからLV2ライブラリを所定のディレクトリにインストールして、ビルド時にパスを指定することにした。（ここでは/optにインストールしている。）

```
./waf configure --prefix=/opt
./waf
sudo ./waf install
```

# ビルド

```
x86_64-w64-mingw32.static-gcc  -DLV2_VERSION="1.18.2" -DHAVE_LV2=1 -I/opt/include  -std=c99 -o tube-fucker.dll  -shared  tube-fucker.c
```

ビルド結果のDLLをWindowsに持って行ってArdourに読み込ませたところ動作したので、ひとまずは成功。
Windows Server 08 r2 std を2022年現在でダウンロードする方法

# はじめに
最近ジャンクでサーバーを買いまして、WinSer08が必要になって探したらもう配布してなさそうだったので、全力を尽くして探した結果、、、

ありました。

ダウンロードにすごく時間かかりますけど、とりあえずゲッツできるみたいです。

# How to download

## 1. Internet Archive
Internet Archive はユーザーが保存のリクエストをしたサイトが保存されるサイトです。
このサイト内にWindows server 08のダウンロードサイトが保存されていたので、それをありがたく頂戴します。

https://archive.org/

## 2. 検索
メインページの検索窓から、以下のほしいバージョンのリンクを検索します。

* English version

```
https://www.microsoft.com/en-us/download/details.aspx?id=5023
```

* Japanease version

```
https://www.microsoft.com/ja-jp/download/details.aspx?id=5023
```

## 3. アーカイブを選択
`2013年の5月以前` のアーカイブを選択します。
それ以降はMicrosoftのサイトのUIが変更されたため、アーカイブ上ではダウンロードが、出来たり出来なかったりしたのでそれ以前から選択します。
青色の〇がついているところが正常にアーカイブされているところです。

## 4. ダウンロード
あとは、出てきたダウンロードサイトで、ほしいバージョンをクリックしたら、自動でダウンロードリンク先のアーカイブに飛んでくれます。
アーカイブなので結構ダウンロードに時間がかかります。

## 直接探す
上の方法では選択したアーカイブの時期に近いダウンロードリンクのアーカイブが選択されるので、なるべく最新のアーカイブからダウンロードしたい方は以下の方法を取ってください。

以下のほしいISOのバージョンのダウンロードリンクをアーカイブで検索します。

上から、
English x86
English x64
Japanease x86
Japanease x64
です。

```
http://download.microsoft.com/download/D/D/B/DDB17DC1-A879-44DD-BD11-C0991D292AD7/6001.18000.080118-1840_x86fre_Server_en-us-KRMSFRE_EN_DVD.iso

http://download.microsoft.com/download/D/D/B/DDB17DC1-A879-44DD-BD11-C0991D292AD7/6001.18000.080118-1840_amd64fre_Server_en-us-KRMSXFRE_EN_DVD.exe

http://download.microsoft.com/download/1/f/8/1f8d70ba-e5dd-4cbf-b627-d20b8af365fe/6001.18000.080118-1840_x86fre_Server_ja-jp-KRMSFRE_JA_DVD.iso

http://download.microsoft.com/download/1/f/8/1f8d70ba-e5dd-4cbf-b627-d20b8af365fe/6001.18000.080118-1840_amd64fre_Server_ja-jp-KRMSXFRE_JA_DVD.iso
```

以上
EC2起動のたびに自動的にEFSをマウントするようにする

## 自動でEFSをマウントしたい・・・
複数のEC2でEFS(Elastic File System)をマウントして「ネットワークファイルシステム完成！」と思ったら、なんてことはなく、EC2を再起動するとマウントは解除されてしまいました。。。

定期的なEC2の停止⇒起動がサイクルに含まれているサービスの場合、これはちょっと困ります。

なので起動の度に自動でEFSをマウントするよう設定してみようと思います。


### 環境
Amazon Linux2です。

## amazon-efs-utilsをインストール
まさにこの要件のためのツールが提供されているようなので、こちらをインストールします。

```bash
$ sudo yum install -y amazon-efs-utils
```

## EFSをマウントする

```bash
$ sudo mount -t efs <ファイルシステムのID>:// <マウントディレクトリ>
```

マウント出来ているか確認します。


```bash
$ df -h

# マウントしたEFSが表示されていればOK
<ファイルシステムのID>.efs.ap-northeast-1.amazonaws.com:/  8.0E     0  8.0E   0% <マウントしたディレクトリ>
```

後で分かりやすいように、ファイルも作成しておきましょう。
今回は「I'm here!」と書いておきます。

```
$ sudo vi test.txt
I'm here!
```

ちなみに、マウント解除は以下のコマンドです。
指定する階層を間違えた場合はこれで元に戻します。

```
$ sudo umount <マウントしたディレクトリ>
```

## 自動でマウントできるように設定する

「/etc/fstab」に記述を追加します。

「/etc/fstab」とは簡単に言うとマウントまわりの設定を記述するファイルです。
詳しく知らない方は(私もですが)以下の記事が参考になります。

https://qiita.com/kihoair/items/03635447591358210772

```bash
$ sudo vi /etc/fstab
(中略)

<ファイルシステムのID>:/ <マウントしたディレクトリの絶対パス> efs defaults,_netdev 0 0 # こちらを追加
```

ここまで出来たらEC2を再起動します。

```bash
$ sudo reboot
```

数分待って再度EC2へ接続し、以下のコマンドを打ちます。

```bash
$ df -h

# マウントしたEFSが表示されていればOK
<ファイルシステムのID>.efs.ap-northeast-1.amazonaws.com:/  8.0E     0  8.0E   0% <マウントしたディレクトリ>
```

念のためファイルも確認します。

```
$ cat /<マウントしたディレクトリ>/text.txt
I'm here!
```

居ました！

とりあえずなんとか出来ましたが、大丈夫かな？

何か問題があれば後日追記します。
React で jsx を使うサンプル (その 2)

こちらと同様のサンプルです。
[React で jsx を使うサンプル](https://qiita.com/ekzemplaro/items/a58fe2dade6cac248d21)

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>React Elements</title>
</head>
<body>

<div id="app"></div>

<br />
Mar/02/2022<br />
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
console.log("*** start ***")
const mm_aa = React.createElement("h1", null, "おはようございます。")
const mm_bb = React.createElement("div", null, "こんにちは。")

const mm_cc = <blockquote><div>今晩は。</div></blockquote>
const mm_dd = <div>Test</div>

const app = document.getElementById('app')
const root = ReactDOM.createRoot(app)
root.render([mm_aa,mm_bb,mm_cc,mm_dd])

console.log("*** end ***")
</script>
</body>
</html>
```

![react_mar02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/f8d50cc5-1df7-1428-88f9-13016cfa4980.png)