OmniAICreator/Qiita-1.07M huggingface dataset:
PHPer が Rubyに入門したメモ

# 前提
JSと同じようにすべてがオブジェクト
`null`ではなく、`nil`で、`nil`すらもオブジェクト

# セミコロン
使わない

# コメント

`#`つかう

```ruby
# コメント
```

# 変数

型推論される
PHPの`$`なし定義と同じ

ローカル変数は先頭を英小文字か"_"にする
ローカル変数のスコープは宣言されたブロック、メソッド定義

```ruby
val = 1;
name = 'name'
```

# 定数

大文字で定義
定数とか名乗ってるのに再代入できる

```ruby
MAX = 10

MAX = 11
```

# グローバル変数

`$`をつける

```ruby
$global_val = 'global'
```

# 関数

英小文字か"_"で始まる必要がある

`def` ~ `end`

引数ない場合`()`が不要
引数ある場合は`()`内に。デフォルト引数も可能

明示的にreturnしない場合、最後の式の評価が返される。
明示的に`return`もできる

```ruby
def hello
  puts 'hello'
end

def sum(val, val2 = 2)
  val + val2
end

def sum2(val, val2 = 2)
  return val + val2
end

```

# 演算子

特に違いはなさそう
`++`のインクリメントはない

```ruby

# 加算
sum = 1 + 1 # 2
# 減算
sub = 5 - 1 # 4
# 乗算
multi = 10 * 2 # 20
# 累乗
expo = 2 ** 3 # 8
# 除算
divi = 10 / 3 # 3
# 剰余 
surplus = 10 % 3 # 1
```

比較に関してもほぼ同じ
`===`の厳密比較はない
参考演算子はある

```ruby
puts 10 == 2 # false
puts 10 < 2  # false
puts 10 != 2 # true
puts true ? 'trueです' : 'falseです'
```

# 文字列
Stringクラス

シングルクォーテーション、ダブルクォーテーションで囲ったもの
ダブルでは変数埋め込める

```
hoge = 'hoge'

puts "hello #{hoge}"
```

# 配列

`[]`で定義
連想配列のことはハッシュと呼び、`{}`で定義する。なおアクセスするときは普通の配列のようになる

```ruby
arr = [10, 'hgoe']
arr[0] # 10

hash = {'key' => 'value'}
hash['key'] # 'value'
```

# 真偽値
**何故か0も真になる**
falseとnilが偽

```
puts 0 ? '真' : '偽'
```

# クラス

`@@変数名`でクラスプロパティを定義できる
PHPでいうstaticプロパティ

`@変数名`でインスタンス変数を定義できる
PHPでいうプロパティ。いきなりメソッドで定義して使用してよい

`def self.メソッド名`でクラスメソッドを定義できる
PHPでいうstaticメソッド

```ruby

class User
  # クラスプロパティ(static プロパティにあたる?)
  @@name = 'static的な'
  
  def initialize
    # PHPでいうプロパティに当たる
    @id = 1
  end

  def updateName
    @@name = 'アップデートした'
  end

  def getId
    @id
  end

  def getName
    @@name
  end

  # クラスメソッド => staticメソッド
  def self.hoge
    puts 'hoge'
  end
end


User.hoge # hoge
# インスタンス化
user = User.new

```

## 継承

`class Admin < User`のように`継承先 < 継承元`で指定

# モジュール
PHPでいうTraitに近い

```ruby
module Calculator
  def sub(val, val2)
    val + val2
  end

  module_function sub
end

# ruby単体なら読み込みしてやる(Railsなら自動でやってくれてる)
require './calculator.rb'
class Hoge
  include Calculator
end

hoge = Hoge.new
hoge.sub(1,2)
```

# 制御文

## if
`if 式 end`で記載
式の後ろにthenをつける事もできるが省略してよい

`elseif`ではなく`elsif` elseとelsでわかりにくく違うくせに`else`はある。
そこは`els`じゃないんだ...

```ruby
if 1 < 2 then

end


val = 10
if val < 2

elsif val < 3

else

end

```

## 後置if
後ろに書かれているifが先に評価され、trueになれば、前が評価される
多言語使用者読みにくい気がするが、ruby界隈では可読性があがるらしい

```ruby
val = 0

# 先にif val.zero?が評価される
puts val if val.zero?

```

## for

rubyのforは指定したオブジェクトから順に値を取り出して繰り返しを行う
指定の回数ループさせる場合`..`で範囲オブジェクトを作成する

そのほかeachも使える

ループ条件がない場合`loop`が使えるがちゃんとbreakしないと無限ループする

```ruby
for val in 1..10
  puts val
end

(1..10).each { |val|
  puts val
}

(1..10).each do |val|
 puts val
end

loop {
  break
}
```

# 例外

```ruby
begin
# エラーが発生する可能性のある処理
rescue
# エラーが発生した場合の処理
else
# エラーが発生しない場合の処理
ensure
# エラー発生の有無にかかわらず行う処理
end

# エラー投げる
raise "error"

```
【Makefile】自動でフォルダ内の全ソースファイルを並列コンパイル＆リンクし実行ファイルを生成する方法

定番の make ですが、ネット見ても断片的な情報が多かったので、備忘録的なまとめです。


下記に記載の2ファイルと、.c ファイル達を同じフォルダに入れて、

`chmod +x make.sh  # 初回のみ`
`./make.sh`

で、CPUコア数+1の並列コンパイルされます。
フォルダに入れたりしたい方は、適時相対パスにしてください。
（Makefileのインデントは、タブで行うこと）

---

```Makefile.
EXEC = test
SRCS = $(wildcard *.c)
OBJS = $(patsubst %.c,%.o,$(SRCS))
# CFLAGS = -g -O0 -pipe -Wall
CFLAGS = -O2 -pipe -Wall
LDLIBS = -lm -pthread

all: $(EXEC)

$(EXEC): $(OBJS)
	$(CC) $(CFLAGS) -o $@ $^ $(LDLIBS)

%.o:%.c
	$(CC) $(CFLAGS) -c -o $@ $<

clean:
	rm -f $(EXEC) *.o
```

SRCSで、全ての .c ファイルを抽出
OBJSで、上記の .o 版リストを作成
実行ファイル test を作成しようとするが、依存関係により、.o ファイル群が見つからないため後回し
同フォルダ内にある全 .c ファイルをコンパイルし、.oを作成
全ての .o をリンクし、実行ファイルを作成
make clean で実行ファイル、中間ファイルを削除
※ CFLAGS、LDLIBS で与えるオプションは適時書き換えてください

---

```make.sh
#!/bin/bash

JOBS=$[$(grep cpu.cores /proc/cpuinfo | sort -u | sed 's/[^0-9]//g') + 1]
if [ $JOBS = '1' ]; then
	JOBS=$[$(grep processor /proc/cpuinfo | wc -l) + 1]
fi
make -j${JOBS} $1
```

1行目：bashを指定（shだと加算でエラー）

3行目：`grep cpu.cores /proc/cpuinfo`でCPUコア数が取れるが複数行見つかる
`sort -u`で1行だけ取り出し、`+1`する

4～6行目：`/proc/cpuinfo`に`cpu.cores`行が無い環境の場合、`JOBS`には 1 (最後に加算したもの)が入っているため、CPUコア数を取るのを諦めて、代わりに論理プロセッサ数を拾ってくる
`grep processor /proc/cpuinfo`で論理プロセッサ数だけ、プロセッサ番号の行が抽出される
`wc -l`で行数を数え、`+ 1`する

5行目：`make`に並列数指定。
`$1`でコマンドライン引数を拾っているため、`./make.sh clean`にも対応

※：コア数+1するのは、それくらいが一番パフォーマンス出る、と、どこかで見たからです。
TortoiseGitで、秘密鍵と公開鍵の仕組みでアクセスする際に、終了コード 128 が出る


# 症状

- フェッチ等の画面で、`Putty 鍵の自動ロード`がグレーアウトしている。
- 以下のようなエラーが出る

```TortoiseGit.
git.exe fetch -v --progress "****"
****: Permission denied (publickey,keyboard-interactive).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.


gitは正常に終了しませんでした (終了コード 128)
```


設定は、
`ToitoiseGit -> 設定 -> ネットワーク -> SSHクライアント`に、Git の`ssh.exe`を指定。
`ToitoiseGit -> 設定 -> リモート -> Putty 鍵`に、秘密鍵から生成した PUTTY鍵 を指定。


# 解決方法
- `ToitoiseGit -> 設定 -> ネットワーク -> SSHクライアント`に、ToitoiseGitの`TortoiseGitPlink.exe`を使う。

そうすると、`Putty 鍵の自動ロード`のチェックが付けられるようになる。チェックを付けることで、上記の`リモート -> Putty 鍵`の設定が有効になり、アクセスする時にこの値を読み取り、画面右下のシステムトレイの Pagent に key を自動登録してくれる、という仕組みらしい。
（画面右下の`Pagent`は、`TortoiseGitPlink.exe`の一部であるもよう。）

