OmniAICreator/Qiita-1.07M huggingface dataset:
【コードレビュー】長い関数orファイルへのレビュー方法

レビューをよくするようになって何年か経つのですが、よく目にするのが１つの関数とかファイルの行数が長くて何をしてるのか把握が難しい状態です。
この場合は必要な処理が書かれているか初見では判断できないのでリファクタリングが必要だということで、次のようなステップでコメントをしています。

### 1. どこがどういう処理をしているのか説明をお願いする

コード自体が長くなっているときは実装した本人もどこが何のための処理なのか曖昧なことが多いので、まず説明をお願いしています。
説明がうまくいかない場合はこちらから「こういうことですか？」と質問したりしますが、こちらがわかっていてもいきなり答えを出したりしないで実装した側が説明できるようにしています。
レビュイーがこの辺をわかっているはず、という場合はこのステップは省いています。

### 2. その説明に沿って関数を分けてもらう

説明してもらった内容で処理のまとまりを考えてもらって関数化してもらいます。
このとき関数名で処理内容を説明できるようにしてもらいます。

ここでの認識違いが出ることはあまり無い印象ですが、お互い分け方に悩むような場合もたまにあります。

### 3. 各関数が長すぎないか確認する

同じ様に、分割した関数についても長くないか見直します。
１とか２に戻って繰り返すイメージになりますが、あまり修正を繰り返すと実装する側のメンタル面がしんどくなるので2回も3回も繰り返さないように多少先回りしてコメントするようにしています。

### 4. 各関数の処理が要求仕様と合っているか確認する

ここまで来てようやく要求仕様と実装がずれていないか確認できる状態になります。
もちろん手前までである程度状況は把握できているはずですが、最終確認をここでするようにします。

### まとめ

長くなりがちなコードはある程度の塊の処理がいくつも続いていることが多いので、関数に分けてその名前で処理内容を説明させるようにし、各関数がコンパクトになるようにします。
4が本来の目的であって「仕様と実装が合ってるか」を確認したいのですが、コードが長くて読み解くのが困難な場合は確認すること自体も間違いやすいので段階を踏んでリファクタリングしてもらうようにしています。
【Rails】database.ymlにMySQLのパスワードを設定する方法

# はじめに
今回は、Mysqlのパスワードを変更したことにより、発生したエラーの解消方法についてまとめました。

※おことわり※
基本的に学習内容のアウトプットです。
初学者であるため、間違い等あればご指摘いただけますと嬉しいです。

# この記事の目的
以下内容のアウトプット
- Mysqlのエラーとその解消方法
- database.ymlにMySQLのパスワードを設定する方法

# 開発環境
- Ruby 2.6.5
- Ruby on Rails 6.0.0
- MySQL 14.14

# この記事の内容
1. Mysqlのエラーの概要
2. Mysqlのパスワードを確認
3. database.ymlにMySQLのパスワードを設定

# 1. Mysqlのエラーの概要
Mysqlのパスワードを設定(変更)したことにより、ローカルでサーバを立ち上げた際にエラーが発生しました。

※エラー解消のプロセスでNOとYESのエラーに遭遇しましたが、最終的にエラー解消できました。
```
Mysql2::Error::ConnectionError: Access denied for user 'root'@'localhost' (using password: NO)

Mysql2::Error::ConnectionError: Access denied for user 'root'@'localhost' (using password: YES)
```

- **エラーの内容**
rootユーザのパスワードが正しくないため、データベースにアクセスできない。

- **エラーの原因**
database.ymlのpasswordが設定できていなかったため。

- **エラーの解消**
database.ymlにパスワードを追記する。

# 2. Mysqlのパスワードを確認
念の為、現在のパスワードが正しく登録できているか確認します。

**手順**
①`mysql -u root -p`を実行する
②`Enter password:`と出力されるのでパスワードを入力
③`Welcome to the MySQL monitor...省略`と出力されたら成功

```
% mysql -u root -p
Enter password: # パスワードを入力する
```

# 3. database.ymlにMySQLのパスワードを設定
シェルを用いて環境変数を定義し、ymlファイルにパスワードを追記します。

**手順**
①`vim ~/.zshrc`を実行
②`iキー`をクリックし、インサートモードに移行
③zshの内部に、以下の記述を行う
```
export DATABASE_PASSWORD='先程確認したパスワード'
```
④`escキー`をクリック → `:wq`を入力 → `Enterキー`をクリック
⑤`source ~/.zshrc`を実行
⑥database.ymlにパスワードを追加する
```
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: <%= ENV['DATABASE_PASSWORD'] %> #　追記
  socket: /tmp/mysql.sock

production:
  <<: *default
  database: XXX_production
  username: XXX
  password: <%= ENV['DATABASE_PASSWORD'] %>　　#　追記
```

`rails db:migrate`を実行し、エラーが出なければ成功です。
Hyper-Vをコマンドから操作する！

# manahyとは
Go言語で開発したHyper-Vを管理するためのツールです。現在は機能は少ないですが、今後、追加していく予定です。
<a href="https://github.com/DevelopNaoki/manahy">レポジトリ</a>

## 実装している機能
- Hyper-Vが有効化されているか確認する
- VMの一覧取得
- VMの電源操作

## 今後実装する（したい）機能
- Hyper-Vの有効化
- VMSwitchの一覧取得
- VHD / VMSwitch / VMの作成・削除機能
- VHD / VMSwitch / VMの各種パラメータの変更機能

# インストール
<a href="https://github.com/DevelopNaoki/manahy/tags">ここ</a>から実行ファイルをダウンロードし、PATHの通っている場所に保存するもしくは、PATHを通してください。

Powershellもしくcmdを開き、`manahy version`と入力、実行してください。以下のような結果が表示されればインストール完了です。
```
> manahy.exe version
manahy version 0.0.0 (beta)
```


# 使い方
manahyは以下のサブコマンドで構成されています。
```
> manahy.exe -h
manahy is management tool on Hyper-V

Usage:
  manahy [flags]
  manahy [command]

Available Commands:
  completion  Generate the autocompletion script for the specified shell
  help        Help about any command
  hyperv      management Hyper-V
  version     print manahy version
  vm          management vm on Hyper-V

Flags:
  -h, --help   help for manahy

Use "manahy [command] --help" for more information about a command.
```

## completion
PowerShell上でサブコマンドの補完できるスクリプトを生成します。
```
> manahy.exe completion powershell -h
Generate the autocompletion script for powershell.

To load completions in your current shell session:

        manahy completion powershell | Out-String | Invoke-Expression

To load completions for every new session, add the output of the above command
to your powershell profile.

Usage:
  manahy completion powershell [flags]

Flags:
  -h, --help              help for powershell
      --no-descriptions   disable completion descriptions
```

## hyperv
Hyper-Vの設定を行うコマンドです。
```
> manahy.exe hyperv -h
management Hyper-V

Usage:
  manahy hyperv [flags]
  manahy hyperv [command]

Available Commands:
  check       check Hyper-V Enabled

Flags:
  -h, --help   help for hyperv

Use "manahy hyperv [command] --help" for more information about a command.
```

## vm
VMの操作、管理を行うコマンドです。
```
> manahy.exe vm -h
management vm on Hyper-V

Usage:
  manahy vm [flags]
  manahy vm [command]

Available Commands:
  destroy     destroy VM
  list        Print VM list
  reboot      reboot VM
  resume      resume VM
  save        save VM
  shutdown    shutdown VM
  start       start VM
  suspend     suspend VM

Flags:
  -h, --help   help for vm

Use "manahy vm [command] --help" for more information about a command.
```
* VMの操作には、VM名を指定する方法とVMIDを指定する方法の2種類があります。
* 同名のVMが存在する場合、VM名を指定することで全てのVMに対して操作が行われます。ただし、VMIDを指定した場合は、そのVMIDを持つ1つのVMに対してのみ操作が行われます。

# Help
## 実行結果が文字化けした場合
以下のコマンドを実行してみてください。
```
> chcp 65001
```

## エラーが発生した場合
権限が足りていない可能性があります。管理者権限で実行してみてください。
【初心者】Dockerのインストール

# Dockerとは
- Docker社が開発した仮想環境を作るためのソフトウェアのこと
- Linuxが持つ仮想化技術で実行環境を他のプロセスから隔離し、その中でアプリケーションを動作させる
  - コンテナ内のアプリケーションから見ると、独立したコンピュータ上で動作しているように振る舞う
- OSをわざわざ開かなくてもアプリケーションを使えるため起動が早い
- OS、ライブラリ、アプリケーションコードがひとまとまりになっており、Dockerを使えばアプリケーションを動かすことができる

### 仮想環境とは
- PCなどのハードウェア内で構築された仮想的な環境
- PCの中に作られたPCに似たような環境のこと
    - 仮想環境の中でアプリケーションを動かすことができる
## Dockerはいつ使われるのか
- アプリケーション開発で多く使われる
    - 理由は、チームの開発環境を同じにできるため
        - インストールしているアプリケーションやOSのバージョンなどは個々によって異なり、皆が同じ環境を持っていることはほぼない
        - チームで開発をする際、それぞれのPCの状態が違うとアプリケーションの動きも違ってくる（→正しく開発が進められない）
:::note
そこで、Dockerを使えばそれぞれが同じ仮想環境を作ることができる
:::
:::note
開発に必要なソフトをまとめて用意でき、メンバーの開発環境を全く同じ状態にできるのがDockerのメリット
:::

