OmniAICreator/Qiita-1.07M huggingface dataset:
UserLAndのubuntuにMySQLをインストールしてrootでログインするまで

# はじめに 
スマホをiphoneからandroidに変えたらまずUserLAndを入れてLinuxで遊びたい。
という思いがあったものの、何して遊ぼうか思いつかないので取り敢えずMySQLを入れた。
起動・ログインまでスラスラとはいかなかったので、MySQLにログインするまでの手順を記録しておきます。

# UserLAndで使用するLinux
UserLAndで使用できるDistributionはArpine,Arch, Deboan, Kali, Ubuntuとありますが、
今回はUbuntuを選びました。インストールされたバージョンは22.04でした。 
```sh
$ cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.2 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
 ~~ 以下略 ~~
```
# MySQLインストール
以下のコマンドでMySQLをインストールします。
```sh
$ sudo apt update

$ sudo apt install mysql-server -y
```

# MySQL起動 
インストールしたばかりで、なんらかのmysqlコマンドを打つとまず以下のエラーが出ます。
```
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

```

mysqld.sockを通してローカルサーバーに繋げたいけどできないようです。
エラーで表示されているパスにmysqld.sockファイルが無いので作成します。
```sh 
$ touch /var/run/mysqld/mysqld.sock
```
MySQLを再起動します。
```sh
$ sudo service mysql restart
```

再起動する時に以下の警告が出るようです。
```                                      
su: warning: cannot change directory to /nonexistent: No such file or directory
```
mysqlユーザーのホームディレクトリが存在しないということなので、設定します。 
```sh 
$ sudo usermod -d /var/lib/mysql mysql
```
この状態で再起動すると警告は出なくなりました。 
```sh 
$ sudo service mysql restart
 * Stopping MySQL database server mysqld          [ OK ]
 * Starting MySQL database server mysqld          [ OK ]
```

# rootでログイン 
以下のコマンドでパスワードを確認しようとするもパスワードは設定されていないようです。
```sh 
$ cat /var/log/mysql/error.log | grep password
2023-04-01T05:20:32.183269Z 6 [Warning] [MY-010453] [Server] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
```
`--initialize-insecure option.`とあるのでmysqldコマンドにつけて実行し、パスワード無しのrootログインを試みますができないようです。
```sh 
$ mysqld --initialize-insecure --user=mysql

$ sudo service mysql restart

$ mysql -u root
ERROR 1698 (28000): Access denied for user 'root'@'localhost'
```

`sudo mysql`ではログインできます。 
```sh 
$ sudo mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 8.0.32-0ubuntu0.22.04.2 (Ubuntu)

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```
 
これでログインができたので、あとはrootパスワード設定や各種初期設定などを進めていくことができます。
Blender3.5でJupyterLab

## 概要

Blender 3.5が出たので、JupyterLabが動くか確認してみました。macOSで試してますが、他のOSでもできると思います。

Blender 3.5とPython 3.10はインストール済みとします。

https://www.blender.org/

## JupyterLabの準備

Pythonは、3.10.9です。

```sh:bash
python -V
```

```test:ouput
Python 3.10.9
```

JupyterLabをインストールしておいてください。

```sh:bash
pip install jupyterlab
```

## blenderカーネルの準備

blenderカーネル用の仮想環境を作成します。

```sh:bash
python -m venv venv
```

アクティベートします。

```sh:bash
. venv/bin/activate
```

ライブラリーをインストールします。

```sh:bash
pip install blender-notebook
```

Blenderのカーネルを追加します。
```sh:bash
blender_notebook install --blender-exec /Applications/Blender.app/Contents/MacOS/Blender
```

下記のように出ましたが、気にせずに「y」とします。

```test:ouput
Current python interpreter version is not 3.7!
blender_notebook will link pip packages installed in this interpreter to the 
blender embedded python interpreter. Mismatch in python version might cause
problem launching the jupyter kernel. Are you sure to continue?
 [y/N]: y
```

これでカーネルの準備は終わりです。お手軽ですね。

### カーネルの削除（Jupyterでblenderを使わなくなったとき）

カーネルが不要になったら下記のようにして削除できます。

```sh:bash
blender_notebook remove --kernel-name blender
```

カーネルの一覧は下記で確認できます。

```sh:bash
jupyter kernelspec list
```

### 参考

https://qiita.com/odu_beyond/items/8bfb73bc24e8014e0903

## JupyterLabの実行

JupyterLabを起動します。このとき、「blenderカーネル用の仮想環境」をアクティベートしている必要はありません。

```sh:bash
jupyter lab
```

新規作成でNotebookの「Blender」を選びます。
Blenderが起動します。

Notebookのセルに下記を書くと、モンキーが作成されます。

```py:jupyterlab
import bpy

bpy.ops.mesh.primitive_monkey_add()
```

単にBlenderを終了しても、自動でBlenderが再起動します。Blenderを終了したいときは、ノートブックのカーネルをシャットダウンしてください。なお、必要ならシャットダウンの前にBlenderのファイルを保存しておいてください。


### 参考

https://qiita.com/SaitoTsutomu/items/854c826bfc65ecae31f9

以上
Android ADB アプリパッケージ名の一部からパッケージ名、バージョンを取得

例えば、mapという文字を含むパッケージ一覧を取得します。
~~~bat:windows cmd.exe
adb shell "pm list packages ""map"""
~~~
:::note info
<details><summary>参考：Androidデバイスが２台以上接続されている時</summary>

デバイスが２つ以上接続されている場合は、-s オプションでデバイスを指定します。
~~~bat:windows cmd.exe
adb -s "XXXXXXXX" shell "pm list packages ""map"""
~~~
</details>

:::
:::note info
<details open><summary>参考：ダブルクオートのエスケープについて</summary>

ダブルクオートは入れ子にする場合、Windows Batの場合は二つ続けて書きます。（""）linuxシェルの場合はバックスラッシュでエスケープします（\\"）
~~~bat:
rem 入れ子 (windows)
"example string ""string 2"" string3"
~~~
~~~bash:
# 入れ子 (linux)
"example string \"string 2\" string3"
~~~
</details>

:::

結果は以下のようになります（複数ヒットすることもあります）
package:より後の部分がパッケージ名です。
~~~:
package:com.google.android.apps.maps
~~~
上で取得したパッケージ名を元に、バージョンとAPIレベルを取得します。
~~~bat:windows cmd.exe
adb shell "pm dump ""com.google.android.apps.maps""|grep -E ""targetSdk=|versionName="""
~~~
これはAndroid側では以下のように解釈されます。１つ目の`|`はパイプ、２つ目の`|`は正規表現の演算子になります。
~~~bash:Android
pm dump "com.google.android.apps.maps"|grep -E "targetSdk=|versionName="
~~~
結果は以下のようになります。
~~~
    versionCode=1066946479 minSdk=23 targetSdk=33
    versionName=11.72.0302
    versionCode=1036500244 minSdk=21 targetSdk=29
    versionName=10.36.5
~~~
googleマップの場合は２つ出てきますが、バージョンを表している情報は上側のものです。
grepの正規表現による絞り込みなので、必ずしも厳密な情報は得られない点に注意してください。（grepはAndroid側で動いています。Android10とAndroid4.4で動作確認）

`#C0FFEE`
Webアプリのセキュリティー(DDoS, CSRF, XSS, SQLインジェクション)

# セキュリティーについて
最近webアプリを作成した過程で、セキュリティーの重要性に気づいたので学んだことのアウトプットとして書いてみようと思います。

## 対策するべきセキュリティー
- DoS/DDoS攻撃
- CSRF（クロスサイトリクエストフォージェリ）
- XSS(クロスサイトスクリプティング)
- SQLインジェクション

## Dos/DDoS攻撃
ウェブサイトなどに対して大量のアクセスやデータを送りサーバーを停止させるサイバー攻撃

DoS(Denial of Servece Attack)
**１つのIP**から大量のアクセスを行う。

DDoS(Distributed Denial of Service Attack)
**複数のIP**から大量のアクセスを行うことである。

## 対策
- 特定のIPアドレスからのアクセスを遮断する
- CDNを使用する。使用することでサーバーへの負担を分散させる。
- ツールを使用する。




## CSRF（クロスサイトリクエストフォージェリ）
攻撃者が正規のユーザーのアカウントを不正に使用して、Webアプリケーション上で操作を行う攻撃である。攻撃者の悪意あるページを訪れることで、イベントが発生し正規ユーザーのCookie情報などが盗まれてしまう。これにより正規ユーザーが望まない操作が行われてしまう。（カード決済、コメント投稿...etc）

## 対策
- フォームタグを使用する際は、必ずトークンを発行するようにコードを書く
- ツールを使用する

## XSS(クロスサイトスクリプティング)
攻撃者が仕込んだJavaScriptがユーザーが訪れるたびにイベントが起動して、ユーザー情報などが盗まれてしまう。

## 対策
- htmlspecialchars関数を使用して、特殊文字をエスケープ処理する必要がある。
- ツールを使用する。

## SQLインジェクション
脆弱性のあるフォームにSQLを発行する文字列を投稿することで、情報を取得したり、データベース内のテーブルを操作されてしまう。

## 対策
- PDOパラメーターバインディングを使用して対策する。
- ツールを使用する。

# ツールについて
- IDS/IPS
- WAF
などを使用することで、脆弱性を狙った攻撃を対策することができる。

# 終わりに
セキュリティーはかなり奥が深いなと感じました。まだまだ書きれていない部分があるので、今後も書いていこうと思います。ここまで見てくださりありがとうございます。

