OmniAICreator/Qiita-1.07M huggingface dataset:
鍵認証でログインする(ssh-keygen, ssh, chown, chmod)

秘密鍵と公開鍵の鍵ペアを作って、認証を行う方法。

ローカル環境で`ssh-keygen`を実行する。
```
$ ssh-keygen
```

`ssh-keygen`を実行すると、次の項目を設定することになる。

- 鍵の保存先。特に何も指定しなければ`/home/username/.ssh/id_rsa`に保存される。
- パスフレーズ

パスフレーズとは、万が一秘密鍵が漏洩した場合などに備えて、秘密鍵に設定するパスワードである。

鍵の保存先とパスフレーズを決めると、鍵の保存先として指定したディレクトリに秘密鍵(`id_rsa`)と公開鍵(`id_rsa.pub`)が生成されている。


ここで生成した公開鍵(id_rsa.pub)を認証を通したいサーバに公開鍵を配置する。認証を通したいサーバに公開鍵を配置するには、認証を通したいサーバの管理者等に問い合わせて配置してもらうといった必要がある。

公開鍵を配置するサーバの管理者は、公開鍵を認証を通したいユーザーのホームディレクトリ化の`.ssh`ディレクトリに受け取った公開鍵を`authorized_keys`という名前で保存すると、公開鍵として設定できる。

公開鍵を配置したら、サーバの管理者は`.ssh`ディレクトリの所有権の変更(`chown`)とパーミッションの変更(`chmod`)を行う。
```
$ sudo chown -R username:username ~username/.ssh
$ sudo chmod 700 ~username/.ssh
$ sudo chmod 600 ~username/.ssh/authorized_keys
```


サーバに公開鍵を配置してもらったユーザーは、`ssh`コマンドを実行して、`ssh-keygen`を実行した時に設定したパスフレーズを入力すると、認証を通したいサーバへログインできる。

例えば、`username`というユーザー名で、接続先サーバーのIPアドレスが`192.168.11.14`のときは、
```
$ ssh username@192.168.11.14
```

とすればよい。
`ssh`を実行すると、パスワードの入力を求められるので、設定したパスフレーズを入力するとログインできる。


# 定期処理でscpを使いたいとき
パスフレーズを指定せずに秘密鍵を生成すると、自動的に鍵認証できる。
これを利用して、`cronjob`で登録したジョブに対して、鍵認証を必要とする処理を実行させることができる。

```
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/yourname/.ssh/id_rsa): /home/yourname/.ssh/newkey
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
```

以上は、`ssh-keygen`コマンド実行後、パスフレーズ無しで鍵ペアをそれぞれ`newkey`, `newkey.pub`で生成する場合の例である。
`Enter passphrase`でパスフレーズの入力を求められるが、この時に何も入力せずにEnterを入力すると、パスフレーズ無しで秘密鍵を生成できる。

次に、生成した公開鍵をサーバ上に配置する。配置先のサーバに既に公開鍵が設定されている場合は、以下のように`>>`を利用して、既存の公開鍵に、新しい公開鍵を追加する。

```
$ scp ~/.ssh/newkey.pub username@192.168.11.14:/tmp/
$ ssh username@192.168.11.14
$ cat /tmp/newkey.pub >> ~/.ssh/authorized_keys
```

追加した公開鍵の行の先頭に、公開鍵で実行させたいコマンドを追記する。
```~/.ssh/authorised_keys
command="実行させたいコマンド"
glrjn0239tjeroemgoirjipgj3ngu23tu1-grnov9ahuy5rg
xcvklmwoig40bnboaejrh02tjgfj2t-afogpdfjlasdnlxvl
...
```

実行させたいコマンドで`scp`を実行するしたいときは、ダウンロードする場合とアップロードする場合で、それぞれ`-f`,`-t`オプションを付ける。
```
command="scp -f /var/log/apache2/access.log" (ファイルをダウンロードしたいとき)
command="scp -t /home/username/Documents/doc.txt" (ファイルをアップロードしたいとき)
```

ローカルからコマンドを実行して、サーバ上の公開鍵に登録しておいたコマンドを実行する際は、サーバ上へ追加した公開鍵に対応する秘密鍵のパスを`-i`オプションを使って、指定してあげる必要がある。
指定する方法は、`-i`に続けて秘密鍵のファイル名を指定すればよい。
```
$ scp -i ~/.ssh/newkey username@192.168.11.14:/var/log/apache2/access.log /tmp/local/access.log
```
Ubuntu に npm をインストール

## できた方法
これの真似。
https://stackoverflow.com/questions/33870520/npm-install-cannot-find-module-semver?page=1&tab=scoredesc#tab-top

```bash
sudo rm -rf /usr/local/lib/node_modules
sudo rm -rf ~/.npm
brew uninstall --force node
brew install node
```
=> インストールできた
```bash
$ npm --version
10.7.0
```

## 環境
```bash
$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 22.04.4 LTS
Release:	22.04
Codename:	jammy
```

## 背景
いくつか試してダメだったので、できた方法を記録します。

* 試行1
https://qiita.com/nouernet/items/d6ad4d5f4f08857644de
=> 以下のエラー
```bash
$ npm --version
:
(node:23470) UnhandledPromiseRejectionWarning: Error: Cannot find module 'semver'
```

* 試行2
https://learn.microsoft.com/ja-jp/windows/dev-environment/javascript/nodejs-on-wsl
=> どうなったか忘れたけど、ダメだった。
Windows上のPythonでファイルパスを指定する

# サマリ
今までLinux上でしかPythonを動かしたことがなかったので、Windows上のPythonを動かした時にファイルパスの指定ができなくて、小一時間悩みました。

# 今回困ったこと
例えば、こんな具合でWindowsのファイルパスを指定します。
```
>>> file_path = "C:\Users\hogehoge\fugafuga"
```
そうなるとこんなエラーが出ます。
```
   File "<stdin>", line 1
     file_path = "C:\Users\hogehoge\fugafuga"
                                                        ^
 SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape
```

# なんで？
LinuxやMacでファイルパスを指定する際は`/(スラッシュ)`でディレクトリを区切りますが、Windowsはファイルパスを`\(バックスラッシュ)`区切ってます。
で、このバックスラッシュが悪さをしています。
Python内でのバックスラッシュはエスケープシーケンスの役割を持っています。改行などの通常の文字列では表せない機能を持つ文字になりますので、ファイルパスを指定するのに余計なことをしているんですね。

# raw文字でエスケープシーケンスを無効化
というわけで、バックスラッシュをエスケープシーケンスを無視させて単純な文字列として認識させる必要があります。
書き方は簡単で、ファイルパスの前に`r:`と付け加えるだけ。`raw = 生`の頭文字で`r:`ということになります。
```
 >>> file_path = r"C:\Users\hogehoge\fugafuga"
 >>> print (file_path)
 C:\Users\hogehoge\fugafuga
```

他にも`os`モジュールで`os.path.join()`関数を使用する手法があります。
こちらについてはまた後ほどに。
Gitコマンド | 備忘録

# はじめに
初めまして！
エンジニアになって数年、今まで本を読むだけでしたが、もっとプライベートで楽しみながら成長したい！自分が学んだ足跡を残していきたい！と思い記事を書きました！
最終的には自在に開発できるようになりたいと思っています。:triumph:
いろいろな記事を参考にさせてもらっています。:bow_tone2:

# 今回の目的
Gitのコマンドで使いそうなものを一通り見返せるものを残して振り返りたい。

# 主に参考にさせていただいた記事
gitの仕組みや理解しやすい解説がありお勧めです。

https://www.udemy.com/share/101WYW3@Z5bLnKp8E2x9Cx3N5Ftq3pOvJP3odRloXSuFZF-55-vzqhwfsPpuH7AWvAF17j-T/

# 一覧
#### git init
ローカルリポジトリ(.git)の作成
#### git clone
リモートリポジトリのコピー取り込み
#### git add
ステージング
git add .で全てステージング
#### git commit
①コミット
git commit -m "コメント"
②コミットコメントの修正
git commit --amend

#### git status
コミットまでの変更ステータスの確認（コンフリクトも確認できる）
#### git log
一番上に最新のコミット情報（HEADが現在位置）
#### git remote
①git remote add orign ＜URL＞
紐付けたいリモートリポジトリのURLをorignというショートカット名で登録
②git remote -v
登録しているリモートリポジトリの詳細を表示
③git remote rename <変更前> <変更後>
リモートリポジトリ名の変更
③git remote rm <対象>
リモートリポジトリの削除

#### git push
git push orign masterは、ローカルのmasterブランチからリモートのmasterブランチにpush

#### git checkout
①git checkout <ブランチ名>
存在するブランチに切り替え（HEADの移動）
switchコマンドと同じ

②git checkout -b <ブランチ名>
新しいブランチを作成し切り替える

③git checkout --　<ファイル名>
ハイフン二つでファイルの変更を取り消し。
git checkout -- .は全て取り消す。

#### git reset
ステージングを取り消す
git reset HEADで全て取り消す

#### git pull
fetchとmerge（または--rebaseでrebase)を一括で行う

#### git branch
①git branch
ブランチ一覧
リモートブランチもみたい時は-a
②git branch -m <ブランチ名>
現在のブランチ名の変更
③git branch -d <ブランチ名>
ブランチの削除（強制削除は-D)