# Dockerのインストール（Mac）
https://docs.docker.com/desktop/setup/install/mac-install/
##### 1. 遷移先の<INS>Docker Desktop for Mac with Apple silicon</INS>をクリックしダウンロード
##### 2. Applicationにドラック&ドロップ
##### 3. Dockerアプリを起動したらメニューバー（Macの画面上部）にクジラアイコンが表示される
##### 4. iTerm2（terminal）でバージョンを確認
```terminal:terminal
$ docker --version
```
`Docker version 20.10.17, build 100c701`
と、上記のように表示されていればOK！

## Dockerの仕組み
```terminal:terminal
$ docker run hello-world
```
`Hello from Docker!`と出力されていたら成功

### 起こっていること
:::note
**Dockerが何をしているのかをしっかりと理解しておくことが大事**
:::
`$ docker run hello-world`とコマンドを実行することで
##### 1. Dockerクライアント（依頼主）がデーモン（バックグラウンドで動作し続けるアプリ）にタスクを実行するよう伝える
##### 2. Dockerデーモンがコマンドを受け取る
##### 3. `hello-world`というDockerのイメージをDockerレジストリから取得してくる
 （Dockerレジストリにアップしておき、必要な時はDockerデーモンがレジストリからイメージを自分のPCに取得）
##### 4. 取得したイメージからコンテナを作成して起動
##### 5. `Hello from Docker!`と表示される
    
| 用語 | 説明 |
| --- | --- |
| Dockerイメージ | アプリケーションのコード、依存ライブラリ、実行環境（OSの一部）をまとめた実行用のテンプレート（コンテナを立ち上げる際に必須） |
| Dockerレジストリ | イメージをオンライン上で保存しておく場所 |
| Dockerコンテナ | イメージから生成された仮想サーバ |

## コンテナとは
Linuxが持つ仮想化技術で実行環境を他のプロセスから隔離し、その中でアプリケーションを動作させる。

コンテナはLinuxの通常のプロセスとほぼ同じものだが、利用できる名前空間やリソースが他のプロセスやコンテナからは隔離され、それぞれ固有の設定を持てるようになっている。

そのためコンテナ内のアプリケーションから見ると、独立したコンピュータ上で動作しているように振る舞う。コンテナを管理するコストはプロセスを管理するコストとほとんど変わらず、仮想マシンを管理するコストと比較すると非常に軽い。

## Linux
- LinuxはOSの一種
    - OSはコンピュータを動かすための基本ソフトのこと
- WebサービスはLinux上で開発するのが主流
:::note
Dockerを使う時、OSはLinuxを使っているためLinux操作は必須
:::

## Docker使用時の注意点
#### 1. 容量が減らない場合がある
- イメージやコンテナを削除しても、ファイルがゴミとして残ってしまいPCの容量が圧迫されることがある
  - 気づかないうちにPCの容量が足りなくなってしまうことも
  - その場合は下記コマンドを実行
      - ファイルをゴミとして残さず、PCの容量を減らすことができる
```terminal:terminal
$ docker system prune
```
#### 2. 一つのOSしか使えない
- Docker以外の`VMwarePlayer`などは別のOSの仮想環境を作ることが可能
    - VMwarePlayerの例：WindowsのPCにMacOSの仮想環境を作り、Macでしか使えないアプリケーションを使うことが可能
- DockerはPCに元々入っているOSからコンテナという仮想環境を作る
    - そのため、別のOSの仮想環境を作ることはできない

:::note
どのような環境が必要なのか、どんな利用をするのかをまず考えDockerを利用する
:::

## NextStep
https://qiita.com/rexid/items/4ea724cef462560039da
[python] 特定の名前を持つファイルを自分のデスクトップに集める方法

# はじめに
欲しいと思ったファイルを会社の共有フォルダから見つけ出すことは時間がかかってしまう。
共有フォルダは自分が欲しいファイル以外にも多くのファイルが存在するからだ。
また、フォルダでのファイル検索機能だとファイルが多すぎて時間がかかりすぎてしまう。
今回は必要な名前を持つファイルをすべて自分のデスクトップのフォルダにコピーしてくることを目標とする。

# 環境
python 3.7.8
window 10

# 構成
```
┃
┣━━ 共有フォルダ/
┃   ┗━━━━ Delta/
┃       ┗━━━━ CBA001/
┃           ┗━━━━ CBA001.xlxs
┃   ┗━━━━ Oil/
┃       ┣━━━━ CBA001 30'.xlxs
┃       ┗━━━━ CBA001.xlxs
┃   ┗━━━━ 成分調査/
┃       ┣━━━━ CBA001 in Water.xlxs
┃       ┗━━━━ CBA001.xlxs
┃   ┗━━━━ 強度/
┃       ┣━━━━ CBA001-007 200h.xlxs
┃       ┗━━━━ CBA001-007.xlxs
```

データはすべて通し番号で管理され、今回必要なデータは`CBA001`のようになっている。
共有フォルダ内はデータの種類ごとに保管される。

# 条件
- コピーした後のファイル名を、ファイルの上位フォルダ名（項目名で）で区分することで重複を防ぐ。

- Dletaフォルダのように、フォルダのフォルダ内に存在するファイルもコピーすること。
# Code


```python
import os
import glob
import shutil

target_name = input('ファイル名を入力してください。: ')

dir_data = os.path.expanduser('~/Desktop') + fr'\{target_name} Data'
os.makedirs(dir_data, exist_ok=True)
# デスクトップにフォルダを作る。

file_share_path = rf'C:\Users\junsa\Desktop\共有フォルダ\**\*{target_name}*.xlsx'
list = glob.glob(file_share_path, recursive=True)
# サブフォルダを含めて再帰的にファイルを探索する

for file in list:
    Copyfile(file)
```

```python
def CopyFile(file_target: str):
    dir_share = r'C:\Users\junsa\Desktop\共有フォルダ'
    dir_list = os.listdir(self.dir_share)
    print(dir_list)
    #['Delta', 'Oil', '強度', '成分検査']
    
    #上位フォルダ名をつけて保存する。 
    for dir_name in dir_list:
        if dir_name in file_target:
            shutil.copy2(file_target, dir_data + fr'\{dir_name} {os.path.basename(file_target)}')
```

# 結果

![スクリーンショット 2022-09-22 234846.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/1d4513e0-7c48-7527-c934-cfc0a9d06ed8.png)


# まとめ
上位フォルダ名をつけることによってファイル名の重複を防ぎ、ファイルをすべて保存することができる。
`os`や`glob`の組み合わせでフォルダ内のファイルのほとんどを条件付きで探すことができる。
必要な時だけファイルをコピーして不必要になったら消したらいいので、デスクトップ画面をきれいに保つことができ、ファイルを探す手間が減ります。


### 過去の投稿


https://qiita.com/junzai/items/3b83d26c5573b597d7ab


https://qiita.com/junzai/items/05d2ffab903e57b47233
Macのターミナル(Zsh)でCtrl + K(kill-line)が効かなくなってZLEを知ったお話

# 概要
ある日、いつものようにターミナル操作をしていて、Ctrl + k で行末まで削除(kill-line)を実行しようとすると、
```sh
Symbol index NOT found, NO DATA to show, sleeping...
```
と表示され、kill-lineが効かなくなってしまった。
![スクリーンショット 2022-09-22 23.37.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2430330/a58557e0-d75c-16e5-552b-4e218c70d6e1.png)

# ZLE (Zsh Line Editor)
テーマなどの拡張を切って、色々試行錯誤していると、Ctrl + k を押したあとに、`zle-line-pre-redraw`と表示されていることが分かった。
その後も調査したところ、ZLEという機能があることを知り、キーバインドを色々設定できることが分かった。
![スクリーンショット 2022-09-22 23.41.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2430330/57213220-0d7d-e4e5-fa72-eb6497479895.png)

# 回避策
なにかの拡張機能がこのキーバインドを変更しているようだったので、以下の記載の記事を参考に、自分のZshのプロファイル(`.zshrc`)の末尾にkeybindをリセットするコマンドを仕込んだ。
```zsh:zshrc.rc
bindkey -d
```
ちなみに`bindkey`単体で実行すると、現在の設定が出力される。（これで、デフォルト設定との差分があることが分かった。）

https://qiita.com/yuku_t/items/e58cbecf13407446bd50
Mellanox ConnectX-2を使ってWindows Server 2019でIPoIBしてみる

ヤフオクで激安のInfiniband製品買い集めたのでWindowsServer2019で使ってみる。

