OmniAICreator/Qiita-1.07M huggingface dataset:
React + TypeScript + Vite + goya(ブラウザのみで形態素解析)

# React + TypeScript + Vite + goya(ブラウザのみで形態素解析)

コード -> https://github.com/HDYS-TTBYS/goya-app

goya -> https://github.com/Leko/goya?tab=readme-ov-file

Goya は Rust で書かれた日本語の形態素解析ツールです。
主な目標は、ブラウザやその他のJavaScriptランタイムで形態素解析を行うためにWebAssemblyにコンパイルすることです。さらに、CLI やRustでも使用できます。

react環境を作成

```bash
npm create vite@latest
cd vite-project
npm i goya-core goya-features
```

wasmをpublicにコピーする

```bash
cp /home/hdys/goya-app/node_modules/goya-core/web/goya_core_bg.wasm ./public \
&& cp /home/hdys/goya-app/node_modules/goya-features/web/goya_features_bg.wasm ./public
```

App.tsx

```js
import { useState, useEffect } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'
import goya_core, { parse } from "goya-core/web/goya_core"; //インポート
import goya_features, { get_features } from "goya-features/web/goya_features"; //インポート

function App() {
  const [text, setText] = useState("")
  const [goya, setGoya] = useState([[]])
  useEffect(() => {
    WebAssembly.compileStreaming(fetch("goya_core_bg.wasm")).then((mod) => //静的アセットから読み込み
      goya_core(mod) //初期化
    );
    WebAssembly.compileStreaming(fetch("goya_features_bg.wasm")).then((mod) => //静的アセットから読み込み
      goya_features(mod) //初期化
    );
  }, [])

  const handleOnChenge = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
    setText(e.target.value)
    if (e.target.value === "") {
      setGoya([[]])
      return
    }
    // 形態素解析
    const lattice = parse(e.target.value);
    const morphemes = lattice.find_best();
    const features = get_features(morphemes.map((morph) => morph.wid));

    const result = new Array();
    morphemes.forEach(({ surface_form }, i) => {
      const feature = features[i];
      feature.unshift(surface_form)
      result.push(feature)
    });
    setGoya(result)
  }

  ...

```

github pagesで公開 -> https://hdys-ttbys.github.io/goya-app/
Visual Studio と C++ で RoboCup Junior Rescue Simulation環境構築

Pythonの場合についてはRCJJの技術委員会が[解説](https://drive.google.com/file/d/1WNk7bWOrg5rjO7UffzQb6TvxIeStIpyZ/view)を出しているのですがC++についてはなかったので紹介します。※Webotsのサイトにあります。

1. まず、[RCJJの資料](https://drive.google.com/file/d/1WNk7bWOrg5rjO7UffzQb6TvxIeStIpyZ/view)に沿ってWebotsとErebusの環境構築をします。  
1. [Visual Studio](https://visualstudio.microsoft.com/ja/downloads/)をインストールします。無料版で構いません。  
1. Webotsの`ファイル→New→新規のロボットコントローラ`をクリックします。  
    <img width="600" alt="photo" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2449798/adac0178-1f95-f874-6a66-1f7cf42f3764.png">  

1. 次へ
    <img width="500" alt="photo" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2449798/4c5db05a-e1a9-2264-b4f5-8f1166fe0df7.png">  
1. C++を選択
    <img width="" alt="photo" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2449798/13cf86b1-408a-00b3-739a-cfc943689e84.png">

1. Microsoft Visual Studio を選択
    <img width="" alt="photo" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2449798/b594d242-0cae-ce11-b01c-e356cb6fd3b3.png">
1. コントローラの名前を設定
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2449798/942eee7e-8776-57d3-9fde-eb6ab1e223cd.png)
1. 完了を選択
    Visual Studioが勝手に開かれます。  
1. コンパイルするとexeファイルが生成されます。  
    そのファイルをロボットウィンドウで選択すると実行されます。
マクロを実行する上でトライキャッチ、並列などの注意点

## 1,はじめに
現場配属後、下記の事象がすぐに起こりました。

:::note alert
(1)マクロによるエラーが起きても処理が終わらずに稼働したままということが現場で起こりました。
(2)Orchestratorのトリガー(時間実行)からだとマクロが稼働しない。
:::

ロボットの構造がいくつかおかしいところがあって、どういう意図でこの構造で開発をしたのかを聞きたかったですが、数年前に開発されたロボットでこのロボットで使用しているマクロの管理者ですら答えをしなかったです。
なので処理を1から見直しました。
他の案件もあったため、改修完了までに約1ヵ月かかりました。

:::note warn
補足：マクロの管理者のスキルは高くないです。(例えになるかわからないですが、withの使い方も知らないです。)
そのため、下記のことからUiPathを修正しようと思いました。
(1)マクロ事態を修正すると管理できなくなること。
(2)マクロ管理者は忙しい方だったので、打ち合わせ工数をできるだけ削減したい。
:::


## 2,修正前のロボットの構造
下記のようにロボットが開発されていました。(ロジックが同じですが変数などは異なります。)
↓(1)マクロ実行の全体像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327229/48d1dfca-8ab9-3838-ca99-f5bab85a8ea7.png)
↓(2)(1)のExcelプロセススコープ内の小さくなっているトライキャッチの中身
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327229/e2970888-5ee7-98ca-40e4-3847615f617e.png)

## 3,修正後のロボットの構造
↓(1)マクロ実行の全体像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327229/e774e7d6-9611-a09c-53fa-6e86210f5c2c.png)
↓(2)(1)のExcelプロセススコープ内の小さくなっているトライキャッチの中身
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327229/77281f65-ea10-eaa2-0b09-b10fdac920a1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327229/85b1ac8b-ffb3-f1cc-46b8-b054065aeb83.png)
↓(3)並列のプロパティ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327229/0b36d19b-5dd0-7c47-a313-b6b14b4a8fb4.png)
↓(4)Excelプロセススコープのプロパティ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327229/1d1d848b-edd0-395b-60bf-bbf2eb8ebbd1.png)
↓(5)正常終了したときのログ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327229/1f560df6-9595-440c-a0e4-1d20aca4edf0.png)
## 4,注意点について
:::note alert
(1)トライキャッチを乱用しないこと。
:::

トライキャッチは便利ではありますが、トライキャッチ内にトライキャッチをすると意図したところでエラーになってくれないことが多いです。
そのため、トライキャッチ内にトライキャッチをしたときにどういう動きになるかを実験をした方がいいです。
私はできるだけこの構造にならないようにできないかを考えています。
理由はテストケースが多くなること、後任者が保守運用に困り、ロボットの説明資料に記載する量が多くなるためです。

:::note alert
(2)並列の処理の仕方を理解すること。
:::

この問題が生じるまでは並列に有用性を感じていなかったです。
しかし、今回の事象により並列は使いやすく、条件分岐をカットでき、上下のスクロールが少なくなっていいなと有用性を感じました。
マクロ実行の場合は3,(3)の並列のプロパティをTrueにすること。
Flaseにするとどうなるかは自分で試して理解した方が勉強になると思うので、試してみてください。
その時に、有効性を感じると思います。

:::note alert
(3)マクロのエラーをパターン分けしないこと。
:::

修正前は**マクロのエラーの1パターンのみ**をスクショする仕様でした。
修正後は**マクロのエラーを全パターン**をスクショするように変更しました。
マクロが正常終了したときに「完了」というメッセージボックスを出力させ、これがあるかないかでエラーであるかを判定させるようにしました。
それの開発方法は3,(1),(2),(4)を見てほしいです。
特に3,(4)のプロパティの可視にチェックすることを忘れないでください。
普段はここのチェックを外しますが、マクロによるエラーではなく、PCの環境によるエラーもある場合も考慮して、可視にチェックしました。

## 5,おわりに
現場に行くと引継ぎがうまくされていないロボットに工数をかける事例が多いです。
また明らかにおかしい構造のロボットもあります。

:::note warn
これらに対して工数を多く使うため、常に自分がいなくなること(後任者にいつでも引き続きができる状態)を想定しながら開発をすることが大事だと思います。
:::
ポイントとしては下記の通りです。

:::note info
(1)個々のアクティビティの仕様を理解した上でシンプルに開発すること
:::

できるだけ使用するアクティビティは少ない方がいいと思いますが、それだと保守運用時には難しくなってしまいます。
それを阻止するために開発の意図を注釈に残しながら、実行中の動きを理解してもらうためにログを入れることが大事です。

:::note info
(2)説明の資料・動画などを残すこと
:::

私は引継ぎは1日で終わらせたいと考えています。
そのために、私は「説明の資料・動画」を残しています。
特に動画をよく使用しています。
動画を渡せばあとは自分で確認してわからないことがあれば聞いてくださいとすると自分の工数を確保できます。

引き継ぎ方については後日書いてみようと思います！
ポートフォリオを作ってみた(1)

## はじめに
自分の市場価値を上げつつ、転職活動をするときに自分に付加価値をつけるべく、ポートフォリオを作ってみることにしました。これは自分がWebマーケティングにも関わってきて、SNSやYoutubeと絡めて、自分がいるというだけで会社に価値を生むにはどうしたらいいか、という発想から来ています。

SNSやYoutubeは普通の人にはハードルが高いと思うので、じゃあGithubやQiita、Zenn.devと絡めてほかの人もマネしやすくしてみよう。と考えて記事も書いてみることにしました。

