OmniAICreator/Qiita-1.07M huggingface dataset:
laravelプロジェクト作成（docker）

laravelのプロジェクト作成と基本的なところまでメモがてら記載しています。
新規プロジェクト作成時や最初どうやるんだっけって時に思い出し用

# 1. Laravelプロジェクトの作成
プロジェクトを作成します。`my-app`の部分（プロジェクト名）はお好きにつけてください。
```
curl -s "https://laravel.build/my-app" | bash
```


### オプション sailコマンドのパスを通す
もしsailコマンドのパスを通していない方は、通しておくことをおすすめします。
```
alias sail="./vendor/bin/sail"
```

# 2. コンテナの立ち上げ
プロジェクトディレクトリに移動し、sailコマンドでコンテナを立ち上げます。
```
% cd my-app
% sail up -d
```
コンテナ内で作業する方はsail shellで入ってphp artisanコマンドに置き換えて実行ください。

# データの準備 Modelの作成
デフォルトで存在するUserと、ユーザーに紐付いたPostモデルを作成します。  
```
php artisan make:model モデルファイル名（Itemとか） -a
```
`-a`はモデル、ファクトリー、マイグレーション、シーダー、リクエスト、リソースコントローラ、ポリシー全て作成する
コントローラ：モデルをuseした状態かつCRUDメソッド記載された状態で作成される
モデル：DBのテーブルと接続するファイル
リクエスト：バリデーション関係のファイル保存時と更新時のファイルが作成される
ポリシー：アクセス権限の設定等できたりするファイル
■database
マイグレーション：テーブル定義ファイル
シーダー：データベースに初期データを登録するため
ファクトリー：ダミーデータを大量に作成するときのファイル