- [実効速度 Over 20G 高速ネットワークを予算1\.5万円で作る \- Qiita](https://qiita.com/TumoiYorozu/items/3e36654fac8b1d60e371)
- [Mellanox OFEDを整理 \- Qiita](https://qiita.com/koseda0136/items/967dddd3b52091169cda)

## ハードウェア

- HCA (NICみたいなカード) 
    - Sun Oracle Infiniband 40Gbps 2Port 4x QDR MHQH29B-XSR
        - [Mellanox ConnectX-2](https://www.newtech.co.jp/products/end/connectx2/) 同等品
    - ヤフオクで１枚 2100円
- IBスイッチ [Mellanox IS5023](https://www.newtech.co.jp/products/end/mis5023/)
    - ヤフオクで9000円
- ケーブル
    - [QSFP+ 1m パッシブケーブル](https://www.fs.com/jp/search_result?keyword=qsfp%20%201m&sort_order=price)
    - FS.com で3本1万円ちょっと


動作テスト用のサーバーは事務所に転がってた古いやつ

1. HP Proliant DL360G7 Xeon L5640 *2  Windows Server 2019 バージョン1809
1. Dell Poweredge R730 Xeon E5-2630v3 *2 Windows Server 2019 バージョン1809

Proliantの古さが泣けるｗ

## インストール

とりあえずWindows Server 2019 をクリーンインストール。
この時点でHCAはConnectX-2として認識されてた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199750/77ffcb3e-1211-4377-6206-9ddfa57377f4.png)

### ドライバのインストール

[Mellanox OFED for Windows \- WinOF / WinOF\-2](https://network.nvidia.com/products/adapter-software/ethernet/windows/winof-2/) からダウンロード。

特に気にしないで色々見ながらダウンロードしたら微妙に古いバージョンダウンロードしちゃった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199750/45753e63-fd11-59e8-d804-ebf9c6b35dec.png)

最新は5.50.54000 だけどインストールしたのは 5.50.52000

ConnectX-2はWindowsServer2012 以降はサポート対象外だから入らないのかと思ったけど案外すんなりインストールできた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199750/0b90f48e-a128-acc7-bd19-a4ad7f5474e2.png)

ここまでではまだリンクステータスがdiscon だった。

### サブネットマネージャ起動

ドライバをインストールしたら`C:\Program Files\Mellanox\MLNX_VPI\IB\Tools`にツールがインストールされてるので

```bat
sc create OpenSM binpath="C:\Program Files\Mellanox\MLNX_VPI\IB\Tools\opensm.exe -service" start=auto
sc start OpenSM
```

してサービスの登録してからサブネットマネージャを起動する。

ここでリンクがActiveになった。

## ネットワーク設定

それぞれのサーバーに固定IPを振る

1. HP Proliant 10.90.90.20
1. Dell Poweredge 10.90.90.10

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199750/7f0d5071-719f-36da-a468-a80559b110c1.png)
(1回FirewallのICMP Echo 開き忘れて途方に暮れたりした)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199750/14496890-9ddd-494a-5002-fde68cbbcbfb.png)

## 速度測定

[iperf3](https://iperf.fr/iperf-download.php#windows) をダウンロードしてProliant側にサーバーを立てる
```bat
D:\temp\iperf-3.1.3-win32>iperf3.exe -s
```

Poweredge側からiperf3起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199750/a60509f8-ccbf-ca29-e7ac-cf9a87da283a.png)

(40G出るはずが3.5Gしか出てないけど) ヨシ！

## ダウンロード実測

Proliant側に共有フォルダを作成してSMBでコピーしてみる。
コピーするのはDellのService Update Utilityのisoイメージ 16GB

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199750/5905ad13-0710-9d89-6390-de4d2406ec56.png)

はっや

## まとめ

クソ古激安InfinibandカードでもまぁまぁなIPoIB環境は作れるもんだね。
ひかり電話ルータ (RT-400NE) に Asterisk をつないでハマったことまとめ

## 概要

- Asterisk/Pjsip は endpoint に `outbound_proxy = sip:<HGWのIPアドレス>` が設定されていると Invite の Request URI にそれを送る。
- ひかり電話のインタフェースでは，ダイヤルされた番号を Request URI の userinfo 部に含めなくてはならない。
- したがって，ひかり電話ルータに Asterisk をつなぐ際には，この設定を使用してはならない。

ここをミスると，HGW から 400 Bad Request が返ってくる。Asterisk には「Everyone is busy/congested at this time」しかログされないことに注意。(pjsip set history on/off で SIP メッセージのロギングを有効化/無効化できる。)

## 設定

pjsip_hikari.conf

```
;ひかり電話HGW
;
[hikari-hgw]
type = aor
contact = sip:4@10.198.1.1 ;<- 内線番号@HGWのIPアドレス：内線番号はHGW内の内線番号で1桁の数字
qualify_frequency = 30
authenticate_qualify = no
outbound_proxy = sip:10.198.1.1 ;lr <- HGWのIPアドレス

[hikari-hgw]
type = auth
auth_type = userpass
username = 0004 ;<- HGWの内線ユーザ(通常は0003とかになるもの)
password = ZjoCLk9d ;<- HGWの内線パスワード

[hikari-hgw]
type = identify
endpoint = hikari-hgw
match = 10.198.1.1 ;<- HGWのIPアドレス

[hikari-hgw]
type = registration
transport = transport-udp ;<- 別途設定したtransportを指定
outbound_auth = hikari-hgw
server_uri = sip:10.198.1.1 ;<- HGWのIPアドレス
client_uri = sip:4@10.198.1.1 ;<- 内線番号@HGWのIPアドレス：内線番号はHGW内の内線番号で1桁の数字
retry_interval = 60

[hikari-hgw]
type = endpoint
transport = transport-udp
context = from-hikari
dtmf_mode = inband
disallow = all
allow = ulaw
direct_media = no
send_pai = yes
;rtp_symmetric = no
;force_rport = no
;rewrite_contact = no
inband_progress = yes
from_user = 4 ;<- HGW内の内線番号
from_domain = 10.198.1.1 ;<- HGWのIPアドレス
;outbound_proxy = sip:10.198.1.1 ; <- HGWのIPアドレス
language = ja
outbound_auth = hikari-hgw
aors = hikari-hgw
```
FortiGateでSSHキーを使ったログイン設定

# はじめに
FortiGateでSSHログインする際にSSHキーを利用してログインする設定をよく忘れるので備忘

# 手順
### 1.SSHキーの作成
SSHキーを作成ツールは何でもよいが今回はTeraTermで作成。
`[Setup] > [SSH Key Generator...]`を選択し 鍵の種別、鍵長を設定して`[Generate]`を選択。
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577993/99ee4012-8e19-9cdd-5893-f34bb4d164b4.png)

鍵のパスフレーズ、コメントの設定を行い`[save public key]`、`[save private key]`を選択し、公開鍵、秘密鍵をそれぞれ保存する。
![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577993/28f38a04-8220-c13b-e036-9462b3d64f24.png)

:::note info
パスフレーズの設定は空欄でも問題ありません
:::

### 2.FortiGate側に公開鍵を設定
SSHキーでログインしたいユーザに公開鍵を設定する(CLIでのみ実施可)。

:::note info
1ユーザにつき最大3つの公開鍵を設定可能です
:::

```
set ssh-public-key1 "<type> <public key>"
```

\<type> \<public key>についてTerTermで作成している場合公開鍵をメモ帳等で開くと`<type> <public key> <comment>`の並びとなっているため、必要個所を適宜コピーする。

:::note warn
改行が含まれていると正しく通らないので、一行にまとめること
:::

![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577993/c1fe9353-20f4-e388-5c0f-d07c58696f15.png)


### 3.ログイン
TeraTermでSSHログインを実施する。
ユーザ名に手順2で設定したユーザ名を入力し、パスフレーズを設定した場合はパスワード欄にパスフレーズを入力、ログイン方式として「Use RSA/DSA/ECDSA/ED25519 to log in」を選択しする。
`[Private key file]`から対応する秘密鍵を選択し`[OK]`を押してログインする。

![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577993/1d5ff78d-7c82-d521-11fd-30ded4496176.png)
Google UXデザイン：デザイン思考のフレームワーク

# はじめに

わたしが[Google UX Design Certificateで得られた素晴らしい体験][google]を、特に重要だと思われるポイントを小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ Google UX Design Certificateを受講してみてください。

[google]: https://qiita.com/mapami/items/7a0d0a3d4661c50f8bec

https://www.coursera.org/professional-certificates/google-ux-design

# デザイン思考のフレームワークとは

デザイン思考のフレームワークは、ユーザー中心の問題解決アプローチであり、ユーザーは誰か、彼らの問題は何か、デザインは何を含むべきかを理解するのに役立ちます。

このフレームワークは５つのフェーズで構成されています。
1. Empathize: 共感
1. Define:　定義
1. Ideate: アイデア
1. Prototype:　プロトタイプ
1. Test: テスト

![スクリーンショット 2022-09-22 20.39.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/4ee04019-ca98-2e6a-b105-053264e72cb6.png)

直線的なプロセスに見えますが、このフレームワークは反復的であるべきです。つまり、デザインを洗練させるために特定のフェーズを繰り返すということです。例えば、テストで得られたフィードバックに応じて、さらなるリサーチや新しいアイデアのブレーンストーミング、新しいプロトタイプの開発が必要になるかもしれません。

## 共感

ユーザーとその問題、欲求、ニーズ、そしてユーザがデザインを体験する環境や状況についてより深く知ることが目標です。

重要なことは、思い込みや推測から離れ、リサーチ結果をあとのデザインフェーズの意思決定に反映させることです。

ユーザーリサーチには、アンケート、インタビュー、観察などが含まれます。

また競合製品に関するリサーチも必要かもしれません。


## 定義

このフェーズでは、共感フェーズで得たリサーチ結果を分析し、どのユーザーの問題を解決することが最も重要なのか、またその理由は何なのかを決定します。

重要なことは、明確な問題提起であり、あなたのデザインが解決しようとするユーザーのニーズの記述することです。


## アイデア

アイデアの目標は、できるだけ多くの設計ソリューションを考え出すことです。最も明白なソリューションが常に正しいソリューションであるとは限らないため、最初のソリューションに妥協しないでください。

アイデアには、チームの他のメンバーとの共同ブレーンストーミングが含まれ、問題に対して可能な限り多くの解決策を生み出します。これには、マーケティング、エンジニアリング、製品管理、または製品やサービスに関するその他の利害関係者が含まれる可能性があります。

ブレーンストーミングセッションでは、考えられるすべての解決策を検討する必要があります。何かが「良い」アイデアなのか「悪い」アイデアなのかに焦点を当てるのではなく、できるだけ多くのアイデアを集めてください。

ブレーンストーミング後、潜在的なソリューションを分析し、プロトタイプとして追求するのに最適なオプションを選択します。ユーザーまたは競合他社の調査に戻ってアイデアを絞り込むことができます。

