OmniAICreator/Qiita-1.07M huggingface dataset:
[Flutter] iOS風なアプリの背景色の仕方


少しずつ書いていきます。


僕は `Swift` -> `Flutter` だったので、アプリのUIについてはiOSの方が好きでした。。


ではやっていきましょう

# 色の設定方法

```
CupertinoColors.secondarySystemBackground,
```

# 最後に
![Frame 9 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/87f2a488-c5cd-549d-f07f-01b44a1317b8.png)
<b>Veroo</b>は、Blockchain技術を活用した「想いの巡るグルメSNSアプリ」です。食に対する熱量、例えばラーメンがめちゃくちゃ好きで年間400杯食べているとか、変態的に具材にこだわった中華料理を作っているなどのような、今まで直接お金にはならなかった食に対する情熱や熱量、その裏側にある想いがトークンを使うことで巡る世界。自分のラーメンに費やす熱量がコミュニティに承認される。自分がほんとにいいと思って作った食べ物がコミュニティで広まる。Verooは単なるSNSアプリではなく、クリエイターたちの想いが紡がれるソーシャルグルメアプリです。

##### Homepage: https://veroo.xyz/
##### Discord URL：https://t.co/VoT0gpsflA
図解人材マネジメント入門に学ぶ、人事評価とは（連載第8回/25回）

# 前回の記事
https://qiita.com/rf_p/items/48b924ba42303f9efbef