他の解決方法としては、以下も考えられる。

- Git の ssh.exe を使う場合は、ユーザフォルダの`.ssh`に適切な名前の秘密鍵を置いてやる
- 自動ロードを使わない場合は、TortoiseGitPlink.exe にした上で、画面右下の Pagent に手動で`Add Key`してやる

ちなみに、ユーザー情報は編集不要。編集してもリモート側からはその鍵のユーザとして扱われる。

# ハマった発端

逆に、新規に作成した Git リポジトリから、何も設定していないのに認証が通って、プライベート設定しているリモート側から clone やら fetch やらできてしまって、焦って色々やったら今度は全く繋がらなくなったという話。（同じPCで最初の環境構築をやったので、その設定が Pagent に残っていて、暗黙にそのキーで接続にいって、成功していたというオチ）
docker-compose upでコンテナのstatusがExitになってしまう時の対処法

##はじめに
AWSでdockerを構築している際にdocker-compose upをしてもコンテナが起動せずにExitになってしまい詰まって少し時間がかかったので、同じところで詰まっている人のために書きます。

##エラー内容
始めに、

```
$ docker-compose up
```

をしてから、別のターミナルで確認すると、

```
$ docker-compose ps

 Name         Command      State       Ports
---------------------------------------------------
app_1        bundle exec   Exit 1
             puma -C
             config ...

web_1        /bin/sh -c /   Up        0.0.0.0:80->
             usr/sbin/ngi             80/tcp
　　　　　　　　nx ...
```
とapp_1のStateがExit 1となっていてupされていません。

##対処方法
僕個人はこれでなおりました。

```docker-compose.yml
services:
    app:
        build: .
        command: bundle exec puma -C config/puma.rb -e production
        volumes:
            - .:/app
            - public-data:/app/public
            - tmp-data:/app/tmp
            - log-data:/app/log
        tty: true  ## tty: trueを追加
```
docker-compose.ymlのappにtty:trueを追加しました。
ttyを有効にすることによってコンテナが落ちてしまう事を防いでいるらしいです。

##最後に
docker-compose.ymlを修正した時に外しちゃったのかな？
Swift×Firebaseでアプリを作ってみよう

#この記事の目的!
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679508/aa0a78da-8cd4-55fc-b9ad-25ee2816b7da.png">