また、ユーザーフローを作成して、ユーザーがソリューションをどのように操作するかを説明することもできます。


## プロトタイプ・テスト

プロトタイプフェーズでは、機能を実証し、テストに使用できる製品の初期モデルを作成することを目標としています。

プロトタイプ作成とテストは相互に関連しています。つまり、プロトタイプの作業が完了するまでテストを待つのではなく、プロトタイプ開発の各段階で設計をテストします。初めてユーザーにデザインを提示するときにデザインが洗練されすぎていると、あまりフィードバックが得られない可能性があります。ユーザーのフィードバックに基づいて設計を繰り返すことができるように、設計プロセス全体にテストを含める方法を検討してください。

- たとえば、簡単なスケッチ、ワイヤーフレーム、またはサイトマップをユーザーに提示することで、デザインの背後にある概念をテストできます。

- 学んだことを踏まえて、次は紙より詳細な設計（忠実度の低いプロタイプ）で、ユーザーテストをもう一度実行することができます。
- ある時点において、FigmaやAdobe XDなどのツール（忠実度の高いプロトタイプ）を使用して、実用的なインタラクティブモデルにし、それもテストします。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/b3df27ef-4547-b27d-60ab-39c7ebe0a111.png" width="250">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/35c28b40-1796-cda2-9241-67e0154eac53.png" width="140">

プロトタイプ・テストフェーズの目標は、製品またはサービスの設計が使いやすく、ユーザーの問題を解決するかどうかについて洞察を得ながら、プロトタイプを改良し続けることです。

最終的にある時点において、プロトタイプを完成し、それを開発者に提供することで、開発者はあなたのデザインを製品に変えてくれます。
Swiftで行列の計算

## はじめに

Swiftでsimdの計算に初めて取り掛かる場合、まずはじめに以下の記事を読むことをお勧めします。
https://developer.apple.com/documentation/accelerate/working_with_matrices


![スクリーンショット 2022-12-16 0.15.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510204/dc95fbe5-cb14-e417-ab48-41c052dbfa43.png)

記事にもある通り、列優先の命名規則になります。

## 計算の確認ツール

[Matrix Multiplication](http://matrixmultiplication.xyz/)を計算手順の思い出し & 計算結果の確認使用します。

## 列ベクトル

列ベクトルが一般的だと思いますが、行ベクトルで生成、計算することも可能です。

![スクリーンショット 2022-09-22 23.05.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510204/0e51dc71-71f9-6000-dc96-985b04915658.png)

``` simd.swift
import simd

let vector = simd_float4(-0.8, 0, 0, 1)
// 4x4の変換行列（列優先）
let transformA = simd_float4x4([
    simd_float4(-0.07, 0, -0.9, 0),
    simd_float4(0, 0.9, 0, 0),
    simd_float4(0.9, 0, -0.07, 0),
    simd_float4(-0.8, 0.01, -1.58, 1.0)
])

let rowResult1 = simd_mul(transformA, vector)
print(rowResult1)
// > SIMD4<Float>(-0.744, 0.01, -0.8600001, 1.0)
```

## 行ベクトル


![スクリーンショット 2022-09-22 18.24.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510204/86fcd56f-b9b6-0af7-50a4-9637fb6d3b8c.png)

引数に`rows`を指定することで行優先で作成することができます。

``` simd.swift
import simd

let vector = simd_float4(-0.8, 0, 0, 1)

// 4x4の変換行列（行優先）
let transformB = simd_float4x4(rows: [
    simd_float4(-0.07, 0, -0.9, 0),
    simd_float4(0, 0.9, 0, 0),
    simd_float4(0.9, 0, -0.07, 0),
    simd_float4(-0.8, 0.01, -1.58, 1.0)
])

let rowResult2 = simd_mul(vector, transformB)
print(rowResult1)
// > SIMD4<Float>(-0.744, 0.01, -0.8600001, 1.0)
```
FortiGateをReset APIで制御(ポリシー設定)

# はじめに

FortiGateをいろいろいじっている中でGUIやCLIでいちいちログインして変更するのが面倒になってきたので、
ポリシーの設定変更についてRESET APIで変更できるか試してみました。


# 環境
FortiVM64 (Ver 7.0.5)


# 手順
### 1. API管理者を作成
既存ユーザでログイン認証するのよくある方式だと思いますが、タイムアウトが面倒なため今回はRESET API専用のユーザを作ります

`[管理者] > [新規作成] > [RESET API管理者]`を選択
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577993/60761616-c04a-8280-653f-b16503e13283.png)

RESET API用ユーザの作成画面に移るので必要個所を設定

:::note info
今回は必要最小限(ユーザ名、管理者プロファイル)のみ設定しています
::::
![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577993/121fcbae-8e89-769c-7dce-05ffd7e67a43.png)

[OK]選択後、APIキーが発行されるため、コピーする

:::note warn
APIキーはこのタイミングでのみ取得可能なため、必ずコピー、保存して下さい
保存し忘れた場合はAPIキーの再生成操作が必要です
:::
![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577993/6b7e2360-c5dc-4ec2-5a31-f2ab8faed51b.png)

### 2. ポリシ設定変更用JSONファイルの用意
ポリシ設定変更内容をまとめたJSONファイルを作成curl実行環境と同じフォルダ等に保存してください
今回はポリシを無効化する設定を行うJSONファイルを用意します

```disable.json
{
    'json':{
        'status':"disable"
    }
}
```

### 3. コマンドの実行
FortiGateのIPアドレス、ポリシーID等`{}`部分を埋めて実行

>curl -X PUT "http://{FortiGate IP}/api/v2/cmdb/firewall/policy/{ポリシーID}?access_token={RESET APIユーザ APIキー}" -d @{JSONファイル名}

実行後正常に変更できた場合、statusがsuccessと表示されます
```:実行結果(成功例)
>curl -X PUT "http://192.168.1.254/api/v2/cmdb/firewall/policy/1?access_token=##############################" -d @disable.json
{
  "http_method":"PUT",
  "revision":"********************************",
  "revision_changed":true,
  "old_revision":"********************************",
  "mkey":"1",
  "status":"success",
  "http_status":200,
  "vdom":"root",
  "path":"firewall",
  "name":"policy",
  "serial":"FGVM************",
  "version":"v7.0.5",
  "build":304
}
```

GUI上でもステータスが無効化されているのが確認できます
![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577993/b436b4f6-5cf5-3aba-5948-0776cd3601be.png)

# 最後に
今回はポリシーの無効化操作を一例としてあげましたが、他の項目についても同じように設定変更が可能です。
ポリシー設定をGETすることで変更可能な項目が確認できるので試してみてください。
"&&"を使えばJSX内で条件式を簡単に記述することができる

はじめに
--
ReactでJSX内に条件によって画面に表示させる内容を変えたいと思い、調べた内容を備忘録としてまとめようと思います。


if文をJSX内で記述すると見づらかった
--
URLのパスが/userかどうかで表示させる内容を変えたいという記事の例です。
if文で実現しようとすると下記のように馴染みのある書き方ができますが、波括弧や括弧が多く個人的には見づらかったです。
他にも

~~~react
return(
  <>
    {(() => {
      if (location.pathname === (`/user`)) {
        return <p>userのページです</p>
      } 
    })()}
  </>
)
~~~