# 連載の構成
- この記事は、[マネジメントについて一人で考える Advent Calendar 2022](https://qiita.com/advent-calendar/2022/management-solo)の連載記事です
    - 1記事目から読んでいただいても良いですし、気になる記事から読んでいただいても問題ありません
- 全25回分の構成は、次の通りです
    - 第1〜6回：ドラッカーの『マネジメント』を中心に解説します
    - 第7〜13回：『図解人材マネジメント入門』を中心に解説します
    - 第14〜22回：『エンジニアのためのマネジメントキャリアパス』を中心に解説します
    - 第23〜25回：私の経験談を中心に、まとめに入ります

# 人事評価の目的は？
- 人材マネジメント6項目のうち1番目は、人事評価です
- ほぼ全ての会社組織において、人事評価は必ず行われるでしょう
- では、人事評価は何のために行われるのでしょう？
    - それに関して、参考図書では次の通り解説されています
> 人事評価の目的は3つあります。「公平感ある処遇の分配」「社員の活用と育成」「企業文化の醸成」です。  
> 引用：[図解 人材マネジメント入門 人事の基礎をゼロからおさえておきたい人のための「理論と実践」100のツボ](https://www.amazon.co.jp/dp/4799326120)
- 今回はこの3点について、ITエンジニアに落とし込んで考えてみます

# 公平感ある処遇の分配
- 公平感ある処遇の分配について考えてみます
- 例えば
    - 年功序列の色が強く、年齢や社歴で評価される
    - 成果主義の色が強く、年齢や社歴より、スキルや成果が評価される
    - どちらの方が公平感ありますか？
- 後者が公平感ある、と答える方が多そうです
    - しかし、常にそうとは限りません
    - 年功序列を重んじる日本企業も一定存在し、そちらに公平感があると感じる方もいらっしゃるでしょう
- toBの枯れた技術を主に使う会社では経験年数がものを言いやすいので、年功序列であるケースもあるでしょう
- 逆にtoCのモダンな技術を取り入れる会社では、絶えず新たな技術を学び続ける必要があるので、成果主義に寄りやすいのではないでしょうか
- つまり会社に合わせた"公平感"が重要になります

# 社員の活用と育成
- 社員の活用と育成について考えてみます
- 例えば
    - 社運を賭けた新規事業の立ち上げに、1人だけITエンジニアがアサインされるとします
        - 担当エンジニアとして、技術力はまだ低い若手エンジニアのAさんがアサインされました
        - 最初のうちは若手にチャンスを増やそうと歓迎されていたけれど、何ヶ月経っても成長意欲が低く、不満ばかり
        - マネージャーはその状況に見て見ぬ振りをして、その配置の意図を説明したり変える様子がない
    - こういうシチュエーションを想像したら、いかがでしょうか
        - 恐らく、意欲の高い他メンバーからAさんへの風当たりは強くなるでしょう
        - 一向に配置転換をしないマネージャーへも、厳しい目が向けられるでしょう
        - そして組織の力は弱まり、成果は出づらくなっていきます
    - 活用に寄りすぎると若手が成長しづらいですし、育成に寄りすぎると看過できない危機に直面するかもしれません
        - どちらの観点も重要ですね

# 企業文化の醸成
- 企業文化の醸成についても考えてみます
- 例えば
    - 技術力はまだ低いけど、各所からの質問や相談に親身に回答するBさん
    - 技術力はすごく高いけど、自分がやりたい領域だけ突き詰めるCさん
    - どちらの評価や給与を高く評価しますか？
- 上記例に関して、結論は"その組織による"でしょう
    - 周囲への貢献や一体感を重視する組織であれば、前者が高く評価されたり
    - 持っているスキルレベルやアウトプット量を重視する組織であれば、後者が高く評価されます
- つまりどういった人が評価されているか、逆に評価されづらいかによって、会社がどういった人材を求めているか強いメッセージになります

# 終わりに
- 改めて、いかがでしたでしょうか
    - 公平感ある処遇の分配
    - 社員の活用と育成
    - 企業文化の醸成
- 次回は報酬について考えます

# 次の記事
https://qiita.com/rf_p/items/de363f8e5aa9a317cfa3

- 連載記事一覧
    - [マネジメントについて一人で考える Advent Calendar 2022](https://qiita.com/advent-calendar/2022/management-solo)
図解人材マネジメント入門に学ぶ、人材マネジメントとは（連載第7回/25回）

# 前回の記事
https://qiita.com/rf_p/items/7f87bd279d964f01c288

# 連載の構成
- この記事は、[マネジメントについて一人で考える Advent Calendar 2022](https://qiita.com/advent-calendar/2022/management-solo)の連載記事です
    - 1記事目から読んでいただいても良いですし、気になる記事から読んでいただいても問題ありません
- 全25回分の構成は、次の通りです
    - 第1〜6回：ドラッカーの『マネジメント』を中心に解説します
    - 第7〜13回：『図解人材マネジメント入門』を中心に解説します
    - 第14〜22回：『エンジニアのためのマネジメントキャリアパス』を中心に解説します
    - 第23〜25回：私の経験談を中心に、まとめに入ります

# 人材マネジメントについて
- この記事以降数回に渡って、[図解 人材マネジメント入門 人事の基礎をゼロからおさえておきたい人のための「理論と実践」100のツボ](https://www.amazon.co.jp/dp/4799326120)を参考図書として、人材マネジメントの解説をしていきます

# 参考図書の紹介
- 今後数回この本に沿って紹介するため、まずはこの参考図書について触れさせてください
- 100のツボというタイトルの通り、100個のQ&A形式で人材マネジメントの解説がされています
    - ツボ1個につき見開き構成で、左側に文章、右側に図解がされています
    - 10Chapter × 10個のツボで100個という構成
- とにかく分かりやすく振り返りやすい本です
- 電子書籍だと見開きという構成上読みづらいので、紙の本で買うのを強くオススメします

# 人材マネジメントの構成要素
- 人材マネジメントは6種類から構成されます
    1. 人事評価
    2. 報酬
    3. 等級
    4. リソースフロー
    5. 人材開発
    6. 組織開発
- 詳しい解説は、次回以降の連載で紹介します

# 人材マネジメントはなぜ重要か
- 人材マネジメントは、業界職種問わず重要なものです
- もし人材マネジメントがうまくいっていないと、様々な問題が起きます
- その中でも特に、定着率低下により人材確保が難しくなることは避けたいでしょう
    - 例えば
        - 人事評価の納得度が低い
        - 報酬に公平感が無い
        - 等級が不明瞭
        - オンボーディングや引き継ぎ体制が未整備
        - 同じ仕事の繰り返しで、成長の機会が無い
        - それぞれが個々に動いており、チームの一体感が無い
    - このような状況では、離職も増えます
- 人材の流動性は一定必要で、離職は悪ではありません
    - しかし離職率が著しく高いと、常に採用や教育に時間やお金がかかります
    - 慢性化していると、業務に支障をきたすようになります

# ITエンジニアにおける重要度はどうか
- ではITエンジニアに限った場合、人材マネジメントに対する重要度はどう変わるでしょうか？
    - より重要度が増すと考えています
- ITエンジニアは、転職やフリーランス転向に対するハードルが低いです
    - パソコンとインターネットさえあれば、場所を問わず働きやすい
    - 一度スキルを身に着ければ即戦力化しやすい
    - 業界として慢性的な人材不足
    - それに伴って給与も増加傾向
    - 等
- そして当然ながら、市場価値の高いスキルや経験をお持ちの方は、転職によるキャリアアップの可能性が高まります
- つまり**人材マネジメントがうまくいっていないと、市場価値の高い方が、次々離職する**恐れがあります
- こう考えると、いかに人材マネジメントを疎かにできない理由がお分かりになったでしょうか

# 最後に
- 繰り返しますが、離職自体が悪ではありません
    - ポジティブな転職も、世の中には多く存在します
- 次回からは、人材マネジメントで気をつけるべきことを考えていきます

# 次の記事
https://qiita.com/rf_p/items/59ddd4812036a84f7ff8

- 連載記事一覧
    - [マネジメントについて一人で考える Advent Calendar 2022](https://qiita.com/advent-calendar/2022/management-solo)
evenメソッドで偶数値の取得

# 問題
配列にある値の中から偶数の値をカウントして出力するメソッドを作りましょう。

出力例：
```
count_evens([2, 1, 2, 3, 4]) → 3
count_evens([2, 2, 0]) → 3
count_evens([1, 3, 5]) → 0
```

ヒント
even?というメソッドを使いましょう。
　
　
　
# 解答
```
def count_evens(nums)
  count = 0
  nums.each do |num|
    if num.even?
      puts count
    end
  end
end
```
　
　
　
# 模範解答
```
def count_evens(nums)
  count = 0
  nums.each do |num|
    if num.even?
      count += 1
    end     
  end
  puts count
end
```

# 解説
配列の中の偶数の数を出力するためにカウントした数を保持するための変数countを用意する。
countをeach文の中で定義するとcount = 0が繰り返し処理されてしまうのでeach文のループ外で定義する事。

even?メソッドとは
偶数であればtrue、そうでない場合はfalseを返します。
```
10.even? # => true
5.even?  # => false
```

each文で数字を順に取り出し、even?メソッドで一つずつ偶数か判断し、偶数だった場合はcountに1を足していく。

each文の処理が終了し、countに代入された最終的な数が偶数の数となる。
　
　
　
　
# まとめ
変数countに対しcount = 0しか設定できていなかった為、偶数だった場合のみ数をカウントしていく(count +=1)をできていなかった。
complitionハンドラーについて（自分なりの解釈で）簡単にまとめてみた

## はじめに
complitionハンドラーについて多くの記事や書籍を漁ってみたがどうにもイメージが掴みづらい。そのため、すごくざっくりとしたイメージを記事にまとめてみる。

## complitionハンドラーについて
- 非同期処理では、リクエストを送る実行をしても望んでいるタイミングでレスポンスが返ってこないみたいなことがある。その望んでいるタイミングでレスポンスを受け取るために使うのがcomplitionハンドラーだと考える。
    - 要は、complitionハンドラーを使って良きタイミングで確実に実行したい処理（レスポンス）をしましょうね、みたいなイメージ。 (これを俗に言う"コールバック"という)
- 基本的にはクロージャーの引数にcomplitionハンドラーを定義する。
    - また引数に非同期処理のcomplitionハンドラーを定義するときはクロージャーの型の前に@escapingをつける
    - func testComplitionCloser(complition: @escaping () -> void) { }   みたいな感じ

```swift:Swift
let greet: String = "こんにちは"
let name: String = "山田太郎です"

//complitionハンドラー
//実行から数秒後(遅延処理を使う)にprint文を出力する関数。
//引数complitionは非同期処理を扱うcomplitionハンドラー
func timerComplition(time: Double, complition: @escaping () -> Void ) {
    //遅延処理 (async == エイシンクと読む,非同期処理)
    DispatchQueue.main.asyncAfter(deadline: .now() + time) {
        //引数で指定したtimeの時間分遅延処理が終わったら、こちらも第二引数で指定したcomplitionハンドラーを呼ぶ
        //complitionはクロージャーのため、最後は必ず（）をつける。クロージャーを呼ぶ際は関数と同じような扱いなため（）が必要
        //イメージとしては、このcomplitionの中に実行したい処理を入れるイメージ
        complition()
    }
}

//遅延する時間を指定しつつ関数を使ってみる
timerComplition(time: 0) {
    //省略したcomplition（ハンドラー内の）クロージャーで実行する処理
    print(greet) //実行後、即こんにちはが出力
}

timerComplition(time: 2) {
    //省略したcomplition（ハンドラー内の）クロージャーでする処理
    print(name) //実行して２秒後に"山田太郎です"が出力
}




//ありそうな場面を想定して書いてみる
//ボタンを押したタイミングでcomplitionハンドラー走らせるみたいな（）
//ViewDidLoadに書かなければいけないことはここでは省略させてください🙇‍♂️
@objc func greetButtonTap() {
    timerComplition(time: 0) {
//省略されているcomplitionの中でprint文を定義
        print(greet)
    }
}

//こっちも同じ
@objc func nameButtonTap() {
    timerComplition(time: 2) {
        print(name)
    }
}

//出力
//この二つのボタンを押したらという程で理解してください🙇‍♂️
@objc func greetButtonTap() //timeは０秒のため、実行して0秒後に”こんにちは”が出力
@objc func nameButtonTap() //timeは２秒のため、実行して２秒後に”山田太郎です”が出力
```

## おわりに
記事の内容で誤った箇所がございましたらぜひご指摘ください。

## 参考記事
[iOSアプリ開発のためにSwiftでクロージャを実用的に使う方法
](https://qiita.com/maztak/items/ac668f5d8a47a46b8cb5)

## 開発環境
- Xcode-13.4.1
- Swift version 5.7
歌詞付きMIDIをMusicXMLに変換 リンクまとめ

# 概要
「歌詞付きMIDIをMusicXMLに変換」シリーズのリンクまとめです。

# リンクまとめ
作成済み
[その１: 歌詞情報の取得](https://qiita.com/shimajiroxyz/items/485723ae22a922f4df17)
[その２：音符の整理](https://qiita.com/shimajiroxyz/items/0efeec7b026562a8b228)
[その３：音符と歌詞の紐付け](https://qiita.com/shimajiroxyz/items/6a542b3efe4c62a936ff)
[その４：MusicXMLへの変換](https://qiita.com/shimajiroxyz/items/029a56ed3e513c838a81)
[その５：Webアプリ化](https://qiita.com/shimajiroxyz/items/6e8ddeb19f90cef2ad3e)

今後の予定（タイトル等、変更可能性あり）
なし


# メモ（参考にした／できそうな記事）
[midiと歌詞からmusicxmlを生成してNEUTRINOに渡したい(1)](https://pokosho.com/b/archives/3768)
[Laravel]firestoreのデータ取得

## TL; DR
- firestoreのデータの取得は`document`から`snapshot` へのアクセスが必要
- `snapshot`からは`data`にアクセスすればデータ取得可能

PHP環境でfirestoreへアクセスしようとした話。

### firestoreのデータ内容
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/780929/139004fe-3432-fb44-e801-09ff86550516.png)

### やったこと
https://qiita.com/43z708/items/e91c53710ef8cec4a537#laravel%E3%81%8B%E3%82%89firestore%E3%81%B8%E3%81%AEset%E3%81%8C%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B

記事の通り、サービス化する前に動作確認のためにいったん以下のソースコードが動くか確認

### 
```php
<?php
class FirebaseController extends Controller
{
    protected $db;

    public function __construct()
    {
        $this->db = app('firebase.firestore')->database();
    }

    public function load() {
        $collection = $this->db->collection('talk_api');

        $document = $collection->document('R4166zsxknrklBy607jH');

        return response()->json([
            'data' => $data,
        ]);
    }
}
```

### 想定した戻り値
```
array:1 [▼
    "doc" => "hogehoge"
  ]
```
とか
```
{doc: "hogehoge"}
```
のKey-Value形式のデータ

### 実際の戻り値
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/780929/a402dbb4-01e7-02a0-8bf1-90b018f003f1.png)
おや。。。違う。。。

### 解決策
想定した値を取得するにはsnapshotまでアクセスする必要があった

https://googleapis.github.io/google-cloud-php/#/docs/cloud-firestore/v1.26.0/firestore/documentsnapshot

```php
use Google\Cloud\Firestore\FirestoreClient;

$firestore = new FirestoreClient();
$document = $firestore->document('users/john');
$snapshot = $document->snapshot();
```

`$snapshot`には`Google\Cloud\Firestore\DocumentSnapshot`オブジェクトが格納されており、上記ドキュメントのメソッドたちが使えるようになる

`dd($snapshot)`すると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/780929/b6a37cb0-cefe-191c-c648-7f15b8a7eb76.png)

`data`に求めているデータがいる

そして、ドキュメント見ていたら`data()`ってメソッドがあったので使ってみたら取得できた

```php
class FirebaseController extends Controller
{
    protected $db;

    public function __construct()
    {
        $this->db = app('firebase.firestore')->database();
    }

    public function load() {
        $collection = $this->db->collection('talk_api');

        $document = $collection->document('R4166zsxknrklBy607jH');
        $snapshot = $document->snapshot();
        $data = $snapshot->data();
        return response()->json([
            'data' => $data,
        ]);
    }
}
```

## 所感
当初のソースコードが間違っていただけだった。
いろんな記事を漁っているうちにおかしなソースコード書いているだけだった。
entで実行されたSQLを確認する

## はじめに
[株式会社 RetailAI X Advent Calendar 2022](https://qiita.com/advent-calendar/2022/retail-ai-x) 6日目の記事です。

最近、Go言語のORMである[ent](https://entgo.io/ja/)を触っています
自分が書いたプログラムがイメージ通りのSQLを発行できているのか確認したい時があったので、やり方を調べてみました

## データ取得処理
### 通常時
```
client.User.Query().All(ctx)
```
clientの中身は[こんな感じ](https://entgo.io/docs/crud#create-a-new-client)に作ります

### SQLを確認したいとき
```
client.Debug().User.Query().All(ctx)
```
clientに対して`Debug()`を実行すると、新しいデバッグクライアントが返却され特定の操作に対して詳細なログを取得することができます

```
2022/12/03 01:34:58 driver.Query: query=SELECT DISTINCT "users"."id", "users"."name", "users"."email", "users"."password", "users"."created_at", "users"."updated_at" FROM "users" args=[]
```
上記のプログラムを実行すると、SQLがログに出力されて、実行時のパラメータがある場合はargsに中身が表示されます

## 参考
https://entgo.io/ja/docs/migrate/#%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%AE%E5%89%8A%E9%99%A4
https://pkg.go.dev/entgo.io/ent/examples/o2mrecur/ent#Client.Debug

## 最後に
明日７日目の記事は、[@tanabe_shogo](https://qiita.com/tanabe_shogo)さんの[Node.jsを使って、BigQueryからデータを取得するWebAPIを作る](https://qiita.com/tanabe_shogo/items/332cfc492440d57013bf)です！
お楽しみください！
JSONataの$moment関数で日付を取得する

この記事は [Node-RED Advent Calendar 2022](https://qiita.com/advent-calendar/2022/node-red) の 5 日目の記事です。

# はじめに

Node-REDで日付を扱う方法は色々あると思いますが、JSONataで日付を取得したりするのが簡単だなと感じています。これまでは`$fromMillis()`などの関数を使うことが多かったのですが、今回ご紹介する方法は、JSONataの$monent()という関数を使う方法です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266424/5c71527f-1f81-f0d6-b671-5e9df7c21d33.png)

# JSONata式の書き方
## 月初と月末の日時を取得する

サンプルをご紹介します。
例えば、Injectをクリックした当月の初日と月末日を取得したいとします。

```text:取得したい日付の例
2022-12-01T00:00:00
2022-12-31T23:59:59
```

この場合のJSONata式は`$moment().startOf('month')`や`$moment().endOf('month')`を使います。`.format（)`を使うと好きな日付のフォーマットに変更できます。

```json:JSONata式
$moment(payload)
.startOf('month')
.format("YYYY-MM-DDT00:00:00")

$moment(payload)
.endOf('month')
.format("YYYY-MM-DDT23:59:59")
```

## 先月の日付

`.add()`を使えば日付の加算や減算も簡単です。例えば先月の日付が欲しいときは以下の様にします。

```json:JSONata式
$moment().add(1, 'months')
```

来年1月の日付が返ってきました。

```text:結果
Tue Jan 03 2023 11:30:10 GMT+0900
```


## 昨年の日付

昨年の日付が欲しければ、`'years'`とするだけです。

```json:JSONata式
$moment().add(-1, 'years')
```

```text:結果
Fri Dec 03 2021 11:31:33 GMT+0900
```

## この他の書き方

主な使い方は上記の通りですが、全部の書き方を調べ切れていません。
moment.jsのサイトを参考にしながら、いじってみると面白いと思います。

https://momentjs.com/

# まとめ

今日は、Node-REDで日付を取得する時にJSONataの$moment関数を使う方法をご紹介しました。

Node-REDの日付の取扱方法については、過去にもいろいろな記事がありました。

https://qiita.com/tseigo/items/e7deb8d6d4902a4aef30

https://uepon.hatenadiary.com/entry/2022/02/17/011209

昨年のアドベントカレンダーでもこんな記事もありました。

https://www.1ft-seabass.jp/memo/2021/12/25/node-red-jsonata-firstday-lastday-span/

いずれの記事でもJSONataについては

`$fromMillis()`

`$toMillis()`

を使っています。

今回は、Node-REDにおける日付問題についての焼き直しの内容になりますが、今回見つけた$moment()による方法を使ってみるとより簡単で書きやすくなるのではと思いましたので、ご紹介致しました。

今回のNode-REDのフローはenebularのDiscoverで公開しております。

- [サンプルフロー](https://enebular.com/discover/flow/bae223df-9b16-4e13-b4d1-c16e34c5d26b)

ご参考になれば幸いです。
Amazon FSx for NetApp ONTAP は ONTAP の GUI が無いので、代替手段を探してみる

# はじめに
Amazon FSx for NetApp ONTAP (以下 FSxN) は、NetApp のストレージ OS 「ONTAP」で動作しています。
オリジナルの ONTAP には「System Manager」というブラウザ向け GUI が実装されていますが、FSxN では利用することができません。[^1] 
GUI で慣れ親しんだ人からするとちょっと困るなーという事になりそうですよね。
ということで、代替の手段を用いて GUI 主体でオペレーションするための方法を整理してみました。
[^1]: 2022/12/06 現在、ONTAP 9.11.0 P3 での状況です。今後のアップデートで変更される可能性があります。

ちなみに、オリジナルの ONTAP の設定・操作方法には、以下の3つの方法があります。
* System Manager (ブラウザ用 GUI)
* ONTAP CLI
* ONTAP REST API

FSxN では、このうち CLI と REST API を利用することが可能です。

# FSxN を GUI 操作する手段
主な手段としては、以下の3つの方法が存在します。

## AWS Management Console
AWS が提供する標準の GUI で、ブラウザからアクセスします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2815139/901e794a-cbb9-9db7-1ca0-5b9b3dade183.png)

FSx ファミリーで共通の GUI となっており、初期デプロイや新規ボリュームの作成といった構築の際や、バックアップ等のデータ保護、パフォーマンス監視等に利用できます。


## Microsoft 管理コンソール (MMC)
Windows OS に搭載されているコンソールアプリケーションです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2815139/d3b835ee-23e7-5117-73e1-cf7db037d987.png)

ONTAP の操作に関しては、スナップインと呼ばれるモジュールを用いてCIFS/SMB 共有の設定に利用することができます。
同じ Active Directory 配下の Windows PC (無論 AD サーバー自身でも OK) から実行します。

前述の AWS Management Console では CIFS/SMB共有の設定ができないため、MMC を併用した手順が [FSxN 公式ドキュメント](https://docs.aws.amazon.com/ja_jp/fsx/latest/ONTAPGuide/create-smb-shares.html) にも記載されています。


## NetApp Blue XP
[Blue XP](https://www.netapp.com/ja/bluexp/) はNetAppが提供するクラウド管理プラットフォームです。
（旧来 Cloud Manager と呼ばれていたものの、強化発展版です）
利用にあたってはユーザーアカウントの登録が必要になりますが、BlueXP そのものは無償利用が可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2815139/4edc7d9d-fc86-e345-705a-dda16383294b.png)

BlueXP は ONTAP を始めとするストレージやデータサービスを統合管理する機能があります。
FSxN にも対応しており、ボリュームの作成や CIFS/SMB 共有の作成、バックアップやリストアといった一通りの運用ができるようになっています。

# できること比較
GUI の需要がありそうな CIFS/SMB 利用に関連した操作項目に関して、できる・できないの比較をしてみました。
厳密には、MMC Console は CIFS/SMB 共有にほぼ限られていますので、用途に応じて複数の方法を使い分ける事になります。

|  | AWS Console | MMC Console | BlueXP |
|:-:|:-:|:-:|:-:|
| SVM 作成  | ○ | - | - |
| Volume 作成 | ○ | - | ○ |
| Qtree 作成 | - | - | - |
| AD 参加 | △<br>SVM 作成時のみ | - | ○ |
| CIFS 共有作成 | - | ○ | △<br>Volume 作成時のみ |
| Workgroup 設定 | - | - | - |
| Quota 設定 | - | - | - |
| Snapshot 設定 | Volume 作成時に<br>既存 Policy から選択 | - | Volume 作成時に<br>既存 Policy から選択  |
| Snapshot 手動作成 | ○ | - | ○ |
| Snapshot からのリストア | バックアップセットから<br>ボリュームを生成 | エクスプローラーを開き<br>「以前のバージョン」から参照 | バックアップセットから<br>ボリュームを生成 |
| ボリュームレプリケーション | - | - | ○ |
| 性能監視 | ○ | - | △[^4] |
| 容量監視 | ○ | - | △[^5] |

上記表で - となっている箇所は、オリジナルの ONTAP の GUI 及び CLI/API では実施可能な項目です。

[^4]: 有償の「[Cloud Insights](https://www.netapp.com/ja/cloud-services/cloud-insights/)」の契約が必要 
[^5]: 現在の使用量の確認のみ。詳細な容量推移等については有償の「[Cloud Insights](https://www.netapp.com/ja/cloud-services/cloud-insights/)」契約が必要


# まとめ
* ONTAP GUI (System Manager) は FSxN では（まだ）使えないので、
・AWS Console + Windows MMC の組み合わせ
・BlueXP
で代替
* シンプルな運用であれば、ある程度は代替手段で可能
* CLI/REST API を併用できるのであれば、オンプレの ONTAP とほぼ同等の事は可能
Rubyで配列文字列をパースしたかった話

## 概要
`"[{'a': 1}]"`みたいな配列の中にjsonが入っている文字列をパースしたかっただけのお話。

## きっかけ
日頃よくスクレイピングをしているんですけど、そのときに上記のような配列にデータが入っている事がありまして、パースするのに少し苦戦したので今後同じ悲しみを産まないために...


## だめだったやり方
僕はRubyの標準ライブラリを信じています。
だから今回もきっと`require 'json'`くんがすべてを解決できると信じていた、そうあの日までは。。。

ぼく「よし、配列の文字列でデータ引っ張って来れたしこれを`JSON.parse`してっと...」
システム「`unexpected token at ''a':1]' (JSON::ParserError)`」
ぼく「Why？？？」

僕の信じていた`JSON.parse`は配列の中にjsonが入っているようなパターンは解析してくれませんでした。
まぁ、当たり前といえば当たり前なのかもですけど....

## できたやり方
いろいろ文献を漁ってみて
「Ruby 配列文字列 パース」とかで調べてもRubyの配列をjoinして文字列にする話とか、その逆とか....そうじゃないんだよなぁって記事がいくつかあった中「`yml`でパースすれば行けるよ」という記事を見かけた。
ぼく「yml？？まさかぁ。とりあえず試してみるかぁ」
```rb
require 'yaml'
str = "[{'a': 1}]"
p YAML.load(str)[0]['a']
```
出力
```
1
```

ちゃんとパースされとる！！！すごい！！！

意外と当たり前にできそうだったけどコツが必要でしたという話
NeovimのDiagnosticsに文字列でフィルタをかける

# やること
Neovimを使っていると、LSPが下記のようなDiagnostics（`"randint" is ...`）を吐く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325849/74ccc133-e7dd-bd7d-b397-2699d98c47cd.png)
このDiagnostics機能そのものを無効にするのではなく、「Warning以下非表示」等の制限をかけるのでもなく、特定の文字列を含むものだけを非表示にする。

# やりかた
- `neovim/runtime/lua/vim/diagnostic.lua`の785行目あたりに、下記を追加する。そしてNeovimを再起動。
```neovim/runtime/lua/vim/diagnostic.lua
  for i = 1, #line_diags - 1 do
    table.insert(virt_texts, { prefix, virtual_text_highlight_map[line_diags[i].severity] })
  end
  local last = line_diags[#line_diags]

  -- ここから追加
  if string.find(last.message, "unbound") or string.find(last.message, "is not accessed") then
    return nil
  end
  -- ここまで

  -- TODO(tjdevries): Allow different servers to be shown first somehow?
  -- TODO(tjdevries): Display server name associated with these?
  if last.message then
    table.insert(virt_texts, {
      string.format('%s %s', prefix, last.message:gsub('\r', ''):gsub('\n', '  ')),
      virtual_text_highlight_map[last.severity],
    })
```
- もちろん`string.find(last.message, "xxx")`の`xxx`を好きに変えて、`or`でつないであげれば、複数の文字列にフィルタをかけられる。
- MacでNeovimを利用している人なら、Neovimを入れた場所を探して、`Neovim/share/nvim/runtime/lua/vim/diagnostic.lua`を編集するということ。
- `Neovim/share/nvim/runtime/lua/vim/lsp/diagnostic.lua`ではないので注意。
    - `diagnostic.lua`の前に`/lsp/`はいらない。

# おまけ
- 上述コードの少し上にある`local prefix = opts.prefix or '■'`を書き換えれば、インラインDiagnosticの先頭部分を変えられる。
```neovim/runtime/lua/vim/diagnostic.lua
  local prefix = opts.prefix or '👀'
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325849/2c6da25d-2473-de8f-34a8-59046a67c02d.png)

# ノート
- 2022/12/03現在、日本語・英語問わずでDiagnosticsに文字列でフィルタをかける方法が、ネット上に見つけられない。
- 私はNeovimのコードを読み込んだわけでも、普段からluaを使っているわけでもないので、ご利用は自己責任でお願いします。

# 追記
下記の書き方の方がスマート。
```neovim/runtime/lua/vim/diagnostic.lua
  if last.message:find("unbound") or 
     last.message:find("is not accessed") or
     last.message:find("Cannot access member") or
     last.message:find("Argument of type") then
    return nil
  end
```
fishでコマンドラインエディタを起動する

## 導入

Qiitaの記事でZennの運営やってるこの社名出すのあれですが、普段からクラメソさんの記事には大変お世話になっています。

お世話になっているので、会社のslackにはDeveloppersIOのRSSが登録されているチャンネルがあります。
そのチャンネルに、今日 (記事執筆時点) こんな記事が流れてきました。

https://dev.classmethod.jp/articles/eetann-zle-edit-command-line/

タイトルからしてもう便利ですね。
普段neovimは使ってないんですが、コマンドをvimで編集できたら便利やろなーと思うことは常々ありました。

ただ、基本的にfish使ってるのでこの記事をそのまま試すことはできません。
というわけで調べてみることにしました。

## 結論

fishのデフォルト機能に存在しているのでできます。
![try_fish_command_line_editor.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532032/90105478-f307-4be5-4228-71b81dec601e.gif)

やり方は、環境変数 `$VISUAL` または `$EDITOR` にエディタを設定するだけです。(例: vimの場合は `set -x $EDITOR vim`)
使用したいエディタを登録しておけば、`Alt+v`あるいは`Alt+e`で起動できます。

## ドキュメントを見に行く

この項目、ドキュメントにしれっと一文で書いてあるだけなので今まで一度読んだページだったはずなのに見落としてました。
fish的には、わざわざエディタを開かなくてもコマンドライン上でそのまま各エディタのショートカットが使えるんでいらないでしょうという立ち位置なのかもしれません。

https://fishshell.com/docs/current/interactive.html#command-line-editor

やっぱりまず公式ドキュメントを読むのは大事ですね。

## デフォルトのキーバインドを変更する

このエディタを開く機能便利なんですが、Macだと特殊記号が出るので使えないです。
そのため、任意のキーバインドに変更してあげる必要があります。
(コマンドラインエディタを起動する関数名は、ドキュメントのcommand_line_editorの項目ではなく別ページのbindの項目に記載されています)

以下の手順で変更できるので、Macの人は試してみてください。

```bash
$ fish_key_reader #入力内容を調べる
Press a key:
bind \ee 'do something' #Alt + Eの場合
$ bind \ee 'edit_command_buffer'
```

これにて変更完了です。
Laravel 9 名前付きルートの階層指定方法

こんにちは　初心者フリーランスです
今回が初投稿ですが、Laravelの勉強中に躓いたことなどをメモしていこうと思います
もし誤りがあったり理解不足などがあればコメントいただけると嬉しいです！！

<h3>今回躓いたことと解消方法</h3>

`web.php`で名前付きルーティングの階層指定方法が間違ってた(しょうもないミス)
名前付きルートの区切り文字を`/ (スラッシュ)`で記述していたため、リダイレクトで`not defined.` エラーになった

```php:誤
Route::get('/contact/complete', [ContactController::class, 'complete'])->name('contact/complete');
```

```php:正
Route::get('/contact/complete', [ContactController::class, 'complete'])->name('contact.complete');
```

※ちゃんとURLとviewの名前付きルート指定を理解しましょう

<h1>ルーティング</h1>
LaravelではWeb.phpにルート設定すると指定したURLを叩くと何を呼び出すかを決められる
<br>
<h3>基本的な記述例</h3>
<h4>GET メソッド</h4>

```PHP:web.php
Route::get('/contact', [ContactController::class, 'index'])
```
URL：http\://〇〇/contact
処理：ContactControllerのindexメソッド

<h4>名前付きルート</h4>

名前付きルートを指定する際は`Route::get`に`name`メソッドをつなげることで命名できる
これを使えばパスの記述時に名前で指定できるので記述が楽になる
別名をつけるみたいなイメージかな

```PHP:web.php
// お問合せページの設定
Route::get('/contact', [ContactController::class, 'index'])->name('contact');
// お問合せ完了ページの設定
Route::get('/contact/complete', [ContactController::class, 'complete'])->name('contact.complete');
```

グローバルなroute関数やto_routeでの記述が楽になる
```php:sample.php
// URLの生成
$url = route('contact');
// リダイレクト
return to_route('contact.complete');
```


<h4>POST メソッド</h4>

POSTメソッドではフォーム情報送信などのサーバとの通信で利用する
入力情報をDBに保存したりする際に用いる

以下のサンプルではお問合せページから送信ボタンを押下時した際に
バリデーションチェック、ログの書き込み、完了ページへのリダイレクトの流れで処理が動く

```PHP:web.php
// お問合せページ
Route::get('/contact', [ContactController::class, 'index'])->name('contact');
// お問合せ情報送信処理
Route::post('/contact', [ContactController::class, 'sendMail']);
// お問合せ完了ページ
Route::get('/contact/complete', [ContactController::class, 'complete'])->name('contact.complete');
```

```php:ContactController.php
function sendMail(Request $request) {
        // バリデーションチェック
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'name_kana' => ['required', 'string', 'max:255', 'regex:/^[ァ-ロワンヴー]*$/u'],
            'phone' => ['nullable', 'regex:/^0(\d-?\d{4}|\d{2}-?\d{3}|\d{3}-?\d{2}|\d{4}-?\d|\d0-?\d{4})-?\d{4}$/'],
            'email' => ['required', 'email'],
            'body' => ['required', 'string', 'max:2000'],
        ]);

        // これ以降の行は入力エラーがなかった場合のみ実行
        // ログに書き込んだあと完了ページにリダイレクト
        Log::debug($validated['name']. 'さんよりお問い合わせがありました');
        return to_route('contact.complete');
    }
```

<h1>まとめ</h1>
しっかり基礎を理解した上で記述しないとエラーになる
<br>
今回はURLとルート指定の理解が足りてなくて呼び出しに失敗した
<br>
今まで生のPHPしか触ったことがなくてフレームワークを初めて触ったので
<br>
MVCモデルやルーティングなどを正しく理解した上で利用していきたい
一年目エンジニアが仕事の生産性向上のために取り組んでいること

## 概要
社会人一年目からリモート主体での勤務をする中、なかなか集中力が持続せず「生産性高く仕事に取り組めてないな・・」と感じることが何度かありました。
そこで仕事の生産性を向上させるために行なった施策を共有いたします。

## 1. 一日の具体的なスケジュールを作成する
まず一日の始めに具体的なスケジュールをざっくりと決めてしまいます。
私はGoogleカレンダーを使って、以下のようにスケジュールを作成しています。
![スクリーンショット 2022-12-03 9.56.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689205/fda68cc8-56e3-1522-fbea-ba67157fff03.png)

具体的な時間込みでスケジュールを設定することによって、**「〇〇時から△△時までの間にこのタスクを終わらせる！」** という意識が働き、ダラダラとすることが減り、生産性の向上につながりました。

## 2. 重めのタスクを午前中に片付ける
1日8時間も仕事するとなると、「長いからゆっくりやろう〜」と考えてしまい、その結果進捗があまり生み出せてないことがありました。
重めのタスクを午前中に終わらせるつもりで仕事に取り組めば、「午後からは楽できるぞ」とモチベーションになり、効率よく仕事に取り組むことができました。


## 3. 座りっぱなしをやめる

エンジニアの仕事はデスクワークなので常に座りっぱなしですが、集中力が切れそうな時は **「昇降デスクで立ちながら仕事する」「休憩中に散歩する」** といったことを心がけています。

ずっと座りっぱなしだと健康にも良くないですし、立つことによって気分が切り替わり、集中力の持続に繋がります。

特に昼食後は眠くなりがちなので、午後から立って仕事したり、昼食後に軽く散歩をするようにしています。

https://www.yomeishu.co.jp/health/3800/

## 4. 水分をしっかりとる

「水分補給」みなさんはできていますか？

座り仕事でも水分は失われますし、水分が足りないと**集中力の低下**につながります。

そこで私は水やお茶を意識的に摂るようにしております。

コーヒーを飲むのも良いですが、体質によってはカフェインで体調が悪くなったり、逆に集中力低下につながる可能性もあるので注意です。

ノンカフェインのお茶や水でも、口に含むだけで眠気が取れ集中力が高まるので、水分摂取はおすすめです。

https://tenjijo.saitama.jp/topics/33#:~:text=%E3%81%BE%E3%81%A8%E3%82%81-,%E6%B0%B4%E5%88%86%E4%B8%8D%E8%B6%B3%E3%81%AF%E9%9B%86%E4%B8%AD%E5%8A%9B%E3%82%84%E4%BD%9C%E6%A5%AD%E5%8A%B9%E7%8E%87%E3%81%AB%E5%BD%B1%E9%9F%BF,%E3%81%93%E3%81%A8%E3%81%8C%E8%80%83%E3%81%88%E3%82%89%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82

https://www.sanikleen.co.jp/waterserver/column/2437.html


## 5. 適度な雑談

自分の会社はコミュニケーションツールにSlackを使っており、timesという雑談用のチャンネルがあります。
そこで技術的な話や都内の気になってるレストランの話題などをすることによって、**新たな発見**や**気分転換**に繋がっています。

注意点としては、雑談をしすぎて作業が遅れないようにすることです。
「15時くらいに〇〇さんと軽く喋ろうかな〜」といった感じで、**時間を決めて**行うと良いかもしれません。
SpriteKitで2D横スクロールゲームをつくろう（その３）

![Xcode-14.1](https://img.shields.io/badge/Xcode-14.1-brightgreen) ![iOS-16.0](https://img.shields.io/badge/iOS-16.0-brightgreen) 

## はじめに
[前回](https://qiita.com/am10/items/d53d1cdf1b973a9f56cc)の続きです。

今回はついに横スクロールさせます。

## 実装
横スクロールを実現するためにはいくつか方法があるかと思いますが今回はカメラをプレイヤーに追従させて横スクロールします！

こんな感じの構成（背景は固定にしてます）。

<img width="300" alt="camera" src="https://user-images.githubusercontent.com/34936885/205416198-f1622eab-5cf4-4b86-9fd6-473ab9f0a0a2.jpeg">

シーン上にカメラ、床、プレイヤーをのせ、カメラの上に背景をのせてプレイヤーの位置に合わせてカメラを移動させることで横スクロールさせます。

### カメラ表示
固定するものは `SKCameraNode` 上にのせます。

```swift
final class GameScene: SKScene {

    private let cameraNode = SKCameraNode()

    override func didMove(to view: SKView) {
        camera = cameraNode
        cameraNode.position = .init(x: frame.midX, y: frame.midY)
        addChild(cameraNode)

        let backNode = SKSpriteNode(imageNamed: "background")
        backNode.size = frame.size
        cameraNode.addChild(backNode)
    }

    override func update(_ currentTime: TimeInterval) {
        // カメラのx座標だけ移動
        cameraNode.position = .init(x: player.position.x, y: frame.midY)
    }
}
```

注意点としてカメラの初期化は下記のようにしてはダメです。

```swift
camera = SKCameraNode()
```

`SKScene.camera` の定義が下記のように weak なので保持できません。

```swift
weak open var camera: SKCameraNode?
```

### ボタン表示
ボタンは常に表示するためカメラに置きます。そのまま置くと床の背面に表示されるので下記のように `zPosition` を設定してやる必要があります。

```swift
override func didMove(to view: SKView) {
    let up = UIImage(systemName: "arrow.up")!
    let upNode = SKSpriteNode(texture: .init(image: up), size: .init(width: 40, height: 40))
    upNode.color = .white
    upNode.name = "up"
    upNode.position = .init(x: -(frame.width/2) + 40, y: -(frame.height/2) + 40)
    upNode.zPosition = 10 // これで床より前に持ってくる
    cameraNode.addChild(upNode)

    let right = UIImage(systemName: "arrow.right")!
    let rightNode = SKSpriteNode(texture: .init(image: right), size: .init(width: 40, height: 40))
    rightNode.name = "right"
    rightNode.zPosition = 10 // これで床より前に持ってくる
    rightNode.position = .init(x: -(frame.width/2) + 120, y: -(frame.height/2) + 40)
    cameraNode.addChild(rightNode)
}
```

## おわりに
前回のと合わせるとこんな感じになります。

![game](https://user-images.githubusercontent.com/34936885/205416891-798e5893-20f5-4660-890a-17dbd69bb2de.gif)

このままではただ動くだけなので次回は敵キャラを表示します！（次回はもっとボリュームのある記事になるはず:kissing_heart:）

SpriteKit あまりさわったことないのでもっといい方法あればぜひ教えて下さい:bow:

## まとめ
* [その１](https://qiita.com/am10/items/df42c1f0091e6c4705e2)
* [その２](https://qiita.com/am10/items/d53d1cdf1b973a9f56cc)
* [その３](https://qiita.com/am10/items/8729f77f3ee512a86052)
* [その４](https://qiita.com/am10/items/90e3a2f58ae88e4ad6c4)
* [その５](https://qiita.com/am10/items/deacceda00c034ac29bb)
日本の国土交通省「自動車のリコール・不具合情報」からデータをJSON形式でダウンロードする （CSVも可）


# 何ができるのか

日本の国土交通省「自動車のリコール・不具合情報」から自動車の故障・不具合の情報データをJSON形式でダウンロードすることが出来ます．

http://carinf.mlit.go.jp/jidosha/carinf/opn/index.html

# どんな出力か

以下のような「改行区切りのJSONファイル」で出力されます

```
{"番号":"1","受付日":"2022年10月31日","住所":"福島","申告方法":"ﾌﾘｰﾀﾞｲｱﾙ","車名":"ニッサン","通称名":"エクストレイル","初度登録年月":"不明","総走行距離":"不明","型式":"NT32","原動機型式":"不明","不具合装置":"制動装置","発生時期":"不明","申告内容の要約":"信号待ちからの発進時、前車がある程度離れていたはずにも関わらず、自動ブレーキが作動した。","keywords":[]}
{"番号":"2","受付日":"2022年10月31日","住所":"岩手","申告方法":"ＨＰ","車名":"フォルクスワーゲン","通称名":"ＶＷゴルフ　１．２／７７ｋＷ","初度登録年月":"2015年03月","総走行距離":"57,000 Km","型式":"DBA-AUCJZ","原動機型式":"CJZ","不具合装置":"走行装置","発生時期":"２０２２年１０月１５日頃","申告内容の要約":"左フロントハブベアリングより異音が発生した。","keywords":[]}
{"番号":"3","受付日":"2022年10月31日","住所":"東京","申告方法":"ﾌﾘｰﾀﾞｲｱﾙ","車名":"スバル","通称名":"レヴォーグ","初度登録年月":"2018年11月","総走行距離":"38,300 Km","型式":"DBA-VM4","原動機型式":"FB16","不具合装置":"制動装置","発生時
```

出力ファイル名を「*.csv」で指定した場合，以下のようなCSV形式で出力されます．
```
番号,受付日,住所,申告方法,車名,通称名,初度登録年月,総走行距離,型式,原動機型式,不具合装置,発生時期,申告内容の要約
1,2022年10月31日,福島,ﾌﾘｰﾀﾞｲｱﾙ,ニッサン,エクストレイル,不明,不明,NT32,不明,制動装置,不明,信号待ちからの発進時、前車がある程度離れていたはずにも関わらず、自動ブレーキが作動した。
2,2022年10月31日,岩手,ＨＰ,フォルクスワーゲン,ＶＷゴルフ　１．２／７７ｋＷ,2015年03月,"57,000 Km",DBA-AUCJZ,CJZ,走行装置,２０２２年１０月１５日頃,左フロントハブベアリングより異音が発生した。
3,2022年10月31日,東京,ﾌﾘｰﾀﾞｲｱﾙ,スバル,レヴォーグ,2018年11月,"38,300 Km",DBA-VM4,FB16,制動装置,不明,前輪ブレーキパッドシムの腐蝕により、ブレーキパッドの異常摩耗が発生した。
```

# 何に使えるのか

自動車の故障・不具合情報についてテキストマイニングをすることができます．

# どうやって使うのか

お手軽に JAR ファイルをダウンロードして使う場合は以下の通りです．

以下から「nlp4j-webcrawler-mlit-downloader-fat.jar」をダウンロードします．

https://github.com/oyahiroki/nlp4j/tree/master/nlp4j/nlp4j-webcrawler/dist

JARファイルを適当なディレクトリに配置し，以下コマンドを実行します．

第１パラメータは開始日
第２パラメータは終了日
第３パラメータは出力ファイル名
です．

※追記※ 第３パラメータのファイル名が .csv で終わる場合，出力ファイル形式がCSVになるように変更しました．

>java -jar nlp4j-webcrawler-mlit-downloader-fat.jar 2022/10/01 2022/10/31 ./out.txt


ソースコードを見てみたいという方は以下からご参照ください．

https://github.com/oyahiroki/nlp4j/blob/master/nlp4j/nlp4j-webcrawler/src/main/java/nlp4j/webcrawler/mlit/P101MlitCarInfoDownloadMain.java



以上．

---

#プロジェクトURL
https://nlp4j.org/

<img width="64" alt="NLP4J_N_128.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110265/4f59b21b-4b43-187d-0aac-7b99c0fd4bac.png">

---
[NLP4J Index](https://qiita.com/oyahiroki/items/ba79a759c599d3459d29)
CloudFormation NoEchoとは

# NoEchoとは
NoEcho プロパティは、テンプレートで使用され、パラメーターの値が AWS Management Console に表示されるかどうかを指定します。 
NoEcho が true に設定されている場合、パラメーターの値はコンソールに表示されません。これは、パスワードなどの機密情報を表示したくない場合に便利です。

次に、CloudFormation テンプレートで NoEcho を使用する例

```
Parameters:
  MyPassword:
    Type: String
    NoEcho: true
```

この例では、MyPassword パラメーターは、AWS Management Console に表示されない文字列です。
爆速でFast APIチュートリアル触ってみた。公式ドキュメント読むの嫌いな人向け。

# 経緯
これまではフロントをメインに業務を行なっていたが、業務の都合上バックエンドも挑戦して欲しいと提案してもらえた。
ただ何も知らなすぎるためひとまず公式チュートリアルを翻訳しながらSwaggerとredocの表示まで進めてみた。


# 前提条件
```python, pip, uvicorn, fastAPI```がインストールされていること

チュートリアルには特に書いておらず、全てのインストール方法を調べるのが面倒だった。

## python
```bash
brew install python3
```
非常に高速なASGIサーバーのこと。
Fast API利用に必要。
https://www.uvicorn.org/

## uvicorn
```
pip3 install uvicorn 
```


## fast api
```
pip3 install fastapi
```

# 公式チュートリアル

## ファイル作成
一番シンプルなFast apiのファイルを作ってみましょう。
```main.py
# starlette(https://www.starlette.io/)から継承したFastAPIクラス
from fastapi import FastAPI

# 全てのAPI作成の基
# サーバーの起動コマンドにも利用
app = FastAPI()


# パスは"/", getリクエスト処理
@app.get("/")
# 通常のpythonの関数定義
async def root():
    # "/"にgetリクエストを行った時のレスポンス内容
    return {"message": "Hello World"}
```
※ ファイル名はmain.pyとすること(実行時にこのファイル名を指定するため)


## コマンド実行
それでは実行してみましょう
```bash
uvicorn main:app --reload

INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [28720]
INFO:     Started server process [28722]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

```
※ 上記コマンドの意味
```
main: コードを記述したファイル名
app: main.pyで作成されたFastAPIのオブジェクト "app = FastAPI()" 
--reload: コードに変更があると、その変更を検知し、サーバーをリスタートする(ホットリロード)
```

## 結果確認
### JSONレスポンス確認
上記のコマンドを打つと、下記のようなものがあるでしょう
```bash
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
このURLをcmd+clickするか、ブラウザに打ち込んでみましょう。

```
{"message": "Hello World"}
```
というJSONのレスポンスが表示されたかと思います。

### Swagger確認
```http://127.0.0.1:8000/docs```とすると、下記のように[Swagger UI](https://github.com/swagger-api/swagger-ui)によるAPIのドキュメントが自動で生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487834/e9b56778-a5f7-e4dd-7d40-37545271998b.png)

### redoc確認
```
http://127.0.0.1:8000/redoc
```
とすると、

下記のように[redoc](https://github.com/Redocly/redoc)によるAPIのドキュメントが自動で生成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487834/25204b5e-8960-498f-f0a2-b78bc162df7c.png)


# 参考
https://fastapi.tiangolo.com/tutorial/first-steps/
【Kotlin/JVM】17歳とMヶ月とD日

「17歳とMヶ月とD日」の計算

```Kotlin
import java.time.LocalDate
import java.time.temporal.ChronoUnit

fun main() {
    val birthDate = LocalDate.parse("1964-09-25")
    val currentDate = LocalDate.now()

    var date = birthDate
    val years = 17L

    date = date.plusYears(years)
    val months = ChronoUnit.MONTHS.between(date, currentDate)

    date = date.plusMonths(months)
    val days = ChronoUnit.DAYS.between(date, currentDate)

    println("${years}歳と${months}ヶ月と${days}日")
}
```

　→[Kotlin Playground](https://pl.kotl.in/3qpr8IPiI)


／以上
目標に悩んでいるエンジニアへ：楽しんで仕事をする事

![25108406_s.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/6f3571f9-bf45-d7c3-b02e-ca6ee2fea2db.jpeg)

昔、インフラの担当者がラックの写真を見せてくれた事があった。
そこには、綺麗に色分けされたLANケーブルがささったラック内のSW(スイッチ）が写ってました。
新設ラックを構築するにあたって、高アベイラビリティ、低コスト、高パフォーマンスのインフラ構築を彼女に担当してもらいました。
本来、経営レベルからのコスト削減を目指して始めたプロジェクトなのですが、どうせならという事で、LVSや、VRRP、ボンディング,etc等のオープン技術を駆使した物も一緒にやりたいという事で、スケジュール的にも非常にタイトなプロジェクトでした。ハードなプロジェクトを見事に対応してくれたのですが、苦労しただけあって、自分で設置したハードの写真を見て、「自分の子供の様にかわいい」と（笑
さぞ、大変で難しくもあったと思います。だからこそ、達成感も並大抵の物ではなかったと思います。

# 仕事には、自分が好きな仕事と自分が出来る仕事がある
自分のやりたい事が見つからないと言って悩んでいる人がいます。時に相談されたりします。
仕事というのは、
- 自分が好きな仕事
- 自分が出来る仕事

があります。最も良いのは、自分が好きな仕事がよいと思います。僕も小学生の頃にプログラマーになりたくて、そのまま今に至ります。イチロー選手も野球大好き少年からプロ野球選手になりました。
引退会見で、**好きな事を見つけて欲しい**と言ってますが、好きな仕事が出来るのは、一部の人達に限られる場合が多いです。
次にあるのが、自分が出来る仕事、向いてる仕事です。人と話すのが向いてる人は、営業だったり、コンサルだったり、話す仕事は色々とあります。

# アウトプットとプロセス
- 自分が好きな仕事 = アウトプット
- 自分が出来る仕事 = プロセス

なんですよね。アウトプットを目指して、エンジニアになった僕ですが、実は物作りや何かをソリューションするというプロセスも好きです。これは、エンジニアでなくても叶ったかもしれません。
好きな仕事（アウトプット）を見つけれない場合は、出来る仕事（プロセス）中心に仕事を考えてみるのも良いと思います。

# 本来、仕事は楽しい事
子供の頃、初めてプラモデルを作って、その体験をベースに将来、車とかロボットを作りたいと夢を描いたり。
親の手を借りながら作った料理を家族に美味しいと言われ、将来、コックになろうと思ったり。
ＴＶでワールドカップを見て、サッカー選手に憧れたり。

本来、仕事というのは、
- 楽しかったり。
- 好きだったり。
- 感動したり。
- 夢中になれたり。

だからこそ、大変だけど、頑張れるはず。楽しいからこそ、もっと、難しい事や大変な事にチャレンジしたくなれるはず。

- 初めて自分の作ったプログラムがリリースされた時の感動。
- 初めて自分の企画が採用された時の感動。
- 初めて自分で営業して、クライアントから「御社に頼みます」と言われた時の感動。

アウトプットもプロセスの話しもありますが、最後は、楽しんで仕事が出来るかがポイントです。仕事に夢中になれたなら無意識に成長する事ができると思います。
【GMC-4】XOR演算

学研の4ビットマイコンGMC-4でXOR演算をやってみた。

# XOR演算とは

ビットにおけるXOR演算とは、eXclusive OR演算のことで、2個の0/1の入力のうちちょうど1個が1の場合1、そうでない場合0となる演算である。

|入力1|入力2|出力|
|:-:|:-:|:-:|
|0|0|0|
|1|0|1|
|0|1|1|
|1|1|0|

整数におけるXOR演算とは、2個の整数を2進数で表し、対応するビットごとにビットにおけるXOR演算を行った結果の整数を得る演算である。
例えば、`10 xor 3 = 9`となる。

```
    10   0xA   0b1010
xor  3   0x7   0b0011
---------------------
  =  9   0x9   0b1001
```

# GMC-4における演算

GMC-4では、以下の演算命令がある。

* レジスタの値に定数を加算し、レジスタに格納する (キャリーの有無を判定できる)
* レジスタの値にデータメモリの値を加算し、レジスタに格納する (キャリーの有無を判定できる)
* データメモリの値からレジスタの値を減算し、レジスタに格納する (ボローの有無を判定できる)
* レジスタの値を1ビット論理右シフトし、レジスタに格納する (もとの値の最下位ビットを得られる)

論理演算は用意されていない。
ここで、ビットにおけるXOR演算の入力と出力の対応をよく見ると、出力は2個の入力を加算して2で割った余り、もしくは和の最下位ビットとみなすことができる。
したがって、入力の2個の整数を加算し、右シフトにより最下位ビットを抽出することで、入力の整数のXORの最下位ビットが得られる。
入力をそれぞれ1ビット右シフトし、同様に加算して最下位ビットを抽出することで、入力の整数のXORの最下位から2番目のビットが得られる。
これを繰り返すことで、入力の整数のXORを求めることにした。
今求めているビットを表す値を用意し、この値がオーバーフローしてゼロになったら終了する仕掛けにした。

# 実装

* データメモリの0番地と1番地に、入力の整数(2個それぞれ)
* データメモリの2番地に、今求めているビットを表す値
* Bレジスタに、計算結果

を置いて計算するようにした。
さらに、2個の値をキーから読み込む処理と、計算が終了したら音を鳴らして計算結果を7セグメントLEDに出力する処理を追加した。
今回の実装では、これで容量がいっぱいになってしまい、XORを利用して面白いことをするのは難しいかもしれない。

以下のプログラムは、[MikeAssembler](https://mikecat.github.io/mike_assembler/)でアセンブルできる。

```
target gmc4

	; 1番目の数の入力を受け付ける
IN1:
	KA
	JUMP IN1
	TIY 0
	AM
IN1_WAIT:
	KA
	JUMP IN2
	JUMP IN1_WAIT
	; 2番目の数の入力を受け付ける
IN2:
	KA
	JUMP IN2
	TIY 1
	AM
IN2_WAIT:
	KA
	JUMP IN_END
	JUMP IN2_WAIT
IN_END:

	; A = [0] ^ [1] ([0] and [1] will be broken)
	; [2] : delta
	; 今求めているビットを表す値を1にする
	TIA 1
	TIY 2
	AM
	; 計算結果を0にする
	TIA 0
	CH
XOR_LOOP:
	; 入力の値の和を求める
	TIY 0
	MA
	TIY 1
	M+
	; 和の最下位ビットをチェックする
	TIY 0
	; take jump if LSB is 0
	CAL SIFT
	JUMP XOR_SKIP_ADD
	; 和の最下位ビットが1だった場合、計算結果に今求めているビットを表す値を加える
	CH
	M+
	CH
XOR_SKIP_ADD:
	; 入力の値をそれぞれ1ビット右シフトする
	MA
	CAL SIFT
	AM
	TIY 1
	MA
	CAL SIFT
	AM
	; 今求めているビットを表す値を1ビット左シフト(2倍)する
	TIY 2
	MA
	M+
	AM
	; 今求めているビットを表す値がゼロでなかったら、次のビットの計算に行く
	CIA 0
	JUMP XOR_LOOP
	; 計算結果をAレジスタに格納する
	CH

	CAL SHTS
	AO
	JUMP IN1
```

このプログラムの機械語表現は、以下のようになる。

```
  | 0 1 2 3  4 5 6 7  8 9 A B  C D E F
--+-----------------------------------
0 | 0 F 0 0  A 0 4 0  F 0 E F  0 7 0 F
1 | 0 E A 1  4 0 F 1  C F 1 5  8 1 A 2
2 | 4 8 0 2  A 0 5 A  1 6 A 0  E 6 F 3
3 | 4 2 6 2  5 E 6 4  A 1 5 E  6 4 A 2
4 | 5 6 4 C  0 F 2 4  2 E 9 1  F 0 0
```

# 実行結果

<iframe width="560" height="315" src="https://www.youtube.com/embed/JwNnV8gZPt4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

キー入力した2個の数のXORを求めることができた。
laravel CarbonImmutable テスト用に時間を固定する

:::note info
この記事は[miriwoお一人様 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/miriwo)の3日目の記事です
:::

## 概要

- テストコードにて時間情報を固定する方法をまとめる。

## 方法

- 下記の内容をテストコードの各テストメソッド内に記載する。

    ```php
    public function test_〇〇のテスト () {
    CarbonImmutable::setTestNow();    

    // テストコード

    }
    ```

- 上記の様に記載することで時間情報を固定する事ができる。

## 参考

- 公式ドキュメントには下記の様に記載されていた。

    ```
    Carbon:: setTestNow
    $testNow = null
    「現在」のインスタンスが作成されたときに返される Carbon インスタンス (リアルまたはモック) を設定します。提供されたインスタンスは、具体的には次の条件下で返されます。 - 静的な now() メソッドへの呼び出し。Carbon::now() - null (または空の文字列) がコンストラクターまたは parse() に渡された場合、ex. new Carbon(null) - 文字列「now」がコンストラクターまたは parse() に渡される場合、ex. new Carbon('now') - 目的の時間を含む文字列が Carbon::parse() に渡されたとき。
    
    timezone パラメーターは上記の例から除外されており、その値に関係なくモック値が返されるため、影響がないことに注意してください。
    
    setTestNow() でモックされた瞬間のみ、タイムゾーンは引き続き、フォールバックとして date_default_timezone_get() のパラメーターとして渡されます (setTestNowAndTimezone() を参照)。
    
    テスト インスタンスをクリアするには、null のデフォルト パラメータを使用してこのメ​​ソッドを呼び出します。

    /!\ このメソッドは単体テストにのみ使用してください。
    ```

- さらにテストで使えそうなメソッドも発見した。

    ```
    Carbon:: setTestNowAndTimezone
    $testNow = null, $tz = null
    「現在」のインスタンスが作成されたときに返される Carbon インスタンス (リアルまたはモック) を設定します。提供されたインスタンスは、具体的には次の条件下で返されます。 - 静的な now() メソッドへの呼び出し。Carbon::now() - null (または空の文字列) がコンストラクターまたは parse() に渡された場合、ex. new Carbon(null) - 文字列「now」がコンストラクターまたは parse() に渡される場合、ex. new Carbon('now') - 目的の時間を含む文字列が Carbon::parse() に渡されたとき。
    
    また、デフォルトのタイムゾーン (たとえば、date_default_timezone_set() を呼び出す) を 2 番目の引数に合わせます。null の場合は、指定された日付オブジェクトのタイムゾーンに合わせます。
    
    テスト インスタンスをクリアするには、null のデフォルト パラメータを使用してこのメ​​ソッドを呼び出します。
    
    /!\ このメソッドは単体テストにのみ使用してください。
    ```

## 参考文献

https://carbon.nesbot.com/docs/
コードリーディングが得意になることによるメリット

日々のソフトウェア開発業務のなかで当たり前のように行っているコードリーディングを得意にする必要はあるのでしょうか？面倒だなとかやりたくないなと思うことはあっても、得意になりたいというモチベーションは湧かないかもしれません。しかし、コードリーディングが得意になると、

- 技術力の向上
- ストレスの低減
- 自信の確立
- 信頼の獲得

というメリットがあります。特にコードリーディングへ苦手意識のある方にはぜひとも克服しようと頑張ってもらいたいです。

## 技術力の向上
コードリーディングは、ソフトウェア開発におけるインプット作業です。コードリーディングが得意になることによって「技術力が向上する」とは、 **コーディング（＝アウトプット）を上達させるためにコードリーディング（＝インプット）を増やすという基本的な考え方** にもとづいています。直接的にコーディングの力を向上させる知識やテクニックを身に着けたいと思うのが自然な発想ですので、やや間接的なアプローチとなる「コードリーディングの量をこなす」という方法を重視する方は少ないでしょう。

ましてやコードリーディングに苦手意識があると、どうしても量をこなさなくなります。英語学習に置き換えてイメージすればわかりやすいでしょうか。苦手意識があると取り組み頻度は上がりにくく、いざ着手してもすぐに疲れてしまいます。まず苦手意識を克服し、徐々にコードリーディングの量を増やすことができれば、自ずとそのインプットがコーディングというアウトプットへ反映されて、技術力の向上を実感できるはずです。

## ストレスの低減
コードは読みにくいものです。かんたんに読めるものであるならば、「リーダブルコード」のように書く段階から読みやすさを意識しようという考え方がことさらに持ち上げられることはありません。コードリーディングが得意になるとは、 **コードの読みにくさ、とっつきにくさへ耐性がついていく** ことでもあります。コードリーディングへ感じるストレスを減らすことができれば、コードリーディングの量も自然と増えていき、前述のような技術力の向上によって好循環が生まれ、成長していけることでしょう。

「慣れる」ことが始めの一歩となるわけですが、そもそもコードリーディングへ苦手意識があるエンジニアにとって、「慣れる」までの道のりは決して楽なものではありません。コードの読みにくさにストレスを感じるからこそ、コードリーディングを敬遠してしまうのであり、その結果としてますますコードリーディングが上達しないという悪循環に陥ってしまうわけです。わずかなヒントを求めて延々とメールの履歴を追いかけたり、検索を繰り返して的はずれな記事を開いては閉じるという無駄な作業に時間を浪費してしまったという経験は誰しもあるかと思います。コードリーディングを避けて迂回路を進むのではなく、コードを読んで解決策を考えるという直接的な経験を積み重ねていけば、コードリーディングへのストレス耐性も強くなっていきます。

## 自信の確立
技術力が向上し、コードリーディングへのストレスや不快感が低減すれば自信がつくのは当然です。しかしそれだけでなく、コードリーディングが得意になったことで得られる自信は、 **初見ですぐに解決策が思いつかないような困難な課題であっても必ず原因を突き止めてやろうという姿勢にあらわれてきます**。こういった問題解決への粘り強い態度は非常に重要な素養であり、それが身につくことは大きなメリットと言えます。

コードリーディングへの苦手意識に限らず、初級者の場合には漠然とした不安や自信のなさを抱えています。何か力をつけられるものはないかと情報を集めることに必死になってはみたものの、やるべきこと、やったほうがいいことが膨大すぎて何も手につかないのではないでしょうか？コンピューターサイエンスの学科に行っていないことをくよくよと悩む気持ちをふくらませるのではなく、今できていないことを少しずつ解決していくことで、できないことよりもできるようになったことに視点が移っていきます。コードリーディングはソフトウェア開発業務において基礎的な作業だからこそ、苦手を克服したときの効果も大きく、その価値も十分にあります。

## 信頼の獲得
コードリーディングが得意になることで、わからないことを同僚や上司に質問する回数は減っていきます。同僚や上司が当然自力で解決してほしいと期待していることができるようになるため、信頼を得られるソフトウェアエンジニアへと変わっていくことができます。

当たり前のことのようですが、裏を返すと **コードリーディングすれば自力で解決できることを他人に頼っているうちはソフトウェアエンジニアとして信頼されていない** ということです。面倒ごとを避けるどころか、周りに押し付けているという仕事ぶりから抜け出す必要があります。初級者の段階では必死にやった上でわからない、できないので仕方ないところも多分にありますが、苦手なものがあると自覚できたのなら、迷わず克服しようと前へ進むことをおすすめします。

## 終わりに
コードリーディングへの苦手意識を克服し、徐々にコードリーディングが得意になっていくことで得られるメリットについて紹介しました。抽象的なテーマであり、中上級者のソフトウェアエンジニアにとってはすでに通過した過去の話だったかもしれません。しかし、コードリーディングという面倒で厄介なタスクをなぜやらなくてはならないのか？と新人のソフトウェアエンジニアに聞かれた時に、今回紹介した技術力の向上、ストレスの低減、自信の確立、信頼の獲得に相当する話を体験に基づいて語る機会があるのではないでしょうか？

苦手で逃れたいことであるからこそ、なぜ克服しようとすべきなのかを繰り返し思い出してモチベーションを保っていく必要があります。そういった場面で本記事を思い出してコードリーディングによって成長した姿をイメージしてみてください。一緒に頑張っていきましょう。
Addressablesでのランタイム更新にはまった話

# 前置き
「Addressablesを使えばアプリ更新無しでリソース更新し放題！」
気が付けば、軽い気持ちで手を出してしまった。よくわからないが、恐らく先人の歩んできた道に沿って行動すればなんてことはない。多少苦戦するかもしれないが、せいぜい獣道くらいだろう。鈴はもった。熊撃退スプレーもある。万全だ。

翌日、暗い部屋で一人頭を抱えながら自身の将来、日本の行く末、世界の終焉について物思いにふけるおじさんと化していた。都会の空気を長く吸いすぎたのだろう。獣道をなめていた。

# 要件
開発中アプリでは、運営中に可能な限り低コストでアセット更新を行いたいため、「アプリを再起動しなくてもアセット更新があれば取得・反映」出来るようにする必要がある。
また事前に必要なリソースはダウンロードしておき、プレイ中のもたつきを極力抑えたい。

# 結論
結論からのべると、いつもの感覚で **async/await** を行うとはまる。
Addressablesでなんらかの処理をする場合、必ず **Addressables.Release** にて解放する必要がある。これはDownloadDependenciesAsyncやLoadResourceLocationsAsyncなどの操作についても同様であり、それを忘れると参照が外れない（ここにはまっていた）。

当たり前だが、勝手によしなにGC的な何かが走ってうまいことしてくれるとか、そんな優しい世界ではなかった。~~よくよく調べると至るところに書いてある。ちゃんと調べよう(自戒)~~

# 実際の実装
今回の要件を満たすため、下記フローでそれを実現しようとした。
※Addresablesのバージョンは、対応時最新の 1.19.19 を使用。

1. 起動時に更新があるかチェック
2. 更新があれば最新アセットをダウンロードし、反映
3. インゲームへ遷移
4. タイトルへ戻る場合、再度1を実施

## カタログの更新チェック
ロード画面で、カタログの更新チェックを行う。
```C#
public async UniTask<bool> UpdateCatalog()
{
    var modifyList = await Addressables.CheckForCatalogUpdates();
    if (modifyList.Count > 0)
    {
        await Addressables.UpdateCatalogs(modifyList);
    }
    return modifyList.Count > 0;
}
```

## 事前に更新アセットをダウンロード
今回、事前ダウンロードしたものは Release せず保持しておきたかったので、必要なタイミングで解放。
※進捗取得、LoadResourceLocationsAsyncを使用したグルーピングについては割愛。
```C#
public async UniTask Preload(string label) {
    // 前回キャッシュしたAsyncOperationHandleを開放
    if (downloadHandleCache.HasValue) {
        Addressables.Release(downloadHandleCache.Value);
    }

    // 最新のアセットを取得
    var downloadHandle = Addressables.DownloadDependenciesAsync(label);
    await downloadHandle.Task;
    downloadHandleCache = downloadHandle;
}
```

## インスタンス作成
必ず Release するを念頭において、Addressables EventViewerなどを利用しながら参照が残らないことを確認しつつ実装を進めます。
この時、生成したインスタンスの破棄に応じて、自動的に Release する仕組みを実装しておくとはかどります。詳細は省きますが、OnDestroy時に処理を挟み込めば良いです。

参考リンク: [Addressables EventViewer | 公式マニュアル](https://docs.unity.cn/Packages/com.unity.addressables@1.19/manual/EventViewer.htmll)
```C#
public T InstantiatePrefab<T>(string path) {
    var handle = Addressables.InstantiateAsync($"{path}.prefab");
    // 同期的に読み込み
    var go = handle.WaitForCompletion();
    // 拡張メソッド/GameObjectの状態を監視し、破棄されれば内部的にReleaseする
    handle.Watch(go);
    return go.GetComponent<T>();
}
```

# 最後に
アセット周りは何かと厄介なので後回しにしがちですが、早い段階で検証と対応を進めておくと後々スムーズに進行出来ると思います。私はもうやりたくないです..が、カタログ運用でもはまると思うので、その時はまた記事にします...。
【フロントエンド】テストコードを書いて欲しい

## はじめに

**テストコードを書くべきだ**と言う話はエンジニアをやっていると耳にタコができるぐらい聞くかと思います。
でも、意外とフロントエンドのテストコードを書いたことがある方は少ないんじゃないでしょうか？

今回は、**フロントエンドこそテストコードを書いて欲しい**と言う話をします。

## そもそもテストコードをなぜ書くのか？

### 1. 動作をコードレベルで補償するため

バックエンドであればAPIを叩いてレスポンスを確認したり、フロントエンドであればブラウザでぽちぽちすれば動作は確認できるかと思います。
逆に言うと、**動作環境を用意し試してみるまで正しく動作しているかわからない**。ということになります。

コードレビューをしている時に思うんです。
コードを見ればどんなことをしているのかは大体わかるけど、、これ、本当に動くんだろうか。。と

そんな状態で:lgtm:とは言えないです。

### 2. 実装スピードを上げるため

**テストコードを書くと、実装スピードが上がります。**

コード量が増えるんだから時間がかかるだろう。と思われがちかと思いますが、逆だと思います。
テストコードがないから実装に時間がかかってるんです。

### 3. 関心事を分離したコードを書くため

かなり気をつけていないと、一つの関数に二つ以上の機能を持たせてしまうことがあります。
小さいプログラムだとそこまで可読性が下がらずに書けてしまったりするので、気づけないんですね。

でも、テストコードを書くと、検証したい内容とは直接的に関係のない処理やデータをモックしないといけないから気づけたりします。

よくテストコードの副次効果と言われたりしますが、僕はむしろこちらがメインぐらい重要だと思います。

## なぜフロントエンドこそ書くべきなのか

上記のテストコードを書く理由を踏まえた上で、「**なぜフロントエンドこそ書くべきなのか**」という話をします。

### 1. バックエンドより動作が不安定なため

フロントエンドは環境が固定できるバックエンドとは違い、ユーザーの手元で動くコードがほとんどです。

APIにも依存し、ユーザーの行動、環境にも依存してしまいます。

- APIから本当にそのデータが返ってくるのか
- 通信環境が悪く、データをフェッチできなかったらどうなるのか
- ボタンを連続で2回押した時はどうなるのか
- 古いブラウザを使っていた時はどうなるのか
- etc..

動作が不安定なフロントエンドだからこそテストコードが必要だと思います

### 2. バックエンドより実装ハードルがあるため

先に話した通り、フロントエンドはバックエンドに依存します。
つまり、バックエンドの実装が終わるまで動作テストできなったりします。

モックデータを使って先に実装したいですよね？
モックデータを返すサーバーを用意するより、テストコードをきちんと書いてモックデータを読み込むようにすれば良いと思います。

他にも、APIを叩けば動作させることができるバックエンドとは違い、ブラウザを立ち上げ、該当ページまで順にアクセスしないといけない
という制約もあります。
アクセスコントロールなどがあるとこういう時間が無駄になってきます。

## まとめ

今回は、**フロントエンドこそテストコードを書いて欲しい**という話をしました。
書き方がわからない。みたいな人もいると思うのでまたの機会に書き方についても話せればと思います。
エンジニアのコミュニティを作ってみた

## 自己紹介
「ねこプロ」というプログラミング学習者のためのコミュニティを運営しています[ちょめ](https://twitter.com/NEKO_PROGRAMING)と申します。
フリーランスで雑多にエンジニアやコンサルのお仕事をやっております。

コミュニティ運営を始めてからかれこれ1年半が経ちました。

ねこプロには”ねこのようにのんびりマイペースに”という基本理念がありまして、勝手ながら管理者であるわたくしものんびりマイペースに運営しております。

とにかくゆる〜く運営しています。管理者仕事してるんかって心配されそうなくらいのんびりやっています。

そんなこんなでメンバーが200人以上集まりました。

最近はメンバーに運営をほぼお任せしているので管理者としては更にのんびりさせていただいてる昨今でございます。

## ねこプロについて
誰もが自由に集まって楽しめる場所、それがねこプロです。
わたくしはねこプロが「公園のような場所」であってほしいと思っています。

ねこプロ設立当初から理想としていたのはコミュニティオーナーによる中央管理的な運営ではなく、メンバー間の助け合いにより成り立つ自律的なコミュニティです。

メンバー同士で自由に発言して自分たちの居心地のよいコミュニティの形を作っていってほしいという考えがようやく最近実現してきたような気がします。

さて、その「ねこプロ」についてご紹介させていただこうと思っていたら共同オーナーの@masakichi_engに既に書かれてしまったのでそちらをご覧ください。

## コミュニティ活動についてご紹介
- ねこプロとは
コミュニティ設立のきっかけやこれまでの活動内容は @masakichi_eng さんの記事で紹介しています。

https://qiita.com/masakichi_eng/items/0c4bdc804a12bf733bf3

- ポータルサイト
ねこプロはDiscordをプラットフォームとして活動しています。チャンネルの構成についてはこちら。

https://nekoprograming.notion.site/80ff4ae9f8d549cf95475c6564df9854

- ねこプロアドベントカレンダー2022
ねこプロのメンバーのQiita記事です。

https://qiita.com/advent-calendar/2022/nekopro

## ねこプロ関連記事のご紹介
Discordの運用をやっていただいている@YUM_3さんの記事のご紹介です

https://qiita.com/YUM_3/items/7ef85614b8a39ea93b63

## ねこプロに関するお問い合わせ
新規メンバーは随時募集中ですので、興味を持っていただけた方は[ねこプロ運営事務局](https://twitter.com/NEKO_PROGRAMING)または[まさきち](https://twitter.com/masakichi_eng)にDMいただければと思います。

引き続き、ねこプロメンバーのアドカレ記事もぜひご覧ください！！
必見：ChatGPTのテクノロジーの凄さについて

OpenAIにより１２月１日発表されたChatGPTですが、世界中で話題になってます。
私も夢中になって色々と調べてます。

日本語でのやり取りも問題なさそうで色々な記事も出てますが、APIとか内部について触れている記事があまりなかったので調べてみました。APIについては下記をご覧ください。

[速報：ChatGPTのAPIを叩いてみた](https://qiita.com/k1morikawa@github/items/5482939eb49fb70207a5)
[続：ChatGPTのAPI調査](https://qiita.com/k1morikawa@github/items/9a37e016d5c572c9d572)
[続：ChatGPTのAPI調査・その２](https://qiita.com/k1morikawa@github/items/19b9fe0e849d2428e230)

今回は、内部について少し詳しく見ていきたいと思います。

# 何が起きたのか？
今週、ニューオーリンズで開催されるNeurIPS2022でGPT-4の噂が飛び交う中OpenAIからChatGPTが発表されました。AIを利用した大規模言語モデルのGPT-3ファミリーの新しいモデル、text-davinci-003を発表しました。これは、「GPT-3.5 シリーズ」と呼ばれるものの一部であり、より複雑な指示を作成し、より高品質で長い形式にも対応してます。

# OpenAIとは
OpenAIは、人工知能（AI）を研究する非営利団体です。そしてみんな大好きイーロン・マスク氏が立ち上げメンバーです。但し、2018年にイーロン・マスク氏は利益相反があるとして退任してます。

# GPT-3とは
GPT-3は、Web等から収集した45TBもの膨大なテキストデータのうち、いくつかの前処理を施した570GBのデータセットを学習に用いたデータセットに対して、 1,750億個のパラメータを持つ自己回帰型言語モデル（ある単語の次に出てくる単語を予測するモデル）を学習することで、 今まであった「BERT」や「GPT-2」のデータ学習量を遥かに超えた、巨大な言語モデルを形成しています。
GPT　-> 1.1億パラメータ
GPT-2 -> 15億パラメータ
GPT-3 -> 1,750億パラメータ
とバージョンアップしてきました。
2020年6月にGPT-3をインターネット経由で利用できるインタフェース（API）を限定公開してます。

# 今回のdavinci-003とは
InstructGPT に基づいて構築されており、強化学習と人間のフィードバックを使用して、言語モデルと人間の指示をより適切に調整します。人間が書いたデモンストレーションと高得点のモデルサンプルで教師付き微調整を使用して生成品質を向上させるdavinci-002とは異なり、davinci-003は人間のフィードバックによる真の強化学習 (RLHF) モデルです。
との事です。

# RLHFとは
https://www.marktechpost.com/2022/02/05/openai-team-introduces-instructgpt-model-developed-with-reinforcement-learning-from-human-feedback-rlhf-to-make-models-safer-helpful-and-aligned/
記事がありました。
GPT-3は、自然言語処理(NLP)が優れていたけど、意図しない出力が出ることがあったけど、人間のフィードバックからの強化学習でInstructGPTモデルが出来たとの事です。
```
Explicit Intentions – following user instructions 
Implicit Intentions – Staying genuine and not being biased, poisonous, or otherwise hurtful.
```
こちらの通りInstructGPTモデルを入れる事で人間の指示に従い安全な物になったという事です。
更に、GPT-3の出力の毒性をInstructGPTモデルで緩和させているみたいです。

人間のフィードバックによりの通り、GPT-3に対して、人間がフィードバックを行い、強化学習させているという事ですね。これは、どのくらいの量のフィードバックが入ってるのかも気になりますが、調べてもあまり情報はありませんでした。

# 最後に
こちらのGPT-3は、APIという事もあり、誰でも自由にアプリが作れる事がとんでもない事です！！
既にあるチャットボットサービスなんかは、終わりですね。検索エンジンもインターフェイスが変わるでしょう。
様々なアプリが変わる革命的な事が起きそうな気がします。
AI化の時代の入り口に僕たちはいると思います。