# 参考サイト
- 3分でわかるXSSとCSRFの違い
https://qiita.com/wanko5296/items/142b5b82485b0196a2da
- 脆弱なサイトと罠サイトを実際に作って学ぶ『CSRF』とその対策
https://www.hypertextcandy.com/csrf-hands-on-tutorial
- ウェブアプリの脆弱性を狙うXSSとCSRF その仕組みの違いと対策
https://ascii.jp/elem/000/004/015/4015004/
個人開発でポータルサイトを作ってみました。

最近、個人開発でポータルサイトを色々立ち上げました。


・<a href="https://tatamiyamado.com/">畳屋の窓口</a>
・<a href="https://cleaning-list.com/">おそうじプロ名鑑</a>
・<a href="https://session-biyori.com/">セッション日和</a>
・<a href="https://guitar-school-mado.com/">ギター教室の窓口</a>
・<a href="https://niwameikan.com/">植木屋名鑑</a>


私はエンジニアではないため、技術的な話は特にありませんが、自分なりに工夫した点を備忘録的メモしておきます。


【主な環境】
・Wordpress
・テーマSWELL

【主な利用プラグイン】
・絞り込み検索プラグイン：vk filter search
・タクソノミー:Custom Post Type UI
・カスタムフィールド生成：Advanced Custom Fields

【工夫ポイント】
Wordpress上でACFを使い、店舗ページのデータベースを疑似的に作成。

wordpressを使ったポータルサイトを構築する場合、データベース化が困難です。そこでACFを活用し、疑似的にですが、店舗データをデータベース化することにしました。

ポータルサイトのSEOにおいて、カテゴリー毎の投稿件数の数はSEOで上位表示されるための大きな要素です。

そのため、店舗ページの投稿をいかに効率化するかが、大規模・中規模のポータルサイト運営を成功させるためのカギとも言えます。


phpやLaravelとか使ってフルスクラッチで構築できるなら、こんな回りくどいことは不要かもしれませんが....

自社にエンジニアはいないけど、wordpressならガンガンいじれる&SEO詳しい人材ならいるよ！っていう企業なら、外注せずに内製化すれば、工数的にもお金的にもローコストで構築できるため、おすすめです。

何より、開発が鬼早くできるため、まずはプロトタイプで事業検証してから、後でフルスクラッチで開発するなんてことも可能でしょう。


とはいえ、次回はフルスクラッチでの開発に挑戦してみたいですね。


全国にビジネスを拡大するうえで、DB型サイトを立ち上げるポイントについては私の下記のブログでちょこっと触れています。

・<a href="https://sla-gweb.com/">庭アド</a>
・<a href="https://uekiya-bassai-sentei-kusakari-bakkon.com/">植木屋サイト</a>
・<a href="https://cleaning-marketing-lab.com/">ハウスクリーニング・清掃集客Lab</a>
・<a href="https://music-school-marketing.com/">音楽教室集客相談所</a>
・<a href="benriya-syuukyaku.com">便利屋アド</a>
・<a href="uekiya-butler.com">植木屋バトラー</a>
rust data struct説明1--Vec 紹介-1

# rust data struct説明1--Vec 紹介-1
# モジュール説明 
module std::collectionsは基本のdata structを含めています（standard implementations)，この内容がこのdata structを紹介します

# タープ分類
```Plain Text
module std::collectionsは分類すると、以下の分類になりました
Sequences： vec, VecDeque, LinkedList
Maps:     HashMap, BreeMap
Sets:    HashSet,BTreeSet
Misc: 　　BinaryHeap
```




# Sqeuences-->Vec 紹介


# vecは何の物？arrayと区別
```Plain Text
vecは動的配列、arrayは静的配列です、以下は区別です
静的配列とは、配列のサイズがコンパイル時に決定されていることを意味し、
メモリ割り当てもコンパイル時に実行されます。
これは、プログラミング中に配列のサイズがわかっている場合に適しており、
配列のサイズは変更されません。
動的配列は、プログラムの実行時に動的に割り当てられるメモリであり、
そのサイズは要件に応じて変更できます。
プログラミング中に配列のサイズを決定できない場合や、
特定の状況に応じて動的に調整する必要がある場合に適しています
```


## create vec
```rust
//方法１　
//create writeable vec
let mut vec1 = Vec::new() 
//create readable vec
let  vec1 = Vec::new() 

//方法２
// vec!というmarcoを利用する、新たのvecを誕生する
// writeable
let mut vec1 = vec![1, 2, 3];
//readable
let vec1 = vec![1, 2, 3];
```
## add vec
```rust
// {}.pushの方法で増加データ,FIFO
let mut v = Vec::new();
v.push(5);
v.push(6)

```
![1680333177775.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231872/cdb85fc4-5ed8-70d1-83dc-76a3bedfad80.jpeg)


##  get an element from the tail 

```rust
let mut v = Vec::new();
v.push(5);
v.push(6)
// pop方法でデータを獲得
let a = v.pop();
println!("{:?}",a);
//結果；Some(6). 
//Someは何のものですか？初心者には難しいです、Some == have valueと考えるのは良いです
```


##  get an element in the vec

```rust
    let v = vec![1,2,3,4,5,6];
    let third: &i32 = &v[2];
    println!("third element is {}",third);
    match v.get(2) {
        Some(third) => println!("the third element is {}",third),
        None => println!("there is no third element"),
    }
```


##  traversal vec

```rust
let mut v = vec![100,2,33];
    for i in &mut v {
        //get an index from v,need write(mut )
        println!("{}",i);
        *i += 50;
        println!("L2 is {}",i);
    }
```


##  Use enums to store multiple types

```rust
enum SpreadsheetCell{
    Int(i32),
    Float(f64),
    Text(String),
}

let row = vec![
    SpreadsheetCell::Int(3),
    SpreadsheetCell::Float(64),
    SpreadsheetCell::Text(String),
];
```


## 　vecのmemory に関する

```Plain Text
vecは動的配列です
let mut vec1 = vec![1, 2, 3]; --＞ 3 memory block occpued
let mut vec2 = Vec::with_capacity(10); --> 10 memory block occpued
vec2.resize(10, 0);  --> 10 memory block value is 0 -> [0,0,0,0,0,0,0,0,0,0] equal
vec.push(2)；  --> add one memory block
vec.pop(1)；  --> mark one memory block recycle　（標識だけ）
このvecのlifetimes終わるの時、memoryを回収する
```
##  vec index 

```rust
let v = vec![0, 2, 4, 6];
println!("{}", v[1]); // it will display '2'

```
```rust
v      +----0----+---1---+---2----+--3-----+   //index position
       |    0   |    2   |  4     | 6      |   //value
```
WindowsユーザーがChromebookを試してみた

# はじめに

Windowsユーザーの私が初めてChromebookを試してみたので、感想、気づきなどについてのまとめです。
この記事は2023年時点でのC425TAを対象としたものです。

# PC向けOSの利用歴

私のPC向けOSの利用歴は次の通りです。
- Windows 
   - Windows Meが初めてのノートPC用OSで、以降はXP, Vista, 7, 8, 8.1, 10, 11と、二十数年間メインマシンにWindowsを利用しています
