OmniAICreator/Qiita-1.07M huggingface dataset:
custom Annotation

NotNull Annotationを作り、NotNullチェックする
annotationで指定したメッセージを表示する
class定義からgetDeclaredFieldsでfield定義を取り出している
f.get(x(instance))でxから値取得する。
これをリフレクションという。

```java
@Retention(RetentionPolicy.RUNTIME)
@interface NotNull{
    String message();
}
class Sample {
    @NotNull(message = " is not null x1")
    private String name;
    @NotNull(message = " is not null x2")
    private String category;
    private String city;

    public Sample(String name, String category, String city) {
        this.name = name;
        this.category = category;
        this.city = city;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

}
public class Outer {
    public static void main(String args[]) {
        Sample s = new Sample(null,null,null);
        method(s);
        s = new Sample("",null,null);
        method(s);
    }
    static void method(Sample s) {
        System.out.println("-------------");
        Field[] fs = s.getClass().getDeclaredFields();
        for(Field f : fs) {
            f.setAccessible(true);
            NotNull n = f.getAnnotation(NotNull.class);
            if(n!=null) {
                String msg = n.message();
                String name = "";
                String fieldName = "";
                try {
                    fieldName = f.getName();
                    name = (String) f.get(s);
                } catch (IllegalAccessException ex ) {
                    ex.printStackTrace();
                }
                if(name == null) {
                    System.out.println(fieldName + msg);
                }
            }
        }
    }
}
```
```
-------------
name is not null x1
category is not null x2
-------------
category is not null x2
```
GitHub codespacesのターミナルでGITHUB CLIの利用が面倒

開発環境を効率化させていく中でcodespacesの利用がすこぶる便利。
効率を追求する中で、GitHubに対してSecretをUIで設定するのが面倒で、どうにかコマンドで行うことを考えた。
GitHUB CLIというコマンドで使うものがあるということが分かった。
詰まった点は２つ
１．コマンド専用のリポジトリを作成するが、そこで作成したcodespaceからは他のリポジトリをデフォルトに設定が出来なかった。

解決方法
一つ上のディレクトリにあがり、そこから、対象となるリポジトリをクローン。gh repo clone XXXX
リポジトリ内に入り、gh repo set-defaultでデフォルトに設定する。

２．gh secertをセットしようとしても403エラーで進まない。
日本語の資料もなく。
英語ではドンピシャの問題と、その解決策が。
https://blog.jongallant.com/2021/06/codespaces-gh-cli-git-credentials/
https://github.com/jongio/gh-setup-git-credential-helper

解決方法
・gh ヘルパーを作成してくれているのでこちらをインストール。及びじっこする体制。
・githubのsetting、開発者設定のところから適切な権限を持たせた上でpersonal tokenを取得。
・ヘルパーを利用して再度ログイン。認証をWEBブラウザではなくて、GITHUB＿TOKENを利用して書き換える。

問題としてはcodespacesとしては権限を適切に持たせたアカウントで動いているためこのようなことが起こる。そしてトークンを上書きできない。
それをヘルパーで上手く使えるようにしてくれている。

大変感謝です。
その AI でどうやってビジネスする？？？

Q. 「その AI でどうやってビジネスする？？？」
A. 「分かりません。」

Qiita に書くべき内容でないかもしれないですが、受託開発のソフト屋で AI やデータサイエンティストの仕事を求められイライラしている方には共感が得られるかもしれません。

昨年は幾つかの案件を行っており多忙でした。最近になり案件がひと段落したためキャッチアップのため社内勉強会やスペシャリスト集会の議事を見返していました。*絶望した。*

