OmniAICreator/Qiita-1.07M huggingface dataset:
invisible風のEditTextにfocusを当てようとした時にハマったこと

## 本記事について
- 「EditTextを配置した画面において、フォームは出したくないけど、画面表示時にキーボードが表示され入力可能な画面を作る」という要件で実装する機会があったのですが、
キーボードを表示するためにEditTextにfocusを当てようとしてハマったことがあったので、メモ書き程度ですがまとめてみました。
("invisible風" についてはフォームは見えないけどフォーカスも当てられて、任意の文字列を入力できるという点から勝手にそう呼んでいます)

## 対応内容
- 以下のような属性を指定したEditTextを用意します。（次項に記載のポイントが満たせていれば属性の設定値はアレンジ可能）

```xml
    <EditText
        android:id="@+id/edit_text"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:inputType="numberPassword"
        android:maxLength="4"
        android:focusable="true"
        android:clickable="false"
        android:focusableInTouchMode="true"
        android:background="@null"
        android:textColor="@null"
        android:textColorHint="@null"
        android:cursorVisible="false"
        android:visibility="visible"
        android:autofillHints=""
        android:hint="" />
```

- あとは任意のタイミングで、上記のEditTextに対して `requestFocus()` をコールすればOKです。
    - 今回は画面表示時にフォーカスが当たった状態にしたかったので、`onViewCreated()` 内でコールしました

## ポイント
- 以下を満たすことで、テキストエリアの（なんちゃって）非表示化 + 入力が可能となります。
    - `layout_height` および`layout_width` の値を **`0dp`** 以上とすること
        - 値が 0 になってしまうと`requestFocus()` のコール（直接Viewをタップした場合も同様）、フォーカスを当てられない状態になってしまいます
    - 標準で表示される部品を非表示とする
        - 入力欄の背景(＝background)
        - カーソル（=cursorVisible）
        - ヒントテキスト（=autofillHints, hint, textColorHint）
        - 入力テキスト（=textColor）

## 追記
フォーカスが外れた状態からキーボードを明示的に表示する際、InputMethodManagerを利用しないとキーボードを表示することができませんでした。
正攻法なのかはわかりませんが、少なくとも要件を満たすにこの実装必要でした。
```kotlin
fun showKeyBoard(context: Context) {
    edit_text.requestFocus()
    val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.showSoftInput(edit_text, InputMethodManager.SHOW_IMPLICIT)
}
```


## 最後に
同様のことをするケースがあまりないからか調べてもなかなかヒットせず、ゴリ押し感が否めない対応となってしまったのですが、他にいい方法をご存知であれば教えていただけると幸いです :pray:
AI-102試験対策のまとめ「Custom Visionポータルを使用した画像分類モデルの構築」

## はじめに
Azure AI Engineer Associate(AI-102)取得に向けた勉強でまとめた内容を本記事では投稿しています。
試験範囲の内容を私が勉強していく中で、
・忘れてしまっていた内容
・他の知識と絡めて理解した方が良い内容
・Microsoft Learnの読解に苦戦した内容
などをできるだけ分かりやすく簡潔にまとめることを意識しています。
Azureの勉強を一から始め、AI-102取得を目指している方の参考になれば幸いです。
※本記事の内容が必ず試験に出るわけではないこと、ご注意ください
※勉強しながら投稿しているため、追加で学んだことがあれば随時投稿内容を更新します。

## 試験対策のまとめ
### Custom Visionポータルを使用した画像分類モデルの構築
#### **Custom Visionリソースの作成**
1.  Custom Visionサービスを使用するために下記リソースを作成
    * Custom Vision Trainingリソース
    * Custom Vision Predictionリソース

#### **新しいプロジェクトを作成**
1. プロジェクトの名前と説明を入力
1. Custom Vision Trainingリソースを選択
1. 分類の種類を下記から選択
    * マルチラベル：画像に任意の数のタグを付ける
    * マルチクラス：画像は1つのカテゴリに分類される
1. 下記の中から使用するドメインを選択
    | ドメイン | 最適化 | 使用例 |
    | --- | --- | --- |
    | Generic | 様々な画像分類タスク | ・他のドメインのいずれも適切でない場合 <br>・どのドメインを選択すればよいか不確かな場合 |
    | Food | 料理の写真 | 個々のフルーツや野菜の写真の分類 |
    | Landmarks | 自然物や人工物のランドマーク | ランドマークが写真にはっきりと写っている場合 |
    | Retail | ショッピングカタログ/Webサイトで見られる画像 | ドレス、ズボン、シャツの高い精度の分類 |
    | Compact domains | モデルデバイスでのリアルタイムの分類の制約 | ローカルでの実行の場合 <br>※エクスポートが可能 |
1. プロジェクトの作成を選択

#### **トレーニング画像の選択**
* 初期トレーニングセットでタグごとに少なくとも30の画像の使用を推奨
* モデルを効果的にトレーニングするためには、視覚的に多様性のある画像の使用を推奨

#### **分類子のトレーニング**
* 現在の画像をすべて使用し、各タグの視覚的特性を識別するモデルを作成

#### **分類子の評価**
1. トレーニング完了後、モデルのパフォーマンスが推定される
1. 分類子の有効性を表す2つの測定値が表示
    * 精度：正しかったと識別された分類の割合
        - 100個の画像が犬と識別され、そのうち99個が実際に犬だった場合⇒精度=99%
    * 再現率：正しく識別された実際の分類の割合
        - 犬の画像が100個あり、そのモデルで80個が犬と識別された場合⇒再現率=80%

* 参考
    - https://learn.microsoft.com/ja-jp/azure/ai-services/custom-vision-service/getting-started-build-a-classifier

## 次の試験対策のまとめ
* **AI-102試験対策のまとめ「Face APIにおけるFind Similar APIの呼び出し」**

https://qiita.com/fsd-jume/items/6d35cf0ab7be24c8b774

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/65aba5d5514e023fd66d
[CSS] flex-boxのspace-betweenで最後の行を左寄せしたいとき

アイテムボックスのようなものを、こう並べたいと思う。
![理想](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3587300/f9bb509f-ace5-c3bd-c8c8-deabe87193de.png)

```html
<div class="parent_element">
  <div class="item">box</div>
  <div class="item">box</div>
  <div class="item">box</div>
  <div class="item">box</div>
  <div class="item">box</div>
</div>
```

一目、こう指定するだけでいいと思う。

```css
.parent_element {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

.item {
  width: 30%;
  padding: 1em;
  margin-bottom: 1em;
  background-color: #fff;
  border: 1px solid gray;
  text-align: center;
}
```



しかし最後の行が中途半端な数の場合、うまくいかない。
![現実](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3587300/37183c90-adb7-3f61-e5cf-1c31d0cd2027.png)
なぜなら、**space-between**だから。

## 解決策1　（非推奨）
**HTMLに要素を追加して透明にする。**
```html
<div class="parent_element">
  <div class="item">box</div>
  <div class="item">box</div>
  <div class="item">box</div>
  <div class="item">box</div>
  <div class="item">box</div>
  <div class="item" style="opacity:0">box</div>
</div>
```
あまりにやっつけ仕事である。
さらに、レスポンシブで列数が変わる（ブレイクしたとき）毎のstyleを記述しなければならない。

## 解決策2 （推奨）　擬似要素を使用する
**スペーサーとして擬似要素を使用する。**

```scss
.parent_element {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  &::after {
    content: '';
    display: block;
    width: 30%;
  }
}
.item {
  width: 30%;
  padding: 1em;
  margin-bottom: 1em;
  background-color: #fff;
  border: 1px solid gray;
  text-align: center;
}
```
レスポンシブにも対応しており、現場で使用していて過不足がない。

## 解決策3　gapを使用する
現時点ではこれが一番すっきりすると思う。擬似要素は使用しない。

```scss
.parent_element {
  display: flex;
  flex-wrap: wrap;
  justify-content: left;
  gap: 1em;
}

.item {
  width: 30%;
  padding: 1em;
  margin-bottom: 1em;
  background-color: #fff;
  border: 1px solid gray;
  text-align: center;
}
```
gapは長らく対応ブラウザが揃わないプロパティであったので**念のため**使用しない、というのが自分の現場の実情だった。
**私は今でもグローバルのサイト（古いデバイスのユーザーが多い）ではgapをなるべく使用しない。**
PHP v8.3.0 のリリースと変更点

# PHP v8.3.0 リリース

PHP v8.3.0 がリリースされました。 :tada: 

https://www.php.net/releases/8.3/en.php

# 新機能や変更点

Qiita に投稿されている PHP 8.3 の新機能や変更点についての記事です。

https://qiita.com/rana_kualu/items/91111443105a75a55e2f

https://qiita.com/HaruKado777/items/54e74936406262b2b39c

https://qiita.com/HaruKado777/items/bd26322cf467ecf0dccd

# 詳細

詳細は以下をご覧ください。

https://www.php.net/ChangeLog-8.php#PHP_8_3

上記のページを機械翻訳したものを掲載しておきます。

> PHP 8.3.0、2023年11月23日リリースの変更点は以下の通りです：
> 
> - Bcmath拡張で数値から末尾のゼロを取り除くバグを修正。
> - CLIに`pdeathsig`を追加し、マスタープロセスが終了した際にワーカーを終了させる。
> - 複数ファイルの同時リンティングに対応。
> - トレイトからのメソッドインポート時に`final`修飾子を許可。
> - セグフォルトやエラーメッセージの改善。
> - シグナルハンドラにSA_ONSTACKを設定し、他のプロセスコードとの互換性向上。
> - ファイバーのシャドウスタックサポートを追加。
> - Zend Max Execution TimerをLinuxのZTSビルドでデフォルト有効に。
> - `open_basedir`パスのランタイム設定での`..`使用を禁止。
> - セグフォルトやリソースリーク、`__debugInfo`の問題を修正。
> - `#[\Override]`属性の導入。
> - Curl、Date、DOM、Exif、FFI、Fileinfo、FPM、GD、Intl、JSON、LDAP、LibXML、MBString、mysqli、Opcache、OpenSSL、PCNTL、PCRE、PGSQL、Phar、POSIX、Random、Reflection、SAPI、Session、SimpleXML、Sockets、SPL、Standard、Streams、XSLTProcessor、ZIPなど、多くの拡張機能での機能追加やバグ修正が含まれています。
【AWS S3】ログなど膨大な量のオブジェクト群から狙ったものだけ取得するコマンド