#### git rebase
変更内容を取り込みながらコミット履歴を一直線にする（ファストフォワードの形になる）
作業ブランチでgit rebase <取り込みたいブランチ名>
プロダクト開発するWebエンジニア向けの練習問題を作った（EverToDo）

# はじめに

~~~
「今週の金曜日にあるプロジェクトのキックオフ会議の準備をしなきゃ」
~~~
みたいな文章を入力すると、自動的にタスクリストが作られる・・・

そんなイカしたToDoアプリを、SaaSにして自社プロダクトとしてリリースしよう！
という話が立ち上がりました。
Webエンジニアであるあなたは、そんなプロダクトの立ち上げフェーズに召喚されて、最初のMVPを実装することになりました。。。

---

という想定で、Webアプリケーションを開発できるような練習問題を作りました。

簡単なWebアプリケーション（ToDoアプリ）を、要件定義から概要設計まで完了した状態にしています。
FigmaのUI/UXデザインを見ながら、ToDoアプリを実装してください！

---

このToDoアプリは、プロダクト開発に携わるエンジニアにとって有用な練習材料となるように工夫しています。

アプリケーションのテーマはありふれたToDoアプリなのですが、その要件は一般的なプロダクトの開発現場で求められる水準に設定しています。
実際の開発環境での作業を想定したトレーニングができる、というワケです。

トレーニングで実現する要件と機能は絞っているので、開発時間を抑えることができるようになっています。

# コンセプト

:::note
ToDoアプリを爆速で作ってスコアを競おうぜ
:::

* 開発課題として、ToDoアプリを実装します
* 要件や画面一覧・機能一覧と、FigmaのUI/UXデザインがあります
* 実装にかかった時間を記録します
* 実装が完了したら、セルフチェックで獲得点数を計算します
* 獲得点数と時間から、最終スコアを計算します

どれくらい早く実装できるんでしょう？
どれくらい正確に要件を満たす実装ができるんでしょう？

この問題に取り組んだら、スコア化できるんじゃないか？！
何度でもやり直しOK条件で、チャレンジしてみてほしいです！

## 想定する対象者

:::note
Webアプリケーションの開発に携わるソフトウェアエンジニア
:::

特に、プロダクトの開発をしているエンジニアにぴったりの問題にしました。

* Web開発の初学者で、実践的な練習問題を探していた
* ここのところマネジメントとドキュメント作りだったので、ソースコードを書きたい気分
* Web系だったらひととおり実装できるようになったと思うんだけど、腕試ししてみたい
* データベース設計や、画面設計にチャレンジしたいと思っていた
* 新しいフレームワークを習得するために、アプリを作ってみたいと思っていた
* 暇なので刺激のあるネタを探してる

コーディングだけでなく、開発に求められる広範囲のスキルが駆使できるように作ってます。
「それなりに実装できるようになった」と自負している人ほど、取り組んでほしいです！

## 目的は何？

私が代表を務めるタビアン株式会社では、スタートアップや事業会社の新規事業の0→1する場面に、エンジニアのチームで参画し、プロダクト開発に携わる仕事をしています。
エンジニアのチームの開発生産性と開発速度を向上できるようなトレーニングがほしいと思い、練習問題を作ることにしました。

実装する速度、要件を実現する精度、コーディングに着手する前に考える習慣が、開発に大切なのではと思っています。

## 得られることは？

* どの要件・機能を実現するのか？ということを、実装速度を意識しながら開発することができる
* リアルなプロダクト開発の要件に使いので、どうやって技術課題に向き合ったら良いのか考えることができる
* 自分のエンジニアリングのスキルが、どこまでカバーしていて、欠けている要素があるのかを認識することができる

# どんなアプリケーション？

画面が3つしかない、ほんとうにシンプルなWebアプリケーションです。

### 【ログイン画面／新規登録画面】

ログインするのも、新規登録するのも、Googleログインだけです。

![P10-02_ Opening.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84173/d733f854-047e-ca07-04ce-01d9eb51424b.png)

### 【タスク一覧画面】

タスクの説明を入力すると、サブタスクを自動で作ってほしい、という要件です。
入力用のテキストフィールドがあるだけのシンプル画面です。

![P20-04_ Task List (Full list).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84173/a2a741e4-015d-8090-6c51-3f27f8e1f7d6.png)

### 【タスク詳細画面】

ユニークなURLが発行されるので、詳細画面に直接アクセスすることを想定しています。

![P30-02_ Task Details.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84173/94e53ccd-7c5c-f0d6-3f51-c9023dde268e.png)

# クイックスタート

↓ ↓ ↓ 説明資料はこちら ↓ ↓ ↓

https://docs.google.com/spreadsheets/d/1bgMGFYI1nQ4FQLZaHOy7-neVzuGwkuUSt1zwx22WPSs/edit?usp=sharing

1. 自分用に説明資料のコピーを作る
2. 書いてある内容やFigmaファイルを読み込む
3. よく考える
4. 実装する
5. スコアを計算する

# 次のステップ

獲得したスコアをぜひコメントで教えてほしいです！
【CSS】ボタンの外側に半透明のoutlineをつける

## 背景

ボタンの外側に半透明のoutline（外枠）をつける方法がわからなかったため、備忘録的に記載する。


## 実装結果

![スクリーンショット 2024-05-08 22.37.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692485/c4786dca-5821-9bbb-f7d7-f91decc872ec.png)


## 実装

```html:html
<div class="btn-outside">
  <button class="btn">
    ボタン
  </button>
</div>
```


```css:css
.btn-outside {
  padding: 4px;
  background-color: rgba(243, 240, 242, 0.1); // 半透明に指定
  width: 352px;
  height: 64px;
  border-radius: 32px;
}

.btn {
  width: 100%;
  height: 100%;
  padding: 16px;
  font-size: 16px;
  background-color: #efefef;
  border-radius: 28px;
}
```

`btn-outside`　側にwidthとheightを指定し、`btn` 側はwidthを100%、heightを100%で指定する。
border-radiusは相対角丸で算出する。
https://coliss.com/articles/build-websites/operation/css/inner-radius-design-tip-with-css.html
C# コンソールアプリでユーザーシークレットを使用する RTA

# やりたいこと

- コンソールアプリでも接続文字列などをリポジトリに混入させない
    - Visual Studio のユーザーシークレットを使う

https://learn.microsoft.com/ja-jp/aspnet/core/security/app-secrets?view=aspnetcore-8.0&tabs=windows

# 環境

- Visual Studio Community 2022 Version 17.9.6
- .NET 8

# 手順

## コンソールアプリを追加

いつも通りです。

## ユーザーシークレットを有効化

1. プロジェクトを右クリック → ユーザー シークレットの管理
     ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/6fc701bf-73fc-df31-de62-23dbe4058892.png)
1. パッケージを追加（はい） 
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/86d002e5-83f8-55f7-4ff7-5ad2e2bed168.png)
1. `secrets.json` が追加されます
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/6d32d569-a008-4026-3a08-02139d8e34d4.png)
1. 適当に設定

```json:secrets.json
{
  "Secrets": {
    "Message": "This is a secret message."
  }
}
```

## Program.cs で読み込む

### IConfiguration を Build()

```diff_c_sharp:Program.cs
-// See https://aka.ms/new-console-template for more information
+using Microsoft.Extensions.Configuration;

Console.WriteLine("Hello, World!");

+IConfiguration configuration = new ConfigurationBuilder().AddUserSecrets<Program>().Build();
```

### 先ほど作ったユーザーシークレットを読み込む

```diff_c_sharp:Program.cs
using Microsoft.Extensions.Configuration;

Console.WriteLine("Hello, World!");

IConfiguration configuration = new ConfigurationBuilder().AddUserSecrets<Program>().Build();
+string message = configuration.GetSection("Secrets:Message").Value ?? "Failed";
+Console.WriteLine(message);
+
+Console.ReadLine();
```

:::note
セクションの指定は JSON のキーをコロンでつなげた文字列で行います。
:::

### 動作確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/3dc869b5-235a-76f3-c377-384ccdf58780.png)

読み込むことができました！

## README に書いておく

新たにプルした人がビルドできなくなってしまうので、README にでも書いておいてあげましょう。

~~~markdown:README.md
# HigeDaruma.DemoConsoleSecret

## 準備

secrets.json に以下を設定してください。

```json
{
  "Secrets": {
    "Message": "{適切に設定してください}"
  }
}
```
~~~

# まとめ

ユーザーシークレットをコンソールアプリで読み出すことができました。`secrets.json` に書いたシークレットはロカールのみに残り、リポジトリにはプッシュされません。安心して秘密を書き込みましょう。
Dify on WSL2の起動時にpostgresがエラーを出力する

以下の環境で実行中にエラーがでて、Perplexityでだいぶ調べて解決したのでメモを残しておきます

環境
Windows10, WSL2, Ubuntu 22.4