## ターゲット
今回は転職活動の職務経歴書にURLやQRコードなどを載せることで差別化することで、応募先企業に実力を証跡として提示するように出来ることが目的になっています。

記事自体はSystemEngineerがターゲットですが、ポートフォリオを見せる相手は企業の人事に関わる人になります。したがって、個人で運用することから、いかに安価にかつ、高品質なものを作るか、ということがミソになっています。

## 利用環境
環境は以下の通りです。
OS：Windows11
開発ツール：Visual Studio
フレームワーク：dotnet core
サーバー：CloudFlare
DNS：CloudFlare
ドメイン管理：ネットオウル

今回は、dotnetを使うことから、dotnetが稼働するサービスで一番安価なものを探しました。その結果、CloudFlareの無料枠を使って運用することにしました。ドメインは独自ドメインを取得するためにネットオウルを使いました。
【雑記】SMBCコンペ　振り返り

# はじめに
 - SMBCコンペに参加しましたので、その備忘録を残します
 - 順位自体は300位台なので、参考にならないかもしれませんがご容赦ください

# やったことまとめ
 - モデル : lightgbm
 - 作成した特徴量 :
         - tree_dbhに対して変数変換した特徴量
                 - log, 2乗から4乗, arctan 
         - tree_dbhに関する集約特徴量（max, min, median, mean）
         - stewardを数値に直し、平均値と最小値に置き換えたもの
         - created_atとspc_commonを基準に日付を並び替え、その種類の木が最初に記録されたときからの対象レコードの木の仮想的な経過時間
         - 数値系変数のターゲットエンコーディング
         - カテゴリカル変数のカウントエンコーディング
         - problemsなどの文字列に対する単語数特徴量
         - 単語数特徴量に対するICAの基底行列
         - tree_dbhに関する集約特徴量に対するPCAの主成分得点行列
 - 交差検証 : GroupKfold
         - Group単位はspc_commonとntaでまとめた変数にナンバリングし、グループIDを作成しました

変数重要度からtree_dbhが予測に効くことがわかったため、tree_dbh関係の変数を作成するようにしました。ターゲットエンコーディングして作成した特徴量とtree_dbh関係の変数のほとんどが変数重要度の上位になっていたため、局所的な予測を行うモデルとなっていました。その結果shake downしたような気がします。

# できなかったこと
 - スタッキング、アンサンブル
         - lightgbm以外にもcatboostやNNなどのモデルとの組み合わせにより汎化性能を上げられたかもしれません
 - 地理情報を活用した分析
         - 経度、緯度を追加する方法については[ディスカッション](https://signate.jp/competitions/1247/discussions/20231221235807-56905)にありました。大変参考になりました！
 - 天候や気温などを活用した分析

# おわりに
何はともあれ非常に学びの多いコンペでした。樹木の健康状態を予測することで、どの樹木が都市の景観維持や山林の保全などに活用できるのではないかと思います。データを提供、作成してくださったSMBCグループ、SIGNATEに厚くお礼申し上げます。
Django TemplateView オーバーライド　urlディスパッチャ viewで使用 


```ruby:qiita.python
path("<slug:slug>/", TemplateView.as_view())
```

以上のようにurlディスパッチャを用いるとき`slug`をviewで用いたいとき

```ruby:qiita.python
def get_context_data(self, slug, **kwargs):
        context = super().get_context_data(**kwargs)
        context['post'] = slug
        return context
```
と、オーバーライドする関数に直接引数を渡すことができる。
LeetCode日記(Day 2)

# 初めに
前回に続き，LeetCodeの解答と解説をまとめていこうと思います～～

## LeetCode(Palindrome Number)
>Given an integer x, return true if x is a 
palindrome, and false otherwise.

凄くシンプルな問題ですね．
これは「回文ならTrueを返してね．そうでなければFalseでお願い」ということですね．
じゃあ，さっそく解いてみましょう～

#解答・解説
```python
  def isPalindrome(self, x: int) -> bool:
         x_str = str(x)

         x_str_reversed = x_str[::-1]

         if x_str == x_str_reversed:
             return True
         else:
             return False
```

これは一瞬で書けますね！
与えられた数字を文字列として置き換えて，反転させたものをx_str_reversedに代入する．
後はそれを比較して，一致していればTrueを一致していなければFalseを返せば終了です！

ちなみに，x_str_reversed = x_str[::-1]は文字列全体を-1のステップでスライスすることで逆順にしています．
逆順にする方法としては，今回使用したスライスに加え，reverse,reversed,ループ文がありますが好きなものを使えばよいと思います．
速度はreverseが一番速いという実験結果が出ているようですのでそちらを使うとleetcodeの実行結果の時間が短縮されるかもしれません．
ちなみに，このコードは58msです．

それでは，また次回お会いしましょう～～
【初投稿】visual studioでちゃんとビルドしましょ！！

# はじめに
初めまして、ykonigini03です。
3月で2年目を迎える初心者エンジニアです。
最近、自身の成長が感じられず、アウトプットのために思い切って本日学んだことをQiitaに投稿します！
拙い文章かもしれませんが、暖かく見守っていただけると嬉しいです。
知識不足な面がありますので、誤情報を記載していましたら、ご指摘いただけると幸いです。

最近のマイブームは、「生せんべい」です。
美味しいですよー！！

# 今日の気付き
cppファイルを編集した後は、すぐにデバックせずにビルドをすること！
このファイル、単体で成りなっているわけではないから！

# 内容
作成中のアプリの画面に表示されてはいけないものが、ありました。
！！そんなに大したことではない！！

C++を使って記述してある
cppファイルを頑張って修正して、そのままDebug！
visualStudioのDebugすごい！！:fist:
と思ったら、何も変わっていない。
ここかな？編集、Debug!→変わってない
・・・繰り返すこと3時間ほど・・・

あれ？何も変わらない。
すると、先輩から、「ビルドした？？」
まさか、そんな・・・
ソリューションをビルドすると、余裕で半日終わってしまうほどのファイル達なので、やりたくないと思っていましたが、、、

# まとめ
◯cppファイル：C++で書かれたファイル

◯（単体のファイルでないなら）
 ビルドをして、Debugしましょうー！！
CubeIDE(CubeMX)でmain.cppを生成する

# はじめに
初投稿です。CubeIDEのコード生成機能で「main.c」ではなく「main.cpp」を生成する方法を解説します。

# CubeIDEではmain.cが生成される
 CubeIDEでは生成されたmain.cをmain.cppにリネームするとC++ファイルとして扱うことができます。しかし、コード生成機能はmain.cppを認識してくれません。したがって、以下のような手順が必要になります。

 - main.cppをmain.cにリネーム
 - コード生成
 - main.cをmain.cppにリネーム

 # 自動でファイル名を変更する
 CubeIDEにはコード生成の開始前や終了後に任意のファイルを実行する機能があります。コード生成開始前にmain.cppをmain.cにリネームするプログラム、終了後にmain.cをmain.cppを生成するプログラムを登録します。

```python:before.py
#!/usr/bin/python3
import os

os.chdir(os.path.dirname(os.path.abspath(__file__)))
if os.path.exists("./../Core/Src/main.cpp"):
	os.rename("./../Core/Src/main.cpp", "./../Core/Src/main.c")
```

```python:after.py
#!/usr/bin/python3
import os

os.chdir(os.path.dirname(os.path.abspath(__file__)))
os.rename("./../Core/Src/main.c", "./../Core/Src/main.cpp")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1767930/b3d9fab2-d390-df15-acb6-f0f59727da10.png)

ファイル構造はこんな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1767930/b3a2e1ca-5f12-a471-c505-76da4e08fbd3.png)

ProjectManagerのCode Generatorタブに「User Action」という項目があります。ここに今作ったファイルの絶対パスを入力します。

 今回はPythonで書きましたが、他の言語でも良いと思います。実行場所が実行ファイルの場所ではなく、CubeIDEのインストールパスになるので注意が必要です。



# おわりに
少し無理矢理な方法ですが、main.cppを生成できるようになりました。

最後まで読んでいただきありがとうございました。
React + TypeScript + ViteでEmotionが効かない

## はじめに

Viteを使用してReact + TypeScriptの環境を構築し、`$ npm i @emotion/react`でEmotionを入れました。

各tsxファイルで`/** @jsxImportSource @emotion/react */`を毎回書くのが煩わしかったので、書かずに済む方法をいろいろ試したのでまとめておきます。

## 環境

- React 18.2.0
- TypeScript 5.2.2
- Vite 5.0.8
- @emotion/react 11.11.3
- @vitejs/plugin-react-swc　3.5.0

## 問題

まずEmotionの公式サイトを見ます。

https://emotion.sh/docs/typescript

tsconfig.jsonに以下を書くだけで良さそうです。

```json:tsconfig.json
{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "@emotion/react"
  }
}
```

が、これだけでは全然効きませんでした。

検索してみると、`@emotion/babel-preset-css-prop`を入れろという記事も見つかりましたが、上記のEmotionの公式サイトを見る限り、TypeScript4.1以上であれば`babel-plugin`はいらないはずです。。

> @emotion/babel-plugin is completely optional for TypeScript users. If you are not already using Babel, you probably shouldn't add it to your build tooling unless you truly need one of the features offered by @emotion/babel-plugin. 

## 解決

いろいろ調べたところ、`vite-plugin-react-swc`のGitに答えがありました。

https://github.com/vitejs/vite-plugin-react-swc

![スクリーンショット 2024-01-09 21.38.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911578/ffe35fd1-99e3-bd52-98a1-35c4310aa5c1.png)

`vite.config.ts`に、`JSX factory`がどこからimportされるかを設定する必要がある、ということのようです。

```vite.config.ts
plugins: [
    react({
      jsxImportSource: '@emotion/react',
    }),
],
```

これで無事にEmotionが効きました。

## 終わりに

軽い気持ちでEmotionを試してみたのですが全然効かず、すごく時間がかかりました。。

## 参考

https://emotion.sh/docs/introduction

https://emotion.sh/docs/typescript

https://github.com/vitejs/vite-plugin-react-swc

https://qiita.com/kyntk/items/db5ec6fea3b70bf06dec

https://ralacode.com/blog/post/react-emotion/
2024年1月第1週振り返り

![s-CB_0008.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/c73aa9b5-8b03-b0df-c411-11bad6be78cf.jpeg)

2日過ぎてしまいましたが、第1週の振り返りを行いたいと思います。

### AWS計画

1. 試験ガイドのAWS公式PAS問題集完了
TOEICの勉強スピードを図り、目標を立てココに追記する。
1. ExamReddinessのAWS公式PAS問題集開始
1. AWS公式+UdemyのPASハンズオン視聴
1. AWS公式+UdemyのPASハンズオン視聴
1. AWS公式+UdemyのPASハンズオン視聴
1. ドキュメント閲覧＋暗記＋公式問題集回す
1. ドキュメント閲覧＋暗記＋公式問題集回す

PASは受験まで6,7日目を繰り返す。
1週間の時点で、計画に無理がないかフィードバックする。

**計画には書きませんでしたが、その他にTOEIC対策もやることになっていました**

### AWS成果と振り返り

**【AWS】**

1. 試験ガイドのAWS公式PAS問題集完了
https://d1.awsstatic.com/ja_JP/training-and-certification/docs-sap-on-aws-specialty/SAP-on-AWS-Specialty_Sample-Questions.pdf
2. ExamReddinessのAWS公式PAS問題集完了
https://explore.skillbuilder.aws/learn/course/12528/aws-certified-sap-on-aws-specialty-official-practice-question-set-pas-c01-japanese
3. AWS Partner: SAP on AWS (Business) (Japanese/日本語)完了

成果は、公式の問題集2つに加え、APN向けのSAP on AWS講座を受講し完了したことです。これらで重要だと思った点はQiitaに下書き状態でまとめています。その他にPAS受験者のブログや参考にされた資料もまとめているので、本番受験に向けた体制を整えることができました。2週目から公式問題集の復習を始めています。

見直しポイントは、UdemyのPASハンズオン視聴を実施できていない点です。14日頃には受験したいため、まずは見るべき動画を絞りたいと思います。そのためにまずは、最終課題として提供されているレビューを見る限りチートではなさそうな問題集を先に手を付けます。計画を立てた時点である程度動画は絞っていたのですが、英語スライド+日本語字幕を眺める集中した時間はなかなかとれないです。14日までには見るべき動画は見ておきたいです。
https://www.udemy.com/course/aws-certified-sap-on-aws-specialty/

また、見直しポイントで挙げたUdemyの代わりの教材としてAWS Partner: SAP on AWS (Technical) (Japanese/日本語)を始めています。AWS公式の教材をまずはクリアする方が正確な知識が身につく可能性が高いためです。

【AWS勉強計画2WEEK】

``` 
    January 2024