## 概要
外部から送信されてきたオリジナルデータやログファイルなどを溜めておくのはS3の使い方としてよくあると思います。
調査でその膨大な数から狙ったオブジェクトを見つけるために、CloudBerryやAWSマネジメントコンソール上で探して取ってくるのはかなり非効率だったため、下記のコマンドで効率化を図りました。

### コマンド
AWS CLIで実行し、一旦フィルタにかかったファイルを全て落としてから、ローカルでgrepして見つける感じです（更に良い方法がありましたら教えて頂きたいです...）
#### CPコマンドを生成
```
↓ 15:31:00 - 15:31:59 までを全て取得する場合
aws s3 ls s3://{バケット名}/{ディレクトリパス}/20231124/ | awk '$2' | grep -E '15:31:([0-5][0-9])' | awk '{print "aws s3 cp s3://{バケット名}/{ディレクトリパス}/20231124/" $4 " ./"}' >> aws_command.txt
```
AWS CLIのlsコマンドの情報からawkコマンドで保存された時刻を取得し、grepで対象の時間帯を指定して絞り込み、ヒットしたオブジェクト名をAWS CLIのcpコマンドに指定してテキストファイルに書き込んでます。

#### 生成したCPコマンドを確認し、問題無ければ実行
```
source aws_command.txt
```

S3からダウンロードされたあとは、ローカルで各ファイルに対して引っ掛けたい文字列が含まれているかチェック→ヒットすれば終了！
Puppeteerでold Headless deprecation warningが出た時の話


久々にPuppeteerを使おうとしてプログラムを動かそうとしたらWarningで怒られました。

> ![スクリーンショット 2023-11-24 10.26.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/6fc61851-3a87-a639-3fc6-210263c358ec.png "スクリーンショット 2023-11-24 10.26.36.png")

## こんな感じで解消できます。

Node.js 21.2.0です。`headless: 'new'`をつけて起動します。

```js
const puppeteer = require('puppeteer');
// import puppeteer from 'puppeteer';

(async () => {
    const browser = await puppeteer.launch({
        headless: 'new',
    });
      
    const page = await browser.newPage();
    await page.goto('https://developer.chrome.com/');  
    await browser.close();
}
)();
```

とりあえず解消したい方はここまででOKです。

## Chromeのヘッドレスモードの仕様変更があるよ話

近々仕様が変わるから起動方法変えたコードにしておいた方が良いよ的な警告です。

```
  Puppeteer old Headless deprecation warning:
    In the near future `headless: true` will default to the new Headless mode
    for Chrome instead of the old Headless implementation. For more
    information, please see https://developer.chrome.com/articles/new-headless/.
    Consider opting in early by passing `headless: "new"` to `puppeteer.launch()`
    If you encounter any bugs, please report them to https://github.com/puppeteer/puppeteer/issues/new/choose.
```

DeepL翻訳だとこんな感じ

```
  Puppeteerの古いヘッドレス非推奨の警告：
    近い将来、`headless: true`のデフォルトはChrome用の新しいヘッドレスモードになります。
    になります。詳しくは
    https://developer.chrome.com/articles/new-headless/ を参照してください。
    早めにオプトインすることを検討してください： puppeteer.launch()`に "new"`を渡すことで、早期にオプトインすることができます。
    バグに遭遇した場合は、https://github.com/puppeteer/puppeteer/issues/new/choose。
```

### Chromeのヘッドレスモードは元々通常モードと別だったぽい

[こちらのChrome公式ブログ](https://developer.chrome.com/articles/new-headless/)に解説が書いてましたが、以前はGooge Chromeのヘッドレスモードと通常モード（ヘッドフルモード）は別々に作られてた模様です。

**Chrome v112から** 新しいヘッドレスモードが使えるようになって、しばらくは後方互換もあるので両方使えるようにしてくれてる模様です。

> ![スクリーンショット 2023-11-24 10.31.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/12ed897e-30f1-d4a4-ff59-b0ad95969f90.png "スクリーンショット 2023-11-24 10.31.54.png")
> 引用: https://developer.chrome.com/articles/new-headless/

現状は古いヘッドレスモードを使う時は`chrome --headless=old`、新しいものを使う時は`chrome --headless=new`のフラグをつけて使い分けできるようです。

という感じでPuppeteerから起動する際も、明示的に古いモードを使いたいって話ではなければ以下のように

```js
    const browser = await puppeteer.launch({
        headless: 'new',
    });
```

と指定しましょうという話でした。

## 結局嬉しいのか

通常利用のChromeとヘッドレスモードもChromeで少し挙動が異なるといった場合が使い込んでいくとあったのですが、その辺が解消された（解消されやすくなった）感じだと思います。

古いモードで作ってた処理もそのうちアップデートしたいですね。
C++ コンパイル時間__DATE__をyyyy-MM-ddに変換

## 概要
`__DATE__`はNov 02 2011（月　日　年）のフォーマットです。
1. 月の文字列を数値に変換すること
2. sscanfでyyyy-MM-ddにフォーマットする

## コード
```c++
    auto getCompileDateTime = []()
        {
            auto ConvertMonthStrToNum = [](const QString& monthStr)
                {
                    if (monthStr == "Jan") return 1;
                    else if (monthStr == "Feb") return 2;
                    else if (monthStr == "Mar") return 3;
                    else if (monthStr == "Apr") return 4;
                    else if (monthStr == "May") return 5;
                    else if (monthStr == "Jun") return 6;
                    else if (monthStr == "Jul") return 7;
                    else if (monthStr == "Aug") return 8;
                    else if (monthStr == "Sep") return 9;
                    else if (monthStr == "Oct") return 10;
                    else if (monthStr == "Nov") return 11;
                    else if (monthStr == "Dec") return 12;
                    else return 0; 
                };

            QString compileDate = __DATE__;
            int day = 0;// 日
            int year = 0;// 年
            char buff[255] = "\0";

            sscanf(compileDate.toLatin1().data(), "%s %d %d", buff, &day, &year);

            QString monthStr(buff); // 月
            int month = ConvertMonthStrToNum(monthStr);

            QDateTime compileDateTime(QDate(year, month, day), QTime::fromString(__TIME__, "hh:mm:ss"));

            return compileDateTime;

        };
```
wslでnerves その31

# 概要
wsl(wsl2じゃない)でnervesやってみる。
qemu(x86_64エミュレータ、ラズパイじゃない)でやってみた。
生成したnerves_livebook.imgを、quemで起動してテストしてみた。
練習問題、やってみた。

# 練習問題
ectoを使え。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/dcea969e-7719-3eca-79c0-38a5c2b97601.png)

# セットアップ

```
Mix.install([
  {:ecto, "~> 3.10"}
])
```

# サンプルコード

```
data = %{}
types = %{name: :string, email: :string, age: :integer}
params = %{name: "alex", email: "alex@example.com", age: 47}

changeset =
  {data, types}
  |> Ecto.Changeset.cast(params, Map.keys(types))
```

# 実行結果

```
#Ecto.Changeset<
  action: nil,
  changes: %{name: "alex", email: "alex@example.com", age: 47},
  errors: [],
  data: %{},
  valid?: true
>
```

以上。
Dataverse 関連ツール

## Dataverse REST Builder
Dataverse Web API エンドポイントに対してのリクエストを作ってくれるやつ
https://chromewebstore.google.com/detail/dataverse-rest-builder/ioajdaokkkgjehbpiogakecdifaeaeho

https://www.youtube.com/watch?v=hjL-6I7G9U8

## SQL Server Management Studio (SSMS)
SQL Server Management Studio から Dataverse に接続してクエリをかけることはできるが、読み取り専用で、更新不可。キャッシュか何かの不明だがクエリ出来ないことが多い。

SQL を使用してデータを照会
https://learn.microsoft.com/ja-jp/power-apps/developer/data-platform/dataverse-sql-query

## XrmToolBox
https://www.xrmtoolbox.com/

単体で使うものではなく、ツールを複数追加して、Dataverse にクエリをかけたりいろいろできるっぽいもの。


### ログイン方法
1. [New] をクリック
1. [Microsoft Login Control ] をクリック
1. [User default configuration] のまま、[Open Microsoft Login Control] ボタンをクック
1. [Office 365] をクリック、[Login] をクリック
1. ダイアログが開くので入力
1. 環境を選択して、[Login] をクリック
1. New connection ダイアログが開くので、Name に適当に名前を付けて、[Finish] をクリック
1. All connection で作成した接続が出てくるので、選択して [OK] をクリック
Dataverse のテーブルの全行を削除する

1. Power Apps のページを開き、右上の歯車アイコンをクリック、[詳細設定]をクリック
1. 左上の [設定] のシェブロンをクリック、[データ管理]をクリック
1. [レコードの一括削除]をクリック
1. [新規]をクリック、[次へ]をクリック
1. [検索] 欄でレコードを削除したいテーブルを選択
1. 必要なら条件を指定、全行の場合は、このまま [次へ] をクリック
1. alert が開くので、[OK] をクリック
1. [次へ]をクリック
1. [送信] をクリック
Dataverse メモ

