OmniAICreator/Qiita-1.07M huggingface dataset:
PLC Mov命令について

# はじめに

PLC（プログラマブルロジックコントローラ）で使用されるMov（データ転送）命令についてまとめます。動作確認はGX Works3行っています。

# 基本的な使用例

`MOV`命令でデバイス`D10`に数値`1`を転送する。
ダブルワードの場合は`DMOV`を使用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343142/db99e865-e7b6-0fa3-4bbb-a603cb56c554.png)

# 16進数を転送する

16進数`H11`(10進数:17）のデータ転送例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343142/7dd0704e-e737-36fa-5cb9-e0d9bd3eb2b5.png)

# ビットデータをまとめて転送

`K1M0`はM0～M3までの4点分のビットデータを扱うという意味です。
`K2M0`とするとM0～M7までの8点分のビットデータですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343142/f6e58915-e6a6-1eb3-79a9-c6fc2fc55505.png)


# 文字列を転送する

`$MOV`を使います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343142/bb3ca55a-a203-8399-517a-9633ec4de653.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343142/1813b47e-44da-cac1-8847-a2fa9f416bf2.png)

# 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343142/e9de5e4f-2764-417b-f9c6-8cbecca1367b.png)

# BMOV(一括転送)

D20から4点(D20～D23)のデータをD25～D28へ転送。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343142/97c35610-a0bc-908c-cc9f-74eb93f705b2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343142/ee2e2df1-78da-2b16-17d0-a27c7be9f44a.png)

# FMOV(一括転送)

D30から10点(D30～D39)すべてに数値`5`を転送。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343142/0e8c98b4-1456-b380-be49-a5461b547d40.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343142/0bf55349-5650-2ff1-26d1-72a7bcc23b3f.png)
【Rails + Heroku】PostgreSQLからJawsDB MySQLへ移行する

## 概要
HerokuのPostgreSQLアドオンは費用が高めです。そこで、よりコスト効率の良いMySQLのJawsDBに移行する方法を紹介します。

## ローカル環境の設定変更
主に修正するファイルは`Gemfile`と`config/database.yml`です。

### ファイルの修正手順
- **Gemfile**: `pg` gemをコメントアウトし（念のため保持）、`gem "mysql2", "~> 0.5"`を追加します。ここで`"~> 0.5"`を指定する理由は、新規に`rails new -d mysql`で作成したプロジェクトに同じバージョンが指定されていたためです。

- **database.yml**: MySQLを使うために、新規に作成したRailsプロジェクトの設定を参考に変更します。違いはdefaultの設定だけだったのでそこだけ変更します。

  変更前：
  ```yaml
  default: &default
    adapter: postgresql
    encoding: unicode
    pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  ```

  変更後：
  ```yaml
  default: &default
    adapter: mysql2
    encoding: utf8mb4
    pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
    username: root
    password:
    socket: /tmp/mysql.sock
  ```

その後、`rails db:create`を実行し、データベースを作成します。その後、`rails db:migrate`でマイグレーションを実行し、`rails s`でサーバーを起動します。正常に立ち上がれば設定は成功です。

### エラー処理
もし以下のようなエラーが発生した場合は、前のインスタンスがまだ稼働している可能性があります。この場合は、`lsof -i :3000`でプロセスIDを調べ、`kill -9 [PID]`で該当プロセスを終了させます。

```
Address already in use - bind(2) for "127.0.0.1" port 3000 (Errno::EADDRINUSE)
```

## データの削除
MySQLでの動作が確認できたら、PostgreSQLのデータを削除します。私の場合は個人開発で利用者がほとんどいないため、安心してデータを削除しました。削除するには、設定ファイルを元に戻した後、`rails db:drop`でデータベースを削除しました。

## Herokuでの設定
次に、Herokuでの設定を行います。

1. HerokuのアドオンセクションでJawsDBを探し、インストールします。
   ![jawsDB-addon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/849608/a0ce9f45-6a5b-3059-2add-a93833120de6.png)

2. 既存のPostgreSQLアドオンを削除します。
   ![delete-heroku-addon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/849608/c981b6f3-0c97-24b8-70a7-7d15998c48c3.png)

   JawsDBが正常にインストールされたことを確認します。
   ![installed-jawsDB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/849608/227ea657-9e08-afee-4607-d2229d4d61e9.png)

3. 変更をデプロイ

最後に変更をデプロイします。以下のようなログが表示されれば、データベースの変更が適用されたことになります。
   ![deploy-pg-mysql.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/849608/d636e6f0-e427-47fc-aa26-785c6cff8a71.png)

4. 実際にアプリケーションを起動して動作を確認し、問題がなければ完了です。

## 追記
デプロイした後、`heroku run rake db:migrate`を実行するとエラーになります。この問題を解決するためには、以下の2点を修正する必要があります。

### 1. `database.yml`のproduction設定の変更

`database.yml`ファイルのproductionセクションにおいて、`JAWSDB_URL`環境変数からデータベースのURLを取得するように設定します。これにより、データベース名やパスワードなどの情報が一括で設定されます。

```yaml
production:
  <<: *default
  url: <%= ENV['JAWSDB_URL'] %>
```

### 2. Herokuの環境変数設定の変更

Herokuの設定を`heroku config`で確認すると、`JAWSDB_URL`環境変数が`mysql:~~~`となっていることが分かります。Railsでは`mysql2`アダプターを使用しているため、このURLを`mysql2`プロトコルに変更する必要があります。これは、既存のURLをコピーし、プロトコル部分に`2`を付け加えることで行います。以下のコマンドを実行します。

```bash
heroku config:set JAWSDB_URL="mysql2://~~~"
```

これらの変更を行うことで、Heroku本番環境でのマイグレーションが正常に機能するはずです。

## 参考資料

https://qiita.com/shizimi_50/items/3f0ca56649dc8f968267
LinkedHashMap 基本メソッド

LinkedHashMap
キーと値のペアを要素とした集まり。

※インポートが必要です。
import java.util.LinkedHashMap;

# 宣言
ジェネリックス（<>）に入れるデータ型がカンマ区切りで２種類あります。
1つ目がキーのデータ型、
２つ目がキーに紐づく値のデータ型を設定します。

```ruby:宣言
LinkedHashMap<Integer, String> lunchMap = new LinkedHashMap<>();
```

# ペア(キーと値）の追加
`put(キー,値)`
キーは重複は許可されません。
同じキーを登録しようとすると、後から足した方に上書きされます。
```ruby:put(キー,値)
lunchMap.put("牛丼", 800);
lunchMap.put("カレー", 700);
lunchMap.put("ハンバーガー", 500);
lunchMap.put("牛丼", 850); /* 牛丼=800 が上書きされます*/
System.out.println(lunchMap);
/* {牛丼=850, カレー=700, ハンバーガー=500} */
```

# キーからペアの値を取得
`get(キー名)`
存在しないキーを設定した場合はnullが返ってくる。
```ruby:get(キー名)
lunchMap.put("牛丼", 800);
lunchMap.put("カレー", 700);
lunchMap.put("ハンバーガー", 500);
System.out.println(lunchMap.get("牛丼"));
/*800*/
System.out.println(lunchMap.get("うどん"));
/*null*/
```

# ペアの数を取得
`size()`
```ruby:size()
lunchMap.put("牛丼", 800);
lunchMap.put("カレー", 700);
lunchMap.put("ハンバーガー", 500);
System.out.println(lunchMap.size());
/*3*/
```
# ペア（キー）の有無を確認
`containsKey(キー名)`

```ruby:containsKey()
lunchMap.put("牛丼", 800);
lunchMap.put("カレー", 700);
lunchMap.put("ハンバーガー", 500);
System.out.println(lunchMap.containsKey("カレー"));
/*true*/
System.out.println(lunchMap.containsKey("うどん"));
/*false*/
```

# ペアの削除
`remove(キー名)`

```ruby:remove(キー名)
lunchMap.put("牛丼", 800);
lunchMap.put("カレー", 700);
lunchMap.put("ハンバーガー", 500);

lunchMap.remove("ハンバーガー");

System.out.println(lunchMap);
/*{牛丼=800, カレー=700}*/
```

# 全てのペアの削除
`clear()`
```ruby:clear()
lunchMap.put("牛丼", 800);
lunchMap.put("カレー", 700);
lunchMap.put("ハンバーガー", 500);

lunchMap.clear();

System.out.println(lunchMap);
/*{}*/
```

# 空っぽかどうかの確認
`isEmpty()`
```ruby:clear()
lunchMap.clear();
System.out.println(lunchMap.isEmpty());
/*{true}*/
```


# forEachでペアを全て出力
`forEach`
```ruby:clear()
lunchMap.put("牛丼", 800);
lunchMap.put("カレー", 700);
lunchMap.put("ハンバーガー", 500);
lunchMap.forEach((key, value) -> System.out.println(key + ":" + value));
/*
牛丼:800
カレー:700
ハンバーガー:500
*/
```

# 拡張for文でペアを全て出力
keyとvalueを、keySetメソッドとgetメソッドでそれぞれ定義します。
データ型に注意しましょう。

`拡張for`
```ruby:拡張for
lunchMap.put("牛丼", 800);
lunchMap.put("カレー", 700);
lunchMap.put("ハンバーガー", 500);
for (String key : lunchMap.keySet()){
    Integer value = lunchMap.get(key);
    System.out.println(key + ":" + value);
}
/*
牛丼:800
カレー:700
ハンバーガー:500
*/
```
そのシリアルコードよこせ

# そのシリアルコードくれよ
みなさんは原神というゲームをやってますか？
やってるいらっしゃる方がいるなら下の画像のシリアルコードについては知ってると思います。（下の画像の赤丸で囲ったところです）
![serial_code.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557059/016dd685-207c-6867-0875-e47b79ba06db.png)

