OmniAICreator/Qiita-1.07M huggingface dataset:
pydanticで設定ファイルのバリデーションをする

- [この記事のゴール](#この記事のゴール)
- [ディレクトリ構成](#ディレクトリ構成)
- [ソースコード](#ソースコード)
- [BaseSettingsクラスについて](#basesettingsクラスについて)
  - [オブジェクトの型バリデーション](#オブジェクトの型バリデーション)
  - [環境変数の取得](#環境変数の取得)
  - [Validatorデコレーターの使用](#validatorデコレーターの使用)

## この記事のゴール

pydanticのBaseSettingsで設定ファイルのバリデーションを行い、開発者の意図しない設定値がコード内で使用されないようにする。

## ディレクトリ構成

```sh
tree
.
├── main.py
├── config.py
└── requirements.txt
```

## ソースコード

```python: main.py
from config import settings


def main():
    print(f"NAME: {settings.NAME}")
    print(f"EMAIL: {settings.EMAIL}")
    print(f"BACKEND_URL: {settings.BACKEND_URL}")


if __name__ == "__main__":
    main()
```

```python: config.py
from typing import List
from pydantic import BaseSettings, EmailStr, HttpUrl, validator


class Settings(BaseSettings):
    NAME: str = "My name"
    EMAIL: EmailStr = "email@dummy.com"

    BACKEND_ACCEPTION_URL_LIST: List = [
        "https://www.local.com",
        "https://www.develop.com"
    ]
    # 環境変数
    BACKEND_URL: HttpUrl

    # case_sensitive=Trueの場合、環境変数名はフィールド名と一致する必要がある
    class Config:
        case_sensitive = True

    # validate BACKEND_URL
    @validator('BACKEND_URL')
    def validate_backend_url_value(cls, v, values):
        assert v in values.get("BACKEND_ACCEPTION_URL_LIST")
        return v


settings = Settings()
```

```txt: requirements.txt
typing==3.7.4.3
pydantic[email]==1.9.1
```

## BaseSettingsクラスについて

### オブジェクトの型バリデーション

BaseSettingsを継承したクラスにおいて、型アノテーションによって明記された型以外がオブジェクトに代入されるとエラーを出力します。
例えば次のような場合、BACKEND_URLの型バリデーションが失敗するためエラーを出力します。

ソースコード

```python
from pydantic import BaseSettings, EmailStr, HttpUrl, validator

class Settings(BaseSettings):
    BACKEND_URL: HttpUrl

settings = Settings()
```

実行コマンド

```sh
export BACKEND_URL=www.local.com
python3 config.py
```

### 環境変数の取得

BaseSettingsを継承したクラスにおいて、値が代入されていないオブジェクトは環境変数から値を読み込んで代入しようとします。
例えば次のような場合、BACKEND_URLは環境変数BACKEND_URLから値を読み込みます。
環境変数が存在しない場合は、エラーを出力します。

ソースコード

```python
from pydantic import BaseSettings, EmailStr, HttpUrl, validator

class Settings(BaseSettings):
    BACKEND_URL: HttpUrl

settings = Settings()
```

実行コマンド

```sh
python3 config.py
```

### Validatorデコレーターの使用

Validator デコレーターを使用すると、以下のような実装が可能です。

- オブジェクトに対しての独自のバリデーションを実行できる
- オブジェクト間の関係性についてバリデーションを実行できる

例えば次のような場合に、BACKEND_ACCEPTION_URLにBACKEND_URLが含まれていないため、バリデーションが失敗するためエラーを出力します。

ソースコード

```python: config.py
from typing import List
from pydantic import BaseSettings, EmailStr, HttpUrl, validator


class Settings(BaseSettings):
    BACKEND_ACCEPTION_URL_LIST: List = [
        "https://www.local.com",
        "https://www.develop.com"
    ]
    # 環境変数
    BACKEND_URL: HttpUrl

    # case_sensitive=Trueの場合、環境変数名はオブジェクト名と一致する必要がある
    class Config:
        case_sensitive = True

    # validate BACKEND_URL
    @validator('BACKEND_URL')
    def validate_backend_url_value(cls, v, values):
        assert v in values.get("BACKEND_ACCEPTION_URL_LIST")
        return v


settings = Settings()
```

実行コマンド

```sh
export BACKEND_URL=https://www.local.com
python3 config.py
```
【EC2,Git】fatal: detected dubious ownership in repository at ...のエラーについて

# エラー内容

EC2で色々試している中で、test.shを以下のように作成した。

```sh:test.sh
#!/bin/bash

cd /home/ec2-user/app_name/ && git pull
```
その後以下のコマンドでアプリケーションの更新内容をgit pullをしようとした。

```
bash test.sh
```

その際、以下のエラーが出た。

```
fatal: detected dubious ownership in repository at '/home/ec2-user/app_name'
To add an exception for this directory, call:

	git config --global --add safe.directory /home/ec2-user/app_name
```
# 対処法

エラーを見るに、権限が疑わしいとのことなので。これは一旦、須藤さんに解決してもらうことにした。

```
sudo bash deploy-me.sh
```
このコマンドでgit pullの実行に成功した。

また、gitの権限自体を現在のユーザーに与える場合、アプリケーションのディレクトリで以下を実行すると権限を変更できる。
```
sudo chown -R 現在のユーザー名 .git/
```
さらに、アプリケーションのディレクトリの所有者自体を現在のユーザーに変更し、全ての権限を与える場合は以下を実行する。

```
sudo chown -R 現在のユーザー名　アプリケーションのディレクトリ名
```
WEB開発をやり始めてみる(Ruby:配列＋いろんなメソッド)

# やったことメモ
配列を使ったメソッドの使い方のまとめ
```ruby:
$ irb
#### 配列の書き方
2.5.0 :001 > a = [1, 2, 3, 'aa', [1, 2, 3]]
 => [1, 2, 3, "aa", [1, 2, 3]]

#### 配列の表示の仕方
2.5.0 :002 > a[0]
 => 1 
2.5.0 :003 > a[1]
 => 2 
2.5.0 :004 > puts a
1
2
3
aa
1
2
3
 => nil 

#### 配列の中身が空かどうか
2.5.0 :005 > a.empty?
 => false 
2.5.0 :006 > b = []
 => [] 
2.5.0 :007 > b.empty?
 => true

#### 配列の中身に〇〇が含まれているか
2.5.0 :008 > a.include?('aa')
 => true 
2.5.0 :009 > a.include?('b')
 => false 

#### 配列の中身を逆順に表示(!を使うと破壊的メソッドといって、元の中身を書き換える)
2.5.0 :010 > a.reverse
 => [[1, 2, 3], "aa", 3, 2, 1] 
2.5.0 :011 > a
 => [1, 2, 3, "aa", [1, 2, 3]] 
2.5.0 :012 > a.reverse!
 => [[1, 2, 3], "aa", 3, 2, 1] 
2.5.0 :013 > a
 => [[1, 2, 3], "aa", 3, 2, 1] 

#### 配列の中身をシャッフルして表示
2.5.0 :014 > a.shuffle
 => [1, 2, "aa", [1, 2, 3], 3] 
2.5.0 :015 > a.shuffle
 => ["aa", 1, 3, [1, 2, 3], 2] 
2.5.0 :016 > a
 => [[1, 2, 3], "aa", 3, 2, 1]

#### 配列を作る(.to_a) (0..25)は0 - 25といった範囲を指定
 2.5.0 :019 > (0..25).to_a
 => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25] 
2.5.0 :020 > aa = (0..99).to_a.shuffle!
 => [49, 76, 39, 50, 52, 17, 12, 21, 97, 0, 67, 59, 56, 32, 11, 64, 72, 9, 95, 73, 92, 58, 78, 28, 37, 31, 90, 93, 4, 8, 60, 2, 47, 66, 74, 42, 6, 84, 7, 10, 63, 75, 36, 33, 3, 53, 35, 19, 5, 77, 23, 48, 38, 81, 15, 57, 13, 27, 24, 16, 1, 70, 98, 87, 20, 80, 79, 88, 40, 30, 26, 99, 83, 61, 18, 82, 54, 89, 46, 29, 68, 14, 71, 25, 41, 91, 85, 96, 51, 94, 22, 69, 62, 45, 65, 34, 44, 43, 55, 86] 
2.5.0 :021 > aa
 => [49, 76, 39, 50, 52, 17, 12, 21, 97, 0, 67, 59, 56, 32, 11, 64, 72, 9, 95, 73, 92, 58, 78, 28, 37, 31, 90, 93, 4, 8, 60, 2, 47, 66, 74, 42, 6, 84, 7, 10, 63, 75, 36, 33, 3, 53, 35, 19, 5, 77, 23, 48, 38, 81, 15, 57, 13, 27, 24, 16, 1, 70, 98, 87, 20, 80, 79, 88, 40, 30, 26, 99, 83, 61, 18, 82, 54, 89, 46, 29, 68, 14, 71, 25, 41, 91, 85, 96, 51, 94, 22, 69, 62, 45, 65, 34, 44, 43, 55, 86] 
2.5.0 :022 > z = (0..10).to_a
 => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 

#### 配列の後ろに足す(pushも同様)
2.5.0 :023 > z << 20
 => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20] 
2.5.0 :024 > z
 => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20] 
2.5.0 :025 > z.push(30)
 => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30] 
2.5.0 :027 > z
 => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30] 

#### 配列の後ろを削除
2.5.0 :028 > z.pop
 => 30 
2.5.0 :030 > z
 => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20] 
2.5.0 :031 > z.shift
 => 0 
2.5.0 :032 > z
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20] 
2.5.0 :033 > z << 3
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 3] 
2.5.0 :034 > z << 6
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 3, 6] 

#### 配列の中身で一緒になっていないものを表示（被っていない）
2.5.0 :035 > z.uniq
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20] 
2.5.0 :036 > z
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 3, 6] 
2.5.0 :037 > z.uniq!
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20] 
2.5.0 :038 > z
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20] 

#### 配列の中身を結合&どう結合をするか
2.6.3 :007 > s = ["my","name","is","kuruma"]
 => ["my", "name", "is", "kuruma"] 
2.6.3 :008 > s.join
 => "mynameiskuruma" 
2.6.3 :009 > s.join(" ")
 => "my name is kuruma" 
2.6.3 :010 > s.join("_")
 => "my_name_is_kuruma" 

```
firebase-ios-sdk使ってCloud Functionsを呼ぶ

Cloud FunctionsはHTTPリクエストで呼ぶことも可能ですが、[firebase-ios-sdk](https://github.com/firebase/firebase-ios-sdk)を使って呼び出す方が扱いやすいです。（HTTPで呼び出す場合は以下の記事を参考に）
https://qiita.com/kitanote/items/c479230aa1bea4fbe1b0

テストコードの使い方をみると requestAs, responseAsを使っていい感じにデータの受け渡しをしてたので、その書き方を採用しました。

https://github.com/firebase/firebase-ios-sdk/blob/eb30b6fdd809cbfe3a9eb7f3ccf1dd46326bef2d/FirebaseFunctions/Tests/CombineUnit/HTTPSCallableTests.swift


``` xxx.swift
struct DataResponse: Decodable {
    var name: String
}
struct DataResponse: Decodable {
    var name: String
}

lazy var functions = Functions.functions(region: "asia-northeast1")  
do {
    let result = try await functions.httpsCallable("function-1",
                                                   requestAs: DataResponse.self,
                                                   responseAs: DataResponse.self).call(data)                                              
}
...
```

1行の呼び出しコードでデータ型の変換までしてくれて非常にわかりやすいです。
ただrequest, response共に、"data"キーが自動で付与される状態になるのでfunctions側では対応してください。

## Request
``` request.json
{
	"data": {
		"name": "aaa"
	}
}
```

## Response

``` response.json
{
	"data": {
		"name": "AAA"
	}
}
```

以上です。
[Rails] モデル名.newってなんぞや[初心者向け]

# 目次
[1.はじめに](#はじめに)
[2.目的](#目的)
[3.モデル名.newとは](#モデル名newとは)
[4.モデル名.saveをすると](#モデル名saveをすると)
[5.まとめ](#まとめ)

# はじめに
りくがめと申します。理解力アップのため記事を書くことにしました。
記事を書くのは初めてなので、温かい目でみていただければ幸いです。
では、よろしくお願いします！

# 目的
**モデル名.new**、**モデル名.save**ってなんぞや
**空のインスタンス**ってなんぞや
ということを説明します。
使い方の説明ではないので、使い方を知りたい方はほかの記事を探してください。

# モデル名.newとは
モデル名.newの説明の前に**モデル**の説明をしておく必要があります。
モデルとは**データベースとやり取りをするところ**です

![qiita.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2916411/5f68ae7e-a084-78b3-4c3e-6989e67c254e.jpeg)

そして、今回はデータベースに**booksテーブル**があり、booksテーブルには**titleパラム**が登録できるとします。

![qiita1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2916411/64bee6ea-36f1-a5d1-3553-0e3936867011.jpeg)

そして、モデル名.newとすると**空のインスタンス**を作成します。
つまり、モデルくんはデータを登録するための**空っぽの箱**を用意してくれます。

![qiita2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2916411/81746e49-85cb-8c28-ccfc-3f8f377e9228.jpeg)

この箱が**空のインスタンス**です。

![qiita3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2916411/fba44bcf-808a-4559-a7a1-effaea6d303f.jpeg)




# モデル名.saveをすると
モデルくんがデータベースに**箱の中身の内容を登録**しに行ってくれます。

![qiita4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2916411/907144a7-d686-65e9-3ef3-bbbd2a91abf2.jpeg)

![qiita5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2916411/02caf321-436a-3986-6f9a-9be492546361.jpeg)

以上、モデル名.newとモデル名.saveの説明になります。
わからないことがあればコメントお願いいたします！

# まとめ
最後までご覧いただきありがとうございます!!
モデルがデータを入れる空っぽ箱を用意してくれる。これが、空のインスタンス変数、モデル名.newの仕組みです。
初学者の方の理解につながれば幸いです。

また、この記事に関して致命的なミスがあればコメントお願いいたします！
では、ありがとうございました！！
COCO形式（json）の物体検出アノテーションファイルを、yolo形式（txt）に変換するスニペット

# origin_x,origin_y,width,height を 正規化された center_x,center_y,width,heightに

COCOは単一のjsonファイルで、box座標は画像に対するサイズになっています。
yoloは画像一枚につき一つのtxtファイルで、box座標は0~1に正規化されています。

以下を実行すると、COCO形式のjsonファイルのデータを、yolo形式のtxtファイルにしてyolo_txt_save_dirに保存します。

```python
import os
import json

coco_json_path = 'coco.json'
yolo_txt_save_dir = 'yolo_txt/'

json_open = open(coco_json_path, 'r')
json_load = json.load(json_open)

annotations = json_load['annotations']
images = json_load['images']

for annotation in annotations:
  id = annotation['image_id']
  for image in images:
    if image['id'] == id:
      file_name = image['file_name']
      im_w = image['width']
      im_h = image['height']
      txt_path = os.path.join(yolo_txt_save_dir, os.path.splitext(os.path.basename(file_name))[0] + '.txt')
      bbox = annotation['bbox']
      x = bbox[0]-(bbox[2]/2)
      y = bbox[1]-(bbox[3]/2)
      bbox = [float(bbox[0])/im_w,float(bbox[1])/im_h,float(bbox[2])/im_w,float(bbox[3])/im_h]
      cls = int(annotation['category_id'])
      line = (cls,*bbox)
      with open(f'{txt_path}', 'w') as f:
        f.write(('%g ' * len(line)).rstrip() % line + '\n')
```

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

機械学習、ARアプリ（Web/iOS）を作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
golangにbool型のXOR演算子がない

# はじめに

某サイトのプログラミングスキルチェックで、練習のためgolangで簡単な問題を解いていました。
私は他の言語では、もう…それはもう仕事では出せないような変態的な手法等使って解いたりしていて、それが脳の端でちらつき、不慣れな言語ではどうやってやるのだろうか、と検索をかけたりしています。

# 問題について

```golang
if (/* 式1 */) /*XOR演算子*/ (/* 式2 */) {
  // 処理A
} else {
  // 処理B
}
```
問題を解くにあたって、`bool`型のXOR演算子を使いたい、と思った場面がありました。
しかし、「golang xor」で検索すると、`int`型同士のビット演算ばかりが検索画面に並びます。
ならばと「golang xor bool」で検索しても、XORではない演算子のみが出てきます。
更に調べると……そもそも`bool`型に対するXOR演算子など無いことが判明しました。

# 解決法

しかしよく考えてみれば、XOR演算子ではないものの、同等の役割を持つものがありました。

```golang
if (/* 式1 */) != (/* 式2 */) {
  // 処理A
} else {
  // 処理B
}
```

それぞれの式が`true`, `false`のときどのような結果になるかを考えれば、たしかにそうだった、と思ったのでした。

# 最後に

思考が膠着して、簡単な解決法を見落とさないようにしたいものです……。
Pixoo64のREST APIを使ってみた③

前回から引き続きPixoo64のAPIの説明です。
# tool(ツール)

### Set Countdown tool
タイマーのツールを起動するAPIです。
分と秒、ステータス(1:開始、0:停止)をセットします。
```json:リクエスト
{
  "Command": "Tools/SetTimer",
  "Minute": 3,
  "Second": 0,
  "Status": 1
}
```
爆弾アニメーションのタイマーが開始されます。
00:00になると爆発アニメーションが流れ、ピピッ、ピピッ、っと電子音が鳴ります。
カップラーメンや休憩時間などのタイマーとして使えます。
![tool_1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2483228/66c18116-20dc-7cc5-0aac-2155b30372cf.jpeg)

### Set stopwatch tool
経過時間を計測するツールを起動するAPIです。
ステータス(1:開始、0:停止、2:リセット)をセットします。
```json:リクエスト
{
  "Command": "Tools/SetStopWatch",
  "Status": 1
}
```
秒単位で経過時間を数えます。
ひよこのアニメーションで経過時間を表示します。
![tool_2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2483228/158a46ed-6908-1d72-6c1a-6e370c114634.jpeg)

### Set scorebord tool
スコアボードを起動するAPIです。
青のスコアと赤のスコアを設定します。
```json:リクエスト
{
  "Command": "Tools/SetScoreBoard",
  "BlueScore": 357,
  "RedScore": 123
}
```
上下に赤と青のスコアが表示されます。
あまり使い道がないような・・・
![tool_3.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2483228/5af6951d-a5ce-c49d-14ce-e9592313b951.jpeg)

### Set noise tool
騒音計測を起動するAPIです。
ノイズステータス(1:開始、2:終了)を指定できます。
```json:リクエスト
{
  "Command": "Tools/SetNoiseStatus",
  "NoiseStatus": 1
}
```
スペクトルみたいなアニメーションがありますが、周波数や音の大きさとは関係ありません。
騒音が気になるときにどうぞ。
![tool_4.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2483228/66e4677d-4710-38b2-86b6-5e4f45e02577.jpeg)

以上、toolのAPIでした。
次回はいよいよアニメーション機能です。
CakePHPのEntityでの時刻の取り扱い

## エンティティの日時のフィールド
Date型、DateTime型のフィールドにデータをセットすると、
`Cake\I18n\FrozenDate`または`Cake\I18n\FrozenTime`のオブジェクトに変換される。
```php
// エンティティのDateTime型フィールドを出力すると
// debug($entity->dt_field);
object(Cake\I18n\FrozenTime) {
    'time' => '2022-10-15 00:00:00.000000+09:00'
    'timezone' => 'Asia/Tokyo'
    'fixedNowTime' => false
}
```
DBから取得した際も同様のオブジェクトとなる。

### FrozenTimeってなに
> 組み込みの DateTime クラスを拡張し、便利なメソッドやロケールを考慮したフォーマットヘルパーを提供する

[Class FrozenTime \| CakePHP 4.4](https://api.cakephp.org/4.4/class-Cake.I18n.FrozenTime.html)
[日付と時刻 - 4.x](https://book.cakephp.org/4/ja/core-libraries/time.html)

要は日時を便利に扱えるオブジェクトらしい。

## 書式出力
#### デフォルト出力
フィールドをそのままechoすると、デフォルト書式で出力される。
（マジックメソッド`__toString()`で出力が実装されている）
```php
echo $entity->dt_field;
// 2022/09/01 0:12
```

同様の出力をするには`nice()`でも可。
```php
echo $entity->dt_field->nice();
// 2022/09/01 0:12
```
このときのデフォルト書式は、ロケールによって決まっている。

#### フォーマットを指定する
デフォルト以外のフォーマットを指定するには、以下の通り。
その時の出力だけ変更する場合は`i18nFormat()`。
```php
echo $entity->dt_field->i18nFormat('yyyy-MM-dd');
// 2022-09-01
```

または`setToStringFormat()`。
これはデフォルト書式自体を変更するstaticメソッドなので、一度実行するとその後のすべてのデフォルト書式出力はこのフォーマットが使用されることになる。
```php
FrozenTime::setToStringFormat('yyyy年MM月dd日 HH:mm:ss');
echo $entity->dt_field;
// 2022年09月01日 00:12:34
echo $entity->dt_field2;
// 2022年10月01日 01:23:45
```


これらの書式を設定する際は、フォーマット書式は組み込みの`date()`で使用する書式（`'Y-m-d'`など）ではなく、`IntlDateFormatter` の書式であること。
[PHP: IntlDateFormatter - Manual](https://www.php.net/manual/ja/class.intldateformatter.php)

フォーマット詳細
[Formatting Dates and Times - ICU Documentation](https://unicode-org.github.io/icu/userguide/format_parse/datetime/#date-field-symbol-table)

### 特定の書式で出力
定型出力のメソッドもある。
以下はMySQLなどで使う`date('Y-m-d H:i:s')`の形に出力する。
```php
echo $entity->dt_field->toDateString();
// 2022-10-01
echo $entity->dt_field->toDateTimeString();
// 2022-10-01 00:12:34
```
ほか、様々な固定の出力形式がある。
apiで「toXXXString()」のメソッドを探すといろいろある。

## 日時操作
ほか、日時比較や計算など便利な関数がたくさんある。
[CakePHP3のChronosの機能紹介 - Qiita](https://qiita.com/Gro/items/96f268a46c09136ba4dc)

## 参考
[CakePHP 4 で日時表示の初期フォーマットを設定する方法 / Twin Turbo Computing](https://tt-computing.com/cake4-date-time-default-format)
pingで呼び出したらpongを返すAPIを作る

http://localhost:3000/ping で呼び出したらpongという文字列が返ってくるAPIを
Node.jsのWebアプリケーション・フレームワークであるExpressを使って作ってみました。
Hello, world!から一ミリくらい前に踏み出してみようという気持ちです。

この記事はExpressのチュートリアルを参考にしています。
https://expressjs.com/ja/starter/hello-world.html

# Node.jsのバージョン管理ツールをインストール
個人的には、anyenv + nodeenvで管理するのが好きです。

https://github.com/anyenv/anyenv

https://github.com/ekalinin/nodeenv

# Node.jsのインストール
ここでは説明しません。

# Yarnのインストール
以下のページを参考にyarnをインストールします。

https://yarnpkg.com/getting-started/install

# Node.jsのプロジェクトを作成
```
yarn init -y
```

# Expressをインストール
```
yarn add express
```

# APIを作成
今回はapp.jsというファイル名で作成しました。 
```
const express = require('express')
const app = express()
const port = 3000

app.get('/ping', (req, res) => {
  res.send('pong')
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})
```

# アプリケーションの実行
以下のコマンドを実行して、アプリケーションを実行します。
```
node app.js
```
【Xcode14】iPadを非対応にする

# はじめに
Xcode14から色々と操作が変わって「これってどうやってやるんだ？」ということが割とあるので毎回記事にできたらなと思います。
今回はXcode14でiPadを非対応にしたいという記事です。

# やりかた
① プロジェクトを選択します
② ターゲットを選択します
③ 「Build Settings」を選択します
④ `Targeted Device Families`と検索欄に入力します
⑤ 背景が緑色の欄をタップします
![スクリーンショット 2022-10-13 20.34.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/dc6b01bd-001f-ffa0-7adb-bc7be7237379.png)

⑥ 「iPhone」を選択します
![スクリーンショット 2022-10-13 20.43.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/d48488b7-1e4b-0194-ead3-f75056b245e5.png)

# 確認
iPadでビルドしてみます。
iPhoneのサイズで表示されていたら成功です
![スクリーンショット 2022-10-13 20.46.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/9c0df97b-3ae0-298e-cb34-7ee153d0d715.png)

# おわり
めっちゃわかりにくい場所に移動してました笑
php artisan env:***で.envファイルを暗号化 / 復号

趣味でも仕事でも一人で開発してることが多いから個人的な恩恵は少なめなのが悲しい。ざんねん。

## 前提
laravelの最新バージョンに`php artisan env:***`というコマンドが追加されていた。
追加されたのは[v9.32.0](https://github.com/laravel/framework/releases/tag/v9.32.0)（[New env:encrypt and env:decrypt commands](https://github.com/laravel/framework/pull/44034)）

```shell
$ php artisan list
Laravel Framework 9.35.1
~~~

env
  env:decrypt            Decrypt an environment file
  env:encrypt            Encrypt an environment file

~~~
```

.envファイルを暗号化/復号出来るコマンドで、.envのデータをバージョン管理に含めたり、環境変数の共有を楽に行うために使えるらしい。

## env:encrypt（暗号化）
`php artisan env:encrypt`は.envファイルの暗号化を行います。
```shell
$ php artisan env:encrypt

   INFO  Environment successfully encrypted.

  Key ........................... base64:GW0IlxjauR28cLyrpngio8n9t38+KftI+GUd8h+7gh4=
  Cipher ................................................................ AES-256-CBC
  Encrypted file ..................................................... .env.encrypted
```
暗号化され出力されたファイルはEncrypted fileとして表示されます。（↑の場合は **.env.encrypted**）

### オプション
暗号化方式やキーは`--cipher`オプションや`--key`オプションを使用して指定することが可能です。
```shell
$ php artisan env:encrypt --cipher=*** --key=***
```

**ERROR  Encrypted environment file already exists.** のエラーが表示された場合は`--force`オプションを付け既存のファイルを上書き指定することで解消されます。
```shell
$ php artisan env:encrypt --force
```

`--env`オプションは暗号化する.envファイルを指定することが可能です。
例えば、**.env.local**を暗号化する際は下記になります。
```shell
php artisan env:encrypt --env=local

   INFO  Environment successfully encrypted.

  Key ........................... base64:1X2FMrmvY5ISMXDQ0utoogiTmwBTzvq4ar1dYTEV7ac=
  Cipher ................................................................ AES-256-CBC
  Encrypted file ............................................... .env.local.encrypted
```


## env:decrypt（復号）
`php artisan env:decrypt`は **.env.encrypted**ファイルの復号を行います。
```shell
$ php artisan env:decrypt --key=base64:*** --force

   INFO  Environment successfully decrypted.

  Decrypted file ............................................................... .env
```
### オプション
`--force`オプションは常につけておいてもいい気がします。
（消してはいけない.envが上書きされないように注意）

`--key`オプションには暗号化時に取得したKeyを**base64:** のプレフィックスも含めて指定してください。
もし暗号化時に暗号化方式も指定していた場合は、同様に`--cipher`オプションの指定が必要です。

**env:encrypt**と同様に`--env`オプションで.envファイルの指定が可能です。
加えて、**env:decrypt**では`--filename`オプションで復号後のファイル名を指定することも可能です。
```shell
# .env.local.encryptedを復号し、.env.localが出力される
$ php artisan env:decrypt --key=base64:*** --force --env=local

# .env.test.encryptedを復号し、.env.tmpが出力される
$ php artisan env:decrypt --key=base64:*** --force --env=test --filename=.env.tmp
```

## おまけ
**復号**派ですか？**復号化**派ですか？
【Linux】ファイルの特定の行のみ取得する方法

## 1行目のみ取得する

ファイルの1行目のみ取得するには以下のように実行します。

```zsh
head -n 1 対象ファイルパス
```

## 指定した行のみ取得する

指定した行のみ取得するには以下のようにします。

```zsh
sed -n 行数p 対象ファイルパス
```

`./sample.txt`の5行目を取得する場合には以下のように実行します。

```zsh
sed -n 5p ./sample.txt
```

## 指定した行以降を取得する

指定した行以降を取得するには以下のようにします。

```zsh
sed -n '開始行,$p' 対象ファイル
```

`./sample.txt`の5行目以降を取得するためには以下のように実行します。

```zsh
sed -n '5,$p' ./sample.txt
```
対話データを増やす方法 

## 日本では言語処理のデータセットを公開しないところが多い

日本では言語処理のデータセットを公開しないところが多いという事実は結構うざいです。
なので、散々悩んだ僕は、いいことに気づきました。
他の国の対話データセット（オープンソース）を使えばいいのです。
しかし、英米つまり英語は文化の差でうまく使えるとはおもいません。
韓国だったら、似てるから使えるのでは？とおもいました。

**韓国では、オープンデータが多いのです。** なぜでしょう？
これは**日本がオープンデータを作ることで負けている**ことを表しています。
今の状況は日本語の言語処理入門者に苦情しか出ないものに限りません。
それを解決する前に、僕らが取れる一番手っ取り早い方法をご紹介させていただきます。
それは、PAPAGO APIを使うのです。

```python
import requests


client_id = "" # Client ID 
client_secret = "" # Client Secret 
url = "https://openapi.naver.com/v1/papago/n2mt"


def translator(input_text):
  req_header = {"X-Naver-Client-Id":client_id, "X-Naver-Client-Secret":client_secret}
  req_param = {"source":"ko", "target":"ja", "text":input_text}
  #print(req_param)
  res = requests.post(url,headers=req_header, data=req_param)
  #print(res.status_code, res.ok)

  if res.ok:
      trans_txt=res.json()['message']['result']['translatedText']
      return trans_txt
  else:
      return ""
```

この関数を用いることで、簡単に翻訳できます。もちろん、使う前にAPIセンターに登録が必要です。
残念ながらpapago以外のいい翻訳機は見当たりません。Googleも勝てません。
（現在、翻訳の仕事もしているからわかります。）
記事は以上です。ざつなので申し訳ないですが、ご参考いただければとおもいます。
LPC812MAXで3個のLEDでRGB(赤、緑、青)(2)


x mbed2リビジョン144
x リビジョン変更がわかる人むけ

目的

基本テスト


![o_cop108.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/6ca3b28d-dad5-c986-d6e5-ae4fb58c17ab.jpeg)



```c++


//mbed_binky_812_RGB_V2

#include "mbed.h"

//GPIOの初期化
DigitalOut myled_r(LED_RED);   //red
DigitalOut myled_g(LED_GREEN); //green
DigitalOut myled_b(LED_BLUE);  //blue

int main()
{

    myled_r = 1; //red
    myled_g = 1; //green
    myled_b = 1; //blue

    //無限ループ
    while(1) {

        myled_r = 0; //red ON
        wait_ms(1000);
        myled_r = 1; //red OFF
    
        myled_g = 0; //green ON
        wait_ms(1000);
        myled_g = 1; //green OFF
    
        myled_b = 0; //blue ON
        wait_ms(1000);
        myled_b = 1; //blue OFF
    
    }//while

}//main




```
javascriptのawaitにタイムアウトを設定したい

### 通常の `await`

```typescript
// ただ１秒待つだけの関数
async function sleepOneSec() {
  await new Promise((resolve) => setTimeout(resolve, 1000));
}

async function main() {
  await sleepOneSec();
}

// 実行
main();
```

---

### `await` with timeout

```typescript
/**
 * await にタイムアウトを設定する
 *
 * timeoutを超えて await で待機すると UnhandledPromiseRejection 例外が throw されます。
 * @param {Promise} promise - 実行したい promise 関数
 * @param {number} timeout - タイムアウト(ms)
 * @returns Promise<T>
 */
export function withTimeout<T>(promise: Promise<T>, timeout: number) {
  const errorMessage = `await での待機が ${timeout}ms を超えました`;

  const timeoutPromise: Promise<T> = new Promise((_, reject) =>
    setTimeout(() => reject(errorMessage), timeout),
  );
  // Promise.race()を利用して先に解決した方を優先する
  return Promise.race([
    promise, // 本来実行したい promise 関数
    timeoutPromise, // こちらの方が早く解決すると reject()
  ]);
}

// ただ１秒待つだけの関数
async function sleepOneSec() {
  await new Promise((resolve) => setTimeout(resolve, 1000));
}

async function main() {
  // OK (タイムアウト２秒)
  await withTimeout(sleepOneSec(), 2000);

  // NG (タイムアウト0.5秒)
  await withTimeout(sleepOneSec(), 500);
  /*
  [ERROR] 19:45:13 UnhandledPromiseRejection:
    This error originated either by throwing inside of an async function without a catch block,
      or by rejecting a promise which was not handled with .catch().
    The promise rejected with the reason "await での待機が 500ms を超えました".
  */
}

// 実行
main();
```

---

`await` で長時間待ちたくない時によいな…と思ってたのですが [await-timeout](https://github.com/vitalets/await-timeout)　なるものが既にありました。
【Rails】コンソール内でmigrateする方法

## 環境
Rails 6.0.1
Ruby 2.6.3
PostgreSQL 11.16

## コンソール内でmigrateする方法
コンソールでUserを作成しようとした際にエラーでできず、最終的にコンソール内でmigrateするのに時間がかかったので備忘録にする。

```
> User.create(name: "山田次郎")
=> ActiveRecord::StatementInvalid (PG::UndefinedTable: ERROR:  relation "users" does not exist)

> User
=> User(Table doesn't exist)

> rails db:migrate
=> NameError (undefined local variable or method `migrate' for main:Object)
```

```
> class CreateUsers < ActiveRecord::Migration[6.0]
>   def change
>     create_table :user do |t|
>       t.string :name

>       t.timestamps
>     end
>   end
> end

> ActiveRecord::Migration.run(CreateUsers)
-- create_table(:users)
   -> 0.0132s
=> [CreateUsers]
```

これで```User.create```することができた。

## 参考

https://qiita.com/shota-yamashita/items/cd6afe0759f3f30f7dff
laravel　controller内でbladeファイルのoldの値を使う方法メモ

# やりたいこと
laravelのbladeファイルで使ってるold機能の値をcontrollerで取得する

<a id="#Chapter2"></a>
# 方法
コントローラー内で \old('') を使う
例）hogeController
```
public function create()
{
    $name = \old('name');
}
```

oldはファサードのため、バックシュラッシュ（\）を使って値を取得できるようだった
なお、初期表示などでoldに値が入っていない場合はnullが代入されていた

<a id="#reference"></a>
# 参考文献
- [[laravel]controller内でoldを取得したい - Teratail](https://teratail.com/questions/227082)
- [Laravelでフォームの値を保持する（oldヘルパーについて）](https://codelikes.com/laravel-old/)
- [Laravel5.1入門 その10 はじめてのFacade - Perl日記](https://r9.hateblo.jp/entry/2015/06/29/233000)
【Rails】ActiveStorageはdependent: :destroyをつけなくてもよい

## 環境
Rails 6.0.1
Ruby 2.6.3
PostgreSQL 11.16

## has_one_attachedにオプションは不要

```app/models/user.rb
has_one_attached :avatar
```

> If the :dependent option isn't set, the attachment will be purged (i.e. destroyed) whenever the record is destroyed.


```ruby
has_one_attached :avatar, dependent: :destroy
```
のようにオプションつけなくても、親モデルが削除されたら付随するavatarも削除してくれる！

https://api.rubyonrails.org/v6.0/classes/ActiveStorage/Attached/Model.html#method-i-has_one_attached
MySQLのGeometry型に範囲を超過した緯度経度が登録出来てしまう

まず、緯度経度は
緯度が赤道を0度とし、南北へそれぞれ90度存在しているため、
-90~90の範囲内になっている。

経度が旧グリニッジ天文台跡（ロンドン）を通る南北の線（茶色の線）を0度とし、東西へそれぞれ１８０度まで表しているため、
-180~180の範囲内になっている。

また、MySQLのGeometry型だが、
左が経度で右が緯度になっている。

```sql
mysql> select ST_AsText(latlng) from geometry_table;
+----------------------------------------------+
| ST_AsText(latlng)                            |
+----------------------------------------------+
| POINT(139.47433610169114 35.328525318453075) |
+----------------------------------------------+
```

ただ、登録しようとすると、緯度経度を逆に登録出来てしまう。
また、特にエラーにもならない。

```sql
mysql> update geometry_table set latlng = GeomFromText('POINT(35.328525318453075 139.47433610169114)');
```

```sql
mysql> select ST_AsText(latlng) from geometry_table;
+----------------------------------------------+
| ST_AsText(latlng)                            |
+----------------------------------------------+
| POINT(35.328525318453075 139.47433610169114) |
+----------------------------------------------+
```

上記のように、範囲外で登録されていると、位置情報がおかしくなる事もそうだが、
ST_Distance_Sphereを利用する時など、エラーになる原因に気が付かずにハマりやすい。

```sql
mysql> select ST_Distance_Sphere(ST_GeomFromText('POINT(139.47433610169114 35.328525318453075)'), ST_GeomFromText( CONCAT('POINT(',ST_X(latlng),' ',ST_Y(latlng),')') )) as distance from geometry_table;
ERROR 1210 (HY000): Incorrect arguments to st_distance_sphere
```

## 参考

* https://www.pasco.co.jp/recommend/word/word026/
Defoldでビットマップ画像を綺麗に表示する方法

# 対策をせずに画像を取りこむと
このように画像がぼやけて見えます。
![images_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917170/9f0a9b08-2f11-71bc-be73-72267518934c.png)

# 対策
### 1.aseetsの画面からgame.projectのファイルを選択
![images_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917170/222b3e4e-a4b8-bef7-f7cb-a6f38ec16189.png)
### 2.下にスライドしてGraphicsを選択
![images_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917170/4c45c0f8-b6b7-21df-ffcf-beb22867742e.png)
![images_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917170/55ebea5a-1523-d935-880e-cbfe97010823.png)
### 3.DefultTextureMagFilterをlinearからnearestに変える
![images_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917170/47d447db-8325-bdff-71a5-bf5890d547ef.png)
![images_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917170/2836706a-7650-358f-4743-2dd6d86eb401.png)

:::note info
*nearestに変更した後に保存することを忘れないように
:::
### fin.画像が綺麗に表示されました。
![images_7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917170/9cfb78ff-1128-97cc-b0dd-690833b2661a.png)
【Laravel】JSONでintegerがstringで返ってしまう

## 環境
Laravel v9.5.1 (PHP v8.1.3)

## 状況
Userの```role```をenumを使って返していたのでてっきり```integer```で返ると思っていたら、JSONの返り値が文字列になっていた。
```php
namespace App\Enums;

enum UserRole: int
{
    case Owner = 1;
    case Admin = 2;
    case Member = 3;
}
```

```
{
  "id": 1,
  "name": "山田太郎",
  "avatar": "https://www.gravatar.com/avatar/xxxxxxxxx",
  "role": "2"
}
```


原因はmigrationファイルでroleを```string```にしており、JSONではDBから引っ張ってきているため文字列で返っていた。


## 解決法

Userモデルに下記を追記する。

```app/Models/User.php
protected $casts = [
  'role' => 'integer'
];
```

## 参考
https://zukucode.com/2017/08/laravel-mysql-json.html
LPC812MAXのPWMを使う(3)


x mbed2リビジョン144
x リビジョンの変更ができる人むけ

目的
使ってみたかった
LED等を繋げる


![o_cop107.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/d0a2da26-9eb2-33a6-e6ba-aaa2f96954e8.jpeg)




```c++


//PWM_LED_RED_812_1

#include "mbed.h"

//PWMのピンの設定
PwmOut servo(LED_RED); //812

//メイン関数
int main()
{

    //周期の設定
    servo.period_ms (20); // servo requires a 20ms period

    //無限ループ
    while(1) {

        for(int offset = 0; offset<20; offset++) {

            //値をセット
            servo.pulsewidth_ms( offset );

            //0.1秒まつ
            wait_ms(100);

        }//for

    }//while

}//main



```
【React】テキストボックス1でエンターキーを押してテキストボックス2にフォーカスを変更する

タイトル通り、Reactでテキストボックス1でエンターキーを押してテキストボックス2にフォーカスを変更できるよう実装します。

```html:sample.html
<div className="TextBox1">
 テキストボックス1<br />
 <input type="text" id="textbox1" onKeyDown={handleKeyDown} />
</div>
<div className="TextBox2">
 テキストボックス2<br />
 <input type="text" id="textbox2" />
</div>
```

```typescript:sample.tsx
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
  if (e.nativeEvent.isComposing || e.key !== "Enter") return;
  // 次のテキストボックスへ飛ばす処理を記載
  document.getElementById("textbox2")?.focus();
};
従来版Db2とDb2 on Cloud, Db2 Warehouse on Cloudの比較記事一覧


多様なニーズにあわせて色々な形態で提供される各Db2製品のうち、
従来型(オンプレミス)のDb2と、DBaaS である Db2 on Cloud や
Db2 Warehouse on Cloud(以下、Db2WoC) について
どちらが適するか比較検討する際に、ポイントとなりそうな点が整理された記事一覧を作成しました。

## IBM Db2データベースの種類
[2022年6月のDb2製品ラインナップを整理してみる](https://qiita.com/mi-kana/items/f995a924ac6e3368d1db)

## 従来型のDb2と、DBaaS の比較 
[Db2と、Db2 on Cloudと、Db2 Warehouse on Cloudは何が違う？ ~基本編~](https://qiita.com/mi-kana/items/566b7aa1a0ee4fb3dcb4)
[Db2と、Db2 on Cloudと、Db2 Warehouse on Cloudは何が違う？ ~導入構成編~](https://qiita.com/mi-kana/items/003be6cda6b80718c70c)
Db2と、Db2 on Cloudと、Db2 Warehouse on Cloudは何が違う？ ~運用編~ (3分冊)
 * 1.[バックアップ/リストア](https://qiita.com/cotflow/items/73fce70958fd27599ac3)
 * 2.[統計情報取得/再編成](https://qiita.com/mi-kana/items/1b7f3af2138cea631db0)
 * 3.[モニタリング/監視](https://qiita.com/Haruka-Ogawa/items/ee07a302047b788940c4)

## DBaaS へのデータ移行方法/ツール
[[Db2] オンプレからクラウド(DBaaS)へのデータ移行方法](https://qiita.com/Haruka-Ogawa/items/8f2e770195780b304c09)

## Db2 on Cloud , Db2WoC への接続方法
CLPPlusは、MacOS含め現在広く利用されるほとんどのOSに導入可能な、
無償のDb2コマンドライン操作ツールです。
デフォルトでSSL接続が必須となる Db2 on Cloud , Db2WoC への、CLPPlusからの接続方法が
こちらの記事に整理されています。

　→　[Db2 on Cloud / WoC への CLPPlus 接続手順](https://qiita.com/Haruka-Ogawa/items/9aa0c14e695d7d68e3de#3-2-ssl%E6%8E%A5%E7%B6%9A)

__補足：__
WindowsやLinuxのPCがあれば、Db2クライアントを導入することで利用可能となる、Db2従来のコマンドラインツールであるCLPを利用して、Db2サーバに接続することができます。
しかしMacにはDb2クライアントが提供されておらず、Db2ドライバーパッケージのみ利用可能となっています。この場合CLPは利用できませんが、その代わりにPureJava実装のコマンドラインツールである、CLPPlusを利用することが出来ます。
【Laravel】日付に関するバリデーション判定集

## 環境
Laravel v9.5.1 (PHP v8.1.3)

## 日付に関するバリデーション判定集
特定のユーザーの投稿を期間を指定して集計したいとき、```$from```と```$to```に投げられるパラメータに日付ならではのバリデーションをつけたい。
```php
$user->postAggregations
     ->whereBetween('created_at', [$from, $to]);
```

投げられた日付パラメータが

- 「2022-1-1」のようなハイフン以外の場合


```php
if (! DateTimeImmutable::createFromFormat('Y-m-d', $from) || ! DateTimeImmutable::createFromFormat('Y-m-d', $to)) {
    throw new InvalidDateFormatException();
}
```

- 存在しない日付の場合

```php
list($fromY, $fromM, $fromD) = explode('-', $from);
list($toY, $toM, $toD) = explode('-', $to);
if (! checkdate($fromM, $fromD, $fromY) || ! checkdate($toM, $toD, $toY)) {
    throw new InvalidDateFormatException();
}
```
- 終了日が開始日より前の日付の場合
```php
if ($from > $to) {
    throw new SpecifyEndDateAfterStartDateException();
}
```

## さいごに
各処理をメソッドにしたり、```$from```と```$to```をコンストラクタにしてクラスにしたりといろいろ使えると思います！
JavascriptをHTMLファイルに反映させる方法

# はじめに
学習中のJavascriptについて自分用の備忘録としても書いていきます。
間違っている所等、ご指摘あれば教えてください。
## script要素
Script要素とはHTMLであり、HTML内で実行できるコードを埋め込んだり、参照する事のできる要素です。
```html
<script src = “参照したいファイル”></script>
```
以上のように記述します。
script要素はbody要素の一番最後に記述することが推奨されています。
理由は、HTMLはブラウザで上から読み込まれていくため、複雑なJavascriptがHTMLの上部に記述されていると、Webページが読み込まれるのが遅くなってしまうからです。（アプリケーションによってはhead要素内に記述することもある）
## イベント
JavascriptはHTMLで「何かが起きたら」コードが実行されます。
その「何かが起きたら」をイベントと呼びます。
具体的には、「クリックをする」や「カーソルが上にくる」などになります。
また、イベントを認識してJavascriptのコードが実行されることを「イベントが発火する」と言います。
## イベント発火のメソッド
イベントを認識して発火させる為には、どんな処理を発火させるかという記述が必要になります。
イベント発火の処理は’addEventListener’というメソッドを使用します。
```javascript
要素.addEventListener('イベント名', 関数)
```
上記のように記述します。
## HTML要素の取得
イベント発火をした際の処理を決めたら、今度は何に対してイベント発火をさせたいのかを決める必要があります。
JavascriptがHTMLを読んで認識できるものはHTMLのclass/id/selectorの３つです。
classを認識するには’getElementsByClassName’メソッドを使用します。
idを認識するには’getElementById’メソッドを使用します。
selectorを認識するには’querySelectorAll’メソッドを使用します。
それぞれ
```javascript
docment.取得メソッド('取得したいclassやid名')
```
上記のように記述することでHTMLの要素を取得できます。
## HTML要素を取得してイベント発火させる
上記で書いた取得と処理をつなぎ合わせる事で、HTMLで動的が処理を実行させる事ができます。
例として指定のclassのHTML要素に対してマウスカーソルが上に来た時発火させる記述を書きます。
```javascript
 const mouseOver = document.getElementById("header")

  mouseOver.addEventListener('mouseover', function(){
    console.log("mouseover OK")
  })
```
上記の記述は、まず変数mouseOverを定義して、headerというclassの要素を取得します。
次に、変数mouseOverで取得した要素に対し、マウスが上にきたらコンソールに’mouseover OK’と表示するという処理を記述しています。
‘mouseover’はマウスカーソルが要素の上にきたらイベント発火するというものですが、この他にもマウスカーソルが外れたらという’mouseout’やクリックしたらという’click’などの多数の発火条件の指定方法があります。
## 終わりに
まだまだ勉強中の身のため、基礎の基礎しか書けていませんが、同じように勉強中の方にとって参考になれば幸いです。
【Laravel】複合ユニーク制約を削除する方法

テーブルのユニーク制約を外す場合、マイグレーションファイルで`dropUnique`を使用する。

複合ユニーク制約を外す場合、複合ユニーク制約作成時に第2引数に指定したindex名を使用できる。

例：
ユニーク制約の追加時

```
    Schema::table('programs', function (Blueprint $table) {
        $table->unique(['program_id', 'account_id'], 'unique_program');
    });
```
ユニーク制約を外す時

```
    Schema::table('programs', function (Blueprint $table) {
        $table->dropUnique('unique_program');
    });
```
ActionController::InvalidAuthenticityTokenの対処方法

# 環境
Rails 6.1.6.1
ruby 2.6.8
OS WSL2(Ubuntu 20.04.2 LTS)

# APIを使用したPOSTの際にエラーが起こる
### エラー文
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294147/973e9c1f-9077-c629-0d11-0082f8e4334c.png)

```
ActionController::InvalidAuthenticityToken in Users::XXXXController#create
ActionController::InvalidAuthenticityToken
```


## 原因
CSRF対策のトークンが無いことが原因のようです。
※CSRF:クロスサイトリクエストフォージェリ

## 対処方法
protect_from_forgeryをcontrollerに追記することで解決
```
class Users::XXXXController < ApplicationController
  protect_from_forgery #追加
```
【メモ】 Netbeans + Corretto 8 でconsolasを使いたい！

やりたいこと
============

* Netbeansの等幅フォントをConsolasにしたい！

環境
=====

* Windows 10
* Java 8 (Corretto)
* Netbeans 12

やり方
=======

* JAVA_HOMEの場所を調べる。
* JAVA_HOME/lib/fontconfig.properties を作る。
* fontconfigのmonospacedのフォント指定をConsolasフォントファミリーに差し替える。
* Netbeansの再起動。

NetbeansのJAVA_HOMEの調べ方
------------------------------

%ProgramFiles%\Netbeans 12\netbeans\etc\netbeans.conf を開く。
netbeans_jdkhome の設定値が、NetbeansのJAVA_HOMEとなる。

※Windows環境変数のJAVA_HOME（jre8を参照している）のほうばかり見ていて、フォント差し替えられないなあと思っていました。fontconfigを差し替えるのはJDKのほうです。注意！

fontconfig.propertiesの設定
----------------------------

Qiitaにたくさん記事があります。省略。
公式ドキュメント: https://docs.oracle.com/javase/jp/1.5.0/guide/intl/fontconfig.html

※ JAVA_HOME\lib\fontconfig.properties.srcを適当にコピペしてfontconfig.propertiesにリネームし、monospacedの設定値を書き換えるのが楽。

結果
====

レジストリのFontLinkを変更してみてもNetbeansでの日本語の文字化けは解消しないし、どうしたものかと思っていましたが、とりあえずできました！（画像なし）
monospacedを書き換えたせいで、エディタの行番号部分もConsolasになってしまうのはご愛敬。
WSL Ubuntu22.04LTSインストール

# 1. WSL2のインストール
## Powershellを管理者権限で起動し以下を実行

```
# Windows Subsystem for Linux を有効にする
C:\Windows\system32> dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

# 仮想マシン プラットフォーム"のオプション コンポーネントを有効にする
C:\Windows\system32> dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all

# WSL2を既定のバージョンとして設定する
C:\Windows\system32> wsl --set-default-version 2
```

## Ubuntu 22.04 LTS（WSL2）のインストール
上記実行後、マイクロソフトストアよりUbuntu 20.04 LTSをインストールする

## WSL2を起動

```
$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"

```

# 2. 環境設定
```
$ sudo apt update			# パッケージを管理しているDBを最新の状態に更新
$ sudo apt dist-upgrade			# インストールされているパッケージを全更新。追加でパッケージが必要になった場合もインストールしてくれる

# LANG設定
$ sudo apt -y install language-pack-ja	# 日本語言語パックのインストール
$ sudo update-locale LANG=ja_JP.UTF8	# ロケールを日本語に設定
$ exit

# 再ログイン
$ date
2020年  4月  1日 水曜日 15:43:23 JST # 日本語表示を確認
```

# 3. ビープ音を消す

~/.inputrcに追記
```
set bell-style none
```

~/.vimrcに追記

```
set belloff=all
```
【RSpec】データ作成で使える小技

## 環境
Rails 6.0.1
Ruby 2.6.3
PostgreSQL 11.16

## テストデータの作成で使える小技

### before

```ruby
let(:cancel_applicatoions) { create_list(:cancel_applicatoion, 30) }
cancel_applicatoions.each do |cancel_applicatoion|
  create(:cancel_applicatoion_status, cancel_application: cancel_applicatoion)
end
```

### after

```create_list```で作成したデータをeachのようにループできる。
```ruby
create_list(:cancel_applicatoion, 30) do |cancel_applicatoion|
  create(:cancel_applicatoion_status, cancel_application: cancel_applicatoion)
end
```
Open3D含むROSパッケージのビルド

## 結論

ROSのpythonでのdependencyは、ROS特有のライブラリだけの話であって、pythonでimportするライブラリを`CMakeLists.txt`, `package.xml`に書く必要はない。



## 環境
- ROS1 noetic 
- WSL2(Windows11)
- Open3Dを含むROSパッケージ

## 再現手順

```
$ catkin build [Open3Dを含むROSパッケージ]
```
すると、以下のエラーが発生。
```sh
Could not find a package configuration file provided by "open3d" with any of the following names: 
open3dConfig.cmake 
open3d-config.cmake
```

# 原因

https://github.com/isl-org/Open3D/issues/2110#issuecomment-1061766465

Open3DConfig.cmakeをつくるためにソースからビルドする必要あり　↑issue元

# 対策

以下の記事を参考に、Open3Dをビルド

http://www.open3d.org/docs/release/compilation.html

そののち、`CMakeLists.txt`に以下を追加。

```txt
set(Open3D_DIR /usr/local/lib/cmake/Open3D)
find_package(catkin REQUIRED Open3D)
```

自分はWSL上で行っていて、cmakeのバージョンが低いと出たので、

https://zenn.dev/suudai/articles/8b484ac39fde38

も実行した。

https://qiita.com/gorou/items/747493ffa15a30b29f5c


## いろいろやったけど、結局だめ

最終的な解決策

Open3Dを含まない状態で、`catkin build`して、`rosrun`や`roslaunch`でパッケージ名が使えるようになったら、Open3Dを`CMakeLists.txt`, `package.xml`, コードに追加して実行する。

これでも、一応動くのでヨシ👈

## [追記]

ROSのpythonでのdependencyは、ROS特有のライブラリだけの話であって、pythonでimportするライブラリを`CMakeLists.txt`, `package.xml`に書く必要はない。
ビジネス文書研修を受けて

会社のビジネス文書に関する研修を受けてのアウトプットです。

背景
社外向けに記事を書くにあたり、文章の書き方を改めて基礎から学びたいと思い受講。

テーマ
相手に伝わる文書のポイントを確認。

個人的なポイント
１、日本語は主語が省略されることが多い
外人が困るところらしい。
文章では意識して主語をいれる。

２、想いが伝わらない文章を投げかけた時
「ご検討ください」とか書くことがあるが、思いが伝わっていないのに検討もできない。
検討しないで終わる。

３、論理の基本構造
主語
↓
論拠
↓
原因、事例
とつながる。課題解決の内容にも似ている。

４、トップダウンとボトムアップ
トップダウン＝どうして？をブレイクダウン
ボトムアップ＝だから何？を抽象化

５、MECEじゃないとき
「この部分が抜けてるよ。だからこの考えはおかしくない？」と疑われてしまう。
逆に「この部分かぶってるよ？」もだめ

６、相手を説得するには
論理的でないとだめ。
でも、論理的も完ぺきではなく頭で分かっていても感情で断られる場合もある。

一番のポイント
MECEの精度が最も腕が試されるポイントなんだろうと思う。

まとめ
知ってることが多かったが改めて勉強すると違う視点が生まれる
論理的な文章が作れるかどうかが力の差になる

RPGで例えると、攻撃力が強い人は論理的な文章を作れる人だと思う
逆に防御力が高いのは文章に配慮ができる人。
私は防御力に注力していた。

攻撃力を高める方法としては、トレーニングやアウトプットが必要。
読解力を鍛えるとかだけではロジカルシンキングの部分は養われない。
Google APIのOAuthトークンの失効について

Google APIのOAuthトークンの有効期限/失効について、挙動・仕様で少し気になる点があったため公式ドキュメントを漁ることにした。いくつか注意しておきたいポイントがあったので、メモとして残しておく。


公式ドキュメント: https://developers.google.com/identity/protocols/oauth2

## Refresh Tokenは複数発行でき、一定数を超えると古いものから無効化される

> Limits apply to the number of refresh tokens that are issued per client-user combination, and per user across all clients, and these limits are different. If your application requests enough refresh tokens to go over one of the limits, older refresh tokens stop working.

新しくTokenを発行しても、古いTokenは有効であり続ける(使われないと6ヶ月後に失効する 後述)。古いTokenを無効化するには明示的にRevokeする必要がある。

## Refresh Tokenが無効化されるパターン

> * The user has revoked your app's access.
> * The refresh token has not been used for six months.
> * The user changed passwords and the refresh token contains Gmail scopes.
> * The user account has exceeded a maximum number of granted (live) refresh tokens.
> * The user belongs to a Google Cloud Platform organization that has session control policies in effect.

* ユーザーがアクセス権を削除した場合(Googleアカウントのセキュリティ設定から削除可能)
* Refresh Tokenが**6ヶ月使用されなかった場合**
* TokenのScopeにGmailが含まれている状態でユーザがパスワードを変更した場合
* 発行されたRefresh Token(有効なもの)の数が制限を超えた場合
* Session control policiesが有効なGoogle Cloud Platform organizationに所属している場合

> A Google Cloud Platform project with an OAuth consent screen configured for an external user type and a publishing status of "Testing" is issued a refresh token expiring in 7 days.

プロジェクトの設定が外部ユーザへ開放されていて、かつTesting状態の場合はRefresh Tokenは**7日間で失効する**。

> There is currently a limit of 100 refresh tokens per Google Account per OAuth 2.0 client ID. If the limit is reached, creating a new refresh token automatically invalidates the oldest refresh token without warning. This limit does not apply to service accounts.

1クライアント(アプリケーション)あたり、サービスアカウントを除いて100個までRefresh Tokenを生成できる。それ以上生成しようとすると古いものから失効していく。


## アクセス権の削除

* アクセス権を削除すると、Refresh Tokenが無効化され、また有効期限内のAccess Tokenを使ってもAPIを呼び出すと400 Bad Requestが発生するようになる。ただし、後述の通り**SDK経由でAPIを呼び出した場合、失効後もしばらくエラーが返ってこないことがあるので注意。**
* アカウント設定画面からアクセス権を削除した場合、発行されているすべてのRefresh Tokenが無効化される。**個別に無効化することはできない**。キーのローテーションをしたいような場合に、この機能は使えない。

## Tokenの無効化

https://developers.google.com/identity/protocols/oauth2/web-server#tokenrevoke

* Refresh TokenもしくはAccess Tokenはアプリケーション側から無効化することもできる。
* **Token単位でRevokeできる**ので、複数Tokenが発行されていて特定のTokenだけ無効化したいような場合はこの機能を使う。

## おまけ: Tokenが失効しているはずなのにAPIからエラーが返ってこない

Refresh Tokenを失効させたはずなのに、expiryを過ぎたAccess Tokenを使ってSDK経由でAPIを呼び出すとレスポンスが返ってきてしまうことがある。調べてみたところどうやらSDK内部でレスポンスをキャッシュする機構があるようで、パラメータの内容を変えてAPIを叩き直してみたところ無事エラーが返ることを確認できた。若干厄介な挙動だ。
WSL2内のneovimでフォントが反映されないときの対応

## はじめに
最近neovimはじめました。諸先輩方よろしくお願いいたしますm(_ _)m
さて、掲題のとおりフォントが反映されないときの対応です。
通常のフローであれば
1. windowsにフォントをインストール
1. wslの画面開いて、画面上部右クリックの規定値を開く
1. フォントやフォントサイズを変更

でwsl2内のフォントが変わり、nvimでファイル開いてもフォントが反映されています。
今回私が遭遇した現象は
**wsl2のターミナルではフォントが変わってるがvim/nvimで開いた画面でフォントが変わっていない**
という状態です。


## 対応
1. 標準でインストールされている「レジストリエディター」を起動
1. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage　　まで移動
1. 以下のそれぞれの値を変更する（一応変更前の値はメモっておこう）
    > "ACP"="1252"
"MACCP"="10000"
"OEMCP"="437"
1. PC再起動

これでvim/nvimで開いた画面でもフォントが反映されています。



## 参考
https://github.com/microsoft/Terminal/issues/177#issuecomment-468117902
VSCode の Code Runner で Jest のテストを実行する

調べると [Jest](https://marketplace.visualstudio.com/items?itemName=Orta.vscode-jest) というそのものズバリな拡張が存在するが、
[Code Runner](https://marketplace.visualstudio.com/items?itemName=formulahendry.code-runner) ユーザーであれば ↑ を入れる必要はなく、下記の設定を書くだけで良い。

```json:settings.json
"code-runner.executorMapByGlob": {
    "*.test.ts" : "npx jest $fullFileName",
    "*.spec.ts" : "npx jest $fullFileName",
    "*.test.js" : "npx jest $fullFileName",
    "*.spec.js" : "npx jest $fullFileName"
}
```

余談だが、デフォルトの出力は色がつかず Jest の結果が見づらいので、出力をターミナルに指定しておくと色がついて見やすい。

```json:settings.json
"code-runner.runInTerminal": true,
```
Macでwebpackがうまく走らなくなった際にした対処

# Macでwebpackがうまく走らなくなった際にした対処

## 概要
ある日突然webpackがうまく走らなくなった。
正確には走らせた後に途中で停止してしまい、コマンドを受け付けなくなってしまった。

結論から言えばNode.jsとnpmのバージョンのずれが問題であった。
最終的にはNode.jsをv12.22.12, npmを6.14.16をすることで解決した。

しかしv12.22.12はlatestではないため、他案件の開発時に問題が生じる。
そこでNode.jsとnpmのバージョンを適切にあわせつつ、
バージョンを手軽にスイッチできるツールであるnodebrewを導入した。

本稿ではインストール済のNode.jsとnpmのアンインストール手順と、
nodebrew導入〜その利用までの手順を解説する。

## Node.jsとnpmのアンインストール

次のコマンド3つを実行。

```.bash
sudo npm uninstall npm -g
lsbom -f -l -s -pf /var/db/receipts/org.nodejs.pkg.bom | while read i; do sudo rm /usr/local/${i}; done$ sudo rm -rf /usr/local/lib/node /usr/local/lib/node_modules /var/db/receipts/org.nodejs.*
sudo rm -rf ~/.npm

```

アンインストールされているかはバージョン確認のコマンドを打って確認。
command not found であればOK

```.bash
npm -v
node -v
```

## nodebrewをインストールする
次のコマンドでnodebrewをインストール。

```.bash
curl -L git.io/nodebrew | perl - setup
```

うまくいけばパスを追加しなさいとの旨のメッセージがでるので次にパスの追加を行う。
`/.bashrc`に次のように追記。(.bashrcがなければ作成する)

```.bash
export PATH=$HOME/.nodebrew/current/bin:$PATH
```

nodebrewのコマンドが使えるようにするために、ターミナルを再起動するかsourceコマンドで.bashrcを読み込む。

```.bash
source /.bashrc
```

これでnodebrewコマンドが使えるようになる。
nodebrewコマンドでNode.jsのv12.22.12をインストールする。

```.bash
nodebrew install-binary v12.22.12
```

なおインストール済みのNode.jsバージョンのリストは`list`コマンドで確認できる。

```.bashrc
nodebrew list
```

実はまだこの段階ではNode.jsもnpmも使うことができない。
そのためには`use`コマンドで使用したいNode.jsのバージョンを指定する必要がある。

```.bash
nodebrew use v12.22.12
```

`node -v` `npm -v`でバージョン情報が表示されるならNode.jsもnpmも正常に使用できるようになっている。
なお使用するNode.jsを他のバージョンに切り替えたいときは`use`の後のバージョン箇所を書き換えればいい。

## 参考
[Node&npmのアンインストール手順](https://qiita.com/aisplay/items/7269da55e456ab69c5d1)
[nodebrew導入](https://nabewakashi.com/how-to-switch-to-nodebrew)
torchvision の Resize オプション

## Resize オプション
torchvision の resize には interpolation や antialias といったオプションが存在する.  
通常あまり意識しないでも問題は生じないが、ファインチューニングなどで backbone の学習をあらためて行わない場合には影響が起きることがある.

![landmark](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1151540/5a51ad0f-a362-5c96-390b-6df59a4b3444.jpeg)  

以上のサンプル画像に対して、オプションを変更すると画像は以下のように変化する.  
![partial image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1151540/3b6ac29e-6b1b-1295-b689-b6334b3bc8ae.png)
```python
# 左上 (default):
transforms.resize(x, size, interpolation=transforms.InterpolationMode.BILINEAR)
# 右上: 
transforms.resize(x, size, interpolation=transforms.InterpolationMode.BILINEAR, antialias=True)
# 左下:
transforms.resize(x, size, interpolation=transforms.InterpolationMode.BICUBIC)
# 右下:
transforms.resize(x, size, interpolation=transforms.InterpolationMode.BICUBIC, antialias=True)
```

BILINEARおよびBICUBICではかなりジャギーを生じていることがわかる.
BILINEAR+Antialias と BICUBIC+Antialias では大きな差はなくジャギーも少ない.  
torchvisionには以下の記載がある.
```
when downsampling, the interpolation of PIL images and tensors is slightly different, because PIL applies antialiasing. 
```
Data AugmentationをPILやnumpy objectの状態で行う場合は気にしなくてもよいと考えられる.  
逆に言えば、Tensorで実行する場合は気にすべきである.  
backbone モデルを再学習しない場合などのユースケースにおいては  
元々の学習の設定方法と合わせておくことで無駄な性能劣化を回避できる.  

#### 参考文献
* [torchvision.transforms.Resize](https://pytorch.org/vision/stable/generated/torchvision.transforms.Resize.html#torchvision.transforms.Resize)
* データは [Google Landmark V2 Dataset](https://github.com/cvdfoundation/google-landmark) から引用