"&&"を使えばJSX内で条件式を簡単に書くことができる
--
[公式ドキュメント](https://ja.reactjs.org/docs/conditional-rendering.html#inline-if-with-logical--operator)の方法に論理演算子"&&"を使う方法が記載されていました。

構文は見当たりませんでしたが、公式ドキュメントを見る限り下記のように記述すれば問題ないと思います。
~~~
{ trueになる条件 && trueの時に返す式や値 }
~~~

そして、if文と同じ条件を"&&"で書くと、下記のようになります。
波括弧・括弧の数が減って見やすくなりました。

~~~react
return(
  <>
     {location.pathname === (`/user`) &&
       <p>userのページです</p>
     }
  </>
)
~~~

もちろん三項演算子でも書いたり色々と方法がありそうです。
できるだけ可読性が高く、量が少ない記述ができるように実装しながら学んでいこうと思います。

参考
--
https://ja.reactjs.org/docs/conditional-rendering.html#inline-if-with-logical--operator
小さなディスクでWindows Server VMを作る

## 検証用に作るVMのディスクコストを抑えたい
Azureで用意されている標準のWindows ServerのイメージでVMをデプロイするとディスクサイズが最小128GBになります。本番利用するマシンであればよいのですが、検証用に作るマシンだとこんなに容量は不要なことが多いと思います。ディスクは存在している限り課金されてしまうので、検証用途であればできる限りディスクサイズは減らしたいところ。そんな用途のために小さなディスク（30GB）が割り当てられたWindows Serverイメージが実はあります。

## 作成手順
1. VMの作成画面を開きます。
1. イメージを選択するプルダウンの下にある[すべてのイメージを表示]をクリックします。
![smalldisk01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/a345ba62-bd57-8eb7-159c-2c9d6ca592e7.png)
1. Marketplaceの画面が開きます。Windows Serverのタイルの左下にある[選択]をクリックします。Windows Serverのタイルが表示されない時はオペレーティングシステムのフィルタでWindows Server OSのみ選択したり、出版社のフィルタで「Microsoft」のみ選択してみてください。
![smalldisk02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/727f8282-0e88-5305-a78d-d7e466b24920.png)
1. 頭に[smalldisk] が付いているデプロイしたいOSバージョンを選択してください。
![smalldisk03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/38241946-f06b-ac14-22ec-dc777c96e631.png)
1. あとはいつも通りにVM作成ウィザードを進めてください。
1. デプロイ後のVMを確認すると、OSディスクが30GBでできていることがわかります。
![smalldisk04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/f2cb2e2e-fc00-86ae-5b96-33bc23a83727.png)
1. OS上からも30GBで認識されていることが確認できます。
![smalldisk05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/42dc69d4-53f0-d504-6ba4-52a346e5db60.png)

## 30GBでは足りないけど128GBもいらないという場合

ディスクの拡張は通常通り実施できるので、64GBにサイズアップできます。Azure Portalからディスクを64GBに変更してOS上からパーティション拡張を実施してください。
![smalldisk06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/31fd5c9f-4d18-b92e-f59a-889a21db3bd6.png)

なお、カスタムサイズを指定すれば50GBや100GBといったディスクサイズにすることができますが、Azureの場合はディスクサイズは階段状の料金体系になっています。50GBを指定すると64GBの料金、100GBを指定すると128GBの料金という課金が発生するので、よほどの理由がない限りはカスタムサイズを指定するメリットはありません。ですので、基本は32GB→64GB→128GB→256GB→…というようにサイズアップしていくことになります。

参考：[Managed Disks の価格](https://azure.microsoft.com/ja-jp/pricing/details/managed-disks/)

## 余談
smalldiskのイメージのディスクサイズはカスタムサイズで30GBになっているので、料金変わらず2GBを足すこともできます。
pythonでカッコのないメソッド呼び出しは何なのか。「メソッドオブジェクト」らしい。


# カッコのある通常のメソッド呼び出し

```py
arr = [3,2,1]
arr.sort()
arr # [1, 2, 3]
```

# カッコを付けないとメソッドオブジェクトが得られる

```py
arr = [3,2,1]
arr.sort # <built-in method sort of list object at 0x10bdb3e40>
arr # [3, 2, 1]
```

メソッドは実行されていない。
このオブジェクトはなんやねん。

# メソッドオブジェクトを一時変数に覚えさせておいて、あとで実行する

ってことが出来るようだ。

```py
arr = [3,2,1]

do_sort = arr.sort
do_sort()

arr # [1, 2, 3]
```

# 参考

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/dd7d6ec3-1fb3-6d2b-a71b-d97c5d63d1b6.png)

https://docs.python.org/ja/3/tutorial/classes.html#private-variables



# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
Cloud9でRailsアプリをデプロイする手順（開発環境）

## こんな方向け
・　Cloud９でアプリのデプロイのやり方を知りたい
・　データベースの作成までのやり方を知りたい



## 大まかな手順
1. データの反映
2. Rubyのバージョン確認
3. MySQLのインストール
4. MySQLのパスワードの修正
5. database.ymlのファイルの修正
6. データベース（DB）の作成
7. Railsアプリを起動


### 1. データの反映
・git cloneでアプリ格納場所のリポジトリをローカルに落とす

```
$ git clone <HTTPSのURL>
```

### 2. Rubyのバージョン確認
・Railsのバージョン確認
```
$ ruby -v
```

### 3. MySQLのインストール

```
sudo yum -y update

# mariadbを削除
sudo yum remove -y mysql-server
sudo yum remove -y mariadb*

# インストール
# Amazon Linux2

MYSQL_PACKAGE_URL="https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm"
sudo yum localinstall -y $MYSQL_PACKAGE_URL
sudo yum install -y mysql-community-devel
sudo yum install -y mysql-community-server
```

・ MySQLサーバーの起動＆確認
```
sudo service mysqld start && sudo service mysqld status
```

・ 初期パスワードの確認
```
sudo cat /var/log/mysqld.log | grep "temporary password" | awk '{print $13}'

# ↑で出てこない場合に入力
sudo cat /var/log/mysqld.log | grep "temporary password"


# MySQLにログイン（パスワードが表示されるので、必ずコピーしておく）
mysql -u root -p
```

### 4.Mysqlのパスワードの修正

・パスワードの修正は下記の記事を参考にしてください

https://qiita.com/ttyoku/items/f7b5c763cbe5ff80eed4


### 5. database.ymlのファイルの修正（usernameやパスワードの追加）

**開発環境のコードを修正する必要があるので、修正
→これをやらないと、エラー沼にハマるので注意**

```
# database.ymlのファイル内を修正

adapter: mysql2
encoding: utf8
database: ~~~~~~（デフォルト名）
pool: 5
username: root（今回は開発環境なのでroot）
password: MySQLインストール後に変更したパスワード（これないとデプロイできない）
host: localhost
```

上書き保存をする

**注意**：Railsには、「開発」「テスト」「本番」の3つの環境があり、今回のデプロイは「開発環境」でのデプロイを想定


### 6. データベース（DB）の作成

MySQLのインストールと、database.ymlの編集が終わったらいよいよデータベースの作成に入る


下記コマンドでconfig/database.ymlの設定内容にをもとにデータベースが作成される

```
$ rails db:create
```

余談だが、本番環境のデータベースを作成したい場合は
```
$ rake db:create RAILS_ENV=production
```


migrationファイルの内容をDBに反映する
→メリットは、SQL構文を書かずともDBにアクセスしてデータをいじれることらしい

→まだよくわかってないが、下記記事を参照

https://qiita.com/ichihara-development/items/9e9a8454178947eb519d

```
$ rails db:migrate
```


### 7. Rails アプリを起動

アプリをデプロイします。
```
・rails s
```

デプロイがプレビューでアプリを見てましょう！

・preview→preview Running Applicatonで起動


・起動が遅い、できない場合は下記のコマンドで不要なコンテナを削除してみてください
```
$ docker system prune -a
```
PS1のメモリカードをPSVita ゲームアーカイブスに持っていく

# 概要

SONY 公式の「コンテンツ管理アシスタント」をインストールすると、Windows上にセーブデータがバックアップでき、また復帰も可能である。

https://manuals.playstation.net/document/jp/psvita/cm/installcma.html

PS1 ゲームアーカイブスのセーブデータ(メモリカード) は、拡張子 .vmp ファイルで、中身は128バイトのヘッダ + 128KB のメモリカードのまんまである。
ならば Play Station のメモリ カードのデータを吸って Vita で継続プレイできるのでは?

# PS1(.mcr) → Vita(.vmp) 変換

「mcr vmp 変換」あたりでググると色々出てくる。
変換ツールもあるので、それを使えば終わりな話ではある。
が、とある理由から自前で作成することに…

# .vmp データ構造

| オフセット | 項目       | バイト数 | 内容        |
|:-----------|:-----------|---------:|:------------|
|0x000000    | マジック   | 4        | 'VMP'       |
|0x000004    | オフセット | 4        | 128(0x80)   |
|0x000008    | ?          | 4        | 0           |
|0x00000C    | シード値   | 20       | 28292A2B... |
|0x000020    | HMAC       | 20       | 計算値      |
|0x000034    | ?          | 76       | 0埋め       |
|0x000080    | データ     | 131,072  | .mcr データ |
|0x200080    |

シード値をAES128でガチャガチャやって鍵を作成。
んで SHA1 HMAC 取ってる。

てきとーにコードを書き書き。
https://gitlab.com/nekodevteam/nekocrypto/-/tree/main/samples/mcr2vmp

でした。
【メモ】LaravelでDDDした時の各ファイルが所属するレイヤー図

LaravelでDDDを適用する際の各ファイルが所属するレイヤーを図にしてみたのでメモ。
![figure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542326/3f612012-c699-8517-ce57-f56c4fbef5ab.png)
【画像解説つき】Sassでよく使うスタイルの定義と呼び出し方法

## ①ファイル構成
sassファイルにmixinフォルダ、moduleフォルダを作成し、
mixinフォルダに_common.scssファイル
moduleフォルダに_btn.scss、_index.scssを作成します
![04.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784679/28a08b4a-9e16-58f0-2c67-97540d48af01.png)
## ②それぞれのファイルにコードを記述する
それぞれのファイルに以下のように記述していきます
**■_common.scssファイル**
よく使うスタイルを「＠mixin」を使って定義する
**■_btn.scssファイル**
＠mixinを利用するには **＠include** を使用します
①ファイルの先頭に＠useを記述してmixin定義ファイルを読み込む
②利用したい場所に＠includeを記述してよく使う定義を呼び出す
**■_Index.scssファイル**
＠useで_btn.scssを読み込む
**■style.scssファイル**
＠useでモジュールフォルダを読みこみます
CSS優先度を利用してBEMのブロックを超えて利用するデザインを先に読み込みます
mixinフォルダは定義を管理しているだけのファイルなので読み込みません

![04-2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784679/4b80e110-c0a9-fce8-12e7-124613f7efc7.png)
## ③生成されたファイルを確認する
保存するとstyle.cssファイルに_common.scssで記述したコード、
_btn.scssで記述したコードが生成されたことが確認できました
![04-3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784679/2699ad38-db46-a849-554c-ef993a0e490a.png)

共通したデザインがあるとき＠includeを使うとコンパクトに記述ができます
【学習記録】応用情報4

# はじめに
学習記録の4です。
# 間違えたところ・知らなかった単語



## イノベーション理論について
> 革新的な商品・サービスなどのイノベーションの普及に関する理論に「イノベーション理論」というものがあります。この理論では、商品購入の態度を新商品購入の早い順に5つの層に分類しています。
イノベータ（Innovators：革新者）
冒険心にあふれ、新しいものを進んで採用する人。
アーリーアダプタ（Early Adopters：初期採用者）
流行に敏感で、情報収集を自ら行い、判断する人。他の消費層への影響力が大きく、オピニオンリーダとも呼ばれる。
アーリーマジョリティ（Early Majority：前期追随者）
比較的慎重派な人。平均より早くに新しいものを取り入れる。ブリッジピープルとも呼ばれる。
レイトマジョリティ（Late Majority：後期追随者）
比較的懐疑的な人。周囲の大多数が試している場面を見てから同じ選択をする。フォロワーズとも呼ばれる。
ラガード（Laggards：遅滞者）
最も保守的な人。流行や世の中の動きに関心が薄い。イノベーションが伝統になるまで採用しない。伝統主義者とも訳される。
イノベーションの普及においては、イノベータとアーリーアダプタで構成される初期市場で受け入れられても、アーリーマジョリティ以降で構成されるメイン市場に普及させるのが難しいと知られており、キャズム理論では、このアーリーアダプタとアーリーマジョリティの間に存在する乗り越えるのが難しい溝を「キャズム」と呼んでいます。

## オプティマイザ（optimizer）について
SQLが実行された際に、対象となるレコードの取得時間が最小となるようにアクセスパスを最適化するDBMSの機能のこと
レコードを取得するためには、インデックスの使用や表全体の読み込みなど複数の実行方法が考えられるが、オプティマイザはクエリの実行計画を評価し、問い合わせ内容に応じて最も効率が良い方法を選択する。

> アクセスパスを選択する基準には「コストベースアプローチ」と「ルールベースアプローチ」の2つがあり、コストベースアプローチが一般的です。コストベースアプローチは、DBMSに蓄積された表やインデックスの統計情報をもとにコストを見積り、その結果に基づいて最も効率的な実行計画を作成する方法です。よって、コストベースアプローチにおいて実行計画を得る際に必要となる情報は「統計情報」が適切です。

なお、ルールベースアプローチは、あらかじめ決めておいたアクセスパスの優先順位などのルールに、実行しようとするSQL構文と表やインデックスの定義情報を当てはめて実行計画を作成する方法です。

## プリエンプションについて
実行状態のタスクがOSの制御によって、CPUの使用権を奪われ、実行可能状態に移されること。以下の条件を満たした場合、プリエンプションが発生する。
+ 実行状態のタスクより優先度の高いタスクが実行可能状態になる
+ 実行状態のタスクに割り当てられたCPU使用時間が終了する

>OSがCPUやシステム資源を管理し、CPU使用時間や優先度などによって複数のタスクを実行状態や実行可能状態へ切替えながら実行していくマルチタスク方式をプリエンプション方式といいます。

## RFI(Request for Information)について
企業。組織がシステム調達や業務委託をする場合や、はじめての取引となるベンダ企業に対して情報の提供を依頼すること。
## RACIチャートについて
+ 責任分担表（RAM）の一種
+ 二次元の票の各軸に、要因名・作業を設定し、それぞれの要因が担う役割及び負う責任を作業別に一覧化したもの
+ プロジェクト内での責任を明確化するとともに、作業が適切に割り振られる手助けをする
    + 実行責任（R）
    + 説明責任（I）
    + 相談対応（C）
    + 報告先、情報提供（A）
Dockerのunexpected error occurred に苦戦している方々へ。 

## 初めに
どうもpythonで転職を目指す者です。
この度Dockerなるものにトライしてみたのですが、インストール段階でかなりの苦戦を強いられました。同じく苦戦している方の少しでも為になればと｡｡｡

## 苦戦した内容
このエラーです。　`unexpected error occurred`

↓↓こいつが強かった。↓↓　私がどうやってこのエラーを解決したのかをシェア致します。
![2022-09-20_13h34_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2719278/e4d5d17d-65e0-3dd9-e0c4-06b37be220a5.png)

### 環境　
Windows11pro  
![2022-09-22_20h35_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2719278/061ec302-98f2-46de-f7f8-eed0a90e614a.png)

## 実装
良くある良質な手引書通りにDockerを実装してみました。
時間を置いていたかつ、色々なサイトを参照したのでソース元をなくしてしまいました。
申し訳ございません。
それ故手引書通りに行ったけど、上手く行かなかった人の為に記しています。

### 試してエラーが解消された方法。
<font color="red">BIOS設定をいじる</font>。⇒Disenable⇒Enableに。

#### BIOSの入り方
再起動してから ⇒ F2を軽く連打。これで入れます。

入ったらこのように設定を見てみてください。
![307568991_3562553537311924_2611984369111803328_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2719278/1c1dbfbc-faea-abf9-8b23-f3a3214d3fef.jpeg)

そしてこれをenable
![308424740_3562553547311923_2019474893199505445_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2719278/836cfcc1-f9fb-789a-a291-2084ee78d334.jpeg)

私の場合はこれで前に進めるようになりました。

## 終わりに
結構設定が複雑でdockerをやろうにも、インストールしてからエラーで進まない。
というのは往々にしてあるみたいです。
私もこのケースの一つで ハイパーバイザーの有効化やらvirtual boxのインストールやらいろいろな事を試してみました。
もしかしたらこれらの処理も合わせた上でBIOS設定も必要なのかもしれません。

ネットにはwinodws11 home ではdockerは難しいとの記載もありましたが、
無事達成する事が出来ました。同じトラブルに遭っているの方に少しでも助けになれば幸いです。
【Linux】ユーザー所有権、グループ所有権を変更する方法

`chown`コマンドを使用すると、指定したファイルやディレクトリのユーザー所有権（所有者）や
グループ所有権（グループ）を変更することができる。
```
chown [オプション] ユーザー[:グループ] ファイル名
```

ファイルの情報を確認。
```
root@b1fb0a296712:/var/www# ls -lsa 
4 -rw-r--r-- 1 root  root  430 Sep 20 03:37 hoge_file.php
```

ユーザーもグループも`root`になっている。

ユーザー所有者、グループ所有者を`laradock`に変更する。
```
root@b1fb0a296712:/var/www# chown laradock:laradock hoge_file.php
```

再度ファイルの情報を確認。
```
root@b1fb0a296712:/var/www# ls -lsa
4 -rw-r--r-- 1 laradock laradock  430 Sep 20 03:37 hoge_file.php
```
ユーザー所有者、グループ所有者が`laradock`に変更されている^^

参考：

https://webkaru.net/linux/chown-command/
Go言語 Docker Engine SDK でホストからコンテナへファイルコピー

あらかじめイメージに埋め込めんでおけないコンテナ固有の設定ファイルを物理ファイルを作成せずにコンテナへコピーしたいと思い、Go言語の Docker Engine SDK API を試そうとしたら手短なサンプルコードが見つからなかったので紹介します。

## 動作確認環境
- go 1.18.2
- Docker version 20.10.15
- ApiVersion:1.41

## コード

NGINX コンテナの index.html を上書きします。

API の CopyToContainer() を使いますが、ドキュメントに次のようにあるので注意ください。
> Note that `content` must be a Reader for a TAR archive
> `content` は TAR アーカイブの Reader である必要がある



```golang
package main

import (
	"archive/tar"
	"bytes"
	"context"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/client"
	"github.com/docker/go-connections/nat"
	"log"
)

func main() {

	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		log.Fatal(err)
	}

	containerName := "my-nginx"
	ctx := context.Background()

	rsp, err := cli.ContainerCreate(ctx, &container.Config{
		Image: "nginx:latest",
		Tty:   false,
	}, &container.HostConfig{
		AutoRemove: true,
		PortBindings: nat.PortMap{
			nat.Port("80/tcp"): []nat.PortBinding{{HostIP: "0.0.0.0", HostPort: "9090/tcp"}},
		},
	}, nil, nil, containerName)
	if err != nil {
		log.Fatal(err)
	}

	html := []byte(`
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Docker copy sample</title>
  </head>
  <body>
    <h1>Hello Docker copy</h1>
  </body>
</html>
`)

	// TAR アーカイブ作成
	var buf bytes.Buffer
	tw := tar.NewWriter(&buf)
	hdr := &tar.Header{
		Name: "/usr/share/nginx/html/index.html",
		Mode: 0444,
		Size: int64(len(html)),
	}
	if err = tw.WriteHeader(hdr); err != nil {
		log.Fatal(err)
	}
	if _, err = tw.Write(html); err != nil {
		log.Fatal(err)
	}
	if err = tw.Close(); err != nil {
		log.Fatal(err)
	}
	content := bytes.NewReader(buf.Bytes())

	// TAR アーカイブをコンテナへコピー
	err = cli.CopyToContainer(ctx, rsp.ID, "/", content, types.CopyToContainerOptions{})
	if err != nil {
		log.Fatal(err)
	}

	if err := cli.ContainerStart(ctx, rsp.ID, types.ContainerStartOptions{}); err != nil {
		log.Fatal(err)
	}
}
```

## 実行
```shell-session
$ go mod init ydclab/docker-copy
$ go mod tidy
$ go run main.go
$ docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED              STATUS              PORTS                  NAMES
9882d97ac986   nginx:latest   "/docker-entrypoint.…"   About a minute ago   Up About a minute   0.0.0.0:9090->80/tcp   y-nginx
```
※ go mod init のモジュールパスは適宜変更ください。

HTML を確認
```shell-session
$ curl localhost:9090

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Docker copy sample</title>
  </head>
  <body>
    <h1>Hello Docker copy</h1>
  </body>
</html>
```

デフォルトの index.html を上書きできました。


## 参考文献
- [Go client for the Docker Engine API](https://pkg.go.dev/github.com/docker/docker/client)
PyScript／Google スプレッドシートをPandasで読み込みDOMを使ってブラウザに表示してみた

PyScriptでGoogleスプレッドシートを読み込み、Pandas、DOMを使ってブラウザ表示できるかどうかを試してみました。非エンジニアです。

# コード例
```
<html>
  <head>
    <title>Pyscript DOM</title>
    <meta charset="utf-8">
    <link rel="icon" type="image/x-icon" href="./favicon.png">
    <link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
    <script defer src="https://pyscript.net/alpha/pyscript.js"></script>
    <py-env>
      - pandas
    </py-env>
    </head>
    <body>
      <div id="msg" style="width: 80%; height: 80%; background-color:#ccc"></div>
      <py-script>

import pandas as pd
import js

from pyodide.http import open_url
<!--スプレッドシートを読み込む(スプレッドシートのアクセス権とURLの末尾を変更する必要あり)-->
sheet_url = ("https://docs.google.com/spreadsheets/d/シート名/export?format=csv&gid=0")

url_content = open_url(sheet_url)

excel_data = pd.read_csv(url_content)

<!--ブラウザに表示したいセルを指定（ここでは0行目の「名前」の列を指定）-->
text_1=excel_data.loc[0,"名前"]

<!--ここからDOM（letは記載不要）-->
from js import document

msg = document.getElementById("msg")
msg.innerHTML = text_1

      </py-script>
    </body>
</html>

```
# スプレッドシートの設定
①シート右上の共有ボタンを押し、アクセス権を「リンクを知っている全員」「閲覧者」にする。
![googlespreadsheet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/777340/b10bcb88-69a7-7821-7541-a6f57e0ce061.png)

②URLの末尾を「edit#gid=0」→「export?format=csv&gid=0」に変更する。
![googlespreadsheet_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/777340/62520cfc-6f3f-606e-6cec-048e12b49ee5.png)


# 作成のきっかけ
Googleフォームでアンケートを実施しウェブサイトに公開しているのですが、省力化したくてPyScriptを試してみました。

# 参考にしたサイト
https://pyscript.net/
https://miyashinblog.com/pyscript/
[Rust] VCランタイムライブラリを静的リンクする

## VCのランタイムライブラリについて
Windows上でMSVCターゲットでビルドした場合、VCランタイムライブラリとリンクされますが、このライブラリには、DLLインポートライブラリと、静的リンク用があります。

https://docs.microsoft.com/ja-jp/cpp/c-runtime-library/crt-library-features?view=msvc-170

デフォルトではDLLインポートライブラリが使用され、ランタイムDLLへの依存関係が発生します。このDLLが中々の曲者で、VisualC++のバージョン毎に存在するため、種類がかなり多いです。

http://www.neko.ne.jp/~freewing/software/microsoft_visual_cpp_runtime_list/

プログラムに対応するバージョンのランタイムがインストールされていない場合、実行時にエラーになります。確実に動作させるには、実行環境にVC++再配布可能パッケージを同時にインストールする必要があります。

ライブラリを静的リンクにした場合、若干EXEファイルのサイズは増えますが、依存関係を気にする必要は無い為、配布の敷居が下がります。しかしながら、DLLインポートしていれば、DLLにセキュリティアップデートがあった場合、Windowsアップデートでの更新が期待出来るので、その辺りはよく考える必要があるかもしれません。

## VCランタイム静的リンクの方法

Rustでは、コンパイルオプション "target-feature=+crt-static" により、静的リンクを指定する事が出来ます。

https://doc.rust-lang.org/rustc/codegen-options/index.html?highlight=%2Bcrt-static#target-feature

コンパイルオプションを プロジェクトのフォルダ/.cargo/config.toml に記述しておけば、ビルド時にコンパイルオプションが反映されます。

```:config.toml
[build]
rustflags = ["-C", "target-feature=+crt-static"]

もしくは、

# for MSVC 32bit
[target.i686-pc-windows-msvc]
rustflags = ["-C", "target-feature=+crt-static"]

# for MSVC 64bit
[target.x86_64-pc-windows-msvc]    
rustflags = ["-C", "target-feature=+crt-static"]
```

config.toml の配置できる場所は色々あるようですが、公式のドキュメントを確認してください。

https://doc.rust-lang.org/cargo/reference/config.html

## ビルドしたEXEファイルの比較

Hello Worldを静的リンクオプション有り無しでそれぞれビルドして、EXEファイルのサイズとDLLの依存関係を比較してみます。依存関係の確認は、[Dependencies](https://github.com/lucasg/Dependencies) を使用しました。

【オプション無し（ファイルサイズ: 152kb）】
![静的リンクオプション無し](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519547/d964c805-bc3c-fe2c-9daa-4e390895029d.png)
【オプション有り（ファイルサイズ: 244kb）】
![静的リンクオプション有り](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519547/4c93e723-ccf4-9bb8-0cc6-f97433417960.png)
依存関係が kernel32.dll だけになったのが確認できます。
VSCode拡張機能Growi ClientをGrowi Cloudで動作するように修正

## LINK

* [リポジトリ](https://github.com/method-inside-a-class-of-method/vsc-extension/tree/main/GrowiCloud/growicloud)
* [拡張機能ファイル(vsix)](https://github.com/method-inside-a-class-of-method/vsc-extension/blob/main/GrowiCloud/growicloud/growi-cloud-client-1.0.0.vsix)
    * コマンドパレットから`Extensions: Install from VSIX...`を実行してインストールできます。
    * マーケットプレースへのアップロードは今の所考えてません。

## 作成の経緯

　業務でGrowi.cloudというWikiプラットフォームを利用しているのですが、
マーケットプレースで頒布されている拡張機能では対応していないようで、
エラーが発生して利用できませんでした。
　そこで、勉強がてら拡張機能の改造にチャレンジしようと発起しました。

## 環境構築

　nodeがベースです。yo, generator-code, vsceというパッケージをnpmかyarnでインストールすればよいのですが、Docker環境で構築したところ結構ハマりました。

* rootユーザーだとパーミッションエラーが頻発するので、一般ユーザーを作って、sshでログインするように設定
* node v18だと`ERR_OSSL_EVP_UNSUPPORTED`が発生するので環境変数`NODE_OPTIONS=--openssl-legacy-provider`を設定。vscodeのtasks.jsonにも同じ設定をしておかないとデバッグ実行時に同様のエラーが発生します。

## コード修正

デバッグ実行して、一つ一つエラーを潰していきました。
APIのエンドポイントやレスポンスの構造に所々差異があったのがエラー原因でした。
あとは、URL連結処理といった細かい部分を手直ししました。
スクラッチで開発したわけじゃありませんが、大体の仕組みが掴めました。
想像していたよりも導入難度は低かったです。
今後、業務でちょっとした不便を感じた際に拡張機能の開発も視野に入れることができそうです。
DDBJの提供する微生物ゲノム遺伝子アノテーションツール, DFASTをGoogle Colaboratoryで利用する

DFASTはDDBJの提供する微生物ゲノム遺伝子アノテーションツールである。

https://www.nig.ac.jp/nig/ja/2019/08/research-highlights_ja/rh20190830.html

通常はブラウザ版を利用すれば良いが、Google Colaboratoryでも利用可能である。

https://dfast.ddbj.nig.ac.jp/

その利用方法を記述する。
出力ファイルが大きいため、Google Drive上に目的のファイルを保存し、Google drive上に出力することを推奨する。

<h1>DFASTのインストール</h1>

condaを利用してインストールすると簡便で良い。
https://anaconda.org/bioconda/dfast

最初のセルに以下のコードをコピーし実行する。
```
#@title installing miniconda and dfast
%%bash
MINICONDA_INSTALLER_SCRIPT=Miniconda3-4.5.4-Linux-x86_64.sh
MINICONDA_PREFIX=/usr/local
wget https://repo.continuum.io/miniconda/$MINICONDA_INSTALLER_SCRIPT
chmod +x $MINICONDA_INSTALLER_SCRIPT
./$MINICONDA_INSTALLER_SCRIPT -b -f -p $MINICONDA_PREFIX

#installing dfast
conda install -y -c bioconda dfast
```

続いてリファレンスデータベースのインストールを行う。
以下のコードを次のセルに入力し実行するとよい。

```
#@title reference database install
!dfast_file_downloader.py --protein dfast
!dfast_file_downloader.py --cdd Cog --hmm TIGR
```

helpを実行し、内容を確認する (しなくてもよい)。

```
#@title DFAST ヘルプの実行
!dfast -h
```

<h1>DFASTの実行</h1>

ファイルをアップロードし実行する場合。
subprocessを利用して実行するとよい。

```
import subprocess
from subprocess import Popen

#コマンドの作成
cmd = 'dfast ' 
cmd += '--genome file_name.fasta ' #入力するファイル名を指定
cmd += '--out folder_name' #出力するフォルダ名の指定

#dfastの実行
test = subprocess.Popen(cmd, shell=True, text=True,\
                        stdout=subprocess.PIPE, stderr=subprocess.PIPE)
outs, errs = test.communicate()

#ログファイルの記録
with open('Dfast_log.txt','a') as f:
  f.write(outs)
  f.write("\n")
  f.write(errs)
  f.write("\n")
```

<h1>Google drive上で実行する場合</h1>

Google drive上にファイルを設置し実行、Google drive上にファイルを出力すると良い。

```
#Google driveへのアクセス
from google.colab import drive
drive.mount('/content/drive')
```

上述のfile_name.fasta、folder_nameにgoogle driveのパスを追加し、実行すれば良い。
以下は実際のコマンドの例である。

```
#コマンドの作成
cmd = 'dfast ' 
cmd += '--genome /content/drive/MyDrive/file_name.fasta ' #入力するファイル名を指定
cmd += '--out /content/drive/MyDrive/folder_name' #出力するフォルダ名の指定
```

<h1>複数のファイルをまとめて実行したい場合</h1>

指定したフォルダのファイル全てに対して実行する場合は以下の操作を利用すると良い。
フォルダ名の指定とファイル名の取得を以下の操作で行う。
```
#目的のGoogle drive上のフォルダ名の入力。最後に「/」を入れる。
DRIVE = '/content/drive/MyDrive/'

#DRIVE内のファイルのリストを取得
files = os.listdir(DRIVE)

#fastaファイルのみを集める
files3 = []  
for i in files:
    if '.fasta' in i:
      files3.append(i)
print(files3)
```

DFASTを実行するためのdefの作成
```
def dfast_run(file_name):
  cmd = 'dfast ' 
  cmd += '--genome ' + DRIVE + file_name 
  cmd += ' --out ' + DRIVE + file_name[:-6] #[:-6]はfastaの拡張子を削除するため
  #cmdをプリントし不備がないか確認する
  print(cmd)
  test = subprocess.Popen(cmd, shell=True, text=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  outs, errs = test.communicate()
  #logの保存
  with open(DRIVE + "Dfast_log.txt",'a') as f:
    f.write(outs)
    f.write("\n")
    f.write(errs)
    f.write("\n")
```

解析の実行
```
#files3にはfastaファイルのリストが入っている。
for i in files3:
  dfast_run(i)
```
ABC 269 回答メモ

0.はじめに
　ABCの参加履歴とその時の所感を個人的にまとめたメモです。

1.A問題
　4つの数字をmapで受け取って計算しながらアウトプット。
　文字列は、問題文からコピペすると後ろに半角スペースがつくからそこは注意。
https://atcoder.jp/contests/abc269/submissions/34921671

2.B問題
　なかなかてこずった問題。
　条件から高々100マスの走査×２なので、時短の工夫は排除

　縦横方向それぞれのチェックで、”＃”が初めに出てくるアドレスと
　”＃”が初めに出てきた後”.”が初めに出てくるアドレス-１で
　abcdを求める。

　縦横がごっちゃになってしまい、求める順番がcd→abとなってしまった。

　テストの結果、上記方法だと10マス目が＃だった場合に判定できないことが
　分かり、10マス目が"＃"だった場合の判断も追加して合格
https://atcoder.jp/contests/abc269/submissions/34937220

3.C問題
　最初見たときは難解で、D問題移行に逃げようと思ったが
　そっちも難しかったのであきらめて取り掛かる。

　例題等を見ているうちに以下の流れで行けそうとつかむ。

　(1)**N**を2進数の文字列**S**に変換
　　例）11→1011
　(2)２の”**S**内の下から桁数乗”の数列を**LS**を作成
　　例）1011→(1,2,8)
　(3)**LS**内の数字の全組み合わせ+0のリスト**ans**を作成
　　例）(1,2,8)→（0,1,2,3,8,9,11）
　(4)ansを小さい順に1行毎出力。

　
　実装時メモ
　　(1)**N**を2進数の文字列**S**に変換
　　　2バイト変換は”bin”を使う、頭に”0b”がつくから文字列にした後排除
```python
S=str(bin(N))[2:]
```

　(2)２の”**S**内の下から桁数乗”の数列**L**を作成
　　　下から何桁の求め方がスマートに行かなった・・・。
```python:
j=len(S)-i-1
```
　(3)**L**内の数字の全組み合わせ+0のリスト**ans**を作成
  　　itertoolsを使用
```python:
import itertools
略）
ans=[0]
for n in range(1,len(L)+1):
	for conb in itertools.combinations(L, n):
	    ans.append(sum(conb)) #タプルをリスト型に変換
```
問題の読解力と、やればできるの精神が大事だと思いました。
https://atcoder.jp/contests/abc269/submissions/34946002

4.D問題
　プログラミングの勉強で今一しっくりこなかった
　再帰関数を使うんだろうなーと思いつつも
　残り30分だったのでテスト日はあきらめました。
　後日挑戦したら、意外と30分で行けたかもと思えました。

　以下の方法での実装を検討

　(1)考察１
　　　1)X,Y,グループ(初期値-１)のリストを作る
　　　2)上からリストを読み、読み込んだペアに該当する
　　　　ペアがあるかを判別
　　　3)最後にグループ数カウント

　　ペア数が1000とはいえ、TLEくさいな・・・と判断

　(2)考察２
　　　1)2000×2000の枠を作成
　　　2)X,Yそれぞれで枠を埋めていく
　　　3)隣り合った組がどれくらい合うかをカウント
　　
　　2000*2000を端から見ていくのが非効率的過ぎると判断