Su Mo Tu We Th Fr Sa
    1  2  3  4  5  6
 7  8  9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
```

7-13日間

目標：PAS合格、SAP勉強開始

1. AWS Partner: SAP on AWS (Technical) (Japanese/日本語)
1. AWS Partner: SAP on AWS (Technical) (Japanese/日本語)
1. AWS Partner: SAP on AWS (Technical) (Japanese/日本語)完了
Udemy教材の非チート問題集完了
1. PAS：集めた資料閲覧＋問題を解く
SAP：日本語のSAP本3週目をやりつつ、公式問題2種類を解く
1. PAS：集めた資料閲覧＋問題を解く
SAP：日本語のSAP本3週目をやりつつ、公式問題2種類を解く
1. PAS：集めた資料閲覧＋問題を解く
SAP：日本語のSAP本3週目をやりつつ、公式問題2種類を解く
1. PAS：集めた資料閲覧＋問題を解く
SAP：日本語のSAP本3週目をやりつつ、公式問題2種類を解く

AWS試験の受験日はバウチャー提供日次第。
13日までの提供は難しそうなので、勉強計画としました。

### TOEIC対策成果

1日に取れる勉強時間は1時間弱。
簡単な参考書なら1-2章程度できることが計測でわかりました。

TOEICはざっくりと頭の中で予定を立てたくらいなので初めから成果です。

1. TOEIC(R) L&Rテスト 英文法 ゼロからスコアが稼げるドリル
1. TOEIC(R) L&Rテスト 英文法 ゼロからスコアが稼げるドリル
1. TOEIC(R) L&Rテスト 英文法 ゼロからスコアが稼げるドリル
1. TOEIC(R) L&Rテスト 英文法 ゼロからスコアが稼げるドリル　完了
1. 基本単語 25/200 金のフレーズ 10/900+リスニング
1. 基本単語 50/200 金のフレーズ 20/900+リスニング
1. 基本単語 75/200 金のフレーズ 30/900+リスニング

TOEIC(R) L&Rテスト 英文法 ゼロからスコアが稼げるドリルは基本的な英語の知識はあるけど、問題が解けない自分にとっては良い教材でした。2週目も復習教材として使用したいと思います。

TOEIC公式問題集を見る限りは、今後は語彙増加で何とかなりそうだと感じました。それ以外については参考書を考えなくてはいけません。

たまたま手元にスピーキングですが実践IELTS技能別問題集スピーキングという積読本があったので、これを少しの間教材にしてしのごうと思います。2週目の内にNEW HORIZONなどの中学生向け参考書を購入予定です。中学生向けがいいらしいので。


### 【TOEIC勉強計画2WEEK】

1. 基本単語 100/200 金のフレーズ 20/900+リスニング（勉強できず復習のみ）
1. 基本単語 125/200 金のフレーズ 30/900+リスニング
1. 基本単語 150/200 金のフレーズ 40/900+リスニング
1. 基本単語 175/200 金のフレーズ 50/900+リスニング IELTS
1. 基本単語 200/200 金のフレーズ 60/900+リスニング IELTS
1. 金のフレーズ 80/900+リスニング IELTS
1. 基本単語 150/200 金のフレーズ 100/900+リスニング IELTS

毎回暗記するまで語彙をやっているので、2か月あれば900語彙増えるはずです。それが1番の対策だと考えているので頑張ります。

以上

来週も頑張ります。
Rust ＋ Tauri + TypeScriptでビルド後にHTMLに遷移できない問題の解決方法メモ

## 解決方法
* 事前にnpm install path でpathをインストールしておく
* ルートフォルダにtest.htmlを作成する
* vite.config.tsを以下のように記入する
  ```vite.config.ts
  import { defineConfig } from "vite";
  import { resolve } from "path";
  export default defineConfig(async () => ({
    clearScreen: false,
    server: {
      port: 1420,
      strictPort: true,
      watch: {
        ignored: ["**/src-tauri/**"],
      },
    },
    build: {
      rollupOptions: {
        input: {
          index: resolve("", 'index.html'),
          test: resolve("", 'test.html'),//←コレ　遷移させたいHTMLを追記していく
        },
      },
    }
  }));
  ```

この状態で、`npm run tauri build` するとdistフォルダにtest.htmlがコピーされて遷移できるようになりした。
独自開発は最後の手だ

## 主旨
ある大規模な開発があるときに、その中で必要とされるモジュールの独自開発はすべきではない。
もともと生じる課題を解決する余力が、モジュールの独自開発に着手した時点で失われる。

## ありがちな状況
- 新しい開発プロジェクトが始まった。開発する製品は、まったくの新規のプロジェクトだ。
- 新規のプロジェクトは、過去のしがらみもなく、新しい手法を試してみたくなる。
- 「新規のプロジェクトなんだから、モジュールも新規に開発しようよ。」
## この記事で主張すること
- 大規模な開発があるときには、新規モジュールの独自開発を極力すべきでないと主張する。
- 独自開発をするしかない必然性が見つかるまで、あるいは、ほかに優先順位が高い課題がないことを見定めるまで、新規モジュールの独自開発をしてはならない。

## 安易に新規モジュールの独自開発をするとおちいる状況
- 例：ステレオカメラモジュールの自作
    - ステレオカメラの作り方自体は簡単だし、OpenCVのモジュールを使うと、カメラキャリブレーション、ステレオ平行化の手順、視差の算出と深度計算は簡単だ。
    - M12マウントのカメラモジュールも多数市販されているし、M12マウントのレンズモジュールも多数市販されている。
    - それらを組み合わせれば、視野角や解像度を自分の思うようなカメラを用意できる。
    - 自作モジュールだと、カメラ間の距離、基線長を自由に選べるのもうれしい。
    - 自作モジュールだと、市販のカメラモジュールよりも安くなるように、部品を組み合わせることもできる。
    - そうして、ステレオカメラモジュールを自作することになる。
- 例： ステレオカメラモジュールを自作した結果
    - ステレオカメラモジュールを自作して、1台についてキャリブレーションをする。
    - ステレオキャリブレーションのために、チェッカーボードをどのように撮影すれば良いのかわかっているので、良い結果がでたと思っている。
    - 「ステレオキャリブレーションのチェッカーボードには、大パネルの液晶ディスプレイが向いている」というノウハウの出番だ。
    - ベニヤ板はたわむし、平面性がいい場所に、印刷したチェッカーボードを貼り付けても、印刷した紙と平面との間に隙間が残る。
    - チェッカーボードを表示した液晶ディスプレイは、そのようなたわみや隙間などの問題もない。
    - そこで、1台のステレオカメラについては、良好な結果を得られる。
    - そこで、ステレオカメラを自作してもうまくやっていけると自信を持つ。
- 例：ステレオカメラモジュールを自作した結果のその後
    - ステレオカメラモジュールの結果を利用しての開発が進む。
    - ところがある時点で、うまくいかない状況に出くわしてしまう。
    - 深度の算出結果がおかしいことに気づく。
    - 状況：
        - キャリブレーションを実施したときと温度が１０度以上異なる。
        - キャリブレーション後に、ステレオモジュールに衝撃を加えてしまった。
        - 何か原因がわからないけれども、キャリブレーションをやり直さなくればならなくなった。
        - キャリブレーションをやり直すとうまくいくようになった。
    - その後：
        - キャリブレーションをすればやり直せば、目的の機能が実現できるのだけども、いつまでキャリブレーションなしで大丈夫なのかがはっきりしない。
        - そのため、ステレオカメラモジュールの結果を利用する機能が、いま安心して使えるものかどうかがはっきりしないことになった。
- 教訓
     - ステレオカメラモジュールはよほどの理由がない限り、自作してはいけない。
     - 利用実績の多いステレオカメラモジュールは、以下のことを考慮している。
         - ステレオカメラのハードウェアの特性が安定するように作られている。
         - レンズの位置が固定されている。
         - レンズ間の距離（＝基線長）が安定するようにしてある。
         - レンズの向きが、応力や熱変形によって変わりにくいようにしてある。
         - カメラモジュールの信号処理で、２つのカメラで同一のゲイン設定、同一のシャッター速度の設定
         - グローバルシャッターを利用しているので、動きのある被写体での特性の劣化が少ない。 
-　このように、安易にステレオカメラモジュールを自作すると、余計な苦労を背負うことになる。
## 例：顔照合モジュールの自作
- 顔検出や顔照合は、深層学習の進展によってオープンソースの実装が進んだことで、市販品のモジュールを使わなくても実装できるだろうという衝動に駆られたりしないだろうか。
- 誘惑：
    - オープンソースの実装が実用上十分な水準に達していることを示してみたい。
    - 顔照合のデータベースの設計も含めて、ソフトウェアの設計・実装能力に長けていることを示してみたい。
    - 市販の顔照合がなくても十分なものを作れることを示してみたい。
- でも、そのような誘惑で顔照合モジュールを自作をすると痛い目を見るだろう。
- 想定される状況
    - たいがいの状況ではうまくいく。
    - しかし、時々極端におかしな結果になることがある。
    - 顔向きが半ば横向きのような状況では、本人の顔ではなく、同じ顔向きでの他人の顔を照合結果として返してしまう。
    -  公開データベース（西洋人中心）で照合を評価するとうまくいくのだが、ユースケースの中心となる日本人の顔画像で検索するとうまくいかない。
    -  「マスクをしている人の顔で顔照合をしなければならない」ことに急遽状況が変わってしまう。今まで、マスクをしていることを想定していなかったので、どうしようもなくなる。
## 一般的な教訓
- 自作モジュールは自作ハードウェアに限らない。
- 自作ソフトウェア、自作の学習済みモデルも自作モジュール。
    - 自作ソフトウェアの場合も同様だ。
- その余計な苦労のために、本来の開発課題に割り当てる時間が不足することになる。
- だから、モジュールの独自開発は、本当に必要とするまで先送りすることを勧める。  

## 最初に既存品を使うことによる学び（追記　2025）
- いい実装は、どのようなインタフェースをもっているのかがわかる。
- いい実装は、どのように信頼性をたもっているのかがわかる。
- 既存のいい実装をしても、今の時点ではどのような課題をもっているのかがわかる。
### 自分ならどのように改良できるかを見つけたとき
- OSSの実装などでは、GithubにIssueを書いて提案を行う。forkしたリポジトリで、改良を実装して、それを本家にPRを上げる。そして、改良の成果を活用しよう。
- 既存品の手直しではなく、まったく別に作り上げることによる価値を見出したとき
　それがあなたの開発の余力の中で可能なら開発してそれを組み込んでいこう。

- 既存品を使いこなしたうえで、さらにいいものを作るのには何が有効なのかを知っているあなたは、きっといいものを作り出せるだろう。
Cloudflareでの大量IPアドレスの一括更新

ステップ1: PythonをインストールするためにVPS上のSSHにログインする

まだPythonがない場合は、以下のコマンドを使う

sudo dnf install python3

次に、最新版に更新するためにYesを選択する

ステップ2: Requestsのインストール: Python内でrequestsライブラリがインストールされていることを確認する。

pip install requests

ステップ3: .pyファイルを作成する。cloudflare_dns_update.pyという名前のファイルを以下のコマンドで作成する

nano cloudflare_dns_update.py

その後、nanoの環境内で以下のコードを貼り付ける
```
import requests

