OmniAICreator/Qiita-1.07M huggingface dataset:
【個人メモ】取得した資格一覧

何をいつ取ったか覚えてられないので、吐き出しておく。
使用用途は無いけど、自社の後輩達がこれをなんとなくみて「あいつにもできるなら、私にも出来る」「あいつむかつくから超えてやる」くらいの動機になればいいと思います笑。


|  資格名  |  取得年月  |
| ---- | ---- |
|  色彩検定2,3級 |  2015年11月  |
|  運転免許 |  2016年11月  |
|  ITパスポート  |  2018年08月  |
|  LPIC Level1  |  2018年12月  |
|  ITIL Foundation  |  2019年04月  |
|  ビジネス実務法務3級  |  2019年06月  |
|  ビジネスマネジャー検定  |  2019年07月  |
|  CCNA  |  2019年09月  |
|  AWS CLF  |  2019年09月  |
|  ファイナンシャルプランナー3級  |  2019年09月  |
|  基本情報技術者試験  |  2019年10月  |
|  AWS SAA  |  2020年01月  |
|  SEO検定4級|  2020年02月  |
|  SEO検定3級|  2020年02月  |
|  LPIC Level2  |  2020年05月  |
|  LPIC Level3(304 Virtualization & High Availability)  |  2020年06月  |
|  JDLA G検定 |  2020年07月  |
|  TOEIC L/R Score 770 |  2020年10月  |
| Pythonエンジニア認定基礎試験 | 2021年01月 |
|  Pythonエンジニア認定データ分析試験 |  2021年01月  |
|  応用情報技術者試験 |  2021年04月  |
|  OSS-DB Silver |  2021年05月  |
|  情報セキュリティマネジメント |  2021年12月  |
|  メンタルヘルスマネジメント3種 |  2022年11月  |
|  メンタルヘルスマネジメント2種 |  2022年11月  |
|  CCNP |  2023年02月  |
|  日商簿記3級 |  2024年02月  |
データベースで使われる図についてまとめた

データベースで使用される最も一般的なフローチャートと図は次のとおりです。

* **データフロー図 (DFD)** は、システム内のデータの流れを示す図です。 DFD は、システムの論理設計を作成するために使用されます。
[Image of データ フロー図 (DFD)]
* **エンティティ関係図 (ERD)** は、データベース内のエンティティとその関係を示す図です。 ERD は、データベースの概念設計を作成するために使用されます。
[Image of エンティティ関係図 (ERD)]
* **階層型データ モデル** は、データベース内のデータの階層構造を示す図です。階層型データ モデルは、データベースの物理設計に使用されます。
[Image of 階層型データ モデル]
* **ネットワーク データ モデル** は、データベース内のデータのネットワーク構造を示す図です。ネットワーク データ モデルは、データベースの物理設計に使用されます。
[Image of ネットワーク データ モデル]
* **オブジェクト指向データ モデル** は、データベース内のデータのオブジェクト指向構造を示す図です。オブジェクト指向データ モデルは、データベースの概念設計と物理設計に使用されます。
[Image of オブジェクト指向データ モデル]

これらは、データベースで使用されるフローチャートと図のほんの一部です。データベースの設計に使用できる他の多くの種類があります。

データベースで使用されるフローチャートと図を選択するときは、次の要素を考慮することが重要です。

* **データベースの複雑さ**
* **データベースの使用目的**
* **データベースのユーザー**

複雑なデータベースの場合は、詳細なフローチャートと図が必要になる場合があります。データベースが特定の目的で使用される場合は、その目的に特化したフローチャートと図が必要になる場合があります。データベースを使用する人々が技術に詳しくない場合は、理解しやすいフローチャートと図が必要になります。
JavaScriptの配列操作メソッドまとめ

# はじめに
JavaScriptの配列操作でよく使用するメソッドについて、簡単にまとめてみたいと思います。

# 配列操作メソッド一覧

## 要素の追加
### pushメソッド
配列の最後に1つまたは複数の要素を追加することができる。

```javascript
let fruit = ["apple1", "apple2", "apple3"];
fruit.push("apple4", "apple5");

console.log(fruit); // ["apple1", "apple2", "apple3", "apple4", "apple5"]
```

### unshiftメソッド
配列の先頭に1つまたは複数の要素を追加することができる。

```javascript
let fruit = ["apple3", "apple4", "apple5"];
fruit.unshift("apple1", "apple2");

console.log(fruit); // ["apple1","apple2","apple3","apple4","apple5"]
```

## 要素の削除

### popメソッド
配列の最後の要素を削除し、その要素を戻り値として返す。
配列が空の場合は `undefined` を返す。

```javascript
let fruit = ["apple1", "apple2", "apple3"];
fruit.pop();

console.log(fruit); // ["apple1", "apple2"]
```

### shiftメソッド
配列の最初の要素を削除し、その要素を戻り値として返す。
配列が空の場合は `undefined` を返す。

```javascript
let fruit = ["apple1", "apple2", "apple3"];
fruit.shift();

console.log(fruit); // ["apple2", "apple3"]
```

※lengthプロパティを用いて削除することも可能。
lengthプロパティに値を設定すると、その値の数だけ要素を残し、それ以外は削除される。

```javascript
let fruit = ["apple1", "apple2", "apple3", "apple4", "apple5"];
fruit.length = 2;

console.log(fruit); // ["apple1", "apple2"]
```

## 条件に一致した要素を取り出す
### findメソッド
条件に一致した最初の要素を返す。

```javascript
const arr = [10, 20, 30, 40, 50];
const result = arr.find(value => value > 30);

console.log(result); // 40
```

### findIndexメソッド
条件に一致した最初の要素のindexを返す。

```javascript
const arr = [10, 20, 30, 40, 50];
const index = arr.findIndex(value => value > 30);

console.log(index); // 3
```

## 繰り返し処理

### forEachメソッド
配列の要素を1つずつ実行する。

```javascript
const arr = [10, 20, 30, 40, 50];
arr.forEach((value) => {
	console.log(value);
});

// 10 20 30 40 50
```

## 新しい配列を作成

- mapメソッド
指定した条件の結果を新しい配列として返す。

```javascript
const arr = [1, 2, 3, 4, 5];
const newArr = arr.map(value => value * 2);

console.log(newArr); // [2, 4, 6, 8, 10]
```

- filterメソッド
条件に一致した要素のみを取り出し、新しい配列を作成する。

```javascript
const arr = [1, 2, 3, 4, 5];
const newArr = arr.filter(value => value % 2 !== 0);

console.log(newArr); // [1, 3, 5]
```

# 最後に
配列操作のメソッドを簡単に羅列してみました。
他によく使用するものがあれば、追記していきたいと思います。
jsonデータの子idに対する親id、祖先idのリスト化

jsonファイルで
```json:qiita.rb
[{"child_id":"AAA","parent_id":"AA"},{"child_id":"AA","parent_id":"A"},
{"child_id":"A","parent_id":"Alphabet"}]
```
のように子idと親idが連鎖しているとき、子とその祖先をまとめたリスト
["AAA","AA","A","Alphabet"]
を出力したい。

1000個のデータがそれぞれ親子関係を持つよう辞書に辞書型データのリストを作成。
```python:qiita.rb
child_id_list = [i for i in range(1000)]
#子を10で割った商が親となる
parent_id_list = [item//10 for item in id_list]
dic= dict(zip(child_id_list,parent_id_list))
#dic_listの形式のjsonファイルを想定。
#読み込み後は子idと親idのリストから生成したdicを使う。
dic_list = [{k:v} for k,v in dic.items()]
```
child_id_listの要素ごとに、子idの親id、さらにその親idと遡っていき、子idとその祖先idをリスト化する再帰関数を作成。
```python:qiita.rb
#child_id:child_id_listの各要素
#memo:メモ用の空の配列
def saiki(dic,child_id,memo):
    if len(memo) == 0:
        memo.append(id)
    memo.append(dic.get(id))
    if memo[-1] == 0:
        return memo
    id = memo[-1]
    return saiki(dic,id,memo) 
```
回してみる。
```python:qiita.rb
import json

def saiki(dic,id,memo):
    if len(memo) == 0:
        memo.append(id)
    memo.append(dic.get(id))
    if memo[-1] == 0:
        return memo
    id = memo[-1]
    return saiki(dic,id,memo) 

child_id_list = [i for i in range(1000)]
parent_id_list = [item//10 for item in child_id_list]
dic= dict(zip(child_id_list,parent_id_list))

big_memo = []

for n in child_id_list:
    memo = []
    memo_a = saiki(dic,n,memo)
    big_memo.append(memo_a)
print(big_memo)
```
結果
```
[[0, 0], [1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0], [9, 0], 
[10, 1, 0], [11, 1, 0], [12, 1, 0], [13, 1, 0], [14, 1, 0], 
[15, 1, 0], [16, 1, 0], [17, 1, 0], [18, 1, 0], [19, 1, 0], [20, 2, 0]…
```
以上のようにchild_id_listの子idを回して
[子id,親id,祖父id,…,祖先id]
のリストが得られた。

ここから[{子id:[親id,…祖先id]}]の辞書リストを作成すれば、子idが複数並ぶリストから特定の親idを祖先に持つものをフィルタリングしたりできる。
Public LB 0.693の悲劇