- MacOS 
   - 数年程前、MacBook Airを1年ほど業務(Webサービス開発）に利用していました

# 私のPCの利用用途

私のPCの利用用途は次の通りです。
- Webサーフィン
- Kindle, PDF等の書籍、文章の閲覧
- 音楽鑑賞
- 動画鑑賞
- SNS(Twitter)利用
- VisualStudio CodeとWSL2を用いたIT関係の調査、調べ物
   - 調べた内容をOneNoteにまとめています

# 雑感

- ノートPC用のオペレーティングシステムとして必要な機能、UIはきちんと提供されています
   - 各種設定画面や設定、アプリに素早くアクセスするためのドック、通知欄等
   - 雰囲気はかなりAndroidに近いです
- セットアップから利用開始まで非常にスムーズでした
- Androidアプリ激推しで非常に驚きました
   - セットアップ時に人気アプリのインストールを選択する画面があります
   - Chrome上から「Twitterをインストール」を選択するとPWAのインストールではなく、Play Store上のアプリがインストールされました
- 日本語入力も問題ないです
   - IMEが提供されています
- Linux環境の構築および、VisualStudio codeのインストールも容易でした
   - PostgreSQLのプロジェクトを開いても応答性等に問題なく操作できました
- 劇的に必要なリソースがすくなくなるわけではないです
   - 当たり前ですが、Androidアプリ、Linux環境を動かせばメモリが大量に必要となります
   - Androidアプリのインストール、アップデートに多くのCPUパワーが必要であり、応答性が著しく低下します(CPU使用率が100%前後)
- Androidスマホとの連携がスムーズです
   - MFAの鍵として利用できますし、タスクバー上で現在の状態をかくにんできます 

# Windowsとの比較について

- OSの提供するシェルの利用には特に違和感はないです
   - というよりも、Windows11はかなりAndroid/ChromeOSに寄せている気がします 
- Windowsアップデートに悩まされないことはうれしいです
   - Android, Linux環境がVMで動作しており、(おそらく）これらの環境のアップデートの為にシステム全体の再起動が求められないとおもわれるため
   - UACのような煩わしさもないです
   - ただし、Android/Linux環境のアップデートにはそれ相応のリソースが必要ですし、設定管理の煩雑さも存在します
- Windows11と比べてAndroidアプリ利用の完成度が高いです
   - 提供されるアプリのラインナップ(3rd partyストアではなく、純正のPlay Store)
   - GUIの応答性、不具合のなさ等
   - ただし利用できないアプリも存在します(OneNote等)
   - おそらく現代ではWindowsアプリよりもAndroidアプリの方が充実していることから、Androidアプリ推しなのは正解ではないでしょうか

# 個人的に困ったこと

- OneNoteのAndroidアプリ版はインストールできません
   - Web版を利用できますが、毎回ページのダウンロードに数秒待たされてもっさりします...
   - Linux版でインストールできるらしい（？）ですが、セキュリティや設定の面倒さからは利用を検討せず
- Web版のGMailの起動、メールの読み込みが遅くてストレスがたまります
   - Androidアプリ版はスムーズに動作するのでそちらを利用しました 
- Steamに対応してくれるとうれしいです -> 現在ベータ版ですが、あまり期待していないです

# ハードウェアについて

- ぱっと見、アルミ筐体かつグレア液晶で「それらしく」見えますが...
   - 液晶ディスプレイ、キーボード、タッチパッド、スピーカー、CPUやストレージの性能等が「値段相応」
   - ハードウェアの質の差を覆すには至りませんでした
   - タッチディスプレイにする前に前述の要素にお金をかけてほしいです

# まとめ

短時間試したのみですが、Windows(あるいはMac)固有のアプリケーションや周辺機器に依存していなければ、という条件付きではあるものの、メインマシンとして十分実用に耐えられるのではないでしょうか。

ChromeOS=Chrome経由でWebアプリしか使えない、単なる機能制限版のOSというイメージでしたが、実際にはAndroidアプリが激推しなので、高レスポンスで高機能なアプリも利用できます。
Androidアプリに対応したことは把握していましたが、実用に耐えられない単なるおまけだろうという事前の予想を良い意味で裏切られました。
実際にAndroidの開発者向けのガイドにChromeOS向けのページが存在するという非常に歪なことになっています。
https://developer.android.com/chrome-os/intro

ここまでするならばそもそもChromeOSという看板を使わずに、Android for Laptop/Desktopとして売ったほうが誤解が少ないのではと素人意見では考えてしまいますが、セキュアで手間がかからないイメージ等のマーケティング上の都合等があるのかもしれませんね。

一方でハードウェアに関しては当たり前ですが「値段相応」であり、まともなユーザー体験のためにはそれなりの価格のハードウェアを購入すべきです。
※より新しいChromebookはメインメモリが4GiBのみ、あるいはCPUがAtomベースのCeleron搭載マシンが多く存在することから、新しいからと言って必ずしもユーザー体験が良いとは限らないと思われます

Chromeが動くだけだった過去とは状況が異なり、セキュア、手間がかからなさに加えてAndroidアプリの動作のスムーズさ、Android OSとの連携等の売りがあるので、各社もっとお金をかけた筐体をプッシュしても良いのでは...
CircleAvatorで画像を表示する方法

CircleAvatorに画像イメージを使用する方法をまとめます。
<h3>ネットワーク上の画像を使用する場合<h3/>

以下のコードでネットーワーク上の画像を表示できます。
```main.dart
CircleAvatar(
    backgroundImage: NetworkImage(
        "url"),
),
```
<h3>ローカルに保存した画像使用する場合<h3/>
ネットワーク上にない画像を使用する場合、画像をフラッタープロジェクトに対してアセットとして登録する必要があります。

<h5>1、imagesフォルダを作成<h5/>
まず画像保存用のフォルダをプロジェクト直下に配置します。今回はフォルダ名をimagesとしました。このフォルダ内に使用する画像を保存していきます。
<h5>2、puspec.yamlを編集<h5/>
プロジェクトフォルダ内に存在する、pubsupec.yamlを編集し、先ほど作成したimagesフォルダをアセットとして登録します。

```pubspec.yaml
# To add assets to your application, add an assets section, like this:
  assets:
```
asset:以下にimagesを追加します。

```pubspec.yaml
# To add assets to your application, add an assets section, like this:
  assets:
    - images/
```

以上でimagesフォルダをアセットとして利用可能になりました！
<h5>3,画像を表示<h5/>

```main.dart
CircleAvatar(
    backgroundImage: AssetImage('images/img.jpg'),
),
```
こちらのコードでimagesフォルダ内の画像を表示できます。
また
```main.dart
CircleAvatar(
    child: Image.asset("images/girl.jpg"),
              ),
```

としても画像の表示はできますが、サークル型ではなく元の画像のまま表示されます。
AWS Certified Cloud Practitionerの勉強をお金をかけずにやってみたら合格できた

AWSの資格取りたいとは思ってたものの、基本的に年がら年中受験できるAWSの資格を受ける気にはなれずそのまま放置していたのだが、会社でAWSの資格を推進してたこともあってどうせなら受けてみた。
そうしたら案外どうにか合格できたので実際にやってきたことを記録として残す。

## はじめに
私のAWSとの関りについてざっくりこんな感じ

- AWSでの作業歴：業務でだいたい2年ぐらい
- AWSでの作業内容：アプリケーション運用保守で触る程度（構築とかはあんまりしてない）
- 業務以外でAWSを使ってない

## １．受験した背景
受験した背景はざっくり以下の通り。~~だいたい下心ありきで受験である。~~ 

- 会社で「AWSラーニングパス」を受講したから
- ラーニングパス受講後、AWS使ってる業務をしているし何らかの資格が取りたかった
- 合格した場合、会社が受験料全額負担してくれたから
- 合格後、有効期間内は資格手当が貰えるから

1番目と2番目に書いてある「AWSラーニングパス」というのはAWSってこういったことができますよ的な概要を知ることができるもの。
無料で動画が見れてAWSでの構築やビジネスの説明を動画授業を受けた。
とはいえ受験したはいいが、このまま何もしないのもどうなのかと思い、資格の勉強をやろうという気持ちが芽生えた。

3番目の受験料負担は期間限定でやってたこともあって、いつでも受験できるAWSの試験に対して重すぎた私の腰を上げる一番のきっかけになったのは間違いなかった。
そして4番目は元々資格手当があったのだが、~~手当の金額も少ない為手が伸ばしにくかったこともあり渋っていたのだが、~~ 受かったら受験料も返ってくるし実質タダでできるというところから受験する気力が芽生えた。

## ２．使ったもの
資格勉強で使ったのは以下の２つ。どちらも無料で利用した。

1. AWS認定資格 クラウドプラクティショナーの教科書　合格へ導く虎の巻（電子書籍）
  https://books.rakuten.co.jp/rk/2ddc4b0e518c393a98e2919a319e33fb/
2. AWS認定資格 無料WEB問題集＆徹底解説 クラウドプラクティショナー
  https://aws-exam.net/clf/

まず1のテキストを電子書籍で購入して、ざっくり2周読む。
その後はただひたすらに2の問題集を解き続ける。
多分3週＋ランダムで何回も解いてた気がする。
それ以外の勉強方法はしていないし、あるなら逆に教えて欲しい。

## ３．試験日当日
試験日当日も特に何も構えることはなく、ただテストセンターの時間までただひたすらに問題を解いていた。
テスト自体はテストセンターに入るのは就活以来だったので変な緊張感があったが、PCの画面に出てくる問題に対してぽちぽち選択していたらあっという間に回答が終わった。
何問か明らかに見たこともない問題もあったけど、そこは一般論的な視線で考えて何とか埋めた。

終わった瞬間、結果が即時反映されて「合格」の二文字があった時には、達成感があった一方で、スリルもなく速攻で表示されるあっけなさもあった。

## ４．今後
今後についてはとりあえず他のAWSの資格を取ろうかなとは計画中。
とはいえ、参考書も受験料も洒落にならない金額なので同じように問題集が無料である「Solutions Architect - Associate」でもやろうかな。
renderとredirect

## renderメソッド
**レンダリング**は、コントローラーのアクションがrenderメソッドを使用してビューの出力を指示する作業である。renderメソッドは、ビューテンプレートを呼び出し、それをもとにHTMLを生成する。

### コントローラーのアクションとビュー呼び出し
renderメソッドは必ずしもコントローラーのアクション内で明示的に記述する必要はない。renderメソッドを指示しない場合でも、Railsでは規約に従って暗黙的にViewメソッドを動作させることができる。

以下の4つの条件に該当する場合は、renderメソッドを明示的に指示しなくても問題はない。
1.ルートで呼び出されたアクションがコントローラー内にない
2.ルートで呼び出されたアクション内にrenderメソッドがない(ただし、redirect_toメソッドがある場合は除く)
3.ルートで呼び出されたアクション内のrenderメソッドにビュー名を指定する引数がない
4.ルートで呼び出されたアクション内のrenderメソッドのビュー名がアクション名と同じ

その場合、Railsは指示されたアクション名に相当するerbファイルを探し出し、そのrenderメソッドを暗黙的に実行する。
例えば、Userコントローラーのshowアクションであれば、view/users/show.html.erbがビューテンプレートとして使用される。


### 任意のビューをレンダリング
renderで明示的にビューを指定すると、指定されたビューが表示される。その際に、もし他のコントローラーに関係するビューを呼び出す場合は、viewsディレクトリ内のそのコントローラー名を持つディレクトリから、viewsを起点にした相対パス名を指示する必要がある。

* 同じコントローラー内に関連するビューを表示させる時
```ruby:users_contoroller.rb
def index
  render 'users_list'
end
```
とすると同じコントローラー内のlistアクションに対応するviewファイル（views/users/user_list.html.erb）を表示させる。
* 違うコントローラー内に関連するビューを表示させる時
```ruby:users_contoroller.rb
def index
  render 'photos/photo_list'
end
```
とすると違うコントローラー内のlistアクションに対応するviewファイル（views/photos/photo_list.html.erb）を表示させる。



## redirect_toメソッド
redirect_toメソッドは、コントローラー内のアクション内で使用する、アクション実行後に他のルートへリダイレクトを行うためのメソッドである。新たなHTTPリクエストをサーバーに送り、コントローラーのアクションが実行される。

redirect_toの引数に外部URLを渡すことで、他のサーバーを宛先にリダイレクトすることもできる。
```ruby
redirect_to 'http://www.examle.com'
```
【ReactHooks】useMemoについて

## useMemoとは
**関数の実行結果をメモ化**するフックです。同じ入力に対して、キャッシュされた結果を返すことができる機能です。**不要な再計算を避けます**。コンポーネントが再レンダリングされた際に、重い計算を再度実行するのを防ぐので、パフォーマンスが改善します。また、レンダリング結果もメモ化できるので、コンポーネントの再レンダリングを制御することもできます。

#### 基本形
```javascript
const メモ化したい変数 = useMemo(() => {
  // 実行したい処理
  return メモ化したい変数
},[依存変数を配列で記述])
```

## 使用例
以下、`handleClick`関数を`useMemo`でメモ化しています。通常、`count`が変更された時に再レンダリングされるので、`handleClick`も再生成されますが、`useMemo`を使って **`count`が変更された場合にのみ**再生成するようにしています。
```javascript
import React, { useState, useMemo } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  const handleClick = useMemo(() => () => {
    setCount(count + 1);
  }, [count]);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
}
```

なお、以下に、`useMemo`を利用した場合と利用しなかった場合の例がありました。関数コンポーネント内でReact.memoを利用しても意味がないので注意とのことです。

https://qiita.com/soarflat/items/b9d3d17b8ab1f5dbfed2

## useCallbackとの違い

#### 目的
`useMemo`は関数の戻り値をキャッシュすることで、同じ入力に対して同じ結果を返すことが目的です。一方、`useCallback`は、同じ関数の再生成を防ぐことが目的です。親コンポーネントが再レンダリングされた場合でも、子コンポーネントが不必要に再レンダリングされることを防ぎます。

#### 引数
`useMemo`の第2引数には、メモ化するための依存関係を配列で渡します。一方、`useCallback`の第2引数には、依存関係ではなく、再生成をトリガーする引数を渡します。コールバック関数を作成する場合には極力`useCallback`を使用するべきと解釈しています。
WinMergeで差分が出た行のみ抽出

# やり方

たとえば比較結果が下記の時。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/d8c9157f-32fd-2a48-9a72-f9d3e988884b.png)

表示 ⇒ Diffコンテキスト 。
0行を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/0e682571-d638-b638-f61b-5de6fac887ef.png)