# APIとドメインの情報
api_key = 'YOUR_CLOUDFLARE_API_KEY'
email = 'telegramweb.vn@gmail.com'
old_ip = '96.30.197.xxx'
new_ip = '103.72.96.xxx'

# リクエスト用のヘッダー
headers = {
    'X-Auth-Email': email,
    'X-Auth-Key': api_key,
    'Content-Type': 'application/json',
}

# DNSレコードを更新するための関数
def update_dns_record(zone_id, record_id, record_type, record_name, record_content):
    url = f'https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records/{record_id}'
    data = {
        'type': record_type,
        'name': record_name,
        'content': record_content
    }
    response = requests.put(url, headers=headers, json=data)
    return response.json()

# DNSレコードのリストを取得する関数
def get_dns_records(zone_id):
    url = f'https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records?type=A'
    response = requests.get(url, headers=headers)
    return response.json()

# ゾーンのリストを取得する関数
def get_zones():
    url = 'https://api.cloudflare.com/client/v4/zones'
    response = requests.get(url, headers=headers)
    return response.json()

# メインスクリプト
if __name__ == '__main__':
    zones = get_zones()
    for zone in zones['result']:
        dns_records = get_dns_records(zone['id'])
        for record in dns_records['result']:
            if record['content'] == old_ip:
                result = update_dns_record(zone['id'], record['id'], 'A', record['name'], new_ip)
                print(f"Updated record {record['name']} in zone {zone['name']} with result: {result}")