この記事ではFirebaseとSwiftを連携させてアプリ開発をしようとしている方へ親切な記事を書いていこうと思います！意外に知られているのに記事かいかんせん少ない！ってことでこれで「ある程度のものは作れるな！」ってぐらいの情報をお届けしようと思います！この記事を軸にして辞書を作成しようと思うのでぜひ更新をみてください！
# 目次
[1.firebaseとは？](#1-firebaseとは )
[2.firebaseの導入方法](#2-firebaseの導入方法)
[3.各サービスの紹介とおすすめの使い方](#3-各サービスの紹介とおすすめの使い方)


#1. firebaseとは？
FirebaseはGoogleのサービスでイメージとしてはAWSの簡略版と思うと使いやすいかな？と思います。簡略版と言ってもしっかりサービスとしては優秀なのでぜひ使ってみて下さい！
<img width="500"src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679508/d7d050d9-5faf-a9f1-fb9f-70608903779d.png">


#2. firebaseの導入方法
Firebaseでは[Firebase公式](https://firebase.google.com/)でアカウントを作ることで自分のプラットフォームを作成することができます。そこからコンソール画面（メイン画面的なところ）から新規プロジェクトより新しいアプリとデータを連携させることができます！。
##プロジェクトを作成する
下の写真のような画面からスタートしましょう！
<img width="500"src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679508/dc842a71-ea7b-cd89-3dc7-c7689b6f9e83.png">
ガシガシ進めていくと下の写真のようにプロビジョニングを開始してプロジェクトが作られます！ちょっと時間がかかるけど待ってね！
<img width="500" alt="dataFlowImage.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679508/642855a0-5d24-c52e-7178-98fac17f1e71.png">
できたら下の画像みたいにメニューバーが横に表示されて色々英語が並んで「うわ」って思いますね笑
<img width="500" alt="dataFlowImage.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679508/9ca246e0-0ec5-06fe-1f5b-ed777d0b6b93.png">

#3. 各サービスの紹介とおすすめの使い方
###[Authentication](https://firebase.google.com/docs/auth?authuser=0)
データベース管理で一番重要なアカウント作成。これを一発で作ることができるのがこのサービス！CloudFirestoreと連携させることでアカウント間での情報交換の実装もすることができるのでめちゃ便利なサービス！
###[CloudFirestore](https://firebase.google.com/docs/firestore?authuser=0)
CloudFirestoreが「ザ！データベース」のサービスと思って下さい！基本的には樹形的な感じをイメージして構築することができます！　Authenticationと連携させる時にはuidという名前みたいなデータを用いて連携させることができます。
###[RealtimeDatabase](https://firebase.google.com/docs/database?authuser=0)
RealtimeDatabaseは位置情報や通知サービスなどの刻々と変化していくデータに関してデータ管理が得意なサービス！データセッションで確定データをCloudFirestoreに登録することでデータ設計がうまくいくかな？って思います！
###[CloudStorage](https://firebase.google.com/docs/storage?authuser=0)
CloudStorageは写真やファイルなどを保管しておく必要がある場合に使うことができる。よくアカウントの写真やデータ共有をするときにお世話になっているサービスですね。
###その他のサービス
HostingやFunctionなどのサービスに関してはまだ使ったことがないのでいい感じに使えるようになったらこのページを更新していきますね。
brew install awscliでエラー、インストーラを使用してのダウンロード方法

◆背景
awscliをmacにインストールしようとしたらエラーがでた為

・以下サイトでインストーラあり
　https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-mac.html
　※インストーラ直URLはこちら
　https://awscli.amazonaws.com/AWSCLIV2.pkg

・Terminalでawsコマンド実行して使える事確認
VS Code Remote Development を使ってEC2上のコンテナにアッタッチする方法

前提: ローカルとEC2にDockerがインストール済み

# 1. Docker のリモート用ポートを開ける

#### 1-1. リモート側の /etc/docker 配下に daemon.json を作成して、下記を記述する

```
{"host":["tcp://0.0.0.0:2375","unix:///var/run/docker.sock"]}
```

#### 1-2. リモート側の /etc/systemd/system 配下に docker.service.d ディレクトリを作成し、その配下に override.conf ファイルを作成して、下記を記述する

```
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd
```

#### 1-3. Docker を再起動する

```
sudo systemctl daemon-reload
```
```
sudo systemctl restart docker.service
```

# 2. SSHキーを生成する

#### 2-1. ローカルで下記を実行する

```
ssh-keygen
```

#### 2-2. パブリックとプライベートのキーペアが生成される

```
id_rsa
id_rsa.pub
```

#### 2-3. リモート側の ~/.ssh/authorized_keys に id_rsa.pub を末尾に追加する
##### ※ .ssh ディレクトリ、authorized_keys ファイルがない場合は作成する

```
cat id_rsa.pub >> ~/.ssh/authorized_keys
```

#### 2-4. ローカル（~/.ssh）で実行し、プライベートキーを追加する

```
ssh-add id_rsa
```

#### 2-5. パスワードなしで、インスタンスに SSH 接続が可能になる

```
ssh <user>@<host>
```

# 3. Dockerコンテキストを生成する
#### 3-1. コンテキストを作成する

```
docker context create <context name> --docker "host=ssh://<user>@<host>"
```

#### 3-2. コンテキストを切り替える

```
docker context use <context name>
```


# 4. VS Codeの設定をする
#### 4-1. プラグインをインストールする
・Remote Development
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331630/368d84b4-962e-92de-9291-9639dee2eacc.png)

# 5. VS Code からEC2上のコンテナに接続する
#### 5-1. VS Code の Remote Explorer にコンテナ名が表示される
#### 5-2. 右クリックで、「Attach to container」 を選択するとコンテナ内のVS Codeが開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331630/8145bb99-a00c-c36a-f552-267ee8a76581.png)

## 参照
https://segmentfault.com/a/1190000023095631
ArduinoIDE、Arduino for VSCode、PlafromIO を M5StickC の開発環境として比較検討してみた

M5StickC の開発をし始めたので、3つの開発環境を比較検討してみました。

# TL;DR
* VSCode + PlatformIO が一押し
* ただし開発初心者だったら、VSCode + Arduino for VSCode がお勧めです

# それでは比較検討へ
## 比較対象 3 つ
No |  開発環境                      | Version
---|--------------------------------|-----------------------
1  |  Arduino IDE                   | 1.8.13
2  |  VSCode + Arduino for VSCode   | 0.3.4 (VSCode 1.52.1)
3  |  VSCode + PlatformIO           | 5.1.0 (VSCode 1.52.1)


## Arduino IDE と VSCode + Arduino for VSCode の比較
### 結論
VSCode + Arduino for VSCode がおすすめ。

### 理由
* コード書くなら VSCode が便利
  * 補完が効く
  * 見た目の変更ができる
  * 設定変更できる要素が多い
* ctrl + shift + p の便利さ
* Arduino IDE は簡素過ぎて痒いところに全然手が届いていない印象
  * hello world するだけなら十分だけど・・・

## Arduino for VSCode と PlatformIO の比較
### 結論
私は PlatformIO を選びましたが、人に依存するところがあるなと思いました。

### Arudino for VSCode のメリット
Simple is Best な感じ。

* 比較的 Arduino SDK に似ている
  * 簡素だが使いやすい感じ
* デフォルトで構成されるフォルダなどは `ほぼ` なくシンプル
  * それでいて必要な機能がある
  * 軽めのコードを書いていくならこっちのほうがいい
* ctrl + shift + p の便利さ

### PlatformIO のメリット
使い込むほど味が出そうな感じ。

* 高機能でかつ使いやすい
  * 各ボタンが簡素にまとまっている
  * フォルダ階層が最初から分割されている
  * 設定項目 plafromio.ini にまとまっている
* VSCode 内で完結できる
  * シリアルモニタもビルドターミナルも切り替えが楽で見やすい
  * 作ったプロジェクト一覧も見れて便利
* ここ数年で伸びてきているようで、今後の見込みがありそう
  * GitHub のリポジトリでも使っている人が多そうだったので、見慣れる意味でこちらを取りました

# 全体考察
## 開発初心者は Arduino for VSCode がお勧め
少し触ってみようとか、開発初心者は Arduino for VSCode のほうがいいかなと思います。
開発自体がよくわからないで PlatformIO を入ると、
ファイルもフォルダも多くて、何をしたらよいか迷ってしまうかと思います。
テストコードとか書かないだろうし。

Arduino for VSCode でも十分高機能ですし、
親切心はこっちのほうが上かもと思うので、
初心者でよくわからん人はこっちを選ぶのがよいでしょう。

## ではなぜ PlatformIO を選ぶのか
開発量が上がってくるとこっちのほうが生産性が高い気がするからです。
最初から量の多い開発をすることを前提とされている感じがするフォルダ構成といい、
開発してきた人が作っている感じがするので、
慣れてくるとこっちのほうがやれることが増えて便利そうだと思ったからです。

もう一つは今後の伸び率が高そうだからです。
のっているプロダクトを使っていると、おのずとトレンドを知ることもできたり、
GitHub のリポジトリも PlatformIO で開発されたものがあったりするのが増えていくと思うので、
そういうときに理解が早くなると思ったからです。
Sambaのバージョン確認方法

#こう！

```sh:
smbd -V
```

#蛇足

smdbじゃないよ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/3c421ddd-3458-f3a5-d2dd-a2634f771fc3.png)

#バージョン
CentOS Linux release 8.3.2011
ESXi on ArmをRaspberry PiのiSCSIに入れようとしてハマる

# この3行のためだけに記事を書きました
UEFI v1.22だとi、SCSIメニューが出なかった！(ように見えた…構成が変わって見逃しただけかもだけど)
UEFI v1.21にしたら、メニューが出た！
…ので、ハマった人がいたらv1.21(執筆時)で試してみてはいかがでしょうか。

以上です。以下オマケ。

# 何でiSCSIなの?
USBメモリが物理的に邪魔で、元々PXE+NFSにしようと思っていたけど、ルーターのDHCPサーバーに設定できなさそうなパラメーター設定が面倒で…

# 環境
- ホスト(ハード): Raspberry Pi 4 8GB
- ホスト(ソフト): ESXi on Arm Fling (Build 17230755) (VMware-VMvisor-Installer-7.0.0-17230755.aarch64.iso)
- iSCSIターゲット(ハード): NUC8i5BEH + WD Black NVMe SSD 2018 (500GB)
- iSCSIターゲット(ソフト): Ubuntu 20.04 + targetcli-fb

# インストール手順
みなさま実施されている、こんな手順でインストール。

1. Raspberry Pi OSでEEPROMを最新にする
2. [firmware/boot](https://github.com/raspberrypi/firmware/tree/master/boot)をFAT32でフォーマットしたSDにコピーして、kernel*を削除
3. [Raspberry Pi 4 UEFI FirmwareのRelease](https://github.com/pftf/RPi4/releases)を展開して、SDに上書きコピー
4. SDを挿してUEFI起動後、ESCキーを押し、UEFIを設定(3GB制限解除, iSCSI設定)
5. UEFIのBootメニューから、ESXiイメージを焼いたUSBメモリを起動させ、ESXiインストール

# はまったこと
## UEFIのメニューにiSCSIが出てこない
先述の通り。v1.21で試してみる。

## iSCSI命名規則
iSCSIを使うのが初めてで、ターゲットとイニシエーターの命名規則がよく分かっていなかった。
…ら、VMwareの[こんな文章](https://docs.vmware.com/jp/VMware-vSphere/7.0/com.vmware.vsphere.storage.doc/GUID-686D92B6-A2B2-4944-8718-F1B74F6A2C53.html)が教えてくれた。
これに合わせて設定。

## インストール先
ESXi 7.0から、128GB以上のメディアでないと、VMFSが作れないと聞いた。([本家blog](https://blogs.vmware.com/vsphere/2020/05/vsphere-7-esxi-system-storage-changes.html))
本家マニュアルのFling-on-Raspberry-Pi.pdfには、`autoPartitionOSDataSize=8192`というオプションが紹介されているが、これで起動すると、何故かESXiのインストーラーが起動せず、ESXiが起動してしまうように見えた。

Raspberry PiのUEFIのiSCSI設定で、Boot LUNを設定できるのを見つけたので、

- Boot LUNは、小さめに作成して、ESXiをインストール
- Boot LUN以外のLUNも作成して、datastoreに設定

すればよいのでは。

インストールメディアのサイズは、先程の[本家blog](https://blogs.vmware.com/vsphere/2020/05/vsphere-7-esxi-system-storage-changes.html)によると、

> 32GB for other boot devices like hard disks, or flash media like SSD or NVMe devices.

とのことなので、1つのターゲットに

- LUN0: 32GB
- LUN1: いっぱい

を作成し、Boot LUNを0にしてインストールしたところ、無事ESXiが起動、またLUN1をdatastoreにできた。

# オマケのオマケ: パフォーマンス
- iSCSIターゲット: 先述の通り
- ゲストOS: Ubuntu 20.04 aarch64
    - open-vm-toolsを手動ビルドしてインストール済み
- ベンチマークソフト: sysbench

で60〜80MiB/sくらい(seqrd/seqwr)だった。
普通に動くけど、USB3の高速なUSBメモリのほうが速いんだろうな。

# 参考文献
- [本家ESXi Arm Editionサイト](https://flings.vmware.com/esxi-arm-edition)
- [ESXiのiSCSI関連ドキュメント](https://docs.vmware.com/jp/VMware-vSphere/7.0/com.vmware.vsphere.storage.doc/GUID-C476065E-C02F-47FA-A5F7-3B3F2FD40EA8.html)

# 宿題
- iSCSIのJumbo Frame効果…vSwitchとiSCSIターゲットはMTU=9000にしてみたけど、iSCSIはMSSいくつで動くのだろう?
画像圧縮ツールSquooshのコマンドライン版を使って、複数ファイルを一括で圧縮する

画像を圧縮するのに、「[Squoosh](https://squoosh.app/)」を使って、ドラッグ＆ドロップで1枚1枚圧縮していました。
一括でできないかなぁと思っていたら、「[コマンドライン版](https://github.com/GoogleChromeLabs/squoosh/tree/dev/cli)」があるのに今更気が付きました。

# インストール方法

```
npm i -g @squoosh/cli
```

# 簡単な使い方

## jpgファイルを出力したい場合

```
squoosh-cli --mozjpeg '{}' -d <出力ディレクトリ> <入力ファイル名>
```

--mozjpegのconfigにはautoを指定して自動オプティマイザーを利用することもできるのですが、自分の環境では、「RuntimeError: memory access out of bounds」が高い確率で出て圧縮に失敗するので、{}を指定しています。

### 例：圧縮したhoge.jpgをoutput_dirディレクトリ下に出力する

```
squoosh-cli --mozjpeg '{}' -d output_dir hoge.jpg
```


## リサイズしたい場合

```
squoosh-cli --mozjpeg '{}' --resize '{"width":<幅のピクセルサイズ>, "height":<高さのピクセルサイズ>}' -d <出力ディレクトリ> <入力ファイル名>
```

### 例：hoge.jpgの幅を850pxにする。

```
squoosh-cli --mozjpeg '{}' --resize '{"width":850}' -d output_dir hoge.jpg
```

# 一括実行ツールを作成する

Pythonで一括実行ツールを作成してみました。
画像を圧縮し、かつ、横長であれば、幅を850pxにリサイズ、縦長であれば、高さを850pxにリサイズします。

```python:resize.py
# -*- coding: utf-8 -*-

import sys
import subprocess
from PIL import Image

if __name__ == "__main__":
  file_list = []

  with open('file_list.txt', 'r', encoding='UTF-8') as f:
    for line in f:
      line = line.rstrip('\n')
      if not line:
        break
      file_list.append(line)     

  for filename in file_list:
    filename = 'input/' + filename

    im = Image.open(filename)

    resize_opt = '{"width":850}'
    if im.width < im.height:
      resize_opt = '{"height":850}'

    cmd = 'squoosh-cli --mozjpeg {} --resize ' + resize_opt + ' -d output ' + filename
    # rc = subprocess.Popen(cmd, shell=True)
    rc = subprocess.call(cmd, shell=True)
```
コメントアウトしている「subprocess.Popen」であれば、コマンドが非同期で実行できるのですが、自分の環境で並列でsquoosh-cliを実行すると、完了するまでPCが操作不能になってしまいました。

## 使い方

1. 上記のコードをコピーして、resize.py(名前は任意)を作成する。
2. resize.pyと同じディレクトリに「input」「output」ディレクトリ、「file_list.txt」を作成する。
3. inputディレクトリ下に圧縮＆リサイズしたい画像を配置する。
4. file_list.txtに画像ファイル名を記述する。(1行1ファイル)
5. 「python resize.py」を実行する。

file_list.txtの記述例

```
hoge.jpg
foo.jpg
```
Railsで子クラスが固有のカラムを利用するSTIを使って実装したときのメモ

Railsで子クラスに個別のカラムを持たせるSTIを実装したのでそのメモ。
内容は例になります。

## 仕様
LINEの投稿をイメージして以下の仕様を想定

- 1回の投稿においてテキスト、もしくはスタンプを投稿できる
- テキストの投稿においては投稿された文字列を保存する
- スタンプの投稿においては投稿されたスタンプのIDを保存する
- 投稿できるものの種類は今後増えていくことが想定されている

今後も投稿できるものの種類が増えそう、という点と投稿できるものの種類によって保存しておくデータの型が変わりそう、という点からSTIを使って実装してみることにしました。

## 実装方針
#### リクエストパラメータについて
- 1つの投稿に対して `post_type` + `text` もしくは `post_type` + `stamp_id` が送られる
- 投稿の種類は`post_type`で表現
- `post_type`が`stamp`の場合は`stamp_id`に値を入れる
- `post_type`が`text`の場合は`text`に値を入れる

#### リクエストパラメータのバリデーションについて
- `post_type`が`stamp`の場合は`text`にデータを入れられないようにバリデーションを入れる
- `post_type`が`text`の場合は`stamp_id`にデータを入れられないようにバリデーションを入れる


## 工夫したところ
バリデーションはモデルに実装するわけですが、子クラス同士はお互いがどのカラムを利用するかを知らないようにしたいと思ったので、親クラスに条件付きでバリデーションを入れて、子クラスでその条件を外すという方針で実装しました。

## 実装
```ruby
# テーブル定義
create_table :posts do |t|
  t.string :type, null: true
  t.string :text, null: true
  t.integer :stamp_id, null: true
  t.timestamps
end

# コントローラー
class PostController < ApplicationController
  def create
    if PostClassSelector.select(params[:post][:post_type]).new(post_params).save
      # 成功時の処理
    else
      # 失敗時の処理
    end
  end

  def post_params
    params.require(:post).permit(:text, :stamp_id)
  end
end

# モデル
class Post
  validates :text,     absence: true, unless: -> { self.available_attribute.include? :text }
  validates :stamp_id, absence: true, unless: -> { self.available_attribute.include? :stamp_id }

  class_attribute :available_attribute

  def self.disable_absence_validator(attribute)
    self.available_attribute ||= []
    self.available_attribute << attribute
  end
end

class Post::Text < Post
  disable_absence_validator :text
end

class Post::Stamp < Post
  disable_absence_validator :stamp_id
end

class PostClassSelector
  def self.select(post_type)
    case post_type
    when :text   then Post::Text
    when :stamp  then Post::Stamp
    else raise StandardError.new('unsupported post type')
    end
  end
end
```
CentOS8のSambaがMacでマウントできなくなった時にやったこと

#起きたこと
おうちのCentOS8君にSambaをインストールしてファイルサーバーとして使ってます。

んで、Macにネットワークドライブをマウントしてるのですが、MacOS Big Surのバージョン11.2のアプデ後になんか繋がらなくなった…(´・ω・`)

**IPアドレスを指定してサーバーに接続** ってやってもダメ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/46cee86a-588e-6664-29ed-787d76045394.png)

MacからCentOS8に対してpingは通るので、物理的に繋がってないとかは無い…。

* Samba再起動してもダメ。
* CentOS8再起動してもダメ。
* Macの電源落として、さらに電源ケーブル抜いて10分ほど放置してもダメ。

うーん…。
Macのsmbの設定が変わったのかなあ、なんて思っていろいろ調べたのですが…うーん。

#ここいじったら直った

**システム環境設定** の **ユーザーとグループ** 。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/77eff966-7b6f-a79e-5620-9b3661c0f4a3.png)

**ログインオプション** の **自動ログイン** や **ログイン時の表示** を別の値にして保存したらなんか繋がるようになった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/9fd7c0aa-74a5-5db7-77fa-d968836ad85d.png)

じゃあ、 **自動ログインが〇〇になっていたらダメ** かというとそうでもない(´・ω・`)
直ったのはOKなんだけど、ダメな時の状態を再現できないのがモヤっとするです…。

#さらにダメな時はこう

MacOSのアップデートでまた繋がらなくなった…。
**ユーザーとグループ** をちょこちょこいじっても今度は直らなかった…。
その時は **キーチェーンアクセス** の該当サーバーへの接続パスワードを一旦消したら直りました。

**接続パスワードを一旦消す = ネットワークドライブを再設置する時にパスワードを改めて入力する必要がある（初回だけだけど）**
です。
パスワードを把握してるなら以下はやってもOKですが、そうでなければ注意です。

**アプリケーション** の…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/79aa2b60-45d8-bd55-1290-39a169fb6ec3.png)

*ユーティリティ* の **キーチェーンアクセス** 。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/227c7b2d-b7c4-8840-4a77-ab573aa0270a.png)

*ログイン* の 該当サーバー名（もしくはサーバーのIPアドレス）のネットワークパスワードを、右クリックして削除選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/3fa9c8a8-ad88-6ed7-3ead-01ebb5e09e96.png)

んでもって、改めて **サーバーへ接続** をやる。
（接続ユーザー名とそのパスワードを求められます）

#蛇足

原因がバチっと特定できないのは中途半端でちょっとイヤだけど、同じ症状で困ってる人の何かのヒントになればと思って、この記事を残しておきます。

#バージョン
MacOS Big Sur バージョン11.2
CentOS Linux release 8.3.2011
Samba Version 4.12.3
やる気を出すには from エンジニアの知的生産術(マイピックアップ) 

「[エンジニアの知的生産術](https://www.amazon.co.jp/%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E7%9F%A5%E7%9A%84%E7%94%9F%E7%94%A3%E8%A1%93-%E2%80%95%E5%8A%B9%E7%8E%87%E7%9A%84%E3%81%AB%E5%AD%A6%E3%81%B3%E3%80%81%E6%95%B4%E7%90%86%E3%81%97%E3%80%81%E3%82%A2%E3%82%A6%E3%83%88%E3%83%97%E3%83%83%E3%83%88%E3%81%99%E3%82%8B-WEB-PRESS-plus-ebook/dp/B07JFRF6MW/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=2GRDGUXMBTF82&dchild=1&keywords=%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E7%9F%A5%E7%9A%84%E7%94%9F%E7%94%A3%E8%A1%93&qid=1608975046&sprefix=%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E7%9F%A5%E7%9A%84%2Cstripbooks%2C272&sr=8-1)」を読み、今の自分にとって大切な考え方をピックアップ !


# 第2章. やる気を出すには

## まずはやるべきことを全て集める

まずは気になることを全て集めておく。それがやるべきことか、やらなくてもよいことかを最初に判断しようとすると、「内容の確認」のタスクが増える。
→　最初のフェーズはまずは**気になることを集める**「気になることは全てここにある」状態を作る。

例えば、
手紙があったとして、それが返信の必要とするToDoなのか、単に捨ててもよいゴミなのかを判断しようとすると、中を読む必要が出てくるためタスクが膨れてしまう。そうなればやる気が減ってしまうため、まずは「気になることを全て集める」作業をする


## 今日やらないといけないことが今日出来る以上の量になった場合

- 質を下げられないか?
- 量をへらせないか?
- 納期を伸ばせないか?
- 方法を変えられないか?
- 別のもので代替できないか?
- お金で解決できないか?

**どうしようもないならやめるべき**

## 「優先順位付け」は難しいタスク

### 探検と利用のトレードオフ

- 「過去の経験から一番良いと思う行動」ばかりしていれば、もっといい行動を見つけることが出来ない。
- もっといい行動を探求して「未経験の行動」ばかりしていれば、過去の経験を活かせない。

**探索と利用はトレードオフの関係にあるため、バランス良く実行する必要がある**

### トレードオフのバランス良くとは?

**不確かな時は楽観的に**
→　**楽観的とは、最良の場合に何が得られるかで判断すること**
→　悲観的とは、悪いことが起きないように行動を選択すること

悲観的な選択をした時に悪いことが起こった場合は、**二度とその選択肢は試されないため、チャンスに気付くこともない**。
しかし楽観的な選択をした場合は、仮に良いことが起きる確率が少なく悪い結果が出た場合でも、その選択から**チャンスが消えることはない**。

例
100円を入れてレバーを引くと、0.3の確率で500円のあたりが出る「お得なスロットマシン」があるとする。3回プレイした結果、運悪く全部外れることが0.7 * 0.7 * 0.7 = 0.343の確率で起こる。その現象が起こってしまい、悲観的な勘違いをした場合は、「このスロットの当たり確率は0だな」と考え、二度とプレイしないことになってしまう。その結果、お得なスロットマシンのチャンスに今後気付く機会は失われる。


チャンスをつぶさないためには、**不確かな時は楽観的に**を意識する。

## 大きすぎる一つのタスクのやる気を出すための手法

###「時間で切る」手法

タスクに合わせて時間を決めるのではなく、「決まった時間サイズにタスクを入れる」手法
→　**長くかかる1個のタスク(量で分割できないもの)にも使うことが出来る。**「情報収集」や「資料のブラッシュアップ」など終了条件が不明確のタスクに有効。

## 時間の見積り能力を鍛える

25分を1ポモドーロとする。

- 各タスクが何ポモドーロでできるのか
- 1日で何ポモドーロできるのか

↑ この2つが時間を見積もるために必要な要素

### 各タスクが何ポモドーロでできるのかの見積もり

1ポモドーロでできそうなタスクの量を見積もってみて、実行し、ズレを比較することで鍛える。


### 1日で何ポモドーロできるのかの見積もり

見積もり、実際に1日実行し、ズレを比較することで鍛える。
※ 1日でできるのは4~8ポモドーロ程度が限度。

**見積もる力を鍛えることによって、タスクの大きさと自分の使える時間が見えるようになってくる。**

### メールは意外とポモドーロ数が多いタスク。

→**「今日のタスクリスト」と重要度を比較し、予定していたタスクから1ポモドーロ奪う価値があるかを考え、それほどでもないと思ったら簡素に返す**

※ メールチェックなどの細切れ時間でできるタスクは、大きな時間の塊で取らないように。細切れでやった方が効率的


## 断ることの大切さ

**かかる時間が大きいのに得られる成果が小さい「日生産的なタスク」は断ることが大切**
→ それによって**自由になる時間が出来る。**
【初心者向け】VSCode からPython boto3 でAWSリリースを触ろう

# はじめに
この記事は、社会人２年目 AWS、python初心者が勉強したことをまとめたものです。
間違っている点、改善点等ございましたご指摘いただけると大変ありがたいです。


# この記事について
新米エンジニアがVSCodeからboto3を使用してAWSリソースを触るまでの手順を自身の備忘録として残したものです。
自分と同じような初心者のためになれば幸いです。

# 準備
デバッグ実行に関連する各種の構成情報を記述するlaunch.jsonファイルに、
AWSアクセスに必要な情報を環境変数として埋め込んでおきます。

```json:launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal",
            "env": {
                "AWS_ACCESS_KEY_ID": "*************",
                "AWS_SECRET_ACCESS_KEY": "****************************",
                "AWS_DEFAULT_REGION": "ap-northeast-1"
            }
        }
    ]
}
```

※launch.jsonには機密情報を記載されているため、絶対にGithub等のパブリックな場所にアップロードしないように

# boto3でAWSリソースにアクセス

```python:practice.py
import boto3

ec2_client = boto3.client('ec2')

print (ec2_client.describe_regions())

```

成功しました。

```console:
{'Regions': [{'Endpoint': 'ec2.eu-north-1.amazonaws.com', 'RegionName': 'eu-north-1', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.ap-south-1.amazonaws.com', 'RegionName': 'ap-south-1', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.eu-west-3.amazonaws.com', 'RegionName': 'eu-west-3', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.eu-west-2.amazonaws.com', 'RegionName': 'eu-west-2', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.eu-west-1.amazonaws.com', 'RegionName': 'eu-west-1', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.ap-northeast-2.amazonaws.com', 'RegionName': 'ap-northeast-2', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.ap-northeast-1.amazonaws.com', 'RegionName': 'ap-northeast-1', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.sa-east-1.amazonaws.com', 'RegionName': 'sa-east-1', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.ca-central-1.amazonaws.com', 'RegionName': 'ca-central-1', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.ap-southeast-1.amazonaws.com', 'RegionName': 'ap-southeast-1', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.ap-southeast-2.amazonaws.com', 'RegionName': 'ap-southeast-2', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.eu-central-1.amazonaws.com', 'RegionName': 'eu-central-1', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.us-east-1.amazonaws.com', 'RegionName': 'us-east-1', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.us-east-2.amazonaws.com', 'RegionName': 'us-east-2', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.us-west-1.amazonaws.com', 'RegionName': 'us-west-1', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.us-west-2.amazonaws.com', 'RegionName': 'us-west-2', 'OptInStatus': 'opt-in-not-required'}],.......
```
技術と管理の関係


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438183/e4fe4a99-671b-7476-94fd-de9ace1c39e1.png)

管理は大事だけど、「管理は技術あってこそ」と思ったのです。。。

- 管理力＝取りこぼさない能力
- 技術力＝タスク消化力＝プロジェクトの安定性

「技術」＝「個々人のスキル」×「組織力」
「組織力」＝「人数」×「コミュ力」

なのかなと。
AceエディタをVueコンポーネントにして使いたい！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065604/ae0ca9b5-54f3-7d1c-f5cb-be8f6e5ec83c.png)
[Ace (Ajax.org Cloud9 Editor)](https://ace.c9.io/) というブラウザ上で動作するテキストエディタがあるのですが、Vueで動作させるためにどうすればいいのかではまったのでまとめておきます。

# 環境
- Vue CLI v4.5.10
- Vue 2を選択して新しいプロジェクトを作成した状態

# NPM
名前にaceがつくパッケージがいろいろあって紛らわしいのですが、本家は[ace-builds](https://www.npmjs.com/package/ace-builds)です。

```
npm install ace-builds
```

# Vue
それでは新しいVueコンポーネントファイルAce.vueを記述していきます。

まずAceをバインドさせるdiv要素をテンプレートに用意します。ref属性は後で使います。スタイルクラスはお好みで。

```HTML
<template>
  <div ref="ace" class="ace"></div>
</template>

<style scoped>
.ace {
  position: relative !important;
  border: 1px solid lightgray;
  margin: auto;
  height: 100%;
  width: 100%;
}
</style>
```

script要素内でインポートするのはace-builds, ace-builds/webpack-resolver そして使いたい言語モードとテーマです。

```Javascript
import ace from 'ace-builds'
import 'ace-builds/webpack-resolver'

// 使いたい言語モードのインポート
import 'ace-builds/src-noconflict/mode-javascript'

// 使いたいテーマのインポート
import 'ace-builds/src-noconflict/theme-github'
```

あとはAceをmountedフックの中で初期化させれば良さそうです。Aceを初期化する際、先ほど定義したref属性の値をthis.$refsで参照します。そしていずれ使いそうなので、dataにAceエディタへの参照editorを保存しておきます。

言語モードはace/mode/_abc_、テーマはace/theme/_abc_の形で指定します。

```Javascript
export default {
  name: 'Ace',
  data() {
    return {
      editor: Object,
    };
  },
  mounted () {
    this.editor = ace.edit(this.$refs.ace);
    this.editor.session.setMode('ace/mode/javascript');
    this.editor.setTheme('ace/theme/monokai');
  }
};
```

できたファイルの中身はこんな感じです。

```Ace.vue
<template>
  <div ref="ace" class="ace"></div>
</template>

<script>
import ace from 'ace-builds'
import 'ace-builds/webpack-resolver'

// 使いたい言語モードのインポート
import 'ace-builds/src-noconflict/mode-javascript'

// 使いたいテーマのインポート
import 'ace-builds/src-noconflict/theme-github'

export default {
  name: 'Ace',
  data() {
    return {
      editor: Object,
    };
  },
  mounted () {
    this.editor = ace.edit(this.$refs.ace);
    this.editor.session.setMode('ace/mode/javascript');
    this.editor.setTheme('ace/theme/monokai');
  }
};
</script>

<style scoped>
.ace {
  position: relative !important;
  border: 1px solid lightgray;
  margin: auto;
  height: 100%;
  width: 100%;
}
</style>
```



とりあえずAceをコンポーネント化できました。App.vueでインポートして、ビルドしてみるとちゃんと動きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065604/17619b71-ab58-fa72-2e7a-c134b4ad73cd.png)


```App.vue
<template>
  <div id="app">
    <div style="width: 20rem; height: 10rem">
      <Ace />
    </div>
  </div>
</template>

<script>
import Ace from './components/Ace.vue'

export default {
  name: 'App',
  components: {
    Ace
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
}
</style>
```

# Aceコンポーネントのパラメータ化
せっかくなので、言語モードやテーマ、あとエディタにデフォルトで表示させるテキストを外から指定したりできるようにしてみました。
こちらに置いておきます: https://github.com/otoiku/ace_component
Rustで名刺代わりのプログラム作った

最近Rustを書いてないので、サクッとCLIソフトを作りたいと思ってたら↓みたいなのがあったのを思い出した。

[名刺いらず! npmコマンドで自己紹介カード/エンジニア流名刺を作ろう!](https://qiita.com/redshoga/items/f1b5b003650172c54044)

似たようなモノをcargoで作れるのではないかと思い、適当に作ってみた。

インターフェースはclapでサクッと作ったので真似してみてね！

https://github.com/MrBearing/takumi_okamoto

https://crates.io/crates/takumi_okamoto

サブコマンドを用意してみました。githubとかqiitaとかはブラウザが自動で開いて私のページを表示するよ！
webbrowserというまんまなクレートがあったので試してみました。

```bash

SUBCOMMANDS:
    all        A subcommand for printing all my profile
    github     A subcommand for opennig my Github
    help       Prints this message or the help of the given subcommand(s)
    qiita      A subcommand for opennig my Qiita
    skills     A subcommand for printing my skills
    website    A subcommand for opennig my website

```
jQueryのアロー関数内からはthisがundefinedになる


## 背景
jqueryの `on('click', ()=> {})` でのアロー関数内から、クリックされたタグに付加したdata属性にアクセスしたい。

## 事象
上記アロー関数内で `$(this)` を参照しても、 `undefined` になってしまい、クリックされたタグにアクセスできない。

## 解決策
`$(this)` ではなく、 アロー関数の引数からタグを取得する。
アロー関数の引数にcurrentTargetという変数があり、それが目的のタグに該当する。

#### NG
```javascript
$('.link').on('click', () => {
     $(this).data('id')   // undefined
});
```

#### OK

```javascript
$('.link').on('click', (e) => {
     $(e.currentTarget).data('id')   // 値が取れる
});
```
yukicoder contest 281 参戦記

# yukicoder contest 281 参戦記

## [A 1372 Median of Submasks](https://yukicoder.me/problems/no/1372)

MSB(most significant bit) が立つまでと、立った後が同じなので、N の MSB だけ立っているのが答え.

```python
N = int(input())

i = 0
while N != 0:
    N >>= 1
    i += 1
print(1 << (i - 1))
```
[AWS] AWS Cloud9 とは

個人的ブックマークでございます。

#[AWS] AWS Cloud9 とは

[AWS Cloud9 とは](https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/welcome.html "AWS Cloud9 とは")

> AWS Cloud9 は統合開発環境、または IDE です。

>AWS Cloud9 IDE では、リッチなコード編集エクスペリエンスを実現しており、複数のプログラミング言語、ランタイムデバッガ、および組み込みターミナルがサポートされています。また、クラウドでソフトウェアのコード作成、ビルド、実行、テスト、デバッグに使用するツールが含まれており、ソフトウェアをクラウドにリリースするのに役立ちます。

>AWS Cloud9 IDE には、ウェブブラウザを通じてアクセスできます。IDE は必要に応じてカスタマイズできます。カラーテーマを切り替えたり、ショートカットキーを割り当てたり、プログラミング言語固有の構文の色やコードのフォーマットを使用したりできます。

#AWS Cloud9 料金

[AWS Cloud9 料金](https://aws.amazon.com/jp/cloud9/pricing/ "AWS Cloud9 料金")

>AWS Cloud9 には追加料金はかかりません。AWS Cloud9 開発環境に Amazon EC2 インスタンスを使用する場合は、コードの実行と保存に使用された コンピューティング とストレージのリソース分 (例: EC2 インスタンス、 EBS ボリューム) のみのお支払いとなります。また、AWS Cloud9 開発環境を、SSH 経由で、追加料金なしで、既存の Linux サーバー (オンプレミスサーバーなど) に接続できます。

>実際に使用した分に対してのみ料金が発生します。最低料金や前払いの義務はありません。AWS Cloud9 開発環境内で作成または使用する AWS リソース (AWS Lambda 関数など) の通常の AWS 料金が課金されます。

>AWS 無料利用枠の対象である新規の AWS のお客様は、AWS Cloud9 を無料でご利用いただけます。AWS Cloud9 環境で無料利用枠を超えるリソースを利用した場合、それらのリソースには通常の AWS 料金が課金されます。
[生産性向上]Eclipseの便利機能まとめ

新卒で１年ほどエンジニアをやって来ましたが、「プログラミングができる」ことよりも、「より早く（生産性高く）」「問題解決するための方法」を身につける方が圧倒的に大切だと感じています。
今回は自身が「生産性を高めるため」「問題解決するため」に役立った考え方・知識・スキルの一つである「Eclipseの便利機能」についてまとめました。
#Eclipseのショートカットキー#
| キー① | キー② | キー③ | キー④ | できること |
| :---: | :---: | :---: | :---: | :---: |
| ctrl | / |  |  | コメントアウト |
| ctrl | E |  |  | **編集タブに開いているファイルに移動** |
| ctrl | Shift | P |  | **対応する括弧を行き来する** |
| ctrl | + |  |  | **次の注釈箇所にジャンプ** |
| ctrl | １ |  |  | **クイックフィックス** |
| F4 |  |  |  | **型階層の表示** |
| ctrl | Space |  |  | **コード補完** |
| Alt | / |  |  | **Sting型の補完** |

参考にさせて頂いたサイト
[便利な Eclipse ショートカット 15個](https://blog.codecamp.jp/eclipse-shortcut)
[【体系別】Java開発を爆速化！これだけは抑えておきたいEclipseショートカット](https://java.keicode.com/devenv/eclipse-shortcuts.php)
[全Eclipse Java プログラマーに捧げる Eclispe 徹底活用術完全版〜Eclipseに空気を読ませて楽する術〜](https://yamashiro0217.hatenadiary.org/entry/20090616/1245121197)

#Eclipseの設定#

こちらを参考にしました。
[Eclipseのオススメ設定](https://javazuki.com/articles/eclipse-settings.html)

・印刷マージンの表示オフ（コーディング時に必要ない）
・空白表示オン（全角スペースやチェックスタイル確認ができる）
・色とフォント（目が疲れないように暗めなのがおすすめ）
・保存時にフォーマット整形
・型フィルター（不必要な型候補を表示しない）
別シートの同一セルを取得したい（Range.Addressの罠）

VBAでツールを作っていた時にハマったのでメモ。

# 要件

シートAのRangeと同一範囲のセルを
シートBのRangeとして取得したい

# 実装と問題

ひとまず考え付く実装がこう。

```VB
    ' SheetAの"A1"を取得
    Dim rangeA As Range
    Set rangeA = Worksheets("SheetA").Range("A1")
    
    ' SheetBについてRange.addressを用いることでSheetAと同一のセルを取得 
    Dim rangeB As Range
    Set rangeB = Worksheets("SheetB").Range(rangeA.Address)
```

上記の実装で基本的にはうまくいくのだが、Rangeが複雑で`Range.Address()`の返り値が255文字以上の場合、想定しない結果となる。

つまりどういうことかというと、

こういうワークシートがあったときに、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1043878/90f40f33-0a51-8c0d-f756-1507d0618279.png)


下記のコードを実行すると、

```VB
    ' Range.Address()が255文字を超えるよう、あえて複雑なRangeを設定
    Dim rangeA As Range
    Set rangeA = Worksheets("SheetA").Range("A1:L13").SpecialCells(xlCellTypeBlanks)
    
    ' Rangeを可視化
    rangeA.Interior.ColorIndex = 3
    
    ' SheetBについてRange.addressを用いることでSheetAと同一のセルを取得    
    Dim rangeB As Range
    Set rangeB = Worksheets("SheetB").Range(rangeA.Address)
    
    ' Rangeを可視化    
    rangeB.Interior.ColorIndex = 3
```

結果がこうなる。

`シートA`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1043878/1c56b0ca-f149-04a9-3607-71cc32610646.png)

`シートB`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1043878/88fcc5d8-94bf-45e7-3564-e671868ef150.png)

これは、`rangeA.Address()`の返り値が255文字以上の場合、切り捨てられた状態で返ってくるためである。

# 解決方法

要するにRanse.Adressの文字列が長すぎことが原因。一度分割したものを再度結合すればよい。
下記のメソッドを実装した。

```VB
' 指定したRangeと同範囲のRangeを別シートのものとして取得する
Function GetRangeAsOtherWorksheetsRange(fromRange As Range, _
                                        toWorksheet As Worksheet) As Range
    
    ' Copy先のワークシートのセルを初期値として設定
    Dim returnRange As Range
    Set returnRange = toWorksheet.Range(fromRange.Areas(1).Address)

    ' RangeをAreaごとに分割しUnionメソッドで結合する
    Dim r As Range
    For Each r In fromRange.Areas
        Set returnRange = Union(returnRange, toWorksheet.Range(r.Address))
    Next

    Set GetRangeAsOtherWorksheetsRange = returnRange
End Function
```
```VB
    ' Range.Address()が255文字を超えるよう、あえて複雑なRangeを設定
    Dim rangeA As Range
    Set rangeA = Worksheets("SheetA").Range("A1:L13").SpecialCells(xlCellTypeBlanks)
    
    ' Rangeを可視化
    rangeA.Interior.ColorIndex = 3
    
    ' SheetBについてRange.addressを用いることでSheetAと同一のセルを取得    
    Dim rangeB As Range
    Set rangeB = GetRangeAsOtherWorksheetsRange(rangeA, Worksheets("SheetB"))
    
    ' Rangeを可視化    
    rangeB.Interior.ColorIndex = 3
```

うまくいった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1043878/a9967a9c-267c-ff73-7839-f7dc9a323aab.png)
Flutter ローカル環境にある画像の表示方法

今回はFlutterでの画像の表示方法に関して解説していこうと思います。

# 画像の準備
保存するための画像を準備しましょう。

今回は下のような画像を準備しました。
この画像を今回表示していこうと思います。

<img width="300" alt="例猫画像" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607760/8ab49e37-0d46-a089-44ba-431e4c40bf24.png">

# 画像の導入

次に画像の導入をしましょう。

pubspec.yamlを開き次のような記述を加えます。

```diff_yaml:pubspec.yaml
flutter:
  uses-material-design: true

+ assets:
+   - assets/images/hime.jpg
```
今回はassets/imagesというディレクトリを作成しその中に画像を保存します。

画像を複数保存したい場合は

```pubspec.yaml
flutter:
  uses-material-design: true
  assets:
    - assets/images/hime.jpg
    - assets/images/...
    - assets/images/...
```
といった形で追加できます。(ディレクトリの名前はそれぞれ自分のものに合わせて変更してください)

その後、Android Studioの上部にある`pub get`ボタンをクリック、もしくは下記コマンドを作成プロジェクト内で実行します。

```shell
$ flutter pub get
```

これで画像の導入は完了しました。

# 画像の表示

それでは実際画像を表示してみましょう。

```dart
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('画像表示'),
      ),
      body: Center(
        child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
          Image.asset('assets/images/hime.jpg'),
        ]),
      ),
    );
  }
}
```

上記のソースで
<img width="300" alt="例猫画像" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607760/1e2698b0-fdff-4ae9-4f2d-f97729425aff.jpeg">

このように画像が表示できました。
<br>
<br>
お疲れ様でした。
ここまでご覧戴き、ありがとうございました。
無駄なレンダリングなしで submit できる react-hook-form

React でフォーム画面を作るときに便利だった [`react-hook-form`](https://react-hook-form.com/) のメモ。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/0ba29186-2c0a-3163-3e91-d0c1287a67e1.png" width="500px" />


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/68061fd4-eea0-9c49-1d7f-4aa58542d99e.png" width="500px" />

```jsx:親コンポーネント
import React from 'react';
import { useForm } from 'react-hook-form';
import D from './D';
import E from './E';
import F from './F';

const C = () => {

  const { register, handleSubmit, watch, errors } = useForm();

  const onSubmit = (data) => {
    console.log(data); // submit時のフォームの値が入っている
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Button type="submit">送信</Button>

      {/* 子コンポーネント */}
      <D name="name" register={register} />
      <E name="mail" register={register} />
      <F name="open" register={register} />
    </form>
  )
}
export.default C;
```

```jsx:子コンポーネント
import React from 'react';

const D = props => {
  return (
    <input type="text" name={props.name} ref={props.register} />
  )
}
export.default D;
```
Python で Amazon S3 バケットの全オブジェクト名を取得するジェネレータ

Amazon S3 の ListObjectsV2 API では取得できる件数の上限が 1000 件のため、それ以上のオブジェクトリストを取得したい場合は ContinuationToken を用いて繰り返し API を叩く必要がある。

この「繰り返し ListObjectsV2 API を叩く処理」は別に難しくもなんともないが、汎用的なジェネレータ関数として実装しておくと便利なのでここにメモしておく。

## 実装
``` python
def list_all_objects(s3, **kwargs):
    continuation_token = None
    while True:
        if continuation_token:
            kwargs["ContinuationToken"] = continuation_token
        res = s3.list_objects_v2(**kwargs)
        if "Contents" not in res:
            return
        for obj in res["Contents"]:
            yield obj
        if not res["IsTruncated"]:
            break
        continuation_token = res["NextContinuationToken"]
```

## 使用例
``` python
import boto3

for obj in list_all_objects(boto3.client("s3"), Bucket="my-bucket", Prefix="foo/"):
    print(obj)
```

``` :実行結果
{'Key': 'foo/0001.csv.gz', 'LastModified': datetime.datetime(2021, 2, 4, 13, 46, tzinfo=tzlocal()), 'ETag': '"488cda75e864ced2c0afd5529f19a105"', 'Size': 2961, 'StorageClass': 'STANDARD'}
{'Key': 'foo/0002.csv.gz', 'LastModified': datetime.datetime(2021, 2, 4, 13, 46, tzinfo=tzlocal()), 'ETag': '"fa09d5eefae8672c163884f0d82b265f"', 'Size': 5702, 'StorageClass': 'STANDARD'}
{'Key': 'foo/0003.csv.gz', 'LastModified': datetime.datetime(2021, 2, 4, 13, 46, tzinfo=tzlocal()), 'ETag': '"712f063ad327d11de0c20cba27e17bf2"', 'Size': 7407, 'StorageClass': 'STANDARD'}
    :
```
レスポンシブデザインとFlexboxを初めて勉強した

#レスポンシブデザイン
スマホのスマホの表示に対応したサイト制作において必須の技術
画面のサイズに応じて最適なレイアウトになる。

メディアクエリ
画面サイズに応じてCSSのスタイルを設定する

```
<head>
・・・
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <!--メディアクエリを機能させる　画面の大きさに応じたレイアウトにさせる　
レスポンシブデザインのurlを読み込む際には、必ずviewportよりも下の行に記述する-->
・・・
<link rel="stylesheet" href="url.css">
<link rel="stylesheet" href="url.css">
<link rel="stylesheet" href="url">
・・・
</head>
・・・
<span class="fa fa-bars menu-icon"></span><!--<a>のリンクをアイコンにまとめる-->
<div class="header-right">
  <a href="#">書きたいこと</a>
  <a href="#">書きたいこと</a>
  <a href="#" class="login">ログイン</a>
</div>
・・・
<div class="clear"></div>
・・・
```
```
.menu-icon { 
  color: white;/*色を白にする*/
  float: right;/*右側にする*/
  font-size: 25px;/*字の大きさ*/
  padding: 21px 0;/*上下のpaddingの２１pxの余白*/
  display: none;/*要素を非表示*/
}
.clear {
  clear: left;/*レイアウトの崩れを修正*/
}
```  
```
@media all and (max-width: 1000px) {/*画面の幅が1000px以下の時に適応させる　タブレット向け*/
  .heading h2 {
    font-size: 20px;/*フォントの調整*/
  }
  
  .lesson {
    width :50%;/*lesson要素を画面の５０％にする*/
    margin-bottom: 50px;
  }
  footer {
    text-align: center;/*テキストやボタンのようなインライン要素、インラインブロック要素を中央にする*/
  }

}

@media all and (max-width: 670px) { /*画面の幅が６７０px以下のときに適応させる スマホ向け*/
  .header-right {
    display: none;/*クラスheader-rightを非表示にする*/
  }
  
  .menu-icon {
    display: block;/*要素の配置を縦並びにする*/
  }
 .top-wrapper .btn {/*2つのクラスを指定*/
    width: 100%;/*幅を１００％にする*/
  }
  
  .facebook {
    margin-bottom: 10px;
  }
  
  .top-wrapper {
    text-align: left;/*テキストを左寄りにする*/
  }
  
  .top-wrapper h1 {
    font-size: 24px;/*フォントの調整*/
  }
  
  .top-wrapper p {
    font-size: 14px;
  }
  .lesson {
    width: 100%;/*幅を100％にする*/
  }

  .message-wrapper .btn {
    width: 100%;/*全体にする*/
  }

}
```
理解できていないこと
・clear: left の意味
#Flexbox
flexboxとはレイアウト方法の一つ

```
.クラス名 {
display: flex;/*横並びにする*/
flex-wrap: wrap; /*折り返す要素の親要素に指定*/ 

.クラス名 li {
flex: auto;/*親要素に合わせて伸縮させる*/
width: 50%;/*２列にする*/
}
```
レスポンシブデザインにも対応させることができる

```
@media (max-width: 1000px) {/*タブレット向け*/
  .flex-list {
    flex-wrap: wrap;/*子要素のサイズに応じて折り返す*/
  }
  
  .flex-list li {
    width: 50%;
  }
```
画面が小さくなるため縦並び

```
@media (max-width: 670px) {
  .flex-list {
    flex-direction: column;/*子要素を上から下へ並べる*/
  }
  
  .flex-list li {
    margin: 0 auto;/*ブロック要素を中央にする*/
  }
```

頑張って理解できるようになりたい。
findに範囲をselectで指定してみたけど、意味あるのか？

#はじめに
先日の面談からずっとSQLを中心に勉強をしています。
今日勉強したことを自分のアプリケーションに生かしていました。
ただ、効果があるかは微妙です。

##ユーザーのマイページを表示させるページへの遷移（コントローラー部分）

###before

```ruby:before
def show
  @user = User.find(params[:id])
end
```

```sql:SQL
SELECT `users`.*
FROM `users`
WHERE `users`.`id` = 2
LIMIT 1
```
usersテーブルの全てのカラムから検索している。

###after

```ruby:after
def show
  @user = User.select(:id, :nickname, :first_name, :last_name, :email).find(params[:id])
end
```

`:id, :nickname, :first_name, :last_name, :email`はそのページで表示させるために必要だった情報です。

```sql:SQL
SELECT `users`.`id`, `users`.`nickname`, `users`.`first_name`, `users`.`last_name`, `users`.`email`
FROM `users`
WHERE `users`.`id` = 2
LIMIT 1
```
SQL文がとても長くなったが、エラーは起きず、
beforeと同じ動作はできました。


##これだとエラー

```ruby:error
def show
  @user = User.find(params[:id]).select(:id, :nickname, :first_name, :last_name, :email)
end
```
`select`と`find`を入れ替えただけ。
「検索をかけてから、探す」
と
「探してから検索をかける」
では、意味が違うのだろう。

##最後に
検証することもできないし、考える必要もないことかもしれないけど、
今回の変更で、多少でも速度や負担に変化はあるのだろうか？塵積も！？

afterの方がSQL文は長いけど、検索しているカラムは最小限だが…
でも、afterの方がコードも長いし…可読性に欠ける？

今回のことは、変化を感じることは少なかったけど、
SQLの勉強にはなりました。
AWS専門認定 セキュリティ(AWS SCS)合格体験記

# はじめに
AWS専門認定 セキュリティ – 専門知識(SCS)に合格しましたので、
情報を共有したいと思います。

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [受験時点での実力](#Chapter1)
1. [点数](#Chapter2)
1. [勉強法](#Chapter3)
1. [感想](#Chapter4)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# 受験時点での実力
AWS ソリューションアーキテクトアソシエイト(SAA)に一年前に合格。
AWS自体は業務で多少触ったことがある程度。

<a id="#Chapter2"></a>
# 点数
1回目　647点不合格　
2回目　810点で合格　

※1000点満点の試験で750点で合格。
画像は２回目受験時のもの。

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1085028/ebcd2573-e75d-0085-9cf4-4431bdc18482.png)

<a id="#Chapter3"></a>
# 勉強法
[要点整理から攻略する『AWS認定 セキュリティ-専門知識』][1]を２回読んで、最後にある練習問題を解いた。
これが終わった時点で受験したら、前述のとおり647点で不合格。
[1]:
https://www.amazon.co.jp/%E8%A6%81%E7%82%B9%E6%95%B4%E7%90%86%E3%81%8B%E3%82%89%E6%94%BB%E7%95%A5%E3%81%99%E3%82%8B%E3%80%8EAWS%E8%AA%8D%E5%AE%9A-%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3-%E5%B0%82%E9%96%80%E7%9F%A5%E8%AD%98%E3%80%8F-NRI%E3%83%8D%E3%83%83%E3%83%88%E3%82%B3%E3%83%A0%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE/dp/4839970947

演習量が足りてないと感じたので、[WEB問題集（コイワクラブ）][2]で演習をした。
これを何回か繰り返した時点で再度受験したら合格することができた。
[2]:
https://aws.koiwaclub.com/

<a id="#Chapter4"></a>
# 感想
AWS SAAよりは難しいが、そこまで難しくないと感じた。
対策にかけた期間は2か月程度。勉強すれば誰でも取れる資格だと思います。
恐らく同じ問題が使いまわされているので、一回目受けたとき不明だった点は退室までに整理しておき、次の受験までに整理しておくと合格の可能性が上がると思います。
次はAWS SAPの合格に向けて勉強を頑張りたいと思います。
macOS 10.15 で wineを利用

# 前言
最近古い windows ゲーム欲しいので、windows executionを実行できる wineを利用したくて、元々 macOS 10.14できる wineが開けらなくなりました。。。

wine公式サイトから downloadしたバーショウンでも動かないですが、githubのsource codesで直接 make, インストールしまいました

# インストール順

1. git clone https://github.com/wine-mirror/wine.git
2. brew install xquartz bison@3.7 flex mingw-w64 pkgconfig
    - bison 3.0+ が必須 
    - export PATH=/usr/local/Cellar/bison/{VERSION}/bin:$PATH の追加も必須
3. cd wine
    - ./wineのフォールダ入れて 
4. ./configure --enable-win64
    - 最新の macOS が 32-bitの構成がダメ
4. make
    - 時間かかりしょうね


# 実行

![Screen Shot 2021-02-05 at 23.36.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541166/428b1195-b3f3-3413-9007-9d3f6a7962e7.png)

wine ファイル生成されて、実行の方法がコメンドください

```
⇒  ./wine
Usage: wine PROGRAM [ARGUMENTS...]   Run the specified program
       wine --help                   Display this help and exit
       wine --version                Output version information and exit
```

![Screen Shot 2021-02-05 at 23.31.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541166/4d906a94-c7d7-4650-348b-2614191d9b8a.png)
J言語でQuineを作る

# はじめに

J言語でQuine作りたいなーと思ったので作ります。
ただ、REPLだと何でもOKになっちゃうので、今回はスクリプトとして(`load`して)動く形にしたいと思います。



# Quine

自身のコードを出力するプログラムのことです。

# J言語でQuine

さっそく完成しました。

```j
echo(,quote)'echo(,quote)'
```

**はい、短い！**

## 解説

J言語のとっても便利な機能の**フック**と、標準ライブラリの動詞`quote`を使います。

動詞`quote`は文字列をクォーテーション`'`で囲みます。

```text:実行画面
   'Hello'
Hello
   quote'Hello'
'Hello'
   
```

**フック**は引数をある動詞を適用したものと、しなかったものについて操作できます。
下の例では足し算の動詞`+`と2乗の動詞`*:`をフックにすることで、引数の`7`を2乗したものと、しなかったものを足し算します。よって、`7 + 49`で`56`となります。

```text:実行画面
   (+ *:) 7
56
   
```

文字列(リスト)の結合の動詞`,`と`quote`をフックにして、それと同じものを文字列として渡します。
すると、そのままの文字列とクォーテーション`'`で囲った文字列を結合することができ、実行したコードと同じ文字列になります！

```text:実行画面
   (,quote)'(,quote)'
(,quote)'(,quote)'
   
```

あとは出力の動詞`echo`をつけたら完成です。

```j:temp/quine.ijs
echo(,quote)'echo(,quote)'
```

```text:実行画面
   load'~temp/quine.ijs'
echo(,quote)'echo(,quote)'
   
```

# おわりに

J言語ではとてもシンプルにQuineを作ることができました。

やっぱり**フックは最強！**
なんだか難しいことはよくわからないけど、転移学習のために学習済みモデルをダウンロードしたい

#対象
Gitとかよくわからないし調べる元気はないけど、Vgg16やらVgg19やらを利用して転移学習がしたい！！特に「機械学習コンペに出てみたけど、画像コンペでとりあえず転移学習で学習させてみたい！」という初心者に向けた記事。

#やること
`vgg16_reducedfc.pth`をダウンロードする。(いずれはコピー系のコマンドをちゃんと使ってみたいけど、今だけは！今だけはそういうの抜きにしてとりあえずダウンロードしたい！！という思いの人、私です)

#Python実行環境を開く
なんでもいいです。VSVodeでもJupyterでも。
今回はJupyterNotebookで。

#コードを打ち実行する
```python
import urllib.request

url = "https://s3.amazonaws.com/amdegroot-models/vgg16_reducedfc.pth"
save_path = "./vgg16_reducedfc.pth"

urllib.request.urlretrieve(url, save_path)
```


を実行します。ディレクトリについて簡単に解説すると、Pythonでは相対的なパスとして`./`を用いることで現在のディレクトリを宣言することができるようです。
三行目のURLを変更することでいろんな学習済みモデルをダウンロードしてみてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1070392/4bf022e9-e35f-03bc-356b-0273a822ac8e.png)