　(3)考察３
　　　1)2000×2000の枠を初期値0で作成
　　　2)X,Yのアドレスに該当する枠のマスを-1で埋めていく
　　　3)枠とは別にX,Y,グループのリストを作成
　　　4)リストを上から見ていき、該当ペアの枠内
　　　　X,Yのマスが-１かをチェック、-1だったら
　　　　グループ番号を振り(1から始めグループごとに
　　　　カウントアップ)
　　　　隣り合った黒マスがあるかを再帰チェック
　　　　隣り合っていれば、振られたグループ番号で
　　　　枠内のマスを埋める
　　　　-1でなかったら、グループが設定されていると判断
　　　5）振ったグループ番号最大値＝グループ数となるため表示

　　　なんとなく、無駄な手順が挟まっている気もするが実装。
　　　
　実装のポイント
　　　1)2000×2000の枠を初期値0で作成
　　　　→枠の範囲の端っこだったら・・・とかの判定を最初入れていたが
　　　　　めんどいので2100×2100とした。
　　　2)X,Yのアドレスに該当する枠のマスを-1で埋めていく
　　　　→X,Yにマイナスがありえたので、すべて1050を足して
　　　　　正の整数とした。
　　　4)再帰関数
　　　　→以下のように関数だけ書くと、うまく動かなかったので
　　　　 強引に戻り値を設定した。
　　　　 競プロでしかPython使ってない経験の浅さを露呈
```python:NG
G_chk(XX,YY,now_G,H)
```
```python:OK
Q=G_chk(XX,YY,now_G,H) #Qはこの後何にも使わない・・・
```
　LTEになったら打つ手なしだな・・と思ったが
　すんなり通ってよかったです。
https://atcoder.jp/contests/abc269/submissions/35025956