# マイグレーションファイルの編集
## ①テーブル定義
作成されたマイグレーションファイルにてテーブル定義を記載
[laravel公式マイグレーション](https://readouble.com/laravel/9.x/ja/migrations.html)
```php
public function up()
    {
        Schema::create('テーブル名', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('memo')->nullable();
            $table->boolean('is_selling')->default(true);
            $table->timestamps();
        });
    }
```
## 【補足】
リレーションやテストデータ等を用意したい場合はファクトリとシーダーファイルの編集を行う
[参考サイト](https://qiita.com/garuda_td/items/946364da71fd66cc3a7b)

# マイグレーション実行
```php
php artisan migrate

//sailでマイグレート実行
sail artisan migrate
// sailコマンド使用できないとき（sailコマンドのパスを通す）
alias sail="./vendor/bin/sail"
```
[laravelとsail1](https://qiita.com/garuda_td/items/946364da71fd66cc3a7b)
[laravelとsail2](https://reffect.co.jp/laravel/laravel-sail#sail)


### 【補足】マイグレーションファイルだけ作成したい場合は下記のコマンド
```
php artisan make:migration create_テーブル名_table
```



# ルーティング
Laravelでは、以下のようにルーティングにRoute::resouceを指定することで、CRUDルーティングを一度に行うことができます。
```routes/web.php
use App\Http\Controllers\ItemController;
Route::resource('items', ItemController::class)
    ->middleware(['auth', 'verified']);
```

### ルーティング確認コマンド
```
php artisan route:list
```

## 【補足】ルーティングを制限する場合
使用しないメソッドをコントローラーで削除した際に、URLを直だたきされるとないと例外が出てしまうので以下のようにルーティングを制限します。
resourceを使ったときのルーティングを制限する方法は2つあります。

```/routes/web.php
// show、updateのルーティングを削除

// onlyを使う方法
Route::resource('items', 'ItemController', ['only' => ['index', 'create', 'edit', 'store', 'destroy']]);

// exceptを使う方法
Route::resource('items', 'ItemController', ['except' => ['show', 'update']]);
```
エンジニアインターン15日目

今日は今月に入って任されていたスクレイピングの機能を何とか完成することができた。ほぼ先輩エンジニアのおかげだけどね…（笑）今回の機能を実装することにあたって、エラーを解決するコツをなんとなくだがつかめた気がする。logのエラー文を読みながら原因を探り、googleでエラーを検索し、解決していく。しかし、この順番は独学でプログラミングをしていたころからわかっていたことだった。でも、できていなかった。今回の機能を作っていく中でこのことをすごく実感し、そして、成長できたと思う。
作っていく中で、if文を書くところで、当てはまらなかった場合にreturnを返すことができていなかったため、空のsql文を実行してしまい負担がかかるコードを書いてしまっていた。その場で処理を終わらせたい場合にはreturnを返し次の操作を実行しないようにすることが大事！あと、lambdaの関数urlを利用するときにパラメータで渡した値がdeployしないと重複して結果が返って来てしまう現象が発生した。そこで、渡すurlの初期値を空の状態 url = "" にしたら解決できた。
やはり毎日エラーと戦う日々だ。だが、エンジニアになるために誰もが通る道だ。つまずいてしまうときは、今の環境をフル活用して成長し続ける！！
[RDS][Aurora] Reader 2台構成でインスタンスタイプ変更にかかるダウンタイムを調査してみた

## 目的
- Aurora ClusterのWriter/Readerのインスタンスタイプの変更を実施するにあたり、ダウンタイムが最小化できる方法を検討。
- アプリのアクセスがWriter/Reader双方に対してあったため、Readerをもう一台追加してオンラインでサイズ変更を行う方法を検証。

## 検証手順
- 以下手順における、踏み台サーバからのアクセスにおけるダウンタイム時間を調べてみる。
    1. Readerインスタンスを1台追加
    1. Reader1のインスタンスタイプ変更(db.t3.medium -> 	db.t3.large)
    1. Reader2のインスタンスタイプ変更(db.t3.medium -> 	db.t3.large)
    1. WriterのFailover
    1. Writerのインスタンスタイプ変更(db.t3.medium -> 	db.t3.large)

## 検証構成
- 以下の構成でWriter/Readerのインスタンスタイプをt3.mediumからt3.large変更する。

| インスタンス台数 | Engine | Engine version |
| :-- | :-- | :-- |
| Writer1台+Reader2台 | Aurora PostgreSQL | 12.9 |


## 構成図
![rds_poc.drawio (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110280/f76e2e54-8c2b-58c4-59c4-8da6225ec23f.png)



## ダウンタイム測定
- 今回の検証では以下のスクリプトで1秒単位で以下の処理を行い、ダウンタイムを計測する。
    - クラスタエンドポイントに対して書き込み
    ```shell:write.sh
    #! /usr/bin/sh
    ENDPOINT='db.ap-northeast-1.poc-rds-custom'
    DB_NAME='rds_poc'
    DB_USER='root'
    COMMAND='INSERT INTO rds_poc VALUES (1);'
    
    # INSERT
    while true
    do
      echo `date` `psql -h ${ENDPOINT} -d ${DB_NAME} -U ${DB_USER} -c "${COMMAND}"`;
      sleep 1;
    done
    ```
    - リードエンドポイントに対して読み込み
     ```shell:read.sh
    #! /usr/bin/sh
    ENDPOINT='db.ap-northeast-1.poc-rds-custom'
    DB_NAME='rds_poc'
    DB_USER='root'
    COMMAND='SELECT * FROM rds_poc LIMIT 1;'
    
    # SELECT
    while true
    do
      echo `date` `psql -h ${ENDPOINT} -d ${DB_NAME} -U ${DB_USER} -c "${COMMAND}"`;
      sleep 1;
    done
    ```
    - 事前にテスト用のテーブルを作成しておく
     ```sql:create_table.sql
    CREATE TABLE rds_poc (
      NAME TEXT  NOT NULL
    );
    ```




## 測定結果
- 検証手順（再掲）
    1. Readerインスタンスを1台追加
    1. Reader1のインスタンスタイプ変更(db.t3.medium -> 	db.t3.large)
    1. Reader2のインスタンスタイプ変更(db.t3.medium -> 	db.t3.large)
    1. WriterのFailover
    1. Writerのインスタンスタイプ変更(db.t3.medium -> 	db.t3.large)


|  | Writeダウンタイム（sec） | Readダウンタイム（sec） | 所要時間（min） |
| :-: | :-: | :-: | :-: |
| 手順1 | - | - | 15 min |
| 手順2 | 0 sec | 0 sec | 10 min |
| 手順3 |  0 sec | 0 sec | 10 min |
| 手順4 | 9 sec | 14 sec | 1 min |
| 手順5 | 0 sec | 0 sec | 10 min |

## 所感
- Reader2台構成とすることで、donwtimeを最小化しつつインスタンスタイプの変更が実施できた
- 今回は踏み台サーバからの簡単なスクリプトを用いて検証を行なったが、client cache保持時間や作業時のアプリケーションのワークロード次第ではアクセスエラーとなる可能性があるため、考慮が必要
- Readアクセスをインスタンス単位で制御する場合にはカスタムエンドポイントの利用も考えた方が良さそう（今回はアプリ側の改修インパクトが高いため、一旦見送り）
【Swift】URLからタイトルを取得する

# はじめに
URLからWebサイトのタイトルを取得することがあり、実装したので記録しておきます。

# サンプルアプリ
![Simulator Screen Recording - iPhone 14 - 2023-02-13 at 22.21.21.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/fa193c50-d9f9-edd1-615a-d108f4b47a24.gif)

# 実装
```swift:ContentView
import SwiftUI

struct ContentView: View {
    @StateObject var viewModel = ViewModel()
    var body: some View {
        VStack(spacing: 20) {
            TextField("URLを入力してください", text: $viewModel.url, axis: .vertical)
                .textFieldStyle(.roundedBorder)

            Text(viewModel.title)
        }
        .padding(20)
    }
}
```

```swift:ViewModel
import Combine
import Foundation

final class ViewModel: ObservableObject {
    @Published var url: String = ""

    @Published var title: String = ""

    private var cancellables = Set<AnyCancellable>()

    init() {
        $url.sink { [weak self] _ in
            guard let self else { return }
            self.fetchURLTitle()
        }
        .store(in: &cancellables)
    }

    private func fetchURLTitle() {
        guard let url = URL(string: url) else { return }
        URLSession.shared.dataTaskPublisher(for: url)
            .map { data, _ in String(data: data, encoding: .utf8) }
            .compactMap { $0 }
            .replaceError(with: "")
            .receive(on: DispatchQueue.global())
            .map { html in
                guard let range = html.range(of: "<title>.*?</title>", options: .regularExpression, range: nil, locale: nil) else { return "" }
                return html[range].replacingOccurrences(of: "</?title>", with: "", options: .regularExpression, range: nil)
            }
            .receive(on: DispatchQueue.main)
            .sink { [weak self] title in
                guard let self else { return }
                self.title = title
            }
            .store(in: &cancellables)
    }
}
```

# おわり
次はOGPも取得してみたいです
IoTシステムの全体像④ 〜データ蓄積〜

# はじめに
毎週1本様々な技術に関する記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiixta.com/7_inai_)

# IoTシステムの全体像
IoTシステムでは次のような順でデータが流れていきます。
`①データ収集 -> ②データ通信 -> ③データ可視化 -> ④データ蓄積 -> ⑤データ分析 -> ⑥データ活用`
6つの記事に渡ってそれぞれのセグメントについてまとめていきますが、この記事では「④データ蓄積」について記述します。

# IoTシステムにおけるストレージの重要性
世界中のIoTデバイスの数は、2023年現在で約75億台であり、2030年には290億台まで増加すると予測されています。これだけ膨大な量のIoTデバイスで取得したデータを蓄積するストレージは、__大容量だけではなく高速処理ができる必要性__ があります。
また、大半のIoTデバイスはクラウドに接続されていますが、クラウドとの通信処理によってデータの処理速度が遅くなる問題があります。特に車のような即座の判断が必要となる機器では、処理速度の遅れが重大な事故につながる可能性があります。その対策としては、__[エッジコンピューティング](https://qiita.com/7_inai_/items/19c75af6ff20465f729f)を用いて、ネットワーク負荷を下げる__ 対策が一般的です。
このように、IoTにおいてストレージは、__単にデータを蓄積する以外にも非常に重要な役割__ を果たしています。

# IoT × ブロックチェーン
IoTと[ブロックチェーン](https://qiita.com/7_inai_/items/2ea53163ae5ec3df9cfe)は非常に相性の良い技術と言われています。
従来のクライアントサーバー型の中央集権型のITシステムでは、アクセスが集中して通信速度が遅くなりやすい、システムが複雑化すると管理が難しくなる。といったデメリットがあります。それに対して、ブロックチェーンを使用した分散管理型のシステムでは、中央にデータが集中しないためアクセス負荷を軽減でき、IoT端末の管理もそれぞれの代表者が行えば良いという状況を作れます。

### ▼事例紹介
IoTとブロックチェーンを組み合わせた事例を1つ紹介します。
世界最大手の海運企業であるMaerskは、IBMと共同でプラットフォーム(TradeLens)を開発しています。国際貿易の中核を担う海運企業では、多くの事業者が携わるため、仕様書やデータの管理方法もそれぞれ違っています。
TradeLensでは、ブロックチェーンを用いることで、貿易に必要な様々な文書を安全かつ改ざん耐性のある形で共有することができます。


# 終わりに
IoTにおいてデータの蓄積方法は非常に重要です。それぞれの蓄積方法に一長一短があるので、その特徴をよく理解した上で、導入することが非常に重要です。

最後までお付き合いくださりありがとうございました。
Golang初心者向け！mapの基礎から応用

## はじめに

Go言語のMapは、非常に便利なデータ構造であり、多くのアプリケーションに使われることがあります。この記事では、GolangのMapの基礎的な使い方と応用をまとめます。

## Mapの基礎的な使い方

Mapを使うには、最初に `make()` 関数を使って新しいMapを作成する必要があります。新しいMapは以下のように作成できます。



```go
//make(map[key名]value)の型名
intMap := make(map[string]int) //valueがint型
stringMap := make(map[string]string) //valueがstring型

```

Mapの要素を追加するには、`[key] = value` の形式を使用します。以下のように追加することができます。

```go
m["foo"] = 10
```

Mapから値を取得するには、`[key]` の形式を使用します。以下のように取得することができます。

```go
value := m["foo"]
```

## Mapのネスト

Mapを使うと、複雑なデータ構造を簡単に作ることができます。Mapをネストさせることで、複雑な構造を作成することができます。たとえば、以下のようにネストさせることができます。

```go
//map[int]stringをvalueとしたMap
m := make(map[string]map[int]string
```

## キーが存在するか確認する

マップにキーが存在するかを確認する必要がある場合は、`_, ok := m[key]`構文を使用することができます。これはマップにキーが存在するかを確認します。存在する場合、`ok`は`true`に設定され、存在しない場合は`false`に設定されます。これは、値を取得することなく、特定のキーが存在するかを確認する必要がある場合に便利です。

Golangでは、OK構文を使用することで、マップのキーが存在するかを確認することができます。次のサンプルコードは、マップにキーが存在するかを確認する方法を示しています。

```go
v, ok := m[key]

if ok {
	// キーが存在する場合の処理
} else {
	// キーが存在しない場合の処理
}

```

このサンプルコードを使用すると、`m[key]`の値が`v`に格納され、キーが存在するかどうかを`ok`で確認することができます。

## マップをループする

マップの全ての要素を反復処理してキーの存在を確認する必要がある場合は、`range`キーワードを使用することができます。これにより、マップの全ての要素をループしてキーと値にアクセスすることができます。例えば、このコードは、マップの全ての要素をループしてキーと値を表示します。

```go
for key, value := range m {
	fmt.Println("key:", key, "value:", value)
}

```

## まとめ

```go
//Mapの生成
//make(map[key名]value)の型名
intMap := make(map[string]int) //valueがint型
stringMap := make(map[string]string) //valueがstring型

//map[int]stringをvalueとしたMap
m := make(map[string]map[int]string)

//Keyの存在判定
v, ok := m[key]

if ok {
	// キーが存在する場合の処理
} else {
	// キーが存在しない場合の処理
}

// マップを全ループする
for key, value := range m {
	fmt.Println("key:", key, "value:", value)
}

```
「日本語プログラミング言語は 日本人にとって可読性が高いが、 なぜあまり普及していないのか」という学生さんの卒論に感銘をうけたお話

# はじめに
本記事は「日本語プログラミング言語は 日本人にとって可読性が高いが、 なぜあまり普及していないのか」という学生さんの卒論に感銘をうけたお話から、同じテーマについて考察し、「日本語トランスコンパイラ言語 Re:Mind（リマインド）」という自作トランスコンパイラ言語を企画するにいたった経緯をまとめておきます。 


# 参考リンク

[2020 年度 卒業論文 日本語プログラミング言語は 日本人にとって可読性が高いが、 なぜあまり普及していないのか](https://halo.aichi-u.ac.jp/wp/wp-content/uploads/2021/10/5fca7c3a7df99c6d0e24a2f840fad199.pdf)

↑こちらが直接感銘を受けた論文ですが、↓こちらの論文も力作で同じように感銘を受けております。年代的には↓先、↑後となります。↓こちらの論文が強く結論づけている点を↑こちらの論文ではアンケート結果を用いながらやんわりと示唆している感じになります。

[日本語プログラミング言語の可能性について](http://www3.otani.ac.jp/fkdsemi/thesis/2006_thesis/nakai_soturon.pdf)

# どこに感銘を受けたか

かなり実証的で、「なでしこ」「プロデル」「ドリトル」の日本語プログラミング言語の構文サンプルを100名くらいのアンケート対象者に読んでもらって、読みやすいかとかプログラムとして認知しやすいかという主観の問題を、ある程度の母数の対象者の傾向で客観的に解き明かそうとしているところ。

## 納得したところ

SI業界の覇者的プログラミング言語Javaと「なでしこ」で基本的に等価なロジックを書いたプログラムを見て、どっちがわかりやすいですかの問いに96%の方が「なでしこ」と回答したこと。

## うなったところ

現時点での日本語プログラミング業界の覇者？「なでしこ」と教育界の覇者？「ドリトル」の日本語プログラミング言語同士の同じプログラムコードを見た回答が、けっこう割れたという点。

その内訳的には「なでしこ」がわかりやすいと答えた方はプログラミングをしたことがない人で「ドリトル」のがわかると答えた方はプログラミング経験者が多かったという結果となっています。

# 論文の結論
論文では多目的用途に開発された「なでしこ」「プロデル」よりも教育目的に開発された「ドリトル」のがプログラム経験者が読みやすいという感想をもつのは、自然日本語に近い構文の前２者より英語系一般的プログラム言語の構文に近いせいではないか、そこに日本語プログラミング言語の普及のカギがあるのではと、結論づけられているように読み取れました。（あくまで筆者の解釈とイメージです。）論者は「ミスマッチ」と表現しています。

## もうひとつ感銘をうけたこと

「また、日本語プログラミング言語の先駆けとなった Mind や、熱心に開発が続く、なでしこ、プロデル、ドリトルはいずれもトイ言語などではなく、十分に本格的な言語であり、教育分野以外でも、多くの業務に使用可能となっている。」この一文のとくに前半に泣かされました。

ここでMindを持ってくるあたりが、ただものではない感があります。冒頭の方でも解説してくれてます。てなわけで、第1世代日本語プログラミング言語Mindの元ユーザーの私にとって好感度マックスです。

# この論文の結論の妥当性はいかに
さて、ここからが本題です。本題とは、日本語プログラミング言語が普及しないのは、プログラミングに関連する仕事を生業としている職業人の感覚と、現在の日本語プログラミング言語の実装の言語仕様や構文になんらかのミスマッチがあるからなのでは？という問いかけにどのように思うかということです。

## たしかにプログラムは手紙のようには書かない
さすがに、口語体でも現在の日本語プログラミング言語の構文解析力から見て、書けなくはないと思いますが、それは仕事としてはあまりないのは確かと思えます。

では、テクニカル文書のようなものなのだろうか・・・
実際問題、現時点で私が仕事で使っているプログラミング言語のソースコードって、独特のテキスト感はありますね。アロー関数とか。

多言語対応のシステムなんかに参画しておりますと、画面上の言語としては中国語や韓国語がけっこう短く、英語は横文字といわれるくらいですから、横幅くいますね。

## 縦方向が短く感じる
英文系プログラミング言語を書いていると、基本半角英数字で書きますので、なんか縦方向には見通しやすい気がします。

# わたしの方向性
Go言語の出現は驚きでした。TypeScriptの影響を受けているような印象もあるGo言語ですが、烈火のように日本のSI業界に浸透してきているような気がします。

昔はプログラミング言語ってけっこう高かったです。いまは、巨大資本のプラットフォーマがオープンソースとして、プログラミング言語環境を無料で提供してしまう時代となりました。
とりあえず、これらの巨人言語との相互運用性重視でいこうかなと考えております。

# 「日本語プログラミング言語」か「日本語トランスコンパイラ言語」か
ここでいう「日本語プログラミング言語」を独自のランタイムコードにコンパイルするコンパイラ言語またはインタプリタ言語と仮に定義します。

独自のランタイムコードにコンパイルする「日本語プログラミング言語」は、英語圏で開発された既存のプログラミング言語のランタイムコードと必ずしも相互運用性に高いわけではない面があります。

システム開発プロジェクトの開発言語として採用の俎上に上がる場合、英語圏で開発された既存のプログラミング言語同士、あるいは同一プログラミング言語でのフレームワーク違いで熾烈な競合を繰り広げている中に採用されていくハードルは、かなり高くなっているものと推察されます。
一枚岩的に採用されるか採用されないかとなり、部分的導入もされにくい。

「日本語プログラミング言語」にとっては苦渋の選択ではありますが、システム開発現場での部分的導入、あるいは設計フェーズでの部分的導入でまず実績をつくるという観点から、英語圏で開発された既存のプログラミング言語にソースコードを変換する「日本語トランスコンパイラ言語」に勝機と商機があるのではないかと考えています。

# おわりに
相互運用性重視という点での私のできそうなことの解のひとつがこれ↓というわけです。最後はおおはしょりで意味不明で失礼しました。[^1]「日本語プログラミング言語」に興味を持たれた方は、ついでにこちらも読んでいただくとうれしいです。

https://qiita.com/mylifewithviolin/items/9d58db8a101807c19bde

[^1]: 2023/04/08 新しいBingやChat-GPTにこのページを解釈させた場合、いまひとつ結論の主旨が抽出しづらい内容になっている印象が否めませんでしたので、「日本語プログラミング言語」か「日本語トランスコンパイラ言語」かという小節を追記してみました。
スキルマップに期間比で変化があったかを可視化する条件付き書式

## この記事の概要

Google Sheetsで以下のようなものを作りたくなったのですが、苦労したので記事にしました。

- いわゆるスキルマップ
- 期ごとにスナップショットをとり、前の期と比べてどの項目が上がったかが分かる
- 社員番号順に並べたとしても異動や退社で繰り上がりが発生するため、メンバーリストの順番はアテにできない

## 完成イメージ

| 現在の期（2023） | 前の期（2022） |
| --- | --- |
| ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/60ef1d55-4ef6-6c4e-d7b3-5c73b24bc1d1.png) | ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/9582083b-0bc0-7fbb-e0c3-b72e99e4f6fb.png) |

- 鈴木がリストから消え、渡辺が追加された
    - これによりリストの並びが同一でなくなった
- スキルが上がったものは背景色がついた

## 実施したこと

大雑把に言えば、`完成イメージ`の`現在の期（2023）`のシートに条件付き書式を設定しただけです。

範囲は`B2:F6`（スコアの記載されている領域）で、書式ルールは`次より大きい`、式は以下です。
（本当はインデントなんかありませんが、1行だとあまりにも見づらいのでこのように記しました）

```
=INDEX(
  INDIRECT("'2022'!A:F"),
  MATCH(
    INDIRECT(ADDRESS(ROW(), 1)),
    INDIRECT("'2022'!A:A"),
    0
  ),
  COLUMN()
)
```

具体的な仕組みを記載します。

### 何度も出てくる`INDIRECT`

条件付き書式の式で、通常の書き方（例：`'2022'!A:F`）では別シートを参照できません。
ところが`INDIRECT`を通すと取得できるため、多用しています。

### 最初の`INDEX`

`INDEX`には`参照するセル範囲, 行の番号, 列の番号`を渡します。

https://support.google.com/docs/answer/3098242

今回の場合は以下を渡しています。

- 参照するセル範囲
    - `2022`のシート全体
- 行の番号
    - `2022`のシートの中で、`2023`のシートと氏名が一致する行
- 列の番号
    - 自分自身の列番号

### `MATCH`による氏名の検索

`MATCH`には`検索キー, 検索対象の1次元配列, 検索の種類`を渡します。

https://support.google.com/docs/answer/3093378

- 検索キー
    - 氏名を表している
    - 例えば`2023`のシートの`B5`セルでは、自分自身である5行目と、1列目であるA列目をあわせて`A5`セルを読み、`高橋`がキーとなる
- 検索対象の1次元配列
    - `2022`のシートのA列、つまり氏名の書いてある列
- 検索の種類
    - 完全一致
    - デフォルトだと`検索キー以下の最も大きい値`を返すので、明示する必要がある

### `ROW()`, `COLUMN()`

`MATCH`の中でも使っているし、`INDEX`の最後の引数にも渡しています。

自分自身の行や列の値を取得できます。

## ちなみに

条件の中に`メンバーリストの順番はアテにできない`を入れていましたが、もし順番が保証されていれば以下の式で実現できました。

```
=INDEX(INDIRECT("'2022'!A:F"), ROW(), COLUMN())
```

## 最後に

「前の期のシートの内容をコピーして、今の期のシートに貼り付けて、値の大小だけ比べる」ようなやり方をとればもっと簡単でした。
しかし、同じ内容が2ヶ所に書かれていると大抵事故るので、このような作りにしてみました。

もっとスマートにできる気もしますが、ひとまずこれで良しとします。

---

最後まで読んでくださってありがとうございます！
Twitterでも情報を発信しているので、良かったらフォローお願いします！

https://twitter.com/xrxoxcxox

Devトークでのお話してくださる方も募集中です！

https://jobs.qiita.com/employers/qiita-inc/dev_talks/489
頂点を追加する方法【Blender】

メモ

<br>
<br>
<br>
<br>

頂点を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2843707/7e9993b7-4427-4474-963e-788a4ea42437.png)

<br>
<br>
<br>
<br>

右クリックで「細分化」を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2843707/527a750c-3059-5411-d269-5cfde503881e.png)

<br>
<br>
<br>
<br>

頂点が間に増える

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2843707/915a9bcd-357a-5371-23d6-d53f3f40c757.png)
StorybookのインタラクションテストでuserEvent.type()中にショートカットが動いてしまう時の対処法

Storybookを使い始めてからあれこれ機能を使いこなし始めたのですが、インタラクションテストをやっている中で少し困った挙動があったので備忘録的にまとめています。

# 環境

Storybook v6.5.15

https://github.com/storybookjs/storybook/releases/tag/v6.5.15

# 困ったこと

インタラクションテストで`userEvent.type()`で入力フォームにテキストを入力しようとした時に、サイドメニューや画像のような機能が勝手に有効になったりして、テストが正常に終了しないケースもあって困っていました

![スクリーンショット 2023-02-13 21.12.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79238/7c9b9c20-a8a7-b5f5-f681-79cc6db771b2.png)

# 原因

上の画像の機能には、それぞれショートカットが割り当てられていて`userEvent.type()`で`storybook`などをjikkousuruto`s`や`t`などでコマンドが優先して実行されてしまうことが原因のようでした。

# 解決策

Storybookのアドオン機能の設定で、ショートカット自体を無効化することで解決することができそうなので、次の設定を追加してショートカットを無効化しました。

```js:.storybook/manager.js
import { addons } from '@storybook/addons';

addons.setConfig({
  enableShortcuts: false,
});
```

`manager.js`がない方は、新しく作成してください。

# 最後に

割り当てられているショートカットのキーを変更したりすることができたら1番良さそうなのですが、今のところはそのような設定は出来なさそう？なので、今後のアップデートに期待というところでしょうか

以上です
Ubuntu 22.04にMongoDB 6.0とfree5GC WebUIをインストールする

本記事は、2023.01.26にリリースされたMongoDB 6.0.4がUbuntu 22.04に対応したことを受けて、Ubuntu 22.04にMongoDB 6.0とfree5GC WebUIをインストールする手順を簡単に説明します。

---

## 目次

- [MongoDB 6.0インストール](#mongodb-60インストール)
- [free5GC WebUIインストール](#free5gc-webuiインストール)
- [最後に](#最後に)
- [主な変更履歴](#主な変更履歴)

---

## MongoDB 6.0インストール

Ubuntu 22.04では、`apt-key`が非推奨になり、`gpg`を使用します。そこで、以下のOSについてインストール手順で示します。

- Ubuntu 20.04
- Ubuntu 22.04

```
# apt update
# apt install wget gnupg software-properties-common ca-certificates lsb-release
# wget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | gpg --dearmor -o /etc/apt/trusted.gpg.d/mongodb-6.gpg
# echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu $(lsb_release -cs)/mongodb-org/6.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-6.0.list
# apt update
# apt install -y mongodb-org
```
`mongod`サービスを有効にして、開始します。
```
# systemctl enable mongod
# systemctl start mongod
```

## free5GC WebUIインストール

Ubuntu 22.04では、`apt-key`が非推奨になり、`gpg`を使用します。
事前にMongoDB 6.0と[Go](https://github.com/free5gc/free5gc/wiki/Installation)をインストールして下さい。

最初に、Yarnをインストールします。
```
# apt install wget
# wget -qO - https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor -o /etc/apt/trusted.gpg.d/yarn.gpg
# echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
# apt update
# apt install yarn
```
次に、[こちら](https://github.com/nodesource/distributions)を参照して、Node.jsをインストールします。
```
# apt install -y ca-certificates curl gnupg
# mkdir -p /etc/apt/keyrings
# curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
# echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
# apt update
# apt install -y nodejs
```
次にfree5GC WebUIをインストールします。
```
# git clone --recursive -j `nproc` https://github.com/free5gc/free5gc.git
# cd free5gc/webconsole
# git checkout main
# cd ..
# make webconsole
```
WebUIを開始します。
```
# cd webconsole
# bin/webconsole
...
[GIN-debug] Listening and serving HTTP on :5000
```
バインドするIPアドレスとポート番号を指定する場合、[こちら](https://github.com/free5gc/webconsole/pull/56)が参考になります。

## 最後に

MongoDB 6.0がUbuntu 22.04に対応したことで、free5GCのC/U-Plane、WebUIともにUbuntu 22.04に移行できるようになりました。また、RAN/UEのシミュレータのUERANSIMもUbuntu 22.04で動作しますので、これで5Gの主なシミュレーション環境をUbuntu 22.04で構築することができますね。

最後に、元記事は[Github](https://github.com/s5uishida/free5gc_install_mongodb6_webui)に書いたものです。

## 主な変更履歴

- [2023.09.02] Node.jsのインストール手順を更新。
- [2023.02.13] 初版。
Ubuntu 22.04にMongoDB 6.0とOpen5GS WebUIをインストールする

本記事は、2023.01.26にリリースされたMongoDB 6.0.4がUbuntu 22.04に対応したことを受けて、Ubuntu 22.04にMongoDB 6.0とOpen5GS WebUIをインストールする手順を簡単に説明します。

---

## 目次

- [MongoDB 6.0インストール](#mongodb-60インストール)
- [Open5GS WebUIインストール](#open5gs-webuiインストール)
- [最後に](#最後に)
- [主な変更履歴](#主な変更履歴)

---

## MongoDB 6.0インストール

Ubuntu 22.04では、`apt-key`が非推奨になり、`gpg`を使用します。そこで、以下のOSについてインストール手順で示します。

- Ubuntu 20.04
- Ubuntu 22.04

```
# apt update
# apt install wget gnupg software-properties-common ca-certificates lsb-release
# wget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | gpg --dearmor -o /etc/apt/trusted.gpg.d/mongodb-6.gpg
# echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu $(lsb_release -cs)/mongodb-org/6.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-6.0.list
# apt update
# apt install -y mongodb-org
```
`mongod`サービスを有効にして、開始します。
```
# systemctl enable mongod
# systemctl start mongod
```

## Open5GS WebUIインストール

事前にMongoDB 6.0をインストールして下さい。
最初に、[こちら](https://github.com/nodesource/distributions)を参照して、Node.jsをインストールします。 
```
# apt install -y ca-certificates curl gnupg
# mkdir -p /etc/apt/keyrings
# curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
# echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
# apt update
# apt install -y nodejs
```
次にOpen5GS WebUIをインストールします。
```
# git clone https://github.com/open5gs/open5gs
# cd open5gs/docs/assets/webui
# bash install
```
必要に応じて、以下のようにWebUIがbindするIPアドレスとポートを設定します。(例、`192.168.0.111:3000`)

`/lib/systemd/system/open5gs-webui.service`
```diff
--- open5gs-webui.service.orig  2023-02-10 22:59:41.808165291 +0900
+++ open5gs-webui.service       2023-02-10 21:56:30.191835861 +0900
@@ -7,6 +7,8 @@
 
 WorkingDirectory=/usr/lib/node_modules/open5gs
 Environment=NODE_ENV=production
+Environment=HOSTNAME=192.168.0.111
+Environment=PORT=3000
 ExecStart=/usr/bin/node server/index.js
 Restart=always
 RestartSec=2
```
変更後、システムサービスを更新して、WebUIを再起動します。
```
# systemctl daemon-reload
# systemctl restart open5gs-webui
```

## 最後に

MongoDB 6.0がUbuntu 22.04に対応したことで、Open5GSのC/U-Plane、WebUIともにUbuntu 22.04に移行できるようになりました。また、RAN/UEのシミュレータのUERANSIMもUbuntu 22.04で動作しますので、これで5Gの主なシミュレーション環境をUbuntu 22.04で構築することができますね。

最後に、元記事は[Github](https://github.com/s5uishida/open5gs_install_mongodb6_webui)に書いたものです。

## 主な変更履歴

- [2023.09.02] Node.jsのインストール手順を更新。
- [2023.02.13] 初版。
Ruby if, else問題

# if, else問題

Aさんは普段土日が休みの仕事に就いており、休みの日は遅くまで寝ていたいと考えています。<br>
そこで、Aさんのために「その日が遅くまで寝ていられるかどうか」を判断するプログラムを作成します。<br><br>

第一引数の値では「平日かどうか」、第二引数の値では「休暇かどうか」をtrueまたはfalseを用いて以下のように表します。
- 条件1:第一引数がtrue（平日である）または、第二引数がtrue（休暇である）の場合はtrueと出力する
- 条件2:第一引数がfalse（平日でない）または、第二引数がtrue（休暇である）の場合はtrueと出力する
- 条件3:第一引数がtrue（平日である）または、第二引数がfalse（休暇でない）の場合はfalseと出力する
- 条件4:第一引数がfalse（平日でない）または、第二引数がfalse（休暇でない）の場合はtrueと出力する

```:雛形
def sleep_in(is_weekday, is_vacation)
  # ここに条件式を実装する
end

# 呼び出し例
sleep_in(false, false)
```


```ruby:模範解答
def sleep_in(is_weekday, is_vacation)
  if (is_weekday != true) || (is_vacation == true)
    puts true
  else
    puts false
  end
end

# 呼び出し例
sleep_in(false, false)
```

## 解説

- 第一引数「平日かどうか」
平日：true
平日ではない：false

- 第二引数「休暇かどうか」
休暇：true
休暇ではない：false

今回の条件から、「平日ではない」もしくは「平日だけど休暇」という場合がtrue。
「平日であり」、「休暇でもない」場合はFalse。

「〜ではない」という記述の仕方は否定の演算子!=を使います。
||は「または」という意味を表現しています。
AndroidStudio Electric Eelで"No matching variant of com.android.tools.build:gradle:7.4.0 was found."が出た

## 何が起こったか
AndroidStudioを電気ウナギ（Android Studio Electric Eel | 2022.1.1）に更新。
新しいAndroidStudioでアプリを新規作成しようとしたところ、"No matching variant of com.android.tools.build:gradle:7.4.0 was found."というエラーが出た。

## 調べた結果
どうやら Gradle JDKを11にしないとダメらしい。
公式情報が見つからなかったのでStackOverFlowを。
https://stackoverflow.com/questions/75114728/no-matching-variant-of-com-android-tools-buildgradle7-4-0-was-found

## 直し方
### Macの場合
AndroidStudio -> Preferences -> Build, Execution, Deployment -> Build Tools -> GradleJDKを選択し、1.8になっているところを11にしてOKボタンを押す。

![スクリーンショット 2023-02-13 20.50.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351850/62ece122-72d8-20d8-405a-895c9c74b0f6.png)

再ビルドが走ってビルドが通った！


### [補足]これはWindows？
File -> Settings -> Build, Execution, Deployment -> Build Tools -> Gradle らしい。

## 感想
いやー焦ったー。なんか設定ミスしたかと思った。
参考になれば幸いです。
What can Anti-Aging and Wrinkle Treatment in Delhi do to Prevent Wrinkles from Worsening

Although there are different kinds of treatments available for restoring skin color or skin tone, you should conclude for the stylish treatment. Look Young Clinic provides stylish Vitiligo Micropigmentation Treatment in Delhi. The first step of the Vitiligo Micropigmentation Treatment is to ameliorate the overall appearance of your skin. In the coming step, the condition is treated by either remedy, surgery, or medicine. The process of the treatment may take many rounds to show its complete effectiveness. Look Young Clinic’s Vitiligo Micropigmentation Treatment in Delhi involves a safe procedure to give you stylish results in the shortest period of time possible. What can you anticipate after each session? You'll surely see the results after the first session. After each session, the color of your skin appears more violent and lightens up in time for your coming session. We add further color in the coming session. After each session, the color starts fading lower until the color matches your normal skin, and also we blend the color to give you the natural look. You may observe a little greenishness and vexation in your skin between 3 – 10 days after each session. It may feel like a sunburn but you shouldn't use any skincare or makeup product without consulting an expert.
another link-
https://www.lookyoungclinicdelhi.com/
https://www.lookyoungclinicdelhi.com/contact-us.php
ファイナンス理論入門　木島・鈴木・後藤先生　朝倉書店

```r

#p.28

#利付債価格
v=200

#額面
P=100

#一年ごとのクーポン価格
C=8

#満期
t=20

f=function(Y){
return(v-C*sum(1/((1+Y)^c(1:t)))-P/((1+Y)^t))
}


#newton method

y=0.5
h=0.001
ite=10^3
eta=0.01

for(l in 1:ite){
df=(f(y+h)-f(y))/h
y=y-eta*f(y)/df
print(abs(f(y)))  
}




```

```r

#例2.2をプログラムで解いてみる。

#p.28 例2.2(A)

#利付債価格
v=98

#額面
P=100

#一年ごとのクーポン価格
C=5

#満期
t=2

f=function(Y){
return(v-C*sum(1/((1+Y)^c(1:t)))-P/((1+Y)^t))
}


#newton method

y=0.5
h=0.001
ite=10^3
eta=0.01

for(l in 1:ite){
df=(f(y+h)-f(y))/h
y=y-eta*f(y)/df
print(abs(f(y)))  
}

yA=y


#p.28 例2.2(B)

#利付債価格
v=95

#額面
P=100

#一年ごとのクーポン価格
C=3

#満期
t=2

f=function(Y){
return(v-C*sum(1/((1+Y)^c(1:t)))-P/((1+Y)^t))
}


#newton method

y=0.5
h=0.001
ite=10^3
eta=0.01

for(l in 1:ite){
df=(f(y+h)-f(y))/h
y=y-eta*f(y)/df
print(abs(f(y)))  
}

yB=y

print(paste0("最終利回りを計算するとAは",yA*100,"%でBは",yB*100,"%です"))


```

```r
#p.64

p=0.6
u=1.4
d=0.8

mu=p*log(u)+(1-p)*log(d)
sig=sqrt(p*(1-p))*log(u/d)

#Black-Sholes model

v=mu-sig^2/2
S0=100

t=seq(0,4,0.01)

St=S0*exp(v*t+sig*rnorm(length(t)))
plot(t,St)

```
【超初心者】xreaでchshできないなら一時変更でしのぐ。

# 【超初心者】xreaでchshできないなら一時変更でしのぐ。

# 概要
超初心者がlaravelをxrea（無料）で環境構築しようとしたところ
rbahsで制限がかかっていてcdすらできない。
皆様が当然にようにchshコマンドでrbashからshellをbashに変更しているのですが
2023年2月現在、chshコマンドが使えないため困っていました。
ただ、chshはログイン時のshellを変更するためのコマンドであって、一時変更時は使用したいshellの名称をそのまま打てばよかったんですよね。
私のようなbash?shell?のような超初心者のために残します。

# 目次
0．結論
1.shellとは
2.rbashとは
3.chshコマンド
4.おわりに

<!-- 各チャプター -->
<a id="#Chapter0"></a>
# 0.結論
sshで接続後、以下のよう使用したいshell名を入力してenterすると
shellが一時的に変更されてcd等のコマンドが使用できるようになります。

・bashに変更したい場合
```
[XXXXXXXX@XXXX ~]$ bash
```

【参考】①現在shellの確認方法
```
[XXXXXXXX@XXXX ~]$ echo $shell
bash
```

【参考】②使用できるshellの一覧
```
[XXXXXXXX@XXXX ~]$ cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/csh
/bin/tcsh
/usr/bin/csh
/usr/bin/tcsh
/bin/rbash

```

<a id="#Chapter1"></a>
# 1.shell/rbashとは
shellはOSと対話するためのインターフェース（窓口）を提供するソフトウェアのことです。rbashとは制限付きのシェル(RESTRICTED SHELL) のことで、xreaのようなレンタルサーバーは初期値がrbashになっています。

<a id="#Chapter2"></a>
# 2.chshとは
ログイン時のshellを変更するコマンド。
なのでこのコマンドが使えない場合、初心者はその都度shellをbashに変更して乗り切ってもいいかなと思いました。

<a id="#Chapter3"></a>
# 3.おわりに
私のような超初心者さんはchshができなくって環境構築できなくなってしまうんじゃないかと思いメモとして残しました。


<a id="#reference"></a>
# 参考文献
- [Laravel8.xのプロジェクトをXREAで無料公開する]https://qiita.com/FoolMaple/items/1bbd628bccf3b68b64ba
- [Linuxコンソールのシェルを変更する方法]https://blog.onk164.net/archives/308.html
Glue JobのTimeout値と最近の実行時間実績を調べるスクリプト

Glue Jobの最近の実行履歴から実行にかかっている時間の最小・平均・最大を計算し、Glue Jobに設定されているTimeout値と合わせて表示するスクリプトを書きました。

こんな感じで表示されます。

```plain
name                                                                   timeout     min    avg    max
gluejob-test2                                                           172800      36     41     44
gluejob-test2-01                                                        172800      52     54     57
longgluejob-sample1                                                     172800    2621   3071   3725
longgluejob-sample2                                                     172800   20837  22760  27465
```

時間の単位は秒です。

ソースコードはこんな感じです。

```python
import sys
import boto3

def main():
    profile = sys.argv[1]
    list_jobs(profile)

def list_jobs(profile):
    session = boto3.session.Session(profile_name=profile)
    glue_client = session.client("glue")
    jobs = fetch_glue_job_list(glue_client)
    print("name                                                                   timeout     min    avg    max")
    for job in jobs:
        job_name = job["Name"]
        timeout = job["Timeout"] * 60 # APIから返される値は単位が分なので秒に変換
        history = fetch_glue_job_history(glue_client, job_name)
        
        job_name_str = job_name.ljust(70)
        timeout_str = str(timeout).rjust(6)
        history_str = " ".join([str(h).rjust(6) for h in history])
        print(f"{job_name_str} {timeout_str} {history_str}")

def fetch_glue_job_list(glue_client):
    jobs = []
    res = glue_client.get_jobs()
    while True:
        for elem in res["Jobs"]:
            jobs.append(elem)
        if "NextToken" not in res:
            break
        res = glue_client.get_jobs(NextToken=res["NextToken"])
    return jobs

def fetch_glue_job_history(glue_client, job_name):
    MAX_COUNT = 100 # 最近の実行履歴として100個取得
    history = []
    res = glue_client.get_job_runs(JobName=job_name)
    while True:
        for run in res["JobRuns"]:
            if run["JobRunState"] == "SUCCEEDED":
                history.append(run["ExecutionTime"])
                if len(history) >= MAX_COUNT:
                    break
        if len(history) >= MAX_COUNT:
            break
        if "NextToken" not in res:
            break
        res = glue_client.get_job_runs(JobName=job_name, NextToken=res["NextToken"])

    if history:
        avg_value = int(sum(history) / len(history))
        max_value = max(history)
        min_value = min(history)
    else:
        avg_value = 0
        max_value = 0
        min_value = 0
    return [min_value, avg_value, max_value]

main()
```
ChatGPTで項番をコピペできないので、ChatGPTにSakura Editorのマクロを組んでもらった

# はじめに
ChatGPTの回答をコピペしてどや顔しようとしたときに、項番がコピペできなかったので、何とかならないかと思った話です。

Sakura Editorのマクロの実行については下記参照
https://qiita.com/t_o01/items/6ad844ab04fc0170b4eb

# 例えば、このようにコピペしたとき
ChatGPTの回答はこのような感じで項番が降られていることが多いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559813/d7f4ecc9-547b-bb4d-cc93-e72fc402bc11.png)
それをコピペすると、項番が抜けてしまします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559813/5ed73720-98ca-4834-826a-fbaf8fbf4a91.png)
# ChatGPTに項番つけてコピペするにはどうすればよいか聞いてみた結果
手動でつけろや！とのこと。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559813/57c372ad-0fe1-973d-2195-909764efd1fa.png)
# なのでChatGPTに、Sakura Editorのマクロで書いてもらいました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559813/8e2ce30a-a6a6-ffac-cb96-61f4fe6e54b1.png)

``` javascript
// 選択範囲の行に項番を追加するマクロ
var lines = Editor.GetSelectedString(0).split("\n");
for (var i = 0; i < lines.length; i++) {
    lines[i] = (i + 1) + ". " + lines[i];
}
Editor.InsText(lines.join("\n"));
```

# 実行してみた結果

実行前
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559813/8e02c6e9-22d5-a207-6489-ca6840e48555.png)

実行後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559813/b61fbdb5-5cf9-9685-a799-3fbfb95970eb.png)
想定通り、選択範囲に項番を振ってもらえました。　　


でも、こんな感じで、一行目の選択範囲が途中からだった場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559813/edba3b75-5c67-3725-0146-3edf9e63c9a1.png)
実行後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559813/ba017bfb-61a5-d57e-1a71-e32e015562f0.png)
一行目の途中から項番を振られてしまいました。
依頼してないことは実装してくれないですよね。わかります。

# 改修してもらう
選択範囲を一行目の先頭からにするように修正依頼しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559813/1f8f7bef-d554-c861-a81b-a082ad5695f3.png)
それっぽいソースになったと思います。

ので、実行してみたところ、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559813/767a4efb-0c7f-64f7-5300-043b970ce33a.png)
エラーが発生しました。
何度かChatGPTに修正依頼しなおしましたが、解決せず。
Docker build cacheのgarbage collectionの設定

# 手順
Docker DaemonのConfigurationファイルの準備

```json:/etc/docker/daemon.json
{
  "builder": {
    "gc": {
      "enabled": true,
      "defaultKeepStorage": "10GB"
    }
  },
  "features": {
    "buildkit": true
  },
  "debug": true
}
```

Docker daemonの再起動

```
systemctl restart docker
```

Logの確認:

```
tail -f /var/log/syslog
```


# 参考

https://github.com/docker/cli/pull/2864

https://github.com/docker/cli/pull/2864/files?short_path=1ebe647#diff-1ebe647007107b0c4b7e7ec7ea95df8a83f734535b2f53b3141299ff950ef5a2

https://medium.com/geekculture/how-docker-buildkit-and-gitlab-runner-fill-up-storage-in-kubernetes-fix-it-a839c841bf95

https://github.com/moby/buildkit#starting-the-buildkitd-daemon


https://docs.docker.com/build/cache/garbage-collection/

https://qiita.com/nakamasato/items/ee3a7f2cd8bbd50a3b70
７つのアクション

本日は７つのアクションについて投稿します。

○アクションとは
---
ユーザー側からリクエストされた内容を実行、処理する事。

使い方
`````
def index
~~
~~
end
`````
こんな感じで使います。

○７つのアクション詳細
---------

| アクション名 | 内容 |
|:-:|:-:|
| 　index（インデックス）　　　|  　　　　一覧表示する 　　　　|
| show（ショー）  |  詳細表示する |
| new（ニュー）  |  生成する |
|  create（クリエイト） | 保存する  |
| edit（エディット）  | 編集する  |
| update（アップデート）  | 更新する  |
|  destroy（デストロイ） | 削除する  |

これが７つのアクションです。

使い方をしっかり学んでアプリ作成に生かしていきます！
本日はここまで！ありがとうございました！！
ChatGPT Java Interface実装

記事ディレクトリ
1. 記事の紹介
2. Java ベースの API を呼び出す
2.1 環境構成
2.2 コードを書く
3. 重要なまとめ
3.1 公式ウェブサイトのリンクアドレス
3.2 開発言語の例へのリンク
1. 記事の紹介
まず、ChatGPT公式 Web サイトにアクセスする必要があります。この Web サイトでは、呼び出しインターフェイスの多くの言語の例が提供されてChatGPTいAPIますjava，go，C#。

私は開発者なので、呼び出しインターフェイスjavaの使用方法を次のように詳しく説明します。javaChatGPTAPI

2. Java ベースの API を呼び出す
2.1 環境構成
公式ウェブサイトのリンク アドレスによると、クリックしてjava例にジャンプしますGitHub。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3148647/1f781852-0866-6c39-87a4-1b09981ee467.png)

GitHub上記にジャンプした後、jar次の図に示すように、パッケージの参照を見つけます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3148647/a0bbd45e-b38a-c14a-d36b-40c7af74211f.png)

3.つまり、次のコードに示すように、プロジェクト ( ) にパッケージpom.xmlをインポートします

<dependency><groupId>com.theokanning.openai-gpt3-java</groupId><artifactId>api</artifactId><version>version</version>       
</dependency>

2.2 コードを書く
1ソース コードをダウンロードする必要はありませんが、example次の図に示すように、このパッケージをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3148647/8f2b94a7-7585-5422-3756-d7eadf53f7ac.png)
2 クリックsrc/main/java/example
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3148647/70b60caa-dcc4-eb05-5bd4-38756a15643f.png)
3 クリックOpenAiApiExample.java
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3148647/94cd74b1-ccfc-9c0e-0e1c-292fe9287743.png)
4 次のようにサンプル コードを取得します。
package example;import com.theokanning.openai.OpenAiService;
import com.theokanning.openai.completion.CompletionRequest;class OpenAiApiExample {public static void main(String... args) {String token = System.getenv("OPENAI_TOKEN");OpenAiService service = new OpenAiService(token);System.out.println("\nCreating completion...");CompletionRequest completionRequest = CompletionRequest.builder().model("ada").prompt("Somebody once told me the world is gonna roll me").echo(true).user("testing").build();service.createCompletion(completionRequest).getChoices().forEach(System.out::println);}

自分の情報を入力するだけですが、取得するには秘钥(token)登録が必要です。OpenAI APIAPI密钥(token)

もちろん、次のメソッドを使用して を呼び出すこともできますChatGPT。
}
springでListのstringなどの要素にvalidationのアノテーションを付与


```java
import java.util.List;

import jakarta.validation.constraints.NotNull;
import lombok.Data;

@Data
public class SampleRequest {
  List<@NotNull String> list;
}
```

アノテーションを自作する場合は ```ElementType.TYPE_USE``` を使用する。

```java
@Target(java.lang.annotation.ElementType.TYPE_USE)
```
AWS WAFにタグ設定する方法

AWS WAFのリソース(Web ACL, Rule Group, IP Set)のタグ操作をする場合、
マネジメントコンソール上からではなくCLIからするっぽいので備忘録として残します。

#### AWS WAFv2のCLIドキュメント

https://docs.aws.amazon.com/cli/latest/reference/wafv2/index.html#cli-aws-wafv2

実際にやる時はCloud Shellで実行するのが良さそう。

## タグ操作

```bash:タグ設定
aws wafv2 tag-resource --resource-arn <value> --tags <value>
```

```bash:--tagsの指定例
Key=<value>,Value=<value>
```

https://docs.aws.amazon.com/cli/latest/reference/waf/tag-resource.html

- 既に登録されているタグの一覧を取得

```bash
aws wafv2 list-tags-for-resource --resource-arn <value>
```

- タグの削除
```bash
aws wafv2 untag-resource --resource-arn <value> --tag-keys <value>
```

## そもそものResource ARNを取得する方法
以前はスコープ(Cloud Front, Regional)によって使用するAPIが変わっていましたが、
WAFv2では統合されているのでスコープの指定が必要になります。

### Web ACL

```bash
aws wafv2 list-web-acls --scope <CLOUDFRONT or REGIONAL>
```

### Rule Gruop

```bash
aws wafv2 list-rule-groups --scope <CLOUDFRONT or REGIONAL>
```

### IP Set
```bash
aws wafv2 list-ip-sets --scope <CLOUDFRONT or REGIONAL>
```

Regionalのリソースを取得する際は`--region`を付け足します。
SQlite3でデータベースのcreated_atから日付だけ取り出す

## 要点
- データベースにデータを作成した日時をそのままWebページに表示させたい
- 初期で保存されているデータをそのまま使うと日付だけでなく、時間まで表示されてしまう
- 日付のフォーマットを変換し、表示させた

## 背景
勉強のためにRuby on Rails5を使い、Webアプリケーション（Todoアプリもどき）を作成中です。
下記のようにやりたいことはほとんど同じだと思われるが、SQLやLaravelなどの別言語での解説が多く、苦戦したため忘れないようにメモとして残しております。

SQliteでの日付時刻を扱う際のポイント→https://qiita.com/TomK/items/132831ab45e2aba822a8
Laravelでデータベースのcreated_atから日付だけ取り出す→https://qiita.com/N0S0/items/d656dbd1b83f4ed8e3d6

## 対処方法
- DateTimeクラスにあるstrftimeメソッドを使用することで簡単に表示させることができました。
- 参考にさせていただいたサイト→https://magazine.techacademy.jp/magazine/18707

## 実際のコード
```rb
require "date"

<% @tasks.each do|task| %>
    <% date = task.created_at %>
    <%= date.strftime("%Y-%m-%d") %>
<% end %>
```
```
2023-02-06
```

## まとめ
参考サイトではDataクラスで取得したデータを指定のフォーマットで表示するメソッドとしてstrftimeというメソッドが紹介されていました。今回はデータベースに保存されていた時刻をそのままDateクラスで取得したデータと仮定して、試してみたら参考サイト通りに表示させることができました。
クラスとして取得したデータではないが、保存されているデータがDateクラスと同じ形式の保存だったからできたのか、そもそもDateクラスとしてSQlite３に保存されているというものなのかはよくわかってないです。
いまいち理解できていなくても何となく試してみたらうまくいった、というパターンは案外多いためあきらめずに色々やってみようと思います。
アルファベットからなる連続IDを生成するPythonコード

### 概要
SpreadSheetのカラム名のように、A, B, C, ...., Z, AA, AB, AC, ADと連続するIDを生成するコードを作成した

### コード
なお今回は、Aを自然数における0と同じ様に扱うように設定した。つまり以下となる。
- 正) Y → Z → BA → BB
- 誤) Y → Z → AA → AB

これは、8 → 9 → 00ではなく、8 → 9 → 10であることに等しい

```python
import string

ZERO_CHAR = 'A'
ONE_CHAR = 'B'
LAST_CHAR = 'Z'
CHAR_SERIES = string.ascii_uppercase


def reverse(_list):
    return list(reversed(_list))


def succ(char):
    alphabet_to_num = dict(zip(CHAR_SERIES, [i for i in range(1, len(CHAR_SERIES) + 1)]))
    num_to_alphabet = {v: k for k, v in alphabet_to_num.items()}

    succ_index = alphabet_to_num[char] % len(CHAR_SERIES) + 1
    return num_to_alphabet[succ_index]


def succ_list(_list):
    # 繰り上がりして桁が増えた場合はONE_CHAR(==B)になる
    if len(_list) == 0:
        return [ONE_CHAR]
    # LAST_CHAR(==Z)の場合は繰り上がる
    elif _list[0] == LAST_CHAR:
        return [ZERO_CHAR] + succ_list(_list[1:])
    else:
        return [succ(_list[0])] + _list[1:]


def succ_code(previous_code):
    return ''.join(reverse(succ_list(reverse(list(previous_code)))))


def gen_code(init_code='AA', limit=10):
    code = init_code
    for _num in range(0, limit):
        yield code
        code = succ_code(code)

LIMIT = 10

for x in gen_code(init_code='ZX', limit=LIMIT):
    print(x)
```
いろいろな認証付きProxyの突破方法

大企業＆セキュリティに厳しい企業だとインターネットに出る際にプロキシ経由のパターンが多いため、よく使うやつをメモ。

### 基本
だいたいこの書式
```
http://${認証ユーザID}:${パスワード}@proxyのIPアドレス:ポート
```

#### とりあえず問答無用でいれる（curlとかはこれでいけるはず）
```
export HTTP_PROXY=http://${認証ユーザID}:${パスワード}@proxyのIPアドレス:ポート
export HTTPS_PROXY=http://${認証ユーザID}:${パスワード}@proxyのIPアドレス:ポート
```

#### yum
```/etc/yum.conf
proxy=http://${認証ユーザID}:${パスワード}@proxyのIPアドレス:ポート
```

#### apt
```/etc/apt/apt.conf
Acquire::http:Proxy "http://${認証ユーザID}:${パスワード}@proxyのIPアドレス:ポート"
Acquire::https::Proxy "http://${認証ユーザID}:${パスワード}@proxyのIPアドレス:ポート"
```

#### wget
```/etc/wgetrc
http_proxy=http://${認証ユーザID}:${パスワード}@proxyのIPアドレス:ポート
https_proxy=http://${認証ユーザID}:${パスワード}@proxyのIPアドレス:ポート
```

#### git
```
git config --global http.proxy http://${認証ユーザID}:${パスワード}@proxyのIPアドレス:ポート
```

#### npm
```
npm config set proxy http://${認証ユーザID}:${パスワード}@proxyのIPアドレス:ポート
```

#### pip
```
pip install xxxx --proxy=http://${認証ユーザID}:${パスワード}@proxyのIPアドレス:ポート
```

他にも載せたいものあれば追記します
【Wordpress】PHP Update Requiredの対応方法について（EC2に接続してアップグレードする）

# 前提
* AWSのEC2インスタンスで稼働しているお手製HTMLホームページを、Wordpressに移行した後に発生したエラーについて記載します。
    * Wordpressインストールするまでの流れを解説した前回の記事はこちら：[WordpressをEC2インスタンスにインストールする方法（Apacheのバーチャルホスト設定方法・Wordpress用DB作成方法も解説）](https://qiita.com/Ryo-0131/items/a6dab55ea5b54b6e10b7)

## PHP Update Requiredの警告
* PHP7.0であることに対して警告が表示されていることを確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/c0f92aa3-2a66-7faa-3d89-026e39280a0c.png)

* WordpressがインストールされているEC2インスタンスへ接続。
* 以下を実施して、PHP7.4にupgrade

```
sudo apt update
``` 

```
sudo apt dist-upgrade
```

```
sudo apt install php7.4
```

```
sudo apt install php-pear php7.4-curl php7.4-dev php7.4-gd php7.4-mbstring php7.4-zip php7.4-mysql php7.4-xml php7.4-fpm
```

* `cd /etc/apache2/mods-enabled/`で確認すると理由は不明だがphp7.0が有効になっていたので、以下を実施してPHP7.4を選択&PHP7.0を無効化してAPACHE再起動。

```
ls -l php*
sudo a2enmod
sudo a2dismod php7.0
sudo service apache2 restart
```

* Wordpress管理画面→先ほどまで表示されていた警告が消えたことを確認。

## 参考記事：
* [WordPress管理画面で「PHPの更新が必要です」への対応でOSも18.04にバージョンアップした](https://www.souichi.club/wordpress/ubuntu-version-up/)
* [PHPのバージョン変更方法＠2021](https://red-full-moon.com/php-version-change/)
M5Stack Core2: shutdown の使い方

M5Stack Core2 をプログラムでシャットダウンする方法です。
仕様
[CORE2 API System](http://docs.m5stack.com/en/api/core2/system)

>このプログラムを使えば、電源を落として、充電が出来ます。

## プログラム

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/51e9b67b-9775-3e09-8b4f-98e0674a9c7a.png)

```text:shutdown.ino
// ---------------------------------------------------------------
/*
	shutdown.ino

					Feb/13/2023
*/
// ---------------------------------------------------------------
#include <M5Core2.h>

// ---------------------------------------------------------------
void setup() {
	M5.begin();
	M5.Lcd.setBrightness(32);
	M5.Lcd.fillScreen(WHITE);
	delay(200);

	draw_five_circles();
	delay(500);
}						 


// ---------------------------------------------------------------
void draw_five_circles()
{
	int tt = 200;
	draw_circle_proc(60,120,BLUE);
	delay(tt);
	draw_circle_proc(160,120,BLACK);
	delay(tt);
	draw_circle_proc(260,120,RED);
	delay(tt);
	draw_circle_proc(110,170,YELLOW);
	delay(tt);
	draw_circle_proc(210,170,GREEN);
	delay(tt);
}

// ---------------------------------------------------------------
void draw_circle_proc(int xpos,int ypos,uint16_t color)
{
	for (int it=0; it< 10; it++)
		{
		int rr = 41 + it;
		M5.Lcd.drawCircle(xpos, ypos, rr, color);
		}
}

// ---------------------------------------------------------------
void loop()
{
	M5.Lcd.setTextColor(MAGENTA);
	M5.Lcd.setTextSize(5);
	M5.Lcd.clear(WHITE);
	draw_five_circles();
	M5.Lcd.drawString("TOKYO 2020",15,10,1);
	delay(3000);
	M5.Lcd.clear(WHITE);
	draw_five_circles();
	M5.Lcd.drawString("PARIS 2024",15,10,1);
	delay(3000);
	M5.shutdown();
}

// ---------------------------------------------------------------
```

シャットダウンは、
M5.shutdown(); で行います。
AWS CLIでワイルドカードを使ってS3のファイル削除


# S3の特定のファイルをまとめて削除

備忘
```
//dryrun
aws s3 rm s3://hoge/ --exclude '*' --include '*aiueo*' --recursive --dryrun|aws s3 cp - s3://hoge/rmlog.txt
aws s3 rm s3://hoge/ --exclude '*' --include '*aiueo*' --recursive --dryrun|tee rmlog.txt

//結果
aws s3 rm s3://hoge/ --exclude '*' --include '*aiueo*' --recursive|aws s3 cp - s3://hoge/rmlog.txt
aws s3 rm s3://hoge/ --exclude '*' --include '*aiueo*' --recursive|tee rmlog.txt

```

### 疑問
cloudshellのローカルに置いたファイルに対して`tee`すれば標準出力にもlogファイルにも両方書き込みにいけるが
`aws s3 cp`するとファイル出力のみで標準出力には表示されなくなってしまう…


### 公式Doc

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html

https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/index.html
2||x−2|-|x-4||=|5-x|「2017東京農業大学数学大問1」をwolframalphaとsympyでやってみた。

手計算は、テクニカルな方法でチャレンジしてみました。
**結論:場合分けが一番でした。**

オリジナル
場合分けです。

https://youtu.be/T_4cjqXBItM

# テクニカルな方法
一目で、x=1,9
2*2=|x-5|
次に、2と4の**中点3**が、私はわかりませんでした。

https://www.wolframalpha.com/input?i=%2B2%28%28x%E2%88%922%29-%284-x%29%29%3D%285-x%29&lang=ja

x = 17/5

https://www.wolframalpha.com/input?i=-2%28%28x%E2%88%922%29-%284-x%29%29%3D%285-x%29&lang=ja

x = 7/3

# 種明かし

||x−2|-|x-4||の値は、xが2以下の時、又は4以上の時、差?2です。
よって、5から2*2離れている点です。
数直線です。

2と4の間は、3が分岐点です？
2からxまでの距離と4からxまでの距離の差に、符号ありです。
いい方法があれば、教えて下さい。(多分、このページ後半で解決したつもり。)

# wolframで
プロットでます。いいですね。

https://www.wolframalpha.com/input?i=2%7C%7Cx%E2%88%922%7C-%7Cx-4%7C%7C%3D%7C5-x%7C&lang=ja

# sympyで
chromebook+linux+vscode+python+sympy+matplotlib(numpyみたい)で、できると思いませんでした。
普通は？windowsです。

```python
from sympy import *
x,y1,y2 = symbols("x y1 y2",real=True)
y1=2*abs(abs(x-2)-abs(x-4))
y2=      abs(5-x)
print("#",solve(Eq(y1,y2),x))
plot(y1,y2)
# [1, 7/3, 17/5, 9]
```
plotコマンドは、縦横比？異なります。
![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109698/738d31a1-6f56-8530-1405-608ea0174ff3.png)

# (追加)問題文について
・問題文の説明がステキです。
・|5-x|もステキですね。|x-5|じゃないところが。
・問題文(3) について、αもステキですね。
~~□<α<□+1でした。
私の気持ち的?には、以下でした。
△-1<α<△~~
小さい方から3番目?

# (追加)youtubeの説明について
1:07絶対値の中の全体のプラスマイナスの判断が簡単にできない。
5:30絶対値をもう一回はずさなければならない。
　
・東京農業大学の問題は、絶対値と絶対値の差。の絶対値
・青森公立大の問題は、　絶対値と絶対値の和。
|2x−5|+|2x+3|<10「21年 青森公立大 1(3)」5行で計算できました。
https://qiita.com/mrrclb48z/items/3cebc56caa04eb9f3795
和の方が簡単でした。3?が必要ありません。

# 参考
以下,ゆうどうです。
やっぱり?共通テスト。負の値の割り算。不等式。

https://qiita.com/mrrclb48z/items/01842623e9db5f4451b8

https://qiita.com/mrrclb48z/items/8bf98e8a79ab44bf0588

絶対値の式を使って、昨年の自転車君の直線を関数にする方法のアドバイスをよろしくお願いします。
https://www.deepl.com/ja/translator#ja/en/しつこくて申し訳ありません。

https://qiita.com/mrrclb48z/items/297442a71820732d3ea3
ChatGPTが解釈できるフォーマット/構文について

## どのようなフォーマットが扱えるか

### 一般的に広く使われている形式

エンジニアであれば誰でも知っているような有名なテキストフォーマットやプログラミング構文はほぼ扱うことができます。

 - json
 - csv
 - xml
 - yaml
 - toml
 - latex
 - mathml
 - markdown
 - html
 - css
 - svg
 - 各種有名なプログラミング言語

### GitHubなどに十分な訓練データが提供されている形式

標準化されて誰でも知っているレベルでなくとも、GitHubなどに十分な訓練データが提供されている形式ならば扱うことができます。つまり利用が広まっているOSSやサービスの独自形式のフォーマットなどです。ただし、一般的に知られているようなフォーマットと比べるとやや精度を欠くことがあります。

 - [Mermaid](https://mermaid.js.org/) : テキストでダイアグラムを記述する言語
 - [PlantUML](https://plantuml.com/ja/sequence-diagram) : テキストでダイアグラムを記述する言語
 - ApacheやNginxなど有名ミドルウェアのログファイル : 構造化されていない形式でもある程度推測してフィールドを認識します。

### プロンプト内で教えたフォーマット

ChatGPT が訓練データが存在するフォーマットしか扱えないかというとそうではありません。プロンプト内で独自のフォーマット(ルール)を教えることで、独自フォーマットも理解するようになります。プロンプト内で新しい知識を教えることを in-context learning と呼ばれます。

in-context learning により独自形式を教えて独自形式をJSONに変換する例

```
Q: A(name->"foo", age=16, B(name->"bar", age=22))
A: {"A": {"name": "foo", age:16, B:{"name":"bar", "age":22}}

Q:AA(size=4, DD(deko="boko"))
A:
```

ChatGPTの回答

```
{"AA": {"size": 4, "DD": {"deko": "boko"}}}
```

このように、この世に存在しないフォーマットでも、例示などにより前提知識を覚えさせることで、学習して使いこなすことができるようになります。

## テキストとして表現できればいい

ChatGPTはJPEGやPNGなどのバイナリデータは扱えません。ですから、画像や映像など一般的にバイナリで提供されるものは扱えないとすぐに考えてしまいますが、一般的にバイナリなものでもテキストとして表現できないか考えることで道が開ける可能性があります。MermaidやSVG(SVGは中身はXML)が良い例です。

「星型のアイコンが欲しい。」と考えた時に、画像だからChatGPTでは使えない、ということはありません。
星型のSVGを求めることもできますし、HTML Canvasで星形を描くJavaScriptを生成することもできます。

## 最強のコンバーター(* to * converter)

ChatGPTは構造やフィールドの意味を理解してくれますし、プログラミング言語も理解します。そして、各種フォーマットを自在に変換することができます。ある意味で、ChatGPTは最強のコンバーター(* to * converter)です。

プログラミング言語を書き換えることもできますし、JSON <=> Toml <=> Yaml <=> XML マッピング可能な形式であればなんでも変換できます。もちろん、独自形式をプロンプトで教えれば独自形式も各種フォーマットやプログラミング言語に変換することができます。

## まとめ

 - ChatGPT は十分な訓練データがインターネットに存在するフォーマットはなんでも扱える
 - プロンプト内で教えることで、独自の形式も理解し、さまざまな形式に変換させることができる
 - 一般的にバイナリ形式のデータもテキストで表現できないか考えることが大事
 - ChatGPT は * to * を実現する最強のコンバーター

## その他のChatGPT関連記事

https://qiita.com/devneko/items/4b3bc01cfa4439bfa36f

https://qiita.com/devneko/items/0dc9fd8b37419d9e369c