# Public LB 0.693の悲劇
[第2回 金融データ活用チャレンジ](https://signate.jp/competitions/1325)に限らずデータ分析コンペのPublic LBで自分にとって一番良いスコアのsubmission.csvを選択からはずすのは自分には煩悩的に無理

[SMBC Group GREEN×DATA Challenge](https://signate.jp/competitions/1247)ではPublic LBが伸びなかったおかげでうなぎ上りに順位をあげることができ運の良さを痛感したが今回はどうなるか・・・

Cross Validatonの平均が0.683くらいの成績のなかでPublic LBが0.693とか出ちゃった場合，他人事として冷静に考えるとPrivate LBは0.67くらいかなぁーとか思いつつ，でも0.693という結果は捨てがたくということで平均的な実力は0.683なのに0.693という奇跡のスコアが出ちゃった時にPrivate LBはやっぱり0.67近傍なのかベイズ推定の香り漂うこの問題を調べるために実験してみた

## 実験
Cross Validationで使用したデータセットは学習用(train)と検証用(test)にデータを分割して検証用のf1_score(average='macro')の平均が0.683という前提で以下の実験を行う

検証用(test)をさらに２分割したデータの組み合わせを10,000個作成する
具体的にはtrain_test_split(test_size=0.5,random_state=XXX)でXXXを変化させながら10,000個の2分割されたデータの組み合わせを作る
2分割×10,000個のデータについてF1を算出しその中から片方が0.693以上の組合せを選びもう片方のF1をdescribe

## 結果

2分割したデータのF1スコアの組，たとえば(0.67,0.69)，(0.682, 0.681)に対して小さい方をf1_min,大きい方をf1_max，差分(f1_max - f1_min)をf1_diffとして整理する
|f1_min|f1_max|f1_diff|
|-:|-:|-:|
|0.670|0.690|0.020|
|0.681|0.682|0.001|

次にPublicLBのスコア(F1_Pub)を閾値として以下の2つのグループを集計する
* グループ1：f1_min >= F1_Pub
* グループ2：f1_max >= F1_Pub and f1_min < F1_Pub 

グループ1, グループ2それぞれを[describe](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.describe.html)する

## 結論

### 0.693のモデルは？
現実は厳しい
グループ1は0件，半分予想していたが…
0.693の相方はかならずそれ以下であることが確定
他人事の冷静な自分の見解を裏切らない結果
相方のdescribeを貼り付けたいところだがdatabricksが期限切れでアクセスできないため断念
median(quantile=0.5),meanともに0.67後半だったはず
その代わりにPrivateスコアを貼っておく
想像以上に最終評価が高い

|暫定評価|最終評価|
|:--|:--|
|0.6930102|0.6846376| 

### 0.692のモデルは？
予想外の結果が…
件数は以下
|全体|グループ1|グループ2|グループ1<br/>or<br/> グループ2|
|-:|-:|-:|-:|
|10,000|2,100|2,739|4,839|

相方が0.692を超える組合せはおおよそ半分もある(...意外)

先に最終評価を記載しておく
|暫定評価|最終評価|
|:--|:--|
|0.6922592|0.6837695| 

暫定評価 ＞ 最終評価なのでグループ2をdescribe
![image-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3687201/4185d205-0d90-b85e-15f4-1e19adeadd11.png)

f1_minはmedian(quantile=0.5)が0.6822でそれよりも上
![image-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3687201/e581de17-8e26-5b34-2ec9-8fdd283a9327.png)
最終評価を予測するときのステップは以下となりそう(確証は無し)

* グループ1(0.692より相方が大きい) or グループ2(0.692より相方が小さい)
確率を素直に受け入れるとグループ2を選択
* グループ2のなかでどのくらいに位置づけられる？
median(中央値)の近傍，ただしグループ1の件数もそこそこあるので多少上振れで期待してよい？？？

自分があと30年若ければ確率振幅に突入して分析を継続するところだが還暦を超え頭も体力もすっかり衰えているので無理

### 結局どうなった？

0.692モデルの実験を踏まえsubmitのポートフォリオを組み換えしようとしたところ突然システムが停止しそのまま試合終了になった

もしシステムが復旧していたらPrivateLBは49位から100位くらいまで順位を下げていた

人間万事塞翁が馬，禍福は糾える縄の如し を痛感する出来事だった
databricksの時間制限

# databricksの時間制限

Google Colabは[06_introduction_to_colab](https://colab.research.google.com/github/nagaoka-ai-innovationhub/basics-of-image-recognition-with-cnn/blob/master/06_introduction_to_colab.ipynb)によると以下の時間制限がある(2024/2/13時点)

* 最初のノートブックを開いてから最大12時間までで、Colabでのノートブックサーバがシャットダウン
* Webブラウザを閉じる等でノートブックのセッションが終了すると、セッション終了から90分後にはシャットダウン
  
[第2回 金融データ活用チャレンジ](https://signate.jp/competitions/1325)で提供されたdatabricksのクラスタは以下の時間制限が定義されているがどのようなタイムアウトが設定されているのか確認したところ以下のタイムアウト以外は設定されていないらしい
![not_active.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3687201/5898dab2-3d93-8c27-76d6-e39496e32c94.png)

ブラウザを閉じて90分経過してもクラスタがシャットダウンされることはなくモデルの学習は継続する
かつブラウザを立ち上げてnotebookに再接続するとmatplotlibの描画など処理結果を確認することができる
Django Apachでsettingを分ける

Djangoを本番環境でデプロイするときにsetting.pyを分けたい。
DEBUGやDATABASESなどが環境で分けたくなる。
以下のようにsettingディレクトリを作成し、もともとのsetting.pyをbase.pyにリネーム、__init__.pyの空ファイルを作成する。

```
project_name
├─ project_name
│    ├─ settings
│    │    ├─ __init__.py    # 空ファイル
│    │    ├─ base.py        # 共通設定
│    │    ├─ development.py # 開発環境設定
│    │    └─ production.py  # 本番環境設定
│    └─ urls.py
│　　　　└─ wsgi.py
└─ manage.py
```

# 変更箇所
環境変数を設定する
```bash:shell
$ export DJANGO_SETTINGS_MODULE=project_name.settings.production
```

BASE_DIRを定義する階層が一つ深くなったのでparentを追加する。
```python:base.py
- BASE_DIR = Path(__file__).resolve().parent.parent
+ BASE_DIR = Path(__file__).resolve().parent.parent.parent
```

環境変数が設定されていないときproject_name.settings.developmentを読み込む。
```python:manage.py
- os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project_name.settings')
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project_name.settings.development ')
```

wsgiは環境変数を読み込めない。しかしwsgiを使うのは本番環境だけなのでデフォルトでproductionを指定する。
```python:wsgi.py
- os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project_name.settings')
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project_name.settings.production ')
```


上の方法でもできるがdotenvを用いて.envにDJANGO_SETTINGS_MODULEを環境変数設定しておき読み込むことでwsgiが環境変数を読み込めないことをクリアし、manage.pyもwsgiもデフォルトをdevelopmentに設定できるかもしれない。
最新のRaspberry PI OS (bookworm) にVNC接続を行う方法

ラズパイの最新OSは RaspberryPi OS (64-bit) bookworm なのですが、VNCを有効化してもRealVNCで接続できなくなっていたので、接続方法を調べました。

# 原因

bookwormからデスクトップのウィンドウマネージャーが X11 から Wayland に変更されたようで、RealVNCがWaylandに対応していないため接続できないようでした。

`/usr/bin/raspi-config` を読んでみたところ、wayvncというVNCサービスが起動するようになっていました。

RealVNCの公式によるとこの解決方法は2種類あるみたいです。
[Connecting to WayVNC on a Raspberry Pi device running Wayland using RealVNC Viewer | RealVNC](https://help.realvnc.com/hc/en-us/articles/14693032843293-Connecting-to-WayVNC-on-a-Raspberry-Pi-device-running-Wayland-using-RealVNC-Viewer#for-devices-using-a-wayvnc-version-prior-to-0-7-0-0-0)

# 解決策１

※ WayVNC のバージョンが0.7.0以降であればこちらの解決策

バージョン0.7.0以降の WayVNC は RealVNC と互換性のある RSA-AES 認証が追加されたらしく、適切な証明書を生成すると、RealVNCから接続できるようになるみたいです。

## ラズパイ側の操作

```bash
# waylandのバージョン確認
wayvnc --version

# vncを有効化 (0=有効, 1無効)
sudo raspi-config nonint do_vnc 0

# 証明書の生成
sudo ssh-keygen -m pem -f $HOME/.config/wayvnc/rsa_key.pem -t rsa -N ""

```

`$HOME/.config/wayvnc/config` に下記の設定を追加

```ini
rsa_private_key_file=rsa_key.pem
use_relative_paths=true
```

```bash
# 再起動
sudo reboot
```

## 接続端末の操作

[Real VNC Viewer](https://www.realvnc.com/en/connect/download/viewer/) をダウンロードして接続。

`ラズパイのIP` `ポート (5900)` `ユーザー名` `パスワード` を指定して接続します。

![](https://storage.googleapis.com/zenn-user-upload/f375fdc0d56e-20231219.png)


# 解決策２

ウインドウマネージャーをX11に戻して、RealVNCサーバーを起動します。

## ラズパイ側の操作

```bash
# デスクトップのウィンドウマネージャーを Wayland から X11 に変更 (W1=X11, W2=Wayland)
sudo raspi-config nonint do_wayland W1

# リブート
sudo reboot

# vncを有効化 (0=有効, 1無効)
sudo raspi-config nonint do_vnc 0

# vncが有効化されているか確認 (0=有効, 1無効)
sudo raspi-config nonint get_vnc
```

## 接続端末の操作

[Real VNC Viewer](https://www.realvnc.com/en/connect/download/viewer/) をダウンロードして接続。

`ラズパイのIP` `ポート (5900)` `ユーザー名` `パスワード` を指定して接続します。

![](https://storage.googleapis.com/zenn-user-upload/f375fdc0d56e-20231219.png)
シミュレーションの実行速度を上げるには

参考リンク
https://qiita.com/ShiraTakiSuki/items/87bcba546e063c16d846

## 結論
**結果を保持するときに，append() や rbind（) を使わない。**

以下のようにすると，実行時間が馬鹿にならない。
回数が多くなると，フリーズしたようになる（ループ回数を10倍したのに，10倍以上（無限に？）時間がかかる）。

```R
result <-　numeric()
A <- numeric() # 一応データ保存
for (j in 1:M)　{
	result <- append(result,　c　==　W)
    A <- rbind(A,　a)
}
```

append() や rbind() する回数はたいてい for ループに入る前にわかっている（わかっていないなら，わかるようにする）なら，結果を保持するメモリーを前もって確保しておき， for ループ内では添字を使って保存する。

そうすれば，実行速度は 10 倍くらいになる（はず）。フリーズ状態にもならない。

```R
result <- numeric(M)
A <- matrix(0, M, N) # 一応データ保存
for (j in 1:M)　{
	result[j] <- c　==　W
	A[j,] <- a
}
```
BlueskyのAPIは無効化できないので、登録するメールアドレスは専用のメールアドレスにして防御しよう

## はじめに
ポストXとして一気に台頭してきたBlueskyへ外部から投稿するAPIを調べていて気になった部分があったのでまとめます。
※この内容は2024/2/12時点の情報です。

## 外部から投稿する仕組み
まず最初に外部から投稿する仕組みについてまとめます。
Blueskyは公式アプリや公式サイト以外から投稿するためにAPIが準備されています。
公式のAPIリファレンスはこちらです。

https://www.docs.bsky.app/docs/tutorials/creating-a-post

仕組みとしては認証を実行して、成功したら投稿のAPIが利用できる状態になります。

公式のTypescriptのコードを引用します。

```javascript
import { BskyAgent } from '@atproto/api'

const agent = new BskyAgent({
  service: 'https://bsky.social'
})
await agent.login({
  identifier: 'example.com',
  password: 'hunter2'
})

await agent.post({
  text: 'Hello world! I posted this via the API.',
  createdAt: new Date().toISOString()
})
```
agent.loginの部分で使用されているメールアドレスとパスワードはアカウントのログインに使用するものです。
なのでloginの関数を利用するとパスワードがあっているかを試せるということになります。

## APIの実行制限
APIのレート制限があり、以下のリンクから値は確認できます。

https://www.docs.bsky.app/docs/advanced-guides/rate-limits

制限を確認する限り、全体のレートがIPアドレス単位で3000/５分、認証はおそらくcreateSessionに該当しそうなのでアカウント単位で30/5分かつ300/1日です。（おそらく単位は回）
無限に試せるわけではありませんが、ある程度の回数はパスワードを試すことがAPI経由でできます。

## APIを悪用すると...
例えばどこかで流出したメールアドレスがあれば、時間をかければ総当たりで試すことができそうです。
1)大量のメールアドレスを取得
2)複数のIPアドレスから通信できる環境を作る
3)それぞれのメールアドレスにパスワードが通るかどうかを総当たりで試す

Blueskyには２段階認証などもないのでパスワードがバレるとアカウントの乗っ取りができてしまうことはもちろん、フィッシング詐欺などもできてしまいそうだとも思いました。

例えばこのようなことができてしまう可能性があると思いました。
1)メールアドレスとパスワードがバレる
2)メールアドレス宛に「アカウント情報のセキュリティ強化です」や「パスワード忘れのために別の認証情報を登録をお願いします」というようなメールを送って偽サイトへの誘導を行う
3)偽サイトで個人情報と現在のパスワードを入れさせる
本来はサイトしか知らないはずのパスワードだから、誤ったパスワードを入れたら違いますと表示するような仕組みがあれば信じる人が出てきそう

## APIの無効化ができるか？
調べた限り、2024/2/12時点でAPIを無効化する手段は見つかりませんでした。
また、アカウントを作った時点でAPIが有効で利用できることになっています。
しかも、公式アプリや公式サイトであれば2段階認証などの導入もあるかもしれませんが、APIだと試されていることを通知されることもないと思われます。

## 対策
個人的な対策としては、Blueskyに登録するメールアドレスはBluesky専用のメールアドレスにしておくことかなと思います。
Gmailのエイリアス機能を使って専用のメールアドレスにして、エイリアスにランダムな文字列を入れて推測させないようにしておいた方が安全だと思います。(+blueskyや+bsとかだと推測される可能性もあるので)
メールアドレスが推測できなければパスワードを試されてバレることはないと思われます。

外部から認証を試されているかを知ることができるのは、調べた限り現状下記のリンク先のシステムのログだけです。

https://bsky.app/sys/log

ただ、こちらも細かな情報が確認できるわけではないので普通に使っているのに赤い！マークが大量にあったら怪しそうぐらいしか確認できないと思われます。

## まとめ
Blueskyが招待制でなくなり一気に人が流れ込んできましたが、セキュリティ面ではまだまだ緩いと思われます。
特にAPIの利用がアカウントを作った時点で利用できる状態になっているのも、あまり周知されていないことだと思いました。
せめてAPIの利用を初期無効にして、本当に必要な時に有効にできる仕組みができるといいなと思いました。
AWSの請求関連の設定

## 予算（Budgets）
プロジェクトに合わせて指定した料金以上になった時にメールが送信されるようにBudgetsを設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664223/d5a0001d-8580-8724-fd8f-b7be97bb86e2.png)
不正利用などで想定外に料金が増えた時などに気付く切っ掛けになります。

## 請求設定
初期設定だと請求書がメールで配信されないので「PDF 請求書を E メールで配信」を有効化。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664223/ce126ff0-7f50-e638-6757-8f7d2cb22062.png)
この設定を有効化すると代替連絡先にも請求書が配信されるようになります。