5.E問題
　なんとなく行けそうだったので挑戦
　インタラクティブ問題好きだけど、テストしにくいのが難。
　
　考察
　　最大1000マスで、1マスだけ埋まっていないマスを探す
　　ということで、2分探索すればいいんだろうなとあたりをつけるが
　　正直2分探索をコード化するといつも失敗するのでこわごわ取り掛かる。
　
　　問題自体は、駒が置かれていない行と駒が置かれてない列を
　　それぞれ求めるだけ。
　　
　　行を求める時は、列は１～Ｎ指定、列を求める時は行を１～Ｎ指定とし
　　走査範囲列と、コンピュータの回答が同じか、ー１かで
　　走査範囲内に、空きがあるかないかを判断できた。

　　理屈は簡単だが、2分探索ロジックがうまく書けずてこずりつつ
　　特にこれといった山場もなく合格。
https://atcoder.jp/contests/abc269/submissions/35044570

Ｆ以降は、できるようになったらやってみようかと思います。
【シェルスクリプト】変数のデフォルト値

## `:+`
変数が定義されている場合にデフォルト値となる。
空文字の場合はそのまま。

```zsh
hoge=Hello
foo=""
 
echo ${hoge:+exist}
# exist
echo ${foo:+empty}
#
echo ${bar:+undefined}
#
```