# メモ
- SharePoint リストとテーブルは、列に計算式が使えるなど非常に似ている。かといって、Dataverse のテーブルが上位互換ということもなく、別物。
- Dataverse の計算列はプレビュー中のせいか不明だが、制限が多い。テーブルの計算列では、Power Fx が使えるということになっているが、日付関係は使えない模様(Year(date_column) のような基本的な関数もエラー) (2023/11/13)
- SharePoint リストはテーブル作成時のみ Excel をインポートできるが、テーブルは後から追加でインポートすることも可能。
- SharePoint リストと同様、先に英語の列名(→ 内部名)で作成後、日本語に変更するテクニックはそのまま有効。
- 暗黙で "(接頭辞) + (テーブル名) + ID" という名前で内部的に主キー(≠プライマリ列)が作成されるため、明示的に同じ名前の列を追加することはできない。(値は Guid)
- Excel からインポートした場合、列名の "_"(アンダースコア)、"-"(ハイフン) は切り詰められる
- 将来的にフィルタしたい列には「検索可能」をチェックする。しないとフィルタ出来ない。
- 作成されたテーブルには、内部名として、接頭辞 cr761_ などがついた名前になる(テーブル一覧の名前列で確認できる)。
- 列名も接頭辞 cr761_ などがついた名前になる([スキーマ]-[列] で確認できる)。
- テーブル指定の UI によっては、接頭辞がついて表示されたり、接頭辞なしで表示されたり、外部名(内部名)で表示されたりいろいろなので注意

## プライマリ列 / プライマリ名列
「使用可能な最初の列」主キー/プライマリキーを連想するが、名前が似ているだけで別物。リストにしたときにリンクが付加される列らしい。重複可。※ドキュメントによって表記のゆれ有り

## オートナンバー列
文字列や日付を接頭辞にしたオートナンバーを生成できる。テーブル作成時にはこの列を作成できず、一旦テーブル作成した後に、オートナンバー列を作成するか、テキスト列から変更できるようになる。{DATETIMEUTC:yyyyddMM}-{SEQNUM:4}、シード値 : 0000 などの設定が可能。

## 検索列(ルックアップ)
データの種類 [検索] は紛らわしいが "ルックアップ" に相当。関連テーブルがなかなか出てこない場合があるので、しばらく待つ。

## タイムゾーン関係
- 日時は UTC に変換されてインポートされる。日本時間 2022/01/01 11:20 のデータは -9:00 されて、2022/01/01 2:20 で格納される。
- Excel インポート時、日付型を指定すると、自動的に「ユーザーローカル」になる。「ユーザーローカル」から「タイムゾーン非依存」へ変換できるが不可逆。テーブル作成時には指定できないため、テーブルを一旦作成後に指定する。グローバルでタイムゾーンを意識したようなものを作らないのであれば、タイムゾーン非依存列を使うのがよさそう。

### タイムゾーンが面倒な場合
先にテーブルスキーマを作成して、Excel データをインポートする場合 : 先に「タイムゾーン非依存」列を作っておいて、インポートする。
Excel からテーブルを作成する場合 : 最初からデータを +9:00 しておき、インポート後に列を「タイムゾーン非依存」に変換する。(インポート時には指定できない。)

参考) ユーザーローカルとタイムゾーン非依存のタイムゾーン関係の動き
https://github.com/MicrosoftDocs/powerapps-docs/blob/main/powerapps-docs/maker/data-platform/behavior-format-date-time-field.md
エンジニアは、考える力とチャレンジする力を磨くべき！

現代社会は、情報の民主化によって大きく変化しました。インターネットやスマートフォンの普及により、誰もが簡単に膨大な量の情報にアクセスできるようになりました。これは、これまで特定の人にしか与えられていなかった情報へのアクセス権を、すべての人に平等に与える画期的な変化です。

しかし、情報の民主化は、単に情報へのアクセスが容易になっただけではありません。それにより、人々は自分で情報を取捨選択し、自らの判断で行動する必要性が高まりました。これは、個人の思考力と判断力の重要性を高めるものです。

特に、エンジニアにとって、考える力とチャレンジする力は、今後ますます重要になるスキルです。エンジニアは、常に新しい技術や知識を学び、新しいことに挑戦していく必要があります。そのためには、自らの思考力と判断力を磨き、自立した存在になることが不可欠です。

本記事では、情報の民主化がもたらす社会の変化と、エンジニアが考える力とチャレンジする力を磨くために必要なことについて、解説します。

# イントロダクション
- 情報アクセスの民主化とその背景
- ネットとスマホの普及による社会の変化
- AIの普及によるさらなる社会の変化

# 情報アクセスの変化
- 昔の情報アクセス: 書籍、新聞など限定された情報源
- 現代の情報アクセス: インターネットとスマートフォンによる広範なアクセス
- 情報の偏りと民主化の影響

昔は、書籍や新聞等がメインで特定の人しか情報を持ってなく、偏った人による社会形成がありました。
ネットとスマホの普及で全ての人が同じ情報にアクセスでき、自らジャッジを行える時代、これが民主化の時代です。

# 自由と個人の責任
- 民主化がもたらす自由の概念
- 個人の判断力と情報の取捨選択
- 自らの道を選択し、未来を決定する能力

民主化とは自由。

自由の時代は、一層、個人個人の考える力が必要とされる時代になります。
自由なので自ら考えて情報を取捨選択し、道を選択して未来を決める事が出来ます。

# AIの役割と限界
- AIの普及と自動的な情報収集
- 生成AIの機能と限界: 過去データを基にした情報生成
- 人間とAIの判断力: 100%正確な答えを出すことの困難性

更にAIの普及で自動的に情報収集が行なえます。生成AIは、様々な過去データを収集し最適な確からしき情報を並べて、文章やソースコード等を生成します。
そのAIのアウトプットを使うのは人間です。人間も100%の答えを出すことは苦手でしたが、AIも同じく100%の答えを出す事は苦手です。
最後は、自分で判断する必要があります。

# 持続的なチャレンジの重要性
- 完璧な方法の不在と多様な試行の価値
- ピカソの事例: 1万点以上の作品制作と独特なスタイルの確立
- VUCAの時代は、変数が多すぎる
- 継続的な思考とチャレンジの重要性

情報の民主化とAIの普及により、人々は自分で情報を取捨選択し、自らの判断で行動する必要性が高まりました。これは、個人の思考力と判断力の重要性を高めるものです。

特に、エンジニアにとって、考える力とチャレンジする力は、今後ますます重要になるスキルです。エンジニアは、常に新しい技術や知識を学び、新しいことに挑戦していく必要があります。そのためには、自らの思考力と判断力を磨き、自立した存在になることが不可欠です。

ピカソは、1万点以上の作品を制作し、独特な抽象画を確立した芸術家です。ピカソは、常に新しい表現方法を追求し、失敗を恐れずにチャレンジし続けました。その結果、独特なスタイルを確立し、世界的な芸術家になりました。

エンジニアにとっても、ピカソのような持続的なチャレンジ精神が重要です。完璧な方法は存在しません。時には、100点満点の手法はないかもしれません。しかし、30点の手法を数多く試すことで、100点満点に近づくことができます。
更にの今VUCA時代では、考える必要がある変数が多すぎるのです。この多い変数をコントロールするのは、非常に難しく、フォーカスを絞りながら変数を減らし、色々な施策を繰り返す事が必要となります。

# 結論
- 今後の時代における重要なスキルとしての自己判断とチャレンジ精神
- 個々の責任と社会への影響

しっかり考え、チャレンジする。これを何度も繰り返す。
これからの時代は、これがとても重要なスキルとなります
mindの研究 その31 - 乱数でじゃんけんしてみる

# 概要
mindが謎なので調べてみた。
練習問題、やってみた。

# 練習問題
mindで、じゃんけんを書け。

# 参考にしたページ

https://qiita.com/t-tkd3a/items/460b6f42ea69051f1130

# サンプルコード

```
乱数種値は　変数。 

簡易小数表示とは　（小数　→　・）
	５桁で　小数形式で表示すること。

一様乱数とは　関数　小数出力
	Ｙ２は　変数
	Ｙ１は　小数変数
	乱数種値を　Ｙ２に　入れる
	Ｙ２を　１３　左シフトし、　Ｙ２と　ＸＯＲし、　Ｙ２に　入れる
	Ｙ２を　１７　右シフトし、　Ｙ２と　ＸＯＲし、　Ｙ２に　入れる
	Ｙ２を　１５　左シフトし、　Ｙ２と　ＸＯＲし、　Ｙ２に　入れる
	Ｙ２を　乱数種値に　入れる
	Ｙ２を　絶対値を　小数化し　Ｙ１に　入れる
	Ｙ１を　2147483648.0で　ｆ割り　Ｙ１に　入れる
	Ｙ１をもどす
。

メインとは
　結果は　文字列
　文字列１は　文字列
　数１は　変数
　数２は　変数
　合否は　変数
　乱は　変数
　乱数値は　小数変数
　20231124を　乱数種値に　入れる
　「乱数種値:　」を　表示し、　乱数種値を　数値表示し、　改行
　5を　回数指定し
　　乱数値を　クリア
　　※一様乱数()を　乱数値に　入れる
　　※「関数戻り値：　」を　表示し、　乱数値を　簡易小数表示し、　改行
　　一様乱数()に　4.0を　f掛けて　整数化し　1を　引いて　乱に　入れる
　　乱を　数値表示し　改行する
　繰り返す
　スタック検査し
　ここから
　　一様乱数()に　4.0を　f掛けて　整数化し　1を　引いて　数2に　入れる
　　「じゃんけん　　0, グー 1, チョキ  2, パー　　」を　表示する
　　文字列入力し　文字列１に　入れ
　　※文字列１を　表示し　改行する
　　文字列１を　数値変換し　数１と　合否に　入れ
　　文字列１が　「bye」に　等しい文字列　ならば
　　　打ち切り
　　つぎに
　　※数1を　数値表示し　改行する
　　もし　数1が　0と　等しく　かつ　数2が　0と　等しい　ならば
　　　「グーとグーで、あいこ」を　結果に　入れる
　　つぎに
　　もし　数1が　0と　等しく　かつ　数2が　1と　等しい　ならば
　　　「グーとチョキで、あなたの勝ち」を　結果に　入れる
　　つぎに
　　もし　数1が　0と　等しく　かつ　数2が　2と　等しい　ならば
　　　「グーとパーで、あなたの負け」を　結果に　入れる
　　つぎに
　　もし　数1が　1と　等しく　かつ　数2が　0と　等しい　ならば
　　　「チョキとグーで、あなたの負け」を　結果に　入れる
　　つぎに
　　もし　数1が　1と　等しく　かつ　数2が　1と　等しい　ならば
　　　「チョキとチョキで、あいこ」を　結果に　入れる
　　つぎに
　　もし　数1が　1と　等しく　かつ　数2が　2と　等しい　ならば
　　　「チョキとパーで、あなたの勝ち」を　結果に　入れる
　　つぎに
　　もし　数1が　2と　等しく　かつ　数2が　0と　等しい　ならば
　　　「パーとグーで、あなたの勝ち」を　結果に　入れる
　　つぎに
　　もし　数1が　2と　等しく　かつ　数2が　1と　等しい　ならば
　　　「パーとチョキで、あなたの負け」を　結果に　入れる
　　つぎに
　　もし　数1が　2と　等しく　かつ　数2が　2と　等しい　ならば
　　　「パーとパーで、あいこ」を　結果に　入れる
　　つぎに
　　結果を　表示し　改行する
　繰り返し。




```