これわざわざ手打ちするのはめんどうですよね？
配信とゲームを行き来して確認するのはめんどうですよね？
なんならそれ以外のコピペできないやつを引っ張ってくるのもめんどくさいですよね？

**Tesseract OCR使いましょう**

# Tesseract OCR
早速ですがコード紹介
```python
from PIL import ImageGrab
import os,pyocr,pyperclip
def get_tool():
    os.environ["PATH"]+=";C:\Program Files\Tesseract-OCR"
    tools=pyocr.get_available_tools()
    tool=tools[0]
    return tool

def get_img_fromclip():
    try:
        img=ImageGrab.grabclipboard()
    except OSError:
        return None
    return img
if __name__ == "__main__":
    last_img=get_img_fromclip()
    tool=get_tool()
    while True:
        img = get_img_fromclip()
        if img is None or img == last_img:
            pass
        else:
            s = tool.image_to_string(
                img,
                lang='jpn+eng',
                builder=pyocr.builders.TextBuilder(tesseract_layout=6)
            )
            print(s)
            pyperclip.copy(s)
            last_img=img
```

処理としては

1.スクショを取る
2.それをプログラムが検知する
3.*OCR*する
4.その結果をクリップボードに格納する

こうするだけで簡単に画像をテキストにコピペできます。
（数年前に誰かが既に作ってそう）

# 余談
```python
os.environ["PATH"]+=";C:\Program Files\Tesseract-OCR"
```
Q:これなに？
A:ほかのアプリケーションの依存関係がおかしくなるからTesseractのパスは実行時のみに入れるようにしてます

```python
except OSError:
```

Q:これは？
A：クリップボードが空っぽだとエラーだすのでそれの回避

# 終わり
日本語対象にやると謎の空白が入りまくるのでそこらへんの修正は必要かもしれないです。まぁシリアルコードにそんなものはありませんが。

（いやこんな記事をAdvent Calenderに入れてしまってまじでごめんなさい）
エンジニア向けイベントの盛り上げに使えそうなリアルタイムアンケートツール　イマキクのススメ

# はじめに
　マナビDX Questの受講がきっかけで、プログラミングやIT分野の勉強をしている方たちの輪に飛び込みました。そこで驚いたのが、自主的な勉強会の数が圧倒的に多いことです。

　ただ、ZoomやTeamsのコメント欄で質問や感想が入るのですが、どうしても特定の人のコメントが多くなってしまい、見るだけの層が多いのが気になっていました。(熱量が高い人の可視化もできるので、もちろんそういった方法も素敵だと思います)

　先日参加したハイブリッドイベントで、「イマキク」というリアルタイムアンケートツールが使われており、匿名で集まる人が多い勉強会において有用だったので、こちらの記事にまとめます。

# イマキクとは

　スマホからアクセスできる、アプリ不要のリアルタイムアンケートツールです。
主催者側はイマキク、参加者側は同じサービス内のスグキクのページを使用してコメントします。

https://imakiku.com/ja/

# メリット・デメリット

## メリット
* 会場＋オンラインのハイブリッドイベントでも、同じ場所にコメントを集約できる
* 匿名なので、初心者が気軽に質問・コメントしやすい
* コメントごとに参加者が押したいいねの数が多いものから人気順をソートできる→会場内で興味が集まっているコメントが分かる
* 参加者が好きなときに質問・コメントできる

## デメリット
* スマホからなので、長文の回答には向かない

# まとめ

積極的なコメントから有益な議論が始まることは多いです。特に大人数の参加者がいる場合に効果を発揮するのではないでしょうか。

# 参考リンク

https://imakiku.com/ja/
ソフトウェアを製造するのではなくデザインする時代に

私たちエンジニアはなにかを生み出すのが好きでした。
何か眼の前のものを作ることが好きでした。
凄まじい技術の進歩にふれるのがワクワクしました。

今までもこれからも根本としてはソフトウェアエンジニアの皆さんが初心として持っていた心になるかと思います。

技術の進歩は凄まじく、新しいモノを作れば・より良い物にしていけば売れる時代と聞いています。
ただ昨今、AIネイティブ時代において、人に置き換えられる仕事はどんどん置き換えられています。
ロボティクスやソフトウェアを生み出すのは現状エンジニアですが、ただ我々すらも仕事が取られるときが来るかもしれません。

なんだか凄まじいことを語る記事に思うかもしれませんが、きっかけと内容はほんのちょっとしたことです。

# 身近なAIサービスの到来

## 副操縦士の登場
2022年。やつが現れました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664827/21f44b51-db1a-47b4-e42f-6c54c2dc2240.png)

やつは魔法でコーディングします。
使ってみると思った以上です。なんでこやつはこのプロジェクトの変数・関数名ルールをあたかも知っているかのように提示してくるんだ、、、

例えば、、、ポケモンの一覧を出す関数を作ってみます。
以下の様にコメントを入力すると、、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664827/eaa1b879-d702-5a33-0cfa-e1e5a30b7b19.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664827/f578e8eb-586a-e65f-2ae1-e762ce485b28.png)


勝手にここまで書いてくれます。もっと複雑な処理も一瞬で書いてくれます。

## ChatGPTの登場
こちらももう有名ですよね。
最近は業務効率化の範囲を超えて、何もかもとりあえずGPTさんに書かせる方が増えてきました。
いいんです。いいんですけどね。。。
こちらの想いについては後述します。

# 人間ができること
AIサービスがたくさん出てきており、ここまで正確にコーディングができるようになってきました。この発展スピードですと、我々エンジニアの中でもプログラマーは仕事を失う方もそろそろ出てきてしまうかもしれません。

その中で人間はまだ機械には真似できない得意なことがあります。

それは

ゼロ→イチを生み出す能力（アート、デザイン）です。

# ひとは考えるのを諦めはじめている
危ない哲学になってきている気がしますが...w
もちろん効率化・参考としてAIを利活用することは、生産性を上げる手段の一つになっているため、顧客利益の最大化・目的達成の手段としてはよいと思っています。完全に否定しているわけではありません。

これらを頼ることが「あたり前」になってしまうと、AIファーストになってしまい、人間が考えるという思考を忘れてしまう。という持論を持っています。

何度もいいますが、目的達成できればいいでしょ系の方々の考えは最もです。

ただ、人が考えるときにAIに投げることが当たり前になってしまうことによって、機械ができなかったゼロ→イチを生み出す能力は、人間でさえもできなくなってしまう未来が来てしまうのではないかと危惧しています。
※ あくまでも一個人の考えです。あくまでも（大事）

AIと仲間になるのはいいですが、相棒になってはいけないかなと思っています。

# ソフトウェアは顧客に寄り添って最適なサービスのつなぎ合わせ（デザイン）するように
まとめにはいっていきますが、ここまでAIの素晴らしさと脅威（褒め言葉）を紹介してまいりました。技術屋さんであれば当たり前のように知っていたり、考え方が異なる方もいらっしゃると思いますが、一個人の考えとして捉えていただけたらと思います。

最後に、ソフトウェアエンジニアにフォーカスしてみます。AIネイティブ時代であり、エンジニアや高度なITスキルを持っていない人々でもITを知らないといけない時代になってきました。

我々ソフトウェアエンジニアもプログラミングは少しずつAI（先程紹介したCopilot等）や便利なフレームワークによりコーディングするボリュームや機会は減るのかなと感じています。

そういった中で我々ソフトウェアエンジニアが生涯生き残っていくには捉え方を変える必要があるのかもしれません。
下記の記事の「ソーシャル・イノベーションに必要とされるスキル」の章では、オードリー・タン氏がプログラミングのことを台湾ではソフトウェアデザインと呼ぶと仰っています。

ぜひ内容を見ていただきたいですが、我々のしごとが人を相手するものであり、デザインというチカラを持つことでAIと共に歩む未来を実現できるかと思っております。

https://sakumaga.sakura.ad.jp/entry/2020/10/21/120000
JavaScriptでlower_bound(),upper_bound()