[リポジトリ](https://github.com/langgenius/dify)から落としてきて、WSL2のUbuntuを起動して、dockerディレクトリにcdし、以下のコマンドをたたく
```
sudo docker compose up -d
```

Difyにアクセスできないので起動状況を見る
```
sudo docker ps
```

postgresが起動していないのでインスタンスのログを見る
```
sudo docker logs <container id>
```


以下のエラーが発生していることがわかる

```
Data page checksums are disabled.
initdb: error: could not change permissions of directory "/var/lib/postgresql/data/pgdata": Operation not permitted
fixing permissions on existing directory /var/lib/postgresql/data/pgdata ... chmod: /var/lib/postgresql/data/pgdata: Operation not permitted
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.
```

解決方法
もちろん、権限回りなど調べてわかることはいろいろやったが、権限では治らなかった。chmodは15回はやった。

最初のファイル
``` docker-compose.yaml
  # The postgres database.
  db:
    image: postgres:15-alpine
    restart: always
    environment:
      PGUSER: xxxx
      # The password for the default postgres user.
      POSTGRES_PASSWORD: xxxxx
      # The name of the default postgres database.
      POSTGRES_DB: dify
      # postgres data directory
      PGDATA: /var/lib/postgresql/data/pgdata
    volumes:
      - ./volumes/db/data:/var/lib/postgresql/data:z
    # uncomment to expose db(postgresql) port to host
    # ports:
    #   - "9999:9999"
    healthcheck:
      test: [ "CMD", "pg_isready" ]
      interval: 1s
      timeout: 3s
      retries: 30
```

修正後
``` new_docker-compose.yaml
  # The postgres database.
  db:
    image: postgres:15-alpine
    restart: always
    environment:
      PGUSER: xxxx
      # The password for the default postgres user.
      POSTGRES_PASSWORD: xxxx
      # The name of the default postgres database.
      POSTGRES_DB: dify
      # postgres data directory
      PGDATA: /var/lib/postgresql/data/pgdata
    volumes:
      - db_data:/var/lib/postgresql/data
    # uncomment to expose db(postgresql) port to host
    # ports:
    #   - "9999:9999"
    healthcheck:
      test: [ "CMD", "pg_isready" ]
      interval: 1s
      timeout: 3s
      retries: 30
# Add volume name
volumes:
  db_data:
```

要は以下を修正し、
```
volumes:
  - db_data:/var/lib/postgresql/data
```
以下を追加した。
```
# Add volume name
volumes:
  db_data:
```
これにて起動完了


なお、こういうのもある。私のPerplexity調査では引っかからなかった。素晴らしい
https://qiita.com/noppe78/items/40cff5859cec4e6eb526
【ザックリ概要】ActiveRecordの基礎

※解釈が入り混じっているので不備などがあるかもしれません。予めご了承ください。
※ザックリと理解するというスタンスなのでまとめ方が不十分かもしれません
***
引用元・参考サイト
[Railsガイド](https://railsguides.jp/active_record_basics.html)
***
# 概要
- `Active Record`はMVCのMを相当する『オブジェクト指向 × DB操作』を可能にした仕組み
データ操作をオブジェクトを介して実現可能にしている
    - ORMというシステム設計パターンを採用しており、ORMではDBの種類ごとのSQLの記述の違いを吸収してくれるなど"互換性が高い"のが大きな特徴
- `Active Record`は次のような特徴を持つ
    - 先述したSQLでのDB操作をオブジェクトを介して実行可能な点に加えて、『RDBのような"テーブル同士の相関"などよりDB寄りなデータの意味までもオブジェクトで表現できる』
> ・モデルおよびモデル内のデータを表現する[^1]
> ・モデル同士の関連付け（アソシエーション）を表現する[^1]
> ・関連付けられているモデル間の継承階層を表現する[^1]
> ・データをデータベースで永続化する前にバリデーション（検証）を行なう[^1]
> ・データベースをオブジェクト指向スタイルで操作する[^1]
[^1]:https://railsguides.jp/active_record_basics.html#orm%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%A8%E3%81%97%E3%81%A6%E3%81%AEactive-record

:::note info
RailsはORMシステム設計パターンを採用しているから楽にDB操作ができる
:::

# Active RecordにおけるCoC（Convention over Configuration）
- ORMを採用したアプリケーションでは実装にあたって設定などが煩雑になりがち
　⇒ Railsは仕様としてルールが設けられているので、そういった設定が最小限で済ませられる（これがいわゆるRailsの"レール"の一部）
    - このルール外にあたる設定を適用したければ煩雑な設定が必要となる

# 命名規則
### モデル
- 先述の"ルール"として『モデル、DBには適した命名をする』
    - [Rails上のモデル ⇔ DB上のテーブル/スキーマ]の関係をRailsに適切に構築してもらうために重要

:::note warn
モデルの命名規則として【モデルのクラス名は"単数形"にする】
2単語以上の英単語から成る名称はキャメルケースで命名する（英単語の先頭字を大文字にする）
:::

- Rails上でオブジェクトを定義する'Class'としては"単数形"で定義する
一般的にはDB上のテーブル名は"複数形"で扱うので、RailsはDB操作時には内部的に"単数形"を"複数形"に変換してくれる。
    - 例）「rails）"Book"クラスが対応しているテーブルは"book**s**"テーブルだな」→「DB）Rails側が"books"テーブルを参照しにきたわ」
> ・モデルのクラス - 単数形、語頭を大文字にする（例: `BookClub`）
> ・データベースのテーブル - 複数形、語はアンダースコアで区切る（例: `book_clubs`）
> 
> |モデル / クラス|テーブル / スキーマ|
> |---|---|
> |Article|articles|
> |LineItem|line_items|
> |Deer|deers|
> |Mouse|mice|
> |Person|people|


:::note info
RailsはORMシステム設計パターンを採用しているから楽にDB操作ができる
Railsは英単語の複数形化の仕組みが卓越している（らしい）
:::

### カラム名
- "主キー"：デフォルトで`id`という名前のカラムが追加される（integer型）
- "外部キー"：`[テーブル名の単数形]_id`という命名にする必要がある
    - 例）`books`テーブルであれば単数形は`book`なので`_id`を追加して ⇒ `book_id`

# モデル作成
- 先述の命名規則でクラスを作成すればOK
    - `ApplicationRecord`という親クラスを継承するクラスとして作成する
```
class Product < ApplicationRecord
end
```
※肝心の中身を記述していないように見えるが、これで内部的にはこのクラスとDBのテーブルとの連携が可能になっている
（この場合は"Product"クラスと"products"テーブルとの連携）

# 命名ルールの上書き
- どうしてもRailsの命名ルールに従えない場合は一手間必要となる
    - デフォルトの命名ルールをオーバーライドすることで既存のルールから外れた実装が可能
> ApplicationRecordは、有用なメソッドが多数定義されているActiveRecord::Baseを継承し
> ているので、使うべきテーブル名をActiveRecord::Base.table_name=メソッドで明示的に指定
> できます。
> ```
> class Product < ApplicationRecord
>   self.table_name = "my_products"
> end
> ```

# CRUD
- DB操作を表す「Create」「Read」「Update」「Delete」のイニシャルを取った言葉
    - 「基本的なDB操作がオブジェクト介してできるよ！！」という理解でOK

# バリデーション
- DBにデータを追加する際にそのデータが想定外な値では困るので「登録内容を事前に検証して場合によっては弾こう」というのが`バリデーション`
    - `save`（データの新規登録）、`update`（データの更新）に際にバリデーションが作用する
AWS Cloud9(Django)+S3+SQS+Lambda+SNS環境構築_目次

こんにちは。
株式会社クラスアクト インフラストラクチャ事業部の大塚です。

この記事は自分が連載(?)している『AWS Cloud9(Django)+S3+SQS+Lambda+SNS環境を作ってS3にアップロードされた時、メール通知をする』という記事をまとめた記事となります。

# 構築する環境

以下の環境を右から順番に連携させていきます。

![aws-django01-ページ6.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/426843a2-5d28-7283-96dc-22fb1cbe3e34.png)

最終的にCloud9に構築した以下のWebアプリからS3にデータをアップロードすることを可能にし、その際に自動でメール通知が飛んでくるような環境を作っていきます。

![2024050811.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/42fe1f99-36d0-a303-c47c-0950eb817246.png)

![2024050812.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/d3ae52ab-5fd1-d68c-cbbf-0401191e93e4.png)

![2024050813.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/5a163d4d-14c0-5962-8a91-75d5aef56368.png)

# 目次
## 1)AWS Lambda/SNSを連携し、メール通知を行ってみる

https://qiita.com/ohtsuka-shota/items/e2b62e5ab61a90807264

## 2)AWS Lambda/SNSにSQSを連携し、メール通知を行ってみる

https://qiita.com/ohtsuka-shota/items/4daaf14c03705ee0ad05

## 3)AWS SQS/Lambda/SNSにS3を連携し、メール通知を行ってみる

https://qiita.com/ohtsuka-shota/items/59821498db47ecbeed7d

## 4)AWS S3/SQS/Lambda/SNSにCloud9を連携し、メール通知を行ってみる

https://qiita.com/ohtsuka-shota/items/32435454b9135bb3be2f

DjangoのProjectについては以下のGutHubに登録済みです。

https://github.com/ohtsuka-shota/cloud9-sqs-lambda-sns/tree/main

## 拡張1)Cloud9で作成したDjangoをコンテナイメージ化してECRにpushする

https://qiita.com/ohtsuka-shota/items/670d457e30b25ad4dcc0

## 拡張2)ECRからイメージをpullしてFargateにコンテナデプロイ

https://qiita.com/ohtsuka-shota/items/414f140251b3af12a779
Expressの起動方法(npm run <script名>ってなに？)

## npm run serve?

業務でモックサーバーのデータをもらい`README`を見ていると
見慣れないコマンドを発見。
```
起動方法: npm run serve
```

そのままコマンドをGoogle先生に聞いても`npm`コマンドに`run`はあるが
`serve`を指定しているものは見つからなかったので調べてみました。
※業務で見たモックサーバーはnodemonを利用していたため
 今回の記事と少し状況が違いますが伝えたいことはnpm runの動作です

 ## 結論: package.jsonのscriptsに設定されたコマンドを実行している

 説明のために以下の記事で作成したExpressサーバーを利用します。
 [ExpressでWebサーバーを立ててみる](https://qiita.com/moody_engineer/items/f5773380ffc964cf10f3)

 記事でも書いてますがExpressを起動するために以下のコマンドを実行すると記載し、実際に起動します。
 ```
 node app.js
 ```

 なら`npm run serve`でなんで起動するの??

 ### npm run <script名>
 `npm run serve`の実際の文法的な表現は`npm run <script名>`になります。
 script名ってなに？と調べてみると
 `package.json`内にある`scripts`内で宣言されているプロパティ名になります。

 そのため、今回のように`npm run serve`でExpressを起動する場合は
 `package.jsonに以下のように設定します。
 ```json
 "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "serve": "node app.js"
  }
 ```

 この状態で`npm run serve`を実行すると
 `package.json`の`scripts`の`serve`に設定されている`node app.js`コマンドが実行され
  `app.js`に記載したExpressが起動します。

  今回のような場合だとわざわざ`npm run <script名>`を使わずに`node app.js`でよくない？となると思いますが、
  `nodemon`などを用いる場合はそうはいかないため、それはまた別記事にします。
rex0220 ちょっと便利なプラグイン 詳細画面で表示幅調整

[ちょっと便利なプラグイン](https://qiita.com/rex0220/items/45883f15ccd34a68b8af)で、詳細画面で表示幅調整する機能をご紹介します。
kintone の少し使いにくいところをちょっとだけ便利にするプラグインです。

# 概要

詳細画面で項目の表示幅調整を行います。
不要な空白部分を無くします。また長い文字列の折り返しを行いません。

- F58 詳細画面で文字列の表示幅調整
- F59 詳細画面で文字列複数行の表示幅調整
- F60 詳細画面で数値の表示幅調整
- F61 詳細画面で計算の表示幅調整
- F62 詳細画面でリンクの表示幅調整
- F63 詳細画面でラジオボタンの表示幅調整
- F64 詳細画面でチェックボックスの表示幅調整
- F65 詳細画面で複数選択の表示幅調整
- F66 詳細画面でドロップダウンの表示幅調整
- F67 詳細画面でユーザー選択の表示幅調整
- F68 詳細画面で組織選択の表示幅調整
- F69 詳細画面でグループ選択の表示幅調整
- F70 詳細画面でテーブルの表示幅調整
- F71 詳細画面でテーブル内項目の自動折り返しをしない

![2024-05-08_22h07_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/92391dd4-7430-c549-2fb3-bf85151c9c38.png)

# ちょっと便利なプラグイン設定

項目タイプ別に表示幅調整をチェックします。

![2024-05-08_22h18_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/227cc0bd-6dfd-a169-9d70-438b5bf40f29.png)
複数のCSVファイルに対して、同一アイテムの数値を加算する

```python

import argparse
import csv
import os


def main() -> None:

    parser = argparse.ArgumentParser()
    parser.add_argument("-i", "--input_dir_path", default="./")
    parser.add_argument("-o", "--output_file_path", default="./output.csv")
    args = parser.parse_args()

    input_dir_path = args.input_dir_path
    output_file_path = args.output_file_path

    csv_files = [file for file in os.listdir(input_dir_path) if file.endswith(".csv")]
    margede_data = {}

    # csvの読み込み
    for csv_file in csv_files:
        with open(csv_file, "r", encoding="utf-8") as read_file:
            reader = csv.reader(read_file, delimiter=",")

            for data in reader:
                if data[0] in margede_data:
                    margede_data[data[0]] += int(data[1])
                else:
                    margede_data[data[0]] = int(data[1])

    # マージ後データのcsv出力
    with open(output_file_path, "w", encoding="utf-8", newline="") as write_file:
        writer = csv.writer(write_file, delimiter=",")

        for jancode, sales_volume in margede_data.items():
            writer.writerow([jancode, sales_volume])


if __name__ == "__main__":
    main()
```
Pythonの例外ハンドリング

## Pythonの例外ハンドリングについて学習
Javaと同じ点や異なる点を整理しながらPythonの例外ハンドリングについて学習する。

## try節
Javaと同じで、例外が発生する可能性のある箇所で使う。exceptかfinallyのどちらかは必須。

## except節
Javaのcatchと同じで例外を捕まえることができる。
asで一時変数を定義することができる。

## else節
すべてのexcept節よりも後ろにelse節を置くことができ、例外が発生していない場合の処理を記載することができる。

:::note info
どのような使い方をすれば効果的なのかを調べる。
:::

## finally節
Javaと同じで、例外の発生有無にかかわらず実行される処理を書くところ

## 基底クラスでの例外捕捉
Javaと同じで、except節で基底クラスを指定することで、継承しているクラス例外を捕捉することができる。

## raiseで例外送出
Javaのthrowsと同じようにraiseで例外を送出することができる。

## with文
Javaの[try-with-resources](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html)のように例外が発生しても、リソースをクローズしてくれる。
コンテキストマネジャーと呼ばれる__enter__()と__exit__()の特殊メソッドを実装したクラスのインスタンスを指定することができる。
Javaだと、[AutoCloseable](https://docs.oracle.com/javase/8/docs/api/java/lang/AutoCloseable.html)か[Closeable](https://docs.oracle.com/javase/jp/8/docs/api/java/io/Closeable.html)をimplementしている必要があり、close()だけがinterfaceに指定されている。
そのため、withブロック開始前に処理されるメソッドが必須であるということがJavaとの違い。

~~~py
with open('python.txt') as file:
   print(file.read())
~~~
Unity 6でGameObjectにGetComponentCount、GetComponentAtIndex、GetComponentIndexメソッドが追加された


Unity 6 Previewで、GameObjectクラスに次のメソッドが追加されました。

* [GetComponentCount](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/GameObject.GetComponentCount.html)
* [GetComponentAtIndex](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/GameObject.GetComponentAtIndex.html)
* [GetComponentIndex](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/GameObject.GetComponentIndex.html)

また、Componentクラスに次のメソッドが追加されました。

* [GetComponentIndex](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Component.GetComponentIndex.html)

```csharp
using UnityEngine;

public class Sample : MonoBehaviour
{
    private void Start()
    {
        // 新メソッドのGetComponentCount
        // 対象GameObjectに付与されているComponentの数を取得
        // Transform Componentも数に含まれる点に注意
        var componentCount = gameObject.GetComponentCount();
        
        for (var index = 0; index < componentCount; index++)
        {
            // GetComponentAtIndexで指定indexのComponentを取得できる
            // GetComponentAtIndexには、ジェネリックバージョンもある
            // 公式ドキュメントには「nullも返しえる」ってあるけれど、例外投げる見たいだからnull返す？
            var targetComponent = gameObject.GetComponentAtIndex(index);
            Debug.Log($"targetComponent is {targetComponent.GetType().Name}.");

            // GetComponentIndexで、引数のComponentのindexを取得できる
            // ※ targetComponentIndexはindexと同じはずだから、実質無駄な呼び出し
            var targetComponentIndex = gameObject.GetComponentIndex(targetComponent);
            Debug.Log($"targetComponent index is {targetComponentIndex}.");
        }
        // ※ ↑処理は、新しいメソッドでなくても、GetComponentsを使えば代替できる

        // 次のGetComponentIndexはGameObjectクラスでなく、ComponentクラスのGetComponentIndex
        Debug.Log($"{GetType().Name} index is {GetComponentIndex()}");
    }
}
```

なお、これらのメソッドは最新のLTSであるUnity 2022.3.20にもバックポートされ、追加されているようです。公式ドキュメントであるUnity 2023.3のScript Referenceにも、該当メソッドが追加されています。（パッチバージョンでAPIが追加されていることに注意してください、Unity 2022.3.19では使えませんでした。）

ちなみに、Unity 6 Previewの前テックリリースバージョン相当である、Unity 2023.2には、これらのメソッドは追加されていません。

* [GameObject Scriptreference](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/GameObject.html)
* [Component Scriptreference](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Component.html)
* [Unity 6000.0（Unity 6 Preview）のリリースノート](https://unity.com/releases/editor/whats-new/6000.0.0#release-notes)
* [Unity 2022.3.20のリリースノート](https://unity.com/releases/editor/whats-ne022.3.20w/2022.3.20)
* [[Forum]Question Purpose of Component.GetComponentIndex()?](https://forum.unity.com/threads/purpose-of-component-getcomponentindex.1538686/)
ExpressでWebサーバーを立ててみる

## Express

Node.jsのためのWebアプリケーションフレームになり
簡単にWebサーバーを作成できるので作っていく。
※外部APIを呼び出すことができないがAPI仕様書がある場合に
 モックサーバーを作ってテストを行ったりしました。

今回はDockerを用いず自分のパソコンにWebサーバーを作成します。

### 実装してみる

Node.jsでプロジェクトを始める方法は下記ページを見てください。
[Node.jsを私用パソコンで始めてみる](https://qiita.com/moody_engineer/items/715a0783c3d9ae1caf06)

今回作成するフォルダ構成は以下になります。
 ```
 - src
    |- app.js
    |- package.json
    |- package-lock.json
    |- node_modules
 ```

※もしNode.jsを私用パソコンで始めてみる、で`test`ディレクトリを作り、
 `npm init -y`を実行していただいた場合は、`test`ディレクトリ直下に`src`ディレクトリを作成し
 `package.json`を`src`に移動してください

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

 Expressをインストールするためにコマンドプロンプト or ターミナルを開き、
 srcフォルダまで移動してください。
 カレントディレクトリが`src`になっている状態で以下のコマンドを実行してください。
 ```
 npm install express
 ```

 package.jsonに以下の表示ができ、`node_modules`ディレクトリが作成されます。
 ```json
 "dependencies": {
    "express": "^4.19.2"
  }
 ```

### サーバーを作成
 `src`フォルダ内で`app.js`ファイルを作成してください。
 `app.js`ファイルに以下のコードを記載してください。
 ※各行で何を行っているかはコードのコメントを確認してください。

 ```JavaScript
 // Expressモジュールを読み込む
 const express = require('express');
 // Expressインスタンスを生成する
 const app = express();
 // ポート番号を変数に宣言しておく
 const PORT = 8000;

 // GET でhttp://localhost:8000がリクエストされたら実行される処理
 app.get('/', (req, res) => {
   console.log('app.get(/)が実行されました');
   res.status(200).send('Hello, Express get method');
 });

 // POST でhttp://localhost:8000がリクエストされたら実行される処理
 app.post('/', (req, res) => {
   console.log('app.post(/)が実行されました');
   res.status(200).send('Hello, Express post method');
 });

 // 指定されたポートでサーバーを起動
 app.listen(PORT, () => console.log(`listen on port... ${PORT}`));
```

### サーバーを起動する
 コマンドプロンプト or ターミナルで`src`フォルダへ移動し下記コマンドを実行してください。
 ```
 node app.js
 ```
 その後に以下のような出力があるとサーバーが起動しております。
 ```
 listen on port... 8000
 ```

### 動作確認
 サーバーを起動で利用したコマンドプロンプト or ターミナルとは別で新しいウィンドウを開いてください。
 新しく開いたウィンドウで以下のコマンドを実行してください。
 ```
 curl http://localhost:8000
 ```
 下記レスポンスが返ってきます。
 ```
 Hello, Express get method
 ```
 また、サーバーを立ち上げるときに利用したウィンドウでは以下が出力されます。
 ```
 app.get(/)が実行されました
 ```

 POSTメソッドを確認する場合は以下のコマンドを実行してください。
 ```
 curl -X POST http://localhost:8000
 ```
 下記レスポンスが返ってきます。
 ```
 Hello, Express post method
 ```
 また、サーバーを立ち上げるときに利用したウィンドウでは以下が出力されます。
 ```
 app.post(/)が実行されました
 ```

 簡易的なWebサーバーの作成が出来ました。
 これから少しずつ改良していきます。
好きなことをデータ解析するのがさいつよ #1

# はじめに
好きなジャンル(やきう)に関してであれば楽しんでいる内に分析能力上がるのがさいつよでは？という激甘マインドで解析を進めていきます。
100日後くらいに、自分に何が残るのか。楽しみですね！
# 想定読者
- 物好き
# 自分のレベル
- Python初心者
- 機械学習なにそれおいしいの？

# 方針
- 思い付きによる試行錯誤は「悪」。筋道を立てて仮説を検証する
- 理解は時間がかかる作業として、急がず、徹底的に腰を据える習慣をつける
- あやふやな理解のままGoogleサーチや生成AIのコードをコピペして使わない

# 入力データ
- 2012年から2023年のセイバーメトリクス系データ

# 出力想定(例)
2023年の両リーグの盗塁数ランキング
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355686/853e8f30-7935-5176-8c3f-35bfb6c51e87.png)

オレンジが盗塁企画数、青が成功数。
現状はこんなもんしかまだ出せていませんが、いずれは盗塁成功率や盗塁企画数を説明変数として、勝利との相関性、後続打者の出塁率への影響など見てみたいものはいっぱいありますね・・・

皆さんも考えているだけでよだれが垂れますよね？( º﹃º｀)ｼﾞｭﾙ

# さいごに
最初のうちは見慣れたデータのオンパレードだと思いますが、
#100くらいでは面白そうなものが出せれば良いなと思います。
もしかしたら、途中でNoteとかZennに移行するかもしれません。
cursorでclaude3 opus,gpt4oが普通に使える

cursorでclaude3 opusが普通に使えることに今更ながら気が付きました。

APIの設定などはしていないので、
特に追加料金などなしで使えるみたいです（多分）

cursorの右上の歯車マークの設定から以下の画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3048274/8a83bd42-41f8-ed8a-ed73-c1fa24eccbdb.png)
（バージョンが低い場合は出ませんでした。必要に応じてバージョンアップしてください

cursorはopenaiしか対応していないと勝手に思っていました…

回答の精度もかなり高く感じます。

（※ claude 3 opusは１日10回の制限がありました。2024-05-18）

また、gpt4oも同じように設定すれば使えました。
（設定は以下の画像を参照してください。gpt-4oと打ち込めば登録できます。その後「あなたはなんというモデルですか？」と問い合わせてください）
しかし、gpt4oに関しては、cursorとUIの相性がまだ良くなくて、あまり使いこなせませんでした（コードスニペットと説明のUIの表示が逆になる…）
今後も変更があれば記載していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3048274/424ba8fd-9f53-2aff-ccb6-fc4574fa46f6.png)
Unity package nameからPackage情報を取得する方法

UnityのEditor C# スクリプトでパッケージ情報をパッケージネームから取得する方法。
Unity Package Managerでインストールされたパッケージ情報を取得します。

`PackageInfoManager.cs`
```cs
using System.Linq;
using UnityEngine;
using UnityEditor;
using UnityEditor.PackageManager;

public static class PackageInfoManager
{
    [MenuItem("TEST / Package Info Test")]
    public static void PackageInfoTest()
    {
        var PackageInfomation = GetPackageInfo("com.unity.inputsystem");
        Debug.Log(PackageInfomation.displayName);
        Debug.Log(PackageInfomation.version);
        Debug.Log(PackageInfomation.name);
        Debug.Log(PackageInfomation.packageId);
        Debug.Log(PackageInfomation.source);
        Debug.Log(PackageInfomation.resolvedPath);
    }

    /// <summary>
    /// Get package information by package name
    /// </summary>
    public static UnityEditor.PackageManager.PackageInfo GetPackageInfo(string packageName)
    {
        var request = Client.List(true, true);
        while (!request.IsCompleted) { }
        if (request.Status == StatusCode.Success) { return request.Result.FirstOrDefault(pkg => pkg.name == packageName); }
        return null;
    }
}

```
Qiitaで技術ブログを始めました！

## Qiitaで技術ブログを始めました！
#### はじめに
初めまして！今日からQiitaで技術ブログを始めることにしました。プログラミングやIT技術に関して学んだことを共有し、自分の知識を整理するとともに、他のエンジニアと交流を深めていきたいと思います。

----
### 目次
- [自己紹介](#自己紹介)
- [Qiitaを始めた理由](#Qiitaを始めた理由)
- [投稿予定のコンテンツ](#投稿予定のコンテンツ)
- [投稿頻度](#投稿頻度)
----
#### 自己紹介
##### 経歴
- 地方国立大学の機械学科に在学中
- 25卒でHRtech企業に新卒入社予定

##### 趣味
- ウォーキング
- 読書
- コインゲーム
- 競馬

##### エンジニアとしての経歴
- Rubyを3か月ほど
- GO言語の基礎を学び中(Tour of go参照)
- 基本情報を勉強中(2024/5/18に受験予定)
----
#### Qiitaを始めた理由
以下の理由からQiitaで技術ブログを始めようと決意しました。
1. 自分の知識を整理し、アウトプットすることで、学んだことを定着させる
1. 他のエンジニアの方々と知識を共有し、交流を深める
1. 同期に技術力で太刀打ちも出来ない状況が悔しいため、技術力を向上させたいから
----
#### 投稿予定のコンテンツ
主に以下のようなトピックについて、記事を投稿していく予定です。
- GO言語の基本と応用
- Web開発のフレームワークの使い方や事例紹介
- 継続的に学ぶ上でためになったこと(ライフハックなど)
----
#### 投稿頻度
週1を目安に投稿します。

----
これからゆるりと投稿をしていきますので、どうぞよろしくお願いいたします！
また、私の記事で技術的な誤りなどがありましたら教えていただけると幸いです:relieved:
作業環境構築-Windows標準機能編

# はじめに
現場では色々と制限されていることもあると思いますが、その中でカスタマイズをできる限りしています。一部インストール必要なものもありますが、どの現場でもインストールされているので載せてます。



# IME単語登録
ツール→テキストファイルからの登録→下記ファイルをインポート

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3621123/c9e94339-9159-ec81-7ec9-7d60be18159f.png)

```output1.txt
ｃ	（）	短縮よみ
ｄ	デスクトップのパス	短縮よみ
う	↑	短縮よみ
ｈ	←	短縮よみ
ｊ	…	短縮よみ
ｋ	「」	短縮よみ
ｍ	→	短縮よみ
ｓ	↓	短縮よみ
ｔ	・	短縮よみ
よ	よろしくお願い致します。	短縮よみ
ｌ	【】	短縮よみ
ｑ	シート「」	短縮よみ
```
# エクスプローラー
よく使うファイルは「お気に入りに追加」をすると、エクスプローラー起動してすぐにアクセスできるようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3621123/5a1a6067-81d9-4718-a1e6-019fdef51e1e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3621123/56e290b1-2e0d-4c02-9fb5-1c361bb2f2f5.png)


# スタート
よく使うフォルダは「スタートにピン留めする」をすると、winキーを押してすぐにアクセスできるようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3621123/9fbca64d-8db3-4bbe-b0e8-9ffb998935d3.png)


# エクセルのクイックアクセスツールバー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3621123/30848266-f5b3-0161-d4c2-08476ec30a90.png)




# デスクトップ、ロック画面の色
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3621123/af60c697-c0ed-72ec-cfca-8d7918864553.png)


# path
・hostsファイル
C:\Windows\System32\drivers\etc

・スタートアップ（PC起動時にソフトなどを自動で立ち上げられる）
C:\Users\ユーザ名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
【Go言語学習】チャネルとミューテックス

# チャネル
ゴルーチン間でデータを安全にやり取りするための手段。
データの送受信が同期的に行われるため、データ競合を防ぐことができる。
チャネルはゴルーチンの同期にも使用でき、一つのゴルーチンが結果を計算し、その結果を別のゴルーチンに送信するといった場合に便利である。
→同期処理

# ミューテックス
一つのゴルーチンだけが特定のリソース（例えば、共有データ構造）にアクセスできるようにするための手段。
複数のゴルーチンが同時に同じリソースにアクセスしようとしたときのデータ競合を防ぐために使用される。
→排他制御

https://github.com/kabasunny/GoPractice/tree/main/channels

```Go
package main

import (
	"fmt"
	"sync"
	"time"
)

type SafeCounter struct {
	v   map[string]int
	mux sync.Mutex
}

func (c *SafeCounter) Inc(key string, ch chan int) {
	c.mux.Lock()
	c.v[key]++
	c.mux.Unlock()
	ch <- c.v[key]
}

func main() {
	c := SafeCounter{v: make(map[string]int)}
	ch := make(chan int)

	for i := 0; i < 1000; i++ {
		go c.Inc("somekey", ch)
	}

	go func() {
		for i := range ch {
			fmt.Println(i)
		}
	}()

	time.Sleep(time.Second)
	close(ch)
}

```
javascriptでライフゲーム作った


# ライフゲーム作った

javascript でライフゲーム作りました

ライフゲーム
[https://ikuo0.github.io/lifegame-js/](https://ikuo0.github.io/lifegame-js/)

ソースコード
[https://github.com/ikuo0/lifegame-js](https://github.com/ikuo0/lifegame-js)

# ライフゲームとは
wiki見ましょう
[https://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B2%E3%83%BC%E3%83%A0](https://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B2%E3%83%BC%E3%83%A0)

# 解説とか
ライフゲームについて今更ここで解説することも無いのでjavascriptでゲームの下地を作成した際の工夫点を書いていきます

以下メインループのソース部分を抜粋します

``` javascript
    self.MainProcess = function() {
        //var g = new MoveTest();
        var g = new LifeGameGame(128, 128, 10);
        var t = performance.now();
        var fpst = t;
        var framen = 0;
        var framerec = 0;
        var gameInput = new GameInput();
        var updatelimit = 0;
        var mainLoop = function() {
            var timestamp = performance.now();
            if((timestamp - fpst) > 1000) {
                fpst = timestamp;
                framerec = framen;
                framen = 0;
            }
            if(timestamp >= updatelimit) {
                updatelimit = timestamp + 15;
                self.deviceToInput(gameInput, self.keyCodes, self.keyEvents);
                self.keyCodes = [];
                self.keyEvents = [];
                //g.main(gameInput);
                g.update();
                framen += 1;
            }
            while(1) {
                var event = app.popEvent();
                if(event === undefined) {
                    break;
                } else {
                    var [eventName, eventData] = event;
                    if(eventName == "change-config") {
                        g = new LifeGameGame(eventData["size"], eventData["size"], eventData["speed"]);
                    }
                }
            }
            setTimeout(mainLoop);
        }
        var drawLoop = function() {
            var canvas = document.getElementById("main_canvas");
            var ctx = canvas.getContext("2d");
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            //Draw(ctx, g.drawData());
            DrawLifeGame(ctx, g.drawData());
            ctx.font = '20px sans-serif';
            ctx.fillText(String(framerec) + "fps", 0, 32);
            requestAnimationFrame(drawLoop);
        }
        mainLoop();
        drawLoop();
    }
```

## 処理ループの実装

``` javascript
            if(timestamp >= updatelimit) {
                updatelimit = timestamp + 15;
                /* 省略 */
        setTimeout(mainLoop);
```

setTimeout(mainLoop);　でループをして timestamp >= updatelimit　の判定で概ね60fpsにしようとしています、実際には 55fps 程度です、これ以上精度を上げられませんでした
setTimeout でループを作成する事によりCPU使用率を７～１０％に抑えられます、while(1) で素直にループを作成した場合はCPU使用率が１００％になります、当然whileにしたほうがフレーム精度は上がりますが
今回は1フレームを競うようななにかではないのでCPU使用率低いほうが良いだろうということでこの実装です

## 描画ループの実装

``` javascript
var drawLoop = function() {
  /* 省略 */
  requestAnimationFrame(drawLoop);
}
```

requestAnimationFrame(drawLoop); でループを作成しています
requestAnimationFrame はモニタのリフレッシュレート毎に呼び出してくれる関数です
CPU使用率結構上がってしまうので2回に1回くらい呼べばいいかもなーと思いつつそのまま使っています

このように処理と描画を完全に分けて処理しています
他の言語で作成する時は処理ループで処理中は描画しないとか、ロック処理必要かもですね
HTTPの概要

# HTTPとは
HTTP(Hypertext Transfer Protocol)とは、WebサーバーとWebブラウザの間で、情報をやりとりする際に利用されるプロトコル（手順・ルール）です。
ホームページやブログを閲覧する時に、HTTPを使用してサーバーとクライアント間でやり取りを行なっており、インターネットサービスを利用するには欠かせない存在となっています。
もともとはWebページを閲覧するためにハイパーテキストと呼ばれるデータを転送するためのものでしたが、現在では、ファイル共有やAPIを介したデータ提供、リモートのシステム操作、スマホやWebブラウザ上で動作するアプリのバックエンド、ユーザー認証やID管理、暗号化された通信の提供など、様々なシーンに利用されています。

# HTTPメッセージ
クライアントとサーバーが行う、リクエストとレスポンスのやり取りをまとめてHTTPメッセージと呼びます。
やり取りの流れは以前、IPアドレスとドメインの記事で紹介しているので、そちらをご覧ください。

https://qiita.com/toumayuetian/items/a6a095320929ae508586

HTTPメッセージに関してもまとめようかと思ったのですが、まだ私自身がいまいち理解できなかったのと、今無理して覚える必要性を感じなかったので、ステータスコードについてだけ下記にまとめました。
プログラミングする際によくステータスコードを見て、何のエラーなのか確認することもあるあと思うので、参考になれば嬉しいです。

## ステータスコードの種類
|ステータスコード|説明|ステータスコード例|
|---|---|---|
|100番台|クライアントからのリクエストを受け入れ可能で、継続して処理されている状態です。|100( Continue) リクエストの継続|
|200番台|クライアントからリクエストがサーバに送られ、通信が成功した状態。|200(OK) リクエストが正常に処理された|
|300番台|リダイレクトで別のURLへリクエストし直すように要求する。|301(Moved Permanently) リダイレクト|
|400番台|クライアント側で操作や入力に不備があった際に出てしまうエラー。|404(Not Found) 指定したwebページが見つからない|
|500番台|サーバ側に問題があり処理できなかったことを伝える。|503(Service Unavailable) 一時的にサーバーにアクセスできない|

# HTTPとHTTPS
httpとhttpsの違いは、通信内容が暗号化されているかされていないかです。
httpは「HyperText Transfer Protocol（ハイパーテキスト トランスファー プロトコル）の略で、データ通信の際に**通信内容を暗号化しない**方式です。
そのため、http通信を使ったWebサイトでデータの入力や発信を行なうと悪意を持った第三者に通信内容が漏えいする可能性があります。
httpsは「HyperText Transfer Protocol Secure（ハイパーテキスト トランスファー プロトコル セキュア）」の略で、WebサイトとWebサーバーの間のデータ通信の時に**通信の内容が暗号化**されているため、第三者への通信内容の漏えいや改ざんを防ぐことができます。
【自己紹介】初めまして、ぱせりです。

## はじめに
こんにちぱ、「ぱせり」です。

静岡のある学校で、学生をやっています。
知識量は、一般人に毛が生えた程度なのであらかじめ悪しからず...

## １：自己紹介
・ニックネーム：ぱせり
・出身：静岡県
・年齢：大学生(2024/5 現在20歳)
・趣味：お絵描き,ゲーム
・所持資格：基本情報技術者試験 etc...

## ２：Qiitaを始めた理由
 主な理由は三つ。
・『興味を広げたい』
　様々な情報を調べて自分の興味を広げることで、知識を豊かにしたいから。

・『目に見える形でなにかを残したい』
　私にはあまり自慢できるほどの実績がないので、Qiitaでの投稿を自分のやったことの一つとして残したいから。

・『誰かに届け』
　記事を見て、その事象について興味を持ってくれる人が一人でも増えてくれたらいいな。「経験の少ない学生であるからこその発信」が誰かに届いたら素敵だな。
 ...という気持ちがあるから。

## ３：投稿内容について
・自分が気になったニュースについて、調査しまとめたもの。
・勉強しているうえで興味深く感じたこと。
・自分が経験した、試験やインターンなどのイベントについて。
・先生や先輩から聞いた "ためになる話し" 。　等

## ４：今後の抱負と目標
・応用情報技術者試験の合格
・月一以上の記事の更新
・就職
・楽しく学ぶこと

## 終わりに
　これから様々なことについて発信していこうと思っておりますので、是非ともちょくちょく「なにしてるんだろうな～」くらいの気持ちでチェックしていただけたら幸いです。

最後まで読んでいただきまして、ありがとうございます。
Gitのインストール（Windows）

# GitをWindowsにインストールしよう！

Gitを使い始めたいけど、どうやってインストールするの？って思っているあなたにピッタリのガイドです。WindowsでのGitのセットアップ方法をサクッと説明しますね。

## WindowsでGitをインストールする方法

WindowsにGitを入れるのはとっても簡単。以下のステップに従ってください。

1. まずは[Git for Windows](https://gitforwindows.org/)にアクセスしましょう。
2. 画面にある「Download」ボタンをクリックして、インストーラーをダウンロード。
3. ダウンロードしたインストーラーファイルを開いて、画面の指示にしたがってインストールを進めてください。

インストールが完了したら、Git Bash（これがあなたの新しいコマンドラインになります）とGit GUIが使えるようになります。なんだかプロっぽい感じがしてワクワクしますよね！

## インストールの確認

インストールがちゃんとできたか確認しましょう。Git Bashを開いて、以下のコマンドを打ってみてください。
```bash
git --version
2024年版[PowerShell] コマンド整理_個人用途

## 参考

## 予備知識

## コマンド一覧

| コマンド |  | 説明 |
|:-:|:-:|:-:|
|  `exit` |   |   |
|  `Remove-Item -Recurse -Force [ファイル名]` |   |   |

## `exit`：セッションを終了（ログアウト）するためのコマンド
- `exit` コマンドは、**PowerShell セッション**を終了するために使用されます。つまり、これはコンソールウィンドウが閉じることを意味しています。

https://qiita.com/taigatomonaga/questions/52bcb8967f14af08866f#answer-comment-4a53b4043de3b5ec8fc8

::: note info
メモ
***Linux***では、シェルセッションを終了するために `exit`または`logout`を使用します。
- `exit` コマンドは、現在のシェルセッションまたはスクリプトから抜け出すために使います。
- `logout` コマンドは**ログインシェル**（ユーザーがログインした直後に開始されるシェル）からログアウトする際に使用します。

***Linux***での `exit` と `logout` の使い分けは、そのコマンドが実行されるシェルのタイプ（**ログインシェル**かそうでないか）に依存します。どちらのコマンドもシェルセッションを終了させる目的で使用されますが、`logout` はより特定の状況（**ログインシェル**での使用）に限定されます。

また、`exit`と`logout`は違う処理をしているため異なる挙動をします。

[参考]：
`exit` https://manpages.ubuntu.com/manpages/noble/en/man1/exit.1posix.html
`logout` https://manpages.ubuntu.com/manpages/noble/en/man3/logout.3.html
:::

そのため、ログアウトしたい場合には***PowerShell***では`exit`を使用し、***Linux***では`logout`を使用するとよいでしょう。
pyvmomiで仮想マシンオブジェクトをループせずに取得する方法(実行時間短縮)

pyvmomiを使ってvCenterの仮想マシン情報の取得をAPIで行う際に、情報取得にかなり時間がかかる(1分程度)という事象に遭遇しました。


調べたところ、対象のvCenterが2000台超の仮想マシンを管理しており、viewを作って仮想マシンをループして検索するところで時間がかかっていたようです。

今回仮想マシンの台数が多い際にも、対象の仮想マシンオブジェクトを素早く取得する方法が分かりましたので(あまり類似記事が日本語でなかったこともあり)、備忘として記しておきます。

# 元々利用していたコード
元々以下のようにviewを作成しfor文でループさせ、仮想マシン名が一致する仮想マシンMOBを取得するコードを書いていました。日本語でpyvmomiを検索するとよく出てくるコードから真似をしております。
```python
def get_mob_info(content, target):
    """
    指定した名前を持つ仮想マシンのManagement Objectを取得する。

    :type content: vim.ServiceInstanceContent
    :param content: ServiceContent

    :type target: str
    :param target: 返すmobの仮想マシン名を指定

    :rtype: Management Object
    :return: 指定したManagement Object又はContainerViewを返す
    """
    container = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True)

    # 返す仮想マシンmobを名前で指定する
    for mob in container.view:
        if mob.name == target:
            r = mob
            break
    return r

```
このコード自体は正しく動作しますが、管理対象の仮想マシンが増えるほど時間がかかるようになります。今回計測したところ1ループに0.02秒程度かかっており、2000台超の仮想マシンがいることで運が悪いと1分弱程度時間がかかるようになっていたようです。

# 改良したコード
時間短縮のために修正したコードは下記となります。viewでのループではなくパスで指定してvCenterのデータベースからクエリする方法となります。この方法で実施したところ実行時間は0.01秒以下となりました。
副次的ですが、コードとしてもスッキリし読みやすくなりました。
```python
def get_mob_info(content, target):
    """
    指定した名前を持つ仮想マシンのManagement Objectを取得する。

    :type content: vim.ServiceInstanceContent
    :param content: ServiceContent

    :type target: str
    :param target: 返すmobの仮想マシン名を指定

    :rtype: Management Object
    :return: 指定したManagement Object又はContainerViewを返す
    """
    search_index = content.searchIndex
    r = search_index.FindByInventoryPath("/<DataCenter名>/vm/" + target)
    return r
```

viewを使用した場合、すべてのオブジェクトを取得してからローカルでforループを実行するため、対象となるオブジェクトが多い場合に処理時間がかかりすぎるようです。一方、SearchIndexを使うとデータベースのクエリを使用して直接目的のオブジェクトを見つけるので時間が短縮されたようです。

# 最後に
ちなみにこの改良は軽くググって解決できずChatGPT(3.5)君に聞いて教えてもらいました。その後でこの記事を書く際に再度[pyvmomiのサンプル集Git](https://github.com/vmware/pyvmomi-community-samples)を確認したところ、普通にサンプルに載っていたのでやはり確認すべきは公式ドキュメントですね。

ただ検索弱者にもプロンプトの書き方次第でいろいろ教えてくれるGPT君は心強い存在です。
Poetryを使用してFast APIを動かしてみる

### ファイル構造
fast-api/
├── app
│   ├── init.py
│  └── main.py
├── poetry.lock
└── pyproject.toml

### pyproject.toml作成
$ poetry init
色々出てくるが、エンター押し続けてればOK

### 必要なパッケージをインストール
$ poetry add fastapi
$ poetry add "uvicorn[standard]"

### poetry.lock作成
$ poetry install --no-root

### main.pyを編集

```python
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def hello():
return {"message" : "Hello,World"}
```

### FastAPI起動
$ poetry run app.main:app --host 0.0.0.0 --port 80 --reload

### 起動しているか確認
・API ドキュメント(Swagger UI)
http://localhost/docs
・代替の API ドキュメント
http://localhost/redoc

### 参考：
Fast API 入門
https://zenn.dev/sh0nk/books/537bb028709ab9/viewer/742f63
FastAPIとは？PythonのWebフレームワークでWebAPIを開発しよう！
https://aiacademy.jp/media/?p=988
GW期間中に読んだ技術書

# はじめに
GWを10連休とったため、GW期間中に読んだ、または読んでいる本を紹介します。

## プログラミング言語大全
様々なプログラミング言語が世の中で使われているため、購入して読んでいます。
プログラミング言語の歴史から広く使われている言語、どういった用途で使われているか分かりやすく説明されています。


https://www.amazon.co.jp/s?k=%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9E%E5%A4%A7%E5%85%A8&i=stripbooks&adgrpid=128688934989&gclid=Cj0KCQjwxeyxBhC7ARIsAC7dS3_-fThLnVCwPNHkTttrQLeah_Uf0UyW2OZTCs8hV-20biaKXuMN-LIaApoCEALw_wcB&hvadid=678966717585&hvdev=c&hvlocphy=1009343&hvnetw=g&hvqmt=e&hvrand=11958397764625994624&hvtargid=kwd-903474869661&hydadcr=4073_13378617&jp-ad-ap=0&tag=googhydr-22&ref=pd_sl_4v9zk187xd_e

## 良いコード/悪いコードで学ぶ設計入門

現在も読んでいる本です。コードの可読性、コードの影響範囲を分かりやすく説明され、今でも繰り返し読んでいる本です。

https://www.amazon.co.jp/%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89-%E6%82%AA%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A7%E5%AD%A6%E3%81%B6%E8%A8%AD%E8%A8%88%E5%85%A5%E9%96%80-%E2%80%95%E4%BF%9D%E5%AE%88%E3%81%97%E3%82%84%E3%81%99%E3%81%84-%E6%88%90%E9%95%B7%E3%81%97%E7%B6%9A%E3%81%91%E3%82%8B%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9-%E4%BB%99%E5%A1%B2/dp/4297127830/ref=sr_1_2_sspa?crid=PPNQPNTJSLQ1&dib=eyJ2IjoiMSJ9.55Cl8KG6VMfGYvcnilh0LzFTOfXPNyFKxTSVdawRHkM10Q6jGpxyp8PU4hk4xGeFp_fHYsjKkdVufDtVARftyohc55wSVPpgAjO08UXUvfIEatK20OqGjWwX9wdmlOIMUdM0rTsqkz3kk3OVCLKervN_dyQCFMNuWyYLmALqahv3zcFCtiWQ5ngEHvvR67Qc.pJCvEsl6j1bDNXF_beHYbFVQF5VTlaiN39i-wbMBet0&dib_tag=se&keywords=%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89+%E6%82%AA%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A7%E5%AD%A6%E3%81%B6%E8%A8%AD%E8%A8%88%E5%85%A5%E9%96%80&qid=1715166048&s=books&sprefix=%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%2F%2Cstripbooks%2C187&sr=1-2-spons&sp_csd=d2lkZ2V0TmFtZT1zcF9hdGY&psc=1

## 日経ソフトウェア2024年5月号付録(5日で学ぶC言語の初歩)
C言語を使った開発をする予定に備えて、復習を兼ねて読破しました。
ポインターの解説がわかりやすいです。

# 最後に
長い連休の間、色々技術書を読む時間がとれたので、記事にしました。
意識高めな新卒未経験エンジニア

今日の反省
分からないことがあればすぐに質問すること。プライドが高いのかどうか分からないが質問を中々しない。結局他の人は知らないが俺の場合30分悩んで分からなかったら未来永劫分からない。正直考える時間が無駄。確かに悩んで悩んだ末にやっと答えにたどり着いた時は中々忘れないようになるがトータルで見た時損してるからすぐに聞くべきだな。
初めてqiitaで文章書くがアウトプットは楽しい！

理由としておれは常に何か考えて悩み事があると無限回考えると言うくせがあるがそれはアウトプットしないからそうしてしまう。
だけどエンジニアの悩みや考え事を常に発信してればアウトプットにもなるし頭の整理になるからやるべき
最近忘却バッテリーという漫画があるがそこの主人公である要圭は漫画の中でとても優秀な立ち位置でどうやって優秀になったかと言うと絶対ノートというノートを作ってそこに数年で何十冊になるくらいアウトプットしてたから。
高確率で優秀なやつっていうのはアウトプットしていて特にスマホではなく紙に書くのが大事。人間は実際に書くことによって脳に記憶するから絶対に紙に書くべき！

これからも人生で極めたいことってのは沢山出てくると思う。エンジニア以外にもゲームだったり恋愛だったりスポーツだったりあると思うが全部ノートを買って毎日ノートにアウトプットしろ。
日記的なのにもなるし見返した時に復習にもなるからマジでオススメ！特にアウトプットが習慣化されて感覚じゃなくて理論的に物事を捉えられるようになるから一石三鳥くらいはおすすめ


習慣化にも色んな方法があって俺がおすすめするのはifーthenルール。
これは何かって言うと日常的にやることにふづいしてやるってこと。例えばこの記事も電車の中で書いてるんだけど電車乗ってる時に記事を書くみたいな感じで他でいえば歯磨きしてる時に音声学習するみたいな感じ。


完璧主義的な傾向を持つ人間が多いがとりあえず行動するってのは大事。これも文章めちゃめちゃで読者からしたら読みづらいかもしれないが最初から書き方を意識したら筆が進まないし途中でやめてしまうかもしれないから記念すべき一記事目はこのまま投稿することにする。
Hardware / CPU

## CPUを学ぶ
CPUの中に２つ装置がある。
それは演算装置と制御装置がCPUの中にある。
この２つを詳しく見ていく。
### 制御装置：
汎用レジスタ：命令データを一時的に保存する。
演算装置：ALU

### 演算装置：
命令レジスタ
命令部とオペランド部に分かれる。
命令部は命令を格納する。
オペランド部は対象データがどこにあるか格納する。
    ＊アドレス指定方式で「データがどこにあるか」を表現する。
デコーダー：命令解読機
    命令を解読して必要な装置に指示を出す。
プログラムカウンタ：つぎに実行する命令のメモリのアドレス。

### 命令の実行手順を学ぶ
命令の取り出し：フェッチ
プログラムレジスタに格納されているメモリ番号と同じメモリ番号に格納されているデータを取り出し、命令レジスタの中に命令部、オペランド部にデータを格納する。そして、プラグラムレジスタは次の命令に備えて、値を１プラスする。
### 命令の解読
命令部がデコーダーに送られ、次の命令の信号を送る。
### オペランドの読み出し
オペランド部に例えば一番のデータを使う場合、メモリの一番のデータを汎用レジスタに送る。
### 命令実行
汎用レジスタに格納されたデータを演算装置（ALU)で実行して、演算結果を汎用レジスタに格納する。
PyTorch on Ryzen7 5700u

# Ryzen7 5700Uなど、CPU内蔵のGPUで、PyTorchを利用する

amdのcudaに相当するrocmのinstall方法は、対応のドライバーのインストールとruntime環境のinstallからなります

https://rocm.docs.amd.com/projects/install-on-linux/en/latest/how-to/native-install/ubuntu.html

```
# Make the directory if it doesn't exist yet.
# This location is recommended by the distribution maintainers.
sudo mkdir --parents --mode=0755 /etc/apt/keyrings

# Download the key, convert the signing-key to a full
# keyring required by apt and store in the keyring directory
wget https://repo.radeon.com/rocm/rocm.gpg.key -O - | \
    gpg --dearmor | sudo tee /etc/apt/keyrings/rocm.gpg > /dev/null
```

```
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/rocm.gpg] https://repo.radeon.com/amdgpu/6.1/ubuntu jammy main" \
    | sudo tee /etc/apt/sources.list.d/amdgpu.list
sudo apt update
```

```
sudo apt install amdgpu-dkms
sudo reboot
```

```
sudo apt remove rocminfo rocm-smi rocm-device-libs
sudo apt install rocm
```

```
sudo tee --append /etc/ld.so.conf.d/rocm.conf <<EOF
/opt/rocm/lib
/opt/rocm/lib64
EOF
sudo ldconfig
```

```.bashrc
export PATH=$PATH:/opt/rocm-6.1.0/bin
export HSA_OVERRIDE_GFX_VERSION=9.0.0
export HSA_ENABLE_SDMA=0
```
を追加


# check

```
dkms status
rocminfo
clinfo
```

# reinstall pytorch

```
python3 -m pip uninstall torch torchvision torchaudio
```

https://pytorch.org/get-started/locally/
を参考に

```
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/rocm6.0
```

# trouble shoot

もし、```rocminfo```が、通常ユーザーで動かなかったら

```
$ ls -la /dev/kfd
crw-rw---- 1 root render 235, 0  5月  8 15:04 /dev/kfd
```
上は動いているときの状況です。

```
sudo usermod -aG render $USER
sudo usermod -aG video $USER
```

や、

```
sudo chmod g+rw /dev/kfd
```

などパーミッションの設定を
TypeScriptで使用されるジェネリック型の一種"Record"

### Recordとは
Recordは、TypeScriptで使用されるジェネリック型の一種です。Recordを使うと、オブジェクトのキーと値の型を指定して新しいオブジェクトを作成できます。
具体的には、
Record`<KeyType, ValueType>`
という形式で使用します。

例えば、Record`<State, number>`は、Stateという列挙型のキーを持ち、その値の型がnumberであるオブジェクトを表します。具体的な使い方としては、州名をキーとして州税率を値とするオブジェクトを作成する場合などに利用されます。

```
const STATE_TAX: Record<State, number> = {
    "Arizona": 4.9,
    "California": 8.8,
    "NorthCarolina": 2.5,
    // 他の州の税率もここに追加する
};
```

このコードでは、各州をStateという列挙型で定義していることを前提としています。

### 列挙型の定義方法
列挙型 (enumerated type)。
例えば、次のように列挙型を定義することができます。

```
enum State {
    Arizona = "Arizona",
    California = "California",
    NorthCarolina = "NorthCarolina",
    // 他の州もここに追加する
}
```

または
```
type State = 'Arizona' | 'California' | 'Northcarolina';
```

このように定義されたStateは、指定された文字列のいずれかを取ることができる型となります。
これにより、特定の値を明示的に指定する必要がある場面で、不正な値を避けることができます。

コードをまとめると以下になります。
```
type State = 'Arizona' | 'California' | 'Northcarolina';

const STATE_TAX: Record<State, number> = {
  'Arizona': 4.9,
  'California': 8.8,
  'Northcarolina': 2.5,
};
```
【ruby】timesを使った繰り返し処理

timesを使った繰り返し処理です。

```ruby
greeting = 'Hello world'
n = 5
n.times do
    puts greeting
end

```

実行した結果です。

![kekka.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710584/a66ee55e-e680-6c13-77a2-d9eb3b9cf966.jpeg)