OmniAICreator/Qiita-1.07M huggingface dataset:
VMD起動時の設定を変更する


#はじめに
本記事では、分子可視化ソフトであるVMDの起動時の設定を変更する方法について解説する

ちなみに、VMDについては以下の記事も書いたので参考にしてください。

https://qiita.com/tacoma/items/42040d8548840a291833

#解説
LinuxとWindowsでファイル名などが微妙に異なるため、分けて解説する

##Linuxの場合
* ./.vmdrc（つまり現在のディレクトリに'.vmdrc'を置いておく）
* $HOME/.vmdrc（自分のホームディレクトリに'.vmdrc'を置いておく） 
* あるいは $VMDDIR/.vmdrc(VMDのインストールディレクトリに.vmdrcを置いておく)

の３つのやり方がある。
ちなみに３つのディレクトリは上に行くほど優先順位が高くなる。

最も手っ取り早いのは、自分のホームディレクトリに'.vmdrc'を置いておくことである。


##Windowsの場合
* ./vmd.rc（つまり現在のディレクトリに'.vmdrc'を置いておく）
* $HOME/vmd.rc（自分のホームディレクトリに'.vmdrc'を置いておく） 
* あるいは $VMDDIR/vmd.rc(VMDのインストールディレクトリに.vmdrcを置いておく)

上の方が優先されるのはWindowsでも同じ

ただし、$HOMEに関しては、Windowsだとホームディレクトリに置くだけだと認識されず、
$HOMEの環境変数を設定する必要があるので少し面倒。

なので、手っ取り早くやりたければ、$VMDDIRにvmd.rcを置くのが良い。

$VMDDIRはインストール時に変更していなければ"C:\Program Files (x86)\University of Illinois\VMD"
基本的に既にvmd.rcが存在しており、それを書き換えていけばよい。
ただし、書き換えに管理者権限が必要となるので、面倒くさければVMDのインストールを自分のホームディレクトリの配下などにすると楽かもしれない。

## .vmdrcあるいはvmd.rcの中身
VMDを開いた状態で、Main WindowからFile→Log Tcl Commands to Consoleを選択すると、自分が行った操作のTclコマンドをコンソールに吐き出してくれるので、それを.vmdrcに書き込んでいけばよい

例えば、以下のようにする

```tcl
#main,graphics画面を表示
menu main on
menu graphics on
#画面の位置を調整
menu main move 5 225
menu graphics move 395 30
#軸の表示を消す
axes location Off
#PerspectiveではなくOrthographicに
display projection Orthographic
#Depth Cueingを切る
display depthcue off
#背景を白にする
color Display Background white
```

これにより、軸も表示されず、白い背景で起動する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/788299/c4060beb-5da7-cc1c-fbae-cd46aab080a7.png)




#参考情報
https://www.ks.uiuc.edu/Research/vmd/vmd-1.7.1/ug/node197.html
迷ったときに立ち返る HTML, JavaScript, CSS 概論

# 前段 

 * 新人向けのナレッジを HTML, CSS をテーマで書いてみよう、ということなのでおじさん得意の苦労話や昔話でもと思ったのですが、まずは反応を探るためにも概論的な話を書いてみます。

 * まずはざっくり書きますので、詳しくは自分で調べるなり、後述するようにコメント残してもらえたらと思います。

 * HTML, CSS, JavaScript でこういうの知りたいとかありましたらコメントで残しておいてもらえると、次書く際の材料にしますので、よろしくお願いします。

# リクエストとレスポンス
![68747470733a2f2f696d672e6573612e696f2f75706c6f6164732f70726f64756374696f6e2f6174746163686d656e74732f31323939352f323031392f30382f32362f36313634392f61376536653162662d666661332d343335322d623136372d3065363232.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1367663/aa12c741-0edc-3e2a-6652-d386057c3cd0.png)

 * Web上で動くシステムはだいたいこの絵で説明できます。

 * クライアント(Webブラウザ)からリクエストをサーバ(Webサーバ, アプリケーションサーバ(以下、APサーバ))に投げて、レスポンスを取得することで Webシステムは成り立っています。

 * サーバ ～ クライアント間のリクエストとレスポンスのやりとりは HTTP というプロトコル(お約束)で決められています。

  * HTTPS (暗号化通信) を使っていない限り、通信の中身は wireshark や tcpdump にてパケットキャプチャすることで確認することができます。興味がある方は一度試してみることをお勧めします。

# さらにリクエストとレスポンス
![68747470733a2f2f696d672e6573612e696f2f75706c6f6164732f70726f64756374696f6e2f6174746163686d656e74732f31323939352f323031392f30382f32372f36313634392f64316361353462302d633066662d343834652d623936332d6663393066.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1367663/27f7870a-a0b3-da63-eab9-156c3eba4d24.png)

 * リクエストとして Web サーバに URL やリクエストメソッド(GET や POST)を投げて、レスポンスとして HTML や CSS, JavaScript を取得し、クライアント(Webブラウザ) にてそれらを解釈し表示します。
   * **HTML, CSS, JavaScript が実行されるのはサーバではなく Webブラウザ上です。ここ大事。**

 * レスポンスとして取得する(主に)HTMLは静的なファイルだけではなく、サーバ側で動的に生成されることもあります。 PHP や JSP, Servlet はサーバ側で HTML を生成しレスポンスとして返します。
   * **PHP や JSP が実行されるのはサーバ側です。これも大事。**

 * 最近はイチからコードを書き始めることは少なく、フレームワーク上で Web システムを作成することが多いですが、どのコードがどこで実行されているのかの意識は常に持つようにしておいてください。慣れないうちは自分が作ったシステムでないとどこで何が実行されているのか迷子になりやすいです。

# リクエスト/レスポンスにおける同期と非同期
 * リクエストを投げて、レスポンスが帰ってくるまで処理を待つのが同期通信。 リクエストを投げた後、レスポンスを待たずに処理を継続し、あらかじめ登録された関数でレスポンスを取得するのが非同期通信。
   * 非同期通信を JavaScript と XML で実現したのが Ajax。
   * 非同期通信は画面遷移なしでレスポンスを取得することができる。この技術によりいまどきの Webシステムが実現された。 非同期通信が実現する前の Webシステムは盛大な紙芝居。

 * 前述のサーバ側にて動的生成されたレスポンスの取得は同期処理になります。
 *  リクエスト/レスポンス以外でもネットワーク上でのサービスを扱うと同期処理、非同期処理の話はいろいろな所で出てきます。慣れないうちは扱っている処理が同期処理なのか、非同期処理なのか考えながら見てみると訓練になるのでやってみてください。

# サーバとクライアント

 * そういえばたいした説明もなしにサーバ、クライアントを記載していたので最後に触れておきます。リクエストを投げてレスポンスを受け取るのがクライアント、リクエストを受け付けてレスポンスを返すのがサーバになります。
   * クライアントからの要求がなければサーバの仕事は基本ないです。(バッチ処理等もありますが、バッチ実行プロセスがクライアントだと思えば ...)
 * Webシステムではなく、クライアントPC上で動くアプリケーションと DBサーバ、APサーバで構成されているシステムをクライアント・サーバシステム(略してクラサバと言われることが多い)と呼ばれますが、これも基本的に上記のリクエスト、レスポンスと同じです。何をリクエストして、何がレスポンスとして戻ってくるかの違いです。

# 後段 
 * "迷ったときに立ち返る HTML, JavaScript, CSS 概論" とタイトルをつけたものの、ほぼ HTTP の話に終始してしまいました ...

 * JavaScript や CSS, REST API でも概論一本書けそうな気もするので、そのうち続編書くかもしれません。

# 余談

 * わからないことはだいたい google で解決しますが、それでも解決しないときはキーワードの作り方を疑ってください。ただし、キーワードの作り方は経験と想像力が必要なので、それらを磨く訓練は技術者として生き続ける限り磨き続けてください。
 * また、google や技術系サイトに慣れると自分が探していない情報以外辿り着けなくなってくるので、新聞や雑誌もまだまだ捨てたものではないですよ。
 * 周りの先輩方に聞くのも問題解決に役に立ちます。教わった知識は周りや後輩にも分かち合うようにしましょう。
改行をすべて消すだけのコード

# 動機

PDFからコピペして翻訳しようとすると、改行が邪魔。

https://www.deepl.com/en/translator


# できたもの
貼り付けた瞬間に、以下の状態で改めてクリップボードにコピーします。
- 改行を半角スペースに変えた状態（ヨーロッパ言語への対応）
- 半角スペースが２つ続いている場合は、１つだけにした状態

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447423/707997a9-9416-7b0f-fe64-f678f8f76ce0.png)

PyInstallerとかで使える状態にしてください。

```Python
import sys

import pyperclip
from PyQt5.QtWidgets import QApplication, QMainWindow, QPlainTextEdit

class Window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        width = 250
        height = 100
        self.setFixedSize(width, height)
        self.setWindowTitle('\\n deleter')

        self.textBox = QPlainTextEdit(self)
        self.textBox.textChanged.connect(self.copy_sentence)
        self.textBox.resize(width, height)
        self.textBox.setPlaceholderText ('Paste your sentence here.')

        self.show()

    def copy_sentence(self):
        sentence = self.textBox.toPlainText()
        no_n_sentence = sentence.replace('\n',' ')
        no_double_space = no_n_sentence.replace('  ', ' ')
        pyperclip.copy(no_double_space)
        self.statusBar().showMessage('Copied!', msecs=3000)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Window()
    sys.exit(app.exec_())
    
    

```
[Nuxt]vuex-persistedstateで、LocalStorageを参照するときとしないときがある場合の解決法

