OmniAICreator/Qiita-1.07M huggingface dataset:
夜の渡り鳥が出す鳴き声を検出するnighthawkをdockerで動かしてみた

# 目的
夜渡る小鳥は鳴き声を出しながら飛んでいきます。春とか秋とか平野部でもよく聞こえます。この鳴き声をフライトコールと言いますが、夜間のフライトコール(NFC:Noctural Flight Call)を録音して渡りの生態を調べることが北米で行われています。そのための自動検知プログラムがpythonで開発されており、それをdockerで動かしてみようというものです。pythonの環境構築はバージョン管理やコンフリクトとかライブラリがないとか苦手なので、dockerを使うというのが新しいと思います。

## 難易度
- 初心者向け

## anaconda3をインストール
- docker desktopをインストールする
    - こちらをご覧ください。 https://docs.docker.jp/desktop/install.html


- docker-anacondaのイメージをとってくる　
    - continuumio/anaconda3:latest

```
$ docker pull continuumio/anaconda3
```

- anaconda3イメージを基にコンテナを作成

```
$ docker run --name anaconda -it -p 8888:8888 -v /Users/XXXXX/docker/anaconda:/home continuumio/anaconda3 /bin/bash
```

- anaconda３に事前からインストールされているパッケージを確認します。

```
base) root@xxxx:/## conda list
```

- anaconda3はtensorflowが最初からインストールされていないので、tensorflowをインストールします。

```
base) root@xxxx:/# conda install tensorflow
```

## nighthawkをインストールする

https://github.com/bmvandoren/Nighthawk