AtCoder Beginner Contest 248
[D - Range Count Query](https://atcoder.jp/contests/abc248/tasks/abc248_d)
自作の二分探索の結果を場合分けして解答したが
[提出結果1](https://atcoder.jp/contests/abc248/submissions/48480948)

そもそもlower_boud()とupper_bound()があれば場合分けをする必要がないかつ
解答コードを少し改造すれば両方とも実装可能だったのでここに記す

```js:lower_bound()
function lower_bound(target, arr) {
  let left = -1
  let right = arr.length + 1

  while (right - left > 1) {
    let mid = (right + left) / 2
    if ((right + left) % 2 !== 0) {
      mid = (right + left + 1) / 2
    }
    if (target === arr[mid]) {
      return mid
    }
    if (target > arr[mid]) {
      left = mid
    } else {
      right = mid
    }
  }
  return right
}
```

```js:upper_bound()
function upper_bound(target, arr) {
  let left = -1
  let right = arr.length + 1

  while (right - left > 1) {
    let mid = (right + left) / 2
    if ((right + left) % 2 !== 0) {
      mid = (right + left + 1) / 2
    }
    if (target === arr[mid]) {
      return mid + 1
    }
    if (target > arr[mid]) {
      left = mid
    } else {
      right = mid
    }
  }
  return right
}
```

ソート済みの配列に対してtarget以上の数が初めて現れる場所はlower_bound()
ソート済みの配列に対してtargetより大きい数が初めて現れる場所はupper_bound()

使用した結果↓
[提出結果2](https://atcoder.jp/contests/abc248/submissions/48480961)
Vector SearchでOperation一覧を見る方法

# コンソールからできるようになった(2024/02/06)
GCPコンソール上から各インデックスに紐付くオペレーションの一覧が見られるようになった。
具体的には以下の手順。
1. VertexAIの「ベクトル検索」画面を開く
1. オペレーションを見たいインデックスの詳細画面を開く
1. 画面下部の「アクティビティ」を選択する

# 動機
gcloudコマンドでVectorSearchのインデックス作成とか更新とかをやると、operation IDが払いだされる。処理が成功したかどうかはこのIDを使って `gcloud ai operations describe ...` して確認する。
ただ、処理を開始したタイミングでIDを控えておかないと、gcloudコマンド経由では**二度と確認できない**。

そんなことある？一覧できるだろ？と思って調べてみた。

# 結論
Vertex AIのREST APIを叩けばできる。
https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.operations/list

叩く先は `https://<リージョン>-aiplatform.googleapis.com/v1/projects/<プロジェクト名 or プロジェクト番号>/locations/<リージョン>/indexes/<インデックスID>/operations`。

こいつを叩くと、IDの一覧だけでなく、operation各々の内容も出てくるので、特定IDの結果だけ特に取り出したい！という需要でなければ、わざわざgcloudを使わないでこのAPIだけ叩いていればいいのかもしれない。

# 具体例
以下のようなインデックスを仮定する。
- プロジェクト名: `vectorsearch-test-project`
- リージョン: `asia-northeast1`
- ID: `123456789`

このとき、このインデックスに対するoperationの一覧を表示するには以下のコマンドを実行する。

```bash
$ curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \
https://asia-northeast1-aiplatform.googleapis.com/v1/projects/vectorsearch-test-project/locations/asia-northeast1/indexes/123456789/operations
```

# 愚痴
GCP、gcloudとコンソールとREST APIでそれぞれできることが違うのなんとかして……
開発部の教育兼採用試験の振り返り

## はじめに
12月よりDX課から開発部の教育兼採用試験(以下「花田チャレンジ」と称する)を経て、開発部に異動してきた者です。
この記事では花田チャレンジを振り返ります。

:::note warn
花田チャレンジを受けた側の振り返りであり、評価した者の振り返りではありません。
:::

## 花田チャレンジ概要
目標: タスクを1箇所に集約できるようなフォームの作成。(バックエンドがメイン)

背景: DX課では事業部側から日々依頼を受けている。しかし依頼の受け口が口頭、SlackのDM、スレッドと複数あるため、依頼が散らばり依頼の進捗状況や受けている依頼の量が不透明になってしまうという問題が発生している。

期間: 1ヶ月(2023年10月2日~2023年10月27日)

開発環境:
バックエンド:Golang
フロントエンド:TypeScript,React,
インフラ: Cloud Run, Cloud SQL,Artifact Registry,Firebase
その他: クリーンアーキテクチャ、軽量DDD

## 1日の流れ
### 課題説明 (30m)
Clean Architecture、DBのインデックスの適切な貼り方、Cloud Run など、その日のペアプロで使う技術・知識を提示して頂きます。
### 調査 (5h30m)
課題説明で提示された技術・知識について調べます。
### ペアプロの事前準備 (0~1h)
ペアプロの前に済ませておく必要のある作業があれば終わらせておきます。(ローカルにDockerでDB立てて、データ保存できるようにしておくなど)

### ペアプロ(1h)
コードを書きます。ただ実装するだけではなく、なぜその実装にしたのかを説明しながら進めていきます。

### 後始末 (0~30m)
コードを整理して GitHub へ push。

## 1週目
依頼、ユーザに関わるhandler,usecase,repositoryを作成し依頼の作成・取得できるようにする。

## 2週目
依頼に対して担当者を追加・編集できるようにする。
Cloud Run 上でアプリを動かせるようにする。

## 3週目
firebase を使い、認証機能をつける。
今まで作ってきたエンドポイントをtoken必須のプライベートAPIにする。
テンプレートを使い画面を作成し、バックエンドと繋ぐ。

## 4週目
リファクタ、抜けていたテストの作成、エラーの修正など。

## 花田チャレンジを通してより明確になった自分の弱み
### モデリング
依頼、ユーザのモデリングを行う円滑に行うことができませんでした。例えば、ユーザの役割を依頼者と担当者で分けたい時にユーザモデルにroleを持たせるべきか、ユーザモデルを継承した依頼者モデルと担当者モデルをそれぞれ作るべきか迷いました。モデリングする時に指針となる経験や知識がなかった事が原因だと考えているので、UMLモデリングを学習しようと思います。

### DB設計
作成した中間テーブルが[SQLアンチパターン](https://www.amazon.co.jp/SQL%E3%82%A2%E3%83%B3%E3%83%81%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3-Bill-Karwin/dp/4873115892)で紹介されているアンチパターンの1つである、とりあえずIDというアンチパターンになっていました。知識不足はもちろんのこと、テーブルを作る目的を意識しせずに作業してしまったいたことが原因です。技術は目的を達成する手段だということを忘れずに開発します。

### フロントエンド・Webの基礎知識
花田チャレンジでは画面を開発部の方が作成した既存のReactテンプレートを使って実装しました。そのため、フロントエンドはあまり理解できていません。個人で、同じようなフォームをテンプレートを使わずに作ってみようと思います。
フロントエンドとバックエンドを連携に、CORSやJavaScript の非同期処理の理解の浅さが原因で時間がかかってしまいました。こちらも再度学習が必要です。

### ネットワーク、クラウド
アプリを公開するために Google Cloud, Firebase を使いました。どちらも初めて使うサービスこともあり、苦戦しました。ただ、原因を振り返ってみるとこれらのサービス特有の知識が不足していたというよりは、一般的なネットワーク・クラウドの知識のなさが原因でした。

### 記録
うまくできた箇所・できなかった箇所や所感などの記録がなく、この記事を書くときに苦労しました。記憶力が良くないにも関わらず、記録をしないとこのような事が起こるので今後積極的にメモを取ります🙇

## 所感
自分の弱みを炙り出す事ができ、いい経験になりました。詰まった箇所を振り返ってみると、知識としては知っていたけど実際に手を動かしたことがない箇所が多いことがわかりました。これからはinputの学習よりもoutputの学習の比率を上げていこうと思います。
【Swift5.9】JSONDecoderとJSONSerializationのデコードの違い

# はじめに
この記事では２つのJSONデコード処理の書き方を説明していきます。
JSONDecoderとJSONSerializationでは処理の書き方などが異なるため
行いたい実装や環境によって適切に選ぶ必要があります。

# 目次
・JSONDecodeについて
・JSONSerializationについて
・まとめ

# 「JSONDecoder」について
### ● 概要
JSONDecoderはSwift 4以降に導入されたクラスで、Codableプロトコルに準拠した型のオブジェクトとJSONデータの相互変換を行います。
JSONDecoderはプロトコルを作成することで、JSONデータから取得した値をSwiftオブジェクトの対応するプロパティに手動で代入する必要がないためJSONSerializationのデコードより安全性の高いコードを書くことができます。

### ●利用に適しているとき
1. Swift 4以降のバージョンの場合
・JSONDecoderはCodableプロトコルに準拠した型を定義することで、型安全性を確保し冗長なデコードコードを削減することができます。
・CodingKeysを使用してプロパティとJSONキーの対応を指定することで、自動的なデコード処理が行われ手動での代入が不要になります。

## JSONDecoderのデコード
```swift
//jsonのデータ
let jsonString: String = "{\"id\":1, \"name\":\"kansae\"}"

//JSONとの対応関係を指定するためのプロトコル
struct User: Codable {
    var identifier: Int
    var name: String

    //プロパティの値とjsonで取得する値が違う場合CodingKeyを使用して対応させることができる
    enum CodingKeys: String, CodingKey {
        case identifier = "id"
        case name
    }
}

if let jsonData = jsonString.data(using: .utf8) {
    do {
        let user = try JSONDecoder().decode(User.self, from: jsonData)
        let name = person.name //直接Stringを入力する必要がないため安全性が高くなる
        let age = person.age
    } catch {
        // デコード失敗した際の処理を書く
    }
}
```

# 「JSONSerialization」について
※今回はデコードの処理のみの解説になります。

### ● 概要
JSONSerializationは、Foundationフレームワークに含まれるクラスで、JSONデータのデコード（JSONデータからSwiftオブジェクトの変換）を行います。
JSONSerializationでは配列や辞書型でデコードされるため、データにアクセスする際に値のキーを手動で打つ必要がありヒューマンエラーを引き起こしやすくなります。

### ●利用に適しているとき
1. データ構造がシンプルな場合
   ・JSONデータが単純で、階層が浅い場合
1. 古いiOSバージョンのサポートが必要な場合
 ・JSONDecodeはSwift 4以降の機能になるため、それ以前のバージョンを使用する場合はJSONSerializationを使用します。

## JSONSerializationのデコード

```swift
//jsonのデータ
let jsonString: String = "{\"id\":1, \"name\":\"kansae\"}"

if let jsonData = jsonString.data(using: .utf8) {
    do {
        if let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: .allowFragments) as? [String: Any] {
            let id = jsonObject["id"] as? Int// ヒューマンエラーを起こしやすい箇所
            let name = jsonObject["name"] as? String 
        }
    } catch {
        // デコード失敗
        // エラーハンドリング
    }
}
```

# まとめ
Objective-cからswift5.0にコードを移行する際にJSONDecoderという新しい機能があることを知ったため、今回記事にまとめさせていただきました。
JSONDecoderとJSONSerializationの使い方に迷っている方の参考になればと思います。
また、こうするとより良いなど意見ありましたらコメントお願いします。
日本語LLM（大規模言語モデル）一覧

## ELYZA
https://note.com/elyza/n/na405acaca130
- ELYZA-japanese-Llama-2-7b
基本モデル
- ELYZA-japanese-Llama-2-7b-fast
語彙最適化モデル
- ELYZA-japanese-Llama-2-7b-instruct
チャット型
- ELYZA-japanese-Llama-2-7b-fast-instruct
語彙最適化チャット型モデル

## Stable LM
https://ja.stability.ai/blog/japanese-stable-lm-3b-4e1tjapanese-stable-lm-gamma-7b

https://ja.stability.ai/blog/japanese-stable-lm-beta

-  Japanese Stable LM 3B-4E1T Base
3B基本モデル
-  Japanese Stable LM 3B-4E1T Instruct
チャット型3B言語モデル
-  Japanese Stable LM Base Gamma 7B
7B基本モデル
-  Japanese Stable LM Instruct Gamma 7B
チャット型7B言語モデル
-  Japanese Stable LM Base Beta 7B
llama2増強基本モデル（7B）
-  Japanese Stable LM Base Beta 70B
llama2増強基本モデル（70B）
-  Japanese Stable LM Instruct Beta 7B
llama2増強チャット型モデル（7B）
-  Japanese Stable LM Instruct Beta 70B
llama2増強チャット型モデル（70B）
-  Japanese Stable LM JA-Vocab Base Beta 7B
llama2増強語彙追加チャット型モデル（7B）
-  Japanese Stable LM JA-Vocab Instruct Beta 7B
llama2増強語彙追加チャット型モデル（7B）

## Qwen
- Qwen-7B

### 参考資料
https://weel.co.jp/media/llm-comparison#index_id5
【21日目】自動運転AIチャレンジの取り組み方について

この記事は筆者オンリーの[Advent Calendar 2023](https://qiita.com/advent-calendar/2023/aichallenge_racing_for_mas)21日目の記事です。  

自動運転AIチャレンジについて、前回大会で初参加でした。
前回大会を参考に、自動運転AIチャレンジに初めて参加する方向けにざっくり記事を書いてみました。

# ざっくりやるといいこと
## パラメータチューニング
本家のリポジトリでビルドしたものをそのまま使用するケースです。
yamlファイルで設定する初期パラメータが設定されています。
これを変更することで
自動運転やってみたいけど制御の仕方よくわからない、モジュールの作り方よくわからない、ROS2、Autowareの仕組みわからないという人はこちらがおすすめです。
Slackで質問すると、運営の方がたぶんこのへんのパラメータチューニングしたらいいんじゃない？みたいなヒントをくれます。
まずはcontrolモジュール、planningモジュールのパラメータチューニングをトライしてみましょう。

## OSS連携
結構難易度は高いですが、他のOSSを参考に自作モジュールを作る、あるいは連携できるように変更する方法です。
pythonroboticsをはじめ制御の方法についてはネットに転がっています。
こちらを参考に自作するという手もあります。
制御の勉強になりますので初心者の方でも時間があればチャレンジしてみましょう。

#参考
前回大会では @h_bog さんの記事を参考にいろいろ勉強させてもらいました。まずは関連記事を見てみて感触をつかんでいただければよいかなあと思います。
ネチケット

[インターネット老人会の魔法書 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/ancient-internet) の8日目の記事です。

# ネチケットとは

【意味】 ネットワーク＋エチケットの造語。インターネットやEメールを使用する上で遵守すべきエチケット、マナーのこと。

# この言葉が生まれた経緯

日本でインターネットが流行り始めた創世記、まだドコモのiモードもなかった時代はインターネットは一部のパソコンオタクの趣味でしか使われておらず、いろんな規制が緩く無法地帯でした。

今ではインターネット上の書き込みで名誉毀損で訴えられたりするのも珍しくありませんが、当時はスマイリーキクチさんの騒動でもわかるようにそういう行為があっても警察でも相手にしてくれず、相手がわからないので訴訟も起こせず、誹謗中傷を書いたり、個人情報を書いたり、掲示板を荒らしたりということが横行しました。

誰が最初に言い始めたのかはわかりませんが、「インターネットの世界でもオフラインの世界と同様にルールとマナーを守ろう」という思いがユーザの間に広まり、自然と生まれたんじゃないかと思っています。

# 最近は

この言葉あまり聞かないですね。
行儀が悪い人を懲らしめる法律とか判例は増えましたが、治安の悪さはその時とあまり変わっていない気がします。
Manage Products, Prices, Quotes, and Orders



[Manage Products, Prices, Quotes, and Orders](https://trailhead.salesforce.com/content/learn/projects/manage-products-prices-quotes-orders/control-access-price-books-products)

+ [注文の価格表として「非営利」をクリックすると、非営利の価格にアクセスしても、選択できる製品がありませんでした。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000QM0Sa)


:::note
To solve the problem, I deleted the contract, which in turn deleted the order. I then created a new contract, making sure to choose USD as the contract's currency and that of the order. The previous contract and order I used were not in USD. After doing this, I got to see the product in USD. The summary is that the contract, order and product have to have the same currency.

この問題を解決するために、契約を削除すると、注文も削除されました。次に、新しい契約を作成し、契約の通貨と注文の通貨として必ず USD を選択しました。私が使用した以前の契約と注文は米ドルではありませんでした。これを実行すると、商品が米ドルで表示されるようになりました。要約すると、契約、注文、商品は同じ通貨でなければならないということです。
:::

# Control Access to Price Books and Products

+ [Hello, I forgot to click add in share with for roles and subordinates in the salesforce classic. How can I solve this problem.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007T2rlO)

:::note
I have open a new playground and dis it again. 
:::
[TypeScript]汎用的な型設定！ジェネリクスを紹介！[Generics]

## 初めに
TypeScriptのジェネリクスは、柔軟で再利用可能なコードを書くための強力な機能です！
この記事では、ジェネリクスの基本から実際の使用例を紹介します！

# 1. ジェネリクスとは？
ジェネリクスとは、特定の型を指定せずに関数やクラスを定義するための仕組みです。
これにより、異なる型に対して同じ関数やクラスを使用できます。

以下の例は、与えられた引数をそのまま返すだけのシンプルな関数です。
関数を呼び出す際に、ジェネリクスの型パラメータ <T> に具体的な型を指定しています！

```typescript
function identity<T>(arg: T): T {
  return arg;
}

const str = identity<string>("Hello, Generics!");
// str の型は string
console.log("strの型："+typeof str);

const num = identity<number>(42);
// num の型は number
console.log("numの型："+typeof num);
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570986/7148a139-6a2c-05d5-97c5-b8af870a8116.png)

# 2.ジェネリクスの具体例
### 3.1 配列の反転
この関数は、与えられた配列を反転するものです。
ジェネリクスを使用することで、数値型や文字列型など異なる型の配列に対して同じ関数が適用できます！
```typescript
function reverse<T>(array: T[]): T[] {
  return array.reverse();
}

let reversedNumbers = reverse<number>([1, 2, 3, 4, 5]);
let reversedStrings = reverse<string>(["apple", "banana", "orange"]);

console.log(reversedNumbers);
console.log(reversedStrings);
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570986/08562bf9-7192-9038-fbb7-1cc35e443320.png)

### 3.2 ジェネリクスクラス
この関数は、任意の型の値を保持するための箱を表します。
数値や文字列など、様々な型でインスタンスを作成できます！
```typescript
class Box<T> {
  private value: T;

  constructor(value: T) {
      this.value = value;
  }

  getValue(): T {
      return this.value;
  }
}

let numberBox = new Box<number>(42);
let stringBox = new Box<string>("Hello, Generics!");

console.log(numberBox.getValue());
console.log("numberBoxが保持するvalueの型：" + typeof numberBox.getValue());

console.log(stringBox.getValue());
console.log("stringBoxが保持するvalueの型：" + typeof stringBox.getValue());
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570986/66696eb7-fb63-e490-8262-00e33196c7b1.png)

# まとめ
ジェネリクスは、TypeScriptで柔軟で効果的なコードを書くための重要な要素です!
紹介した以外の活用方法も沢山あるので、調べてみてください！
私のフロントエンド学習法

今年でフロントエンドになってから6年目が経過しました。
ある程度はフロントエンドエンジニアとしての知識がついてきた気がするので、継続的に知識をつけるために気をつけていることなどをまとめてみようと思います。

## 業務内での学びの深め方

### 知っていることでも調べるようにする

普段の仕事は同じような作業が多いので学びが少ないと感じている方も多いとは思います。
しかしながら、技術を分かった気でいても実は深く理解していなかったということはよくあります。

例として、cssの`display`プロパティでは`display: block flow;`などの二値構文（multi-keyword）がサポートされていますがこの構文が各ブラウザのどのバージョンからサポートされているのかご存知でしょうか。

ブラウザ上で利用される技術は多岐に渡り、日々新しい仕様や機能がリリースされます。
そのため常に自分が学んだ知識は古いものであるという意識を持ち、気になった項目は知っているつもりでも改めて調べなおすことを意識しています。

### 勉強の予定を先に入れる

パーキンソンの法則のように、日々の業務というのは予想以上に膨らんで時間を圧迫します。
「時間があるときに〇〇する」という大昔のコメントやタスクを見たことがある人も多いと思います。
そのため基本的に業務中に学べる機会がある場合はそれを絶対動かせない予定として認識して、残りの時間でどう業務を行うのかという考え方をしないと業務中に学びを深めることは難しいと思っています。

### Timesでインプットのログを取る

自分はTimesにひたすら読んだ記事や気になる情報のリンクを貼って、コメントを付けています。
Timesでインプットのログを取ると、記事やLTの題材探しが非常に簡単になります。
自分がつまずいたことや軽く流し読みしていた情報を記事やスライドにまとめる段階で、更に追加調査をするのですがこの追加調査で得られる知見が非常に有益な物が多いため、自分はインプットのログを取ってそこからアウトプットにつなげる流れを重要視しています。

### 業務の中でアウトプットをする

Internet Explorerのサポートが終了して、通常のWebサイトやサービスでは日常的に新しいAPIや構文が使えるようになってきました。
そのため以前より圧倒的に新しい技術が本番環境でも使えるようになっています。
アーキテクチャレベルで大きな変更を加えることは難しいですが、CSSを一行新しい書き方で書く程度であればすぐに仕入れた知識を実務でアウトプットできる環境が整っています。
そのため業務では具体的な理由がなければ最新のブラウザのAPIに準拠した書き方になるようにして業務中でインプット・アウトプットのバランスが取れるように気をつけています。

## 業務外での学習

### 社外の勉強会に参加する

社内の勉強会や学習コンテンツが充実していると、簡単にインプットが行えますが社内で「教える立場・教わる立場」が固定化したり、社内でのナレッジに偏りが出てき始めます。
ジュニアクラスのエンジニアであっても、社外勉強会で仕入れた他社の取り組み事例などは先輩も知らない知識であることが多く、一方的な「教わる立場」を脱却するよい機会でもあります。

### ポッドキャストを聞く

毎日在宅で仕事をしているので、運動不足を解消するためになるべく毎日歩くようにしています。
歩いているときはポッドキャストを聞くようにしていて[mozaic.fm](https://mozaic.fm/)や[Rebuild](https://rebuild.fm/)などテック系のポッドキャストを聞いて運動時間も活用しながら楽しく知識をインプットできるようにしています。

https://mozaic.fm/

https://rebuild.fm/

https://fukabori.fm/

https://open.spotify.com/show/2uv9mONog0nr9q5YJJsvIt

## まとめ

以上が継続的に行っているフロントエンドの学習です。
人によって合う・合わないはあるかと思いますが、なるべく自分に合って毎日続けられるレベルのキャッチアップ手法を選ぶことが大切だと思っています。
Generative AI Test

# 結果
点数が低いですが、無事に合格した。
公式サイトの動画を観るのが勉強になった。
そして、法律に関連することも意外に面白かった。（元々は無関心だった）
# 資料
https://www.jdla.org/certificate/generativeai/#toc1
https://ai-wonderland.com/entry/jdla-generativeai-test
# 補足
大規模言語モデルの性能評価について知っている。
### リーダーボード
リーダーボードは、異なるモデルやアルゴリズムが特定のタスクやベンチマークにおけるパフォーマンスを比較するためのランキングシステムです。研究コミュニティや企業は、自らのモデルを試験し、それらの結果をリーダーボードに投稿することで、他のモデルや過去のアプローチとの比較を行います。これにより、最も精度が高い、最も効率的、あるいは特定のタスクに最も適したモデルを一目で識別できるようになります。

### ベンチマーク

ベンチマークは、モデルの性能を定量的に評価するための標準化されたテストセットや評価基準を指します。ベンチマークは、特定のタスク（例えば、自然言語理解、翻訳、要約、質問応答など）に対するモデルの能力を測定するために設計されています。評価には通常、精度、リコール、F1スコアなどのメトリクスが使用され、モデルがどれだけ正確にタスクを実行できるかを示します。

ベンチマークは、一般に公開されており、誰でもアクセスして使用できるため、研究者や開発者が自分のモデルを客観的に評価するのに役立ちます。さらに、異なるモデル間での比較を可能にするため、ベンチマークは固定されたデータセットや評価手順に基づいています。
### 推論の効率化（動向）
推論の際にAIモデルは、リアルタイムで与えられたデータに対して判断を下します。

より強力なコンピューター・チップを開発することは、性能を向上させる明らかな方法です。IBM Researchの重点分野のひとつは、ディープラーニングを支配する数学演算である行列乗算に最適化されたチップを設計することです。IBMのプロトタイプ人工知能ユニット（AIU）やアナログAIチップの研究は、この種の数値演算に最適化されたハードウェアの例です。

AIモデルをより高速に実行させるもう一つの方法は、モデル自体を縮小することです。不要な重みを刈り込む（プルーニングする）ことと、量子化によってモデルの精度を下げることは、推論時に優れた性能を発揮する、より効率的なモデルを設計するための2つの一般的な方法です。

推論を高速化する3つ目の方法は、AIモデルを、AIタスクを解決するためにさまざまなハードウェア・バックエンドが実行できる処理に変換するミドルウェアのボトルネックを取り除くことです。これを実現するために、IBMはオープンソースのPyTorchコミュニティーの開発者と協力しました。

### 利活用（動向）
RAG (Retrieval-Augmented Generation)の利用：
RAGは、外部の知識ベースから事実を検索して、最新の正確な情報に基づいて大規模言語モデル（LLM）に回答を生成させることで、ユーザーの洞察をLLMの生成プロセスに組み込むというAIフレームワークです。
エージェント：
生成 AI App Builder は、Dialogflow CX 上に構築されたエージェントを提供します。この機能を使用すると、ウェブサイトのリンクまたはドキュメント（データストア）を指定して、Google がコンテンツを解析し、大規模言語モデルを搭載した仮想エージェントを作成します。これは、データストア ハンドラと呼ばれる特別な状態ハンドラで実現されます。 これらのデータストア ハンドラを使用して、エージェントはエンドユーザーとコンテンツに関する会話を行うことができます。
コード生成、
外部ツール呼出し
### リスク（特徴）
悪用
誤情報の拡散
敵対的プロンプト
特定の生成AIサービスへの依存
環境問題
【SwiftUI】マルチモジュールで画像を表示する

## 始めに
マルチモジュール化してから同じモジュール内にあるxcassetsファイルで画像をセットしたのに表示できませんでした。

※以下のようにGuideViewでMedia.xcassetsでセットした画像を表示したい

![スクリーンショット 2023-12-14 10.51.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554113/093ddced-b170-110c-541a-ed91dc0cfeae.png)

## 結論
以下は、Media.xcassetsでセットした画像です。今回は、"IMG"という画像を表示します。
![スクリーンショット 2023-12-14 10.53.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554113/5a1c13a3-0727-3dde-f307-2d124aeeaba5.png)

```swift
Image("IMG", bundle: Bundle.module)
```

これで表示できました。

## まとめ

```swift
Image("IMG")
```
上記の書き方で表示できると勘違いしてました…

異なるモジュールにある画像を表示したいときは以下の記事が参考になりそうです！

https://zenn.dev/kyome/articles/46e4f3641a4181
The operation couldn’t be completed. (OSStatus error -10814.)

Xcode 15でアプリ開発時にめちゃくちゃマイナーなエラーが発生したのでその解決策を記録しておきます。

# エラー文
```
The operation couldn’t be completed. (OSStatus error -10814.)
Domain: IDELaunchCoreDevice
Code: 0
Recovery Suggestion: Verify that the Developer App certificate for your account is trusted on your device. Open Settings on the device and navigate to General -> VPN & Device Management, then select your Developer App certificate to trust it.
User Info: {
    IDERunOperationFailingWorker = IDELaunchCoreDeviceWorker;
}
--
The operation couldn’t be completed. (OSStatus error -10814.)
Domain: NSOSStatusErrorDomain
Code: -10814
User Info: {
    "_LSFunction" = runEvaluator;
    "_LSLine" = 1608;
}
```

# 状況
Xcode 15にてBroadcast Upload ExtensionをiOS Appに追加後、Broadcast Upload Extensionをデバッグしようとしたら発生しました。
この時、どのアプリを起動するかが選べますが、自分のアプリを選択していました。
また、開発後にBundle IDを変更したのもあり、これが大いに影響していそうでした。
また、エラー文で示されたようにVPN & Device Managementを見に行きましたが、デベロッパーAppという項目はありませんでした。iOS 17あたりから変更があったような気もします。

# 解決策
どのアプリを起動するか？の一覧になんと自分が開発したアプリが二つ表示されていました。どちらかがトラップでどちらかが正解でした。
普通に最近使用した項目としてずっと触らずに実行していたのが問題だったようです。
どうやら、Bundle IDを変更した前のものが残っていたようです。
IT未経験者がLPIC-1を合格するために使った教材

## はじめに
これからLPIC-1を取得するIT未経験者に向けた記事です。
先月LPIC-1を取得し、その時の勉強法を役に立てていただければと思います。
以下101、102のスコアです(満点が800)
![スクリーンショット 2023-12-14 085011.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3647195/be41af6b-6f4a-5877-b40c-a51a4ab6a80c.jpeg)

## LPIC-1を取得する意義
私は現在AWSのSAAを取得するために勉強していますが、ハンズオン学習においてLinuxコマンド、SSH、サブネットマスクやCIDER、ルーティング、IPアドレスに実際に触れます。その時LPIC-1を取得したおかげでスムーズに学習を進めることができ、またLPIC-1学習時では操作ができなかったことをAWSで操作することができて、さらに学習の内容が深まりました。
IT未経験者がAWSの資格を取るための前段階として非常に有効な資格です。

## 使用した教材一覧
1. [サムライテラコヤのLinuxコース](https://terakoya.sejuku.net/course_programs/01GS4PT0K1G4AV3K9BKEQP9422)
2. [Ping-t](https://mondai.ping-t.com/g)
3.  LPICレベル１小豆本
4.  LPICレベル１スピードマスター
これらを使用して一ヶ月半ほどでLPIC-1を取得しました。


## それぞれの教材の特徴
### サムライテラコヤ
サムライテラコヤはSAMURAI ENGINEERというプログラミングスクールが運営している定額・学び放題のプログラミング学習教材です。
月額4500円ほどですが、無料で出来る教材もありIT初心者でもわかりやすい教材がかなり多く、Q&Aで環境構築トラブルやわからないことを質問できる環境が整えられています。もし本当にITのことが何もわからない状態で手を付けられない状態ならこちらのサービスを使用すると効率的に進めると思います。
別コースですがITリテラシーコースは未経験者にとってかなりお世話になりました。

### Ping-t
Ping-tは問題集です。正直に言うとPing-tだけでLPIC-1は受かりますが少し注意点もあるので後述します。102試験の問題集は有料で、一ヶ月2400円で、二ヵ月で3200円と申込み期間が長いと割引が効きます。
101の問題は無料なので取得後に、102にどのくらいの時間がかかりそうか把握できるので、それに応じて期間を決めて申し込んでください。

### 小豆本
小豆本は教科書です。使い方としては記述されているコマンドを実際にVirtul Box等のLinux環境を用意して実際に打ち込んでました。また座学的な内容も含んでいます。各章ごとに問題集があるのでそこで理解度のチェックを行えるのもよいところです。
本の内容にLinuxの環境を立ち上げるための手順もあるのでそれを参考にしてください。

### スピードマスター
問題集です。LPICの試験時にこの教材を学習していたおかげで解けた問題がいくつかあったので正答率を上げる目的のために購入するのがベストです。


## 勉強法と注意点
まず小豆本やサムライテラコヤなどで手順通りにLinuxの環境を整え、コマンドを入力できる環境を整えます。
次に教材に沿って、コマンドを入力したり、内容を学習してください。
#### その時重要なのはわからないことがあったらそこで止まらずに前に進んでよいということです。後から見返したら理解したり、問題を解いて理解することが多々あるので先に進むことが重要です。

小豆本は各章に問題がありますので理解度チェックもできます。復習のために解くのにも有効です。

Ping-tも各章ごとの問題を解くことができるので、インプットに飽きたら学んだ章の問題を選んでアウトプットを行いましょう。

小豆本等の教材の内容を終えれば、残るはPing-tの問題をやりこむだけです。
目安としてPing-tにはレベルというものがあり、このレベルを上げていけば着実に合格に近づきます。以下は私のPing-tのレベルです
![スクリーンショット 2023-12-14 102327.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3647195/61fdd9b6-60e1-a3e6-5932-1242f98d139d.jpeg)
それでも不安ならスピードマスターを使うとより合格に近づきます。

##### 注意点として未経験者が暗記だけでこの資格を取るのはもったいないです。前述したとおり私はAWSの資格を取るために勉強していますが、LPICを学習する際にコマンドを実際に打つことでその後の学習をスムーズに続けられています。ここはかなり重要なポイントなので是非、環境構築してコマンドを打ってみてください。理解度もかなり上げることができます。

## 最後に
IT未経験者がIT業界に入るためには最低限の実力やポテンシャルを揃えなければならないと勝手に思っています。LPIC-1はLinuxの入門としてとてもよい資格でAWS等で次につなげやすい資格だと思います。是非チャレンジしてみてください。
ログから必要な情報のみを正規表現で抜き出すメモ

### やりたいこと
下記のようなログファイルから成功件数だけ抜き出したい。
→「~~~成功：」や「失敗：~~~」という部分を削除したい。
```text
開始日時 : 2019/10/21 14:45:03 終了日時 : 2019/10/21 14:50:16 全体 : 469 成功 : 469 失敗 : 0
開始日時 : 2019/10/21 15:05:35 終了日時 : 2019/10/21 15:06:38 全体 : 41 成功 : 40 失敗 : 1
開始日時 : 2019/10/21 15:36:42 終了日時 : 2019/10/21 15:37:44 全体 : 42 成功 : 0 失敗 : 42
```
### 正規表現
#### 必要な箇所を検索する方法
```
成功 : (\d+)
```
> `\d`は任意の数字にマッチ。
> `+`は直前のパターンが1回以上繰り返されることを意味する。
> `()`は正規表現のグループ化。パターンの一部をまとめて扱うために使用する。
> →`(\d+)`1つ以上の数値にマッチする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640315/fa959091-01f5-04dd-d023-03d3f20674b4.png)

#### 不要な箇所を検索・置換で削除する方法
```
.+成功 : | 失敗 :.+
```
> `.+`1つ以上の任意の文字にマッチすることを意味する。
>`|`OR演算子。前後のパターンのいずれかにマッチすることを意味する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640315/afec909f-a09e-1acc-fdb5-e6b0c2a469c8.png)
↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640315/a684379a-55bc-a135-aaae-7bf8a63507d8.png)
【PokeAPI】名前に「パピプペポ」が含まれるポケモンは弱いのか？

# 初めに

私が良くyoutubeで見ている「ゆる言語学ラジオ」というチャンネルの動画を見ているとこんな一幕がありました。

```plaintext
「濁音は強いイメージを、半濁音はかわいいイメージを与えやすい」
```

だから、ロングセラーのお菓子の名前は`パピコ` や `アポロ`などの半濁音が入りやすいし、怪獣の名前は`ゴジラ`や`バラモン`などの濁音が入っていることが多いそうです。

https://yurugengo.com/

また、ポケモンの名前でも伝説のポケモンは`グラードン`や`ディアルガ`など濁音が入っていることが多いし、マスコットキャラである`ピカチュウ`には半濁音が入っています。
そこで私は

```plaintext
かわいいポケモンはかっこいいポケモンよりも弱いイメージがあるから、

名前に半濁音が多いポケモンはステータス上弱くなる傾向にあるのでは？
```

と疑問に思ったので、軽く統計を取ってみることにしました。


# ドメイン知識

ポケモンのステータスは「HP」「こうげき」「ぼうぎょ」「とくこう」「とくぼう」「すばやさ」の6種類で示されています。
これらは内部ではポケモンの種類ごとにそれぞれどのステータスが高くなりやすいかという情報が数値で与えられている。これをネット上では**種族値**(非公式名称)と呼んでます。

今回の調査では、6種類の種族値を合計した「**合計種族値**」をポケモンの強さの指標として用いました。
例えば、冒険の序盤に手に入るピカチュウの合計種族値は320となっており、伝説のポケモンと呼ばれるグラードンの合計種族値は660となっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2916360/1ba71887-cdab-1685-38e1-d23a175a7001.png) ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2916360/3a8f7cab-f0f5-dfe6-2bf8-7f7355c7d280.png)

# 実装

## 概要

今回の調査では、「名前に含まれる濁音・半濁音の個数毎にグループを作り、グループごとの平均合計種族値を比較する」ことで名前とステータスの関連性を考察します。

## PokeAPI

```python:サンプルコード
# 指定したポケモンの情報を取得
response = requests.get("https://pokeapi.co/api/v2/pokemon/" + str(id)).json()

# 名前の取得
name = response['name']

# 合計種族値の取得
sum_stat = 0
for stat in response['stats']:
    sum_stat += stat['base_stat']
```

ポケモンの名前やステータスのデータを手に入れるにあたって、PokeAPIを利用しました。
データ取得の実装説明に関してはほぼ以下の記事を参考にしたため割愛させていただきます。

https://qiita.com/railgun-0402/items/c3f087c8eb091497b75c

今回はポケモンの名前と種族値にアクセスするために使いましたが、他にもタイプだったり図鑑の説明までデータがあるのでいろいろな使い方が出来そうです。

ただ、上記のコードではポケモンの名前が英名で取得されるため以下の記事を参考に日本名で取得するように改良しました。

https://qiita.com/jinto/items/9d0d9df30dded1e61015

## 濁音・半濁音の判定

```python
import pykakasi

kakasi = pykakasi.kakasi()
kakasi.setMode('K', 'a')

# 「ッ」の削除
text = text.replace("ッ", "")

# ローマ字変換
kakasi.convert(text)[0]['hepburn']
```

pykakasiを用いてポケモンの名前をローマ字に変換した後、濁音と半濁音に相当するg,z,d,b,pがいくつ含まれているかを数えました。また、このやり方では「ッ」が含まれる場合に二重にカウントしてしまうことが考えられるので、ローマ字変換する前に「ッ」を除外するという処理を挟みました。
(後から考えたら、文字コードで範囲参照するなどもっといいやり方があった気がします...)

これらを基に、PokeAPIにデータが載っている全てのポケモンの名前を濁音・半濁音の数毎にグルーピングして、各グループの平均種族値を算出しました。

# 結果

![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2916360/2edd9347-4311-bb12-a855-cc4df63d1b96.png)

各グループごとに集計した結果が上のグラフです。
緑のグラフが濁音・半濁音の無いグループ、赤が濁音が含まれるグループ、青が半濁音が含まれるグループを指しています。
私の予想では緑を境に赤の値が高く青の値が低くなると考えていましたが、一概にそうとは言えない結果となりました。

この結果から考察を軽く並べると
- 濁音がついているポケモンは何もついていないポケモンより強くなる傾向にある
- 半濁音がついているからと言って弱くなるわけではないが、半濁音が2つ含まれるポケモンは明らかに種族値が低くなる傾向にある(例：ピッピ、ププリン)
- 濁音が4つ含まれるポケモンの平均が特に高そうに見えるが、該当ポケモンが1匹しかいないため(ドドゲザンのみ)単にデータ不足と考えられる


## 補足

今回は集計から除外しましたが、濁音と半濁音が混在するポケモンももちろんいます。
その中で面白かったのは濁音2つ半濁音1つのグループで、"ブーピッグ"と"ブリザポス"の2匹しかいません。
平均種族値が525と圧倒的でした。(外れ値なため、平均が偏っている感はありますが)

# 最後に

言語学も統計学も知識が浅いので込み入った考察などはできませんでしたが、そこそこ有意な結果が得られて良かったです。
そもそも、ラジオの中でこの話が出てきた経緯は「なぜ、おかしの名前はパピプペポが多いのか？ 言語学者、小学生の質問に本気で答える」という書籍の中に含まれている話が元となっているので、こちらの文献を読んで言語学側の知識も深めたいです。

https://amzn.asia/d/8NOZs1M
申請書の入力方法をナビゲート！

「[コラボフロー Advent Calendar 2023](https://qiita.com/advent-calendar/2023/collaboflow)」14日目の記事です！

今年も残すところ2週間ちょっとですね・・・
今年は長年応援してきた阪神タイガースが日本一になり、最高の年でした🎉
今から来年の連覇を願ってやまないこにおです。

---

みなさん、申請書の画面や入力方法のガイドはどうされてますでしょうか？
マニュアルを作成したり、申請書のフォームに説明を記載したりされてるのではないかなと思います。

でもマニュアルの作成は項目が変わる度に画面キャプチャを取り直したり、フォームに説明を入れすぎると申請書の体裁を整えるのが難しかったりしますよね💦

そこで今回は、コラボフローのJavaScript APIを利用した入力ガイドを作成する方法をご紹介します！

## 利用するライブラリ

今回は「TourGuide JS」というJavaScriptライブラリを利用します。
TourGuide JSの使い方は非表示にシンプルで、簡単にステップ形式のチュートリアルを作成することができます。

https://tourguidejs.com/

## フォームの作成

まずはフォームを作成します。
今回は以下のような稟議書のフォームを作成しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152259/160c27ee-51f3-3634-98c8-a797e36bb49e.png)

フォーム上部にある「入力ガイド開始」のリンクは、ラベルパーツで作成しており、以下のHTMLをセットしています。

```javascript
<a href="javascript:void(0)" onclick="startTour();return false;">入力ガイド開始</a>
```

## JavaScript カスタマイズコード

次に入力ガイドを表示するJavaScriptカスタマイズコードを作成します。

入力ガイドのステップは、以下のように形式で指定します。

```javascript
const tourSteps = [
	{
		title: '｛ガイドのタイトル｝',
		content: '｛ガイドの内容｝',
		target: '#｛パーツID｝',
		order: '｛ガイド表示の順番｝'
	},
    ...
]
```

今回作成したフォームに合わせて実装したコードが以下になります。
各ステップの内容を指定し、インスタンスを生成して実行するだけのシンプルなコードです。

```javascript:tour.js
'use strict';

const tourSteps = [
	{
		title: '稟議書番号',
		content: '稟議書番号は「RINGI」+「yyyymmdd」+「連番」の形式で入力してください。',
		target: '#fidNo',
		order: '1'
	},
	{
		title: '内容または目的',
		content: '分類に「契約」を含む場合は、契約内容について記入してください。',
		target: '#fidPurpose',
		order: '2'
	},
	{
		title: '添付資料',
		content: '金額が10万以上の場合は、見積書を添付してください。',
		target: '#fidAttach',
		order: '3'
	},
	{
		title: '特記事項',
		content: '急ぎ承認が必要な場合は、特記事項に理由を記入してください。',
		target: '#fidNotices',
		order: '4'
	}
];

const tourGuide = new tourguide.TourGuideClient({
	steps: tourSteps
})

// 入力ガイドの開始
function startTour() {
	tourGuide.start();
}

```

## CSSカスタマイズコード

次にCSSのカスタマイズコードを作成します。
コラボフローのCSSによりガイド内のフォントが小さくなってしまうため、以下のようなCSSを作成します。

```css:tour.css
.tg-dialog,.tg-dialog-title,button.tg-dialog-btn {
	font-size: 15px !important;
}
```

## カスタマイズ設定

フォーム設定画面のカスタマイズタブにて以下のURL指定、JavaScriptファイルをアップロードします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152259/acedbdca-2930-2a2d-3086-fabdb6a09925.png)

### 設定値

#### JavaScriptファイル

| 順番 | 指定方法 | ファイル名/URL |
|:-----------|:-----------|:-----------|
| 1 | URL | https://unpkg.com/@sjmc11/tourguidejs/dist/tour.js |
| 2 | ファイル | tour.js |

#### CSSファイル

| 順番 | 指定方法 | ファイル名/URL |
|:-----------|:-----------|:-----------|
| 1 | URL | https://unpkg.com/@sjmc11/tourguidejs/dist/css/tour.min.css |
| 2 | ファイル | tour.css |

## 入力ガイド開始！

新規文書から作成したフォームの申請入力画面を開き、「入力ガイド開始」のリンクをクリックすると、以下のようにツアーガイドが表示されます💁‍♂️

![tourguide.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152259/7ef25a24-ce2d-c45d-529d-6c4116b2597d.gif)


## まとめ
いかがでしたでしょうか？
各ステップの内容を指定するだけで簡単にステップ形式のガイドを作成することができました！
またフォームのレイアウトが変わっても、パーツIDで要素を指定しているため、カスタマイズ側のコード変更が不要なのもよいですね✨

TourGuide JSのドキュメントを確認していたところ、コード側でツアーの途中にステップを追加することもできるようなので、ある条件の時だけ説明を追加するということもできそうです！

ご興味ある方は是非お試しくださいー🙋‍♂️
GitHub CLI (gh) に認証情報として渡せる環境変数名は GITHUB_TOKEN より GH_TOKEN が優先される

GitHub には公式の CLI ツールとして GitHub CLI があります。
https://cli.github.com/

CLI の認証情報として渡せる環境変数名には `GH_TOKEN` と `GITHUB_TOKEN`が対応していますが、両方設定されていた場合は `GH_TOKEN`の方が優先されるというただそれだけの話です。ドキュメントにもそのように記載されています。
https://cli.github.com/manual/gh_help_environment

> GH_TOKEN, GITHUB_TOKEN (in order of precedence): an authentication token for github.com API requests. Setting this avoids being prompted to authenticate and takes precedence over previously stored credentials.

ただ、こちらの仕様をすっかり忘れて `GITHUB_TOKEN`にちゃんと設定したはずなのに CLI が動かんとかが稀によく発生していたので備忘録として書きました。特に CI/CD サービスで CLI を利用する際にサービス側の env 設定とかに `GH_TOKEN`が設定されているのに気づかず、 job の中で `GITHUB_TOKEN`に別の token を設定してる場合とかで気づきにくいので気をつけましょう。
コマンドプロンプトに現在時刻を表示する

![DALL·E 2023-12-14 11.24.53 - A realistic image of a command prompt window open on a desktop computer screen. The command prompt displays various lines of text and commands, promin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52151/877a38bc-82e6-251c-21d8-d4bc89538bb9.png)

# はじめに

みなさん、コマンドプロンプトは毎日使いますか？
最近は、プログラミング時は、VS Codeを使用するので、コマンドプロンプトを開いてエディターを立ち上げる機会がだいぶ減りましたが、なんだかんだでコマンドプロンプトを開く機会があります。

# 時刻を表示する

コマンドプロンプトに現在時刻を表示することが可能です。
知っている人も多いのですが、それ以上に知らない人の方が多いような気がします。
好みの分かれるところですが、私が現在時刻を表示する一番の理由は、コマンドを実行した時刻をあとで確認できることでしょうか笑

あとは、常に現在時刻を目にすることで、作業に集中しすぎないことを意識できることかな。

コマンドプロンプトに時刻を表示する方法は、使用するshellによって異なります。
私は、zshを使用していますので、オンラインマニュアルでその方法を調べることができます。

https://zsh.sourceforge.io/Doc/Release/Prompt-Expansion.html#Prompt-Expansion

現在時刻を表示するためには、```%T```を使用しますが、この方法だと、秒が表示されないのと、時刻が1桁の場合、例えば9時41分なら、9:41と表示されてしまいます。個人の好みとしては、09:41:05 ← (時:分:秒)と表示されて欲しいところです。

オンラインマニュアルを詳しく見ていくと、こんな表記方法が見つかります。
```zsh
A typical example of this is the format ‘%D{%H:%M:%S.%.}’.
```
PROMPT変数を以下のように設定し、
```zsh
PROMPT="%D{%H:%M:%S.%.} $ "
```
実際に試してみると、
```zsh
09:52:26.478 $
```
というような表示になりました。1000分の1秒単位まで表示されています。
個人的にはここまで必要がないので、
```zsh
PROMPT="%D{%H:%M:%S} $ "
```
を採用することとしました。

(上記コマンドプロンプトを設定した時の例)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52151/ab7ce86b-2a4c-6c80-dcdc-aa2e88053286.png)

# 終わりに

オンラインマニュアルをみると、もっともっとカスタマイズが可能であることがわかります。
コマンドプロンプトに何を表示するのか、それは人によってかなり奥の深い世界のようです。

# 参考

https://zsh.sourceforge.io/Doc/Release/Prompt-Expansion.html#Prompt-Expansion
「エンジニアのキャリアデザイン」ウェビナーに参加してみた

## はじめに

### なぜ参加したのか

- 自分のキャリアを明確に持っていなかったから
- 未経験エンジニアの方々と関わることが多く、キャリアの話をするときにヒントになれば嬉しかった

（本音は、またまたFaceBookで流れてきて面白そうだったからで、実際面白かった）

## ウェビナー

### コンテンツ

内容は、DIVXのCEOの物部さんとCTOの田島さんからのエンジニアキャリアに関するトークと事前に募った質問の応答であった。

## 学び

### キャリアの考え方

大きな枠組みとして`フォアキャスティング`と`バックキャスティング`という考え方があるということを知った。
この言葉自体は初めて聞いたものだったが、自分なりに以下のように考えられるのかなと考えた。
```
フォアキャスティング: 現在の延長線上
バックキャスティング: 未来からの逆算
```
このように考えると、いま目の前のことを取り組むのか、将来なりたい姿から逆算して取り組むのかの違いになる。

これはどちらかが正しいというものではなく、その人の目指すものや置かれている状況によって変わる。
今の僕は、フォアキャスティング寄りだし、数年前はバックキャスティング寄りだったと思うので、個人の中でも置かれてる状況によって変わるものなのだろう。

### 勇気の話

実際にこのウェビナーで「勇気の話」として取り上げられていたものではない。
たが、個人的には勇気の話なのではないかと解釈した。

>「何か仕事をするときに、すべて分かった状態で始められることはない」

というお話があった。

だからこそ、`「〇〇だからできない」`をやめましょうという話だった。

時間が無いから、納期が短いから、部下が、上司が、会社が、恋人が、親が、、、などなど、どんなことでも言い訳できてしまう。

このウェビナーでは、仕事が忙しいからと故郷に暮らすおじいちゃんに会うことを先延ばしにしていたら、もう会えなくなってしまった。というお話があった。
僕はことは「勇気の話」なんだと解釈した。（失礼だったらごめんなさい）

だからこそ、どんなことでも「〇〇だからできない」とできない理由を探すことをやめて、「できるようにするためには？」とスイッチすることが大切なのだろう。


## まとめ

- キャリアにはフォアキャスティングとバックキャスティングという考え方がある
- どちらかが良いというわけではなく、その時の置かれている環境や自分の目標によって変わる
- 「〇〇だからできない」をやめる
- できない理由探しをやめて、「できるようにするためには？」を考える

個人的に面白かったのは、質疑応答の箇所で、「エンジニアの転職のタイミングはいつが良いか？」という質問があった。
（基本的に質問の内容は漠然としていて、質問者の詳細はわからない上での回答である）

物部さんの回答は`「つまらなくなったら」`だった。
正直、このウェビナー面白いと感じたのはこういった素直な話が聞けたからだった。
キャリアとか関係なく、人生単位で考えたら`「面白いことをした方がそりゃいいよね」`ってことの裏返しなのかと思い、当たり前過ぎて大笑いしていた。
AWS-Associate合格日記

## はじめに
私は新卒2年目文系出身のインフラエンジニアです。
昨年の10月にSAAを取得しましたが、1年越しにDVAとSOAを取得しました！
普段は、AWSを使った開発や、インフラ基盤の監視復旧などをしています。
SAAを取得したときに比べてAWSを触る時間が圧倒的に多かったですがそれでもまだまだだなという感じでしょうか。
[SAA取得の記事](https://qiita.com/risurisa/items/d43ca96499f46625768e)

## DVA・SOAを受けた理由
私の業務ではあまりDVA周りのサービスは触りません。
ですが、SAAの次に取るなら1番難易度が低そうだと思ったことが理由です。
SOAに関しては、今までラボ試験がありましたが現在ラボ試験がない状態なので、受けるなら今がチャンスだ！と思ったことがきっかけです。

## 勉強方法
SAAの時は勉強に3か月ほどかけました。（そもそも基礎知識もなかったので・・・）
DVAとSOAは大体2・3週間で集中して勉強し、とにかく問題を解きまくりました。
DVAは420問、SOAは700問解いて、間違えた問題を解きなおしました。
とにかく問題を解いてサービスの特徴をつかむことと、サービスとサービスの組み合わせの傾向がつかめると合格できると思います。
できる環境があればコンソールを実際に操作してみることもオススメします。

## モチベーション
私がDVAとSOAを受けるモチベーションになったのは、同期が皆合格していたことでした（笑）
私だけ持っていないのは恥ずかしい！と思い勉強しました。
周りの人の存在はかなり大きいですね。
Associateを3つ取ったことで基礎知識は身についたなと思います。

## 問題集
使用した問題集は以下です。
よろしければ参考にしてください！

* [徹底攻略 AWS認定 ソリューションアーキテクト – アソシエイト教科書 徹底攻略シリーズ](https://amzn.asia/d/dTUrHS5)
* [Cloud License](https://cloud-license.com/)
* Udemy【０１版】AWS 認定デベロッパー アソシエイト模擬試験問題集（5回分325問）
GitHubに上げたコードからAIで何やったか見れるやつ作った

N高生です。GitHubのコードを取ってきてAIで何やったか見れるやつを作ってみました。
スマホ対応はめんどくさくてしてません....PCで見てください。

# つくったもの

https://aidee.app/

### GitHubと連携/取得リポジトリを設定
![スクリーンショット 2023-12-14 午前10.05.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437056/73094490-630e-0e5a-d40d-e95a2c4eb29a.png)

### 最新の日報を取得
![スクリーンショット 2023-12-14 午前10.06.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437056/36d38dcf-b1e7-a325-8d94-992c71f4cce6.png)

### ユーザーごとに何やったか見れます
![スクリーンショット 2023-12-14 午前10.06.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437056/dfc8d5e5-d5e2-fe30-82e1-737eeff7c776.png)

### 詳細も見れたり
![スクリーンショット 2023-12-14 午前10.06.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437056/ecdb26a9-493a-94eb-e731-05df78e9da45.png)

### 実際のコードに飛ぶんだり
![スクリーンショット 2023-12-14 午前10.06.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437056/fb80fb71-ed4f-8e1e-62f7-039cf46c1f8f.png)

### 日別に見たり
![スクリーンショット 2023-12-14 午前10.06.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437056/ec0ab788-324a-d3f6-d5b1-854261293968.png)

### ユーザーを招待することもできます
![スクリーンショット 2023-12-14 午前10.07.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437056/88ca2f36-de27-ae1a-9328-065c3c4f7291.png)

![スクリーンショット 2023-12-14 午前10.07.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437056/49ff7f32-3166-da36-8034-f570dd46bad5.png)





### アカウント登録
![スクリーンショット 2023-12-14 午前10.04.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437056/ce93393e-a609-f562-d0c1-51f0946e9326.png)

### 料金テーブル
![スクリーンショット 2023-12-14 午前10.02.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437056/92264657-8944-cbea-e68f-82bbc91d6db6.png)



## 技術スタック

![‎技術スタック](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437056/1e362680-e39e-fe1e-2110-084562fc2d5d.png)


### Next.js

フロントエンド/バックエンドはNext.jsを使用しました。
はじめはExpress.jsなどで分離していたのですが、API仕様を考えたり、突貫工事が増えたり開発コストが上がってしまったりしたのでNext.jsで書き換えました。

### UIフレームワーク
Tailwind CSSベースのRippleUIを使用しています。

https://www.ripple-ui.com/

導入した理由はなんか軽そうみたいな適当な理由です。
個人開発っぽいですが、見た感じ自分でもメンテできると思ったのでこちらを使用しました。


### Docker

最初はマルチステージを導入していたのですが、詰まったときのイライラと工数からビルド時間がかかったほうがマシと判断し、シンプルな構成にしています。

```dockerfile
FROM node:18-alpine AS base

FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app

ARG CHATGPT_API_TOKEN
ARG DATABASE_URL

COPY . .

RUN echo DATABASE_URL=${DATABASE_URL} >> .env

ENV NODE_ENV production

RUN yarn && yarn cache clean
RUN yarn prisma generate

EXPOSE 8080
ENV PORT 8080
ENV HOSTNAME "0.0.0.0"

CMD ["sh", "./startup.sh"]
```

### 決済系
Stripeを導入しました。

### GCP
`main`にマージされると自動的にCloud Buildが走り、Cloud Runにデプロイするようにしています。
Cloud Buildは遅いし高いので変えたいです。
月6000円ぐらいかかってます。



# 最後に

https://aidee.app/signin

使ってみてください！
【Rust】mlua 使ってみた

Rust で Lua を動かすときに使うクレートのひとつ、mlua を使ってみました。

# インストール
```sh
cargo add mlua
```

👆をやるだけです。

https://ichigopack.net/lua/windows.html

Lua は `apt` でインストールしたらシンボリックリンクが足りなかったとかで Rust のコンパイルに失敗したので 👆 の方法でインストールしました。

# 試しに動かす
### Rust 内で Lua プログラムを呼ぶ
```rust
use mlua::prelude::*;

fn main() {
    let lua = Lua::new();

    lua.load("var = 123").exec().unwrap();
    println!("var: {:?}", lua.globals().get::<_, Option<i32>>("var").unwrap());
}
```

```
var: Some(123)
```

Lua 内で定義させたグローバル変数を Rust で呼び出すことができました。

### Rust で定義した関数を Lua で呼ぶ

```rust
use mlua::prelude::*;

fn main() {
    let lua = Lua::new();

    let f = lua.create_function(|_, ()| -> LuaResult<()> {
        println!("hello from rust");
        Ok(())
    }).unwrap();
    lua.globals().set("rusty_hello", f).unwrap();

    lua.load("pcall(rusty_hello)").exec().unwrap();
}
```

```
hello from rust
```

Rust 側からグローバル変数として `rusty_hello` 関数を定義してあげると、Lua 内では `pcall` などを使って関数呼び出しができます。Rust で書かれた関数を Lua 内部から起動できた形になります！

ちなみに、async function の定義もできます。

# おわり
同じように Rust から Lua を使わせるクレート rlua も世の中にはありますが、使い心地は mlua の方がいいなという感じです。