以上。
mindの研究 その30 - mindで湯婆婆してみる

# 概要
mindが謎なので調べてみた。
練習問題、やってみた。

# 練習問題
mindで、湯婆婆を書け。


# サンプルコード

```
メインとは
　文字列１は　文字列
　文字列２は　文字列
　数１は　変数
　数２は　変数
　乱数は　バイト変数
　乱数に　２４３を　入れる
　「契約書」を　表示し　改行する
　「甲は油屋当主として、乙を油屋に雇用することを」を　表示し　改行する
　「契約し、労働に伴う対価の支払いを右の通り、約定する。」を　表示し　改行する
　「なお、一日の労働の対価は金百円とする。」を　表示し　改行する
　「甲　油屋当主　湯婆婆」を　表示し　改行する
　「乙」を　表示し　改行する
　「契約書だよ。そこに名前を書きな。」を　表示し　改行する
　文字列入力し　文字列１に　入れ
　文字列１を　文字列２に　入れる
　ここから
　　文字列１から　一文字切り出し　数１に　入れる
　　もし　数１が　０に　等しい　ならば
　　　打ち切り
　　つぎに
　　乱数に　５を　掛け　乱数に　入れる
　　乱数に　１を　引き　乱数に　入れる
　　もし　乱数が　１２７より　小さい　ならば
　　　数１を　数２に　入れる
　　つぎに
　　※数１を　一文字表示し　改行する
　繰り返し
　※数２を　一文字表示し　改行する
　「フン。」を　表示し　文字列２を　表示し　「というのかい。贅沢な名だねぇ。」を　表示し　改行する
　「今からお前の名前は」を　表示し
　数２を　一文字表示し
　「だ。いいかい、」を　表示し
　数２を　一文字表示し
　「だよ。分かったら返事をするんだ、」を　表示し
　数２を　一文字表示し　改行する




```


以上
まちがいさがし(pythonでAA)

以下の「**鬱**」の中、どれかが「**欝**」だよ、さがしてみよう。

ヒント:この画像は50x50文字。コードが読めれば見当がつくよ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3555292/12bb7340-7601-5e09-6e96-e0eff8f086ae.png)

## 以下のコードで書きました
```python
from PIL import Image, ImageDraw, ImageFont
import numpy as np

size = 50 # 画像サイズ
ofs_y = 55.0 / 256 # オフセット（フォントごとに異なる）
font = ImageFont.truetype('Koruri-Bold.ttf', size)

img = Image.new('1', (size, size), color='white')
draw = ImageDraw.Draw(img)
draw.text((0, -ofs_y * size), '鬱', font=font, fill='black')

data = np.array(img)

i = 0
for stride in data:
    for bit in stride:
        i += 1
        print("欝" if i == 1467 else "　" if bit else "鬱", end= "")
    print("")
```
デスクトップRAIDストレージをexFATにフォーマットしてmacOSにつなぐと壊れる

## はじめに

備忘録です。Qiitaは検索エンジンにかかりやすいので、こんな情報も誰かの役に立つかもしれないと思って書いています。タイトルの通りです。exFATにフォーマットしたHDDをmacOSに接続するとほぼ確実に壊れて接続できなくなるということがありました。

デスクトップRAIDストレージ WD My Book Duo

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/efa903dd-d6e5-ccd4-aa0e-8c1b311ce200.png" width=300 height=300>

https://www.westerndigital.com/ja-jp/products/external-drives/wd-my-book-duo-usb-3-1-hdd

「不正なディスクの取り出しが行われました」などのメッセージが表示される可能性が高いです。

## 対処法 - Windowsに接続する

一度おかしくなってしまうと、macOSではハードディスクを認識できなくなります。

その場合は落ち着いて、Windowsに接続します。Windowsではディスクの修復が必要といった表示が出ると思うので、ディスクの修復をします。出なければ、ディスクの一覧を確認して修復が必要であることを確認します。その後、ディスクを右クリックするなどして修復を行います。修復は数秒で終わります。おそらくディスク本体は壊れていないと推測されます。

## 結論

この分野に詳しくないのではっきりと原因はわかりません。しかし、「ハードディスクのスリープ」に問題があるようです。macOSの設定「省エネルギー」には、「可能な場合はハードディスクをスリープさせる」という項目があります。この項目をオフにすると、問題が発生しなくなりました。

![省エネルギー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/4ac79b26-fbe3-600f-c81a-cf698703572e.png)


憶測になりますが、macがハードディスクをスリープさせようとすると、ディスクの不正な取り出し、になってしまっているようです。

以上、中途半端な記事ですが、少しでも同じような症状で困っている人の参考になれば幸いです。
この記事は以上です。
Flutter側でXcodeのバージョンを切り替える方法

# 環境確認
```shell
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.3.6, on macOS 13.5.1 22G90 darwin-arm, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 15.0.1)
[✓] Chrome - develop for the web
[!] Android Studio (version 2022.3)
    ✗ Unable to find bundled Java version.
[!] Android Studio (version 2022.2)
    ✗ Unable to find bundled Java version.
[✓] VS Code (version 1.84.2)
[✓] Connected device (3 available)
[✓] HTTP Host Availability

! Doctor found issues in 2 categories.
```

# ゴール
Xcode15.0.1 -> Xcode14.3.1 へ変更したい

# 前提
バージョンが異なるXcodeが二つ以上インストールされていること

本記事のXcodeのパス

**Xcode 15.0.1のパス**
```
/Applications/Xcode.app/Contents/Developer
```

**Xcode 14.3.1のパス**
```
/Applications/Xcode14.app/Contents/Developer
```

# 手順
1. 使用しているXcodeのパスを確認
```
$ xcode-select --print-path 
/Applications/Xcode.app/Contents/Developer
```
※ 基本的に異なるバージョンでインストールされたXcodeは同じパスにあるので設定したいXcodeのバージョンのパスは以下のように確認できます

```
ls /Applications/
```


２. 使用したいXcodeのバージョンを選択
```
$ sudo xcode-select -switch /Applications/Xcode.app
```
３. もう一度設定が反映された確認
```shell
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.3.6, on macOS 13.5.1 22G90 darwin-arm, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 14.3.1)
[✓] Chrome - develop for the web
[!] Android Studio (version 2022.3)
    ✗ Unable to find bundled Java version.
[!] Android Studio (version 2022.2)
    ✗ Unable to find bundled Java version.
[✓] VS Code (version 1.84.2)
[✓] Connected device (3 available)
[✓] HTTP Host Availability

! Doctor found issues in 2 categories.
```
[AWS]猫でもわかるDirect Connect(Cloud Wan対応版)