すると **差分が出た行だけ** に絞ってくれる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/ae196392-875a-affc-98a8-400ec25102ab.png)

結果を全選択して、コピーすれば…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/4cf9c690-0faa-21bc-e9e4-81ccc35b8856.png)

テキストエディタに張り付けもできる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/5efaa245-3444-be92-f411-45d17b1905df.png)

Diffコンテキストの『〇行』というのは　**『差分の前後〇行まで含めて表示』** という意味。

『1行』に設定すれば下記になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/5ab4bbea-e51c-4d6d-4d2b-447f2d8c888b.png)

**純粋な差分行だけじゃなくて、前後何行かも含めて表示してほしい** といった時は1行以上にすると便利。


# 参考サイトさん

https://hirooooo-lab.com/development/winmerge/

# バージョン

Windows 10 Pro 22H2 OSビルド 19045.2788
WinMerge Version 2.16.20.1
mongodb on ubuntu server 22.04 armhf

mongodb on ubuntu server 22.04 armhf

https://oversun.jp/?p=134
から全ファイルをdownloadさせていただく。

```
sudo apt-get install libboost-chrono1.74.0 libboost-filesystem1.74.0 libboost-program-options1.74.0 libboost-regex1.74.0-icu70 libboost-thread1.74.0 libpcrecpp0v5 libyaml-cpp0.7
```

```
sudo dpkg -i mongodb-server-core_3.2.2222.04_armhf.deb 
```

```
sudo dpkg -i mongodb-server_3.2.22~22.04_all.deb
```

```
sudo dpkg -i mongodb-clients_3.2.2222.04_armhf.deb
```

```
sudo dpkg -i mongodb_3.2.2222.04_armhf.deb
```
翌日には6割以上忘れられている深イイ話

## 深イイ話、覚えている？

新人プログラマーの皆様、先輩プログラマーの皆様こんにちは。

入社式や所属部署のオリエンテーションで、「新人の心構え」だったり、今後エンジニアとしてやっていく上で大事なことだったりといった深イイ話は聞きましたか？あるいは深イイ話をしましたか？

わたしは、去年の今頃に **「日本語」と「セルフマネジメント」を頑張れ** と割とシンプルな深イイ話をしたつもりだったのですが、一年経って何か覚えているかと聞いてみたところ **何も覚えていない** という忌憚のない返事を頂きましたので少し考察してみることにしました。


## そもそも深イイ話じゃなかった説？

![感覚的不一致.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/8123d8b0-b4d0-d400-bd3e-ad83351f8e90.png)

なるほど。コミュニケーションが成立してないのですね。

例えば、**話す側が 「新人の心構え」という新人が身につけて当然の話しをしたのだから伝わって当然** という感覚で話をしたり、**聞く側に前提となる知識などがない**という時には高確率で「感覚的不一致」が発生しそうですね。

多人数に対して深イイ（と思っている）話をする場合、校長先生の朝礼と同じで、話す相手によって話の内容をカスタマイズできなくて一般的な聞く側の関心から遠い話になりがちだから難易度が高いけれども、トピックの選び方や話し方などでは工夫できるかな・・・？というところでしょうか。

一方で個別に会話したことは記憶してもらえていたという話も聞けたので、1 on 1 で伝える場合は前段で軽い会話を挟んで興味を引いたりその会話によって伝える内容をカスタマイズするなどは効果があるようでした。


## 情報過負荷（Information overload）説

> 情報過負荷とは、人が処理できる情報量を超える情報が与えられたときに、情報を適切に処理することができなくなる現象です。新しい環境に適応し、多くの情報を同時に処理する必要がある場合、情報過負荷が発生する可能性があります。この場合、先輩からの大切な話を聞いているつもりでも、情報が過剰であるために記憶に残らないことがあります。

なるほど。話した側は「いい話」をしたんだから「伝わった」でしょうと感じたけれども、聞いた側は右から左に通り過ぎてて「はぁ？なんで覚えてないの？」みたいな悲しい事故はこういうメカニズムで起きていたのですね。

話す側は、「ちゃんと聞いてるの？」「聞く気あるの？」と問い詰める前に、聞く側の状況を今一度ヒアリングして整理するとこの状況は回避できるかもしれませんね。


## 情報忘却と忘却曲線問題説

様々な阻害要因を乗り越えて伝わったとしても、人間の脳は「忘れてしまうように出来ている」という問題があります。

> 情報忘却とは、記憶の一部または全部を失うことを指します。情報忘却は、私たちが情報を受け取ったときに起こり、情報を維持するために積極的な努力が必要です。記憶を維持するためには、情報を何度も繰り返し復習することが効果的であり、メモを取ったり、要点をまとめたりすることも役立ちます。

興味が無いことはもちろん、興味があることですらも反復しない限りは忘れてしまうという話ですね。次々新しい技術が出てくるのを覚えないといけないのに、困ったものです。

![忘却曲線.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/585ffaef-631b-b713-b133-ef54c7a8b9fe.png)

なるほど。復習をしなければ１日後にはおよそ66%の内容を忘れてしまうように人間はできていて、わたしが「深イイ話」と思って話した話も一年後には忘れられてしまう方が普通なのですね。悲しいけれども。


## おわりに

本文からは読み取れないと思いますが、「深イイ話」を覚えていてほしいという話ではなくて、IT業界というところで４０年なり４５年なり生存していくのはとても大変だから、自分なりに**自分に合った生存戦略を見つけて欲しいな**という話でした。

配属、案件、先輩ガチャに加えてAIの登場といった不確定要素がある中で、どうしたら安定して『エンジニア』としての市場価値を出し続けられるのか。頭の片隅においておいてもらえるとよりよい『エンジニア』ライフを送れるのではないかと思います。

ついでに、冒頭の深イイ話(?)が１年後の皆様の何かのお役に立てていたら幸いです。

> **「日本語」と「セルフマネジメント」を頑張れ** と割とシンプルな深イイ話をしたつもり。


## おまけ１（新卒エンジニア向け手紙）

https://qiita.com/kaku3/items/2c8d4d783be7ce4fc9ea

https://qiita.com/kaku3/items/0bf1703cb8d6f84afbc5


## おまけ２（新卒エンジニア向け記事）

https://qiita.com/kaku3/items/fb949aa1a53f1f71c796

https://qiita.com/kaku3/items/aa2f81cf1e3974b8ad3a

https://qiita.com/kaku3/items/f8411523cce000de750e

https://qiita.com/kaku3/items/937354cc180c8bee823b


## おまけ３（営業A短編シリーズ）

https://qiita.com/kaku3/items/03aae7b9e3c70c55f513

https://qiita.com/kaku3/items/3378ea55b1240d7360a1


## おまけ４（エンジニアのためのお仕事問題集）

2030年にIT人材が最大79万人不足するらしいので、学習用の資料をgitで**無料**公開してます(不定期更新)。
よろしければどうぞ。