## 代替連絡先
「代替連絡先」の「請求に関する連絡先」に請求書PDFを共有するメールアドレスを設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664223/5a233471-7a5f-085f-ef93-d146d6e766d1.png)
この設定でRootアカウントを共有せずに請求書だけ共有する事ができます。

## Slack
上記の設定を組み合わせて、Slackチャンネルのメールアドレスを登録しています。
Slackに請求書PDFが届くので過去の請求書も残り、Rootアカウントでアクセスできない人に共有できるので便利です。
Onyxでu8を表示するときはcastしよう

前回に続いて[Onyx](https://onyxlang.io/)ネタです。

`u8` を表示すると数値そのものではなく、**コードポイントとして解釈** されてしまいます[^1]。

```onyx:main.onyx
use core {printf}

main :: () {
    v: u8 = 100;
    printf("{}\n", v);
}
```

```:結果
d
```

表示するときは `u32` 等の別の型にキャストしましょう。

```onyx:main.onyx
printf("{}\n", cast(u32) v);
```

```
100
```

# 背景

OnyxはWASMをターゲットにしているため、プリミティブ型もWASMに準拠しています。用意されている数値型は以下の通りです。

- `u8`
- `u16`
- `u32`
- `u64`
- `i8`
- `i16`
- `i32`
- `i64`
- `f32`
- `f64`

いずれの場合も `printf` に対応していますが、 `u8` の場合**のみ** `d` が表示されます。これは、 `str` 型が `[]u8` のエイリアスとして定義されているためです。
`printf` 上では、`u8` は整数ではなく文字として扱われていたというわけです。

```onyx
// NOTE: onyxでは型そのものも値（コンパイル時定数）として扱えるため表示可能
printf("{}\n", str); // [] u8
```

[^1]: この例のようにきれいに文字が出ればすぐ気づけたのですが、最初にハマった時は謎の文字化けが表示され途方に暮れていました...
Redux toolkitのthunk関数の型定義について

# 背景
認証の非同期処理をthunkを使って、サインインが完了したらreduxの値を更新したい。
redux toolkitのcreateAsyncThunkを使う。
createAsyncThunkでrejectWithValueを使った時のpayloadの型がanyになる。

# rejectWithValueを使った時のpayloadの型がanyになる
![スクリーンショット 2024-02-13 19.24.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689380/e9a4fc89-c7c1-6887-5473-d897806e5615.png)
```react.js
export const signInThunk = createAsyncThunk(
  'auth/signIn',
  async (signInArgs: SignInArgs, { rejectWithValue }) => {
    try {
      const result = await signInFirebaseWithEmailAndPassword({ ...signInArgs });
      return { loading: false, error: [], identity: result.identity, statusCode:result.statusCode };
    } catch () {
      return rejectWithValue({
        statusCode: result.statusCode,
      });
    }
  },
);
export const authSlice = createSlice({
  name: 'auth',
  initialState,
  reducers: {},
  extraReducers: (builder) => {
    // auth/signIn
    builder.addCase(signInWithEmailAndPasswordThunk.fulfilled, (_, action) => ({
      ...action.payload,
    }));
    builder.addCase(signInWithEmailAndPasswordThunk.pending, (state) => {
      state.loading = true;
    });
    builder.addCase(signInWithEmailAndPasswordThunk.rejected, (state, action) => {
      state.loading = false;
      state.error = ['Auth error'];
      state.statusCode = action.payload?.statusCode;
    });
  },
});
```

# 解決策
`createAsyncThunk<T>`のTの型を定義する。これだけだけど、型の順番に注意が必要。以下の順番になっている。
- 成功した時の戻り値の型
- 引数の型
- rejectWithValueで渡す型

```react.js
export const signInThunk = createAsyncThunk<
  AuthState, // 成功した時の戻り値の型
  SignInArgs, //　引数の型
  { rejectValue: Pick<AuthState, 'statusCode'> } // rejectWithValueで渡す型
>(
  'auth/signIn',
  async (signInArgs: SignInArgs, { rejectWithValue }) => {
    try {
      const result = await signInFirebaseWithEmailAndPassword({ ...signInArgs });
      return { loading: false, error: [], identity: result.identity, statusCode:200 };
    } catch () {
      return rejectWithValue({
        statusCode: result.statusCode,
      });
    }
  },
);

```

# 終わり
redux toolkitは知らないことがまだまだいっぱい。.

https://redux-toolkit.js.org/api/createAsyncThunk#return-value
投資するってよ

ご無沙汰しております。

さて、無事転職活動が終了し、もろもろの手続きを行っております。

その最中、自分が投資をしていないことに気がつきました。

現職でやっている投資といえば、持株会のみ。
奨励金が10%あるので、やっておりました。
退職までに55万投資したのが、70万近くになる見込みです。
2年間とはいえ、頑張りました。

さて、次回の会社では3つの投資を行おうと思います。

　①iDeCo(個人型確定拠出年金)：10000/月
　②NISA(少額投資非課税制度)：10000/月
　③持株会(奨励金8%)：20000/月


お時間になったので、詳しい説明は後日にしますが、
①自分で積み立てる年金。投資もそうであるが、そもそも掛け金が、税金の控除対象になるので、やるだけで節税対策になる。(月2000円程度の節税)

②ある程度までの投資なら税金がかからない制度。
　お得ですね。社会勉強として行います。

 ③自社の株を会社が8%にして買ってくれる制度。
 　自分の給料からは20000円引かれますが、21600円分の株を購入することができます。お得ですね。もちろん配当金も出ますよ。唯一の欠点は、株主優待がもらえないことかな。そもそも自社株に株主優待なんてねーよ！（笑）


  さてさて、執筆活動はこの辺にして、あとは引っ越しの準備でもしようかな~
0xL4ugh CTF - WordPress 1 Writeup

# CTFサイト

https://ctf24.0xl4ugh.com/

# 問題

原文

>Our WordPress site has experienced a security breach, and the precise method of compromise remains undetermined at present. We need you help to investigate what actually happened.
Q1. There were two attackers attempting to compromise our environment. What is the IP address of the victim, and what is the IP address of the first attacker? Q2. What are the versions of the Apache and PHP servers deployed in our environment?
Flag Format 0xL4ugh{A1_A2}
Example: 0xL4ugh{IP1_IP2_apache1.2.3_php1.2.3}(no spaces)

日本語

>私たちの WordPress サイトでセキュリティ侵害が発生しましたが、侵害の正確な方法は現時点では未確認です。実際に何が起こったのかを調査するためにあなたの協力が必要です。
Q1. 2 人の攻撃者が私たちの環境に侵入しようとしていました。被害者の IP アドレスは何ですか? 最初の攻撃者の IP アドレスは何ですか? Q2.私たちの環境にデプロイされている Apache サーバーと PHP サーバーのバージョンは何ですか?
フラグ形式 0xL4ugh{A1_A2}
例: 0xL4ugh{IP1_IP2_apache1.2.3_php1.2.3}(スペースなし)

# 解く

http.requestでフィルタリングすると、`192.168.204.128`にリクエストがたくさん飛んでいるので被害者IPは`192.168.204.128`と推測。

![http request.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/6c0c8ce1-a585-f590-4e34-ec223718b889.png)

続いてパケットを見ていくとHTTP HEAD methodがたくさん飛んでいるのを発見。
`User-Agent`に`WPScan`の記載があり、wp-configファイルの探索が行われているもよう。
結果、最初の攻撃者のIPは`192.168.204.132`になる。

![wp-config scan.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/a919e776-328e-e4f7-2194-f2fcf5dc0347.png)

ここまでで`0xL4ugh{192.168.204.128_192.168.204.132}`は確認できた。
残りのApacheとPHPのバージョンを確認していく。

GETリクエストを見ると両方確認できた。

![TCPストリーム.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/27bd77e9-9735-063d-0b70-f6b0c3b37e7b.png)

よって最終的なFlagは`0xL4ugh{192.168.204.128_192.168.204.132_apache2.4.58_php8.2.12}`
「フロントエンドの知識地図」を読んでみて

## はじめに
こんにちは！◤●ㅅ●◥ﾉ
初心者でもわかりやすいものを勧めてもらったので読んでみました！

全部で340pくらいで、
１日に1,2時間くらいのペースで読んで１週間で読み終わりました。

内容はフロントエンドの技術についてさらっと全体を学んで、それに加えて
・「エンジニアとして知っておくべきこと」
・「どの分野にフォーカスしてスキルアップをするか」
という２点を中心に教えてくれる内容でした

自分は読むにあたって
・フロントエンドにはどのような技術があるのかを知ること
・その上で興味を持つ分野を探す
の２つを目的に読んでみました

読んで学びとなったところをまとめてみました

### 学び〜フロントエンド開発の基本
#### フロント開発とは
フロントエンド-ユーザーがみたり操作したりする画面の部分
フロントエンドの開発者⇨フロントエンドエンジニア


#### フロントエンドエンジニアのスキル
・ コンテンツマネジメントシステムの使い方、連携の仕方
・ HTML,CSS ,JavaScriptの代替言語の知識
・ ソフトウェアテストへの理解、テストコードの書き方
・ Webアクセシビリティへの理解など

#### フロントエンドの中心の言語
HTML
・タグに囲まれた部分で表現をする
・Webページ上のコンテンツに対し以下のタグで構造上の役割を意味付けできる
CSS
・Webページの見た目を制御する
JavaScript
・ユーザーの操作に応じた動作を追加するなど高機能なWebページを実現できる

### 学び〜フロントエンド開発の技術
#### JavaScriptのフレームワーク
プロジェクトの骨格
フレームワークを利用することで,JavaScriptからCSSを記述することが容易になる
比較的静的なWebサイトの制作でもJavaScriptフレームワークを利用する場面がある

:star: 代表例
React
　JSXと呼ばれるJavaScriptをHTMLのように書ける構文
Vue.js
　単一ファイルコンポーネントという独自のファイル形式が使用される
Svelte
　ReactやVue.jsに比べるとやや後発のフレームワーク
　ソースコードを簡潔に書ける
##### フレームワークのトレンドを追う
・npmtrends
・State of JavaScript

#### CSSのフレームワーク
クラス名をつけただけで、ボタンの見た目を作れる

:grinning:メリット
工数の削減
デザインを活用、実装の工数の削減
一貫したデザインを構築できる

:fearful:デメリット
デザインのカスタマイズの幅の限界

:star: 代表例
Bootstrap
　単体でデザインが完結している
Tailwind CSS
　ユーティリティファーストな設計のCSSフレームワーク
MUI
　Material Designというデザインシステムをもとにした
　React向けUIフレームワーク
Vuetify
　Vue.js向けのUIフレームワーク

##### CSSのトレンド
State of CSS
CSSの利用に関する開発者へのアンケートをまとめたサイト

### まとめ
フロントエンドの基本についてわかりやすく書いてあって自分的にはとても良かったです。
また、技術を知るという点について基本的なHTMLやCSS、JavaScriptやそれを拡張して使いやすくするフレームワークについてしれたのが良かったと思いました。
フレームワークはReactが聞いたことはあるけど、触ったことがほぼないので今後はReactについて興味を持って学んでいきたいかなって思いました。
まとめとしては書いてないですが、開発の流れや役割なども解説してくれたり、開発環境の構築、体験、標準仕様の歴史なども簡単に教えてくれるので興味を持った方はぜひ読んでみてください！
ここまで読んでいただき、ありがとうございました！
ではまた〜　◤●ㅅ●◥ﾉ"
Raspberry Piでk3sクラスタを建ててみた

Raspberry Piでk3sクラスタを建ててみたので、構築手順を簡単にまとめてみました。

## k3sとは
（IoTやエッジコンピューティングに最適化された）軽量なKubernetesです。

https://k3s.io/

# 前提
- ２台のRaspberry Pi（Masterノード１台＆Workerノード１台）を使ってk3sクラスタを構築する
- MasterノードとWorkerノードには固定IPアドレスが割り振られていて、相互に通信が可能な状態であること


# 動作環境
- Masterノード
    - Raspberry Pi4 ModelB 4GB
    - Raspberry Pi OS（64-bit）
    - hostname: master
- Workerノード
    - Raspberry Pi4 ModelB 4GB
    - Raspberry Pi OS（64-bit）
    - hostname: worker01


# 共通の設定（Master＆Worker）
Raspberry Pi OSではデフォルトでcgroupsが有効化されていないので、`/boot/cmdline.txt`の末尾に以下を追加します。
```
cgroup_memory=1 cgroup_enable=memory
```

Kubernetesではswapの利用は非推奨なので、無効化しておきます。
```bash
$ sudo swapoff --all
$ sudo systemctl stop dphys-swapfile.service
$ sudo systemctl disable dphys-swapfile.service
```

再起動します。
```bash
$ sudo reboot
```

# Masterノード
以下コマンドでk3sをインストールします。

※デフォルトではk3クラスタにアクセスするための設定ファイルは `/etc/rancher/k3s/k3s.yaml`に保存されますが、kubectlを使う際に該当ファイルへのアクセス権限が不足することによってエラーが発生する場合があるようなので、`--write-kubeconfig-mode`オプションを忘れずに指定してください。
```bash
$ curl -sfL https://get.k3s.io | sh -s - --write-kubeconfig-mode 644
```


インストール後、ノードを確認してみると以下が表示されると思います。
```bash
$ kubectl get nodes
NAME     STATUS   ROLES                  AGE     VERSION
master   Ready    control-plane,master   2m36s   v1.28.6+k3s2
```

Workerノードの設定を行う前に、（k3sクラスタに参加するための）node-tokenを取得しておきます。
```bash
$ sudo cat /var/lib/rancher/k3s/server/node-token
```

# Workerノード
以下コマンドでk3s（agent）をインストールします。K3S_URLとK3S_TOKENは実環境に合わせて変更してください。
```bash
curl -sfL https://get.k3s.io | K3S_URL=https://<MasterノードのIPアドレス>:6443 K3S_TOKEN=<上記のToken> sh -
```

ノードを確認してみると、MasterノードとWorkerノードの両方が表示されるようになると思います。
```bash
$ kubectl get nodes
master     Ready    control-plane,master   13m   v1.28.6+k3s2
worker01   Ready    <none>                 30s   v1.28.6+k3s2
```

# Nginxを起動してみる

定番のNginxで動作確認してみます。
以下のyamlファイルを作成しておきます。
```yaml: nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  type: NodePort
  ports:
    - port: 80
      nodePort: 30000
  selector:
    app: nginx
```

以下コマンドを実行します。
```bash
$ kubectl apply -f nginx.yaml
deployment.apps/nginx created
service/nginx created
```

podの状態を確認してみます。
```bash
$ kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
nginx-7c79c4bf97-nk7fd   1/1     Running   0          22s
```

別端末（ノートPC）のブラウザからアクセスしてみます。
```
http://<WorkerノードのIPアドレス>:30000/
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2954734/a4ee0ea8-ecd0-8f5a-9a62-b6c97b8abdb2.png)

# 参考URL
- https://docs.k3s.io/
- https://zenn.dev/kuma3303/articles/21d5725a94fcc1
- https://kmconner.net/posts/2021/05/29-k3s-setup/
文字列に関すること（調べたこと）：Python

<font color=`#ffce44`>※このQiitaで記事を書くことに慣れていない為、誤字・脱字や読みづらい部分もあるかと思いますが、ご理解ください。</font>

閲覧いただき、ありがとうございます！
私は、現在医療業界で働く医療従事者になります。
とある経緯からpythonを勉強中です。
ここでは自分が勉強した事を復習したり、忘れないようにするため記載いたしますので、もしもっとこうした方が良いよ、とかこれはちょっと。。。というものがあれば教えていただけますと幸いです。
※記事内容は随時更新します


## 対象のワードが文字列の中に含まれているか確認する
```py:記述
keyWord = "mi"
words = "I love milk"
print(keyWord in words)
```
出力結果：True

※もし含まれていなければ「False」と出力されます。
現場で使えるAPI設計

# 現場で使えるAPI設計

## **API設計**

Googleの[API設計ガイド](https://cloud.google.com/apis/design?hl=ja)をベースにAPI設計を行っています。

今回はその中でも特に「[標準メソッド](https://cloud.google.com/apis/design/standard_methods?hl=ja)」について触れます。

## **標準メソッド**

「List」,「Get」,「Create」,「Update」,「Delete」の5つから成る標準メソッドを用いてAPI設計方針を定めています。

＊標準メソッドに該当しないAPIは[カスタムメソッド](https://cloud.google.com/apis/design/custom_methods?hl=ja)を参考にしています。

### **メリット**

- 各エンドポイントの使用の予測が容易になり、学習コストが低下する
- 新たなAPIの作成や既存のAPIのメンテナンスのコストの低下する
- 一貫性が保たれているため、バグの削減に貢献する

以下は記事に関する標準メソッドのAPIの例です。

| 標準メソッド | HTTPメソッド | エンドポイント | 例 |
| --- | --- | --- | --- |
| List | GET | /articles | GET /articles |
| Get | GET | /articles/{id} | GET /articles/1234 |
| Create | POST | /articles | POST /articles |
| Update | PUT | /articles/{id} | PUT /articles/1234 |
| Delete | DELETE | /articles/{id} | DELETE /articles/1234 |

それぞれのメソッドについて簡単に説明します。

**List**

このメソッドは、特定のコレクションに関する情報をリスト形式で取得します。

コレクション名とパラメーターをもとにリソースの一覧を取得し、レスポンスとして返します。

**Get**

このメソッドは、特定のリソースに関する詳細な情報を取得するために使用されます。

リソース名とパラメーターをもとに指定されたリソースの詳細な情報を取得し、レスポンスとして返します。

**Create**

このメソッドは、新たなリソースを作成するために使用されます。

親リソース名、新たに作成するリソースの情報をもとに新しいリソースが親リソースの下に作成され、新たに作成されたリソースの情報がレスポンスとして返されます。

**Update**

このメソッドは、既存のリソースの情報を更新するために使用されます。

更新するリソースの情報をもとに指定されたリソースが更新され、その更新されたリソースの情報がレスポンスとして返されます。

**Delete**

このメソッドは、特定のリソースを削除するために使用されます。

削除するリソース名をもとに指定されたリソースの削除が行われ、空のレスポンスが返されます。

## **標準フィールド**

フロントエンドとバックエンドなどの複数サービスの開発を円滑に進めるため、類似するコンセプトの標準メッセージフィールドの統一を行います。

### **メリット**

メッセージの類似コンセプトを統一することで、以下のような利点が期待できます。

- 一貫性のある命名規則により、バグの削減
- リクエスト、レスポンスのメッセージ把握の学習コストの低下
- フロントエンドとバックエンドなどの複数サービス開発の開発者体験の向上

| フィールド名 | 説明 | 例 |
| --- | --- | --- |
| id | リソースの一意のID。 | 12345 |
| name | リソースの一意の識別子。 | "Qiita" |
| description | リソースの一意の説明文 | "この記事はQiitaによって公開されています。" |
| createAt | リソースが作成された日時。 | "2023-10-21T19:20:30.45Z" |
| updateAt | リソースが最後に更新された日時。 | "2023-10-22T19:20:30.45Z" |
| deletedFlg | リソースが削除されているかのフラグ | true |

## **現場で感じた良かった点・改善した点**

コーディング規約を運用していく上で、実際に感じたことを紹介したいと思います。

**良かったこと**

一つ目は、リソース指向の設計を反映しているためAPIの全体を把握しやすいことです。

API Group単位のリソースのキャッチアップのみで全体を把握することが可能です。

**改善したこと**

上記で紹介した標準メソッドは、複数のリソース依存のAPI設計に対応していないため、新たにコーディング規約を設計する必要がありました。

プロダクトが大きくなるにつれ、他のリソースと依存関係のある機能の需要が高まってくるかと思います。複数リソースにまたがるAPI設計が複雑化してしまうことがあります。

タグに紐づいた記事リストを取得するAPIが具体的な例です。

「タグ」と「記事」の二つのリソースに跨り、「タグ」のスラッグに紐づいた記事一覧を取得する機能です。

- api/v2/tags/${slugName}/articles

弊社では、URL構造として親リソースに「関連を示すリソース」（この場合は「タグ」）を示し、子リソースが「取得対象のリソース」（この場合は「記事」）を示すように設計しています。

特定のタグに関連する記事を取得することをURL上で直感的に理解できるようにリソースの関係性の明確化をしています。

上記は一例となりますが、複数リソースに跨るケースのAPI設計を弊社で定義する必要があります。

## **まとめ**

API設計には様々なベストプラクティスが存在しており、エンジニアによって良い設計の基準も変わってきます。

そのため弊社ではコーディング規約を設けることでソフトウェアの品質を保つだけでなく、新しくジョインするエンジニアの学習コストの低下やバグの削減などに大きく貢献しています。

実際に自分がジョインした時も、コーディング規約があることでAPIの実装把握やAPI設計に悩むことなく実装できたのでその恩恵をものすごく感じています。

今後も良いソフトウェア品質を保つために、良いベストプラクティスがあればどんどん取り入れて行きたいと思います！

## **参考文献**

- [API設計ガイド](https://cloud.google.com/apis/design?hl=ja)
2024年問題は「滞り」Workatoでサプライチェーンを統合させて「円滑」にする


# こんな人に参考にしてほしい
- ### 物流システムと在庫管理の効率化が必要
###
- ### 管理するシステムの増加で手間が発生してる
###
- ### 2024年から業務プロセスを変えたい！
###

2024年4月1日以降から、トラックドライバーの時間外労働時間の上限が制限されます。その影響で「サプライチェーンの滞り」が生じるかもしれません。

物流対策としては **【中継地点を設ける】【モーダルシフト(輸送手段を転換)】【IoTデバイスの導入】** などがあります。

しかし、**管理するシステムの増加など**により、
**ホワイトカラー業務は、さらに迅速且つ、適確な業務**を行う必要があります。

ビジネスモデルがサプライチェーンに関与する場合、
**2024年問題でホワイトカラー業務も大きく影響を受けることでしょう。**

そこで、**Workatoを活用すると、サプライチェーンを統合させて「円滑」にする**ことができます。
WorkatoはiPaaS製品です。システムやデータを繋げることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570089/0b770c4c-037f-2cde-3b7f-e77baa4c3b7b.png)

例えば
物流システムと在庫管理の連携：
**トラッキングデータから、納期予定日をリアルタイムに反映**

販売システムと生産・調達システムの連携：
**販売状況をリアルタイムに連携し、生産・調達決定のリードタイムを短縮**

Workatoでサプライチェーンの各要素を繋げることができれば、シームレスな環境を実現することができます。サプライチェーンの強化を加速できることでしょう。

## Workatoで業務プロセスを刷新できる

Workatoはローコードで開発できるiPaaS製品です。
iPaaSとはシステムやデータを繋げるためのアプリケーションです。

繋げることで組織全体を統合させることができます。
Workato公式では、以下のように説明されています。

>全社的なシステム統合からデータ連携・自動化を実現し、効率化とデータドリブンによりビジネス変革を加速する。...
API連携、iPaaS、会話型Bot、 ERPなどのレガシーシステムとの連携、RPAとの連動、ワークフロー自動化のすべて機能が単一のプラットフォームに搭載されているため、Workatoのみで組織全体の統合・自動化を実現することが可能です。...

[Workato公式｜エンタープライズ オートメーション プラットフォーム](https://workato.jp/)

組織全体の統合も可能ですが、ノンコア業務である、システムやデータを連携させることで、**システム間の無駄な入力作業を省き、業務プロセスを刷新する**こともできます。
Workatoはトリガーとアクションを設定して、開発を進めていきます。

### トリガーとは
**特定の事象が発生すると、あらかじめ設定された動作やプロセスが自動的に開始される仕組み**のことです。

Workatoにシステムを監視させて、登録や更新を検知したら起動するリアルタイムのトリガーや、設定した日時に起動するスケジュールのトリガーなどがあります。

### アクションとは
トリガーをきっかけに処理を行う仕組みのことです。Workatoでは、**多数のアプリケーション**を用意しているので、業務に合わせたプロセスを作ることが可能です。(画像は一部です）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570089/9ccc8f83-e12e-a2c3-15f7-4b6b44fb4b7f.png)

Workatoはアクションやトリガーなどで、レシピを作成していきますが、
実行結果などをデータで閲覧することも可能です。
そのため、連携したSaaS(クラウドサービス)の利用履歴を確認することによって
よく使用されているかどうかなどの費用対効果の指標としての参考にすることもできます。
別記事で、ジョブ一覧や入力・出力情報の確認方法を紹介しているので、参考にしてみてください。

https://bstyle-value-technologies.blogspot.com/2024/05/workato-subscription.html

## 終わりに

公式ではデータドリブンも可能にすると説明しています。
データトリブンとはデータ収集をして意思決定をする取り組みのことを指しています。

例えば、サプライチェーン上で、遅延などの問題が起きていた場合に、
ボトルネックとなる部分の情報を抽出し、改善に向けた取り組みを迅速に行うことができます。

弊社では、業務効率化や自動化に関する記事を書いているので、参考にしてみてください。

https://bstyle-value-technologies.blogspot.com/search/label/Workato
ギター マルチエフェクター MOD Dwarf を無料で使ってみよう(6) -Ver 0.0.10&0.0.11-

1週間もしないぐらいの頻度でバージョンアップされていますね。
あとVer 0.0.11も出ました。ASIOドライバの修正ぐらいなのようです。

MOD Desktop をよく知らないという人は[過去の記事](https://qiita.com/Inqb8tr_jp)『ギター マルチエフェクター MOD Dwarf を無料で使ってみよう(1) 』を読んでみてください。すぐに使いたいという人は[ダウンロード](#ダウンロード)からダウンロードしてインストールしてください。

![screenshot4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129361/3d59c1b4-6615-922d-3492-4f9c2621becd.png)

## 変更点

* Bata Back Track ペダルボードの追加
* INFO: USEFUL.TIPS ペダルボードの追加
* 【追記】ASIOドライバの修正（Ver 0.0.11)

今回のペダルボードは上記のスクリーンショットからもわかるようにギター入力がありません。一番左側のStep Seq. 8x16 x42プラグインの下の方にある**Sync**ボタンを押すことでバッキングトラックが再生できるようです。

Ver 0.0.11ではASIOドライバの修正がおこなわれましたが、これはDAWへの入力に不具合があったからのようです。ということでWindowsでもDAWへの入力は可能のようですが、Reaperで試したところ、音を取り込めたものの再生は音が出ませんでした。バグなのか未開発ということなのかはわかりません。

下記はRepaerの設定画面です。

![スクリーンショット 2024-02-14 095433.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129361/6202a9d5-7883-d0c5-f668-6bdbfbb8a9dd.png)


下記はフォーラムでのVer 0.0.10の公開投稿です。

https://forum.mod.audio/t/introducing-the-mod-app-for-desktops-beta-release/10495/214

## ダウンロード

https://github.com/moddevices/mod-desktop/releases/tag/0.0.10

https://github.com/moddevices/mod-desktop/releases/tag/0.0.11
【Git】　fatal: Unable to create '○○': File exists. のエラーの対処法

半年以上前に作成した記事が眠っていたので、ちゃんと編集して載せたいと思います。
同じエラーで悩んでいる方の参考になれば幸いです。

## はじめに
gitでプロジェクトを管理していたら
```
fatal: Unable to create '○○': File exists.
```
というエラーが出てしまったので、後で見返せるように投稿します。

所々間違っている点があるかもしれませんが、ご了承ください。

## エラーの内容
```
fatal: Unable to create '○○': File exists.
```

このエラーの内容ですが、簡単に言うと同じリポジトリ内でプロジェクトの強制終了や、フリーズ、gitのコマンドが複数同時に実行されてしまっているときに起きるエラーだそうです。

### index.lockファイルとは
同時に複数のユーザーが同じGitリポジトリにアクセスする場合、同じファイルでの変更（競合状態）が起こらないようにGitがindex.lockファイルを生成し、競合が起きないようにロックをかけてくれています。
今回は、プロジェクトのフリーズ、強制終了等によってindex.lockファイルにロックがかかってしまったのではないかと思います。

## エラーの解決法
### index.lockファイルの削除
まずは、ロックがかかってしまっているindex.lockファイルを消す必要があります。
とはいってもエクスプローラーから普通に'index.lock'ファイルを消そうとしても表示されません。
そのため、コマンドプロンプトからindex.lockファイルを削除します。

### ターミナル→コマンドプロンプトで対象のディレクトリに移動
エラーが出てしまっている'フォルダ名/.git'ディレクトリまでcdコマンドで移動します。

### dirコマンドでファイルの一覧を表示
dirコマンドで.gitフォルダ内の一覧を表示します
```
dir
```
ファイルの一覧↓
```
 ドライブ C のボリューム ラベルは Windows です
 ボリューム シリアル番号は 82FD-F600 です

2023/10/19  18:01                19 COMMIT_EDITMSG
2023/10/19  15:31               251 config
2023/10/19  15:31                73 description
2023/10/19  15:31                23 HEAD
2023/10/19  15:31    <DIR>          hooks
2023/10/19  18:01            64,708 index
2023/10/20  16:26                 0 index.lock //★コレ
2023/10/19  15:31    <DIR>          info
2023/10/19  15:32    <DIR>          logs
2023/10/20  16:27    <DIR>          objects
2023/10/19  15:32    <DIR>          refs
               6 個のファイル              65,074 バイト
               5 個のディレクトリ  46,534,533,120 バイトの空き領域
```

このようにフォルダ内のファイルが出力されるので、index.lockファイルがあることを確認します。

### delコマンドを使用し、index.lockファイルを削除する
index.lockファイルがあることを確認したらdelコマンドを使用してindex.lockファイルを消去します。

## 再びコミットを実行
この状態で再びコミットを行うとエラーが消え、commitやpushが行えるようになります。

### 参考記事

・index.lockファイルの概要
https://learn.microsoft.com/ja-jp/azure/devops/repos/git/git-index-lock?view=azure-devops

・【Git】index.lockのせいでコミット・プッシュ等が出来なくなった時の対処方法
https://harusara22.work/git-index-lock/#container

## おまけ
初めてqiitaに投稿しましたが、こういったエラー内容をすぐに忘れてまた調べての繰り返しだったので、今回は復習、アウトプットをする良い機会になりました。
また、色んなタイミングで復習がてら投稿したいと思います。
最後までお読みいただき、ありがとうございました。
【React】CORSエラーの備忘録

Reactでシステムのメンテナンスをしていたところ、以下のようなエラーが出た。
```
Access to XMLHttpRequest at 'http://127.0.0.1:3000/ファイル名' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
```
どうやらCORSポリシーに違反しているのでリクエストをブロックするとのことらしい。

ブラウザ（フロント側）からバックエンドサーバーにリクエストを送った時に起こるエラーでCORSポリシーによってアクセスが出来なくなってしまった。

ここからは私が実際に行ったやり方なので参考程度に見て欲しいです。（自信ない）

## Access-Control-Allow-Originヘッダーを追加
```
header('Access-Control-Allow-Origin: http://127.0.0.1:3000');
```
今回は記事を見ても上手く動かなかったのでhttp://127.0.0.1:3000 をヘッダーに追加。

:::note warn
＊を使ってすべてのオリジンからアクセスできるようにすることもできますが、非公開APIやセキュリティの面でも危ないので使うときは気を付けましょう
:::

### Access-Control-Allow-Originとは
Access-Control-Allow-OriginとはHTTPヘッダの項目の一つで、送信するコンテンツが他のサーバーとのリソース共有（CORS）を許可されているかを示すもの。

【参考記事】
[Access-Control-Allow-Origin 【ACAO】](https://e-words.jp/w/Access-Control-Allow-Origin.html#:~:text=Access%2DControl%2DAllow%2DOrigin%EF%BC%88ACAO%EF%BC%89%E3%81%A8%E3%81%AF,%E3%81%A6%E3%81%84%E3%82%8B%E3%81%8B%E3%82%92%E7%A4%BA%E3%81%99%E3%82%82%E3%81%AE%E3%80%82)

### package.jsonにプロキシ設定を記述する
以下の記事を参考にプロキシ設定
[Reactのproxy設定を細かく設定する](https://scrapbox.io/ponpoko04-blog/React%E3%81%AEproxy%E8%A8%AD%E5%AE%9A%E3%82%92%E7%B4%B0%E3%81%8B%E3%81%8F%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B)
```
   "proxy": {
     "/api": {
       "target": "http://127.0.0.1:3000"
     }
   }
```
だが、この書き方だとReactではエラーになるらしい。（実際にエラーが出てしまった）
間違っていたらすみません。

書き方を以下に変更したところエラーは出なくなった。
```
"proxy": "http://127.0.0.1:3000"
```

CORSがまだちゃんと理解できていないのでしっかり理解できるようにしたい。
マスタとトラン まとめ

プログラミングにも不変、可変がある。マスタは不変じゃねーの？素朴な疑問が浮かんだどうなんだろ。

> #### トランザクションテーブル
> 権限を持つ者であるならばレコードの追加、削除、カラムの値の変更が可能である。テーブルへの変更操作の頻度は多いため、保存容量は多くないとダメ。サービス開始後にレコードを追加される必要がある。

> #### マスタテーブル
> 管理者権限を持つ者であればレコードの追加、削除、カラムの値の変更が可能である。テーブルへの変更操作の頻度は少ないため、保存容量は少なくてすむ。サービス開始前にレコードを追加する必要がある。

# んじゃこれどっちになるん？
レコードの追加、削除、カラムの値の変更が不可能である。サービス開始前にレコードを追加する必要がある。
今の知識ではわかりません。


そもそもマスタの意味を間違えて覚えていたことに気づいた。
Go言語における環境変数使い方: osパッケージ

環境変数は、オペレーティングシステムにおける動作環境を定義するキーと値の組み合わせです。Go言語を用いたアプリケーション開発では、環境変数を活用することで、デプロイメントの柔軟性を向上させ、設定値を外部から注入することが可能になります。

Go言語の標準ライブラリであるosパッケージは、環境変数を操作するための関数群を提供しています。

### Getenvで環境変数の取得

`os.Getenv()` 関数を使用して、特定の環境変数の値を取得します。

```go
package main

import (
    "fmt"
    "os"
)

func main() {
    // "HOME" 環境変数の値を取得
    home := os.Getenv("HOME")
    fmt.Println("Home directory:", home)
}
```
このコードスニペットは、ユーザーのホームディレクトリパスを表すHOME環境変数の値を取得し、出力します。

### LookupEnvで環境変数の取得

`os.LookupEnv()`関数は、`os.Getenv()`と似ていますが、存在しない環境変数の場合にデフォルト値を返すことができます。

```go
package main

import (
    "fmt"
    "os"
)

func main() {
    debug, exists := os.LookupEnv("APP_DEBUG")
    if exists && debug == "true" {
        fmt.Println("Debug mode enabled")
    } else {
        fmt.Println("Debug mode disabled")
    }
}
```
この例では、APP_DEBUG環境変数が設定されているかを確認し、設定されていればその値を、そうでなければ設定されていない旨を出力します。

### Setenvで環境変数の設定

`os.Setenv()` 関数は、環境変数を設定または更新します。
```go
// "DB_PORT"という環境変数を設定
os.Setenv("DB_PORT", "3306")
```

### Unsetenvで環境変数の削除

`os.Unsetenv()`関数は、指定された環境変数を削除します。

```go
// "DB_PASSWORD"という環境変数を削除
os.Unsetenv("DB_PASSWORD")
```

### まとめ

`os`パッケージを使用することで、Go言語のプログラム内から環境変数を柔軟に取り扱うことができます。`os.Getenv()`と`os.LookupEnv()`を使用して環境変数の値を読み取る方法、および`os.Setenv()`で環境変数を設定する方法を理解することは、Go言語でのアプリケーション開発において非常に役立ちます。

### 参考資料

Go言語標準ライブラリ osパッケージ: https://golang.org/pkg/os/

### オンラインデバッグ
https://go.dev/play/
DNSサーバーとDNSレコード

## DNSサーバー
ドメインとIPアドレスを変換してくれるサーバー
別名がネームサーバー

## DNSレコード
設定する事でWebサイトやメールが使えるようなるレコード類

## Aレコード	
ブラウザ表示するドメインにIPアドレスを指定する為のレコード

## MXレコード 
メールアドレスのドメインにメールサーバーを指定する為のレコード

## NSレコード
ドメインにDNSサーバー(ネームサーバー)を指定するレコード
引数、戻り値とは？関数について理解が足りないので勉強してみた

関数についてあまり理解できていなかったので、
引数、戻り値について調べた備忘録です。

下記を参考にしました。

引数、戻り値とは？【分かりやすい解説シリーズ #7】【プログラミング】
https://youtu.be/aTkXCEU65bg?si=DTP1RSfFA7NJakCr
```
引数（パラメータ）＝材料
戻り値（返り値）＝結果
```
関数は、各言語で用意されているものもあるし、自作することもできるもの

```
材料をいれると
↓
処理されて
↓
結果が出てくる
```

例えば、大根電動おろし器があったとする
```
大根を処理機に入れて
↓
おろし処理され
↓
すりおろされた、大根おろしがでてくる
```
プログラミングの考えに戻すと
```
引数
↓
関数
↓
戻り値
```

## 実際の処理（phpの場合）関数の定義
```php
function 関数名(引数){
	行う処理;
	return 戻り値;
}
```
## 簡単な実例
```php
function colc ($num1,$num2){
	// 引数１と引数２を足して$totalに入れる
	$total = $num1 + $num2;
	// $totalを戻り値として返す。
	return $total;
}
```
関数の名前はcalculator（カルキュレーター）から
「calc(計算)」にしました。
```php
//作った関数を呼び出す
$kekka = calc(1,2);
```
1,2という数字を引数として渡します。
そして結果である戻り値を、$kekkaという変数の中で受け取っています。
これを実行すると、$kekkaという変数の中には
「３」という数字が入ってきます。

標準関数について、
例えば「number_format」という標準関数では、
数字をを渡すと、③桁ずつカンマ付きにして返してくれるというphpの標準関数です。
https://www.php.net/manual/ja/function.number-format.php
このページを見てみると、関数の名前、処理内容が書いてあります。
さらに下の方を見てみると、引数であるパラメータの仕様、戻り値が掲載されています
このように、関数には引数と戻り値が予め指定されているので、
関数を使う際にはどんな引数が必要で、どんな返り値が返ってくるのかということを
しっかり理解して使う必要があります。

## まとめ
・関数とは機能を部品化したもの
・引数とは関数に渡す材料
・戻り値とは関数から返ってくる処理結果
2024年でGWTを利用する意味

Webアプリ開発と言えば、フロントとバックで言語を分ける事が一般的のようですが、
GWTというツールを使えば、一つの言語だけで、Webアプリが開発可能です。

    しかもSPA(Single Page Application)としてページ遷移することなく、アプリを動作させることができます。

    通信も、Javaだけで行うことができ、JsonやXMLなどを意識する必要がありません。

　その為、開発も柔軟で速く行う事が可能です。

    https://www.gwtproject.org/
【CSS】ホバー時に外から内に囲まれるように表示される罫線アニメーション

■概要
CSSの::beforeと::after疑似要素を使用して、リンクにホバーした際に罫線が動的に表示されるエフェクトを実装する方法を紹介します。
<br>
■具体的に
リンクの周りに初期状態で表示される罫線「」が、ユーザーがリンクにマウスを合わせたときに外側から内側に向かって拡大するアニメーション効果についてのコードと解説をしています。
<br>
■実装のメリット
このエフェクトを用いることで、ウェブサイトのUIに洗練された視覚的魅力を加えることができます。
<br>
■実際の挙動

![screenshot_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711935/b74f14f5-0302-7243-1da3-a6e4dd45f387.png)

![screenshot_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711935/ad035f42-4110-8ffb-18f5-a6ad0d8a57e1.png)
<br>
■コード

```HTML:HTML
<div class="readMore">
    <a href="#">Read More</a>
</div>
```



```CSS:CSS

#about .readMore a {
  position: relative;    /* 相対指定 */
  display: inline-block; 
  font-size: 0.875rem;   /* フォントサイズ */
  padding: 18px 45px;    /* 内側の余白 */
  color: #000;           /* 文字色 */
}

/* ::beforeと::after疑似要素に共通するスタイル */
#about .readMore a::before, 
#about .readMore a::after {  
  border: 2px solid #E03131;
  position: absolute;               /* 絶対指定 */
  content: "";                      /* コンテンツの内容を空に */  
  transition: all 0.3s ease-in-out; /* 徐々に加速 */
}

/* ::before疑似要素のスタイル「左上括弧」 */
#about .readMore a::before {  
  border-width: 2px 0 0 2px; /* 上と左の境界線のみ表示 */
  top: 0;                    /* 要素の上端からの位置 */
  left: 0;                   /* 要素の左端からの位置 */
  width: 30px;               /* 幅を30pxに設定 */
  height: 25px;              /* 高さを25pxに設定 */
}

/* ::after疑似要素のスタイル「右下括弧」 */
#about .readMore a::after {  
  border-width: 0 2px 2px 0; /* 下と右の境界線のみ表示 */
  bottom: 0;                 /* 要素の下端からの位置 */
  right: 0;                  /* 要素の右端からの位置 */
  width: 30px;               /* 幅を30pxに設定 */
  height: 25px;              /* 高さを25pxに設定 */
}

/* ホバー時の::beforeと::after疑似要素のスタイル */
#about .readMore a:hover::before,
#about .readMore a:hover::after {  
  width: 100%;               /* 幅を要素全体に拡大 */
  height: 100%;              /* 高さを要素全体に拡大 */
}

```

■コードの解説
1、aタグに相対指定
2、疑似要素beforeとafterに共通するスタイルを充てます、具体的には絶対指定とボーダーの太さと色、そしてアニメーションの速度です
3、疑似要素after
border-widthを使い括弧の左上を作成します(「 )
上と左を2px、右と下は0に設定することで実現します。
3、疑似要素before
こちらもafterと同じ考え方で右下括弧( 」)を表示させます。
4、疑似要素にカーソルが触れた時にwidthとheightを100％にして周りの罫線を全て表示させます。
0xL4ugh 2024 - Lost In History Writeup

# CTFサイト

https://ctf24.0xl4ugh.com/

# 問題

原文

>MM0X and xElessaway were in a mission to find someone but seems they had a stalker and got us this picture of them both. can you identify the place they were?

日本語

>MM0X と xElessaway は誰かを探すという任務に就いていましたが、ストーカーに遭ったようで、二人の写真を入手しました。彼らがいた場所を特定できますか？

写真

![LostInHistory.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/a4ae22de-3d9a-a26c-2adf-738662bfc7e5.jpeg)


# 解法

まず、右側にアラビア文字の様なものが見えたのでエジプトあたりかなと推測。
そして、写真の奥側に彫刻の様なものがあり、博物館や美術館だと推測。

とりあえず、Googleの画像検索をかけてみると写真のような場所のサイトを発見。

![画像検索.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/4fe59e34-9191-1b94-2174-16f234abc6f8.png)

アクセスすると「The National Museum of Egyptian Civilization(国立エジプト文明博物館)」という場所のサイトで、写真の場所と一致していた。

https://nmec.gov.eg/the-nmec-has-received-mrs-khalida-bouzar-un-assistant-secretary-general-undp-assistant-administrator-regional-director-for-the-arab-states/

ということでFlagは`0xL4ugh{The national museum of Egyptian Civilization}`
Power Apps の Sorry, you'll need to sign up

# 概要

Power Appsポータル (https://make.powerapps.com) にアクセスすると下記のような画面でアクセスできない場合がありますので、解決案としてメモしておきます。

![screencapture-make-powerapps-error-nobaptenant-2024-02-13-17_13_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287622/4bf0ede7-9edf-0e77-c340-84880bf63e10.png)

# 解決案

ブラウザのキャッシュを削除してください。

## Microsoft Edge

https://support.microsoft.com/ja-jp/microsoft-edge/microsoft-edge-%E3%81%AE%E9%96%B2%E8%A6%A7%E5%B1%A5%E6%AD%B4%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%BE%E3%81%9F%E3%81%AF%E5%89%8A%E9%99%A4%E3%81%99%E3%82%8B-00cf7943-a9e1-975a-a33d-ac10ce454ca4

## Google Chrome

https://support.google.com/accounts/answer/32050?hl=en&co=GENIE.Platform%3DDesktop
【備忘録】GitHubにSSH Keyを登録したり、複数のSSH Keyを使い分けたりする

:::note warn
初学者によるメモ書きです。
間違いや非効率な点、セキュリティ的に問題のある行為が含まれる場合はご指摘ください
:::

WSLとかでつかえる

最初にgitのアップデートをしておくと安心かも
`sudo apt-get update`
`sudo apt-get install git`

## 設定方法
### SSHキーの作成
- `ssh-keygen -t rsa`
- いくつか質問が出てくるはず．特になければ全部EnterでOK

### GitHubに公開鍵を登録
- [SSH keys](https://github.com/settings/ssh)にアクセスして `New SSH key` をクリック
- タイトルは区別できる好きな名前をつける
- キーは，`cat ~/.ssh/id_rsa.pub | clip.exe` で公開鍵のキーをクリップボードでコピーできるので，そのまま貼り付ける (Windows系の場合)
	- Mac なら `cat ~/.ssh/id_rsa.pub | pbcopy`
	- Ubuntu なら `sudo apt-get install xsel` で xsel をインストールしたあとに `cat ~/.ssh/id_rsa.pub | xsel --clipboard --input`
- `Add SSH key` をクリックして登録完了

### 設定確認
- `ssh -T git@github.com` で `Hi {NAME}!` と表示されればOK


## GitHubからのクローン
- リポジトリのトップページで緑色の `<> Code` から`SSH` を選択
- 出てくる文字列をコピーし，`git clone {コピーした文字列}` でクローンできる



## アカウントの設定
- ユーザ名 `git config user.name {GitHubのユーザ名}`
- メールアドレス `git config user.email {GitHubのメールアドレス}`
- オプション `--local` をつけると，そのgitディレクトリだけで反映される


## 複数のGitHubアカウントを使い分けたいとき
### 新しいGitHubアカウント用の公開鍵・秘密鍵をつくる
- `cd ~/.ssh` で .ssh ディレクトリに移動
- `ssh-keygen -t rsa`
- 1番目の質問で，追加するアカウント用のキーの名前を決める
	- `id_rsa` と被らないように `id_rsa_sub` など
- 残りの質問はEnterでぽいぽい
- `ls` で鍵が生成させれているか確認しておく

### config ファイルに追加するアカウントの設定を書き込む
- `touch config` で .sshディレクトリ内にconfigファイルを作成
- `nano config` などで開く
- 以下のように設定する
	- `github` や `github-sub` は任意のホスト名 (あとで接続するときに使う名前)
	- `IdentityFile` は秘密鍵の場所
```
#メインアカウント
Host github #任意のホスト名
  HostName github.com
  IdentityFile ~/.ssh/id_rsa #メインアカウントの鍵のファイル
  User git
  Port 22
  TCPKeepAlive yes
  IdentitiesOnly yes

#サブアカウント
Host github-sub #任意のホスト名
  HostName github.com
  IdentityFile ~/.ssh/id_sub_rsa #サブアカウントの鍵のファイル
  User git
  Port 22
  TCPKeepAlive yes
  IdentitiesOnly yes
```

### ディレクトリごとにアカウントを変える設定
- `~/.gitconfig` と同じディレクトリに `.gitconfig_private` と `.gitconfig_work` をつくる
- それぞれに以下のように記述する
```
[user]
    name = <USER>
    email = <MAIL>
```

- `.gitconfig` に以下を追記する (`gitdir`は適宜変更)
```
# workディレクトリの時に.gitconfig_workが読み込まれる
[includeIf "gitdir:~/GitHub/work/"]
path = ~/.gitconfig_work

# privateディレクトリの時に.gitconfig_privateが読み込まれる
[includeIf "gitdir:~/GitHub/private/"]
path = ~/.gitconfig_private
```


### 接続確認
- 先ほど設定したホスト名で `ssh -T [Host]` で接続できる
	- `Hi {アカウント名}!` のメッセージが表示されればOK

### 注意
- GitHubからのクローンなどでリモートと接続するときは以下のように `git@[Host]` として接続するようにする
```
git clone git@[Host]:<アカウント名>/<リポジトリ名>.git
```

- 特定のアカウントで管理したいリポジトリ内は `git config user.name NAME --local` で設定しておく
	- 正しいアカウントでできているかは commit して試してみるとか


## 参考
- [ディレクトリによってgitアカウントを自動で切り替える設定(includeIf) #Git - Qiita](https://qiita.com/shungo_m/items/387d70b1645ae03435b5)
- [複数のgitアカウントを使い分ける #Git - Qiita](https://qiita.com/0084ken/items/f4a8b0fbff135a987fea)
databricksのバージョン管理

# databricksのバージョン管理

Google Colab + GitHubでnotebookの変更履歴を管理するとたまにGitHubにコピーをとり忘れたりすることがある

databricksは自動的に変更履歴を取得してくれるのでcloneをとらずに安心してnotebookを編集できる

![dbc_ver.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3687201/63ea7aed-d1dc-ee25-88a0-9d5e16c43cc8.png)

データ分析コンペでsubmitを60回くらいやるとnotebookのバージョンとsubmissionファイルの対応が怪しくなるがdatabricksの変更履歴を使えば日付時刻をキーにして対応を探り当てることができるので便利

[第2回 金融データ活用チャレンジ](https://signate.jp/competitions/1325)で提供されるMLclusterを使うと学習に使ったデータも自動保存してくれるようだ
![dbc_exp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3687201/143f086f-cd3a-8ece-d4a2-0e7cebe5454c.png)
Cloud Tasksで長時間実行ジョブのキュー管理をマスターする

# 背景
- 比較的長めのジョブタスクを制御するqueueシステムを作りたかったので、Cloud Tasksで簡易実装をしていきます
- pubsubでは確認応答期限が最大10分. 1時間までは引き延ばせますが、実装が複雑になるのでCloudTasksで実装することにしました

# Cloud Tasksとは

概要は以下ページ

https://cloud.google.com/tasks/docs/dual-overview?hl=ja

> すべてのワーカーはデフォルトのタイムアウト期限の 10 分、最大 30 分以内に HTTP レスポンス コード（200～299）を Cloud Tasks サービスに送信する必要があります。別のレスポンスが送信された場合、あるいはレスポンスがない場合、タスクが再試行されます。

https://cloud.google.com/tasks/docs/quotas?hl=ja

- タスクの最大サイズ1MBです

# 実装

- あるAPI(https://sample.com/hoge)へのpushを行うqueueです
- レスポンスコード(200~299)のレスポンスが返ると、タスクはキューから出されます


```py

import json
from google.cloud import tasks_v2
from google.protobuf import duration_pb2

def create_task():
    # ジョブ内容のデータ作成
    data_dict = {
        'job_name': 'test_job_name',
        'count': 2
    }
    data_str = json.dumps(data_dict, ensure_ascii=False)
    data = data_str.encode("utf-8")
    
    client = tasks_v2.CloudTasksClient()

    # タスクの作成
    # oidc認証設定もここで行います
    task = tasks_v2.Task(
        http_request=tasks_v2.HttpRequest(
            http_method=tasks_v2.HttpMethod.GET,
            url='https://sample.com/hoge',
            headers={"Content-type": "application/json"},
            oidc_token=tasks_v2.OidcToken(
                service_account_email='tekitou@developer.gserviceaccount.com',
            ),
            body=data
        ),
    )

    # 実行完了までの時刻を設定
    # 最大の30分にします
    duration = duration_pb2.Duration()
    duration.FromSeconds(1800)
    task.dispatch_deadline = duration

    # Use the client to build and send the task.
    return client.create_task(
        tasks_v2.CreateTaskRequest(
            parent=client.queue_path('PJ_PATH', 'asia-northeast1', 'queue_name'),
            task=task,
        )
    )
```

# 参考

https://cloud.google.com/tasks/docs/samples/cloud-tasks-create-http-task-with-token?hl=ja

https://cloud.google.com/tasks/docs/samples/cloud-tasks-create-http-task?hl=ja