```
api_key = 'YOUR_CLOUDFLARE_API_KEY' これは前のステップで取得するAPIキーです（準備部分を参照してください）
email = 'fpt@gmail.com' > Cloudflareのログイン用メールアドレス
old_ip = '96.30.197.xxx' > 古いVPSのIPアドレス
new_ip = '103.72.96.xxx' > 新しいVPSのIPアドレス
これらの情報は、最適ですが、何かテキストファイルにコピーして、きれいに整理した後、nanoにコピーすることをお勧めします。
Vimの基本操作について

## はじめに
記事をご覧いただきありがとうございます。
vimのコマンドについての解説です。
vim初学者向けによく使うコマンドをアウトプットを兼ねて記載しました。

## Vimとは
Vimはマウスなしで、コマンドを打ち込んで操作をするテキストエディタです。
テキストエディタなのでVSCodeやAtomなどといったテキストエディタと同じようなものです。
異なるのはコマンドを打ち込んで操作をするといった点になります。

## vimのモード
|モード          |  動作                                              |
|:--------------:|:------------------------------------------------------:|
|ノーマルモード| 「ESC」を入力、カーソルを移動、コピー・ペーストなどのコマンドが使用可 |
|コマンドラインモード| 保存やvimの終了を行う |
|ビジュアルモード| ノーマルモードから「v」を入力、範囲指定をする際に使用 |
|入力モード| ノーマルモードから「i」を入力、ファイル編集・文字入力に使用 |


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1003708/e4852aa1-2352-210b-4ec1-3410a735068c.png">

## vimの起動と終了
vimコマンドを実行 ターミナルから実行可能です
```
vim test.txt
```

## vimの保存と閉じる
vimの保存
```
:w
```

vimを保存して閉じる
```
:wq
```

vimを閉じる
```
:q
```

vimを強制終了する
```
:q!
```

## 移動操作 
|コマンド         |  動作                                              |
|:--------------:|:------------------------------------------------------:|
| k | 上に移動 |
| j | 下に移動 |
| h | 左に移動 |
| l | 右に移動 |
| 0 | 行頭に移動 |
| gg | 先頭行に移動 |
| G | 最終行に移動 |
| 行数＋G | 入力した行数に移動 |

## 文字挿入
|コマンド|動作|
|:------:|:------:|
|i|カーソル位置に文字を挿入|
|a|行末に文字を挿入|
|o|カーソルの下に行を挿入|
|O|カーソルの上に行を挿入|

## 文字削除
|コマンド|動作|
|:------:|:------:|
|x|カーソルの文字を削除|
|dw|単語を削除|
|dd|行削除|

## やり直し
|コマンド|動作|
|:------:|:------:|
|u|処理を1つ戻す|
|CTRL＋R|取り消しを取り消す|

## コピー
|コマンド|動作|
|:------:|:------:|
|yy|1行コピー|
|v＋範囲選択＋y|選択した範囲をコピー|
|V＋範囲選択＋y|選択した行をコピー|

## ペースト
|コマンド|動作|
|:------:|:------:|
|p|カーソルの下の行にペースト|
|P|カーソルの位置にペースト|

## 文字置き換え
|コマンド|動作|
|:------:|:------:|
|r＋置き換えたい文字|文字を置き換える|
|%s/old/new/g|ファイル全体で見つかるものに対して変更|
|%s/old/new/gc|ファイル全体で見つかる物に対し、確認を取りながら変更|

## さいごに
私はvimtutorを主に使用して勉強をしました。vimtutorはコマンドから「vimtutor」
を入力することで使用することができます。
vimは私もまだ慣れていないですが、普段からvimを使用することで慣れていきたいと思います。

## 参考文献
▪️ vimtutorで速習Vim

https://dev.classmethod.jp/articles/vim-quickstart-with-vimtutor/

▪️ はじめてのVim ~ Vimはいいぞ！ゴリラと学ぶVim講座

https://knowledge.sakura.ad.jp/21687/
Amazon Kinesisファミリーまとめ

# 1. Amazon Kinesisとは

リアルタイムで大量のストリームデータ（アプリケーションログ、IoTセンサー情報、クリックストリームなど）を収集・処理・分析できるAWSサービス群です。

> 【注意点】  
> S3バケットに保存されたデータを解析する場合は、Kinesisのストリーム処理は不要です。  
> 保存済みデータの分析にはAthenaやGlueなどを使います。




# 2. Amazon Kinesis Data Streams

ストリームデータをリアルタイムで受信・処理できるマネージドサービスです。
データは重複なく、到着順序を保ったまま配信されます。

> 【注意点】  
> 送信先としてS3はサポートしていません。


## 2.1. シャード（Shard）

### 2.1.1. 一般概念としてのシャード

- データベースやストリーム処理における「データを水平分割する単位」。
- MongoDBやApache Kafkaなどでも使われる汎用概念です。

### 2.1.2. AWSにおけるシャード（Kinesis Data Streams）

- ストリーム内の**並列処理の最小単位**。
- 1シャードあたり：
  - 最大1MB/秒 または 1,000レコード/秒の取り込み能力。
- シャード数を増やすことでスループットをスケールアウトできます。

> 【注意点】 
> Amazon Kinesis Data Streams単体で写真や大容量バイナリデータを直接ストリーム処理する設計は一般的ではありません。  
> （メタデータなら可能ですが、本体データは通常S3等に保存します）


## 2.2.PutsRecords呼び出し

PutsRecords呼び出しはデータを同期的に送信することができます。

## 2.3.HTTP ライブストリーミング (HLS) 機能
Amazon Kinesis Video Streams の HTTP ライブストリーミング (HLS) 機能により、開発者は業界標準の HTTP ベースメディアストリーミングプロトコルを使用して、取り込んだビデオストリームを再生できる。

# 3. Amazon Kinesis Data Firehose

ストリームデータをリアルタイムまたはほぼリアルタイムで、以下の保存先に自動配信します。
- <font color="red">**Amazon S3**</font>
- Amazon Redshift
- Amazon OpenSearch Service
- Splunk
- HTTPエンドポイント

> 【注意点】  
> Amazon Kinesis Data Firehoseは、**Amazon DynamoDBに直接配信できません**。

### 特徴まとめ

- Firehose単体ではシンプルな変換処理（形式変換、圧縮など）のみ対応。
- より複雑なデータ変換には**Lambda関数を連携**させる必要があります。
- 最近では**Apache Parquet**や**Apache ORC**といった列指向フォーマットへの変換にも対応。

> 【注意点】  
> Firehoseは"完全リアルタイム"ではありません。数秒〜数分単位でバッファリングされてから配信されます。

> 【注意点】
> S3イベント通知によって直接Firehoseを呼び出すことはできません。




# 4. Amazon Managed Service for Apache Flink

以前の名称：**Amazon Kinesis Data Analytics**

Apache Flinkベースのマネージドサービスで、リアルタイムストリーム処理・状態管理・イベント駆動型アプリケーション開発が可能です。

### 特徴まとめ

- SQLクエリやApache Flink APIによる高度なストリームデータ処理が可能。
- リアルタイム不正検知（fraud detection）、セッションウィンドウ管理、複雑イベント処理（CEP）などに最適。

> 【注意点】  
> Flinkを使えば不正検知や複雑な状態管理ロジックも実装可能です。  
> 「不正分析ができない」というのは誤りです。

※[Apache Flink](https://flink.apache.org/)は、分散ストリーム処理プラットフォームのひとつのOSS。



# 5. 関連用語（参考）

### 5.1. RTSP（Real Time Streaming Protocol）

- 音声・映像などメディアストリーミングを制御するプロトコル。
- Kinesisが扱う"テキスト・イベントストリーム"とは用途が異なる。
TypeScriptでJestのテストを書くための環境構築

# はじめに
この記事は、TypeScriptでJestを使うための環境構築手順の備忘録です。Jestに関する公式ドキュメントは[こちら](https://jestjs.io/ja/docs/getting-started)です。

https://jestjs.io/ja/docs/getting-started

# 動作環境
nodeのバージョン
```shell
node -v        
v18.12.1
```

# 環境設定
最初に新しいプロジェクトを作成します。

```shell
mkdir jest-lesson
cd jest-lesson
```

次に、npmパッケージマネージャーを使ってプロジェクトを初期化します。
このコマンドは`package.json`ファイルを生成します。

```shell
npm init -y
```

次に、TypeScriptをプロジェクトに追加します。

```shell
npm i -D typescript
```

そして、TypeScriptの設定ファイル`tsconfig.json`を生成します。

```shell
npx tsc --init
```

次に、Jestと関連パッケージをインストールします。

```shell
npm i -D jest @types/jest ts-jest
```

Jestの設定ファイルを追加または更新します。

```json
"scripts": {
  "test": "jest"
},
```

# Jestの動作確認

簡単な関数`sum`を作成します。

```typescript:src/sum.ts
export function sum(a: number, b: number): number {
  return a + b;
}
```

この関数のテストを書きます。

```typescript:src/sum.test.ts
import { sum } from "./sum";

it("1と2を足すと3になる", () => {
  expect(sum(1, 2)).toBe(3);
});
```

テストを実行してみましょう。

```shell
npm test
```

動作すれば設定完了です。
フォルダ構成は次のようになります。

```
.
├── README.md
├── jest.config.js
├── node_modules
├── package-lock.json
├── package.json
├── src
└── tsconfig.json
```

# おまけ
[gibo](https://github.com/simonwhitaker/gibo)を使って`.gitignore`ファイルを作成します。

```shell
gibo dump Node VisualStudioCode macOS >> .gitignore
```
Wordpress製のサイトのコンテンツをLocizifyを使ってLocizeに流し込み翻訳作業を行う


Locizifyの導入で微妙につまづいたので備忘録。



## 1. Locize上で新規プロジェクトを作成

これによって、プロジェクトIDとAPIキーが手に入ります。
右上の歯車マークから。


## 2. Wordpressのテーマの`header.php`に、Locizifyで指定されているスクリプトを追記する

Wordpressでヘッダーとして使われているのは、`header.php`の中身の情報です。
なのでここに追記します。

こんな感じ。子テーマにheader.phpが存在しない場合は、親テーマのものをそのまま流用して使っています。

親テーマのheader.phpに直接手を入れると、更新の際に不具合が生じることがあるようです。
その場合は親テーマのheader.phpを子テーマのディレクトリにコピーして持ってきてから編集すべきらしい。

![スクリーンショット 2024-01-09 20.23.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594257/8c27978c-f657-fa0b-e5d7-6fdcf4a579b1.png)

![スクリーンショット 2024-01-09 20.23.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594257/6b127ab0-eaf6-695f-ecab-815b06456cff.png)


追記すべきスクリプトは、公式ではこのように書かれている。

```HTML
<script
    id="locizify"
    projectid="[PROJECT_ID]"
    apikey="[API_KEY]"
    referencelng="[LNG]"
    fallbacklng="[LNG]"
    saveMissing="true"
    src="https://unpkg.com/locizify@^5.0.5"