[エンジニアのためのお仕事問題集](https://github.com/kaku3/workbooks)
【備忘録】pivot_wider と pivot_longerを毎回忘れる

ただの備忘録です。

ロングデータとワイドデータの変換は結構頻発するにもかかわらず、なぜかpivot_widerとpivot_longerの引数を毎回忘れてまう。

毎回ググっているが、みんなちゃんと書いてくれていてぱっと見、よくわからないので、最低限だとどうなるかここに残しとく。

とりあえずこんなデータがある。

```r
df <- tibble(ID = rep(1:3, 2),
             questionaire = c(rep("Q1",2), rep("Q2",2)),
             ans = runif(4, 1, 5) %>% round(0))

> df
# A tibble: 4 × 3
     ID questionaire   ans
  <int> <chr>        <dbl>
1     1 Q1               1
2     2 Q1               2
3     1 Q2               3
4     2 Q2               3
```

- これはいわゆるロングデータだけれども、ワイドデータにしたくなることがある。

# ワイドデータにする
- questionaire列を作って、その中の値をansにするには以下

```r
wide <- df %>% 
  tidyr::pivot_wider(names_from = questionaire,
                     values_from = ans)

> wide
# A tibble: 2 × 3
     ID    Q1    Q2
  <int> <dbl> <dbl>
1     1     1     3
2     2     2     3
```

- 列名にしたい列を`names_from`で指定し、どの値を入れるかを`values_from`で指定するだけ。


# ロングデータにする

```r
long1 <- wide %>% 
  pivot_longer(cols=c(Q1,Q2))

> long1
# A tibble: 4 × 3
     ID name  value
  <int> <chr> <dbl>
1     1 Q1        1
2     1 Q2        3
3     2 Q1        2
4     2 Q2        3
```

- ロングデータにする際はロングデータにしたい列を指定するだけで良い。
- ただし、列名がデフォルトで`name`と`value`になっている。
    - `names_to`と`values_to`で指定しれやれば良い


```r
long2 <- wide %>% 
  pivot_longer(cols=c(Q1,Q2),names_to = "question",
               values_to = "ans")

> long2
# A tibble: 4 × 3
     ID question   ans
  <int> <chr>    <dbl>
1     1 Q1           1
2     1 Q2           3
3     2 Q1           2
4     2 Q2           3
```

終わり。
AccessのVBAでファイルを1行ずつ読み込み（Stream使用）

# 概要

『dat』や『txt』などの『テキストエディタで中身が確認できるファイル』を1行ずつ処理。
ファイルの文字コードを指定して文字化けしないように。

# やり方

下記の参照設定を追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/299c7598-657d-4f2b-f9d6-0a08093811df.png)

```vb:サンプルコード
'フォーム内に『btn_test』という名前のボタンがある想定のサンプル。
Private Sub btn_test_Click()

    'Accessファイルと同じフォルダーに置いてある『tester.txt』を読み込む。
    Dim file_path_ As String
    file_path_ = CurrentProject.Path & "\tester.txt"

    Dim stream_ As New ADODB.Stream
    'stream_.Charset = "shift_jis" 'SJISならこう。
    stream_.Charset = "utf-8"
    stream_.Open
    stream_.LoadFromFile file_path_
    
    Do Until stream_.EOS
    
        'adReadLine ≒ 定数　『現在の位置から次の行を読み込むという動作』となる。
        Debug.Print stream_.ReadText(adReadLine)
        
        '『adReadAll』を引数で渡すと『現在の位置から最後の行まで全て読み込む動作』になる。
        
    Loop
    
    stream_.Close

End Sub
```

下記は読み込むファイルをサクラエディタで開いたところ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/2f42edfa-43e5-a03b-2648-a5c3f2b5330f.png)
サクラエディタ設定が下記なので改行は『キャリッジリターン + ラインフィード』
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/0bde19b9-9492-4508-7b0d-17875e1c3abb.png)
文字コードとBOM有無については下記。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/f76bd58b-c1c8-cd27-0586-b03c0f5251f3.png)

実行結果は下記。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/0fb4ab56-4b78-e479-315d-e3c50641fcec.png)

# 空行がある場合

前述の実行結果を参照。
問題無く処理できる。
『例外になる』『空行が処理されない』といったことは起きない。

# 改行

サンプルのVBAコードはそのままで、読み込むファイルの改行コードだけを変えて検証。

## キャリッジリターン + ラインフィード

前述の実行結果を参照。
問題無く処理できる。

## キャリッジリターン

読み込むファイルが下記。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/046609c6-23c6-a427-7f2f-bc040401cdc3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/410c2f46-daac-cc5f-d7c6-b5e923079300.png)
実行結果は下記。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/0512f330-8712-8977-99b8-fd4dddcc820a.png)
問題無く処理できる。

## ラインフィード

読み込むファイルが下記。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/c3adf742-1a25-435f-2c9f-df0ca0e8ef49.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/fa2b2bc3-f49b-2328-409b-4a401e6f02b6.png)
実行結果は下記。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/36993420-ecd6-aea0-80a1-81b8522f0c57.png)
問題無く処理できる。

# BOM

サンプルのVBAコードはそのままで、読み込むファイルの改行コードだけを変えて検証。

## BOMあり

前述の実行結果を参照。
問題無く処理できる。

## BOM無し

読み込むファイルが下記。
（文字コードだけならBOM無し）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/9a90cd2e-d5ae-6002-c534-5aed32c7ba83.png)
実行結果は下記。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/192edd70-3105-ad1b-161a-de866151641b.png)
問題無く処理できる。


# 参考サイトさん

https://learn.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/streamreadenum



# バージョン

Windows 10 Pro 22H2 OSビルド 19045.2788
Microsoft Access for Microsoft 365 MSO (バージョン 2302 ビルド 16.0.16130.20298) 32 ビット
【新人プログラマー応援】向いていないと思っても

大学の情報系授業で相当いい単位は取得した社会人5年目の人が思う新人プログラマーとして向いてる人と向いてない人の違い。
# プログラム言語の習得にはどれくらいかかる？
電気科出身の筆者であるが、C言語の習得に関しては1年間丸々かけて習得した（必修授業だったため、どうしても習得せざるおえなかった）。
別途就職してから3ヶ月の研修にてJAVAの習得を行った。JAVAに関してはC言語との違いを理解しながら学ぶことが出来たので、結構おもしろいと思っていたが、3ヶ月で初めてプログラミング言語を触った人間にとっては過酷でしかないと思う。
3ヶ月で結構向いている人はすぐに組めるようになる人もいるが、全体の10%にも満たない。

# 研修で向いていないと感じても
大体の会社で3ヶ月の研修を終えるとその後にOJTに移行すると思う。だけど、そんなこといわれてもプログラムが全然組めない状態で来ている人がほとんどである。
なので、研修で全然できなかったなとかは関係ないと思う。全然できなくて当然だと教える方も思っている筈である。
まあ、過去にいろいろとプログラミングが出来ていて出来る人がいればそれはそれで教えるほうは楽ではあるけどさ。

# 向いていないから諦めるならすぐに諦めよう
自分はITの仕事向いていないなと思うのであれば、すぐに転職しちゃったほうがいい。そのほうが気持ちも楽になる。
残業が多いから辞めるとかという理由も全然ありだと思う。

# 年収を増やすために辞める
これは一理あるんだが、IT業界では転職していった方が年収がのびる。なので、年収をふやす為にも辞めるというのも一つの選択肢には違いなのが、1年くらいの実務歴で辞めちゃうと結構転職では苦労することが多い。まあ、それでも転職できない訳ではないので、エージェントサイト等に一回登録してみてどういう企業が自分を求めているのかを判断するのもいいかと思う。
サクラエディタで現在開いているファイルのBOM有無を確認

# やり方

設定 ⇒ 文字コードセット指定 。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/66eafe93-35d4-9b9c-e6b7-60b41f97c30c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/13e3814d-5aa9-2484-f826-a9052af5f362.png)

# 蛇足

ステータスバーの右端に文字コードが表示されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/03aae2a8-7aaa-7d66-fa99-fcb03e8f182c.png)

しかし『BOMあり』なのか『BOM無し』なのか **コレガワカラナイ** 。

『BOMあり』だと下記表示になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/a69e3379-0eda-e3ce-07a0-331f6293154c.png)

つまり、ステータスバーで『UTF-8』だけの表示なら『BOM無し』と判別できる。

でも使う側が **そういう仕様を覚えないといけない** 。
覚えるの面倒くさい。

『UTF-8 BOM無』という表示にしたかったが、やり方が分からなかった。

# 参考サイトさん

https://boukenki.info/sakura-editor-bom-settei-houhou/

# バージョン

Windows 10 Pro 22H2 OSビルド 19045.2788
サクラエディタ v2.4.1.2849 32bit (tag v2.4.1)
Rubymine初期設定、デバッグの使い方

# デバッグ概要

RubyMine公式

https://pleiades.io/help/ruby/debugging-code.html

# 設定

Rubymine公式より
> RubyMineは、ERBおよびHAMLファイルを含むRubyコードのデバッガーを提供します。
> Ruby 2.0+プロジェクトのデバッグには、プロジェクトSDKにインストールされたdebase(英語)および
> ruby-debug-ide(英語) gemsが必要です。これらのgemsがインストールされていない場合、
> RubyMineは、初めてデバッグを実行するときにこれを行うことを提案します。

:::note warn
注意
プロジェクトで debug、byebug、または同様のデバッグ gem を使用すると、RubyMine デバッガーに影響を与える可能性があります。低速化や予期しない動作を防ぐために、このような gems を無効にすることをお勧めします。
:::

という事なのでgemを追加しましょう。
（debug,bybugが有効になっている方は無効にしましょう）
``` rb:Gemfile.rb
gem 'Ruby-debug-ide'
gem 'debase'
```

``` terminal:gemのインストール
bundle install
```

これで、Rubymineのデバッグが利用可能になりました。

## デバッグの手順
- Rubymineを起動する
- （オプション）設定 | ビルド、実行、デプロイ | デバッガーページでデバッガー設定を構成します。
- 必要に応じて、既存の実行 / デバッグ構成を作成または変更します。
- コードにブレークポイントを配置します。
- デバッガーセッションを開始します。
- デバッグセッション中に、プログラムの状態を調べます（変数値の確認、式の評価など）
　デバッグコンソールを使用してこれを行うこともできます。