###起こったこと
vuex-persistedstateで、pageなどから「$store.state.module名.state名」のようにstateを訪問するとLocalstorageを参照するが、VuexのmoduleAから「rootState.moduleB.state名」のように訪問すると初期値（0だったりnullだったり...）を参照してしまう。結局5時間溶かした。

###解決法
pluginの順番を直したら正しくLocalStorageを参照するようになった。自分の場合はSPAモード（つまりssr:false）で初期処理を行うために用意した「init.js」というpluginを一番前においていた。
（こんなかんじ↓）
plugins: [
"~/plugins/init.js"
"~/plugins/firebase.js",
"~/plugins/persistedstate.js",
・・・・・・
  ],
そしてpluginは基本的に上から順番に実行されるのでpersistedstate.jsが実行される前にinit.jsが実行されていることになり、不具合が起きたようだ（自信なし）。
初期処理だから一番前に置くべきという意見もあるがその初期処理に必要なpluginがあるならそっちのほうを先に実行させるべきなのだろう。
C# ~シミュレーション~ Cランクレベルアップメニュー

現在働いている会社ではシステムエンジニア研修の１つに「paizaBランク問題をクリア」があるのでその目標を達成するまでの過程を備忘録として残します。

業務に参加した際に記述方法を忘れてしまっているであろう未来の自分に向けて、メモを残すと同時にこの記事がC#を学習している方、同じ箇所で躓いている方の参考になればと思っています。
ですので内容に誤りがある場合やより良い記述をご存知の方はコメントで共有していただけると嬉しいです。

それでは本編に入ります。
今回はPaizaラーニング、レベルアップ問題集「シミュレーション」の問題をC#で回答したときの内容になります。


## STEP: 1 辞書の基本
問題文:https://paiza.jp/works/mondai/c_rank_level_up_problems/c_rank_simulation_step1

```c#:paiza.cs
using System;
class Program
{
    static void Main()
    {
        int NaturalNumber = 0;
        for(var i = 10000; i < 10013; i++)
        {
            NaturalNumber = i;
            if(NaturalNumber % 13 == 0)
            {
                Console.WriteLine(i);
            }
        }
    }
}
```

## STEP: 2 シミュレーションの練習
問題文:https://paiza.jp/works/mondai/c_rank_level_up_problems/c_rank_simulation_step2

```c#:paiza.cs
using System;
class Program
{
    static void Main()
    {
        int MAX_NUM = int.Parse(Console.ReadLine());
        var aA_B = Console.ReadLine().Split(' ');
        int A = int.Parse(aA_B[0]);
        int B = int.Parse(aA_B[1]);
        int paizaNUM = 1;
        int kirishimaNUM = 1;
        
        for(int i = 1; i <= 10000; i++)
        {
            kirishimaNUM += paizaNUM * A;
            if(MAX_NUM < kirishimaNUM)
            {
                Console.Write(i);
                i = 10001;
            }
            paizaNUM += kirishimaNUM % B;
        }
    }
}
```

## FINAL問題 シミュレーション
問題文:https://paiza.jp/works/mondai/c_rank_level_up_problems/c_rank_simulation_boss
メソッドを分離して記述する必要があったので記述方法に少し苦戦しました。

```c#:paiza.cs
using System;
class Program
{
    public int iAttackCount = 0;
    public int MyAttackDamage = 0;
    public int EnnemyAttackDamage = 0;
    public int MyAttack(int iAttackCount)
    {
        if(iAttackCount <= 2){
            MyAttackDamage = 1;
        }
        else
        {
            MyAttackDamage = EnnemyAttack(iAttackCount - 1) + EnnemyAttack(iAttackCount - 2);
        }
        return MyAttackDamage;
    }
    public int EnnemyAttack(int iAttackCount)
    {
        if(iAttackCount <= 2){
            EnnemyAttackDamage = 1;
        }
        else
        {
            EnnemyAttackDamage = MyAttack(iAttackCount - 1) * 2 + MyAttack(iAttackCount - 2);
        }
        return EnnemyAttackDamage;
    }
    
    static void Main()
    {
        bool bHPFlag = true;
        int MY_HP = int.Parse(Console.ReadLine());
        Program obj = new Program();
        while (bHPFlag) 
        {
            obj.iAttackCount++;
            obj.MyAttack(obj.iAttackCount);
            obj.EnnemyAttack(obj.iAttackCount);
            MY_HP -= obj.EnnemyAttackDamage;
            if(MY_HP <= 0)
            {
                bHPFlag = false;
            }
        }
        Console.WriteLine(obj.iAttackCount);
        
    }
}
```
PHPの基本操作① 「簡単な出力と構文、配列、連想配列、少数、フォーマット」

##参考書籍
よくわかるPHPの教科書 PHP7対応版