></script>
```

が、実際にはこれだけだとうまくいかない。

### サイトのドメインがlocalhostでない場合

ドメインっていうのか？ 詳しくない。
`allowedAddOrUpdateHost="[mydomain.com (default localhost)]"`
を追記する。

### 翻訳先の言語のファイルがまだ存在しない場合

例えば、
`referencelng="ja-JP" fallbacklng="en"`

としていると何かエラーが出るときは、

`referencelng="ja-JP" fallbacklng="ja-JP"`

とすると、Locize上に日本語の翻訳キーが流し込まれ、
これをもとに翻訳作業を始めることができた。

### やっておくといいこと

`debug="true"`は絶対に書いておいたほうがいいです。


## 3.翻訳したい自分のサイトを開き、ブラウザ上で右クリック、Inspect→Consoleでログを確認する

このログを見て、文句を言われていたら怒られている。
ログがかなり読みやすいので、すぐに解決できると思う。

`i18next::translator: missingKey ~...`みたいに出ていたら、未検出のキーをLocizeに追加してくれている。

自分のサイトのページを開いた後、Locizeの画面をリロードすると、キーが増えていると思う。
そうすれば翻訳作業を開始するだけ。

![スクリーンショット 2024-01-09 20.32.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594257/27f47fe0-3a9a-3047-12ba-cd733da594e6.png)

## 4.さらにつまづいています

https://youtu.be/f0ukRI0LMfo
この動画の前半、Get Startedから見ると解決するかもしれません

またLocizifyのリポジトリのReadmeもかなり丁寧に書いてあります。
Scriptの中身もじっと見ると解決するかもしれません
https://github.com/locize/locizify
あるフォルダ内にあるファイルとフォルダを表示する

AI chat の練習とC++のファイルの仕組みを知る目的でやってみた

copilotで質問を入れる

質問

:::note info
C++ std::filesystem を使って、AAAフォルダの中のファイルとフォルダを表示してください。
※ただし、AAAフォルダの中のフォルダの中のファイル名は表示しないでください。
:::

Copilotの回答
以下のコードを試してみてください。このコードは、C++17のstd::filesystemを使用して、指定されたフォルダ内のファイルとフォルダを表示します。ただし、フォルダ内のフォルダの中のファイル名は表示されません。

```cpp: inFolderList.cpp
#include <iostream>
#include <filesystem>

namespace fs = std::filesystem;

int main() {
    const std::string folder_path = "AAA";
    for (const auto& entry : fs::directory_iterator(folder_path)) {
        if (entry.is_directory()) {
            std::cout << "Directory: " << entry.path().filename().string() << std::endl;
        } else {
            std::cout << "File: " << entry.path().filename().string() << std::endl;
        }
    }
    return 0;
}

```
:::note warn
詳細情報
https://qiita.com/ueken0307/items/4d866bb78e9f4fe6232d
https://technotes.hatenablog.jp/entry/2020/05/07/045034
:::

質問

:::note info
次に、main関数を以下のように変更してください。
int main(int argc, char* argv[]) 

そして、AAAフォルダは止めて、argv[1]を使用して実行ファイルにドロップしたフォルダ（下記 ※folder）に変更してください。

※    std::string folder = argv[1];

お願いします
:::

```cpp: inFolderList2.cpp

#include <iostream>
#include <filesystem>

namespace fs = std::filesystem;

int main(int argc, char* argv[]) {
    const std::string folder_path = argv[1];
    for (const auto& entry : fs::directory_iterator(folder_path)) {
        if (entry.is_directory()) {
            std::cout << "Directory: " << entry.path().filename().string() << std::endl;
        } else {
            std::cout << "File: " << entry.path().filename().string() << std::endl;
        }
    }
    system("pause");//<<これは追記した
    return 0;
}
```

:::note warn
詳細情報
https://qiita.com/ueken0307/items/4d866bb78e9f4fe6232d
https://technotes.hatenablog.jp/entry/2020/05/07/045034
:::


実行結果：
適当に作ったテストフォルダを実行ファイルにドロップした
ドロップしたフォルダ名は表示しない
フォルダの中にあるものを表示

```

File: a.txt
File: b.txt
Directory: resourece
Directory: zapA
続行するには何かキーを押してください . . .

```
別件でプログラムをCopilotを指示した時、日本語を伝えるのが厳しくて別の苦労で断念。
今回は日本語文を伝えやすい形に、アルゴリズムも単純なものを考慮したところ、すんなりうまくいった。
人のサンプルは、あるあるとしてプラスアルファを入れられてしまい、直感的に理解するのができないので、その部分を削除したものをCopilotに作らせると言うのが目的。
できればプラスアルファする場合、それは置いといて、次のサンプルとして作って欲しいところ。
そうすれば余計な情報が入っていないので理解しやすく誤認して使い方を間違えるリスクも減る。

コツとしてはいきなり目的のプログラムを依頼しない。
小さい量で塩梅を見て追加変更指示をする印象
いろいろ試さないと塩梅加減は難しいかもしれない。

これが理解できたので次回はこれを直感的に使えるツールにする予定
このツールはまだ誰も作っていないかもしれない。

次に続く


Copilotにお礼を伝えた

:::note
分かりやすくシンプルなプログラムをありがとうございます。
パッと見て理解しやすいので大変勉強になりました。
:::

返事が帰ってきた

```
どういたしまして！お役に立てて嬉しいです。
何か他に質問があれば、遠慮なく聞いてくださいね。😊

```
Azure認定資格 AZ-700を取得しました

ネットワーク系のAzure認定資格を取得したので体験記を残します。

他の資格体験も書いていますのでよければご覧ください。
* [Azure認定資格 AZ-500を取得しました](https://qiita.com/shingo_kawahara/items/6c23e843b21257287031)
* [Azure認定資格 AZ-400を取得しました](https://qiita.com/shingo_kawahara/items/1e0d371276d264fe65fc)
* [Azure認定資格 AZ-900を取得しました](https://qiita.com/shingo_kawahara/items/86b4b7599318996f6f60)
* [Azure認定資格 AZ-203を取得しました](https://qiita.com/shingo_kawahara/items/551ac6b880a4a59e4291)
* [Azure認定資格 AZ-300を取得しました](https://qiita.com/shingo_kawahara/items/7d1c217e2588c5a232e3)
* [Azure認定資格 AZ-301を取得しました](https://qiita.com/shingo_kawahara/items/5e5c1febeb773a95b6af)

# 試験の傾向は？
* 問題：40問
  他の試験と同じように「2択問題」「1問1答」「ケーススタディ」は出題されました。各セクションを先に進めると前のセクションに戻ることができません。
* 時間：100分
* 合格ライン：700点
* 得点：866点

# 試験範囲
* コア ネットワーク インフラストラクチャを設計して実装する (20 - 25%)
* 接続サービスを設計、実装、管理する (20 - 25%)
* アプリケーション配信サービスを設計して実装する (20 - 25%)
* Azure サービスへのプライベート アクセスを設計して実装する (5 - 10%)
* Azure リソースへのネットワーク接続をセキュリティで保護する (15 - 20%)

[学習ガイド](https://learn.microsoft.com/ja-jp/credentials/certifications/resources/study-guides/az-700)に詳しく出題内容が示されています。

Azureの数多くあるネットワーク関連サービスが一通り出題範囲に含まれていますね。Virtual WANやFirewall Managerなどある程度大規模じゃないと触らないようなサービスもあります。

# 学習方法と試験内容
基本はMicrosoft Learnで学習を進め、使ったことないサービスは実際に手を動かしてということで理解を深めました。
試験内容ですが、今までで一番ホワイトボードを使いました。試験会場で受講した場合に配布されるやつですね。初めてあのホワイトボードをほぼ使い切りました。
というのもネットワーク関連試験ということで、構成図を書かないと分からないような問題が多かったです。このVMとこのVMは通信できるか？みたいなやつですね。
あとは、他の資格試験に比べて、即答できる問題が少なかったように思います。ちゃんと構成図を書いてアーキテクチャを理解した上で回答しないといけないものが多かった印象です。
そのため時間がかなりギリギリになってしまいました。AZ-700では時間配分も考えながらやるのが重要です。
S2SやP2S VPN接続は一度手を動かして経験しておくとよいかなと思います。

# まとめ
構成図を書いて考える系の問題が多かったので時間配分には要注意です。
今回も受験中にMicrosoft Learnで調べながらやれましたが、時間に追われてあまり深く調べるということはできませんでした。（とはいえかなり役には立った）

次はAI関連の資格を目指したいと思います！
手軽で分かりやすいスケジュール作成

## 導入
論文発表に向けてスケジュールを作成する際など，スケジュール管理用のアプリケーションを導入することすら面倒なことがありました．
個人でスケジュールを管理する程度であれば，もっと簡単な方が効率的な作業につながることもあると思います．

## ガントチャート
個人的には，Googleのスプレッドシートを用いるのが一番手軽かなと思います．
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1814188/1966c941-5549-3e68-f150-38c756e35eea.png width=20%>

スプレッドシートのテンプレートの中に，ガントチャートがあります．
ガントチャートは時間が横軸，作業内容が縦軸の，棒グラフ状の一覧表のことです．以下のようなものです．
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1814188/b4c433ce-0035-7496-ea76-20385f23d0ec.png width=80%>

ガントチャートは何をいつまでにすべきかがシンプルに分かりやすいため，スケジュールの作成に最も適していると思います．

## カスタマイズ
状況に応じてテンプレートを弄ると，より分かりやすくまとまると思います．
私は各作業項目にどの程度日数を要するかをざっくり分類し，各作業項目の手前に色分けしています．


ガントチャートは横軸が長くなるとスクロールするか全体を縮小するかしないと予定日数が見えませんが，色分けにより手早く全体の概要を把握できると思います．

加えて論文発表用のスケジュールとして作成したので，各作業項目が一人で達成できないものであると判断した場合，相談が必要という色分けの分類をしています．
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1814188/45173043-b8d8-0e41-0119-6bc8e0babcef.png width=80%>

以上が手軽で分かりやすいスケジュール作成方法でした．
分かりやすいカスタマイズは個人や状況に依るので，様々な整理方法を試すとよいと思います．
Keychainのすゝめ

まだssh-agentを直接使っているんですか？そろそろKeychain経由で使うようにしましょうよ。
Keychain=Macだと思っているみなさん、それは勘違いです。そのKeychainとこのKeychainは異なります。Fedora, UbuntuなどのLinuxにもありますよ。


# keychainとは

.bashrcなどに
```
eval `ssh-agent`
```

と書いているとセッションを開くたびにプロセスが増えていってしまってうざいと思いますよね。別に体感で重くなったりはしないかもしれませんがうっとおしいです。

間に入ってそれを制御してくれるのがkeychainということです。

https://github.com/funtoo/keychain/

各種Linux(WSL1,2含む)で使えます。
※Windowsの場合はssh-agentのサービスがあるのでそれを使えばssh-addしたものは永続されます。
https://learn.microsoft.com/ja-jp/windows-server/administration/openssh/openssh_keymanagement

※macの場合でも同じ感じでssh-agentを直接使うようです。

iCloud Keychain, Google Password Managerなどはクラウド経由でパスワード等を共有できますが、これとは異なります。

# インストール

`$ sudo apt install keychain` , `$ sudo dnf install keychain` などで入れます。だいたいのディストリにはあるでしょう。

そして .bash_profileに追記しましょう。下のほうでいいです。

```
eval `keychain --eval --agents ssh ~/.ssh/hogehoge.ed25519`
```

古い `eval ``ssh-agent`` `は消してください。

# 確認

テスト用に適当に鍵を作ります。

```
murata@derorisnet:~$ ssh-keygen -t ed25519 -C 'iranai kagi' -f ~/.ssh/hogehoge_ed25519
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/murata/.ssh/hogehoge_ed25519
Your public key has been saved in /home/murata/.ssh/hogehoge_ed25519.pub
The key fingerprint is:
SHA256:RU4gOOY+CmPhsBPn/Di6s0/CxNs1GVFNUzQABpif3rs iranai kagi
The key's randomart image is:
+--[ED25519 256]--+
|    o+++==*+     |
|   o+ o. =. .    |
|   o.o.   o      |
|+.. .oo  .       |
|oO...+. S        |
|Bo= +...         |
|o*.= .  .        |
|.o+ .  .         |
|+*..   E.        |
+----[SHA256]-----+
```


keychainに登録します。(.bash_profileに書いてもOK)

```
murata@derorisnet:~$ eval `keychain --eval --agents ssh ~/.ssh/hogehoge_ed25519`

 * keychain 2.8.5 ~ http://www.funtoo.org
 * Found existing ssh-agent: 440
 * Adding 1 ssh key(s): /home/murata/.ssh/hogehoge_ed25519