##### デバッグプログラムのステップスルー

https://pleiades.io/help/idea/stepping-through-the-program.html#step-over

# Ruby例外処理の書き方（begin、rescue）
こちらの記事に詳しく書かれています🙏

https://qiita.com/ngron/items/4c319ae7340b72c7e566


## 不具合調査を楽にする仕組み
- Bugsnap
- Better Errors
- New Relic
- TracePoint

https://tech.stmn.co.jp/entry/tech/4431


## Ruby on Railsのプロジェクト１０大エラー
https://www.transnet.ne.jp/2018/06/15/1101colnd/
seedsを使った初期データの投入

## seedsについて
アプリに初期データを入れておきたい場合にseedsを使います。
このファイルにデータを生成するコードを書き、コマンドを実行することでデータベースにテストデータを投入することができます。

## seedsの使い方
通常はseeds.rbのみに記述しますが、今回は２つのファイルに分けて記述します。

##### データを追加するためのスクリプト
```rb:db/seeds.rb
table_names = %w(staff_members)

table_names.each do |table_name|
  path = Rails.root.join("db", "seeds", Rails.env, "#{table_name}.rb"
  if File.exist?(path)
    puts "Creating #{table_name}..."
    require(path)
  end
end
```

##### 実行したいクエリ（投入するデータ）
```rb:db/development/staff_members.rb(新規作成)
StaffMember.create!(
  email: "test@example.com",
  family_name: "テスト",
  given_name: "太郎",
  family_name_kana: "テスト",
  given_name_kana: "タロウ",
  password: "password",
  start_date: Date.today
)
```

## seedの実行

```terminal:データの投入
$ bin/rails db:seed
```

##### このコマンドは、db/schema.rbの内容を読み込んでデータベースの構造を作り直し、seedデータを投入する
```terminal:データの投入をやり直す
$ bin/rails db:reset
```

##### 指定した文字列をRailsアプリケーションの文脈で実行するコマンド。投入に成功していれば「1」が表示される
```terminal:正しくデータが投入されたか確認する
$ bin/rails r "puts StaffMember.count"
```

```terminal:属性の値を調べたい場合
$ bin/rails r "puts StaffMember.first.属性の値"
```
【ドラゴンボール風解説】Lambdaについて

# はじめに
この記事はAWSの説明は今ひとつよくわからないのでドラゴンボールに例えて説明してほしい。
というAWS初学者向けの記事です。
※投稿記事作成にはchatGPTを使用しております

# Lambda
オス、オラ悟空！Lambdaか！ドラゴンボールの世界では、界王神界に似てるかな？
界王神界って、神様や天使たちが住んでいる場所で、神様や天使たちは、地球や他の星に助けを求めるときに、界王神界にいる大神官に連絡を取るんだ。Lambdaも同じで、**アプリケーションが必要な処理を実行するとき**に、Lambdaに処理を依頼するんだ！

さらに、Lambdaは、界王神の神様たちが使う技「神の領域（かみのりょういき）」のように、**必要に応じて強力なリソースを割り当てることができる**んだ！たとえば、アプリケーションの**負荷が高いときは、自動的にリソースを増やして処理を高速化**することができるんだ！

ただし、界王神界には、界王神や大神官など、神様たちがいるように、LambdaもAWSのリソースを使って処理を実行するため、AWSアカウントが必要だぞ！また、Lambdaの**実行時間や使用したリソースに応じて課金**されるから、使いすぎには注意しよう！

オラも、界王神界で修行して、強くなった経験を活かして、Lambdaを使ってアプリケーションを効率的に処理していくんだ！強敵たち、オラにかかってこい！ワクワクしてきたぞ！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3304054/10c9f707-57fc-2dfc-0894-54ce61e5fadb.png)
ChatGPTで、パスワードをhash化するときに使われるsaltの由来を調べてみた！

![download.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/b5b16b76-bf19-5bf8-f54d-1049b9ee84b7.jpeg)

# Q、プログラミングで使われるsaltとはどういう意味ですか？
>A、"Salt"は、プログラミングのコンテキストでは、パスワードのハッシュ化に関連して使用されるランダムな文字列のことを指します。
パスワードを単純なハッシュ関数でハッシュ化すると、同じパスワードを使用するすべてのユーザーが同じハッシュ値を持ち、攻撃者が事前に計算したハッシュ値のリストを使用してパスワードを簡単に復元できるため、安全ではありません。
そこで、ハッシュ値を生成する前にランダムな文字列（salt）をパスワードに追加し、同じパスワードでも異なるハッシュ値が生成されるようにします。これにより、攻撃者はランダムな文字列を知らない限り、ハッシュ値を計算することができなくなります。
例えば、パスワードが「password」として、saltが「abcd1234」とすると、ハッシュ値を生成するためには、「passwordabcd1234」という文字列をハッシュ関数にかけます。同じパスワードを持つ他のユーザーは、異なるsaltが割り当てられ、異なるハッシュ値が生成されます。
このように、saltを使用することで、ハッシュ化されたパスワードをより安全に保ち、パスワードの漏洩や攻撃から保護することができます。

# Q、どうしてsaltと言うの？
>"Salt"は、パスワードのハッシュ化に使用されるランダムな文字列のことを指す用語で、元々は調味料の塩（salt）から由来しています。
塩（salt）は、食品を保存するために使われる防腐剤として長い間使用されてきました。同様に、パスワードのハッシュ化に使用されるランダムな文字列は、ハッシュ値を計算する前にパスワードに追加され、同じパスワードでも異なるハッシュ値を生成するために使用されます。このため、パスワードの安全性を向上させる防御策として、塩（salt）のように使用されることがあり、"Salt"という用語が使用されるようになったとされています。
GCFE攻略法

ChatGPTのレビューを受け、更新しました。

# はじめに
GCFEは、フォレンジック調査に関する出題が行われるGIACの試験です。
私が受験した時は、75問の四択問題（一部3択や5択あり）と7問のCyberLive問題を3時間で解答するというものでした。
出題範囲は各種アーティファクトの調査手法が中心です。レジストリ、LNKファイル、ブラウザ、USBデバイス接続といったフォレンジック調査で必要な調査手法に関して出題されます。

試験の時間、範囲詳細は以下のページをご参照ください。

https://www.giac.org/certifications/certified-forensic-examiner-gcfe/

よく似た名前の資格であるGCFAとの大きな違いは、GCFEが1台のマシンの調査に特化しているのに対し、GCFAは複数台を同時に調査する方法に特化している点です。一部の出題範囲がかぶっています。保全やイベントログの調査といった領域では同じものもありますが、基本的には全く別の試験です。フォレンジック調査を行うのであれば、両方取得しておくと良いと思います。

# 勉強方法
基本的には以下に記載している方法で問題ありません。
GCFE特有の注意点も特にありませんが、過去に受験したGPEN、GWAPT比べると英語が難しい気がしました。もしかするとペネトレーションテスト分野の試験のほうが英語は簡単になっているかもしれません。英語が苦手な方は模擬試験に出てきた英単語は調べておいたほうが良さそうです。

https://qiita.com/log0417/items/78f1e3136f508d54784d


また、私が参考にしたブログを紹介しておきます。基本的には私の勉強法と同じです。大事なポイントなので繰り返しますが、インデックスの作成は非常に重要です。

https://muchipopo.com/it/gcfe/

おそらく上記ブログの方は、GCFE試験にCyberLiveがないタイミングで受験されているのではないかと思いますので、CyberLiveについて触れておきます。

CyberLiveは仮想マシンを操作して回答する問題です。GCFE以外のGIAC試験と同じで、仮想マシンの中にあらかじめ用意されているデータを利用して回答します。当然ですがインターネットには接続されておらず、ググることはできません。
基本的には模試のCyberLive問題で慣れておけば問題ないかと思います。ツールの使い方は知っておく必要がありますが、問題そのものはそれほど難しくはないと思います。理解していれば1問5分以内で回答できるはずです。
ただ、GPENやGWAPTと比べて若干問題文の説明が少ないように思いました。GPENやGWAPTの方がより丁寧な説明が記載されており、あまり迷わない問題になっていました。いずれもツールに慣れておく、見るべきレジストリキーなどを知っておくことで十分対策可能な範囲ですが、個人的に若干戸惑いました。

なお、フォレンジックの場合は処理に時間がかかるツールがありますが、こういったツールの場合は予め処理済みのデータが用意されていますので、何分も待つ必要はありません。したがって、処理に時間がかかることを懸念した時間配分は不要です。
私はCyberLiveとスキップした問題の回答で1時間、残りの2時間で75問を回答するというペース配分を予定していました。

また、CyberLiveはVMを初期状態にリセットできますが、GCFEにおいてはこの機能は基本的に使わない方が良いと思います。ペネトレ系の試験ではリセットした方が良いケースもありますが、フォレンジックの場合はリセットしなければ回答できないといったことには通常ならないと思います。色々なツールを起動してごちゃごちゃしてきたという場合はリセットしても良いかもしれません。なお、リセットした場合は次の問題に進んだ時点で試験時間が2分延長されますが、リセット自体に1分程度かかりますので、試験時間の延長を目的としたリセットはほぼ意味がないでしょう。

# 試験本番
こちらもいつもどおりで、朝一に受験する、睡眠、朝食はしっかり摂る、試験室のPCの前に座ったら10秒瞑想してから開始です。
本番では思いの外スキップした問題が多く、CyberLive到達時点で残り時間は1時間以上ありましたが、CyberLiveの問題で思ったより苦戦してしまい、CyberLiveも一部スキップしました。
最終回答は残り15分で、思ったよりギリギリまでかかってしまいました。これは単純な見落としが原因でしたので、受験される方はケアレスミスにご注意ください。