##他記事リンク
- [PHPの基本操作①<br>「簡単な出力と構文、配列、連想配列、少数、フォーマット」](https://qiita.com/kunrenyouAcount/items/7a3bb6e5769ba94a7dc5)

- [PHPの基本操作②<br>「ファイルの読み込み、ファイルの書き込み、XMLの読み込み、JSONの読み込み」](https://qiita.com/kunrenyouAcount/items/bec393cae5901e32ec70)

- [PHPの基本操作③<br>「入力欄、ラジオボタン、チェックボックス」](https://qiita.com/kunrenyouAcount/items/1c66ccee97c33f320fb2)

- [PHPの基本操作④<br>「数字かどうかの判定、正規表現、別ページにジャンプ」](https://qiita.com/kunrenyouAcount/items/5b292d8481a76386fd1e)

- [PHPの基本操作⑤<br>「クッキーとセッションの保存と取得」](https://qiita.com/kunrenyouAcount/items/7324fad1d3d1845de075)

- [PHPの基本操作⑥<br>「電子メールの送信」](https://qiita.com/kunrenyouAcount/items/2172f03af0d8d8a32cc6)

- [PHPの基本操作⑦<br>「ファイルアップロードの受信をする」](https://qiita.com/kunrenyouAcount/items/dece31f962472fb23610)



##文章を表示
print関数を使用して出力する

```php:文章を表示
<?php
  print('一番簡単な出力です');
?>
```

##現在時刻
date関数を使用して出力する
※date_dafult_timezone_setでタイムゾーン(どこの国の時刻か)を設定する

- 時間 → G時
- 分 → i分
- 秒 → s秒
- タイムゾーン → Asia/Tokyo

```php:現在時刻
<?php
  date_default_timezone_set('Asia/Tokyo');
  print(date('G時 i分 s秒'));
?>  
```

##繰り返し(for)
for(初期値; 条件式; 処理後に実行される処理)で条件を満たす場合、繰り返し{}内の処理を実行します。

```php:繰り返し(for)
<?php
  for($i = 1; $i <= 365; $i++){
    print($i . "\n");
  }
?>
```

##繰り返し(while)
while(条件式)で条件を満たす場合、繰り返し{}内の処理を実行します

```php:繰り返し(while)
<?php
  $i = 1;
  while ($i <= 365) {
    print($i . "\n");
    $i++;
  }
?>
```

##一年後までのカレンダー

```php:一年後までのカレンダー
<?php
  for($i = 1; $i <= 365; $i++) {
    $day = date('n/j(D)', strtotime('+' . $i . 'day'));
    print($day . "\n");
  }
?>
```

##配列を使う
「曜日」を取得 → date('w')

```php:配列を使う
<?php
  $week_name = ['日', '月', '火', '水', '木', '金', '土'];
  print('今日は' . $week_name[date('w')] . '曜日です');
?>
```

##連想配列を使う
キーを使って、値を取り出す。

```php:連想配列を使う
<?php
  $fruits = [
    'apple' => 'りんご',
    'grape' => 'ぶどう',
    'lemon' => 'レモン',
    'tomato' => 'トマト',
    'peach' => 'もも'
  ];

  foreach ($fruits as $english => $japanese) {
    print($english . ' : ' . $japanese . "\n");
  }
?>
```

##条件分岐
()内の条件に対して「真偽」を判定し、処理を実行します

```php:条件分岐
<?php
  date_default_timezone_set('Asia/Tokyo');
  if(date('G') < 9) {
    print('※ 現在受付時間外です');
  } else {
    print('ようこそ');
  }
?>
```

##少数の切り捨て、四捨五入、切り上げ
少数第一位の値に対して、切り捨て、四捨五入、切り上げを行います。

```php:少数の切り捨て、四捨五入、切り上げ
<?php
  print("切り捨て(floor)" . "\n");
  print("1.4 → " . floor(1.4) . "\n");
  print("1.5 → " . floor(1.5) . "\n");

  print("四捨五入(round)" . "\n");
  print("1.4 → " . round(1.4) . "\n");
  print("1.5 → " .round(1.5) . "\n");

  print("切り上げ(ceil)" . "\n");
  print("1.4 → " . ceil(1.4) . "\n");
  print("1.5 → " . ceil(1.5) . "\n");
?>
```

##書式を整える
sprintf(フォーマットの形式, 最初に代入する値, 2番目に代入する値, .....);
フォーマットの形式 → %桁数d
フォーマットの形式 → %文字数s
記載しない場合には、桁数、文字数は変更されません。
また、文字を数字のフォーマットしようとした場合には0になります。

```php:書式を整える
<?php
  $date = sprintf('%04d年 %02d月 %02d日' , 2018, 1, 23);
  print($date);

  $ngformat = sprintf('%d', 'abc');
  print($ngformat);

  $okformat = sprintf('%s', 'abc');
  print($okformat);
?>
```
linuxでのvscode使用時にBash設定がOSの設定と乖離してしまう問題

# 症状

1. 突然言語設定が日本語になった
2. matplotlibが使えなくなった (`tclError couldn't connect to display`)

# 原因

```
$ echo $LANG
ja_jp.utf-8  # 日本語になっている

$ echo $DISPLAY
# 何も表示されない 
```

# 応急処置

応急処置は環境変数を毎回宣言すること．

```
$ LANG=en_US.utf8
$ export DISPLAY=:0.0
```

# 根本的な解決

仮に本体OSのshellであれば，`.bashrc` に上記のコマンドを貼り付けるだけ．
VScodeの場合は `.config/Code/User/settings.json` に以下を追加．

```json
"terminal.integrated.inheritEnv": true,
"terminal.integrated.shell.linux": "/bin/bash"
```

私の場合はOSとVScodeのshellを一致させたかったので以上で完了でした．
FirestoreがSDKでアクセス出来ない時の備忘録

# 内容

Python SDK経由でFirestoreにアクセスした際に以下のようなエラーが出た。「***」はプロジェクトIDです。
自分の場合は、GAEを無効にしていたため、駄目だったっぽいです。以下の「Note that Cloud Datastore or Cloud Firestore always have an associated App Engine app and this app must not be disabled.」が該当箇所です。放置していたプロジェクトで作業しようとしたため、昔に何も考えずに無効にしていたのでしょうかね。何にしても無駄な時間を使いました。

```
404 The project *** does not exist or it does not contain an active Cloud Datastore or Cloud Firestore database. Please visit http://console.cloud.google.com to create a 
project or https://console.cloud.google.com/datastore/setup?project=*** to add a Cloud Datastore or Cloud Firestore database. Note that Cloud Datastore or Cloud Firestore always have an associated App Engine app and this app must not be disabled.
404 The project *** does not exist or it does not contain an active Cloud Datastore or Cloud Firestore database. Please visit http://console.cloud.google.com to create a 
project or https://console.cloud.google.com/datastore/setup?project=*** to add a Cloud Datastore or Cloud Firestore database. Note that Cloud Datastore or Cloud Firestore always have an associated App Engine app and this app must not be disabled.
```
データサイエンティスト100本ノックでSQLがエラーになったときの対処法

> 起こった事象


データサイエンティスト100本ノックをやろうとした時にSQL文が打てなくなった。

> 解決法

Dockerfile.notebookに以下を追加してコンテナをビルドし直す

```
FROM jupyter/datascience-notebook:python-3.8.6
#FROM jupyter/datascience-notebook:d53a302fbcd0
USER root
ENV DEBCONF_NOWARNINGS yes
RUN apt-get update
RUN apt-get install -y libpq-dev
USER jovyan
RUN pip install --upgrade pip
RUN pip install --upgrade setuptools
RUN pip install --no-cache-dir ipython-sql==0.3.9
RUN pip install --no-cache-dir psycopg2==2.8.5
RUN pip install --no-cache-dir imblearn==0.0
RUN pip install ipython-sql ←この一文を追加
RUN Rscript -e "install.packages(c('DBI', 'RPostgreSQL', 'rsample'), dependencies = TRUE, error = TRUE, repos='https://cran.r-project.org')"
#RUN Rscript -e "install.packages(c('DBI', 'RPostgreSQL', 'recipes'), dependencies = TRUE, error = TRUE, repos='https://cran.r-project.org')"
```

これを追加することでSQL文を打てるようになります。
アドミニストレーター認定試験に向けた学習 ⇒ アドミニストレーター認定の準備: レポートと自動化 ⇒ レポートとダッシュボードの練習

１．「分析 - レポートとダッシュボード」セクションは、アドミニストレーター認定試験の何 % を占めていますか?
２．アドミニストレーター認定試験の「分析 - レポートとダッシュボード」セクションの主なトピックはどれですか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/867b0884-a952-1fc8-8373-1914c10fbb38.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/a7949f69-b730-2190-22c7-7a4805232499.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/c07ab348-0b67-698d-0ad2-a483d4d3b166.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/7964359d-7d57-2146-8b90-36eb14274a71.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/cd134fa2-c6a6-0f2e-6bed-19cb8f313a76.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/821f44ca-bf49-5a7a-ab06-5bce768eab37.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/c7bb32b1-0916-9bcf-b0f5-e9671734534f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/5fbb54c6-7805-cf04-ade3-435e501db5e6.png)
AHKでファイルパス文字列を開く

MS Teamsなどでファイルパスを送信する際、
リンク化できないのでいちいち

1. パスを選択
1. コピー（Ctrl+C）
1. エクスプローラ開く（Win+E）
1. アドレスバーを開く（Alt＋D）
1. ペースト（Ctrl+V）
1. Enter押す

なんて手を踏まなければならない

面倒なのでAHKを常駐させて

1. パス選択
1. AHK実行（下記コードではCtrl+Shift+O）

以上
とさせるホットキーを作った。


動作は至ってシンプル。
SendKeyでCtrl+Cコマンドから`Run explorer.exe`でパスを開く

CtrlとかShiftとかホットキーの予約文字はここ参照

http://ahkwiki.net/Hotkeys



``` bat
; ホットキー設定 Ctrl + Shift + O
^+o::	
	;メイン動作
	;Ctrl+Cでコピーされた内容をエクスプローラーで開く
	clipboard = 
	Send, ^c
	ClipWait
	Run explorer.exe %clipboard%
```
SSHでログインミスを少なくするために取る方法

# ログに乗る乗るログに乗る、あなたがログインに失敗していることが。
私は様々なマシンを管理をしているので、各マシンからログイン失敗するとログに乗ってくるんです。

そこで、すこしでもそのようなログに乗ったりメールで失敗された記録が送られないようにするいい方法をお教えします。

## 公開鍵認証にしましょう
皆さん、SSHは公開鍵認証ができることはご存知ですよね？
ですので、それを活用しましょう。

手前味噌ですが、方法は以下の通りです。

https://qiita.com/evakichi/items/abb6dde9df78f049b913

このように最初にパスフレーズで鍵を認証しておけば
ログインしようとした時点で、慌ててパスワード入れるのに失敗して
ログに乗っちゃうってことはなくなります。
しかも、この時点でパスフレーズの入力失敗をしても私たちにはバレません。

## エージェントを使えば何段にしても平気

ここからは新しい試みです。

```bash:~/.ssh/config
Host *
ForwardAgent yes
```

このことを書いておけばとりあえず一段目のSSHから2段目のSSHをするときに
同じ公開鍵が登録されていれば、エージェントが何とかしてパスフレーズ入力無しで
ログインをしようとしてくれます。

また、書かなくても

```bash
$ ssh -A hoge
```

って繰り返せば何段でもhogeさん(ここのサーバ名は任意)にパスフレーズなしで行けます。

##じゃぁ、公開鍵はどう送ればいいの？

初めて入る場合には、公開鍵をサーバに送っておく必要があります。
公開鍵を送る手段は以下の通りです。

```bash
$ ssh-copy-id -i ./ssh/公開鍵名 ユーザ名@サーバ名
```
こうするとあら不思議、あなたの目的のサーバの~/.ssh/authorized_keys に公開鍵が登録されます。
このときだけ、パスワードが要ります。あしからず。

是非お試しあれ。
Synology の NAS に debian pkgをインストールする方法

## SynologyのNASに必要なpkgをインストールする方法

### Synology NAS の ssh を有効にしておく。
DSMのコントロールパネルから端末とSNMP を選択して、"SSHサービスを有効化する。" を有効にする。

teraterm等で、NASにSSHで接続する。

uname -a を実行して、Synology の NASのCPU Archを確認する。

$ uname -a
Linux DS_XXX 4.4.59+ #25426 SMP PREEMPT Mon Dec 14 18:48:52 CST 2020 x86_64 GNU/Linux synology_geminilake_920+

これを見るとx86_64だと分かる。

ここから、必要なPKG を探してくる。
https://www.debian.org/distrib/packages

sshpass が必要だったので、amd64のsshpass のdebian pkg をdownload してinstall する。
https://packages.debian.org/buster/amd64/sshpass/download

~~~
$ sudo wget http://ftp.jp.debian.org/debian/pool/main/s/sshpass/sshpass_1.06-1_amd64.deb
$ sudo dpkg -i --force-all sshpass_1.06-1_amd64.deb
~~~

--force-all を付けないと、signature errorで怒られる。

~~~
$ sudo dpkg -i sshpass_1.06-1_amd64.deb
Authenticating sshpass_1.06-1_amd64.deb ...
debsig: Origin Signature check failed. This deb might not be signed.

dpkg: error processing sshpass_1.06-1_amd64.deb (--install):
 verification on package sshpass_1.06-1_amd64.deb failed!
Errors were encountered while processing:
 sshpass_1.06-1_amd64.deb
~~~

インストールが成功すると、sshpassのコマンドが打てるようになる。

~~~
$ sshpass
Usage: sshpass [-f|-d|-p|-e] [-hV] command parameters
   -f filename   Take password to use from file
   -d number     Use number as file descriptor for getting password
   -p password   Provide password as argument (security unwise)
   -e            Password is passed as env-var "SSHPASS"
   With no parameters - password will be taken from stdin

   -P prompt     Which string should sshpass search for to detect a password prompt
   -v            Be verbose about what you're doing
   -h            Show help (this screen)
   -V            Print version information
At most one of -f, -d, -p or -e should be used
~~~
駆け出しエンジニアがレスポンシブのLPを組むときに気をつけたい6つのポイント

こんにちは、@amiamiといいます。
前職ではUIデザイナーのようなことをやっていてコードを書いたことがなく
いきなり、初めてLPの実装をすることになりました！
（できたLPはこちらです！　https://lp.re-shine.jp/orderer/)
その際に割と引っかかってしまった点を書いておきます。
社会人●年目の新人プログラマーですが、皆さんと一緒に頑張っていきたいです。


# 1. いきなりCSSを書き始めない

webページは構造が大事。
どの要素をどうまとめるかをイメージしながらHTMLのみ書いていきます。
CSSのクラス名もつけていきましょう。
（完璧につける必要はないです。ざっくり内容と構造に合わせてつけていきましょう）

デザインの不明点もこの段階できっちり洗い出しておきます（できてなかった）
例えば、下のエリアのコーディングについて
当初、矢印部分だけが画像だったのですが、表部分も含めた画像に変えてもらいました。

![service_compare.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31662/b17bfba0-3b1b-07e1-c8cd-9d8918a90174.jpeg)


あとは、レスポンシブで画面が変化した際、要素が固定になるのか、伸びるのかはきっちり確認しておく必要があります。


# 2. 全部一気に仕上げようとしない

当たり前でしたね。
section要素ごとに対応しましょう。
一つずつ完成させることでモチベーションにも繋がります。
bodyや別sectionのスタイルを継承していたりするのをきっちりカバーできるメリットもあります（できてなかったので焦った）
テキストのみや1枚画像などの、要素が少ないところから始めるといいでしょう。


# 3. 都度確認しながら進める
いつ、どこで変な記述をしたか気付くためにエディタに確認用のプラグインは必須です。
VScodeでHTMLとSCSSを書いていたのでこの二つは本当に便利でした。

Live Server : https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer
Live Sass Compiler : https://marketplace.visualstudio.com/items?itemName=ritwickdey.live-sass

使い方は公式やこの辺りを参考にしてください。

https://qiita.com/kn339264/items/e6f6a69f70a96e61fc11

https://webdesign-trends.net/entry/9295

# 4. position:absolute;を使いすぎない

`position:absolute;`は親要素に対しての位置を自由に指定できるので
置きたい要素をきっちり決めることができます。
レスポンシブデザインだと画面サイズが変わってしまうので
多用してしまうと、修正が大変になります。
ですので、使いどころを決めて使用するのがいいと思います。
`div::after`などの擬似要素や、画像の上にアイコンを重ねたりといった場面です。

駆け出しエンジニア的には、`position:absolute;`を指定するときは
必ず親要素に`position:relative;`を指定することを忘れないようにしましょう。
変なところに要素が表示されてしまいますので…


# 5. 安直にheight指定はしない


`height`でエリアのサイズを決めてしまうと
子要素の大きさによっては子要素がはみ出してしまうことがあります。

背景色などは下のように`padding`でエリアを作ると
画像が背景からはみ出さないようにして色指定することができます。

```
div {
  background-color: #f8f8f8;
  padding-top: 100px;
  padding-bottom: 113px;
}
```




# 6. PC版が組み上がってからレスポンシブに取り掛かる

PC版が一通り作成終わって、デザイン通りになっていることを確認したら
SP版を作り始めます。

SP版はiPhoneの 375pxを基準に作っていきました。
利用するスマートフォンによって文字サイズや画像サイズなどの見た目が変わってしまわないように
SP版のデザインはvwで実装することで利用するスマートフォンによらず同じ見た目にすることができます。

このサイトで紹介されているようなSASSの`@mixin`で関数を作ってしまうと
デザインデータのpx値をそのまま関数に入れればいいので楽に実装できます。


https://qiita.com/katsunory/items/3bede89cee8e2ded8426


https://jajaaan.co.jp/css/responsive-font-size/

# 終わりに

大体このような感じのことを気をつけていけば、（私のように）つまずかずにLPが作れると思います。
LPを作り慣れている方なら当たり前のようなことばかりですが、少しでも参考になれば。
VS Codeで全角スペースを確実に見つけるRicty Diminishedのインストール方法

# 事件
先日、社内の鬼殺隊の柱のような先輩陣に「僕のコードが動きません！」と訴えたら、エラーの原因が**全角スペースが混じっていただけ**という、時代が時代ならただごとでは済まなかったであろう、つまらないミスをしてしまったので、柱のアドバイスで全角スペースをわかりやすく表示してくれる`Ricty Diminished`というフォントを、VS Codeに入れることに。

フォントをインストールするという簡単そうな作業なのに、ネット上にいろんなやり方が溢れていて、煩雑なものだけにとどまらず、うまく行かないのもあったので、ここにうまくいったシンプルな方法を記します。

# 実装！

1, Ricty Diminishedとググる。もしくは下をリンクをば。

https://github.com/edihbrandon/RictyDiminished

2, RictyDiminished-Regular.ttfをクリック

![スクリーンショット 2021-04-22 15.35.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645077/6cf95ec7-86c3-f865-7a39-3c18fe1018d9.png)

3, Downloadをクリック

![スクリーンショット 2021-04-22 15.39.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645077/e275b2dc-1862-3def-dee5-dfad4a2ce278.png)

4, ダウンロードしたファイルを開いたら「フォントをインストール」をクリック。
![スクリーンショット 2021-04-22 15.39.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645077/92dc0c46-8415-74b3-f781-58b9c6814bec.png)

5, VS codeで「設定」を開く（Macは`Command` + `,`）

6, Font familyに「Ricty Diminished」を先頭に追加
![スクリーンショット 2021-04-22 15.34.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645077/34f66d4f-662e-744c-a171-56f0f645d2b6.png)

# 一件落着
これでめでたく、不届き者、全角スペースを見逃すことはなくなるでしょう。
![スクリーンショット 2021-04-22 15.32.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645077/27a1c977-8067-15bd-c482-a47e8fb74ca0.png)
部分テンプレート render @posts どういう意味？

#はじめに
Ruby on Railsではコードの可読性や管理性を重視し、複数のビューファイルで共通するコードを一つのビューファイルにまとめ、部分テンプレートとして使用することが好まれています。
そこで、Railsの教材を元に、部分テンプレートの作成をしていたところ

```index.html.erb
<%= render @posts %>
```
という謎のコードが出てきました。
呼び出された部分テンプレートは _post.html.erb でサーバーを起動すると、Postテーブルに登録された投稿の数だけ投稿のタイトルと内容が繰り返し表示されています。
```render + インスタンス変数```に何が隠されているのか調べてみました。

#序論

今、投稿一覧ページ (index.html.erb) にはPostテーブルの要素の数だけ投稿のタイトルと内容が繰り返し処理により表示されている状態です。
すなわち、本来 index.html.erb ファイルは

```index.html.erb
<% @posts.each do |post| %>
  <%= post.title %>
  <%= post.content %>
<% end %>
```
こうあるべきです。

それがなぜ

```index.html.erb
<%= render @posts %>
```
このように記述されたのか順を追って解説します。


#patialオプション
まず、

```index.html.erb
<% @posts.each do |post| %>
  <%= post.title %>
  <%= post.content %>
<% end %>
```
このコードの投稿のタイトルと内容を表示する部分からテンプレートを作成します。部分テンプレートのファイル名は必ずアンダーバーから始まるので_post.html.erb と設定します。

```_post.html.erb
<%= post.title %>
<%= post.content %>
```
このようになります。

この部分テンプレートを呼び出すために index.html.erb にrenderメソッドを用います。

```index.html.erb
<% @posts.each do |post| %>
 <%= render partial: 'post', locals: {post : post} %>
<% end %>
```
部分テンプレート名は_postですが、呼び出す際はアンダーバー無しのpostで呼び出します。

renderメソッド内のpartialオプションは、「部分テンプレートを呼び出すよ！」と明示させるためのものなので省略可能です。

ただし、今回のようにlocalsを記述している場合はpartialを記述しないとエラーが出てしまいます。

#localsオプション
部分テンプレートを呼び出すコードに
```<%= render partial: 'ファイル名', locals: {部分テンプレート内の変数 : 変数に入れたい値} %>```
localsとあります。

localsオプションを用いると、部分テンプレート内で使う変数の定義をすることができます。

今回の例では”部分テンプレート内の「post」という変数”に”呼び出し元で定義した変数「post」”が代入されています。

#collectionオプション
さて、部分テンプレートによって

```index.html.erb
<% @posts.each do |post| %>
 <%= render partial: 'post', locals: {post : post} %>
<% end %>
```
このようにコード量を減らすことができました。

上記のコードは@postsの要素の分だけ部分テンプレートが繰り返し呼び出されています。そこでcollectionオプションを用いてコードをさらにスッキリさせたいと思います。

```index.html.erb
<%= render partial: 'post', collection: @posts %>
```

collectionオプションを用いると、なんと3行あったコードを１行で書くことができます。

collectionオプションとは指定した変数の要素の分だけ、部分テンプレートを繰り返し表示できるオプションです。
すなわち元のコードの”each文”と”localsオプション”の機能を担っています。

「え？localsで指定した変数は？」と思いますよね。

collectionオプションでは指定した変数（@posts）の単数形（post）が自動的に、変数に入れたい値として指定されます。

もしcollectionオプションを用いて変数も指定したい場合は
```<%= render partial: 'post', collection: @posts, as: "指定したい変数名" %>```
で指定できます。

#まだ省略できる！？

```index.html.erb
<%= render partial: 'post', collection: @posts %>
```
このように最初に比べかなりスッキリしたコードですが、ある条件を満たせばさらに省略できます。

1. 呼び出す部分テンプレートが、views/posts内に存在する
1. 部分テンプレート名が_post.html.erbである
1. 部分テンプレート内の変数がpostである

上記の条件を満たす場合、下記のコード量まで省略可能です。

```index.html.erb
<%= render @posts %>
```

なんと！！見覚えのあるコードですね！！！さっきまで全く理解できなかったコードです。

```render + インスタンス変数```にここまでの情報が詰まっているとは、、、

#結論

```render + インスタンス変数```で構成された

```index.html.erb
<%= render @posts %>
```
このコードには、views/posts内の部分テンプレート

```_post.html.erb
<%= post.title %>
<%= post.content %>
```

を@postsの要素の分だけ繰り返し呼び出す処理が隠されていました。

renderメソッドのpartial,locals,collectionオプション、さらには省略の条件まで理解してようやく納得できます。
簡単に書かれたコードほど初心者泣かせですよね、、、:sweat:

#参考文献
https://pikawaka.com/rails/partial_template
【Python】関数が呼び出された回数をカウントする

# はじめに

Seleniumスクレイピングのかんたんなデバッグのためにスクリーンショットを保存する関数を用意した際、ファイル名に番号をつけ、何番目に保存された画像かわかるようにしたかった経緯があります。

その関数の累計呼び出し回数を、その関数内で利用したいということで検索してみたところ、意外とシンプルな解が見つからず難航したため、ここに1つの解を記しておきます。

「いい」方法ではないと思われますが、数十行程度のプログラムを書く際にはこれでいいのではと思います。

# 解

```python:コード
def f(cnt=[0]):
  cnt[0] += 1
  print(str(cnt[0]) + "回目の呼び出し")

f()
f()
f()
```

```bash:実行結果
1回目の呼び出し
2回目の呼び出し
3回目の呼び出し
```

# さいごに

デフォルト引数にリストを用いるのは一般的に推奨されていませんが、その特性が活きる場面があるのだなと。


[参考](https://www.it-swarm-ja.com/ja/python/%e9%96%a2%e6%95%b0%e3%81%8c%e5%91%bc%e3%81%b3%e5%87%ba%e3%81%95%e3%82%8c%e3%81%9f%e5%9b%9e%e6%95%b0%e3%82%92%e8%bf%bd%e8%b7%a1%e3%81%99%e3%82%8b%e6%96%b9%e6%b3%95%e3%81%af%e3%81%82%e3%82%8a%e3%81%be%e3%81%99%e3%81%8b%ef%bc%9f/1045439200/)
(StackOverflowの機械翻訳？)
OpenCVでMTS形式の動画から静止画を取得するとぶれてしまう問題

#MTS形式動画からきれいな静止画を取得できない

今回はインターン先でOpenCVを使っていた時にはまった問題と解決方法について書いていきます。

##やろうとしていること

**動画からきれいに画像を取得すること。**

すでにある画像認識のための機械学習モデルがあり、そのモデルではどの画像をどのように識別したかを確認することができる。

クライアント様への説明もあるため人間による正解データとの比較が必要になった。

そのためにOpenCVを利用して動画から識別される部分の画像を切り取っていった。


##問題点
**切り取った画像は動体が非常にぶれており細かい部分の確認ができない状態になっていた。**

動いている物体の文字を確認したかったのだが、ブレにぶれまくっておりとてもではないが識字できない状態になっていた。

しかしながら、動画で一時停止してみると多少ぶれてはいるが識字できる状態であった。

つまり一時停止とOpenCVを用いた切り抜きに鮮明度で差が生まれていた。

この時に頭の中に2パターンの可能性が浮かんでいました。

1．OpenCVが原因でうまく読み込めていない場合。
2．動画形式が前後の補完によってきれいに見せることができている場合。

結果的には1のOpenCVが原因(正確にはFFmpeg)でうまく読み込めていませんでした。

##原因
原因は動画のインターレースでした。動画のインターレースとは動画のFPSを変更せずに滑らかに見せるために差し込まれる画像のことで、OpenCVをインターレースのある動画を切り抜くと非常にブレた画像のようになってしまいます。

##対処法
極論言えば動画のインターレースを削除すればいいです。自分が行った内容はAviUtlでのでインターレースを行いました。

参考記事
[【AviUtl】インターレース解除する4つの方法【デインターレース】](https://aviutl.info/innta-re-sukaizyo/)

またプログラムからも可能なようです。
参考記事
[CCDカメラで撮像した画像をOpenCVを使って縞々模様を除去する](https://phst.hateblo.jp/entry/2019/11/20/141222)

僕の場合は動画の数も少なかったのでAviUtlを使いましたが、細かい動画がたくさんある場合はプログラムの方が便利そうですね。
連邦のスプレッド構文とやらを覚えさせてもらった。

最近オブジェクトについて勉強する機会があったので、アウトプット。

```javascript

const array1 = {
	"aaaaa":{sss:"ええええ",ddd:"うううう"},
	"xxxxx":{sss:"ええええ",ddd:"うううう"}
};
//キーである"aaaaa"と"xxxxx"をそれぞれの右側のオブジェクトにidをキーにして代入したい。

let array2 = [];
Object.keys(array1).forEach((Doc) => {
	array2.push({...array1[Doc], id: Doc});
});

console.log(array2);
//=>[ddd: "うううう",id: "aaaaa",sss: "ええええ"],[ddd: "うううう",id: "xxxxx",sss: "ええええ"]

```

ポイントは```...array1```で使われている```...```は ```スプレッド構文```というものらしい。

```スプレッド構文```を使うと ```{sss:"ええええ",ddd:"うううう"}``` で囲まれている``` {} ```中括弧を外すことができる。これでオブジェクトの中身をそのまま別のオブジェクトの中で扱えました。
NVIDIA/AMD GPU で OpenCL で C++ でカーネル記述はまだ無理だった(2021/04 時点)

https://www.khronos.org/blog/opencl-3.0-specification-finalized-and-initial-khronos-open-source-opencl-sdk-released

OpenCL 3.0 で大々的(?)に C++ for OpenCL(カーネル言語で C++ サポート)がうたわれていますが... 現状(2021/04)対応している GPU はないことがわかりました. :cry:

## C++ 

OpenCL で C++ するには以下の条件のどちらかがいります.

* `cl_ext_cxx_for_opencl` 拡張が定義されており, OpenCL ドライバのコンパイラが C++ サポートしている.
* SPIR-V を中間言語にしており, 外部コンパイラ(clang)が C++ を SPIR-V バイナリにする
  * SPIR-V IL 対応は OpenCL 2.1 or 2.2(3.0 では必須ではない)
 
## NVIDIA 

OpenCL 3.0 対応ドライバが出ました. しかし実体は 1.2 + alpha くらいです. `cl_ext_cxx_for_opencl` は定義されていません. SPIR-V IL 対応拡張もありません. したがって C++ は扱えません :cry:

## AMD

amdgpu-pro ドライバでのお話をします. バージョンは 2.0 止まりでした. SPIR-V IL 対応拡張もありませんでした :cry:

## おまけ: Intel

ワンチャンあるかもだが, 現状 Xe GPU(dGPU)が販売されていないため不明.

## まとめ

OpenCL で C++ がまともにサポートされるのは 4~5 年後くらいですかね...

C++ 使いたかったらおとなしく NVIDIA GPU + CUDA にしましょう.

clspv で C++ OpenCL カーネルを Vulkan で動かすという手もありますが, Vulkan で実行はメモリモデルの制約とかあった気がするので GPGPU 用には向かない気がします. あとは Colab みたいなサーバ環境でも使えないですし.

clspv(OpenCL カーネル記述 -> SPIR-V -> Vulkan 実行) で C++17 言語機能を使う
https://qiita.com/syoyo/items/8eab8d3f80bd78a29d56
Pythonで別ディレクトリにある自作ライブラリをimportする方法

## Pythonで別ディレクトリからimportする方法

使いたいファイル（自作ライブラリ）があるディレクトリのパスを`sys.path`に追加することで、importのパスをカレントディレクトリからの相対パスに変更せずに呼び出すことができるようになります。


### ディレクトリ構造

```shell
src
 ├── hoge
 │   ├── main.py
 │   └── hoge.py               
 ├── test.py
```

### コード

```python:test.py
import sys
from pathlib import Path

p_cwd = Path('.')
p_hoge_dir = p_cwd.joinpath('hoge')
sys.path.append(str(p_hoge_dir))

from hoge.main import main
main()

```

```python:main.py
from hoge import hoge

def main():
    hoge()
```

```python:hoge.py
def hoge():
    print('Hello World!')
```

## 参考文献
- [Pythonでimportの対象ディレクトリのパスを確認・追加](https://note.nkmk.me/python-import-module-search-path/)
【Docker・Laravel】コンテナの中でartisanコマンドを実行する方法

個人メモです。

Dockerコンテナの中で複数のプロジェクトを展開している場合にartisanコマンドを実行する方法。

コンテナの中に入ってすぐに`php artisan config:cache`が使えない場合、コンテナの中で該当するプロジェクトのルートディレクトリに移動する必要がある。

```
$ docker exec -it コンテナ名 bash

bash-4.2# cd projects/src/プロジェクトディレクトリ 
bash-4.2#
bash-4.2# php artisan config:cache
Configuration cache cleared!
Configuration cached successfully!
```

コンテナ内でディレクトリを移動してもプロンプトは変わらない。


<br>
###参考： ディレクトリを移動しない場合はエラーになる

```
$ docker exec -it コンテナ名 bash

bash-4.2# php artisan config:cache
Could not open input file: artisan
```
クリックメニュー


```index.html
<body>
  <h1>このゲームの内容</h1>

  <div class= menu>
    <h2>登場人物</h2>
    <ul class="closed">
      <li>1.太郎君</li>
      <li>2.山田くん</li>
      <li>3.よしおくん</li>
    </ul>
  </div>

  <div class="menu">
    <h2>約束</h2>
    <ul class="closed">
      <li>1.怒らない</li>
      <li>2.寂しくさせない</li>
      <li>3.愛情をあげる</li>
    </ul>
  </div>
  <script src="script/jquery-3.6.0.min.js"></script>
  <script>
   'use strict';

   $(document).ready(function(){
     $('.menu h2').on('click', function(){
       $(this).next().toggleClass('closed')
     })
   });
  </script>

</body>
```

jQueryを使ってクリックしたら、メニューが開くプログラムです。

jQueryダウンロードは、こちら▶　https://jquery.com/download/

これをscriptタグに埋め込む。

(document).ready(function()
これからjQuery始まるよの合図。必ず記述。

h2をクリックすると、ul要素の中のliタグたちが現れる。
css上では、closedは消えている。

```style.css
.closed {
  display: none;
}
```
menuクラスのh2要素を取得する。

onはイベントを設定する、(click, function() 
イベント発生要素(this).next(次の要素つまりul).toggaleClass(指定のクラスがあれば削除、なければ追加)(クラス名今回はclosed)
Laravel composer update で abandoned されたパッケージの警告問題を解消する

## 環境

- PHP 7.4.15
- Laravel 7.30.4
- Composer 2.0.9
- PHPUnit 8.5.15

## composer update

```
$ composer update

Package fzaninotto/faker is abandoned, you should avoid using it. No replacement was suggested.
Package phpunit/php-token-stream is abandoned, you should avoid using it. No replacement was suggested.
```

- https://github.com/fzaninotto/Faker
- https://github.com/sebastianbergmann/php-token-stream

パッケージがアーカイブされてます🥺

## Faker

以前の記事で軽く紹介しましたが、[fzaninotto/Faker](https://github.com/fzaninotto/Faker)のアーカイブされてます。
新しいリポジトリはこちらです。[fakerphp/faker](https://github.com/fakerphp/faker)

- [補足: fzaninotto/Fakerのアーカイブ](https://qiita.com/ucan-lab/items/bc421788d4a352afc6ea#%E8%A3%9C%E8%B6%B3-fzaninottofaker%E3%81%AE%E3%82%A2%E3%83%BC%E3%82%AB%E3%82%A4%E3%83%96)

```
$ composer remove --dev fzaninotto/faker
＄ composer require --dev fakerphp/faker
```

執筆時点では `fakerphp/faker: 1.14.1` がインストールされました。

```
$ php artisan db:seed
```

シーディング実行して壊れてないか確認します。
開発用のツールなので、動いてくれればまぁ良いでしょう。

## PHPUnit


- https://github.com/changeweb/Unifiedtransform/issues/283

これについてはPHPUnit8からPHPUnit9でバージョンアップする必要があります。

```
$ composer remove --dev phpunit/phpunit
$ composer require --dev phpunit/phpunit

our requirements could not be resolved to an installable set of packages.

  Problem 1
    - phpunit/phpunit[9.5.0, ..., 9.5.x-dev] require sebastian/diff ^4.0.3 -> found sebastian/diff[dev-master, 4.0.3, 4.0.4, 4.0.x-dev (alias of dev-master)] but the package is fixed to 3.0.3 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.
    - Root composer.json requires phpunit/phpunit ^9.5 -> satisfiable by phpunit/phpunit[9.5.0, ..., 9.5.x-dev].

Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.
```

おお...エラー出た><。

```
$ composer require --dev --with-all-dependencies phpunit/phpunit
$ ./vendor/bin/phpunit --version
PHPUnit 9.5.4 by Sebastian Bergmann and contributors.
```

エラーメッセージで言われてる通り、依存パッケージも含めてアップグレードを試します。
執筆時点では `phpunit/phpunit 9.5.4` がインストールされました。

テストが壊れてないか確認します。

```
$ php artisan test
```

こちらも開発用のツールなので、動けば良いでしょう。

## 確認

```
$ composer update
```

警告メッセージが出なくなったのでokです。
IBM Cloud VPC でシンプルなウェブサイト構築を体験する - 5. セキュリティー・グループ作成

この記事は、[IBM Cloud VPCでシンプルなウェブサイト構築を体験する](https://qiita.com/kenichit/items/796b0cff7d09a0f517f6)の構築ステップを説明しています。

次のステップ「6.ロード・バランサーの作成と動作確認」の準備として、セキュリティー・グループを作成します。このステップで作成するセキュリティー・グループは、構成図中に赤い四角で示した部分で動作させるための簡易なステートフル・ファイアウォールです。
![dialog-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/5c2cccdb-bcec-2910-abb0-4efc4e5c1849.png)

## ステップ5-1
「VPCインフラストラクチャー」>「ネットワーク」>「セキュリティー・グループ」をクリックします。
ロード・バランサー用セキュリティー・グループを作成するため、画面右側の「作成」ボタンをクリックします。
![security-group-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/e64b595c-0e30-9a71-9bf1-3cdcd3024431.png)

## ステップ5-2
パラメーター・シートの「ロード・バランサー用セキュリティー・グループ」のパラメーターを入力します。
![security-group-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/a5f54c5f-1bfe-ffc1-4b36-afb103e99913.png)

## ステップ5-3
ステップ5-2の画面で表示されている「インバウンド・ルール」>「追加」ボタンをクリックします。
パラメーター・シートを参照し、インバウンド・ルールを1つ追加します。このルールにより、インターネットからロード・バランサーへのHTTPS通信が可能になります。
![security-group-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/d6b6b5bd-de7d-d974-80c3-86335676dac7.png)

## ステップ5-4
ステップ5-2の画面で表示されている「アウトバウンド・ルール」>「追加」ボタンをクリックします。
パラメーター・シートを参照し、アウトバウンド・ルールを1つ追加します。このルールにより、ロード・バランサーがウェブサーバーにリクエストを送信できるようになります。
![security-group-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/b976e0e3-0cde-bae4-5bd8-45334b762eeb.png)

## ステップ5-5
入力が完了したら、画面右側の「セキュリティー・グループの作成」ボタンをクリックします。
![security-group-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/a89137b0-aba5-fba2-fc63-2ef65bd50438.png)

## ステップ5-6
ロード・バランサー用セキュリティー・グループが作成されます。
次に、webサーバー用セキュリティー・グループ作成のため、「作成」ボタンをクリックします。
![security-group-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/f70c4421-8464-2087-17e4-2a602d3f0538.png)

## ステップ5-7
パラメーター・シートの「webサーバー用セキュリティー・グループ」のパラメーターを入力します。このルールにより、ウェブサーバーがロード・バランサーからのリクエストを受けられるようになります。
入力を完了したら、画面右側の「セキュリティー・グループの作成」ボタンをクリックします。
![security-group-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/ddd62f9c-cc7f-28f8-609f-b7d8b4475ef2.png)
作成されたロード・バランサー用とwebサーバー用セキュリティー・グループが表示されます。
![security-group-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/4c1c3c1c-521c-c50b-2133-00dd8e1d36c4.png)

次に、[ロード・バランサー作成](https://qiita.com/kenichit/items/abed2a73cd567392f431)へ進みます。
#### UI変更について補足(2022/6/20)
[VPC作成(2022年版)](https://qiita.com/kenichit/items/aa63cedf7f0a0aee71a1)から始めた方は、[ロード・バランサー作成と動作確認(2022年版)](https://qiita.com/kenichit/items/4633974e3ec2a4015df8)へ進みます。
IBM Cloud VPC でシンプルなウェブサイト構築を体験する - 2. サブネット追加

この記事は、[IBM Cloud VPCでシンプルなウェブサイト構築を体験する](https://qiita.com/kenichit/items/796b0cff7d09a0f517f6)の構築ステップを説明しています。

ステップ:「1. VPC作成」で1つのサブネットが作成されています。このステップでは、作成したVPCに構成図の赤い四角で示した2つのサブネットを追加します。
![dialog-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/0b4f5555-4254-393b-605c-2c5262b7c9b8.png)

##ステップ2-1
「VPCインフラストラクチャー」>「ネットワーク」>「サブネット」をクリックします。
画面右側の「作成」ボタンをクリックします。
![subnet-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/65bb761c-7b67-17f7-2fe8-2f07eefe9b6d.png)

##ステップ2-2
パラメーター・シートの「webサーバー用サブネット ロケーション: 東京2」のパラメーターを入力します。「仮想プライベート・クラウド」の値が「1.VPC作成」で作成したVPCの名前と一致していることを確認してください。
入力が完了したら、画面右側の「サブネットの作成」ボタンをクリックします。
![subnet-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/ded3b8ac-aab5-916f-d87c-4fb43f33cbc0.png)

##ステップ2-3
同様にして、パラメーター・シートの「bastion用サブネット ロケーション: 東京3」を作成します。
![subnet-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/308e01be-68fc-8148-8c60-9171bffb6ad3.png)
![subnet-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/bccb8494-e69a-17cd-a6bd-886e5bbe8527.png)
VPCの中に3つのサブネットができて、東京リージョンの別々のロケーション(ゾーン)に配置されます。
![subnet-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/4c16faad-fdf3-33d4-09b9-c9821614aebf.png)

##ステップ2-4
確認として、「VPCインフラストラクチャー」>「はじめに」>「VPCレイアウト」をクリックし、「VPCの選択」で作成したVPCを選びます。
![subnet-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/cd8c0afd-5f74-1991-75ad-091226b8c8c9.png)

次に、[仮想サーバー・インスタンス作成](https://qiita.com/kenichit/items/2a071bf70aef2a2f0683)に進みます。
IBM Cloud VPC でシンプルなウェブサイト構築を体験する - 1. VPC作成

この記事は、[IBM Cloud VPCでシンプルなウェブサイト構築を体験する](https://qiita.com/kenichit/items/796b0cff7d09a0f517f6)の構築ステップを説明しています。
このステップでは、構成図の中の赤い四角で示したVPCとサブネット1つを作成します。
![dialog-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/18c2073a-a7ae-3023-bc19-03534dd1f700.png)

##ステップ1-1
IBM Cloudコンソールの左上ナビゲーション・メニューをクリックし、「VPCインフラストラクチャー」>「ネットワーク」>「VPC」をクリックします。
![vpc-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/937a616e-0ec6-af58-35c7-6caafa8c5902.png)

##ステップ1-2
「仮想プライベート・クラウド」の「作成」ボタンをクリックします。
![vpc-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/27dfb53d-5a77-f0a2-d09e-f534ad4e9e50.png)

##ステップ1-3
VPC作成に必要な情報をパラメーター・シートを参照し入力します。
「VPC用の新規サブネット」にはパラメーター・シートの「ロケーション:東京1」のパラメーターを入力します。
入力が完了したら、画面右側の「仮想プライベート・クラウドの作成」ボタンをクリックします。
####補足:
「デフォルト・セキュリティー・グループ」の「SSHを許可」と「pingを許可」にチェックを入れたままにします。この設定により、VPCにデプロイされる仮想サーバーはデフォルトでSSHとping応答ができるようになります。
![vpc-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/29df77cd-f8e5-0519-054f-e5a6d735e6d9.png)

##ステップ1-4
VPCが作成されます。
![vpc-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922552/7d4234ee-9b62-41da-bcda-1ec8c2390b57.png)

次に、[サブネット追加](https://qiita.com/kenichit/items/2971f9da1542c2efde80)に進みます。
paiza.IO　ショートカット一覧

普段はVScodeかVisual Studioでコーディングしているのですがpaizaで学習をすすめる際はエディタがpaizaが提供しているpaiza.IOになります。
そこで少しでも早くpaiza.IOのショートカットを覚えられるようメモとしてこの記事を残そうと思います。
paizaで学習を進めている人はこの記事を参考にショートカットを駆使してコーディングスピードを向上し学習効率を高めていきましょう！
もし記入されていないショートカットがあればコメントで教えていただけると嬉しいです。

## 編集系
1. `Alt + Shift + ↑/↓` カーソル行／選択行をまるっとコピー(複数行対応)
2. `Ctrl + D`  カーソル行／選択行を削除(複数行対応)

## 移動系
1. `Ctrl + →/←` 単語の先頭にジャンプ

## 選択系
1. `Ctrl + Click` forcusカーソルの追加
mysqldump の警告対策

coreserver などで使われている次バージョンでエラーが出た時の対策です。

```text
mysql> select version();
+------------+
| version()  |
+------------+
| 5.7.33-log |
+------------+
```

エラーの状況

```text
$ mysqldump -uscott -ptiger123 city > city.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
mysqldump: Error: 'Access denied; you need (at least one of) the PROCESS privilege(s) for this operation' when trying to dump tablespaces
```

対策 1　（警告をひとつ消します）

```text
$ mysqldump --no-tablespaces -uscott -ptiger123 city > city.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
```

対策 2　（もうひとつの警告を消します）
次のファイルを作成

```text:dbase.conf
#
#	dbase.conf
#
[client]
user = scott
password = tiger123
#
```

警告が出ません

```text
$ mysqldump --defaults-extra-file=./dbase.conf --no-tablespaces city > city.sql
```
nkfで文字コードが混在したファイルの一括返還

#はじめに

各行で文字コードが混在したファイルがありました。EUC-JPとUTF-8が混在しているようです。

nkfって一行づつ文字コードを判別する命令あった気がするんですが、みつかりません。

しかたないので作りました。

```bash:/usr/local/bin/line_nkf
#!/bin/bash
while read line; do
      echo $line | nkf
done
```

上記のファイルを作って

```
$ sudo chmod +x /usr/local/bin/line_nkf

$ cat 混在ファイル.txt | line_nkf > output.txt
```

とかやってみてください。
SQL インデックスについて　まとめと参考サイト　



###インデックスとは
インデックスは大量のデータから，検索結果を高速に見つけ出すために必要な機能です。

1000件程度しかテーブルにないのであれば，インデックスが無くても，データを1秒未満取得できます。10000件くらい以上になってくると，インデックスなしでは，検索結果に差が出てきます。

https://anderson02.com/sqlserver/sqlserver-index/sqlserver-index-01/


###テーブルスキャンとは
テーブルスキャンとは端から端までデータを読み込むことです。

###インデックスの必要性
インデックスとは，「Id」などの項目の値を，昇順などの順番に並べるという事です。
「Id＝１」を検索する場合、「１」の次に「2」が来た時点で検索を完了できます。たとえ「１」「１」「１」「３」と「１」が複数あった場合も１よりも大きい数字が見つかった時点で検索を終了できるので，検索は各段に速くなります。


https://anderson02.com/sqlserver/sqlserver-index/sqlserver-index-2-06/


###インデックスの種類
インデックスには大きく分けて「クラスター化インデックス」と「非クラスター化インデックス」という2種類があります。


https://anderson02.com/sqlserver/sqlserver-index/sqlserver-index-2-07/


###IndexSeek
非クラスター化インデックスを作成し「検索条件あり」で検索を実行すると、テーブルスキャンで１２秒かかっていた検索時間が１秒で完了しました。
実行プランを確認するとIndexSeekになっています。

「Seek」とは「ピンポイントでデータを見つけました」という意味です。IndexSeekなので，「インデックスを使って，ピンポイントでデータを見つけた」という意味になります。いままでは「TableScan」でした。スキャンは「全部読んだ」という意味なのですが，「Seek」はピンポイントで見つけたという事なので，インデックスがうまく機能したという事です。

https://anderson02.com/sqlserver/sqlserver-index/sqlserver-index-2-08/

###クラスター化インデックスシーク
クラスター化インデックスを作成し「検索条件あり」で検索を実行すると、テーブルスキャンで１２秒かかっていた検索時間が１秒で完了しました。
実行プランを確認するとクラスター化インデックスシークになっています。
「Seek」なので，クラスター化インデックスがうまく機能して，ピンポイントでデータが見つけられたという意味になります。

https://anderson02.com/sqlserver/sqlserver-index/sqlserver-index-2-11/

###インデックスに無い項目を取得すると遅くなる
非クラスター化インデックスのリーフページに存在する項目のみでSelectする場合は高速に取得できるという事です。

https://anderson02.com/sqlserver/sqlserver-index/sqlserver-index-2-14/


###付加列インデックス
非クラスター化インデックスだけではどうしてもパフォーマンスが出ない場合に使用する。
非クラスター化インデックスのリーフページに存在しない項目をSelectすると，キー参照が発生し，検索は遅くなります。
そこで、付加列インデックスを作ることで、リーフページに項目を追加することができます。

###付加列インデックスの注意点
付加列インデックスを使えば，簡単に速度アップが見込めますが，あまり安易に使わないほうがいいです。本来は必要のないデータ容量を使用するため，無くていいならないほうがいいのです。どうしても非クラスター化インデックスだけでは速度が出ない場合につかうようにしてください。

https://anderson02.com/sqlserver/sqlserver-index/sqlserver-index-2-15/

###プライマリキーとユニークキー

プライマリキーを作成すると，クラスター化インデックス自動的に作成されます。

ユニークキーを作成すると非クラスター化インデックスが作成されます。



https://anderson02.com/sqlserver/sqlserver-index/sqlserver-index-2-16/

###インデックスが効かないパターン

・前方一致以外のLike検索

・検索条件で関数を使うようなケース

インデックスがうまく効いているかどうかは，結局実行プランをみればわかるので，SQLを書いたら，実行プランを見るという習慣を付けましょう。

https://anderson02.com/sqlserver/sqlserver-index/sqlserver-index-2-18/

###インデックスの作り過ぎに注意

インデックスを作成すると検索時間は短縮できますが，データの挿入，削除，更新が遅くなることには注意しておかなければなりません。
更新が頻繁に発生するオンライン処理系でデータベースを使用するのであれば，インデックスは2～3個以内にしておくのが良いでしょう。

###SQL文を最速にする11のポイント
●WHEREの左辺で算術演算子や関数を使わない
●「後方一致」検索はなるべく避ける
●IS NULL，IS NOT NULLを単独で使わない
●SELECT文で「＊」を使わない
●ORはある程度絞り込んでから使う
●DISTINCTの代りにEXISTSを使う
●GROUP BY，ORDER BY，HAVINGは注意する
●演算子の組み合わせで速度が変わる
●テーブルの別名を利用する
●SQL文の表現を統一する
●SQL文を簡潔に記述する

https://xtech.nikkei.com/it/article/COLUMN/20060111/227105/
SecureRandomで128bit IVを生成するmethodと、AES CBCモードで暗号/復号化するクラス

SecureRandomで128bit IVを生成するmethod

```java 
  private static IvParameterSpec getIV() throws Exception{
    SecureRandom secureRandom = SecureRandom.getInstance("NativePRNGNonBlocking");
    byte bytes[] = new byte[16]; // 128 bits are converted to 16 bytes;
    secureRandom.nextBytes(bytes);
    IvParameterSpec iv = new IvParameterSpec(bytes);
    return iv;
  }
```

ivとsourceを引数にとって暗号/復号するクラス

```java
  public class CryptionKey {
    Cipher cipher;
    SecretKey secretkey;

    public CryptionKey(String key) throws NoSuchPaddingException, NoSuchAlgorithmException {
      cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
      secretkey = new SecretKeySpec(key.getBytes(), "AES");
    }

    public String encrypt(String src, IvParameterSpec iv)
        throws InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
      cipher.init(Cipher.ENCRYPT_MODE, secretkey, iv);
      byte[] encrypted =  cipher.doFinal(src.getBytes());
      return new String(Base64.getEncoder().encode(encrypted));
    }

    public String decrypt(String encrypted, IvParameterSpec iv)
        throws BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, InvalidKeyException {
      cipher.init(Cipher.DECRYPT_MODE, secretkey, iv);
      byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(encrypted));
      return new String(decrypted);
    }
  }
```

上記を使ったテスト

```java
  @Test
  public void test() throws Exception {
    IvParameterSpec iv = getIV();
    System.out.println("iv: " + new String(Base64.getEncoder().encode(iv.getIV())));

    CryptionKey cryptionKey = new CryptionKey("yourEncryptKey01");

    String source = "pokemon";
    System.out.println("source: " + source);

    //暗号化
    String encrypted = cryptionKey.encrypt(source, iv);
    System.out.println("encrypted: " + encrypted);

    //復号化
    String decrypted = cryptionKey.decrypt(encrypted, iv);

    System.out.println("decrypted: " + decrypted);
  }
```

出力結果

```
iv: KJX6FUG1ze538IowMAY5Yg==
source: pokemon
encrypted: e6x9TcXf+R0tqzC9HkqK3g==
decrypted: pokemon
```
macOS で Gitbook を利用する

macOS で `Gitbook` が使えるようにする方法を記述します。

## 環境

- macOS Big Sur バージョン 11.2.3

## 準備

- 以下の投稿を参考に `Node.js` を事前にインストールします。

[macOS に Homebrew、nodebrew、Node.js をインストール](https://qiita.com/toshiok/items/276b082b69055717609f)

## gitbook-cliのインストール

- インストールするには、以下のコマンドをターミナルで実行します。

```sh
npm install --global gitbook-cli
```

## gitbook-plugin-umlのインストール

- インストールするには、以下のコマンドをターミナルで実行します。

```sh
npm install gitbook-plugin-uml
```

## graphvizのインストール

- インストールするには、以下のコマンドをターミナルで実行します。

```sh
brew install graphviz
```

## 不具合対応

- このままだとGitbookを利用すると以下のエラーが発生します。

```sh
/Users/ユーザ名/.nodebrew/node/v14.16.1/lib/node_modules/gitbook-cli/node_modules/npm/node_modules/graceful-fs/polyfills.js:287
      if (cb) cb.apply(this, arguments)
                 ^

TypeError: cb.apply is not a function
    at /Users/ユーザ名/.nodebrew/node/v14.16.1/lib/node_modules/gitbook-cli/node_modules/npm/node_modules/graceful-fs/polyfills.js:287:18
    at FSReqCallback.oncomplete (fs.js:184:5)
```

- これを解決するには、次のティレクトリに移動します。

```sh
cd ~/.nodebrew/current/lib/node_modules/gitbook-cli/node_modules/npm/node_modules/
```

- そして、graceful-fsをv4.2.0にダウングレードします。

```sh
npm install graceful-fs@4.2.0 --save
```

## Gitbookの利用

- これで、Gitbookが利用できるようになりました。
- `gitbook-cli` の使い方はオフィシャルサイトの [How to use it?](https://www.npmjs.com/package/gitbook-cli#how-to-use-it) で確認できます。
- 以下に主要な `gitbook` コマンドを記載します。

```sh
gitbook init
gitbook install
gitbook serve
gitbook build
```
AWS 認定ソリューションアーキテクト – プロフェッショナル(SAP)取得のための勉強方法

# はじめに
以下のAWSの資格を取得しました。

- AWS 認定 クラウドプラクティショナー(CLF)
- AWS 認定ソリューションアーキテクト – アソシエイト(SAA)
- AWS 認定ソリューションアーキテクト – プロフェッショナル(SAP)

2019年、当時の常駐先にてクラウドの重要性を知り、勉強を開始しました。AWSの実務に携わる機会のないまま勉強を続け、上級のSAPまで取得しました。

取得するまでの勉強期間は、初級のCLFが約3か月、中級のSAAが約5か月、上級のSAPが約1年でした。SAPは1度不合格になり、2021年3月の2回目の受験で取得しました。

本記事では、上級のSAP取得のための勉強方法を共有します。お役に立てば幸いです。

# 対象とする読者
SAAを取得済み、あるいは同レベルの知識をお持ちの方で、SAPの取得を目指している方。

# SAPの勉強方法
## 1. 知識の取得
以下の本で、SAP取得に必要な知識を身に着けました。問題集ですが解説が詳しいため、主に知識を得る目的で使用しました。
私が使用したのはペーパーバック版で、線を引いたり、ネットで調べた内容を余白に書き込みながら読み進めました。

https://www.amazon.co.jp/dp/B08DSYSM34

難点を上げるとすれば、問題番号と解答番号がずれていることです。解説ページの番号を1つ1つ手直しするのは面倒でした。。。

## 2. 問題演習
演習には以下を使用しました。

https://www.udemy.com/course/aws-solutions-architect-professional-practice-exams-amazon/

SAPの本番試験は問題文が長く、しかも原文の英語を（恐らく）機械翻訳しているため、読みにくいのが特徴です。
対策として、Chromeの翻訳機能をONにした状態で、上記の問題集を使用しました。機械翻訳になるため読みにくくはなりますが、むしろ本番試験に近い日本語で演習ができます。
1セットあたり75問ですが、空き時間に10問だけ解いて解説を読む、といった使い方をしました。

# 試験本番で集中力を維持する方法
問題文をマウスでドラッグして、反転表示させながら読むようにしました。
読み飛ばしを減らす効果もあります。

# 最後に
SAPの対策としては、この記事で紹介したもの以外にも行いましたが、むしろ遠回りになったと考えているため、省略します。