Enter passphrase for /home/murata/.ssh/hogehoge_ed25519:
 * ssh-add: Identities added: /home/murata/.ssh/hogehoge_ed25519
```


登録されているか確認します。

```
murata@derorisnet:~$ keychain -l
256 SHA256:RU4gOOY+CmPhsBPn/Di6s0/CxNs1GVFNUzQABpif3rs iranai kagi (ED25519)

murata@derorisnet:~$ ssh-add -l
256 SHA256:RU4gOOY+CmPhsBPn/Di6s0/CxNs1GVFNUzQABpif3rs iranai kagi (ED25519)

```

別セッション（タブなど）を開いて確認もしましょう。登録されていればOKです。
もちろんパスワードをかけた鍵ファイルでもOKです。1度目に入力確認されます。


# で？

使い勝手は変わらないが、プロセスが1つになるのでssh-agentのプロセスがばかすか増えることはなくなるぞ。
WSL2とVScodeを使っていますが結局、WSL側とWindows側の両方に置いておく必要があるという点は変わらないですわ。。。

WSL2からWindowsのssh-agentを使う方法もあるみたいです。
paizaラーニング解答: ループメニュー2[Ruby]

# ループメニュー2
https://paiza.jp/works/mondai/loop_problems2/problem_index?language_uid=ruby
## STEP: 1 未知数個の数の受け取り
```ruby
a = gets.split.map(&:to_i)
puts a
```

## STEP: 2 未知数個の文字列の受け取り
```ruby
a = gets.chomp.split
puts a
```

## STEP: 3 奇数だけ出力
```ruby
n = gets.to_i
a = gets.split.map(&:to_i)
a.each do |i|
    if i.odd?
        puts i
    end
end
```

## STEP: 4 割り切れる数だけ出力
```ruby
n = gets.to_i
a = gets.split.map(&:to_i)
a.each do |i|
    if i % 3 == 0
        puts i
    end
end
```

## FINAL問題 偶奇の判定
```ruby
n = gets.to_i
a = gets.split.map(&:to_i)
a.each { |i| puts i.even? ? "even" : "odd" }
```

## STEP: 1 各桁の和
```ruby
n = gets.split('').map(&:to_i)
puts n.sum
```

## STEP: 2 カウント変数を使った計算
```ruby
n = gets.to_i
m = gets.split.map(&:to_i)
for i in 0...n
    puts m[i] * (i + 1)
end
```

## STEP: 3 2 で何回割れる？
```ruby
n = gets.to_i
count = 0
while n.even?
    n /= 2
    count += 1
end
puts count
```

## STEP: 4 任意の数で何回割れる?
```ruby
n, m = gets.split.map(&:to_i)
count = 0
while n % m == 0
    n /= m
    count += 1
end
puts count
```

## STEP: 5 10 進数から 2 進数に変換
```ruby
n = gets.to_i
puts n.to_s(2)
```
参考

https://blog.willnet.in/entry/2012/01/30/112724
## STEP: 6 10 進数から M 進数に変換
```ruby
n, m = gets.split.map(&:to_i)
puts n.to_s(m)
```

## STEP: 7 N が M ずつ増えたときにいつ K を越える？
```ruby
n, m, k = gets.split.map(&:to_i)
count = 0
while n <= k
    n += m
    count += 1
end
puts count
```

## STEP: 8 毎日増加するお金
```ruby
a, b = gets.split.map(&:to_i)
count = 0
while a <= b
    a += a / 10
    count += 1
end
puts count
```

## STEP: 9 階乗の計算
```ruby
n = gets.to_i
puts (2..n).inject(:*)
```
inject(:*)で配列の要素同士を掛け算できます。
## STEP: 10 階乗の末尾に 0 はいくつ付く？
```ruby
n = gets.to_i
count_zero = 0
while n > 0
    count_zero += n / 5
    n /= 5
end
puts count_zero

# ループ処理の中身
# 1ループ目
# count_zero = 20
# n = 20

# 2ループ目
# count_zero = 24
# n = 4

# 3ループ目
# 4 / 5は0.8。小数点以下は切り捨てのため 24 + 0 = 24
# count_zero = 24
# n = 0
```
paizaの解説をよく読まないと理解しにくいかも。
## STEP: 11 加算された数列の最大値
```ruby
n = gets.to_i
a = gets.split.map(&:to_i)
ans = 0
(0...n).each do |i|
    ans = [a[i] + i + 1, ans].max
end
puts ans
```

## STEP: 12 加算された数列の最小値
```ruby
n = gets.to_i
a = gets.split.map(&:to_i)
ans = 1000
(0...n).each do |i|
    ans = [a[i] + i + 1, ans].min
end
puts ans
```

## STEP: 13 1 はどこにある？
```ruby
n = gets.to_i
a = gets.split.map(&:to_i)
n.times do |i|
    if a[i] == 1
        puts i + 1
    end
end
```

## STEP: 14 約数の個数
```ruby
n = gets.to_i
ans = 0
(1..n).each do |i|
    if n % i == 0
        ans += 1
    end
end
puts ans
```

## FINAL問題 約数の列挙
```ruby
n = gets.to_i
(1..n).each do |i|
    if n % i == 0
        puts i
    end
end
```
ラズパイにsudo権限でのみ実行可能な自作コマンドを実装する

# コマンドの作成
適当なディレクトリ(/usr/local/custom_commandなどの名前で作成)にシェルファイルを置く
ファイル名がコマンド名になる(ここではtesthelloで作成)。

↓/usr/local/custom_command/testhelloの中身
```
# vim testhello
#!/bin/sh

echo "HelloWorld!"
```
# 権限を変更してパスを通す(失敗)
以下は失敗例です。成功例だけ知りたい人は次の章まで飛んでください
```
$ sudo chmod 744 testhello
$ vim ~/.bash_profile
```
以下を追記
```
export PATH=$PATH:/usr/local/custom_command/
```
sudo以外のユーザーで実行できないようにはなったものの、sudo testhelloと打つと「コマンドが見つかりません」と出てしまう、、、

# 権限を変更してパスを通す（成功）
```
$ sudo chmod 744 testhello
```
sudo ユーザーはコマンドのパスとしてsudoers内のsecure_pathを使うらしいので、sudo visudoを開いてここに追加
```
$ sudo visudo
```
↓↓↓最後の行
```
Defaults        secure_path="(中略):/usr/local/custom_command"
```
# 成果物
```
$ testhello
> -bash: /usr/local/custom_command/testhello: 許可がありません