# 感想
完走した感想ですが、これまでフォレンジック調査を数多くやっていたので、基本的に出題される問題は概ね問題なく回答できました。今回も休憩なしで突破しましたが、やはり最後の方は疲れがあるせいか、CyberLiveでケアレスミスで時間を浪費することがありました。CyberLiveに入る前くらいには一度休憩をとった方が良いと思います。

ちなみに、模試の1回目は73%、2回目は79%と思ったほど得点できず、実は少々不安でした。しかし本番に強いのか、本番では89%（合格後のメールによると88.57%）得点できました。

全体的にこれからフォレンジック調査を始めるという方も、すでに数多くやっているという方にもオススメできる良問の試験でした。
ただ、英語はやや難しいと感じたため、いつも通り試験後のアンケートには英語が難しい旨を書いておきました。

# 次の目標
特に決めていませんが、またGIACにチャレンジできるといいなと思います。
【Laravel9】Laravel Mixを使用しているプロジェクトでBreezeをインストールすると、js・css共に反映されない問題


> 需要があるかどうかは分かりませんが、あくまで自分用のメモとして残しておきます。

# どういうこと？
個人的に`Laravel Mix(webpack)`を使用してLaravelプロジェクト開発の練習を行っていた際、認証機能の実装を全部手動で行うのが手間だった為、`Laravel Breeze`に丸投げしてしまおうと思いインストールしたら、`js`も`css`も反映されなかった。

# インストールの手順は？
公式のドキュメント通りにインストール。
```
composer require laravel/breeze --dev
```
```
php artisan breeze:install

php artisan migrate
npm install
npm run dev
```

# インストール後の状態は？
`welcome.blade.php`のページは問題ないが、認証関連のページが軒並み全滅。

# 原因は？
ドキュメントの通りインストールすると、`vite`を使用するようにページが生成されてしまうのが原因の模様。
現プロジェクトは`laravel mix`を使用しているため`vite`が動かず、結果生成された認証関連の`blade`ファイルに反映されなくなってしまっていた。

※各種`blade`ファイルの`js` `css`の読み込みが以下のような記述だと、`laravel mix`環境では反映されない
```
@vite(['resources/css/app.css', 'resources/js/app.js'])
```

# 解決方法は？
単純に、上記の記述を書き換えればOK。
```
@vite(['resources/css/app.css', 'resources/js/app.js']) ← 削除
↓
<link href="{{ mix('css/app.css') }}" rel="stylesheet"> ← 追加
<script src="{{ mix('js/app.js') }}"></script> ← 追加
```

## 【補足】`@vite`の記述が確認できたファイル

`resources/views/layouts/guest.blade.php`
`resources/views/layouts/app.blade.php`
Railsのコントローラーについて

## コントローラーとは
**コントローラー**は、モデルやビューを制御するためのオブジェクトである。
リクエストに応じてルーターから呼び出されれ、リクエストの内容をもとに、決められたアクション内の処理を実行する。
モデルからデータを取得し、ビューで描画するためのデータを準備するなど、アプリケーションの機能を実装し、クライアントへ結果をレスポンスとして返信する。

### コントローラーとREST
**REST**(Representional State Transfer)とは、Webアプリケーションのアーキテクチャスタイルの1つで、Web上での情報交換をするための仕組みである。
RESTは、HTTPプロトコルに基づいて、Webリソースを操作するための一般的なルールを定めており、URI、HTTPインタフェース（GET、POST、PUT、PATCH、DELETEなど）を使用してリソースを表現する。

ルーターという窓口を通して要求内容を受け取り、呼び出されたアクションを実行するのがコントローラーの役割である。コントローラーは、HTTPリクエストやHTTPレスポンスの情報を制御するとともに、Railsにおける、モデルを中心としたリソースのやりとりを制御している。

### コントローラーの仕組み
コントローラークラスは基本的に次のような構成で生成される、
```ruby
class コントローラー名　< ApplicationContoroller
  def アクション名
    処理内容
  end
end
```
コントローラー名は基本的に複数形にする。ルーティングでコントローラーの任意のアクションが指定された時実行する処理をアクション内に記述する。

### パラメーター
パラメーターの値を参照するには**params**インスタンスを使用する。アクションが実行されたタイミングでparamsインスタンスを利用することで、取得した各パラメーターの値をハッシュ値として取り出すことができる。

paramsの要素の取得は`params[:user]`、または`params["user"]`のように記述する。また、ルートで設定されるidなどのルートパラメーターは、`params[:id]`のように参照・取得できる。

#### ストロングパラメーター
**ストロングパラメーター**は、セキュリティの脆弱性を回避するための仕組みである。

具体的には、通常のパラメーターとは異なり、特定のパラメーターのみを許可し、その他のパラメーターを無視するように設定できる。

例として、ユーザー情報の新規登録について考える。

受信した新規ユーザーのデータは、`params[:user]`で取得することができる。この情報をもとに、次のように新規ユーザーをインスタンス化する。
```ruby
User.new(params[:user])
```
パラメーターの許可処理を行っていないため、例外エラーが発生してしまう。

Railsでは、データの保存処理を行うために、保存対象となる属性値を含むパラメーターに対して許可処理を行う必要がある。

<br>

requireメソッドは指定されたパラメーターを要求する。
`require(指定されたキーのパラメーター)`
permitメソッドは指定されたパラメーターを許可する。
`permit(許可パラメーター)`
次のようなコードの場合、リクエストパラメーターに`:user`が含まれていない場合例外が発生し、`:name, :email, :password, :password_confirmation`以外のパラメーターは無視される。
```ruby
private
  def user_params
    params.require(:user).permit(:name, :email, :password, :password_confirmation)
  end
```
### セッション情報とクッキーの利用
クライアントとサーバーがやり取りした後、情報を保持しない仕組みを**ステートレス**という。ストートレスなWebアプリケーションは不都合なことが多々あり、例えば、一度ログインしても、その情報が消えて、他のアクションをした時にまたログイン要求をされてしまう。

HTTPは、クライアントとWebサーバーのやりとりを行う際、はじめにブラウザとWebサーバー間で接続関係(**HTTPセッション**)を確立する。HTTPセッションを利用して、クライアントの状態を維持することができる。

* セッション情報への値の保存
Railsではセッション情報をsessionパラメーターとしてコントローラーおよびビュー内で使用することができる。`session[キー]　＝ 値`のように保存する。

* セッション情報の読み込み
保存したセッション情報を読み込む場合は、sessionに対してキーを指定する。ユーザー情報の@user
インスタンスにセッション情報を読み込む場合、`@user = session[:user]`のように読み込むことができる。

このように、1回のやりとりで消えてしまう情報を、保存・読み込みし、アクション間にわたって最低限必要な情報を連携させることができる。

#### セッションストア
アクション内で生成したセッション情報は、次のリクエストに連携するために裏でセッションにひも付けて保存し、必要な時ににセッション情報として呼び出せるように管理する必要がある。

セッション情報を保存する場所を**セッションストア**という。セッション情報は、デフォルトで**クッキー**(ブラウザに保存される情報)に保持されるため、デフォルトのセッションストアは**クッキーストア**と呼ばれる。
基本类型使用

# 基本类型使用
# hashmap 使用
1 使用 use std::collections::HashMap;

2新建哈希map

let mut scores = hashmap::new()

3 插入值

scores.insert(key,value)

4 只有建没有值下插入值

scores.entry(key).or\_insert(value)

5 覆盖值

scores.insert(key,value)

6 获取map的值

onwerkey = String::from(key)

scores.get(&onwerkey)



hasher 是一个实现了 `BuildHasher` trait



# STRING的使用
字符串是 UTF-8 编码的，所以可以包含任何正确编码的数据

1新建字符串

let mut s = String::new();

2  存储

let hello = String::from("你好");

3 更新字符串

let mut s = String::from("foo")

方法1 s.pust\_str("bar") 能push多个字符串 

方法2 　s.push("a") 只能push单个字符串

４　使用 +号进行拼接字符串

let s1 = String::from("Hello, "); let s2 = String::from("world!"); let s3 = s1 + &s2; // 注意 s1 被移动了，不能继续使用

首先，`s2` 使用了 `&`，意味着我们使用第二个字符串的 **引用** 与第一个字符串相加。这是因为 `add` 函数的 `s` 参数：只能将 `&str` 和 `String` 相加，不能将两个 `String` 值相加。不过等一下 —— 正如 `add` 的第二个参数所指定的，`&s2` 的类型是 `&String` 而不是 `&str`。那么为什么示例 8-18 还能编译呢？

之所以能够在 `add` 调用中使用 `&s2` 是因为 `&String` 可以被 **强转**（\_coerced\_）成 `&str`。当 `add` 函数被调用时，Rust 使用了一个被称为 **解引用强制转换**（\_deref coercion\_）的技术，你可以将其理解为它把 `&s2` 变成了 `&s2[..]`。第 15 章会更深入的讨论解引用强制转换。因为 `add` 没有获取参数的所有权，所以 `s2` 在这个操作后仍然是有效的 `String`。

其次，可以发现签名中 `add` 获取了 `self` 的所有权，因为 `self` **没有** 使用 `&`。这意味着示例 8-18 中的 `s1` 的所有权将被移动到 `add` 调用中，之后就不再有效。虽然 `let s3 = s1 + &s2;` 看起来就像它会复制两个字符串并创建一个新的字符串，而实际上这个语句会获取 `s1` 的所有权，附加上从 `s2` 中拷贝的内容，并返回结果的所有权。换句话说，它看起来好像生成了很多拷贝，不过实际上并没有：这个实现比拷贝要更高效。

5 使用format进行拼接字符串