> #### nighthawkの概要
>
> - Nighthawk は、夜行性の鳥の移動を音響モニタリングするための機械学習モデルです。
> - Nighthawk は、北アメリカ東部で最大のカバー範囲を持つ、アメリカ大陸からの夜行飛行通話 (NFC) の録音について訓練されています。モノチャンネル オーディオ ファイルを .wav 形式で処理し、検出結果を表形式 (.csv および .txt) で返します。Nighthawk には現在、夜の移動中に鳴く鳥類 82 種、18 科、4 目からのトレーニング データが含まれています。
> - Nighthawk は Python 環境で実行されます。基礎となるモデルは[TensorFlow](https://github.com/bmvandoren/Nighthawk/blob/main/tensorflow.org)でトレーニングされました。
> - Nighthawk のトレーニングとパフォーマンスの詳細については、次の[論文](https://www.biorxiv.org/content/10.1101/2023.05.22.541336)を参照してください。

- nighthawkのライセンスはCreative Commons Attribution-NonCommercial 4.0 International Licenseで商用利用不可です。
- インストールマニュアル通りに`nighthawk-0.3.0`をインストールします。Python 3.10 を使います。

```
conda create -n nighthawk-0.3.0 python=3.10
```

- 次に、環境をアクティブ化します。

```
conda activate nighthawk-0.3.0
```

- そして、Nighthawk Python パッケージとその依存関係をインストールします。

```
pip install nighthawk
```

## 実行時エラーの対策

しかしそのままでは動きませんでした。メッセージから`soundfile`と`libsndfile1`のインストールが必要でした。また`pip install soundfile`の実行すると、rootユーザーとしてpipを実行することに関する警告が表示されました。この警告は、rootユーザーでの実行がシステムのパッケージマネージャーと競合したり、権限の問題を引き起こす可能性があるためです。


```
python -m venv myenv
source myenv/bin/activate  # Unix/macOSの場合
# myenv\Scripts\activate  # Windowsの場合
pip install soundfile
apt-get update && apt-get install -y libsndfile1
apt install time
```

- 計算時間計測のため、timeもインストールしておきます。

これで走るようになりました。めでたしめでたし。


## 実行結果

- 出力はフライトコールの検出結果だけでなく、音声分析ソフトravenやaudacityのフラグテーブルも出力できます。次の例はravenようです。

```bash
(myenv) (nighthawk-0.3.0) root@f3b4f7f3e72d:~# time  nighthawk /home/231109_1800.wav  --raven-output
Loading detector model...
Getting detector configuration file paths...
Running detector on audio file "/home/231109_1800.wav"...
loading taxonomy
using taxon subset
masking taxa with ap less than 0.7
....略
processing file: using custom model runner
Processed 3613.4 seconds of audio in 792.7 seconds, 4.6 times faster than real time.
predictions generated
doing calibration
merging taxonomic predictions
Writing output file "/home/231109_1800_detections.csv"...
Writing output file "/home/231109_1800_raven.txt"...

real	13m18.061s
user	67m20.669s
sys	3m49.935s
```

１時間のモノラルファイルで13分かかりました。６個フライトコールを検出しました。そのうち正解は２つでした。北米の教師データなので東北アジアの小鳥とは違うかもしれません。


どなたかのお役に立てたら嬉しいです。
福田昭のデバイス通信 第5回 第6回

# パイプライン

複数の命令をオーバーラップ実行し、高速化を図るCPUの仕組み。

- 命令を読み出す (命令フェッチ)
- 制御信号を生成し、レジスタを決定する (命令デコード)
- レジスタを参照し、命令を実行する (実行)
- メモリの読み書き (メモリアクセス)
- レジスタに書き込む (ライトバック)

ステージ毎に1クロックサイクル必要な為、5クロックサイクルで1命令を実行できる。
依存関係が無い場合は同時に命令を実行し、1命令を1クロックサイクルで実行できることもある。
クロック周波数の最大値は最長のステージに依存する為、ステージを分割すると改善できるが、1命令当たりのクロックサイクル数やシリコン面積、消費電力が増加する。

# インオーダー実行とアウトオブオーダー実行

命令を順番通りに実行することをインオーダー実行、命令の順番を変えて実行することをアウトオブオーダー実行と呼ぶ。
アウトオブオーダー実行は性能を向上させるが、シリコン面積と消費電力が増加する。

# シングルコアとマルチコア

シングルコアはパイプラインを増やし、クロック周波数を改善するが、消費電力の限界で行き詰まる。
マルチコアはCPUコアを増やし、少ない消費電力でスループットを向上させる。

# キャッシュ

頻繁にアクセスするデータが保持され、メモリアクセスの回数を減らす。
メモリバスの要求値を下げ、コストと消費電力を減少させる。
16~256バイトのラインで構成され、ラインが指すアドレスをタグと呼ぶ。
GitHubのプルリクエストで自動化できる点をまとめてみた

## はじめに
プルリクエストを使った開発で自動化できる箇所をまとめました

## 自動化できる点
次の4点の自動化をこの記事では紹介します
1. プルリクエストのテンプレートを用意し、PRに記載する内容を最低限揃える
2. プルリクエストのレビューアサインを自動化する
3. チーム内のレビューアサインを自動的に回す
4. レビュー依頼やコメントを　Slack で通知させる

### 1.プルリクエストのテンプレートを用意し、PRに記載する内容を最低限揃える
テンプレートでプルリクエストに書くべき項目を列挙しておくことで、最低限書くべき内容を揃えます。後からプルリクエストを見たときに開発の背景をたどることができます
最低限、PRの背景や目的、変更前後が整理されていると良いと思います。チーム内で相談してテンプレートの項目を整理しても良いかもしれません

https://docs.github.com/ja/enterprise-cloud@latest/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository

### 2.プルリクエストのレビューアサインを自動化する
CODEOWNERS ファイルを設定しておくことでファイル・フォルダ単位での変更を検知しユーザーやチームに単位でレビューがアサインされます。変更点を考慮してレビューアサインすることや、変更したのにレビュー依頼し忘れを防止することができます。ただ、担当領域が多いと何でもかんでもレビューアサインされるので通知過多になりますが...

https://docs.github.com/ja/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners

### 3.チーム内のレビューアサインを自動的に回す
以下のような理由でチームメンバーでのレビューを輪番制で行いたいときに自動化することができます
- 担当をつけて当番でレビューをしている
- 必須レビューは存在し、他のメンバーにレビューをアサインして学習を促す

https://docs.github.com/ja/organizations/organizing-members-into-teams/managing-code-review-settings-for-your-team

GitHubのページだと、設定イメージつかない場合は以下のサイトでわかりやすく書かれているので参考にしてみてください

https://devlog.atlas.jp/2022/02/24/4364

### 4.  レビュー依頼やコメントを　Slack で通知させる
Slack と GitHub を連携させることで、レビュー依頼やプルリクエストにコメントがあったときに Slack に通知が来るようにします

https://github.com/integrations/slack

通知に関する設定はコマンドもしくは GitHub の設定にある Scheduled reminders から行なうことができます

https://github.com/settings/reminders

## まとめ
取り入れられそうなものがあったら、参考にしてみてください
【Typescript】入れ子状のオブジェクトから分割代入する方法を学んだ

## 背景
乱数で7けたの数字を生成し、それを郵便番号として住所を検索するのを試みていた。
APIとしてzipcloudを使用。
なお従来は `res.data.results`のように取り出していた
## 学んだこと
分割代入で以下のように取り出せるそう
```Post.tsx
const {data: {results}} = await axios.get(requestUrl);
```
## レスポンスのデータ形式
以下の通り。
```
config:
data: 
  message: 
  results:
  status: 
headers: 
request: 
...
```
Chromium における "TLS SHA-1 サーバー署名対応の廃止" について

# これは何？
SHA-1 という暗号化アルゴリズムは既に安全なものでは無く、2015 年以降重大な脆弱性が
確認され続けています。
このため [RFC 9155](https://www.rfc-editor.org/rfc/rfc9155.html) で廃止が勧告され、それに従い Chromium が SHA-1 のサポートを2023 年で打ち切りました。
(Google Chrome 117 以降 / Microsoft Edge 119 以降)

本記事は [Deprecate TLS SHA-1 server signatures](https://chromestatus.com/feature/4832850040324096) 、
すなわち TLS SHA-1 サーバー署名の廃止についての関連ドキュメントのまとめ及び備忘録です。

# 事象
Chromium ブラウザのバージョンアップに伴い、以下のいずれかのエラーでサイトへの接続に失敗します。
・ ERR_SSL_PROTOCOL_ERROR
・ ERR_SSL_VERSION_OR_CIPHER_MISMATCH

net-export で確認した場合には、 Reason = 245 ([SSL_R_WRONG_SIGNATURE_TYPE](https://boringssl.googlesource.com/boringssl/+/refs/tags/version_for_cocoapods_6.0/include/openssl/ssl.h#4792)) として
出力される例が多いようみられます。

``` net-export.sample
    SSL_HANDSHAKE_ERROR
    --> error_lib = 16
    --> error_reason = 245
    --> file = "..\\..\\third_party\\boringssl\\src\\ssl\\extensions.cc"
    --> line = 452
    --> net_error = -107 (ERR_SSL_PROTOCOL_ERROR)
    --> ssl_error = 1
```

# 原因と対策
TLS Handshake 中の Server Key Exchange において、サーバー上で SHA-1 の署名アルゴリズムが使われている場合に発生します。
例として古い OpenSSL モジュールを用いている場合などが該当します。

なお、クライアント証明書の問題ではないため、原則サーバーサイドでの修正が必要となります。

# 一時回避策 (クライアントサイド)
Google Chrome では [InsecureHashesInTLSHandshakesEnabled](https://chromeenterprise.google/policies/#InsecureHashesInTLSHandshakesEnabled) ポリシーにて、
本機能を制御することが可能です。
ただし、本ポリシーは Chrome v123 で削除の予定です。

## 回避策についての補足
Microsoft Edge では上記ポリシーを正式サポートしておらず、動作の保証はなされません。

# 出典
[TLS SHA-1 Server Signatures](https://chromium.googlesource.com/chromium/src/+/713741538b3790da4f749b688e64f0158492a6af/docs/security/tls-sha1-server-signatures.md)
YAML の解説ページを日本語に翻訳しました

[Learn yaml in Y minutes](https://learnxinyminutes.com/docs/yaml/) を日本語に翻訳しました。

https://learnxinyminutes.com/docs/ja-jp/yaml-jp/

といっても翻訳したのは 2 年前で、当時に出した Pull Request がようやくマージされたという経緯です。

このサイトの言語解説は、その言語の文法に則ったソースコード内でその言語の仕様を解説するというスタイルです。

なお、この YAML 解説ページの英語版は GitHub Docs から引用される程度の信頼性はあるようです。

[ギットハブ　アクション　のワークフロー構文 - GitHub Docs](https://docs.github.com/ja/actions/using-workflows/workflow-syntax-for-github-actions#about-yaml-syntax-for-workflows)

> YAML を初めて使用する場合は、「[Learn YAML in Y minutes](https://learnxinyminutes.com/docs/yaml/)」 (YAML を Y 分で学習する) を参照してください。

もしよければご活用ください。
初めてのチーム開発

## 初めてのチーム開発を終えて
こんにちは、先日、初めてのチーム開発を終えたのでその振り返りをしたいと思います。よかったところや、反省点などたくさんあるので参考になれば。

## アイディア決め（よかったこと）
アイディア決めでよかったことは、一人ずつアイディアをもってきてそれから決めたことです。ここでいろいろなアイディアを出し合うことで、自分一人では出なかった発想や、考え方を見ることができてとても勉強になりました。

## アイディア決め（反省点）
アイディア決めでよくなかったなと思う所は、どのくらいのボリュームになるかをあまり考えていなかったことです。というのも実装を一週間でやらなければならなかったので、この時点で一週間で実装可能かをよく考えるべきでした。後で詳しく書きますが、実際に考えていた機能をすべて実装できず全体の５割くらいしか実装できませんでした。なので、アイディアを決めるときは予算や時間などを考慮して実現可能かを吟味していくことが重要だったなと今になって思います。

## 要件定義（よかったこと）
要件定義のフェーズでよかったことは、スライドを作成してみんなで見ながら要件定義をしていたことです。いままでは、口頭で説明していてわかりずらかったのが、スライドをみんなで見ながら作成していったことで何を話しているか、何をしたらいいのかがとても分かりやすくなりました。みんなで共通のものを見ながら作成するのはとても重要なことだなと思いました。

## 要件定義（反省点）
要件定義で悪かったことは、要件定義をあまり理解せず進めていたことです。特に機能要件と非機能要件の項目がよくわかっておらず、なぁなぁで終わらせてしまったので、次からはしっかりと理解して何を決めるのかを細かく決めていきたいと思います。

## 設計、タスク出し、環境構築（よかったこと）
このフェーズでよかったことは、画面レイアウトを先に決めたことです。画面レイアウトを決めておいたおかげで、実装でフロントの仕事がすごく楽になったと思います。

## 設計、タスク出し、環境構築（反省点）
反省点は、タスク出しと見積りが甘すぎたことです。タスク出しが大まかすぎたせいで実装の時になにをしたらいいのかのすり合わせができておらず、つぎはぎなコードになってしまいました。また、見積りが甘すぎて３時間でできると思っていたところに１０時間かかっていたりと、実装の時に痛い目を見たので、設計するときには細かくタスクを分けて、しっかりと見積りをしていきたいと思います。

## 実装（よかったこと）
実装していて、よかったなと思う所は、毎日定例をして進捗を確かめ合っていたことです。これのおかげで、なんの機能をあきらめて、どこの作業をフォローしてすればいいのかがわかったので、今回のチーム開発において一番やっていてよかったと思う所でした。

## 実装（反省点）
実装しているときの反省点は、リスケジュールが遅かった点です。月曜日から日曜日までの実装期間で、火曜日には進捗が遅れていることがわかっていたのに、リスケジュールをしようと思ったのが木曜日で、時間をロスしてしまいました。次からは、進捗が遅れていると分かったときにリスケジュールをしていきたいと思います。

## チームの人達から見た自分のいい所と悪かった所
チームの人達で反省会をして、自分たちのよかった所、改善点などを話し合いました。今回自分の良かった所は、コードの修正が早かった所や、いつでも冷静でいた所らしいです。自分ではあまり思いませんが、第三者から見た自分はこんな人なんだなと知ることができてよかったです。また、改善点はチームの中であまり発言していなかったのでもっとガンガン発言していってもいいといわれました。確かにあまり進んで発言することが少なかったので、これから、チーム開発をするときはガンガン自分の意見を言いたいと思います。

## 最後に
今回のチーム開発では、みんな初めてのチーム開発＋フレームワーク禁止でとてもハードに感じました。ですが、みんなで協力して一つものを作り上げたのはとてもいい経験になったと思いますし、何よりとても楽しかったのでここまで一緒に開発してくれたみんなには本当に感謝です。もう一度チーム開発があると思うので、そこで今回の経験を活かしつつ、みんなで楽しんで開発できるように頑張りたいと思います。ここまで見てくれてありがとうございました！
AWS Builder ID(削除済み)のメールアドレス再利用はできるのか？

できるの？

# 結論
~~できなさそう。:no_good:（2024/2/1現在）~~
できました！:ok_woman:（2024/2/21現在）

# やりたいこと

![ビルダーIDアドレス移行.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198171/8e33513a-927a-c605-7f64-5592408683f0.jpeg)

Builder ID【A】のメールアドレス【X】を、
別の削除済みBuilder ID【B】に紐づいていたメールアドレス【Y】に変更したい。

:::note info
ビルダーIDのメールアドレスを後から変更すること自体は可能。

> AWS ビルダー IDの作成に使用したメールアドレス と 名前および ニックネームを編集できます。

参考：[AWS ビルダー ID プロファイルの編集](https://docs.aws.amazon.com/ja_jp/signin/latest/userguide/edit-details-aws_builder_id.html)
:::

# ID削除から7日後時点で試した際にはNG
削除済み(削除処理から7日経過)のBuilder IDで使用していたアドレスで
新規Builder IDの作成と、既存BuilderIDへの紐付け、いずれも試しましたが
どちらもできませんでした。
### 新規Builder IDの作成 : NG
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198171/ec363f51-80e4-5ef4-10a2-6514e79f0693.png)
### 既存Builder IDへの紐付け : NG
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198171/d10d0808-9885-4e91-ece0-06b71d253a30.png)

# ID削除から4週間経過したら成功した【2024/2/21追記】
2〜3週目時点では試していなかったのですが、 約4週間経過した後に
新規Builder IDの作成を試したところ、成功しました！

### 新規Builder IDの作成 : OK
27日経過後のメールアドレスでサインアップを行った所、認証コードのメールが飛んできました。
そして認証コード入力後、以下のパスワード画面に遷移しました。
キャプチャを撮り忘れてしまいましたが、この後Buidler IDの作成が正常に完了しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198171/e2cc8a66-f7dc-6813-cca9-087bb4130049.png)

### 既存Builder IDへの紐付け : (未検証)
既存BuilderIDへの紐付けについては動作確認できていないのですが、
新規作成ができたのならおそらくできそう。
（またID削除してもう1ヶ月待たなきゃいけないと思うとやる気がでません...）

# ID削除時の案内で、再利用可能性を期待してはいた

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198171/c11dceaf-56cd-2686-5047-e39312722d93.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198171/aa39e405-039b-3b99-2b74-6d5033f9b2e7.png)

> 削除中は、同じメールアドレスで別の ID にサインアップすることができません。

と記載があったので、「削除後は同じメールアドレスで別のIDにサインアップができる」んだろうなと読んでいました。

# re:Postでも聞いてはみたけど...
https://repost.aws/ja/questions/QUHSWvludzR1iC05h0IcB56A/aws-builder-id%E3%81%AE%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E5%86%8D%E5%88%A9%E7%94%A8%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6

回答者さまも、即時で検証してくださった結果としては、作成に失敗されていたようです。
このとき、「(ID削除後の)時間経過が足りないんですかねぇ...？」と思っていたのですが、その通りだったようです。

# あとがき【2024/2/21修正】
2/21の結論として、削除済みのBuider IDの再利用は可能ですが、
再利用可能となるまでに1週間以上〜4週間弱を要するようです。

まぁそもそもBuilder ID認証を使うサービスが数える程度しかないので
ほとんどの人は困らないと思うのですが、
とある事情で気になったときにあまり情報が見つからなくて困ったので書いてみました。
React初学者、Atomic Designでつまずく

# はじめに
Reactの学習を始めて約2週間になります。
Udemyの講座学習にて **Atomic Design** をハンズオン形式で学んでいたところ、便利である反面、とある **落とし穴** に気づきました。

**そもそもAtomic Designとは？** 
UIの構成要素を5つのコンポーネントに分解し、順番に設計していく手法です。

https://qiita.com/Kazuhiro_Mimaki/items/3d9a8594064aab5119da
# 事の発端
Atomic Designを用いて簡単なプロフィールページを作成していました。
すると、**スタイル（デザイン）が適用されていないではないか..**
エラーは出ていないし、正常に動いているのになぜ..？
コードを一通りチェックしました。

# 原因
**propsの名前がファイル毎に異なっていました。**
スタイルを適用している部分で受け渡しを行っているpropsの名前がバラバラだったんですね。
同じものを受け渡ししているのに名前が違ったら、そりゃあ正常に反映されません。
**なんやねーん！まーた単純なミスか。。**
若干萎えつつも、なぜこのような単純なミスをしてしまったのか考えてみたところ・・・
 **Atomic Designを用いたためファイル数が多くなりすぎて、名前のズレに気づけなかった。** 
 のが要因でした。
# おわりに
**Atomic Designには、デザインの変更が容易になる、パーツが使いまわせるといったメリットがあります。
その一方で、今回のようにファイル数が膨大になって管理が大変！みたいなデメリットもあります。**
したがって、共同開発の際は特に注意が必要ですね。
メリット・デメリットを考慮して採用を決めていくべきだと思います。

**個人学習でこのような発見ができて、むしろラッキーでした。**
3年目に突入するエンジニアの目標

# 背景
・ここに書き記すことで実行力が上がる。
・見える化することで管理しやすい

# 去年の振り返り
去年は会社に入りたてで、制度を使っていっぱい資格を取る年にしようと考えていた。
### 目的
・資格勉強による基礎力知識向上
・案件アサイン率の上昇
・会社への勉強意欲のアピール

### 結果
・基礎知識→実務でも生かすことができた
・案件へはアサイン→できた
・会社への勉強意欲のアピール→賞をもらえた

### 反省点
・興味のある分野や実務で使う資格（AWSCLF・Python基礎/実践・LinuxEssential・JavaBronze）はとることができたが、業務で使っていないが大事なDBの資格は取ることができなかった。
・FEとAWSのSAAは模試合格点まで勉強したが、試験を受けずに終わってしまったこと

# 2023に立てた2024の目標
・自分でDjangoアプリを作る！
・DBに強くなる
・Dockerの理解
・技術のアウトプットを増やす
・1か月に1冊技術書を読む

# 転職エージェントと話して
今後の頑張り方がわからなかったのでとりあえず転職エージェントという第三者目線で判断してもらった。
その結果今の僕には下記の経験が足りないらしい
・API開発経験
・DB周りの知識とDB設計経験
・チーム開発経験

### API開発
API開発を個人でやる方法を調べてみると、PythonのDjangoやFlaskでアプリを作成しAPIコール
を行えるようにセットアップする方法が見つかった。
アプリ作成の際にはDBを使用したり、今勉強しているDjangoが必要なので良かった

### DB周りの知識とDB設計
これについては、DBの構文については大学で学習したので、もっと概念的なことを学びたいと思った。
YouTubeで動画教材をとりあえず無料で見てみて、分からないなと思ったり足りないと思った分野をUdemyなどで購入して理解を深めようと思った。

### チーム開発
これはプライベートでやるのは中々難しい。と思っていたが、ChatGPTに聞いてみるとイベントの参加やGitHubやGitLabなどのオープンソースプロジェクトに参加がありやってみたいなと思った。
またその日の出来事を技術ブログにすることでアウトプットにもなると思った。
あとは個人開発依頼の常駐先に今で１年ほどになるので、会社にお願いして案件先を変えてもらうのも一つである。ただそれまでにポートフォリオを１つは作成したい。

# まとめ
以上から今年の目標は下記に決まった
**・Docker環境でDBが絡むDjangoアプリの制作（簡単なチュートリアルと自分で考えたもの１つずつ）
・そのアプリからAPI作成
・YouTubeなどを有効活用してDB周りに強くなる
・チーム開発イベントへ参加してみる or 案件を変えてもらう
・1ヶ月に1冊のペース技術書を読む
・上記すべてに対してブログを作成**


<font color="red">**先輩エンジニアの方々、目標に関するアドバイスや効果的な方法がありましたら、教えていただけると嬉しいです。**</font>
今年も１年後悔無いように頑張るぞ！年末にこれ見返してもっと達成できていたら嬉しい。
Alma Linux 9/Rocky Linux 9 、apacheサーバーで、sqlite3のDBファイルのネットワークで使うためのコツ(一応、玄人向けです。) [FUKUTAKA編]

#

[ここをクリックすると他の技術投稿の目次に行きます](https://qiita.com/FUKUTAKA7938/items/2312362e44dbcecd11ca)

# Alma Linux 9/Rocky Linux 9 、apacheサーバーで、sqlite3のDBファイルのネットワークで使うためのコツ(一応、玄人向けです。) [FUKUTAKA編]

※この見解は、あくまでApacheサーバーの構築(SELinux と firewalld の設定含む)と
Python3での WSGIプログラミング（テンプレートエンジンのDjango や Flaskなどもでもかまいません）ができるのが前提です。

一から書いていくと、ものすごく長くなりますので、大まかなことを書いていきます。
ご了承ください。
あと、分かりにくかったら、ごめんなさい。

通常のWSGIプログラミングでは、SELECT くらいしかコードが動きませんが、
この設定方法を使えば、INSERT や UPDATE などもできます。

私の見解では、このSQLite3ファイルの接続のコツには２つの方法があります。


## ○共通設定： sqlite3 データベースファイルを /var/www/html の中に置くこと。
(/var/www/htmlの中にディレクトリを置き、その中にDBファイルを作るのも可)

## ① sqlite3のDBファイルを 「その他のユーザ」のファイル権限を rw にする方法
(オーナー名をrootユーザ、グループ名をrootユーザ でも可)

なお、この方法は、セキュリティ上良くないと私は思います

または

## ② sqlite3のDBファイルをファイル権限の 「オーナー」名を apache ユーザにすること 
(オーナーのファイルタイプ 「rw」、グループとその他のユーザのファイルタイプ 「r」 で可)


この2つのうちで、
②を私は推奨（あくまでも個人的な見解です。）
①は、apache オーナー以外でもデータの書き換えができてしまいます。
なので、
## ②の解説をします。

apache サーバーのWebページを閲覧するときは、アクセスするためのapacheサーバのオーナーが標準で apache になります。
(Ubuntu系なら WWW-DATA が、標準でオーナー名になるみたいです。)
なので、apache にするわけなのですが、

やり方としては、まずは、
/var/www/html内にディレクトリを作って、
(/var/www/html/ディレクトリ名)
  
その中にSQLite3 の DBファイルを移す。

そして、SQLite3のDBファイルと
このディレクトリのオーナー名をapache、グループ名をroot に変更して

ディレクトリのパーミッションを 700 に変更し、

SQLite3のDBファイルのパーミッションは、
そのまま　または、600でよろしいかと思います。

 こうすることで、rootユーザとapacheオーナー(ブラウザ)からでしか、
 ディレクトリの中に入れませんし、
 DBファイルもroot ユーザとapacheオーナー(ブラウザ)からしかアクセスできません。

 （これは、結局ディレクトリに入る段階で、
rootユーザーまたはapacheオーナーでしか入れないから、
DBファイルはそのまま、または、600で良いかと思います。）


通常は、「その他のユーザ」のファイル権限で読込ですが、中に入れたり見れたりします。

 つまり、その他のユーザからはディレクトリには入れないし、エラーがでます。

ちなみに、/var/www/html の直の下に配置すると、その他のユーザ権限から入れて、確認等ができてしまいますので、
あくまでも更にディレクトリを奥に作るのが良いかと私は考えました。

ちなみに、オーナーapache(WWW-DATA)は、ログイン画面からアクセスしようとしてもできません。

これが、ある種のセキュリティ方法です。

では、sqlite3 でSQL構文を使うには、どうしたらよいかですが、

```# sqlite3 DBファイル名（Pathは指定してください）```

でできますし、root権限で使いたくないならsqlite3 で、SQLite3のDBファイルを書き換える前に、
ディレクトリとDBファイル名のオーナー名、グループ名を自分の端末のユーザ名に書き換えて、パーミッションをデータ修正しやすいものにしておけば良いかと思います。

終わったら、また、設定する（設定するの忘れる人多いかもなので必ず設定しましょう）。

あとは、WSGIプログラミングで、UPDATE や INSERT で コードを書くだけです。

ちなみにWSGIプログラミングのpython3なら
    
    dbname = "/var/www/html/{ディレクトリ名}/{SQLite3のDBファイル名}.db"
    conn = sqlite3.connect(dbname)

で、アクセスできます。

さらに言いますと、
/var/www/htmlの中に入られたことを考えて、

この中のディレクトリの中に
さらにディレクトリを作って、
オーナー名(apache)とグループ名(root)とパーミッション(700)を設定をし、その中にDBファイルを入れて処理します。

```(/var/www/html/ディレクトリ1/ディレクトリ2/dbファイル名.db```のように)

こうすると端末操作で、/var/www/htmlの中に入られたとしても、

最初のディレクトリ1は名前がわかっても、
ディレクトリ2から下は、２つ目はroot でないとアクセスできないので、名前さえ確認ができないかと

なので、絶対に root パスワードは、もれがないように秘密にしたほうが良いですよ。

って、感じです。あくまでも主観的な見解なので、ご了承ください。

ところで、普通のファイルも同じ方法で、Webからアクセスできるの気づきました？

#

[ここをクリックすると他の技術投稿の目次に行きます](https://qiita.com/FUKUTAKA7938/items/2312362e44dbcecd11ca)
lualatex で 画像が表示されないときの解決法

# lualatex で画像が表示されないときの対処法
## 原因は \usepackage にあるらしい
\documentclass[a4adapter,12pt]{ltjsreport}
を、texファイルの先頭で宣言しており、画像を表示するには、usepackageでdocumentclassから必要なパッケージを呼び出す必要がある。

## 解決方法
自分の場合、\usepackage[dvipdfmx]{color} を削除することで表示されるようになった。

いろいろな記事を見てると、画像を表示するために、
```:tex
\documentclass[a4adapter,12pt]{ltjsreport}
\usepackage[dvipdfmx]{color}
\usepackage[dvipdfmx]{graphicx}
```

を書いてやる必要があるみたいだが、自分の環境では、

![スクリーンショット 2024-02-01 195923.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402613/3734b221-72fd-cb9d-06dd-a0aa123d7faf.png)

こんな感じで。空白は表示されるが、中身を見ることができない現象に出くわした。

```:tex
\documentclass[a4adapter,12pt]{ltjsreport}
\usepackage{color}
\usepackage{graphicx}
```

これで表示されるようになった。
vue-query hooks can only be used inside setup() function or functions that support injection context.

Vue.js で tanstack query を扱う際、`*vue`ファイルではなく、`*.ts`ファイルに処理を切り出したいときがある。
単なるグローバル変数+リアクティブで便利に使いたい。

その場合例えば"message"というクエリキャッシュに同期的に文字列を埋め込む時、`*.ts`に処理を切り出したい。

```ts:message.ts
import { useQueryClient } from '@tanstack/vue-query';

export const setMessage = (message: string): void => {
  const queryClient = useQueryClient();
  queryClient.setQueryData(['message'], message);
};
```

として、これを使おうと思ってもうまくいかない。

```
vue-query hooks can only be used inside setup() function or functions that support injection context.
```
というエラーが出ると思う。`useQueryClient()` は `<script setup lang="ts">` 内でやれと。

これをエラーなく実現するには
https://tanstack.com/query/v5/docs/framework/vue/guides/custom-client
参照のこと。このドキュメントを探すのに骨が折れた。


以下サンプル
```ts:main.ts
import { VueQueryPluginOptions, QueryClient } from ‘@tanstack/vue-query’;

export const queryClient = new QueryClient();

export const vueQueryPluginOptions: VueQueryPluginOptions = {
    queryClient,
    queryClientConfig: {
      // オプション色々
    },
};

app.use(VueQueryPlugin, vueQueryPluginOptions);
```
```ts:message.ts
import { queryClient } from '@/main';

export const setMessage = (message: string): void => {
  queryClient.setQueryData(['message'], message);
};
```
snapshotからEC2インスタンスを立ち上げる手順（イメージ編）

イメージから立ち上げる方法と、ボリュームを付け替える方法がある。
ボリュームを付け替える方法は以下
https://qiita.com/vanshi/items/33cdf1544d72313f3d0e

# 手順
- 1.snapshotから「スナップショットからイメージを作成」
- 2.イメージ>AMIにAMIが作成される
- 3.AMIからAMIインスタンスを起動
- 4.EC2インスタンスの設定（オリジナルのEC2がある場合は設定を合わせる）
- 5.EC2インスタンスとして起動できる

# ElasticIPの付け替え
オリジナルのEC2がある場合は、ElasticIPを付け替える。
Elasitc IP>該当のElastic IPをクリック>Elastic IPアドレスの関連付け

上記手順で立ち上げたインスタンスタイプを選択
「このElastic IP アドレスの再関連付けを許可する」にチェックを入れる


最後に、オリジナルだったインスタンスを終了する
Flaskで作ったwebシステムをAWSでデプロイしたい[サーバー]

# 初めに
今回、専門学校の友人を集めてチーム開発をするにあたって、作ったwebシステムを公開したいと思い、挑戦してます。
# とりあえずやってみよう
AWSは学校で単語を少し覚えた程度ですが、なにもやってみないとわからないのでとりあえずできることを色々やってみました。
## 調べて出てきたものを参考にしてみる
「AWS 動的WEBサイト 公開」と調べて出てきたこちら

[【AWS】動的Webサイト構築の備忘録](https://qiita.com/grapefruit1030/items/f864b669d54ec8097d04)
を参考にしました。
データベースはMySQLを使いたいのでRDBを使おうとしましたが、、、

__なぜか接続ができない__

色々調べましたが原因がわからなかったので担任の先生に相談してみると、別の方法をすすめられました。
## EC2にLAMPを入れてやってみる
そもそもできないなら他の方法でやればいいじゃん！ということで、教えてくれました。

[Amazon Linux への LAMP のインストール](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/install-LAMP.html)
このサイトを参考に早速調べてやってみると、
サーバーをたてることはできましたがなぜかApacheなどが入れられない

原因は自分が間違えて「Amazon Linux」ではなく「Amazon Linax 2023」のサーバーをたててしまっていたことでした。

なので「Amazon Linax 2023」で説明しているこちら
[Amazon Linux 2023への LAMP のインストール](https://docs.aws.amazon.com/linux/al2023/ug/ec2-lamp-amazon-linux-2023.html)
を参考にしてみるときちんとできました。

# 最後に
とりあえずサーバーは準備できたのでデータベースとサイトの公開を頑張ります。
1NCEをM5Stack用SIM7080G搭載CAT-M/NB-IoT+GNSSユニットで動かしてみる

# はじめに
以前に、M5Stack用SIM7080G搭載CAT-M/NB-IoT+GNSSユニットとIoT Connect Mobile Type S というNTTコミュニケーションズが提供しているSIMを使って、HTTP通信の確認まで行いました。そのときの記事がこちらです。

https://qiita.com/yukimatsu/items/ad63bed6367639091540

そのときにも、1NCEのサービスを使用したいと思っていたのですが、今回ようやく試すことが出来たので、その内容を書いておきます。

そのときから、1NCEのサービスを使用したいと思っていたのですが、ようやく動作確認が出来たので、その内容を書いておきます。結果としては、無事に動作したことが確認できています！


<br>

**M5Stack用 SIM7080G搭載 CAT-M/NB-IoT+GNSSユニット（アンテナつき）**

https://www.switch-science.com/products/8191


# そもそも1NCEとは
https://1nce.com/ja-jp/

1NCEは、低容量のグローバルなIoT通信を実現するサービスで、IoTに特化したIoT・M2M向けの法人用回線サービスとなります。プリペイド、10年間一括2,000円で格安にIoTアプリケーションを配備、接続、管理できるそうです。
日本では、ソフトバンク株式会社が販売しています。尚、法人用回線サービスとなるので、個人での申し込みはできないと思います。


# 1NCEのSIMを使って通信する方法

ハード構成やソースコード全体などは、以下の記事を参考にしてください。

https://qiita.com/yukimatsu/items/1ad1b505ea63006d0647

こちらの記事ではAPN設定の変更箇所のみを記載します。

**1NCEの設定**
```cpp
// APN設定：1NCE用の設定
const char APN[] = "iot.1nce.net";
const char LTE_USER[] = "";
const char LTE_PASS[] = "";
```

**IoT Connect Mobile Type Sの設定**
```cpp
// APN設定：IoT Connect Mobile Type Sの設定
const char APN[] = "mobiledata.ntt.com";
const char LTE_USER[] = "";
const char LTE_PASS[] = "";
```

TinyGsmClientライブラリを使用した場合は、以下のように接続して下さい。
```cpp
TinyGsm modem(Serial2);
TinyGsmClient client(modem);

// 途中省略

modem.gprsConnect(APN, LTE_USER, LTE_PASS);
```


# 終わりに
1NCEのSIMカードを使って、M5Stack用SIM7080G搭載CAT-M/NB-IoT+GNSSユニットで通信できることを確認しました。1NCEは、低コストで長期間使えるという特徴があります。IoTプロジェクトに興味のある方は、ぜひ試してみてください。なかなか面白いサービスだと思うので、いろいろ使ってみれたらと思います。
チルンハウスの三次曲線

# はじめに
「代数曲線」のwikiにチルンハウスの三次曲線リンクがあるが、日本語ページがないので、英語ページを参照しつつメモ。

# 方程式

極座標表記
```math
r = Asec^3(\frac{\theta}{3})
```
媒介変数表記
```math
t=tan(\frac{\theta}{3})として
```
```math
x=A(1-3t^2)
```
```math
y=At(3-t^2)
```
もしくは、
```math
27Ay^2=(A-x)(8A+x)^2
```

交差点が原点になるように、右に8A移動した式は、それぞれ、
```math
r=9A(sec\theta-3sec\theta tan^2\theta)
```
```math
x=3A(3-t^2)
```
```math
y=At(3-t^2)
```

```math
x^3=9A(x^2-3y^2)
```




# Sin Cos Tan Sec Cosec Cot
ここで、secは1/cosを指す。
    1 / cos = sec
    1 / sin = cosec(csc)
    1 / tan = cot

エクセルで、角度（ラジアン）との関係性をグラフにした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/3ad9174a-9b6f-38d7-30b8-5da468af9109.png)

# コード
```java:processing
size(800, 800);
translate(400, 400);

background(255);
fill(0);
text("(1,1)", 20, -20);
text("(2,2)", 40, -40);
text("(8,8)", 160, -160);

noFill();

stroke(0);
line(-400, 0, 400, 0);
line(0, -400, 0, 400);

rect(-20, -20, 40, 40);
rect(-40, -40, 80, 80);
rect(-160, -160, 320, 320);

stroke(255, 0, 0);
beginShape();
for (float th=-2f*PI; th<2f*PI; th+=0.01) {
  float t = tan(th/3f);
  float x=1f-3f*t*t;
  float y=t*(3f-t*t);
  vertex(20*x, 20*y);
}
endShape();
```

![tschirnhausen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/ce8d03c0-d8cd-160a-c0d1-028d19ac9b78.png)

右に８A移動した場合は
```java
for (float th=-2f*PI; th<2f*PI; th+=0.01) {
  float t = tan(th/3f);
  float x=3f*(3f-t*t);
  float y=t*(3f-t*t);
  vertex(20*x, 20*y);
}
```
![tschirnhausen_shift8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/18a25f5c-5039-94a8-e81c-e506f3d24466.png)


wolfram alphaを用いて
(1-x)(8+x)^2-27y^2をプロット，x=-14..2, y=-8..8
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/e1fd9aaf-6af6-9337-664c-f25e7b76cdac.png)

9(x^2-3y^2)-x^3をプロット，x=-6..10, y=-8..8
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/6e632e16-8f1d-8d42-61c5-7f4838402f6e.png)

# 参考サイト

https://ja.wikipedia.org/wiki/%E4%BB%A3%E6%95%B0%E6%9B%B2%E7%B7%9A

https://en.wikipedia.org/wiki/Tschirnhausen_cubic
Django RestFramework JWT認証についてめも

# RESTAPIを実装したいので調べてみた

## プロフィール
* Django初めて1ヶ月程度の知識です。

## まずは動かしてみる
* [このページを参考に作ってみた](https://qiita.com/yutoun/items/f750d82d811a85b9304b)

1. settings.pyの一番下に追加
```settings.py
REST_FRAMEWORK = {
    # jwtトークン認証
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),  
}
SIMPLE_JWT = {
    'AUTH_HEADER_TYPES': ('JWT'),
    # JWT有効期限
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=30),
}

```

1. 適当にアプリを作成```python manage.py startapp app1```私はapp1というアプリ名で作成した


1. まずはindex.htmlの表示
```app1/views.py
from django.shortcuts import render

def index(self,req):
        return render(req,'app1/index.html')

```
1. ここで表示してみたらsettings.pyにapp1を追加してなかったので追加したところ表示できた

## ではここからどうやってヘッダにトークンが入っていないものを弾くのか？
* 例によってわからなかったのでchatGPTさんに質問した
* そしたら下記のような回答


```app1/views.py
from django.shortcuts import render

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated


# このクラスがどうやら肝心らしい
class UnauthenticatedView(APIView):
    authentication_classes = [SessionAuthentication]  # Use a different authentication class if needed
    permission_classes = [IsAuthenticated]

    def index(self,req):
        return render(req,'app1/index.html')

def index2(req):
    return render(req,'app1/index2.html')

```
1. ```as_view()```こいつがよくわからなかったので再度chatGPTさんに質問
![about_as_view.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609333/9fecbf87-8bbb-fc50-5efb-f729002d28a7.jpeg)
1. ということは書き方変えればいいのかなと試したところ

```app1/urls.py
from django.urls import path
from . import views
from .views import UnauthenticatedView

urlpatterns = [
    # 最初はこう書くのかなと思っていた
    # path('', views.UnauthenticatedView.as_view(), name='index'),
    path('', UnauthenticatedView.as_view(), name='index'),
    path('index2/', views.index2),
]
```

### 認証弾いた！！！

![jwt_err.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609333/7a7de88e-4765-e9cd-7647-6c17e115d6a6.jpeg)


## まとめ
* なんでこうやって書くと認証がされるのかこれから解明していく
* 書き方はなんとなくわかった
* わかりやすい説明ほしい...
Twig & Chart.jsでグラフ描画

```html
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<div>
    <canvas id="myChart"></canvas>
</div>

<script>
    {% set foo = ['A','B','C','D','E'] %}
    {% set bar = ['1','2','3','4','5'] %}
    
    const name = [];
    const value = [];
    {% for f in foo %}
    name.push('{{ f }}');
    {% endfor %}

    {% for b in bar %}
    value.push('{{ b }}');
    {% endfor %}


    const ctx = $('#myChart');

    new Chart(ctx, {
        type: 'line',
        data: {
            labels: name,
            datasets: [{
                label: 'ex',
                data: value,
                borderWidth: 1
            }]
        },
        options: {
            scales: {
                y: {
                    beginAtZero: true
                }
            }
        }
    });
</script>
```

![スクリーンショット 2024-02-01 18.32.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855584/c21726eb-58d1-8c0f-4f4f-1ec7b0277f73.png)

---

入れ替えがめんどくさかったらjsonに直でシリアライズして入れてもいい

```javascript
    new Chart(ctx, {
        type: 'line',
        data: {
            labels: {{ foo|json_encode(constant('JSON_UNESCAPED_UNICODE'))|raw }},
            datasets: [{
                label: 'ex',
                data: {{ bar|json_encode(constant('JSON_UNESCAPED_UNICODE'))|raw }},
                borderWidth: 1
            }]
        }
    });
```
JSのPromiseではresolve, rejectでは処理が終わらないという話


resolve, rejectでは処理が終わらず、returnの代わりには使えないため注意が必要です。

例えば以下のコードを実行すると、どうなるでしょうか？

``` javascript
const flag = true;
const promise = new Promise((resolve, reject) => {
  if(flag) {
    console.log("成功への道");
    resolve("成功！");
  }
  console.log("失敗への道");
  reject("失敗");
});

promise
.then((value)=>console.log(`promise関数実行完了:${value}`))
.catch((value)=>console.log(`promise関数実行失敗:${value}`));
```

consoleには次のように表示されます。
```
成功への道
失敗への道
promise関数実行完了:成功！
```

resolveした後も処理は止まらず、reject関数も呼ばれてしまいます。

ただし、resolve,reject関数は一度呼ばれた後、状態変化しないので
catchに落ちることはありません。（参考：https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve#%E8%BF%94%E5%80%A4）

以下のようなコードを実行したとしても
``` javascript
const promise = new Promise((resolve, reject) => {
    console.log("処理開始");
    resolve("成功1");
    reject("失敗1");
    resolve("成功2");
    reject("失敗2");
    console.log("処理終了");
});

promise
.then((value)=>console.log(`promise関数実行完了:${value}`))
.catch((value)=>console.log(`promise関数実行失敗:${value}`));
```
consoleには次のように表示され、最初に実行したresolve関数の値(成功1)のみ返ります。

```
処理開始
処理終了
promise関数実行完了:成功1
```

resolveした後、処理を終わらせるには、明示的にreturnする

``` javascript
const flag = true;
const promise = new Promise((resolve, reject) => {
  if(flag) {
    console.log("成功への道");
    resolve("成功！");
    return;
  }
  console.log("失敗への道");
  reject("失敗");
});

promise
.then((value)=>console.log(`promise関数実行完了:${value}`))
.catch((value)=>console.log(`promise関数実行失敗:${value}`));
```

もしくはif elseを使いresolveとrejectが排他的に行われるようにする必要があります。
``` javascript
const flag = true;
const promise = new Promise((resolve, reject) => {
  if(flag) {
    console.log("成功への道");
    resolve("成功！");
  }else {
    console.log("失敗への道");
    reject("失敗");
  }

});

promise
.then((value)=>console.log(`promise関数実行完了:${value}`))
.catch((value)=>console.log(`promise関数実行失敗:${value}`));
```
Go言語のスライスでよくある勘違いとその解説

Go言語のスライスは非常に強力な機能を提供しますが、理解しにくい部分もあります。ここでは、Go言語のスライスを使用する際によくある勘違いや混乱の原因となるポイントをいくつか紹介し、それらを明確にします。

### 1. スライスと配列の違い

Go言語の新規ユーザーはしばしばスライスと配列を混同します。配列は固定長であり、そのサイズはコンパイル時に決定されますが、スライスは動的な長さを持ち、実行時にサイズが変更可能です。配列をスライスに変換することはできますが、その逆は直接的には行えません。

### 2. スライスの長さと容量

スライスの[「長さ」と「容量」](https://qiita.com/zhao-xy/items/a2bba7619ba10b02f38a)は異なる概念ですが、これらが混同されることがあります。長さはスライスに含まれる要素の数を指し、容量はスライスの背後にある配列が持つ要素の最大数を指します。`append`を使用してスライスに要素を追加すると、必要に応じて容量が自動的に増加しますが、この挙動を誤解すると予期せぬパフォーマンスの問題が発生する可能性があります。

### 3. スライスの変更と副作用

スライスは参照型であり、同じ配列を指す複数のスライス間で変更が共有されることがあります。これは、スライスを関数に渡したときやスライスを別のスライスに割り当てたときに顕著です。この挙動を理解していないと、予期せぬデータの変更が発生することがあります。

### 4. スライスの`append`操作

`append`関数はスライスに要素を追加する際によく使用されますが、この関数が新しいスライスを返すことを忘れがちです。`append`を使用する際は、返されたスライスを受け取る変数に再代入する必要があります。これを怠ると、追加された要素を失うことになります。

### 5. `nil`スライスと空のスライス

`nil`スライスと空のスライスは異なります。`nil`スライスには背後に配列が存在しないため、その長さと容量は0ですが、空のスライスは背後に配列が存在しないわけではありませんが、要素を持たない状態です。これらの違いは、スライスが実際にデータを持っているかどうかをチェックする際に重要です。

### 6. スライスのコピー

スライスのコピー操作には`copy`関数を使用しますが、この関数はコピーされる要素の数がコピー元とコピー先のスライスの長さの小さい方に等しくなることを理解することが重要です。全ての要素をコピーしたい場合は、コピー先のスライスが十分な容量を持っていることを確認する必要があります。

### まとめ

Go言語のスライスは非常に便利ですが、その挙動を正確に理解することが重要です。スライスと配列の違い、長さと容量の概念、スライスの参照型としての性質、`append`操作の使い方、`nil`スライスと空のスライスの違い、そしてスライスの正しいコピー方法を理解することで、Go言語のスライスをより効果的に使用できます。

参考
1．[[Go言語] スライス初心者ガイド: 空のスライスとnilスライスを理解する](https://qiita.com/atsutama/items/c42d63b9bca6e633c98c)
2. [Go言語におけるスライスの長さと容量のちがい](https://qiita.com/zhao-xy/items/a2bba7619ba10b02f38a)
3. [Golang における配列とスライスのコピー時の違い](https://zenn.dev/_kazuya/articles/af582f7652271b90cd11)
【ST言語ことはじめ】オルタネートについて

## はじめに
オルタネートは、プログラマブルロジックコントローラー（PLC）でよく使用される制御機能の1つです。この記事では、ST（Structured Text）言語を使用してオルタネートを実装する方法について解説します。

## 使用機材

|   |機種など   |
|:---:|------|
|PLC  |Q02CPU, QX41, QY41P, Q62P, Q38B    |
|アプリ  |GX Works 2    |

I/O割り付けはこちらを[参照](https://qiita.com/so2/items/0f0cab2e324179718b89 "I/O割り付け表")

## オルタネートの実装（ラダー図）

ラダー図でオルタネートを組むと以下のようにM0とM1のa接点とb接点がクロスするような並列回路となります。

```batch:ラダー図
(+)                                               (-)
|    X1                                   PLS M0    |
+----| |----------------------------------(    )----+
|                                                   |
|    M0    M1                               M1      |
+----| |---|/|----+-----------------------(    )----+
|                 |                                 |
|    M0    M1     |                                 |
+----|/|---| |----+                                 |
|                                                   |
|    M1                                    Y71      |
+----| |----------------------------------(    )----+
|                                                   |
```

## オルタネートの実装（ST言語）
オルタネートを実装するために、以下のST言語のコードを使用します。

```st
(* ボタン1の入力とオルタネート出力の定義 *)
PLS(X1, M0);

(* ボタン1が押されるたびにオルタネートを切り替え *)
IF M0 THEN
    M1 := NOT M1;
END_IF;

(* オルタネート出力をランプ1に出力 *)
Y71 := M1;
```

### コードの解説
- PLS（Pulse）命令を使用して、ボタン1の入力信号をM0に割り当てます。
- ボタン1が押されるたびに、M0がONになり、オルタネート出力のM1が反転します。
- M1の状態がY71（ランプ1）に出力されます。

## まとめ
この記事では、ST言語を使用してオルタネートを実装する方法について解説しました。オルタネートは、制御システムで信号を交互に切り替えるための便利な機能であり、適切に実装することで効率的な制御が可能となります。
【Vue3】クリックイベントを重ねて実装する方法

## はじめに
私は、Todoリストのようなカードに編集ボタンを実装しました。
カード自体にクリックイベントをつけ、編集ボタンにもクリックイベントをつけます。そうすると、編集ボタンを押してもカード自体のクリックイベントが発生してしまいました。

```vue:Card.vue
<div @click="goReferencePage()">
    <span @click="goEditPage()"></span>
    <span @click="deleteCard()"></span>
</div>
```


## 解決方法
stop修飾子を利用しました！`.stop`はJavaScriptの`stopPropagation`を呼び出します。子要素に.stopを与えることで、親要素への伝搬を止めさせ、無事に子要素のクリックイベントを発生させることができました。


```vue:Card.vue
<div @click="goReferencePage()">
    <span @click.stop="goEditPage()"></span>
    <span @click.stop="deleteCard()"></span>
</div>
```
DatabricksにおけるEXECUTE IMMEDIATEのサポート

Databricksランタイム14.3でサポートされました。

https://docs.databricks.com/en/sql/language-manual/sql-ref-syntax-aux-execute-immediate.html

動的SQLを記述できます。

```sql
-- リテラル文字列による自己完結実行
EXECUTE IMMEDIATE 'SELECT SUM(col1) FROM VALUES(?), (?)' USING 5, 6;
```
![Screenshot 2024-02-01 at 18.16.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/001955d6-f64a-3630-3a64-8103190654ee.png)

```sql
-- SQL変数で構成されたSQL文字列
DECLARE sqlStr = 'SELECT SUM(col1) FROM VALUES(?), (?)';
DECLARE arg1 = 5;
DECLARE arg2 = 6;
EXECUTE IMMEDIATE sqlStr USING arg1, arg2;
```
![Screenshot 2024-02-01 at 18.17.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/a6f19281-6da5-87cb-b2c8-3781914aab65.png)

```sql
-- INTO句を使用
DECLARE sum INT;
EXECUTE IMMEDIATE sqlStr INTO sum USING arg1, arg2;
SELECT sum;
```
![Screenshot 2024-02-01 at 18.18.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/558cd7fb-3cdb-375e-a61e-aed63800d296.png)

```sql
-- 名前付きパラメータマーカーを使用
SET VAR sqlStr = 'SELECT SUM(col1) FROM VALUES(:first), (:second)';
EXECUTE IMMEDIATE sqlStr INTO sum
  USING (5 AS first, arg2 AS second);
SELECT sum;
```
![Screenshot 2024-02-01 at 18.18.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/4befe708-aecb-684d-5800-a6fd74930996.png)

私はこれまでは動的に生成していたSQL文字列を`spark.sql`に渡していましたが、SQL側で結構動的に処理できるようになりますね。

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
Go言語におけるスライスの長さと容量のちがい

GO言語のスライス（Slice）は、動的なサイズを持つ配列のような構造です。スライスは、配列よりも柔軟にデータを管理することができ、Go言語におけるデータの扱いをより効率的にします。スライスの「長さ（length）」と「容量（capacity）」は、この柔軟性の核となる概念です。

#### スライスの長さ（Length）
スライスの「長さ」とは、スライスが現在含んでいる要素の数です。len()関数を使用してこの値を取得できます。例えば、

```go
package main

import "fmt"

func main() {
	s := []int{1, 2} // 長さが2のスライスを作成
	fmt.Println(len(s))// 長さ
}
```

```
2
```

#### スライスの容量（Capacity）

スライスの「容量」とは、スライスが背後で確保している配列のサイズです。これは、スライスに追加可能な要素の最大数を意味し、cap()関数によって取得できます。容量は、スライスに新たな要素を追加する際に、背後の配列が再割り当てされるかどうかを決定する重要な要素です。

例えば、
```go
package main

import "fmt"

func main() {
	s := make([]int, 3, 10) // 容量10のスライスを作成
	fmt.Println(cap(s))// 容量
}
```

```
10
```

#### 長さと容量の動的変化
スライスに要素を追加すると（例：append()関数を使用）、その長さが増加します。もし追加によって長さが容量を超える場合、Goは新しい、より大きな容量を持つ配列を確保し、既存の要素を新しい配列にコピーした後、新しい要素を追加します。このプロセスは透過的に行われ、スライスを使用する側は容量の管理を意識する必要はありません。

```go
package main

import "fmt"

func main() {
	s := []int{1, 2} // 初期データ[1 2] がスライスを作成
	fmt.Println((s))

	s = append(s, 3) // 3をスライスsに追加
	fmt.Println((s))
}
```

```
[1 2]
[1 2 3]
```
#### 容量の初期設定と成長
スライスを作成する際に、容量は指定することも、指定しないこともできます。容量を指定しない場合、Goは自動的に管理します。スライスの容量は、通常、要素が追加されるたびに倍増します。これにより、大量の要素を追加する際のメモリ再割り当ての回数を減らし、パフォーマンスを向上させることができます。



```go
package main

import "fmt"

func main() {
	s := []int{1, 2} // 長さと容量が2のスライスを作成
	fmt.Println(len(s)) // 長さ
	fmt.Println(cap(s)) // 容量
	fmt.Println((s))

	s = append(s, 3) // 3をスライスsに追加
	fmt.Println(len(s)) // 長さ
	fmt.Println(cap(s)) // 容量 ２倍になるので、2 * 2 =4
	fmt.Println((s))
}
```

```
2
2
[1 2]
3
4
[1 2 3]
```

#### まとめ
スライスの長さと容量は、Go言語におけるデータ構造の柔軟性と効率性を支える重要な概念です。長さはスライスが現在持っている要素の数を、容量はスライスが背後で確保している配列のサイズを表します。Goはこれらの概念をうまく抽象化しており、開発者は効率的なデータ操作を容易に行うことができます。

#### 
1. [GO言語オンラインデバッグツール](https://go.dev/play/)
java.lang.IllegalStateException: Unbound values in registryエラーで悩まされた

# エラー内容
:::note alert
java.lang.IllegalStateException: Unbound values in registry ResourceKey ...
:::
というエラーの対処に悩まされた。

# 本文だよ
ごたくはいいからはよ解決方法見せろよって方は
[解決チャプター](#解決)まで飛んでください

[TurtyWurty様](https://www.youtube.com/@TurtyWurty)の動画([1.20 Minecraft Forge Modding Tutorial - Ore Generation](https://www.youtube.com/watch?v=aOAavvVzHI8))を参考にして
鉱石生成のコードを書いたのだが
先程の[エラー内容](#エラー内容)に記述した通りエラーが出た。
周りを見渡しても英語情報だし...
しょうがないのでTurtyWurty様のGithubを見てみた。
configured_feature...placed_feature。
アヤシイところはなかった。
軽くggって出てきたstackOverflowに出てきたことを見ても
そこの内容は正しかったり。
そこで出てきた[forge biomemodifire]がヒントとなった。
「あれ?俺ここ見てないな」と。

# 解決
見てみたらコードの内容とかじゃなく、フォルダの階層・名前が違った。
ファイルパスの表示が
`forge/biome_modifier`のはずが
`forge.biome_modifier`となるエディタがあって、
それをそのまま名前と勘違いして打ち込んでしまったわけ。

追記:
字幕よく見たら2つのフォルダーって書いてあった orz

あと、ファイルの中身も違った。
"biomes"キーの中身
"minecraft:is_overworld"の先頭に#がなかった。
あと"type"キーの中身
"forge:add_feature"が複数形でなかった
("forge:add_features"ってこと)
もういっちょ。
placed_feature -> overworld_example_ore.json
"feature"キーの中身がBlockIdになってた...w
打ち込みミスしすぎだなぁ

悪いのはそれを表示したエディタでもなく、TurtyWurty様でもなく
見間違えた私なので、そこに気をつけてください。
エディタに「間違えるからその表記やめろよ!!!」なんて言いたいわけじゃないので。

ではでは。
Incus: Arch Linux で使う

こちらを参考にしました。
[Incus](https://wiki.archlinux.org/title/Incus)

## インストール

```bash
sudo pacman -S incus
sudo systemctl start incus
sudo pacman -S 	btrfs-progs
```

バージョンの確認

```text
$ incus --version
0.5
```

## 初期化

```bash
incus admin init
```

## コンテナーのインストール

```bash
incus launch images:archlinux/current/amd64 arch
```

確認

```text
$ incus list
+------+---------+----------------------+------+-----------+-----------+
| NAME |  STATE  |         IPV4         | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+----------------------+------+-----------+-----------+
| arch | RUNNING | 10.56.160.101 (eth0) |      | CONTAINER | 0         |
+------+---------+----------------------+------+-----------+-----------+
```

## 接続

```bash
incus exec arch bash
```

```text
$ incus exec arch bash
[root@arch ~]# 
```

## login 後のインストールと設定

ユーザー、パスワードの設定

```bash
useradd -u 1200 -m -g wheel uchida
passwd uchida
```

sudo のインストール

```bash
pacman -S sudo
```

visudo で設定

>```text
>%wheel ALL=(ALL:ALL) ALL
>%wheel ALL=(ALL:ALL) NOPASSWD: ALL
>%sudo  ALL=(ALL:ALL) ALL
>```

avahi のインストール

```bash
sudo pacman -S avahi
sudo systemctl start avahi-daemon
sudo systemctl enable avahi-daemon
```

## /etc/pacman.d/mirrorlist の更新

次のファイルで差し替えます。

```text:/etc/pacman.d/mirrorlist
################################################################################
################# Arch Linux mirrorlist generated by Reflector #################
################################################################################

# With:       reflector @/etc/xdg/reflector/reflector.conf
# When:       2024-01-23 05:03:47 UTC
# From:       https://archlinux.org/mirrors/status/json/
# Retrieved:  2024-01-23 05:01:35 UTC
# Last Check: 2024-01-23 04:52:26 UTC

Server = https://geo.mirror.pkgbuild.com/$repo/os/$arch
Server = https://mirror.lty.me/archlinux/$repo/os/$arch
Server = https://mirror.moson.org/arch/$repo/os/$arch
Server = https://ftp.sh.cvut.cz/arch/$repo/os/$arch
Server = https://archlinux.mailtunnel.eu/$repo/os/$arch
Server = https://mirror.f4st.host/archlinux/$repo/os/$arch
Server = https://mirror.cyberbits.eu/archlinux/$repo/os/$arch
Server = https://md.mirrors.hacktegic.com/archlinux/$repo/os/$arch
Server = https://mirror.sunred.org/archlinux/$repo/os/$arch
Server = https://archlinux.thaller.ws/$repo/os/$arch
Server = https://mirror.pseudoform.org/$repo/os/$arch
Server = https://mirror.ufscar.br/archlinux/$repo/os/$arch
Server = https://at.arch.mirror.kescher.at/$repo/os/$arch
Server = https://de.arch.mirror.kescher.at/$repo/os/$arch
Server = https://mirror.theo546.fr/archlinux/$repo/os/$arch
Server = https://america.mirror.pkgbuild.com/$repo/os/$arch
Server = https://asia.mirror.pkgbuild.com/$repo/os/$arch
Server = https://europe.mirror.pkgbuild.com/$repo/os/$arch
Server = https://sydney.mirror.pkgbuild.com/$repo/os/$arch
Server = https://mirror.ubrco.de/archlinux/$repo/os/$arch
```
LaravelでGoogle Two-Factor Authentication（2FA）を導入する方法

# Google Two-Factor Authentication（2FA）の導入方法

Google Two-Factor Authentication（2FA）の導入をしたのでその備忘録

## Google2FAパッケージのインストール

まずは、Google2FAパッケージをインストール


```bash
composer require pragmarx/google2fa-laravel
```

こちらのライブラリ
https://github.com/antonioribeiro/google2fa-laravel

## 設定

Google2FAパッケージをインストールしたら、Laravelの設定ファイルを公開する

```bash
php artisan vendor:publish --provider="PragmaRX\Google2FALaravel\ServiceProvider"
```

## middlewareの設定

app/Http/Kernel.php
上記のKernel.phpファイルに下記を追加

```php
protected $routeMiddleware = [
    //　略
    '2fa' => \PragmaRX\Google2FALaravel\Middleware::class,
];
```

## ルートの設定

2FAの認証ルートを設定します。

```php
Route::group(['middleware' => 'auth','2fa'], function () {
    Route::get('two-factor-authentication', [Google2faController::class, 'index']);
    Route::post('two-factor-authentication/login', [Google2faController::class, 'login']);
});
```

## 認証処理

コードに詳細を記載しておきます。
```php
<?php

namespace App\Http\Controllers\Api\Admin;

// use略
use PragmaRX\Google2FA\Google2FA;

class Google2faController extends Controller
{
    // 表示
    public function index()
    {
        $google2fa = new Google2FA(); //　必須

        $secretKey = $google2fa->generateSecretKey();　//必須

        $user->google2fa_secret_key = $secretKey;
        $user->save();
        // ↑ここで、あらかじめ作成したUserテーブルのシークレットキー用カラムに$secretKeyを保存しておく

        $google2faUrl = $google2fa->getQRCodeUrl(
            $Name, // ログインする名前を入れるのが一般的
            $user->email,　// ユーザーのメールアドレス
            $secretKey
        );
        
        $google2faItems = [　
            'secretKey' => $secretKey,
            'QRCodeUrl' => $google2faUrl // これをフロント側でどうにかしてQRコードに変換
        ];
        }


        return $google2faItems;
    }


    //ログイン処理
    
    public function login(Request $request)
    {
        $code      = $request->input('authenticationCode');
        // $request->input('authenticationCode');はGoogle Authenticaterアプリで表示されている6桁の数字
        $secret    = $request->input('secretKey');
        // シークレットキー
        $google2fa = new Google2FA();　// 必須

        $valid = $google2fa->verifyKey($secret, $code);
        // $validで認証の結果がbooleanで返ってくる
        
        if (!$valid) {
            return response()->json(
                ['message' => 'アクセス権限がありません']
            );
        }

        return $loginData //ログイン後に必要なデータを返す。
    }
}

```



ここから、開発環境によって変更する部分がありますが、私はこれでgoogleの２段階認証の実装を行いました！


ご参考になれば幸いです。

## 一緒に働く仲間を募集しています！
株式会社コネクター・ジャパンでは一緒に働いてくれる仲間を募集しています！

事業拡大に伴い、エンジニアさんを大募集しています。
興味のある方は下記リンクから弊社のことをぜひ知っていただき応募してもらえると嬉しいです。
▼会社について
https://www.wantedly.com/companies/cnctor/about
▼代表メッセージ
https://cnctor.jp/10years-anniversary/
▼応募はこちら
https://www.wantedly.com/projects/1522201
【ST言語ことはじめ】GX Works 2で使える命令文の一覧

## はじめに

GX Works 2は、三菱電機が提供するプログラミングソフトウェアであり、特定のPLC向けにカスタマイズされた命令セットを提供しています。一方、ST（Structured Text）言語は、IEC 61131-3規格で定められているプログラミング言語の1つであり、標準化された命令セットを提供しています。

## IF文

```st
IF X1 = X2 THEN
    Y71 := TRUE;
END_IF;
```
```st
IF X1 = X2 THEN
    Y71 := TRUE;
ELSE 
    Y72 := TRUE;
END_IF;
```
```st
IF X1 = X2 THEN
    Y71 := TRUE;
ELSIF X1 = X3 
    Y72 := TRUE;
END_IF;
```

IF文は条件に応じてプログラムの流れを制御するための命令です。条件式が真（True）の場合には、IFブロック内のコードが実行されます。条件式が偽（False）の場合には、ELSEブロック内のコードが実行されます。

## CASE文

```st
CASE D10 OF
    1 : Y71 := FALSE;
    2, 3 : Y72 := FALSE;
    4..9 : Y73 := FALSE;
ELSE
    Y71 := TRUE;
END_CASE;
```

CASE文は複数の条件に応じて処理を分岐させるための命令です。与えられた変数の値に応じて、異なる処理を実行します。CASE文には、条件にマッチするパターンごとに処理を指定できます。

## FOR文

```st
FOR D10 := 1 TO 10 BY 2 DO 
    D20 := D20 + 1;
END_FOR;
```

FOR文は、指定された回数だけ繰り返し処理を行うための命令です。指定された変数を初期値から終了値まで、指定されたステップで増減させながら、繰り返し処理を行います。

## WHILE文

```st
WHILE D10 <= 50 DO
    D10 := D10 + 5;
END_WHILE;
```

WHILE文は、指定された条件が満たされる間、繰り返し処理を行うための命令です。条件が満たされなくなると、処理を終了します。

## REPEAT文

```st
D10 := 50;
REPEAT
    D10 := D10 / 2;
UNTIL D50 < 0;
END_REPEAT;
```

REPEAT文は、条件が満たされるまで、繰り返し処理を行うための命令です。条件が満たされた場合、処理を終了します。

## EXIT文

```st
(* FOR, WHILE などのループ処理開始 *)

    (* ループ内での強制終了 *)
    IF X1 := TRUE THEN
        EXIT;
    END_IF;
    
(* END_ ループ処理の終端 *)
```

ループ内での強制終了を行うための命令です。特定の条件が満たされた場合に、ループから脱出します。

## RETURN文

```st
(* プログラムの終了。ファンクションブロックの場合は呼び出した処理に戻る *)
RETURN;
```

プログラムの終了を行うための命令です。プログラムの実行を終了し、ファンクションブロックの場合は呼び出し元に戻ります。

## さいごに

このように、各命令の構文と使用方法を理解して、効果的にプログラミングに活用しましょう。

総括すると、GX Works 2で使える命令とST言語の規格上定められている命令文との主な差は、プラットフォーム依存性、機能の制約、開発環境の違いにあります。開発者は、プロジェクトの要件や目標に応じて、適切なプログラミング言語や開発ツールを選択する必要があります。
フロントのクエリパラメータを検知し、APIのクエリパラメータに設定する

## はじめに
普段はReactで実装しています。ReactとAPIのget通信時、クエリパラメータを設定するのですが、量が増えてくると何かと大変です。特にAPIのクエリパラメータの設定箇所が大変でした。

表題通り、フロントのクエリパラメータを検知してAPIのクエリパラメータに設定する方法を記載します。

## 成果物
![api.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/2d6791d9-8f2b-6e08-bab5-8ff7825a1dbf.gif)

:::note info
検索バーを変更する事でフロントのクエリパラメータを変更。
その後、APIのクエリパラーメターを変更し接続しています。
:::


## ソースコード
```shell:ディレクトリ構成
├── src
│   ├── App.tsx
│   ├── components
│   │   ├── Content.tsx
│   │   ├── Header.tsx
│   │   ├── api.ts
│   │   ├── hooks.tsx
│   │   └── index.tsx
│   ├── index.css
│   ├── index.tsx
│   ├── logo.svg
│   ├── react-app-env.d.ts
│   ├── reportWebVitals.ts
│   └── setupTests.ts
```

```tsx:App.tsx
import React from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
import { Sample } from './components';

function App() {
  return (
    <Router>
      <Sample />
    </Router>
  );
}

export default App;
```

```tsx:src/components/index.tsx
import { Content } from './Content';
import { SearchBar } from './Header';
import { useSearchQuery } from './hooks';

export const Sample = () => {
  const { data, error } = useSearchQuery();
  if (!data) return <div>loading...</div>;
  if (error) return <div>{error}</div>;

  return (
    <div style={{ margin: '16px' }}>
      <SearchBar />
      <Content data={data} />
    </div>
  );
};
```

```tsx:src/components/Header.tsx
import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import TextField from '@mui/material/TextField';

export const SearchBar = () => {
  const [query, setQuery] = useState('');
  const navigate = useNavigate();

  useEffect(() => {
    // ユーザーの入力があるたびにURLのクエリパラメータを更新
    const params = new URLSearchParams();
    if (query) {
      params.append('id', query);
    } else {
      params.delete('id');
    }
    navigate(`?${params.toString()}`, { replace: true });
  }, [query, navigate]);

  return (
    <TextField
      label="検索"
      value={query}
      onChange={(e) => setQuery(e.target.value)}
    />
  );
};
```

```tsx:src/components/Content.tsx
import React from 'react';
import { Result } from './hooks';
type Props = {
  data: Result[];
};

export const Content = (data: Props) => {
  return (
    <div>
      {data.data?.map((item) => (
        <div key={item.id}>
          <p>{item.name}</p>
          <p>{item.email}</p>
          <p>{item.body}</p>
        </div>
      ))}
    </div>
  );
};

```
未経験者のpython学習1日目

# この記事の目的
インプットした知識や情報を文字に起こすことで記憶に定着させる。自分が学習したこと、知らなかったこと、疑問に思ったことをアウトプットすることでエンジニアとして成長することを目的とする。
## 本日学んだこと
Python自体学んだことがなかったため、まずは簡単にPythonの全体理解をすることから始めた。
以下に本日学んだことを記載する。
・pythonとは数値計算からWebアプリ開発、AI開発など幅広い用途で使えるプログラミング言語である。
・GoogleやInstagramをはじめとして幅広い企業で利用されている
・Pythonは人が書いたプログラムを機械語に翻訳して実行する「インタプリタ言語」である。ほかの言語の場合人間が書いたコードを機械が認識できる形式に変換する「コンパイル」という作業が必要になる。一方Pythonはコンピューターがプログラムを読み込みながら即座に実行するため、コンパイルが不要である。そのため、不具合があればその場ですぐに確認できる。
### Progateで実践
print
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689477/96350438-4130-8418-6415-bdd5efaabafa.png)
画面に文字列や数値を表示するのに用いる

str、int
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689477/ccf7cf75-bc7e-29b8-6cbe-1038720d1eb6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689477/a2089323-c24f-c48e-18de-4f7145d9cfc9.png)
str:数値型を文字列型に変換する
int:文字列型を数値型に変換する

if
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689477/e3d8ac9e-4ec2-ee33-2a0b-1e598ed5fc6c.png)
if文を用いると「もし〇〇ならば、××を行う」といった条件分岐が可能となる