AI は誰でも使える状況になってきている。AI の分野のうち画像認識に関しては各クラウドサービス（例：`AWS Rekognition`, `Google Cloud Vision API`）で用事が足りるかを考えて、もう少し踏み込んだ場合も [OpenMMLab](https://openmmlab.com/) のように論文の実装をまとめてくれているフレームワークが存在している。言語モデルと合成音声に関しても直にそのようになるだろう。NLP/言語モデルは詳しく知らないが `Azure OpenAI Service` が噂の ChatGPT の実装を提供してれるのだろう。

話題の　OpenAI がプラットフォームと理論を握れば、日本企業の得意技 "カイゼン" はうまくいかない。彼らの豊富な資源と教師データの前にリバースエンジニアリングと分析を行ったところで真似できない。本当は論文を読み込んで実装に落とし込める技術者は少ないので他社との優位性を考えて狙っていきたいが、受託システム開発の会社では競争にならないはずだ。

また、AI の導入が進むべき中小企業の大半は自転車操業で PoC の余裕がなく、まず費用対効果が社内で説明できないので仕事にならない。さらに実データに対する定量評価のための期間の話が必要などと言ったら案件化しない。私も **９９％の精度のパッケージの買い切り** が好きだ。

なので、私含めて何をすべきかでイライラする方も居るだろう。使えて当たり前の道具でキャッキャしていていも仕方がない。「その AI でどうやってビジネスする？？？」、自分たちのソリューション（目的）に AI が必要だったら使えばいいだけのように思う。AI で何かしようと考えるのは賛同できない。
複数並べたiframeのコンテンツを同時にスクロールさせる

# はじめに

検索してもそのものズバリが出てこなくて、あれこれ試行錯誤して一応動いたので書き残します。

# やりたいこと

似通ったHTMLページを複数横に並べて、目で比較したい。複数コンテンツ同時表示だけなら`iframe`で解決できるが、1画面に収まらないコンテンツを比較するため、同時に全`iframe`をスクロールさせたい。

# 前提条件

- jQueryを使っています。使わなくても書けるのかもしれませんが、、、
- HTTP Server経由で動きます。ローカルファイルではクロスサイト扱いされるようで動きません。
- Google Chromeでのみ確認してます。
- クロスドメインは動きません(`iframe`の制限)。

# ソースコード

```html
<html>
<head>
</head>
<body>
<script src="https://code.jquery.com/jquery.js"></script>
<script>
  $(function() {
      $(window).on("load", function(e){
	      $('iframe').last().contents().scroll(function(e) {
	          $("iframe").contents().each(function(index) {
		          if (index < $("iframe").length - 1) {
		              $(this).scrollTop($("iframe").last().contents().scrollTop());
		          }
	          });
	      });
      });
  });
</script>
<iframe width=30% height=100% src="./A.html" scrolling=no></iframe>
<iframe width=30% height=100% src="./B.html" scrolling=no></iframe>
<iframe width=30% height=100% src="./C.html"></iframe>
</body>
</html>
```

# 解説

iframeでA,B,Cという複数ページを読み込むのですが、最後のページでスクロールイベントが発生したときに処理を走らせます。

処理内容は、最後のページ以外のスクロール位置を、最後のページの位置に合わせるというものです。

そして、最後のページ以外はスクロールバーを隠します。

すると、このサンプルでは A B C と並んで Cの右にスクロールバーが出ます。

# 料理方法

`width`は並べるコンテンツ数に合わせて適宜。
文章みたいなものであれば、章などの区切りで揃うようスクロールさせられるといいかもしれません。
Qiitaの編集画面もそう言えば同時スクロールしてますね。こちらはどちらにもスクロールバーがついています。位置をずらしたらずらしたままスクロールさせるのもひとつのやりかたかもしれません。


# 最後に

jQuery初めて使ってみました。よくわかりません。。
Amazon API Gatewayの実行ログをAWS CloudFormationで設定する

AWS CloudFormation で Amazon API Gateway を構築する時、実行ログの設定がわかりづらかったので記録します。

Amazon API Gateway は、Amazon Management Console ではステージエディターの「ログ / トレース」タブで実行ログを設定できます。実行ログは、画面上では「CloudWatch ログ」と表示されています。画面のたどり方は、「API > ステージ > ログ / トレース > CloudWatch 設定 > CloudWatch ログ」です。

この CloudWatch ログの設定では、次の値が選択できます。

* オフ
* エラーのみ
* エラーと情報ログ
* リクエストとレスポンスの全ログ

選択できる各値の AWS CloudFormation での指定の仕方を列記します。

オフ:

```yaml:template.yaml
Resources:
  SampleApi:
    Type: AWS::Serverless::Api
    Properties: 
     MethodSettings:
        - LoggingLevel: OFF
          ResourcePath: "/*"
          HttpMethod: "*"
          DataTraceEnabled: False
```

エラーのみ:

```yaml:template.yaml
Resources:
  SampleApi:
    Type: AWS::Serverless::Api
    Properties: 
     MethodSettings:
        - LoggingLevel: ERROR
          ResourcePath: "/*"
          HttpMethod: "*"
          DataTraceEnabled: False
```

エラーと情報ログのみ:

```yaml:template.yaml
Resources:
  SampleApi:
    Type: AWS::Serverless::Api
    Properties: 
     MethodSettings:
        - LoggingLevel: INFO
          ResourcePath: "/*"
          HttpMethod: "*"
          DataTraceEnabled: False
```

リクエストとレスポンスの全ログ:

```yaml:template.yaml
Resources:
  SampleApi:
    Type: AWS::Serverless::Api
    Properties: 
     MethodSettings:
        - LoggingLevel: INFO
          ResourcePath: "/*"
          HttpMethod: "*"
          DataTraceEnabled: True
```

わかりづらかったのが、この「リクエストとレスポンスの全ログ」をオフにする設定です。「リクエストとレスポンスの全ログ」は、`DataTraceEnabled` を `True` に設定すると `LoggingLevel` の値が `Error` か `Info` かに関わらずに選択されます。又、`DataTraceEnabled` を省略した場合のディフォルト値は `True` です。本番環境での設定が推奨されない値にも関わらず、ディフォルト値が `True` ですので、実行ログを有効にする場合は明示的に指定するようにしてください。

参考までに公式ドキュメントで実行ログに言及している部分は、次の通りです。

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/set-up-logging.html#set-up-access-logging-using-cloudformation
Elixir 学習記

# 目次

1. [環境構築](https://qiita.com/SF-28/items/1a4a9a71a149f42d646f)
1. [データ型](https://qiita.com/SF-28/items/3f4208d51f2bbaa4afe9)
1. [演算子](https://qiita.com/SF-28/items/82dfb7cd5398656adbac)
1. [パターンマッチング](https://qiita.com/SF-28/items/c82793814f5493e51b69)

## 背景

前々から気になっていた Elixir を最近学び始めました。
アウトプットの練習も兼ねて、取り組んだことを書き連ねます。
現在進行形で学習中なので、おすすめの教材や方法があれば是非教えてください:open_hands:

## 実行環境

- macOS Ventura
- [Rancher Desktop](https://rancherdesktop.io/)
- [Visual Studio Code](https://azure.microsoft.com/ja-jp/products/visual-studio-code)
    - [Docker Extension](https://code.visualstudio.com/docs/containers/overview)

## 教材

- [公式ガイド](https://elixir-lang.jp/getting-started/introduction.html)
- [Elixir School](https://elixirschool.com/ja)
- [Elixir Tutorial](https://www.tutorialspoint.com/elixir/index.htm)

## コミュニティ

https://join.slack.com/t/elixirjp/shared_invite/zt-ae8m5bad-WW69GH1w4iuafm1tKNgd~w

https://qiita.com/nako_sleep_9h/items/9b6b9b70084cf5998f2d

https://speakerdeck.com/elijo/elixirkomiyunitei-falsebu-kifang-guo-nei-onrainbian
動画でDockerを学ぶ

# 動画でDockerを学ぶ
## 理由・背景
実務で少し使ったので・・・少しDockerを学ぼと思います。
方法としては動画を見てチェックです。
Docker Composeは必須だと思います。
コードは記録しておきたいなと思います。
### 公式
https://matsuand.github.io/docs.docker.jp.onthefly/

## Docker Tutorial for Beginners
https://www.youtube.com/watch?v=pTFZFxd4hOI
### シラバス
TABLE OF CONTENT 
0:00:00 Introduction
0:00:57 Prerequisites
0:01:40 How to Take This Course
0:02:26 Getting Started with Docker
0:03:10 What is Docker?
0:06:25 Virtual Machines vs Containers 
0:09:39 Docker Architecture
0:11:54 Installing Docker
0:15:29 Development Workflow
0:17:45 Docker in Action
0:27:54 The Linux Command Line 
0:28:47 Linux Distributions
0:29:49 Running Linux
0:35:01 Managing Packages
0:38:35 Linux File System
0:40:33 Navigating the File System
0:44:53 Manipulating Files and Directories 
0:48:20 Editing and Viewing Files
0:52:15 Redirection
### 用語
ハイパーバイザー：仮想マシン (VM) を作成および実行するソフトウェアです。
Dockerfile:設定ファイル
リダイレクト:UNIXのシェル、MS-DOSのコマンドプロンプトなどで、標準の入出力先を別の入出力先に変更することである。
### Take Away
docker version
docker compose up -d
docker-compose down --rmi all --volumes
docker image ls
docker ps
◼︎ nano
Ctrl + X → Exit
Everything is a file?
### 所感　まとまらなかった。良心的な方ではないかと思います。
## Docker Compose Tutorial
https://www.youtube.com/watch?v=HG6yIjZapSA&t=1539s
### シラバス
0:00 Intro
0:27 Running Multi-container Apps (intro)
1:16 Installing Docker Compose
2:30 Cleaning Up our Workspace (delete containers and images)
5:39 The Sample Web Application
8:50 JSON and YAML Formats
13:00 Creating a Compose File
21:58 Building Images
25:38 Starting and Stopping the Application
27:49 Docker Networking
### 用語
docker-compose.yml
### Take Away
docker-compose -v
### 所感　
クイックで見る分にはいいのかな？
公式ちゃんと見ないとね。

## Maven
###Take Away
%ユーザのホームフォルダ%/.m2/repository
→ 忘れがちだけど・・・・
◼︎良さげな資料
https://maven3.kengo-toda.jp/
Testlink テストケースに外部リンクをつける

# Testlinkのテストケース等の編集画面で外部へのリンクをつける方法

* テストケースが複雑（詳細な前提条件が必要）な場合、Redmine Wiki など外部のページへのリンクを付けてそちらに詳細を記述するとスッキリします。

+ Wiki などに詳細条件などのページを用意してください。

1. ホーム画面から「テストケースの編集」を選択
2. ツリーからテストケースを選択
3. [編集] ボタンをクリック
4. 編集画面でリンクを付けたい文字列を選択状態にする
![picture905-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114660/f7928af7-b97c-f677-3661-7d5c1ce35e5a.png)
5. [リンク挿入/編集] アイコンをクリック
6. 「ハイパーリンク情報」の URL 欄に目的の URL をコピペ（Redmine Wiki 等）
![picture957-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114660/61b41a23-8b35-80e4-e6eb-3b32d44535d5.png)
7. 「ターゲット」タブで <フレーム> を選択
8. 目的のフレーム名に適当な名前を入力
9. [OK] をクリック

* リンクをクリック（この例だと 詳細条件： ）で新規タブで目的のページが開きます。
ALB Listener Rule Target 振り分け

![スクリーンショット 2023-02-13 135935.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348536/7a91133f-ac0a-4a3d-f531-d87cce88b8ce.jpeg)

![スクリーンショット 2023-02-13 140026.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348536/79b80edb-4adf-32f5-d29b-76233610b497.jpeg)
ジオメトリノードでカメラ方向からメッシュを投影する

既存オブジェクトに　メッシュを投影することで
オブジェクトを作り替えることなく新しく効果を足すことができます
特にカメラ方向から投影することで必要なカットだけ３D上でレタッチを施すといったことも可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151493/be5150ce-8b04-e581-d46e-0d7ed117d47e.png)

今までもシュリンクラップ等を使って似たようなことはできましたが
ジオメトリノードでより柔軟に作成する方法を試してみました

::: note
この記事はblender3.3を想定しています
またジオメトリノードの基本的な使い方は把握している人を対象にしています
:::

## レイキャスト
図はレイキャストのノードでグリッド状のメッシュを上から-Z方向(0,0,-1)に向かって投影する例です
（投影したものが見やすくなるように設定を調整してあります）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151493/680ee280-8fcb-0b03-6da7-69a1496c2a39.png)
レイキャストは 「ソースの位置」から「レイの方向」で指定した方向を探って
ターゲットジオメトリに当たった場合には「ヒット位置」に当たった座標が出力されます
（当たらなかった場合には(0,0,0)）
ヒットフラグにはターゲットに当たったかどうかのbool値が出力されます

::: note
ここで　レイキャストの入力の「レイの方向」を見ると◇の入力になっているので
計算したいポイント個々で投影するベクトルを設定できる　ということになります。
:::

## カメラ投影
「レイの方向」を指定することでのカメラ投影です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151493/0758e7b9-0139-14be-8d1c-0db9a5a6b348.png)
「投影するメッシュ」の頂点座標を　カメラオブジェクトと同じ回転を加えることでレイの方向のベクトルとして利用しています

::: note
Blenderのカメラのデフォルト値は-Z方向となるため
投影するメッシュのトランスフォームもマイナス方向への移動になっています
なお、この段階ではカメラのfovは考慮していません
:::
ここではジオメトリ分離を利用して　レイがヒットしなかった頂点を取り除いています

これで基本的な動作は実現できたものの
- レイとメッシュ頂点が重なった部分しか使えない（ターゲットから外れた部分のメッシュも欲しい）
- 投影座標がターゲット表面上にピッタリすぎる

といった問題があります

とりあえずはヒットした中で一番遠い距離にヒットしなかったメッシュを揃えるものを作ってみました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151493/5e5da63b-83f5-b49b-fcb1-f9a2a3765541.png)
新しいバージョンでは扱いやすい機能も載っているようですがもう少し色々試したいと思います
組込ソフトウエア開発概説：開発・デバッグ環境

<h3>■開発環境</h3>
一言「マイコンのプログラムを作る」と言っても、そのプロセスを細かく見ていくとこんなツールが必要になります。<br>
<br>
1) プログラムを設計する ... フローチャートやプログラム構成を記述するドローイングツール<br>
2) プログラムを書く ... エディタソフト<br>
3) マイコン用バイナリに変換（ビルド）する ... コンパイラ・リンカ<br>
4) マイコンのメモリに転送する ... 書き込みツール<br>
5) ステップ実行などデバッグを行う ... デバッグツール<br>
6) プログラムのバグを探す ... 静的・動的プログラム解析ツール<br>
<br>
昔は上記全てを別々に入手していましたが、最近は主に2～5で使うツールが1つのソフトウエアにまとまっている統合開発環境（Integrated Development Environment：IDE）が主流です。<br><br>

<b>ルネサスエレクトロニクス　CS+</b>
https://www.renesas.com/jp/ja/software-tool/cs

<b>STマイクロエレクトロニクス　STM32CubeIDE</b>
https://www.st.com/ja/development-tools/stm32cubeide.html

<b>NXPセミコンダクターズ　MCUXpresso</b>
https://www.nxp.jp/design/software/development-software/mcuxpresso-software-and-tools-:MCUXPRESSO

Windowsパソコン向けソフトウエア開発の場合はVisualStudioで決まりですが、ファームウエアでは上記のようにマイコンメーカごとに別々のソフトウエアが必要だと思ってください。そのため、私のパソコンには3つ以上の開発環境が入っていた時期もありました。しかも案件によっては開発環境のバージョンが固定されるものもあり、別バージョンの同一ソフトを複数入れるケースも。それらが上手く共存できず、VMや別パソコンの調達が必要になるという苦労も組み込みソフトウエア開発ならでは、です。


<h3>■デバッグ環境</h3>
プログラムを書いて一発で完璧に動く、なんてことはまずあり得ません。もちろん動かす前にプログラムを見直してある程度は正しく動く確率を上げることはできますが、絶対100%にはなりません。動かしてみて初めてわかることも多いです。何かの本で読んだのですが、こんな言葉があります。
<br><br>
　<b>プログラムはあなたの思った通りには動かないかもしれないが、あなたの書いた通りには動く</b>
<br><br>
そんなあなたの意図とプログラムのギャップ、いわゆる「バグ」を追い込むデバッグには大きく2つの方法があります。
<br><br>
<b>・デバッガを用いたリアルタイムトレース</b><br>
プログラムを実行させて、プログラム中の任意の箇所で一時停止させてそのときの変数の値を確認したり、ステップ実行させてプログラムの挙動を追います。ハードウエアにJTAGと呼ばれるCPU通信専用のI/Fを用意しておき、JTAGデバッガという機器経由でPCと接続、PC上の専用アプリケーションで制御する方法が一般的です。ファームウエアが起動し、安定動作するまでは必須なツールです。前述のIDEに含まれている場合もありますし、より強力な機能を備えたデバッガとして第三社が販売しているものもあります。<br><br>

<b>Computex PalmiCE4</b>
https://www.computex.co.jp/products/palmice4/index.htm

<br>
また、プログラムにロギングポイントを（自動で）仕込み、ファームウエアを動作させた後に蓄積されたログを解析するタイプのものもあります。

<b>HEARTLAND.DATA DT+</b>
https://hldc.co.jp/product_service/development/dtplus/
<br>

<b>・printf()、シェル</b>
ハードウエアに追加でUARTのI/Fをつける必要がありますが、ある程度ファームウエアが安定動作してからはかなり強力なデバッグ手法となります。必要に応じてプログラムの中にprintf()を追加してその表示でプログラムの挙動を追うのが基本です。シェルの仕組みも入れておけば、任意のシェルコマンドを実装することで、ファームウエアを実行させている最中にファームウエア内部の情報を表示させたり、ファームウエアの挙動を変えることができます。

<h3>★Centeでは...</h3>
Centeではシェルの仕組みとしてCente shellをご用意しており、UARTドライバの開発とファームウエアへの組込も承っております。ユーザアプリケーションのデバッグでも非常に有効なツールで、市場で発生したトラブル調査にも有効です。組込機器設計の最初の段階から、（市場投入基板ではなくするとしても）UART I/Fを搭載し、デバッグ用途のUARTドライバ、シェルをファームウエアに入れることをお勧めしています。
<br><br>

<h3>■おわりに</h3>
第一シーズンとして、コンピュータ内蔵の電子機器、いわゆる組込機器において専用のソフトウエア＝ファームウエアがどんな構成になっているか、開発するには何を考えなければならないか、のアウトラインを解説しました。「このあたりもう少し聞きたい」のようなご要望がありましたら、お気軽にコメントいただければと思います。<br>
次シーズンはTCP/IPネットワークにフォーカスして、組込機器にネットワーク機能を持たせる手順について解説します。


<h3>■今日の閑話</h3>
また昔話で恐縮ですが、まだIDEなんてものがなかった時代、プログラムをどのエディタで書くかがエンジニアの一つのテーマでした。私が入社した頃はvi派とEmacs派に分かれて宗教戦争さながらの論争を繰り広げていたことを思い出します。（興味のある人は<b>「エディタ戦争」</b>で検索！）
このころのエンジニアはプログラミング中にマウスに手を伸ばすなんてことはしません。キーボードのホームポジションに両手を置いた状態でプログラムを書き、キーワードを検索・置換し、プログラムブロックを移動させ、関数間をジャンプし、ファイルを切り替え...をやってのけます。そんな先輩エンジニアの画面を横で見せてもらったとき、カーソルが画面中を自由自在に飛び回わりながらみるみるプログラムができていく様にえらく感動した記憶があります。<br><br>



Cente：
https://www.cente.jp/

お問合せはこちら：
https://www.cente.jp/otoiawase/
【devise_token_auth】rack (2.2.4) lib/rack/utils.rb:464:in `[]='の解決方法

<h2>症状</h2>
device_token_authを使って認証機能を実装しようとしたところ、以下が表示されました。

翻訳すると、「nil:NilClass の未定義メソッド」でした。


```terminal:error
 NoMethodError (undefined method `downcase' for nil:NilClass):
rack (2.2.4) lib/rack/utils.rb:464:in `[]='
rack (2.2.4) lib/rack/utils.rb:432:in `block in initialize'
rack (2.2.4) lib/rack/utils.rb:432:in `each'
rack (2.2.4) lib/rack/utils.rb:432:in `initialize'
rack (2.2.4) lib/rack/utils.rb:425:in `new'
rack (2.2.4) lib/rack/utils.rb:425:in `[]'
rack (2.2.4) lib/rack/etag.rb:29:in `call'
rack (2.2.4) lib/rack/conditional_get.rb:40:in `call'
rack (2.2.4) lib/rack/head.rb:12:in `call'
activerecord (6.0.6) lib/active_record/migration.rb:567:in `call'
actionpack (6.0.6) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
activesupport (6.0.6) lib/active_support/callbacks.rb:101:in `run_callbacks'
actionpack (6.0.6) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack (6.0.6) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (6.0.6) lib/action_dispatch/middleware/actionable_exceptions.rb:18:in `call'
actionpack (6.0.6) lib/action_dispatch/middleware/debug_exceptions.rb:32:in `call'
actionpack (6.0.6) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
railties (6.0.6) lib/rails/rack/logger.rb:37:in `call_app'
railties (6.0.6) lib/rails/rack/logger.rb:26:in `block in call'
activesupport (6.0.6) lib/active_support/tagged_logging.rb:80:in `block in tagged'
activesupport (6.0.6) lib/active_support/tagged_logging.rb:28:in `tagged'
activesupport (6.0.6) lib/active_support/tagged_logging.rb:80:in `tagged'
railties (6.0.6) lib/rails/rack/logger.rb:26:in `call'
actionpack (6.0.6) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
actionpack (6.0.6) lib/action_dispatch/middleware/request_id.rb:27:in `call'
rack (2.2.4) lib/rack/runtime.rb:22:in `call'
activesupport (6.0.6) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
actionpack (6.0.6) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (6.0.6) lib/action_dispatch/middleware/static.rb:126:in `call'
rack (2.2.4) lib/rack/sendfile.rb:110:in `call'
actionpack (6.0.6) lib/action_dispatch/middleware/host_authorization.rb:103:in `call'
rack-cors (1.1.1) lib/rack/cors.rb:100:in `call'
railties (6.0.6) lib/rails/engine.rb:527:in `call'
puma (4.3.12) lib/puma/configuration.rb:228:in `call'
puma (4.3.12) lib/puma/server.rb:727:in `handle_request'
puma (4.3.12) lib/puma/server.rb:476:in `process_client'
puma (4.3.12) lib/puma/server.rb:332:in `block in run'
puma (4.3.12) lib/puma/thread_pool.rb:134:in `block in spawn_thread'
```

<h2>解決方法</h2>
authorizationを追加したら、動作するようになりました。

```ruby:device_token_auth.rb
  config.headers_names = {:'access-token' => 'access-token',
                         :'client' => 'client',
                         :'expiry' => 'expiry',
                         :'uid' => 'uid',
                         :'token-type' => 'token-type',
                         :'authorization' => 'authorization' 
                        }
```

<h2>参考</h2>

https://github.com/lynndylanhurley/devise_token_auth/issues/1540
ArchLinux: Arduino IDE を使う

こちらのページを参考にしました。
[Manjaro Linux 18.1.0でArduinoを動かす](https://notchained.hatenablog.com/entry/2019/11/29/221306)

## インストール

```bash
sudo pacman -S python-pyserial
yay  arduino-ide-bin
```

cu を使う為に

```bash
sudo pacman -S uucp
```

## 環境設定

```bash
sudo gpasswd -a uchida uucp
```

OS を再起動する

## IDE を起動

```bash
arduino-ide
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/9a100d7c-0f51-cc49-ab98-a6b3f8d5db47.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/c6b9aa48-8b6f-c62a-4fdf-36519854c474.png)
AIX 7.2TL5 の vscsi 環境では rw_timeout 値は ディスクの属性に存在する

#### はじめに


仮想SCSI (virtual scsi/ vscsi) 環境で AIX のOSバージョンアップした後に、rw_timeout 値が vscsi アダプター属性に存在せず hdisk 属性にあることについて、何度か同じ質問を受けたので情報連携で Qiita にも記載します。


AIX 7.2TL5 では rw_timeout 値は hdisk に存在しています。

下記はご参考資料です。


---

#### 参考

[Multipathing and disk resiliency with VSCSI in a dual VIOS configuration.](https://www.ibm.com/support/pages/node/631991)
(抜粋)
> The Read Write timeout
>The « rw_timeout » value was introduced in AIX 6.1 TL9, it was first designed as an attribute of the vscsi adapter. But <font color="OrangeRed">starting AIX 7.2 TL5 the rw_timeout is now a disk attribute. </font>This change was introduced because depending on the backing device type the recommended value can be different, and a single vscsi adapter might address different backing device.


設定変更方法

* Before AIX 7.2 TL05:

```
# chdev -l vscsiYY -a rw_timeout=xx -P
```

 * After AIX 7.2 TL05:

```
 # chdev -l hdiskX -a rw_timeout=xx -P
```


---
・chdev コマンド
https://www.ibm.com/docs/ja/aix/7.2?topic=c-chdev-command

>-P オプション：実際にデバイスを変更することなく、デバイスの特性をカスタマイズ・デバイス・オブジェクト・クラスで永久に変更します。 これは、使用不可にすることができなくて、使用可能状態のときには変更することもできないデバイスの場合に便利です。 変更はデータベースに加えられ、変更がデバイスに適用されるのは、システムを リブートしたときです。このフラグは、-T フラグと共には使用できません。 どのデバイスも -P フラグをサポートしているわけではありません。 

---

#### その他 参考ドキュメント


・MPIO デバイス属性
https://www.ibm.com/docs/ja/aix/7.2?topic=io-mpio-device-attributes


・IBM AIX MPIO Best Practices and Considerations
https://www.ibm.com/support/pages/node/6325339


・vscsi(Virtual SCSI) と NPIV(N Port ID Virtualization) の比較概念図
https://www.ibm.com/support/pages/vscsi-virtual-scsi-diagram-and-npiv-n-port-id-virtualization-or-virtual-fibre-channel-diagram

    
以上です。
ChatGPTについて

先月、OpenAI が立ち上げたインテリジェント ロボット ChatGPT は、テクノロジーの世界に旋風を巻き起こし、多くの人々が積極的に試し始め、世界で最も裕福な人の Musk も参加しました。
これらはすべて、AI 絵画、AI 動画制作、「バーチャル ヒューマン」などから形成される「 AIGC (AI Generated Content、AI Generated Content)」の一部です。
1.ChatGPTとは？
これは、米国サンフランシスコに本社を置く人工知能研究所 OpenAI が立ち上げた「新世代」の AI であり、主に次のような Web ページの形で人間が提起したさまざまな質問や要求に答えます。

さまざまな業界に関する質問に答える

必要に応じて原稿を書く

小説を書き、物語を語り、詩や歌詞を書く

コード改善の経験を与えるか、コードを直接書くことさえできます

などなど .
2. 良さそうに見えますが、Apple の Siri から Microsoft の Xiaobing、Xiaodu や Xiaoai まで、過去にこのような AI 会話サービスはたくさんありました。 ChatGPT と TA の違いは何ですか?

過去の AI サービスと比較すると、ChatGPT には明らかな利点がいくつかあります。

コンテンツの作成、特にコード ガイダンスを支援できます。単に特定のテンプレートからコンテンツを選択するのではなく、リアルタイムの計算結果に基づいて回答を提供することに注意してください。提供する情報が正確であればあるほど、より的を絞った回答が得られます。

文脈を理解できる、つまり記憶力がある。例えば、質問をした後、「今の回答で、○○とはどういう意味ですか？」という形で質問します。（Siriを使ったことのある友達は、その重要性を知っているはずで、同じ情報を何度も提供する必要はありません）

モデルはユーザーのフィードバックに基づいて継続的に最適化され、回答の正確性と完全性は日々改善されます。

より「対話」感があります.ChatGPTは言語組織のロジックとシステムを大幅に改善したと言わざるを得ません.質問に答えるアシスタントまたは教師のように感じます.水密と言えます.



3. ChatGPT の原則は何ですか? それは本当に考えますか？

「人工知能」とは、簡単に言えば、「人工」によって訓練された「知性」であり、訓練サンプルは最も高い確率で答えを出します。

OpenAI が提供する公式資料では、そのメカニズムの段階的な説明が提供されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3148647/ccfc8fcd-9c69-a3a3-767a-fac44c022c7d.png)

簡単に言えば、ChatGPT はすべての人工知能「仮想人間」と同様に、回答の精度はサンプル サイズ (現在は 2021 年以前のデータのみで、リアルタイムで更新する機能はありません)、学習アルゴリズム、計算能力に依存しますが、一部の人が考えるような「自己認識」や「自己判断」にはなりません。

4. すごくパワフルそうに見えますが、欠点や欠点はありますか？勉強にも仕事にも使えますか？

数日間使用した結果、ChatGPT は論理的な分析と言語構成に強く、意見や態度を尋ねるのに適していると思います。事実がまったくチェックされていないため、情報の照会には適していません。

明らかに、ロボットが提供する答えは単なる根拠であり、「ブラック ボックス」(情報の出所と信憑性を区別できない) でさえあります。たくさんのリンクをリストするだけの検索エンジンと比較して、ロボットは明確な選択肢を与えてくれるようです。ただし、これにより、信憑性と虚偽を区別する能力に対する要求が高くなります。私たち一人一人が、入手した情報の正確性に対する「第一の責任」を負っています。

OpenAI は公式情報で ChatGPT の制限についても説明しています。

答えは間違っているかもしれません。

有害なガイドラインや偏ったコンテンツを作成する可能性があります。

データ サンプルは 2021 年以前に限定されているため、世界の理解は包括的ではありません (ただし、ChatGPT は、新しいクラウンの流行に関する上記の情報など、2021 年以降のデータ サンプルを急速に完成させていることがわかりました)。



5. ChatGPT の使用を開始するにはどうすればよいですか? 無料なの？

現在、OpenAI は、ソフトウェアのインストールやハードウェアの条件を必要とせず、https://chat.openai.com/ で直接実行できる ChatGPT の無料デモ アプリケーションを提供しています。

ただし、ログインする際にはOpenAIのアカウントで登録・ログインする必要があります。登録の際、携帯電話番号の国に制限があります。

OpenAI が起動すると、データ収集とプライバシー保護に関する指示が表示されることに注意してください。
上記のように、ChatGPT はユーザーの質問とフィードバックに基づいてサンプル ライブラリを拡張し続けるため、次の点に注意してください。

質問や会話の際に、自分に関する個人情報を決して開示しないでください。

違法なビジネスには使用しないでください。

それに与えられた答えは参考としてのみ使用することができ、完全に信じるものではありません. （自動質問応答にしても自動運転にしても、AIの最大の問題は「刑務所に行けない」ということわざがあります图片）

6. ChatGPT を含む AIGC に関して、関連する法律や規制はありますか?

ネットワーク通信とコンテンツ管理に関する通常の法律と規制に加えて、AIGC には次の 2 つの特別な規制ポイントも含まれることに注意してください。

ChatGPT は多数のサンプルから学習することで回答を提供しますが、これらの「サンプル」の元の作成者には回答の知的財産権がありますか? これに関してはまだ論争があります。AIペイントやAI支援プログラミングの分野では、こうした論争がすでに出始めています。一部の画家は、一部の AI 絵画は自分のスタイルを模倣できると述べています。AI 支援プログラミングの分野では、一部のソース コードは非オープン ソース (または契約に制限がある) であるため、補助的な回答を提供するために使用された場合、侵害になりますか? これはまだ解明されていない領域です。
Python ColabでASWのS3からダウンロードする

# イントロ
AWSのS3のバケットは、流行っているデータ保存先ですね。人工衛星のデータを会社によりよく使用します。しかし、Pythonで直接に読み込めませんが、ダウンロードできます。本日の記事には、GoogleのColabでは、AWSのS3バケットからデータをダウンロードし方を紹介します。

# セットアップ
最初に、ColabでAWSのモジュールをインストールしたいです。Pipでawsとaswcliのモジュールをインストールして、AWSを繋げるようになります。そしてColabの場合は、ドライバーに接続します。

```python
!pip3 install aws 
!pip3 install awscli 
#Colab link drive 
from google.colab import drive 
drive.mount('/content/drive')
```

次に、AWSのアカウントを設定します。AccessID(アクセント番号)とAccessKey(アクセントガキ）が必要です。持っていない場合は、AWSの記事をご覧ください [リンク](https://aws.amazon.com/jp/premiumsupport/knowledge-center/create-access-key/). このアクセント情報が持っていうると、「awscli.ini」というファイルを作りました。AWSを繋げるために、このファイルが必要です。このファイルの中で、ACCess情報とS3のバケットの地域に設定します。
```python
text = ''' 
[default] 
aws_access_key_id = {Access id goes here }
aws_secret_access_key = {Access key goes here}
region = {AWS region goes here,  example ap-northeast-1}
''' 
#Create file 
path = "/content/drive/MyDrive/config/awscli.ini" 
with open(path, 'w') as f: 
   f.write(text) 
#Print the results 
!cat /content/drive/My Drive/config/awscli.ini
```

# AWSCLI

次に awscli.iniのファイルは、Colabの環境に入り込みます。osというモジュールを使用して、環境の設定に入り込めます。
```python
import os 
!export AWS_SHARED_CREDENTIALS_FILE=/content/drive/MyDrive/config/awscli.ini 
path = "/content/drive/MyDrive/config/awscli.ini" 
os.environ['AWS_SHARED_CREDENTIALS_FILE'] = path 
print(os.environ['AWS_SHARED_CREDENTIALS_FILE'])
```
これが終わると、AWSのS3のバケットを接続できるでしょう。確認するために「ls」というシェルスクリプトを使いましょう
```python
!aws s3 ls s3://{your bucket name}
```

自分のS3のバケットを持っていない場合は、無料のデータサイエンスを使用しましょう。
データをダウンロードのために、一般的なシェルスクリプトの「cp」を使用します。S3には、保存量を減らすために、zipとtar.gzの圧縮のファイルをよく使います。Colabに環境でこのファイルをダウンロードして、解凍するときに、自分のドライバーの中で保存することが適当と思います。
```python
!aws s3 cp s3://{bucket name}/{file name}.zip .
!aws s3 cp s3://{bucket name}/{file name}.tar.gz .
```

データをダウンロードした後で、ドライバーに解凍しました。zipとtar.gzの例は下記の通りです

```python
!tar -xzvf "/content/{file_name}.tar.gz" -C "/content/drive/MyDrive/{save loc}"
!unzip "/content/{file name}.zip" -d   "/content/drive/MyDrive/{Saveloc}"
```

# メモ
メモ１：自分のドライバーの保存先は「Colab notebook」の中の場合は、文字の間のスペースは問題を引き起こせてしまいます。解決するために、\ バックスラッシュを入ります。 ("colab\ notebook").
【Laravel 9.12】例外が発生することをテストする方法 assertThrows()

# `assertThrows()`

:::note
Laravel 9.12 以降で可能です。
:::

例外が発生する関数を引数に指定することで検証を行えます。

### 使用例

例外が発生することを確認する
```php
$this->assertThrows(fn () => throw SomeException(''));
```

特定の例外が発生することを確認する
```php
$this->assertThrows(
    fn () => maybeExceptionThrownFunction(),
    CustomException::class,
);
```
 
特定のメッセージを持った例外が発生することを確認する
```php
$this->assertThrows(
    fn () => throw Exception('My message'), 
    Exception::class,
    'My message',
);
```

# `expectException()`との違い

`expectException()`は例外を発生させる前に呼び出すことで発生した例外を検証することが可能ですが、
例外が発生した時点でテストは終了してしまうため他のアサーションと組み合わせることなどはできません。
`assertThrows()`は例外を引数の関数内で検証できるため、
テスト自体を終了せずに他のアサーションを実行することも可能です。
同じ関数から複数の例外を検証する場合なども`expectException()`では、
確認したい例外の数だけテストメソッドを増やす必要がありますが、
`assertThrows()`は1つのテストメソッドでまとめれるためスッキリ書くことができます。

<details><summary>コードの比較</summary>

```diff_php
public function testExpectException(): void
{
    $this->expectException(Excepiton::class);

    throwExceptionsFunction();

    // 以下は実行されない
    $this->assert...
    ...
}

public function testAssertThrows(): void
{
    $this->assertThrows(
        fn () => throwExceptionsFunction(),
    );

    // 実行される！
    $this->assert...
    ...

    // 続けて別の例外を検証することもできる！
    $this->assertThrows(
        fn () => throwExceptionsFunction(),
        AnotherException::class,
    );
}
```
</details>

https://laravel-news.com/laravel-9-12-0

https://github.com/laravel/framework/pull/42155
ChatGPT「プロダクト開発におけるフレームワークへの依存度をどう決定するか」

![DALL·E 2023-02-13 12.46.11 - How to determine framework dependencies.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192321/6a600ccd-71b4-d4d2-53c0-034064943a2a.png)

※本記事は9割ChatGPTによる自動生成です
※アイキャッチ的に使用している画像はタイトルをDALL・Eに与えて生成した画像です

フレームワークへの依存度は、開発チーム内でのコンセンサスに基づいて決定されます。

開発チーム内で「フレームワークへの依存度は強くする方針」というコンセンサスがあれば、統一的にフレームワークを使用し、レビューなどもそれに従って行います
一方、「弱くする」方針であれば、フレームワークはライブラリとして使用され、変更可能な形に設計されます。

このような依存度の決定には、ビジネス拡大の速度や確度の見積もりによる影響があります。
ビジネス拡大の速度や確度が低い場合は、コンセプト検証やPMF（Product Market Fit）検証を目的に、特に全体の開発工程の中で初期フェーズのスピードを優先して「強くする」方針をとることが多く、代償として将来の変更に対する耐性を下げます。

逆に既に拡大の確度やその速度が速いことが想定できる場合には、フレームワークへの依存度を低くして開発工程全体の、特に後期以降の開発速度を優先して設計します。

さらに、「最初から確定している複雑さ」や「PMF（Product Market Fit）達成後の未来に折り込む複雑さ」といった条件分岐も影響します。「最初から確定している複雑さ」であれば、最初からサードパーティに強い依存は避けたいと考えますが、「PMF達成後の未来に折り込む複雑さ」であれば、確度に応じて設計の取捨選択が行われます。

このように、フレームワークへの依存度は、開発チーム内のコンセンサス、ビジネス拡大の速度や確度、未来に折り込む複雑さなどが影響する複雑な要因に基づいて決定されます。

開発チームは、フレームワークへの依存度について慎重な判断を行うことが大切です。
フレームワークへの強い依存度は、変更やアップグレードに対するフレキシビリティを低下させることがあります。
一方、フレームワークへの弱い依存度は、自由度が高まりますが、冗長性やメンテナンス性に欠けることがあります。

開発チームは、ビジネスニーズや将来の見通し、開発効率などを考慮して、フレームワークへの依存度を適切なバランスで決定することが大切です。
また、フレームワークへの依存度が変わった場合には、適切なタイミングでアップグレードや変更を行い、開発効率を維持していくことも大切です。

## 結論

結論として、フレームワークへの依存度は、開発チーム内のコンセンサス、ビジネスニーズ、将来への見通し、開発効率などが影響する複雑な要因に基づいて決定されます。
開発チームは、適切なバランスを保つことが大切であり、フレームワークへの依存度が変わった場合には適切なアップグレードや変更を行うことが大切です。

※本記事は9割ChatGPTによる自動生成です
※アイキャッチ的に使用している画像はタイトルをDALL・Eに与えて生成した画像です
wslでledger その13

# 概要
wsl(wsl2じゃない)でledgerやってみた。
練習問題、やってみた。


# 練習問題
弥生会計のエクスポートしたcsvを、elixirでledgerが読めるように変換せよ。

# サンプルコード

```

defmodule Vs do
	use Agent
	def start_link() do
		Agent.start_link(fn -> 
			[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
		end, name: __MODULE__)
	end
	def get(p) do
		Agent.get(__MODULE__, fn v ->
			Enum.at(v, p)
		end)
	end
	def set(p, x) do
		Agent.update(__MODULE__, fn v ->
			List.update_at(v, p, fn _ -> 
	            x
            end)
		end)
	end
end
defmodule Main do
    def main() do
        csv = """
"2000",139,"","H.21/01/23","普通預金","みずほ銀行","","対象外",842,0,"受取利息","","","非課売上",842,0,"","","",0,"","","0","0","no"
"2000",142,"","H.21/01/31","普通預金","みずほ銀行","","対象外",388500,0,"売上高","","","課税売上込",388500,0,"商品販売","","",0,"","","0","0","no"
"2000",225,"","H.21/02/14","水道光熱費","","","課対仕入込",2046,0,"現金","","","対象外",2046,0,"電気料金","","",0,"","","0","0","no"
"2000",226,"","H.21/02/15","通信費","","","課対仕入込",1501,0,"現金","","","対象外",1501,0,"電話料金","","",0,"","","0","0","no"
"2000",227,"","H.21/02/16","水道光熱費","","","課対仕入込",1058,0,"現金","","","対象外",1058,0,"水道料金","","",0,"","","0","0","no"
"2000",87,"","H.21/02/17","消耗品費","","","課対仕入込",980,0,"現金","","","対象外",980,0,"事務商品購入","","",0,"","","0","0","no"
"2000",112,"","H.21/02/22","旅費交通費","","","課対仕入込",4730,0,"現金","","","対象外",4730,0,"通勤定期代","","",0,"","","0","0","no"
"""
        Enum.map(String.split(csv, "\n"), fn l ->
			print(l)
		end)
	end
    def print(nil) do
        IO.puts "ok"
    end
    def print("") do
    end
    def print(l) do
        l = String.replace(l, "H.", "20")
        l = String.replace(l, "\"", "")
		s = String.split(l, ",")
		#IO.puts Enum.at(s, 4)
		cond do
		Enum.at(s, 4) == "普通預金" ->
			Vs.set(0, "Assets:" <> Enum.at(s, 4))
			Vs.set(2, "-")
		Enum.at(s, 4) == "水道光熱費" ->
			Vs.set(0, "Expenses:" <> Enum.at(s, 4))
			Vs.set(2, "")
		Enum.at(s, 4) == "通信費" ->
			Vs.set(0, "Expenses:" <> Enum.at(s, 4))
			Vs.set(2, "")
		Enum.at(s, 4) == "消耗品費" ->
			Vs.set(0, "Expenses:" <> Enum.at(s, 4))
			Vs.set(2, "")
		Enum.at(s, 4) == "旅費交通費" ->
			Vs.set(0, "Expenses:" <> Enum.at(s, 4))
			Vs.set(2, "")
		true ->
			Vs.set(0, "ok0")
		end
		cond do
		Enum.at(s, 10) == "受取利息" ->
			Vs.set(1, "Income:" <> Enum.at(s, 10))
		Enum.at(s, 10) == "売上高" ->
			Vs.set(1, "Income:" <> Enum.at(s, 10))
		Enum.at(s, 10) == "現金" ->
			Vs.set(1, "Assets:" <> Enum.at(s, 10))
		true ->
			Vs.set(1, "ok1")
		end
        IO.puts "#{Enum.at(s, 3)}  #{Enum.at(s, 16)}\n    #{Vs.get(0)}    #{Vs.get(2)}#{Enum.at(s, 8)} JPY\n    #{Vs.get(1)}"
    end
end
Vs.start_link
Main.main




```

# 実行結果

```
2021/01/23  
    Assets:普通預金    -842 JPY
    Income:受取利息
2021/01/31  商品販売
    Assets:普通預金    -388500 JPY
    Income:売上高
2021/02/14  電気料金
    Expenses:水道光熱費    2046 JPY
    Assets:現金
2021/02/15  電話料金
    Expenses:通信費    1501 JPY
    Assets:現金
2021/02/16  水道料金
    Expenses:水道光熱費    1058 JPY
    Assets:現金
2021/02/17  事務商品購入
    Expenses:消耗品費    980 JPY
    Assets:現金
2021/02/22  通勤定期代
    Expenses:旅費交通費    4730 JPY
    Assets:現金
```

# 成果物

https://paiza.io/projects/Gj_FM78-TekcSRsWMgwKDQ?language=elixir


以上。
業務でつまづいたので1からJavaScriptを勉強し直す

# はじめに
この記事を焦って書いています。
理由としてはJavaScriptが全然書けなかったからです。
私は現在文系の大学１年生です。エンジニアに将来なるべくインターンに参加させてもらっており、業務として主にフロントエンドの開発を任されています。
そこでやることになった業務内容にReactを使用したものがありました。これまで私はReactを独学で勉強していたことがあったため出来るだろうと自分の力を過信してしまっていました。
その結果見事に詰まり1からJavaScriptの勉強をしっかりと行うことを誓いました。

### 簡単な自己紹介
現在都内の大学に通う大学１年生です。
大学では法学部法学科に所属しています。
プログラミングは大学1年生のにはじめ独学で進めてきました。
大学生限定プログラミングコミュニティ「ENTER」の代表を務めさせていただいています。

### なぜ書けないのか(原因)
原因は大きく分けて２つあると考えています。

**1つ目はコピペで乗り切ってきてしまったことが原因です。**

これまで開発の経験やハッカソンの経験、Reactなどを使用した開発を行ってきて運が良かったのかコピペで必要な部分を補うことで乗り切れてきてしまいました。必要な部分はドキュメントを調べて関連する部分をQiitaのコードをコピペ。さらにわからないことがあれば関連するUdemyで復習。といった方法で乗り切ってきました。

もちろん基礎の文法は勉強をしたはずでしたが軽く攫うような勉強方法であったため今になってボロが出てきてしまいました。


**2つ目は一度作ったもの、経験したものに頼りすぎていたからです。**

これは少しわかりにくいですが簡単に説明をすると、

何かを作ろうとするときに自分が確実に今すぐできる技術内容だけを選択し開発を行っていた、今わからない技術内容を取り入れようとはせず既存のコードの流用などを行ってきたというものです。

>Ex.)Webサイトを作るときにメニューを作成することになった。自分はこれまでにハンバーガーメニューを使用したことがあり、GitHub上にコードも残っている。だからハンバーガーメニューを取り入れよう。

といったような感じです。もちろん自分が今までに作ってきて使用したことのある技術はできているが故に安心ですがこれを業務に結びつけようとすると悲惨なことになります。
安全 安心を求めると業務などで新しい技術、自分がこれまでに使用したことのないものを仕事として行うとこれまでにその耐性がないため死にます。

そして今回は見事にこれまでコピペで乗り切ってきたツケが回ってきたというわけです。

### これからの勉強方法
流れとしては今のところ以下のような順番で進めていこうと考えています。

**1.Progateを復習、自分の躓いている部分を明確化するべく一周行う**

**2.書籍 -モダンスタイルによる基礎から現場での応用まで　JavaScript本格入門-を一周する。**

**3.Udemy講座 -【JS】ガチで学びたい人のためのJavaScriptメカニズム- を一周**

**4.これまでつまづいた部分をまとめておきインターン先の友人に質問をする**

以上のように進めていきます。
またこの記事では長くなってしまうため書きませんが他の記事で日報がわりに毎日進めた内容を書いていこうと思います。
日報は以下の記事を参照ください。

https://qiita.com/kohta9521/items/d4fb52a633468abc3502

業務内容はReactであったためJavaScriptのみではなく、以上の内容が終わり次第Reactの勉強へと移っていこうと考えています。

### 終わりに
読んでいただきありがとうございました。
フロントエンド開発を進める上でJavaScriptは欠かせないものです。
業務中に自分の未熟さを痛感し、やり直そうと思えたのは良くも悪くも大学1年生のこのタイミングでよかったなと思いました。今後は基礎を大切にしつつ、しっかりとプログラミングの勉強を継続していこうと思います。
C#でちょっと時間計測したいときはこれ


# 使い方

```C#
using (ElapsedTimeLogger.StartNew()) {
        ///重い処理
}
using (ElapsedTimeLogger.StartNew("計測タイム")) {
        ///重い処理
}
```
表示結果
0.5536 ms
計測タイム : 0.5419 ms
# 実装

```C#
public readonly struct ElapsedTimeLogger :IDisposable{
    public static Action<string> Logger = Debug.Log;//いつでも自分で関数を設定できる。
    readonly Stopwatch _stopwatch;
    public readonly string Label;
    ElapsedTimeLogger(Stopwatch stopwatch) {
        _stopwatch = stopwatch;
        Label = null;
    }
    ElapsedTimeLogger(string label,Stopwatch stopwatch) {
        _stopwatch = stopwatch;
        Label = label;
    }
    public static ElapsedTimeLogger StartNew() =>new (Stopwatch.StartNew());
    public static ElapsedTimeLogger StartNew(string label) =>new (label,Stopwatch.StartNew());
    public void Dispose() {
       Log();
    }
    public void Log() {
        if (Label != null)
            Logger(Label + " : " + _stopwatch.Elapsed.TotalMilliseconds + " ms");//編集しました。
        else  Logger(_stopwatch.Elapsed.TotalMilliseconds + " ms");//編集しました。
    }
}
```

# 作った経緯(宣伝)
YukataScriptっていう言語作ってて計測しまくってたので、作りました。
https://qiita.com/aakei/items/eb279ce7212b0dd6ac2e
https://github.com/Akeit0/YukataScript
EC2 Apacheでベーシック認証を設定する

# EC2 Apacheでベーシック認証を設定する
```
$ sudo su -
$ htpasswd -c /etc/httpd/htpasswd ユーザ名
New password: ←パスワード入力
Re-type new password: ←パスワード入力
Adding password for user ユーザ名

$ cat /etc/httpd/htpasswd 
ユーザ名:$apr1$1EUQyMiS$KK1T0nJ15fI/JW6r74WXm/

$ chown apache:apache /etc/httpd/htpasswd
$ chmod 600 /etc/httpd/htpasswd
$ vim /etc/httpd/conf/httpd.conf
以下を追記
<Directory "/var/www/html">
  AuthType Basic
  AuthName "auth"
  AuthUserFile /etc/httpd/htpasswd

  <RequireAny>
  Require ip xxx.xxxx.xxx.xxx ←アクセス許可IP
  Require valid-user
  </RequireAny>
</Directory>

$ systemctl reload httpd.service
React Hook Formで扱うグローバルエラー

# はじめに
Reactでフォームを扱う時どのように扱っていますか？ReactのAPIを用いたり、recoilなどの状態管理ライブラリを用いるなど様々な方法があると思います。その中でも私は[React Hook Form](https://react-hook-form.com/)を用いて管理することが多いです。
この記事ではそんなReact Hook Formのバージョン7.43.0で追加された[グローバルエラー](https://github.com/react-hook-form/react-hook-form/releases/tag/v7.43.0)について解説していきます。バージョン7.43.0ではある条件で型に関するバグがあるのでバージョン7.43.1以降を利用するようにしましょう(後述)。
この記事はこちらの[issue](https://github.com/react-hook-form/react-hook-form/discussions/9691)によって提案された機能の解説となっています。

# グローバルエラー
グローバルエラーは特定のフォームフィールドに紐づいていないエラーを指します。サーバーエラーやカスタムエラーなどに該当します。
## これまで
グローバルエラーは今回正式にサポートされましたが、これまでも扱うことが出来ました。
```tsx
export const SampleForm = (): JSX.Element => {
  const { handleSubmit, clearErrors, setError } = useForm();
  const onSubmit = () => {
    clearErrors();
    try {
      fetch(...);
    } catch(e: FetchError) {
      setError('server', { type: 'serverError', message: e.message });
    }
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input type="text" name="hello" />
      <button>送信</button>
    </form>
  );
};
```
このコードは問題なく動作しますが一点DX上のデメリットがあります。
通常のエラーは再送信する時に自動的に一度エラーをリセットしますが、グローバルエラーはフォームフィールドに紐づいていないので再送信前に`clearErrors`でエラーを手動で削除する必要があると言う点です。このような実装はライブラリの仕様を知らないとバグに繋がるなど保守の面でも不利な性能を持つので積極的に使いたい手法ではないと考えています。
さらに、以下のように`useForm`により強い型制約を渡した場合にグローバルエラーをセットすると型エラーが出てしまう問題があります。
```tsx
export const SampleForm = (): JSX.Element => {
  const {
    handleSubmit,
    clearErrors,
    setError
  } = useForm<{ hello: string }>();

  const onSubmit = () => {
    clearErrors();
    try {
      fetch(...);
    } catch(e: FetchError) {
      // ここでエラーが出ます(型 '"server"' の引数を型 '"hello"' のパラメーターに割り当てることはできません。)
      setError('server', { type: 'serverError', message: e.message });
    }
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input type="text" name="hello" />
      <button>送信</button>
    </form>
  );
};
```
`useForm`にフォームフィールドの型情報`{ hello: string; }`を渡しているので、`setError`に始まりあらゆる関数の`name`を要求する引数は`'hello'`だけになります。つまりグローバルエラーを扱いたいときはダミーの型情報も合わせて渡すか、緩い条件で扱うことが求められます。
## 7.43以降
これを解決したのが今回追加された機能です。この機能はReact Hook Formで扱えるエラーの`name`にフォームフィールドの他に`'root'`や`` `root.${string}` ``を渡すことを可能にするというものです。これによって先ほどのコードは以下のように書けるようになります。
```tsx
export const SampleForm = (): JSX.Element => {
  const { handleSubmit, setError } = useForm<{ hello: string }>();

  const onSubmit = () => {
    try {
      fetch(...);
    } catch(e: FetchError) {
      setError('root.server', { type: 'serverError', message: e.message });
    }
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input type="text" name="hello" />
      <button>送信</button>
    </form>
  );
};
```
型の制約によるエラーやセットしたエラーのリセットもする必要がないので、他のフォームフィールドと同じように扱うことができるようになりました。
バージョン7.43.0では`useForm`に型を渡した時は型エラーで設定できないことに注意してください(7.43.1で修正されました)。

# おわりに
これまで私はグローバルなエラーを扱うときはこの記事で紹介したデメリットと天秤にかけてReact Hook Formとは別で用意した状態で管理していたので、この機能でフォームに関するエラーを一つの源からで扱えるようになって綺麗に書くことができるようになりとても嬉しいです。
LaravelのEloquentはException投げるのか投げないのかどっちなんだーいオイッ！

# とある新人のコードレビューしていて質問されたのだが
新人「データベースのupdateでtry/catchしなくていいですよね？」
私「そんなあほな」
新人「だってVSCodeの表示ではreturn intてかいてます・・・」
私「ほわぁぁぁぁ！！！！」

# LaravelのORMマッパEloquentのupdate/deleteが返す値
```
 * @return int
 */
public function update($query, $bindings = []);
```
* ヾ(ﾟДﾟ )ｫｨｫｨ、まじかよ、intを返しやがるぜ！

# 今までtry/catchしてたのは無意味？
* なんとなく遠い記憶で、return intだったのは知っていたが当然Exception投げるだろうとおもこんでいた
* でもPHPDocには @throw はかいていない・・・
* ちょっとまて、今までかいたやつは全部修正か・・・・
* ぜんぶ修正なんて地獄絵図やぞ

# 実はPDOの設定がある
* https://www.php.net/manual/ja/pdo.error-handling.php
```
PHP 8.0.0 以降では、これがデフォルトのモードです。 
エラーコードを設定することに加え、PDO は PDOException をスローします
```
* ふう、おれPHP8以上ーやたー

# でも、Laravelは接続時に設定しておりましたよ
```
 11 class Connector
 12 {
 13     use DetectsLostConnections;
 14
 15     /**
 16      * The default PDO connection options.
 17      *
 18      * @var array
 19      */
 20     protected $options = [
 21         PDO::ATTR_CASE => PDO::CASE_NATURAL,
 22         PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
```

# 結論として
* try / catchで問題ない
* php8以降はさらに try / catchで問題ない
* updateやdeleteメソッドのPHPDocはなおしてほしいところ(投げないパターンがもしかしてあるのか？？)
dockerがビルドできない「failed to solve with frontend dockerfile.v0」の対処

macOSでdocker desktopをアップデートしたところ以下のエラーでビルドできなくなりました。

```
 % sudo docker build -t elasticsearch-demo .
[+] Building 1.4s (2/3)                                                                                                                                                                            
[+] Building 1.4s (3/3) FINISHED                                                                                                                                                                   
 => [internal] load build definition from Dockerfile                                                                                                                                          0.0s
 => => transferring dockerfile: 37B                                                                                                                                                           0.0s
 => [internal] load .dockerignore                                                                                                                                                             0.0s
 => => transferring context: 2B                                                                                                                                                               0.0s
 => ERROR [internal] load metadata for docker.io/opensearchproject/opensearch:1.3.2                                                                                                           1.3s
------
 > [internal] load metadata for docker.io/opensearchproject/opensearch:1.3.2:
------
failed to solve with frontend dockerfile.v0: failed to create LLB definition: rpc error: code = Unknown desc = error getting credentials - err: exit status 1, out: ``

```
どうやら、buildkitとの不整合が原因らしいので（曖昧）buildkitを使わないように以下のコマンド使用したら解決しました。
```
DOCKER_BUILDKIT=0  docker build -t elasticsearch-demo . 
```
初めてFlask使ってECみたいなサイトを作ってみた - 其ノ弐

# tl;dr
* stripeを使うことで、簡単に決済ページ周りを作れました
* SQLite3を使ってDBを作成、データをDB経由にて管理できるようにしました
* ユーザーが個人情報を入力するRegistrationページを作りました

### Summary
前回の続きとして、ECサイトのページを追加作成したました。決済ページ(stripe)、商品詳細ページを追加作成し、また各商品はsqlite3のデータベースに保存しました。データベースの商品をindexに表示させ、前回 `checkout` , `thanks`ページとしていた個人情報入力、表示画面は `registration` ページとして、取得したユーザーデータはデータベースに保存。全体のページ構成を整理しました。

### サイト状態
![Screen_Recording_2023-02-12_at_1_06_20_AM_AdobeExpress (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386347/0ce137b4-a8b3-146a-05f0-cb3f0a69a663.gif)
gifが小さくてみづらいのですが、後日イメージ図などを貼れればと思います。

### 関連投稿
https://qiita.com/ZawaP/items/25706c6f306daf9e5660

https://qiita.com/ZawaP/items/4aefe5e0f20e17fe9ddc

https://qiita.com/ZawaP/items/706eb8e216d70d6ff206

#### 小噺
--- 
(エンジニア見習い A)
　　　　「前回なんとかローカル環境で立ち上がるECっぽいもの作ってみたぞ」
 　　　　「ただなんか色々足りない気がする、、、」
　　　　「そもそも `index`, `checkout`, `thanks` の3Pしかないしな、、、<font color="green">**決済できないとECサイトとはいえない気がする**</font>。。。」
　　　　「あとECって大体、<font color="green">**商品ごとにページある**</font>よな、、、」
　　　　「そもそも今だと<font color="green">**商品名や金額をHTMLに直書きしている**</font>けどこれはなんかやばい」

    ---モクモクモクモク---
(エンジニア見習い A)
　　　「よし、stripeという世界的に有名な決済サービスに登録して、無料で決済ページを作れたぞ！」
　　　「そして、商品ごとにページを作った！」
　　　「Sqlite3というDBを使い、商品データをDBで管理できるようにしたぞ！」
　　　「これは神サイトなのでは、、、」
     （きっと続く)

---

### 参考
* Pandas pandas.read_csv
    * https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html
* Python csv file
    * https://docs.python.org/ja/3/library/csv.html
* Python sqlite3
    * https://docs.python.org/3/library/sqlite3.html
Pythonで初めてPandas使ってstripeの商品csvをdbに取り込んでみた



## tl;dr
* csvの取り込みはPythonに組み込みモジュールが用意されている
* `Pandas`を使うと、より柔軟にデータを取り込み、加工できるためメリットが多い。
    * headerの取り込みが容易となる
    * 数値と文字列が混在しているデータを柔軟に処理できる
    * C言語にて作られているため高速

### What I did?
今回はstripeに登録した商品付フィードcsvを、`sqlite3`のDBに取り込んだ。
stripeには商品フィードと価格フィードの2つがあるため、それぞれ`products.csv`, `prices.csv`となっている。別々のテーブルにする必要を感じなかったため、mergeして一つのデータとしています。データは Pandas.to_sql 

```python:csv_to_db_py
def add_data():
    conn = sqlite3.connect('products.db', isolation_level=None)

    df_product = pd.read_csv('csv/products.csv', usecols=[0, 1, 4])
    df_price = pd.read_csv('csv/prices.csv', usecols=[0, 1, 7, 8])

    # csvデータ2つをmrge
    df = df_product.merge(df_price, how='inner', left_on='id', right_on='Product ID')

    #delete duplicated column
    df = df.drop(columns=['id'])

    #Pandas to_sql
    df.to_sql(name='products', con=conn, if_exists='replace', index=False)
    conn.close()
```

### Ref.
Pandas read.csv
https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html
【Vue】初期カーソル位置を特定のinput 要素に設定する

## やりたいこと
例えば検索ページにおいて、最初から検索窓にカーソルがフォーカスされていたら、ユーザーに優しいですよね、

ということでvueでカーソル位置を指定する機能を実装します。2分で終わります。



## 実装
１.カスタムディレクティブを作成します。

```js:main.js
const app = createApp(App)

app.directive('focus', {
    mounted(el) {
        el.focus()
    },
})
```

２.フォーカスさせたいinputに対して、v-focusを付与します。これで完了です。

```vue:search.vue
<input
    id="search"
    v-focus
    required
    name="search"
    type="text"
    block
/>
```

## 結果

ページを開くと自動で検索窓にフォーカスされるようになりました。
![スクリーンショット 2023-02-11 16.23.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1175390/9fa9ec4a-e981-5f11-55a1-92f170e7a0fd.png)
Vue3のwatcherでpropsの値の変更を監視する【備忘録】

propsで値を渡した場合、```ref```や```data```で受け取っても変更を監視することはできません。
監視するには```watch```の使い方を工夫する必要があります。
## 参照元
公式ドキュメントの[監視ソースの種類](https://ja.vuejs.org/guide/essentials/watchers.html#watch-source-types)に書かれた、getterを使います。
## Vue3+setup(+TypeScript)の場合
```sample.vue
<script setup lang="ts">
import { ref, watch } from 'vue';

const props = defineProps<{ hoge: Type }>();
const hoge = ref<Type>(props.hoge);

watch(() => props.hoge, () => {
  hoge.value = props.hoge;
});
</script>
```
## ケースステディ
### 【OK】引数で受け取り
引数で受け取っても同様に作用します。
```ok.vue
<script>
watch(() => props.hoge, (val) => {
  hoge.value = val;
});
</script>
```
### 【OK】Propsオブジェクトを監視
オブジェクト自体を監視対象にすることもできます。
```ok.vue
<script>
watch(props, () => {
  hoge.value = props.hoge;
});
</script>
```
### 【OK】refの値を監視
refで設定した値を監視することもできます。
```ok.vue
<script>
const fuga = ref<string>('');
watch(fuga, () => {
  // fugaが変更された時の処理内容
});
</script>
```
### 【NG】オブジェクトから特定のプロパティを指定
propsに限らず、特定のプロパティを指定しても監視できません。
指定したプロパティの値を渡すことになるためです。
```NG.vue
<script>
// これらはNG例
const piyo = {count: 1}

watch(props.hoge, () => {
  hoge.value = props.hoge;
});
watch(piyo.count, () => {
  // 処理内容
});
</script>
```
windows10 コマンドプロンプトの上位互換 windows terminalを 使おう

# コマンドラインを使いやすくしよう

Windows Terminal　がおすすめ

# インスコ方法

参考
https://4thsight.xyz/9087



microsoft storeから手に入れる

Windows Terminal


# 起動方法

```
win + R で wt と入力し enter
```

# powershellとコマンドプロンプトの違い

powershellはコマンドプロンプトの上位互換
linux の ls や cd も使える。
stripeを使ってflaskのWebページに決済ページを作成する方法

## tl;dr
* Stripe (https://stripe.com/ )を使えば、簡単に決済画面を導入できました (ノーコードでもできるようです)
* 商品登録は手動とAPIの2種類があり、今回はテストなので手動登録したが、APIもいつか触ってみたいです


### What I did?
*`stripe`を使って`Flask`で作成したWebサイトに決済ページを作成しました。
* 手順に沿ってコピペすることでテストコードはほぼ手間をかけずに実装可能、ローカルドメイン周りで若干詰まったが全体としてかなり楽に実装できました。
* 実際にはstripeに登録した商品からユニークな`Price ID`を取得し、`POST`リクエストに含める必要があるため、そこはDBなどを使って実装する必要があります。

```python app.py
@app.route('/create-checkout-session', methods=['POST'])
def create_checkout_session():
    try:
        checkout_session = stripe.checkout.Session.create(
            line_items=[
                {
                    # Provide the exact Price ID (for example, pr_1234) of the product you want to sell
                    'price': 'price_XXXXXXXX',
                    'quantity': 1,
                },
            ],
            mode='payment',
            success_url=YOUR_DOMAIN + '/success.html',
            cancel_url=YOUR_DOMAIN + '/cancel.html',
            automatic_tax={'enabled': False},
        )
    except Exception as e:
        return str(e)
    return redirect(checkout_session.url, code=303)

@app.route("/success")
def success():
    return render_template('success.html')

@app.route("/cancel")
def cancel():
    return render_template('cancel.html')
```