let ss = format!("{}-{}-{}",s1,s2,data);

6 内部表现

string是一个vec<u8>的封装

7 遍历字符串的方法



```rust
//需要操作单独的 Unicode 标量值
for c in "aa".chars() {
    println!("{}",c);
}
//bytes 方法返回每一个原始字节，这可能会适合你的使用场景
for b in "नमस्ते".bytes() {
    println!("{}", b);
}
```


# * vector的使用
1 新建vec

```rust
let v: Vec<i32> = Vec::new();
```
2 更新vector

```rust
let mut v = Vec::new();
v.push(5);
v.push(6)
//无法使用println察看
```
3 [读取 vector 的元素](https://rustwiki.org/zh-CN/book/ch08-01-vectors.html#%E8%AF%BB%E5%8F%96-vector-%E7%9A%84%E5%85%83%E7%B4%A0)

```rust
let v = vec![1,2,3,4,5,6];
    let third: &i32 = &v[2];
    println!("third element is {}",third);
    match v.get(2) {
        Some(third) => println!("the third element is {}",third),
        None => println!("there is no third element"),
    }
```


4 遍历vector中的元素

```rust
let mut v = vec![100,2,33];
    for i in &mut v {
        // 遍历需要 &v
        println!("{}",i);
        *i += 50;
        //如果需要修改，需要mut
        println!("L2 is {}",i);
    }
```


5 使用枚举来存储多种类型

```rust
enum SpreadsheetCell{
    Int(i32),
    Float(f64),
    Text(String),
}

let row = vec![
    SpreadsheetCell::Int(3),
];
```
MySQLでテーブルデータの一部をSQLで移管する

# 概要
特に外向けに難しいことを発信しようとしたわけでもなく、今後もたまに使いそうだと思った備忘、そのいくつか。

# やりたいこと

table1 → table1_extendに一部データを移管（insert）したいが、わざわざスクリプトを組むのは面倒なので、SQL一発でやりたい。定期的な同期については今回は考えない（ホントはtriggerとかでやるんでしょうね。

# 対象テーブルの構造

```
table1
+--------------+-------------+
| Column       | Type        |
+--------------+-------------+
| table1_id    | INT         |
| table1column1| (data_type) |
| table1column2| (data_type) |
| table1column3| (data_type) |
+--------------+-------------+

table1_extend
+------------------+-------------+
| Column           | Type        |
+------------------+-------------+
| table1_id        | INT         |
| table_ext_column | VARCHAR(255)|
+------------------+-------------+

```

# 流したSQL

あくまで手法の紹介なので、果たして本当にこんなふうに移管をしたいシーンが有るかどうかはさておき、これでtable1 → table1_extendへのデータ登録ができます。

```sql
INSERT INTO table1_extended (table1_id, table_ext_column)
SELECT
  table1_id,
  CONCAT(
    COALESCE(table1column1, ''),
    COALESCE(table1column2, ''),
    COALESCE(table1column3, '')
  )
FROM
  table1;
```

# おわり

雑にデータをガバッと入れたいときぐらいにしか使えませんが、プロトタイプつくったりとか、検証用に立てた環境を使いやすくしたいときとかには便利かもしれませんね。
【プリキュア20周年】プリキュアデータベース（非公式）をリリース

## はじめに
この度、プリキュアを一覧で見られるサイトを作成してみました。

https://precure-database.vercel.app

理由としては、プリキュア20周年にも関わらず、プリキュアを一覧で見られるサイトがありません。今現在どんなプリキュアがいるんだろうって思っても、集合絵ぐらいしか全員を見れるものがありません。

https://anime-precure.com/


プリキュアシリーズ公式ポータル（旧プリキュアガーデン）もありますが、こちらはシリーズを一覧で見られますが、プリキュアを一覧で見られません。

そこで、先日GraphQLを使って作ったAPI、[Graph PreQL](https://graph-preql.vercel.app)をリリースしました。

https://qiita.com/mu_tomoya/items/9c86170e20ad2546b2f4

ただ、これだけだとGraphQLにある程度理解のある人しか使うことができません。

そこで、このGraph PreQLを自分の扱いやすいように改造を繰り返して、様々なデータを追加しました。

※権利関係は全く通していないただのファンサイトなので、著作者に指摘されたらすぐに閉鎖します。

## 使い方
![precure-database1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267174/03476094-8b12-2cad-b04e-e18b89299559.png)
「プリキュアを検索」のページに入ると、まずはプリキュアが一覧で出てきます。
そこから好きなプリキュアのページに入ると、そのプリキュアのキャラクター紹介ページに飛べます。
キャラクター名から誕生日、パートナー妖精、声優、必殺技、そして東映アニメーション公式Youtubeで公開されている各プリキュアの変身シーンも埋め込みで載せています。変身シーンも載せたいがために、毎日プリキュアの変身シーンがアップされるたびにYoutubeのidをGraphPreQLのほうに追記しました。youtube_idさえあればサムネイル画像も取ってこれたり、うまくURLくっつければ動画の埋め込みをループで回せたりするので便利なんですね。
その他こだわっている点としては、そのプリキュアのカラーごとに所々色を変えているところです。キャラ名だったり。

![cure_sword.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267174/4cf1d158-68a4-360f-0273-a7e9cae9d9ad.png)

また、一覧ページで選択タブをクリックすると、それぞれ詳細に条件を絞れ込めます。出演シリーズで絞り込めたり、色で絞り込めたり、指定した日より前、後に出てきたプリキュア（放送日基準）で絞り込めたりします。

## 技術的に頑張ったところ
フロントエンドは<b>Next.js</b>、ホスティングは<b>Vercel</b>を使い、CSSはすべて<b>TailwindCSS</b>を使っています。技術選定としては、個人開発なのでお金をかけたくないので、Vercelでホスティングをしています。Graph PreQLもデータはすべて静的なjsonのため、一切データベースを使っていないため費用はかかっていません。

ほとんどがデータをそのまま引っ張ってくるだけなので、普通のREST APIでも全然大丈夫なんですが、GraphQLの技術を使ってみたいと思い、今回はGraphQLを使いました。

そしてGraphQLクライアントとして、<b>Apollo</b>を使っています。ほんとに便利で、SSGでもSSRでもCSRでもどれでも簡単にGraphQLサーバーと接続してクエリを投げてデータを取ってこれます。そしてキャッシュまでしてくれるので、わざわざSWRなどほかのキャッシュが得意なライブラリを使わなくても済みます。

プリキュア検索ページでは、動的にデータを取ってきたいため、CSRとして使っています。
各キャラクターの個別ページに関しては、ユーザーによって見せるデータが変わることはないのでSSGで静的生成しています。

各個別ページにいって戻るをするたびに、直前の検索結果が初期化されると不便だと思い、どのタブのどの値を選択したかを、Contextで状態管理できるようにしました。これで戻ってきても同じデータが見られるようになりました。

デザインに関しても、[なぜエンジニアが作る画面はダサいのか…?「理由」と「対策」を徹底解説【エンジニア向け画面デザイン講座】](https://qiita.com/mskmiki/items/544149987475719e417b)を参考に、しかもプリキュアというとてもかわいくてかっこいい、デザインにあふれた世界観なのでただのデータの羅列にしたくないと思い、例えばキャラ名をグラデーションにしたり、リストをハートマークにしたり、なるべく画面から角を取り除き、丸みのあるデザインにしたり、スマホから見ても見やすいようにしたりデザインを整えました。

画像はなるべく軽量化をするために、WebPに全部変換しました。

## 最後に
今年でプリキュア20周年なので、プリキュアで育った自分としてはまだまだプリキュアを使ってエンジニア的な部分で盛り上げていきたいと思います。
今後もこのプリキュアデータベースはシリーズだったり映画だったりの情報も追加していけたらなと思っています。
Graph PreQLのほうも、APIとしてとても使いやすいものになっていると思うので、こちらとともにぜひ使ってみてください。
<b>明日はついに、キュアウィングが変身！</b>
Railsのデータベースのdropからseedまでを一瞬でやりたい

railsの初期値(seedの内容)を変更して作り直す場合、一度データベースをdropしてseedを実行し直す必要がある。
開発初期など実験や試行錯誤している段階では頻繁に多用するかと思うので、上記作業を一瞬で行うコマンドをメモしておきます。

#### drop, create, migrateを一括で行う
```
rails db:migrate:reset
```
#### seedを実行
```
rails db:seed
```

以上！！
PowerShellログ出力における考察

https://guitarrapc-tech.hatenablog.com/entry/2014/01/17/073338#HostUI-%E3%81%AB%E3%82%88%E3%82%8B%E5%8D%98%E7%B4%94%E3%81%AA%E5%87%BA%E5%8A%9B

https://memo-log.9999ch.com/2019/03/30/2280

https://www.vwnet.jp/windows/PowerShell/ExecuteLog.htm
勉強メモ123_visudoコマンドで「visudo: /etc/sudoers がビジー状態です。後で再試行してください」のエラーが出た場合

## visuoコマンド実行
```terminal
[root@localhost ~]# visudo
visudo: /etc/sudoers がビジー状態です。後で再試行してください
```

## psコマンドで出てくるvisudoのプロセスを確認し、プロセスIDを指定してkillコマンド実行
```terminal
[root@localhost ~]# ps aux | grep visudo
root      8518  0.0  0.1 119264  1036 pts/4    S+   12:08   0:00 visudo
root      8603  0.0  0.0 112824   980 pts/5    S+   12:27   0:00 grep --color=auto visudo
[root@localhost ~]# kill 8518
```
## 再度、visudo実行、エラーが出なくなるのを確認
```terminal
[root@localhost ~]# visudo
visudo: /etc/sudoers.tmp は変更されません
```