$ sudo testhello
> HelloWorld!
```

# 参考
sudo「コマンドが見つかりません」PATHが初期化されているときの対処法
https://blog.thingslabo.com/archives/000395.html

自作のコマンドを作成した
https://qiita.com/yoshiken/items/2b8e6c24d6b95e65b625

# 編集履歴
1/16: chmodを755→744にして、chownの設定をやめました
nodejsを最新にしよう（WSL）

nodejsがv20を要求されているアプリを起動したいので、何も考えずapt-getでinstallしようとしたら
```
sudo apt install nodejs
sudo apt install npm
```
ってやっても
```
node --version
v10.19.0
```

で、ダメだったんだけど、これ単純な手順じゃないのね…。
https://qiita.com/tora_oba/items/2761452fe8c2b0035ba0
に則って、`n`を利用したらいけましたね。

ただ、最後に`node -v`を利用しても`bash: /usr/bin/node: No such file or directory`というメッセージがでて上手くいかなくて、VSCode再起動しないとダメだった。これに5分迷った。

## 参考
何故かMacばかりなのね。この界隈
https://www.trifields.jp/how-to-install-node-js-on-ubuntu1804-3544
フォームリクエストにバリデーションを書くメリット

## はじめに
Laravelでコントローラにバリデーションを書いていました。

すると「それフォームリクエストに書いたらええんちゃう？」とアドバイスをもらいました。

フォームリクエスト自体が初耳だったので、実際に実装して使い方を学んでみます。

フォームリクエストにバリデーションを書くことで、コントローラがスッキリと見やすくなりました。



## 環境
Laravel 9.52.16

## 問題
* このようにコントローラの中にバリデーションを書いていた

```php: SalesOrdersController.php
// 中略

public function store(Request $request) 
{
    // バリデーション
    $request->validate([
        'title' => 'required|max:2000',
        'sales_abstract' => 'required|max:2000',
        'category' => 'required|max:50',
        'budget' => 'required|numeric',
        'schedule' => 'required|date',
    ]);

    // 認証済みユーザの発注として作成（リクエストされた値を元に作成）
        $request->user()->sales_orders()->create([
            'title' => $request->title, 
            'sales_abstract' => $request->sales_abstract,
            'category' => $request->category,
            'budget' => $request->budget,
            'schedule' => $request->schedule,
        ]);

    // 前のURLへリダイレクトさせる
    return back();
}
```

しかしこの記述におけるバリデーションは、フォームリクエストに移すことができるそうです。

## 解決法
* フォームリクエストにバリデーションを移す

まず、以下のコマンドでSalesOrdersRequestを作成します。

```terminal: ターミナル
root@:/var/www/html/niches# php artisan make:request MesssagesRequest
```

そして生成されるファイル内に次のように記述します。

```php: App\Http\Requests\SalesOrdersRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth; 

use App\Models\SalesOrder;

class SalesOrdersRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;　// middlewareを使っているのでtrueにしています
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, mixed>
     */
    public function rules()
    {
        // ここにバリデーションルールを書く
        return [
            'title' => 'required|max:2000',
            'sales_abstract' => 'required|max:2000',
            'category' => 'required|max:50',
            'budget' => 'required|numeric',
            'schedule' => 'required|date',
        ];
    }
}

```

これにより、先ほどのコントローラを以下のように書き換えることができます。

```php: SalesOrdersController.php
// 中略

public function store(SalesOrdersRequest $request // SalesOrdersRequestに変更) 
{
    // バリデーションはSalesOrdersRequest内に記述しているので不要

    $request->user()->sales_orders()->create([
            'title' => $request->title, 
            'sales_abstract' => $request->sales_abstract,
            'category' => $request->category,
            'budget' => $request->budget,
            'schedule' => $request->schedule,
    ]);

    return back();
}
```

storeアクションの引数に「SalesOrdersRequest」と指定することで、

バリデーションルールの記述をごっそり削ることができます。


## 参考
https://readouble.com/laravel/8.x/ja/validation.html
【2024年01月版】tcp/udp で port を開けているプロセスを見つける4つの方法【中年エンジニアのためのLinuxメモ】

# はじめに

tcp port 22 を開けているプロセスIDをみつけたい、どうするんだっけ？
という時に、見るためのメモ

# 結論

netstat, ss, lsof, fuser をお好みで使う。
※ カーネルで開けている場合はプロセスIDが出ないので注意、意外と盲点。

# 条件

tcp(udp) port 22 を開けているプロセスIDをみつけたい

# ４つの方法

## netstat

`netstat -lntp | grep 22`
`netstat -lnup | grep 22`

```terminal
$ sudo netstat -lntp | grep 22
tcp        0      0 0.0.0.0:22           0.0.0.0:*               LISTEN      751021/sshd: /usr/s 
```
# ss

`ss -lntp | grep 22`
`ss -lnup | grep 22`

```terminal
$ sudo ss -lntp | grep 22
LISTEN 0      128          0.0.0.0:22      0.0.0.0:*    users:(("sshd",pid=751021,fd=3))  
```

# lsof

`lsof -i TCP:22`
`lsof -i UDP:22`

```terminal
$ sudo lsof -i TCP:22
COMMAND    PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
sshd    751021 root    3u  IPv4 4704025      0t0  TCP *:22 (LISTEN)
```

# fuser

`fuser 22/tcp`
`fuser 22/udp`

```terminal
$ sudo fuser 22/tcp
22/tcp:           751021 764790 764902
```

# 参考リンク

[man netstat](https://manpages.org/netstat/8)
[man ss](https://manpages.org/ss/8)
[man lsof](https://manpages.org/lsof/8)
[man fuser](https://manpages.org/fuser)

# さいごに

かんたんでしたね
ラズパイやArduinoのモジュール・センサーが一覧で素早く分かるサービスを作った


先日、[Module Guru](https://sensorsandmodules.com?trk=qt-aa)（sensorsandmodules.com）というウェブサイトをリリースしたので、ご紹介します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3671928/1f328d64-4f53-4541-aefe-8b139c61be36.png)

（一部分のスクリーンショットです）


## 使用技術

使用した技術は主に以下の通りです。

- Next.js
- Node.js
- JavaScript
- TypeScript
- React.js

## 問題解決

もともと私自身、電子工作をしている中で、「使ってみたいモジュールや部品について簡単に概要や活用事例、使い方を知れたら便利なのに…」という思いがありました。

このウェブサイトでは、100を超えるモジュール・センサーを始めとした電子部品・パーツのシンプルな説明を提供しています。

Next.jsで運用されているため、SSG/SSRを活用し、レイテンシの少ない高速でストレスフリーな閲覧が体験できるように設計しました。

## ご質問・ご要望など

もし何かウェブサイトに足りない所や、使い勝手のよくない部分などがあればコメントなどで教えて頂けると助かります。

（参考）

- [Arduino と Raspberry Pi の違い - 移植編 #RaspberryPi - Qiita](https://qiita.com/K2_/items/5e0e79f84e4dd26bd373)
- [Macで楽々RaspberryPi キーボード・ディプレーなしにラズパイを使う #Mac - Qiita](https://qiita.com/makaishi2/items/cabed517a758c60affe4)
- [RaspberryPi を安定運用させる #RaspberryPi - Qiita](https://qiita.com/HirohitoHigashi/items/7b57781a8a4874012d3d)
Pascalの環境構築

# Pascal の環境構築

Pascal の環境構築したので備忘録。

- テスト環境

```shell
$ cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.3 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.3 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
```

## インストール

Pascal にはいくつかコンパイラがありますが、今回はFree Pascal Compiler(以下 fpc)を使います。

```shell
$ sudo apt-get update -y
$ sudo apt-get install -y fpc
```

## apt-get 以外の人

- 公式サイトのダウンロードページ
    - [Free Pascal - Download](https://www.freepascal.org/download.html)

- Docker file(gitlab)
    - [FPC / FPC / Docker · GitLab](https://gitlab.com/freepascal.org/fpc/docker)

## コンパイル方法

ここでは先程インストールした fpc を使います。

```shell
# デフォルトでは実行ファイルの名前はソースコードと同名になります
$ fpc program.pas

# 実行ファイルの名前を指定したい場合は、-o オプションを使います。
$ fpc program.pas -oHelloWorld
```

## サンプルコード

```pascal
program HelloWorld;
begin
  writeln('HelloWorld');
end.
```

実行してみる。

```shell
$ ./HelloWorld
HelloWorld
```
Pythonで「集合を作成する」の動作を確認してみた

# 概要

Pythonで「集合を作成する」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/python/set/index1.html

# 実装

以下のファイルを作成しました。
```sample.py
myset = {"H", "a", "p", "p", "y"}
print(myset)

x = 10
y = 20
myset = {x, y}
print(myset)

myset = {10, 20}
print(myset)

x = 10
y = 20
myset = {x, y}
print(myset)
y = 40
print(myset)
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
{'a', 'p', 'H', 'y'}
{10, 20}
{10, 20}
{10, 20}
{10, 20}
```

# まとめ

何かの役に立てばと。