## `+`

変数が定義されている場合にデフォルト値となる。

```zsh
hoge=Hello
foo=""

echo ${hoge+exist}
# exist
echo ${foo+empty}
# empty
echo ${bar+undefined}
#
```

## `:-`

空文字の場合と変数が未定義の場合にはデフォルト値となる。

```zsh
hoge=Hello
foo=""

echo ${hoge:-exist}
# Hello
echo ${foo:-empty}
# empty
echo ${bar:-undefined}
# undefined
```

## `-`

変数が定義されていない場合のみデフォルト値となる。

```zsh
hoge=Hello
foo=""

echo ${hoge-exist}
# Hello
echo ${foo-empty}
#
echo ${bar-undefined}
# undefined
```
google artsの画像をダウンロードしたい

https://artsandculture.google.com/

ある日、google artsの画像をダウンロードしたいという依頼を受けました。
右クリックで画像ダウンロードするかできないんだったら検証モードで確認すれば行けるのでは？と当初思ったのですが、見てみると1枚画像ではないみたいなんですよね...

そのまま全部ダウンロードしてきて、合体させるのは苦行ですし、何か方法が無いか探してみました。

## 方法1
WEBツールを利用する「dezoomify」
(若干処理が遅いので方法2より時間がかかる)

https://dezoomify.ophir.dev/


## 方法2
ソフトを利用する「dezoomify-rs」

### 使い方

exeを起動するとコマンドが立ち上がるのでダウンロードしたいurlを入力
成功したらどのサイズをダウンロードするか求められるので数値を入力でダウンロード

https://github.com/lovasoa/dezoomify-rs/releases/tag/v2.9.1

## 方法3
pythonでスクレイピングして画像をつなげてダウンロード


## 感想
dezoomifyは設定によるのかダウンロードしてきた画像の色味が若干違うような気がしましたので、
dezoomify-rs使うほうが良いのかなと思いました。
pythonでスクレイピングするっていうのも勉強になりそうで良いのですが今回は時間がなく「dezoomify-rs」を使用することにしました。