## はじめに
この記事は[NTTテクノクロスAdvent Calendar 2023](https://qiita.com/advent-calendar/2023/ntt-tx) の 4日目の記事になります。


NTTテクノクロスの加藤です。
普段はメガクラウドチームにてAWS関連の業務をしています。

## 資料紹介
AWS Direct Connectを俯瞰して理解するためにまとめた資料です。あくまでも私個人が理解した内容をイメージ図にしたものです。そのため不正確な箇所もありますがそこは大目に見てください。

### 作成動機
私は図にして整理しないと理解が進まないタイプです。Direct Connectを勉強していた時に必要に迫られて描きました。

### 改版履歴
|年月|内容
|:-----------|:------------|
|2022年1月|作成着手|
|2022年3月|第1版完成(社内有識者レビュ2回実施)|
|2022年7月|第2版(専門NW対策時に加筆)|
|2023年2月|第2.1版(JAWS-UG 朝会 #42 LT発表用に誤記修正)|
|2023年11月|第3版(Cloud Wan追加、全体見直し)|

## 猫でもわかるDirect Connect & VPNイメージ図
![DirectConnect_nw_20231120_r1-DirectConnect.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366133/df881211-9969-6042-a916-232b128ad893.png)

### 【2024/09/02追記】
DirectConnect接続環境におけるAmazon Route53、特にリゾルバーのエンドポイントの役割を俯瞰して理解するために、Route53部分を拡大したイメージ図を作成しました。そちらも合わせて見て頂くとより理解が深まるかと思います。
- [猫でもわかるRoute53(Resolver,Hosted zone)](https://qiita.com/kamogashira/items/60a1f2720d016c167951)

### 作成効果
この図が頭の中に入っていたので、2022年3月受験ソリューションアーキテクトプロフェッショナル、2022年7月受験専門NWではDirect Connect関連の問題は悩まずに済みました。

### 想定読者
これからDirectConnectを勉強する人に一番需要があるかと思います。勉強する時にこの図を横に置いて出てきたキーワードが図のどこにあるかを確認するのがおすすめです。

### 業務貢献
現在初めてDirectConnectを含むシステム設計・構築をしています。そこでお客様へDirectConnectを説明する時の資料として活用しました。特にVIFの種類と接続機器、Route53 resolverの説明では重宝しました。またCloud Wanを提案したかったため今回第3版として加筆しました。

### 補足説明
資料名に偽りありです。Direct Connectとは別サービスのSiteToSiteVPN、ClientVPN、Cloud Wanも記載しています。AWSと外部の接続方法を取りまとめた資料としてみてください。

## おわりに
初期の完成度が低いバージョンに対して丁寧なレビュ＋適切なコメントをしてくださった同じチームの岩瀬さんには心から感謝しています。

### 2024/04追記
2023年12月に[CloudWatch Network Monitor](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/what-is-network-monitor.html)がGAされDirectConnectのNW監視が手軽に行えるようになりました。

### 2024/08追記：猫でもわかるシリーズ紹介
過去に私が作成した猫でもわかるシリーズ記事の紹介です。
- [猫でもわかるRoute53(Resolver,Hosted zone)](https://qiita.com/kamogashira/items/60a1f2720d016c167951)
- [猫でもわかるBLEA](https://qiita.com/kamogashira/items/e1a7852617ec1d7e3bf5)
- [猫でもわかった気になるRedshift Serverless(更新系限定)](https://qiita.com/kamogashira/items/df9bda2a7248b9af6b16)

## 参考文献
[AWS Direct Connectユーザーガイド](https://docs.aws.amazon.com/ja_jp/directconnect/latest/UserGuide/Welcome.html)
[AWS Black Belt Online Seminar「AWS Direct Connect」](https://pages.awscloud.com/rs/112-TZM-766/images/20210209-AWS-Blackbelt-DirectConnect.pdf)
[AWS Black Belt Online Seminar「AWS Cloud WAN概要」](https://pages.awscloud.com/rs/112-TZM-766/images/AWS-Black-Belt_2022_AWS_Cloud_WAN_Part01_1125_v1.pdf)
BunでSQLiteをとりあえず触ってみて動いたのでメモ

Node.jsが大好きなので、Bunを触り始めたのだけど、新しいだけあってネットを漁っても適切なサンプルコードがほとんど見当たらない。そこで、試行錯誤しながら自分で動かしてみたサンプルをメモしておきます。

今回は、Bunが高性能SQLite3ドライバーをネイティブに実装してるということなので、それを試してみた。BunのSQLiteドキュメントは下記にあります。
#### Bun>SQLite
https://bun.sh/docs/api/sqlite

インストールなどの話は前回の下記記事など参考にしていただければと思います。
まぁ、ファイル作って実行するだけなので簡単です。
https://qiita.com/toshirot/items/3af83303f95ac7baa546
下記の記事も参考になるかも
Bunかる〜く触ってみた[Bunの実行, nodeとの比較] 
https://qiita.com/yusei53/items/7347041cb8fbcfa280cc #Qiita @yuseidayo53より 

# あとで書き換えますが、最初にだーっと書いてみて動いたコード

```javascript:sqlite-test1.js
import { Database } from "bun:sqlite";
// データベースファイルの名前を指定
const dbFileName = 'test-1.sqlite';
// テーブルの名前を指定
const tableName = 'dogs';
// 新しいデータベースインスタンスを作成し、ファイルが存在しない場合はデータベースファイルを作成
const db = new Database(dbFileName, { create: true });
// テーブルが存在しない場合はテーブルを作成
const query1 = db.query('CREATE TABLE IF NOT EXISTS ' + tableName + ' (Id INTEGER PRIMARY KEY, Name VARCHAR(255), CreatedAt TIMESTAMP)');
query1.run();
// データをテーブルに挿入 p.s. id重複考慮してないので2件目は++してね
const query2 = db.query('INSERT OR IGNORE INTO ' + tableName + ' VALUES (1, "pochi", CURRENT_TIMESTAMP)');
query2.run();
// テーブルからデータを取得
const query3 = db.query('SELECT * FROM ' + tableName + ';');
query3.run();
// 取得した結果を配列で表示
console.log(query3.values());
```
実行と結果
```sh
#=======================================
#上記 sqlite-test1.js を
bun run sqlite-test1.js
#するとこんな感じで配列が返る。
[
  [ 1, "pochi", "2023-11-23 14:11:50" ], 
  [ 2, "hachi", "2023-11-23 14:17:44" ]
]
```
# db.query()と.run()を関数にまとめてみた
```javascript:sqlite-test2.js
import { Database } from "bun:sqlite";
// データベースファイルの名前を指定
const dbFileName = 'test-2.sqlite';
// テーブルの名前を指定
const tableName = 'dogs';
// 新しいデータベースインスタンスを作成し、ファイルが存在しない場合はデータベースファイルを作成
const db = new Database(dbFileName, { create: true });
// テーブルが存在しない場合はテーブルを作成
doQuery('CREATE TABLE IF NOT EXISTS ' + tableName + ' (Id INTEGER PRIMARY KEY, Name VARCHAR(255), CreatedAt TIMESTAMP);')
// データをテーブルに挿入 p.s. id重複考慮してないので2件目は++してね
doQuery('INSERT OR IGNORE INTO ' + tableName + ' VALUES (1, "pochi", CURRENT_TIMESTAMP);')
// テーブルからデータを取得
doQuery('SELECT * FROM ' + tableName + ';')

/**
 * データベースクエリを実行する関数
 *
 * @param {string} sql - 実行するSQLクエリ
 * @returns {void}
 */
function doQuery(sql){
    const query = db.query(sql);
    query.run()
    // 取得した結果を配列で表示
    let res=query.values()
    if(res) console.log(res);
}
```
実行と結果
```sh
#=======================================
#上記 sqlite-test2.js を
bun run sqlite-test2.js
#するとこんな感じで配列が返る。
[
  [ 1, "pochi", "2023-11-23 14:11:50" ], 
  [ 2, "hachi", "2023-11-23 14:17:44" ]
]
```
OutSystemsでメール送信機能を試してみた

## はじめに
ローコードプラットフォームのOutSystemsに触れる機会があり、
せっかくなので備忘録として書いてみた

OutSystemsってどういうもの・・？についてはこちらの公式ドキュメントを[参照](https://www.outsystems.com/ja-jp/)

## やったこと
メールを送信するサンプルアプリを作成
※無料環境ではメールの送信が出来なかったため、有料ライセンスで行った

## 実装
#### 1.OutSystemsのServiceCenterでSMTP設定を行う
OutSystemsのServiceCenter/Administration/Email ConfigurationでSMTP設定を行う

(参考：[OutSystems公式ドキュメント](https://success.outsystems.com/ja-jp/documentation/11/extensibility_and_integration/configure_outsystems_to_send_emails/))

実際の設定画面はこちら
![メール設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3243395/a70bcfaa-4e2a-ec36-0248-3d2052c640b3.png)

#### 2.ServiceStudioでメール送信機能を作成
OutSystemsのlogic/ServerActionでsendEMailを作成する

Send Emailアクションはこちら
![emailsetting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3243395/a680fff5-aeac-a18d-ce83-2ceda5487127.png)

**To** については送信したいユーザーを設定
**Email** については、テンプレートからResetPasswordを選択

選択したテンプレートはこちら
![newmail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3243395/a43957f5-8a83-0219-2b94-468757d6b752.png)

このテンプレートでは **CustomerName・CompanyName** の項目が入力必須なので設定を行う
テンプレートを使用するとNameが**SendEmail**から**ResetPassword**に変更されます

設定したsendEMailはこちら
![スクリーンショット 2023-11-24 18.57.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3243395/2e2e96c3-d7de-22e6-94f2-0114aba3c746.png)

#### 3.ボタンからsendEMailを呼び出す
適当な画面にボタンを設置し、onClickにsendEMailを設定する

設定したonClickはこちら
![ボタンアクション設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3243395/79bbe38e-b5b1-ffe5-86c1-2cf9b0b9a3de.png)

## 結果
画面でボタンを押下すると実際にメールが送られることを確認できた

ボタン一つだけ設置した画面
![画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3243395/4849ae44-3eea-cb15-2d05-e19a4800182b.png)

送信されたメール
![result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3243395/cd5f6c92-0684-82eb-8b1a-9927e3b82c37.png)


## まとめ
今回は公式ドキュメント内に書いていることを確認しただけになってしまったが、
パスワード再設定など、メール送信を含む発展的な機能の実装も行っていたため、
機会があればそういった機能について記事を書く予定です
ChatGPTにアプリを作ってもらう１

# この記事について

自分用のwebアプリをChatGPT(3.5) に全部作ってもらおうとしている途中。重くなってきたのでセッション切替記念に、次のプロンプト。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12729/edfc4b6f-8ad3-8f7e-532b-b2b0320fbde6.png)

以下、このプロンプトの結果。Qiita用に出力を再整形したこと以外は無編集。

---

# プログラミング冒険：中学生のための学びの旅

## 第1章: プロンプトの魔法
主人公はプログラミングの冒険に挑戦することになり、最初に待ち受けていたのはプロンプトの魔法だった。

### 1.1 不適切な質問とは？
主人公は最初、良い回答を得るためには質問の仕方が重要であることに気づきます。しかし、不適切なプロンプトを入力してしまい、思った通りの回答が得られないことに悩まされました。

```
ユーザー: 「Firebase使って書籍アプリを作りたい！」
```

このプロンプトではFirebaseを使用することはわかりますが、どの部分を具体的に尋ねているのかが不明確です。主人公は改めて質問を整え、具体的な助言を引き出すことに成功しました。

```
ユーザー: 「Firebaseでデータベースを設計する方法を教えて！」
```

### 1.2 具体的な質問の力

良い回答を得るためには、具体的な質問が重要であることを学んだ主人公。この経験を通じて、プロンプトの魔法がどれほど大切かを理解しました。

## 第2章: 問題の再発見
プログラミング冒険の途中で、主人公は同じ問題に何度も遭遇し、それが成長への鍵であることを知ります。

### 2.1 問題から学ぶ
主人公は何度も同じエラーや問題に直面し、それがプログラミングの学びの中で重要な役割を果たすことに気づきます。

```
エラー: 「v-bind:key ディレクティブがない！」
```

同じエラーが繰り返される中で、主人公はv-bind:keyディレクティブの重要性を理解し、リストの効率的な描画方法を学びました。

## 第3章: クライマックス：サーバーサイドの挑戦
物語のクライマックスでは、主人公がサーバーサイドの設計と開発に挑戦します。Firebaseを使用してバックエンドを構築する中で、新たな問題が待ち受けています。

### 3.1 Firebaseでの設計
主人公はFirebaseを使ってデータベース、ストレージ、認証などの設定を行い、サーバーサイドの基盤を構築します。

```
const firebaseConfig = {
  apiKey: "APIキー",
  authDomain: "XXXXXX.firebaseapp.com",
  projectId: "XXXXX",
  // ...（略）...
};
```

### 3.2 問題解決の冒険
サーバーサイドでも問題解決の冒険が続きます。主人公はセキュリティルールやCloud Functionsの設定に苦戦しますが、それを乗り越えることでプログラミングスキルが向上しました。

```
エラー: 「セキュリティルールが厳しすぎてデータにアクセスできない！」
```

## 結末

主人公のプログラミング冒険は、良いプロンプトや問題の繰り返しを通じて、深い学びと成長への扉を開きました。中学生の冒険もまた同じように、失敗やエラーを恐れずに挑戦し、新たな知識とスキルを手に入れていくことができるでしょう。未知の世界への探求心を持ち、自分なりの冒険を楽しんでください！
ChatGPTを使って資格取得を目指してみた

# はじめに

https://qiita.com/jun2/items/518623e60946e619dec3
にてOSSDB-Goldの取得を目指したときの話となります。
ChatGPTをどのようにして使ったのか？というところをご紹介したいと思います。

# 公式文書の要約

公式文書・・・難しいですよね。。私は文章を読むのが苦手なのでどんな本でも噛み砕くのに苦労します。
こういったときに「噛み砕いて」とか「要約して」とかはすごく助かりました。
また、これってこうゆう理解をしたけどあってる？など最終理解の確認を求めると同意してくれるのもGoodです。
一方あべこべなことを言ってくることもあります。
「ここではこう言ってたけど今回の話とは辻褄が合わなくない？」
などと聞くと間違えてました！やっぱりこうです！と訂正してきたりします。それがまたあべこべで突っ込んでいくと一番最初のあべこべな内容に戻って・・・と堂々巡りになりました。

# 一般例の表示

例えばpg_stat_activityなどどのように見えるんだろう・・・今環境がないからわからないや。
といったときに役立ちます。
pg_stat_activityの出力例を見せて！というとselectを実行したかのように見せてくれます。
ただ・・・バージョンが古く出力列の情報が古かったため原稿のバージョンの列には合わなかったりします。
こういった点は注意が必要そうです。

# 主要なオプションの抜粋（これはやっちゃだめだった）

公式文書を眺めていると、大量のオプションの暗記を求められます。
正直萎えてしまうため、この中で主要なオプションってなんですか？とついつい聞いてしまっていました。
基準は不明ですし、資格取得を目指すなら全部覚えるべきでした。
結果、ここで聞いた内容は一切試験には役立たなかったと記憶しています。

# 例題を出してもらう

そもそも上でも例題があまり出回っていないしかくになりますので、ChatGPTとしても知識がない模様です。
ただ、Postgresqlの一般的な知識の例題は作成・出題してくれました。
国家資格などであればどうなんだろう・・・と思い「応用情報技術者試験の模擬問題をお願いします」と聞いてみたところ、こんな回答。

```
DB Normalization Explained

ChatGPT 3.5

User
応用情報技術者試験の練習問題を下さい

ChatGPT
もちろんです。以下は応用情報技術者試験の練習問題の一例です：

問題：
データベースの正規化について説明してください。正規化の目的と、第一正規形から第三正規形までの主な特徴を述べてください。

答え：
正規化はデータベース設計のプロセスであり、データの冗長性を減少させ、データの整合性を維持するために行います。第一正規形では、すべての列がアトミックな値を持ち、重複がない状態です。第二正規形では、部分関数従属が排除され、主キー以外の列が主キーに完全に関数従属しています。第三正規形では、転送関数従属が排除され、すべての列が主キーに直接関数従属しています。




User
模擬試験をお願いします

ChatGPT
問題：
1. プログラミングのバグが発生した場合、デバッグの手順について簡単に説明してください。

答え：
バグが発生した場合、デバッグ手順は以下の通りです：

バグの再現手順を特定し、入力や状態を確認します。
コードを検査して潜在的なエラーを見つけます。
デバッグツールやログメッセージを使用して、プログラムの実行中に変数やステートメントの値を確認します。
問題を特定し、修正を行います。
修正後、再びテストを行い、問題が解決されたことを確認します。
2. クライアントサイドとサーバーサイドの違いについて簡潔に述べてください。

答え：
クライアントサイドは、ユーザーのブラウザ内で実行され、ユーザーに対するインタラクションを処理します。一方で、サーバーサイドはサーバー上で実行され、データベースへのアクセスやビジネスロジックの処理を担当します。クライアントとサーバーはネットワークを介して通信し、ウェブアプリケーションなどを構築します。

3. RESTful APIとSOAP APIの主な違いを述べてください。

答え：
RESTful APIは軽量でシンプルなアーキテクチャを採用し、HTTPメソッドを使用してリソースにアクセスします。一方、SOAP APIはXMLベースで厳格な仕様を持ち、通信にはHTTPだけでなく他のプロトコルも使用できます。RESTは状態を持たない(Stateless)ながら、SOAPは状態を持つことができます。

これらの問題に対する理解を確認してみてください。

```

ん〜・・・ま役に立つといえばそうだけど・・・というところですね。
そもそも国家試験は過去問などが充実しているため、ChatGPTに頼る必要はなさそうです。


# まとめ

結果として助けられたと思います。
特に私のように形式張った文章を噛み砕いて理解するという能力に劣っているような人にとっては無いよりは絶対マシだと思います。
欲を言えば、4.0を使ったほうがよりよいとは思いますが、結果取得できたのですから3.5でも十分役立ったでしょう。
Amazon EKSの耐障害性を考える

# はじめに
この記事はDevOps on AWS大全の一部です。
DevOps on AWS大全の一覧は[こちら](https://qiita.com/tech4anyone/items/b06f88035d27c6ef13b2)。

この記事ではAmazon EKSを耐障害性の観点から超詳細解説しています。

具体的には以下流れで説明します。

- Amazon EKSとは
- Amazon EKSのスケーラビリティ
- Amazon EKSのストレージ
- Amazon EKSのロギング


AWSの区分でいう「Level 200：トピックの入門知識を持っていることを前提に、ベストプラクティス、サービス機能を解説するレベル」の内容です。

# この記事を読んでほしい人
- Amazon EKSを採用するときのベストプラクティスを説明できるようになりたい人
- Amazon EKSの耐障害性に不安を感じている人
- AWS Certified DevOps Engineer Professionalを目指している人


# Amazon EKSとは
EKSとはKubernetesクラスターをAWS上でローンチするためのサービスです。
ECSと同じようにコンテナアプリケーションの自動デプロイやスケーリング、管理をするためのサービスですがEKSはオープンソースのKubernetesベースでありAWSオリジナルのECSとはAPIが異なります。

以前はEKS on EC2しかサポートしていませんでしたが、現在はEKS on Fargateもサポートしているため、Kubernetesをインフラストラクチャレイヤーの管理なしで使えるようになっています。

AWSではコンテナサービスを使いたい場合、まずはECS on Faragateを検討するのがベストプラクティスです。
EKSを検討するのはすでにKubernetesを利用しているあるいは可搬性を考慮する場合が多いです。

# Amazon EKSのスケーラビリティ
EKSのスケーラビリティを考える前にノード管理の仕方について抑え、その後スケーラビリティを考えるという流れで説明します。

## EKS on EC2
EKS on EC2の場合、ノードの管理の仕方が2パターンあります。
１つがマネージドノード型ノードグループ、もう1つがセルフマネージド型ノードです。

マネージド型ノードグループでは、Kubernetes アプリケーションを実行するためのEC2インスタンスを個別にプロビジョニングまたは登録する必要はありません。
1 回の操作で、クラスターのノードを作成、自動的に更新、または終了できます。

一方セルフマネージド型ノードの場合、自分でノードを作成しクラスタに登録する必要があります。
Amazon EKS最適化AMIと呼ばれる特殊なAMIがEKSで用意されているのでこれを使ってEC2インスタンスを構築し、EKSクラスタに登録するという流れです。

ここからはEKS on EC2のスケーラビリティについてです。
EKS on EC2はどちらのノードタイプでもノードがAutoScalingGroupで管理されています。
そのため、ノード内にポッドが多数起動し負荷が高くなるとAutoScalingが新しいノードとしてのEC2インスタンスを起動します。

ただし、ECSと異なりEKSはKubernetesの仕組みで動いているのでAWSの世界のAutoScalingGroupを直接意識することはあまりありません。
実際にはCluster-AutoscalerというKubernetes側の仕組みを使ってスケーリングし、その裏側でAutoScalingのAPIがCALLされているという仕組みです。

## EKS on Fargate
EKS on Fargateの場合はECS on Fargateと同様、管理対象がありません。
そのため、スケーリングについても特に設定することなく自動で使うことが可能です。

また、数年前はEKS on Fargateのスケーリング性能が悪すぎるため性能を求めるならEKS on EC2を選ぶしかないといわれていましたが、最近は性能が改善されているのでEKS on Fargateでも耐えられるケースが多くなっています。

# Amazon EKSのストレージ
EKSでストレージの設定をする際にはEKSクラスタ上でStorageClassマニフェストを指定しCSIに準拠したドライバを活用する必要があります。

EKSは様々なストレージオプションをサポートし、これにはAmazon EBSやAmazon EFSが含まれます。

EBSは単一のEC2インスタンスにアタッチされるブロックレベルのストレージを提供し、高いパフォーマンスと信頼性を実現します。

一方、EFSはマルチAZにわたる複数のEC2インスタンスで共有されるファイルレベルのストレージであり、スケーラビリティとシンプルな共有が可能です。

# Amazon EKSのロギング
Amazon EKSは、コントロールプレーンとノード/コンテナの2つのレベルで効果的なロギングを提供します。

## コントロールプレーンのロギング
コントロールプレーンロギングでは、APIサーバーやスケジューラーなどのKubernetesマスターコンポーネントのアクティビティをCloudWatch Logsに自動的に記録します。
これにより、クラスタのパフォーマンスや問題のトラブルシューティングが容易になります。

## ノード/コンテナのロギング
ノードとコンテナのロギングでは、FluentdあるいはFluent Binを使用してログデータをCloudWatch Logsや他のカスタムロググループに送信できます。
これにより、アプリケーションとインフラストラクチャの活動を監視し、問題の特定と修正が迅速に行えます。


# まとめ
この記事ではAmazon EKSを耐障害性の観点から超詳細解説しました。

- Amazon EKSとは
- Amazon EKSのスケーラビリティ
- Amazon EKSのストレージ
- Amazon EKSのロギング

次回はKinesisシリーズの耐障害性を考えます。
Pythonで「ブール値(True、False)の使い方」の動作を確認してみた

# 概要

Pythonで「ブール値(True、False)の使い方」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/python/num/index7.html

# 実装

以下のファイルを作成しました。
```sample.py
flag = True
if (flag):
    print("Succeeded")
else:
    print("Failed")

print(True + 8)
print(False + 2)

print(str(True) + " is 1")
print(str(False) + " is 0")
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
Succeeded
9
2
True is 1
False is 0
```

# まとめ

何かの役に立てばと。
MySQL で複数種類の複合ユニーク制約をつける  (NULLも許容) (+Railsのマイグレーション例)

# 概要

知らなかったが MySQL で複合キーのユニーク制約を付けた場合、nullのあるカラムは許容してくれるみたいだ。

たとえば `column_1` と `column_2` で複合ユニーク制約のあるテーブルで、 以下2個のレコードを追加した場合、  ユニーク制約に引っ掛かりそうだが許容してくれる


```
column_1の値: AAA
column_2の値: NULL
```

```
column_1の値: AAA
column_2の値: NULL
```

こうすると例えば、1テーブルで複数の複合ユニーク制約があっても、問題なく扱うことが出来る

たとえば `column_1 / column_2` の組み合わせと `column_3 / column_4` の組み合わせでそれぞれ複合ユニーク制約がある場合、片方の組み合わせはNULLでも問題なくなるのだ

```
column_1の値: NULL
column_2の値: NULL
column_3の値: YES
column_4の値: YES
```

```
column_1の値: NULL
column_2の値: NULL
column_3の値: YES
column_4の値: NO
```

# Ruby on Rails でのマイグレーションの例

普通に複合ユニーク制約を複数追加するだけで良い

```rb
class AddUniquenessToExampleTable < ActiveRecord::Migration[7.1]
  def change
    add_index :examples, [:column_1, :column_2], unique: true, name: 'index_examples_uniqueness_1'
    add_index :examinees, [:column_3, :column_4], unique: true, name: 'index_examples_uniqueness_2'
  end
end
```


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
残業を「ほぼ」0で開発プロジェクトを終えた話

# はじめに

まず、風呂敷を広げた題目ですが、私自身小規模なプロジェクトしか取り扱いません。
人の管理もし易いですし、納期も比較的穏やかな中、発生しそうになった時間外に対しての対応をどのようにしたか？について記事にします。
大プロジェクト・超短納期などの方には「綺麗事だ！」と思われてしまうかもしれませんが、何かしらの解決のエッセンスにでもなれば幸いです。
また、プロジェクトには開発経験が豊富なプレイヤーはいません。
開発経験豊富なプレイヤーには下記は当てはまらないだろうとも思いますので、ご承知の上御覧ください


# そもそもなぜ時間外が発生するのだろうか？

簡単な理由は「遅れているから」、「突発的なトラブルが発生し解消を試みないと遅延が発生しうるから」、「外的要因にて待たなければ行けないから」というところなのかなと思っています。
最後はある程度致し方ないでしょうが、調整はできないものか？というところは一考してもらう必要があります。
では前2つについてはどうでしょう？これら2つは私のプロジェクトにおいても部下から言われました。
一見すると仕方ない理由に見えますが、深ぼっていくとそうでもない場合があります。
一体どのような経緯で上記2つを報告されたのでしょうか？

# そもそも遅延していなかった

「遅れているので残業したいです。」
私のプロジェクトでは相手のスキルレベルに合わせて工程の粒度を変えて指示しますが、その単位で終了日・進捗率を入れさせています。管理のため、毎日進捗率をいれるよう指示するのですがなかなか0%から進みません。これでは確かに「遅れています」が、そもそも本当に0%なんてあるのでしょうか？
よくよく聞いてみると、工程内での進捗がそもそも把握できていない模様でした。
一番細かい粒度はXX取得APIの設計書を作成する、XX画面の設計書を作成する。程度の内容ですが、その中で今自分がどの程度の進捗があって、それが遅れているのか？進んでいるのか？というのがわからない模様です。
ここから更に細かくすると、パラメータの条件の設計を行う。エラーパターンの設計を行う。などというところになりますが、できれば将来的にはもっと荒い粒度で指示を出せる人員になってほしい（PLになるために自分で工程を分析できるようになってほしい）というところもあります。
この状況を踏まえ改めて内容を確認し、進捗率を確認してみるとそもそも遅滞していないことがわかりました。
全体でどのくらいの作業が発生する予定で、そのうちどのくらいが完了したか？というのは経験を積めば感覚的にわかったりするものですが、経験が浅いうちは書き出しして消し込んでいくことで自分の正確な進捗率を把握させるといのは良さそうです。
私は作業に飽きるとだいたいこんなことをやっています。で、自分の立ち位置を見てなんだ楽勝じゃんと思えばなんなら他の仕事をして憂さ晴らししたりしています笑

# リカバリ手段が時間外のみである

私にも原因があるのですが、タスクをふる際良くも悪くも機械的です。
過去のプロジェクトの実績から設計・実装・テストにかかる割合と規模感の割合・個人の力量から計算式を作って割り当てていきます。これは感覚的なブレを作りたくないことからやっていることです。
規模感と言ってもそこまで粒度を細かくしておらず、中には最小単位が大きすぎて振り過ぎなタスクも存在します。また、テストもこんな時間かかるものじゃないだろうと思っているタスクもあるため実装で遅れても内容によってはテストや皇族のタスクで十分リカバリ可能な場合があります。
また、よほど無理がある場合は私が余力のある人に振りなおすことも可能です。

https://qiita.com/jun2/items/496b492d3bbc95ceaf4c
にも書きましたが、真面目な子が多いので、自分ですべてなんとかしようという意識が強いのでしょう。
他にリカバリ手段はないか？そもそも残業で賄えるものなのか？など一旦考えさせてみると意外と時間外は不要だったりします。

# 終わりに

別に時間外が悪とはいいません。なんなら給与の面からしたら私は適度にやりたいと思っているほどです。
が、プロジェクトとして時間外0で予定見積もり通り完了させました。というのはこれほどの成果はないと信じてやってきた次第です。
一方教育面ではある程度苦労は必要だと思います。技術者として思い悩みときには夜までやったタスクを達成した経験は絶対に糧になります。
2〜3年目のほぼ新人であればあえてそのまま時間外させたかもしれません。
今回はそうでなかったので、もう少し難しいことを求めたというところでしょうか。
プロジェクトではときには私も「余力のある人員」として開発していたりします（ここで本当の遅延は埋めたので、ちょっとずるに近いですが）皆様のプロジェクトの規模や条件は異なるかもしれませんが、少しでも役に立つ記事であればと思います。
NestJS から MySQL に接続する

# はじめに
この記事では、NestJS から MySQL への接続手順について記載します。

# 開発環境
開発環境は以下の通りです。

- Windows11
- VSCode
- Node.js 20.5.0
- NestJS 10.0.0
- TypeScript 5.1.3
- MySQL 8.0.33
- MySQL2 3.6.3
- TypeORM 0.3.17

# パッケージのインストール
MySQL への接続に必要なパッケージをインストールします。

```powershell
npm install --save @nestjs/typeorm typeorm mysql2
```

```powershell
npm install --save-dev @types/node
```

# ```TypeOrmModule``` のインポート
次にルートのモジュールである ```AppModule``` に ```TypeOrmModule``` をインポートします。
```forRoot()``` の引数に MySQL への接続情報を記載します。

```app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CatsModule } from './modules/cats.module';
import { CatsService } from './services/cats.service';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'password',
      database: 'database',
      entities: [],
      synchronize: true,
    }),
    CatsModule,
  ],
  controllers: [AppController],
  providers: [AppService, CatsService],
})
export class AppModule {}
```

:::note warn

```synchronize: true``` は、データベースがアプリの起動ごとに自動で作成されるかどうかに関するオプションになります。そのため、本番環境では利用しないでください。
:::

# 参考
- [Database](https://docs.nestjs.com/techniques/database)
- [Data Source Options](https://typeorm.io/data-source-options)
Swiftで、map, filter, reduceの使い方

## 配列を操作するときに使うメソッドですね。

全体のコードはこんな感じです。
```swift
// 文字列の配列を作成します
let words = ["apple", "banana", "cherry"]

// mapを使用して各要素の文字数を取得します
let wordLengths = words.map { $0.count }
// 結果: [5, 6, 6]

// filterを使用して5文字以上の単語のみを抽出します
let longWords = words.filter { $0.count >= 5 }
// 結果: ["apple", "banana", "cherry"]

// reduceを使用して全ての単語を結合します
let sentence = words.reduce("", { $0 + " " + $1 })
// 結果: " apple banana cherry"
```

## filterを使った例
filterメソッドは、配列の値で条件に合うものだけ取り出すものです。

```swift
// filterは、コレクションの要素を条件に従ってフィルタリングするメソッドです。
let fruits = ["apple", "banana", "orange", "grape", "peach"]

// appleだけを取り出した配列を作る
let apple = fruits.filter { $0 == "apple" }
print(apple)

// appleとgrapeを除いた配列を作る
let filteredFruits = fruits.filter { $0 != "apple" && $0 != "grape" }
print(filteredFruits)
```

## mapを使った例
mapメソッドは、配列の要素を変換した新しい配列を作成する。

```swift
let fruits = ["apple", "banana", "orange", "grape", "peach"]

// 例1: 配列の要素を大文字に変換する
let uppercasedFruits = fruits.map { $0.uppercased() }
print(uppercasedFruits) // ["APPLE", "BANANA", "ORANGE", "GRAPE", "PEACH"]

// 例2: 配列の要素をInt型に変換する
let numbers = ["1", "2", "3", "4", "5"]
let intNumbers = numbers.map { Int($0) }

// 例3: 配列の要素を新しく作成した構造体に変換する
// 多次元配列で、商品名と値段を書く
let goods = [["name": "apple", "price": 100], ["name": "banana", "price": 200], ["name": "orange", "price": 300]]

// 商品名と値段を格納する構造体
struct Goods: CustomStringConvertible {
    let name: String
    let price: Int

    var description: String {
        return "Goods(name: \(name), price: \(price))"
    }
}

// 構造体に変換する
let goodsStructs = goods.compactMap { dict -> Goods? in
    if let name = dict["name"] as? String, let price = dict["price"] as? Int {
        return Goods(name: name, price: price)
    } else {
        return nil
    }
}
print(goodsStructs)
```

## reduceを使った例
reduceメソッドは、配列の要素を連結(結合ともいう)するメソッド。このコードだと、苗字と名前の間に、スペースを入れて、配列の値を結合している。

```swift
let names = ["田中", "太郎", "佐藤", "二郎", "山田", "花子"]

// 苗字と名前の間に半角スペースを入れて連結する
let result = names.reduce("", { acc, name in
    acc + " " + name
})

print(result)// 田中 太郎 佐藤 二郎 山田 花子
```

## 参考にしたサイト
今回は、こちらのサイトを参考に学習しました。
昔お世話になった、日本語でSwiftの解説がされているサイト

https://swift.codelly.dev/guide/%E3%82%B3%E3%83%AC%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E5%9E%8B/sequence%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB.html
Slingbox 350を分解してみた

ハードオフで330円で購入しARM SOCかと想像したのですが、外れてarcとかいうCPUのようです。シリアルも見当たらないので部品取りにしようと思います。

![IMG_20231124_064315.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/6dc6b530-90f2-cd43-8d76-7006dc07ca77.jpeg)

シリアルがないので、製品を作った会社では開発は行わず、チップメーカーの提供するファームウエアをまったくいじらずに、そのまま使っているのではないかと思われます。

使えそうな部品

ADV7181C - NTSCデコーダー(0.5mm 64pin)
THS7373 - ビデオバッファ
SSM2604 - オーディオコーディック
PI5PD2065WE - USBパワーコントロール
78Q2123 - Ethernetトランシーバー
25P10VP - 1 MBit SPI Flash
12.2MなどTXC社の水晶いろいろ
表面実装部品いろいろ

コンデンサーはニチコンで結構いい部品が使われています。コストをあまり考えずに設計されたようにも見えます。

変換基板のほうが高くつきそうです。 ^ ^;

分解は結構面倒でゴム足の前面側の下に二本ネジがあるのと、がっちりはめ込まれています。

D端子 RGBケーブルも入っていたので、これだけでも元がとれます。

中に埃がかなりあったので、長期間利用されたものと思われます。

ADV7181Cに1325と入っているので2013年25週に製造されたもののようです。

5V 3AのACアダプタも入っていましたが、長期間利用された形跡があるので、あまり期待しないほうがよいかもしれません。

ハードオフは無限の部品箱です。
GradleプロジェクトのJava17 -> 21にしたときにハマった

# 背景
ある個人開発のJava(Gradle)プロジェクトをJava17 -> 21に引き上げると、プロジェクトから魑魅魍魎が発生してしまいました。  
これを解消すべく、以下を試していきました。  

私の環境はIntelliJのCommunity版を使用しております。

# やったこと  
## build.gradleのsourceCompatibilityを21に引き上げ  
```gradle
java {
	sourceCompatibility = '21'
}
```  

これだけだと、Gradleタスク実行時に  
```
エラー: 21は無効なソース・リリースです
```
が発生しました。  

## IntelliJのGradle設定変更  
Ctrl + Alt + Sで設定を開き、「ビルド、実行、デプロイ」-> 「ビルドツール」 -> 「Gradle」のGradle JVMを21に変更。  
しかしこれでも以下が発生した。
```
Execution failed for task ':compileJava'.
> java.lang.NoSuchFieldError: Class com.sun.tools.javac.tree.JCTree$JCImport does not have member field 'com.sun.tools.javac.tree.JCTree qualid'

```  

## lombokの更新
どうやらlombokを1.18.30以上に引き上げないと上記エラーが出るようです。  
素直にbuild.gradleのdependenciesを変更し、  
```gradle
	compileOnly 'org.projectlombok:lombok:1.18.30'
	annotationProcessor 'org.projectlombok:lombok:1.18.30'
```
としました。すると次のエラーが再び発生。
```
Unsupported class file major version 65
```

## Gradle wrapperのバージョン引きげ  
gradle-wrapper.propertiesの以下を7.6.1 -> 8.4に変更  
```properties
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
```
これでTaskが正しく実行されるようになりました。

## 参考  
https://volkruss.com/posts/a001/  
https://stackoverflow.com/questions/77171270/compilation-error-after-upgrading-to-jdk-21-nosuchfielderror-jcimport-does-n  
https://tech.omablo.com/archives/865
github actions をローカルでテストできる act で遊ぼう

この記事は [一分で読める小ネタのカレンダー | Advent Calendar 2023 - Qiita](https://qiita.com/advent-calendar/2023/raki) の１５日目

# act

- [nektos/act: Run your GitHub Actions locally 🚀](https://github.com/nektos/act)
- github actions のワークフローを編集して、いちいちコミットしてプッシュしてからテストするのは面倒くさい
- act を使えばローカルでワークフローを実行して試せる（できないこともあるけど）
- 実際にワークフローをテストするよりも、何ができるのか、どう書けばいいのか、を練習するのに向いている（業務で使うワークフローは規模が大きかったり難解だったり実行時に制限があったりしてローカルでテストするのは向いてないことも多い）
- 特にコンテキスト（ワークフロー実行時に与えられる情報の塊）を確認したり、組み合わせたりして使い方を理解すれば、実際に動作しているワークフロー側での失敗を極力避けられる（かもしれない）
- [GitHub Actions のドキュメント - GitHub Docs](https://docs.github.com/ja/actions) を見ながら、できることややりたいことを模索して欲しい

本文はここまで。以下は時間外ｗ

# my-examples-github リポジトリ

- 作っておくと便利
- act を利用することでワークフローに関するゴミコミットは避けられるので、my-til でも足りる
- が、issue template 等の他のことでも使えるし、github に関することを集めていくとそれなりになるので、わけてあると見やすい（かもしれない）
- あと git についても一緒にまとめるならわけてあると見やすい（これは確実）
- my-examples- がたくさんあったほうがやってる感でるので、そういうのがモチベーションになるなら作る、めんどくさいから１つのリポジトリで十分なら作らない、という感じで

# act でやるテスト

- pre-commit を既に試したなら pre-commit ワークフローを動かしてみる
- 新しいワークフローを作って [コンテキスト](https://docs.github.com/ja/actions/learn-github-actions/contexts) を出力してみる
- if 文の使い方
- step の output とその拾い方
- on.workflow_dispatch で手動実行と input で変数渡し
- on.pull_request で実行された場合に input の値が入ってこないことを確認
- [Workflow dispatch input environment variables are empty · Issue #1365 · actions/runner](https://github.com/actions/runner/issues/1365) で解決方法を確認
- composite action （ワークフローの別ファイル化）
- ジョブの複数実行（A->B-C,D->E）のようにジョブが成功したら別のジョブを実行など
- gh を使って issue 作成など
- 他にもパッケージやリリースなどいろいろできるのでちょっとずつ試して欲しい

# 作ってみようワークフロー

- on.schedule を使ってスケジュール実行させる
- 毎日、毎週、毎月などで issue を作成するようにすると、自分向け定期タスクの管理ができる。自分をアサインしておくと、github のホーム画面で issue が確認できるので便利
- 文面を変更したり、ラベルを付けたり工夫する
- スケジュール実行で単純な月初日実行は（1日を指定するだけなので）楽にできる。が、日本時間で1日0時指定実行には工夫が必要になる（utc な cron あるあるな）ので、実現方法を考えてみよう。稀に必要になるよ。。。
- ちなみに act ではスケジュール指定実行はできない（？）ぽくて、`act schedule` を実行すると、スケジュール実行できるワークフローが全部動くっぽい

# その他

- github actions のベストプラクティスを学ぶ（人のを見るだけじゃなくて自分なりのプラクティスを考えるの大事）
- git でローカルブランチを残さない運用（git に慣れたらね）で act を使うとバグるというか、ワーニングがたくさん出るので、act を使う時はデフォルトブランチをローカルに作っておく

# 改善依頼

- act の便利な使い方とか
- スケジュール実行の仕方を知っているぜとか
- こんなワークフローを作っているぜとか

# おまけ

<details><summary>日本時間1日0時を指定してスケジュール実行の解答例</summary>

```yaml
on:
  schedule:
    - cron: "0 15 29 2 *"  # 2024/02/29 来年以降は 28 にして（うるう年をさぼる
    - cron: "0 15 30 4,6,9,11 *"  # 小の月
    - cron: "0 15 31 1,3,5,7,8,10,12 *"  # 大の月
```

- UTC なので 15時を指定する（+9hで0時）
- UTC なので日にちは月末日でなければならない
- 月ごとに実行日を変えてあげればいい
- パズルみたいで面白いね
- [add timezone support to scheduling workflow runs with cron · community · Discussion #13454](https://github.com/orgs/community/discussions/13454)

</details>