OmniAICreator/Qiita-1.07M huggingface dataset:
モンドリアン風アイコンの作り方

表計算ソフト(LibreOffice Calc)をつかってSNSなどでつかうアイコンをつくってみました。
![mondrian_icon.jpg](https://qiita-image-store.s3.amazonaws.com/0/34816/8393b572-4170-0617-49b1-60c5743f1074.jpeg)

# 1. セルの大きさを正方形に整える

<img width="450" alt="mondrian_1st.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/34816/547e6af4-dfc0-9d4b-0c2a-39d35e931d8a.jpeg">
セルの幅を高さと同じに設定して形を正方形に整えます。

# 2. デザインしたい線を書き込む

<img width="450" alt="mondrian_2nd.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/34816/8a2ea359-dd1a-e07c-bcfe-e1719793478c.jpeg">
デザインしたい形（漢字）に沿ってセルの色を黒で塗りつぶします。

# 3. 線を延長する

<img width="450" alt="mondrian_3rd.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/34816/7cda9123-1d59-7c5a-0842-b7aa1dedb7d8.jpeg">
モンドリアン風デザインに近づけるために一部の線を延長します。

# 4. 三原色で塗りつぶす

<img width="450" alt="mondrian_4th.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/34816/cc37f111-9da4-091b-5570-2324a634a95e.jpeg">
白で残されているセルを赤、青、黄色で塗りつぶします。

# 5. 境界（ボーダー）を消す

<img width="450" alt="mondrian_last.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/34816/7d317f0d-085a-898e-227e-bd774e99aff8.jpeg">
セルの境界を消して出来上がりです。
StyleGenのソースの用意の仕方

# まずは公開されているgithubからソースをcloneする

`git clone https://github.com/openai/gpt-2.git`

# 次にgiutilをインストール(すでにインストールされている人は次へ進む

https://cloud.google.com/storage/docs/gsutil_install?hl=ja
ここからダウンロードしインストールする
※だいたい10分くらい？

# gsutilで対象のモデルなどをダウンロード
download_model.shを実行
※gitに公開されているデータはbashで記載されているがwindowsでも可能

##＜Windowsの場合＞
###まずディレクトリの作成
`mkdir models`
`mkdir models\117M`

###各ファイルをダウンロード
・checkpoint
`gsutil cp gs://gpt-2/models/117M/checkpoint models/117M/checkpoint`

・encoder.json
`gsutil cp gs://gpt-2/models/117M/encoder.json models/117M/encoder.json`

・hparams.json
`gsutil cp gs://gpt-2/models/117M/hparams.json models/117M/hparams.json`

・model.ckpt.data-00000-of-00001
`gsutil cp gs://gpt-2/models/117M/model.ckpt.data-00000-of-00001 models/117M/model.ckpt.data-00000-of-00001`

・model.ckpt.index
`gsutil cp gs://gpt-2/models/117M/model.ckpt.index models/117M/model.ckpt.index`

・model.ckpt.meta
`gsutil cp gs://gpt-2/models/117M/model.ckpt.meta models/117M/model.ckpt.meta`

・vocab.bpe
`gsutil cp gs://gpt-2/models/117M/vocab.bpe models/117M/vocab.bpe`


##pipで必要なモジュールをダウンロード
`pip install -r requirements.txt`
※tensorflowのバージョンによってはエラーが生じる(v1.8.0ではエラーが発生した)

#重要
これ以降の処理はまだ確認できていないため、各自gitを参考にしながら進めていただきたい。

# 参考サイト
##まるで本当みたいな フェイクニュース を書き出すAI「GPT-2」MITが開発。簡易版と論文を公開
・https://japanese.engadget.com/2019/02/15/ai-gpt-2-mit/
##Code
・https://github.com/openai/gpt-2
##OpenAI: Better Language Models and Their Implications
・https://blog.openai.com/better-language-models/#content
回帰のためのk-最近傍法アルゴリズム

```
from sklearn.neighbors import KNeighborsRegressor

X, y = mglearn.datasets.make_wave(n_samples=40)

# 分割
X_train, X_test, y_train, y_test = train_test_split(
        X, y, random_state=0)

# インスタンス生成、最近傍点は3にセット
reg = KNeighborsRegressor(n_neighbors=3) 

# モデル学習
reg.fit(X_train, y_train)

# モデル評価
reg.score(X_test, y_test)
```

なお、回帰予測器はR2スコアを返す
※回帰モデルの予測精度をあらわす指標。0-1までの数値が返され、1に近づくほど高精度な予測
【Python】シーケンスからn件ずつ取り出したい、n件未満でも取り出したい。

# 概要
- やりたかったこと
    - pythonでシーケンスからn件ずつ取り出してループしたい。
    - 末尾にn件未満の要素が残った場合、それも取り出したい。
- 結論
    - ループの中でスライスを取る。
    - Iteratorとzipを使ったら、n件未満の要素が取り出せなかった（仕様通り）。
    - itertools.zip_longestを使うと、末尾に余分な要素が追加されてしまった（これも仕様通り）。
- 環境
    - python3.6.7

# 本題
シーケンスから要素を何件かまとめて取り出したいケースって、たまにあると思います。100件のシーケンスから3件ずつ取り出す・・・というような感じです。
100件から3件ずつだと、最後は1件だけになります。この最後の1件を、1件しかないことを気にせずに取り出したい、というのがこの記事の目的です。

## 愚直にスライスを取る
**この記事で意図通りに動くのはここだけです。**
私はまだpythonを勉強がてらに始めたばかりなので、素直に考えつくのはこんな方法でした。

```python
test_data = ['いちばん', 'にばん', 'さんばん', 'よんばん', 'ごばん']

# 最大で2つずつ取り出したい
size = 2

for start in range(0, len(test_data), size):
    print(test_data[start : start + size])
```

その出力

```
['いちばん', 'にばん']
['さんばん', 'よんばん']
['ごばん']
```

シンプルです。スライスを取る時に、**シーケンスの範囲外を指定されてもエラーを起こさない**という、pythonの優しさのおかげで、ループの最終3回目は`test_data[4:6]`ですが問題なく取り出せます。

しかし、もしかしたら、もっと楽な、スマートな方法がないだろうか？と思って探してみました。
・・・探してみたけどうまくいかなかったので、試行錯誤は折り畳みます。

<details><summary>zipを使った場合（失敗しました）</summary><div>
## zipを使った場合
Googleさんにお伺いして、最初に見つけたのは大体こういった感じのコードでした。

```python
test_data = ['いちばん', 'にばん', 'さんばん', 'よんばん', 'ごばん']
size = 2 # 最大で2つずつ取り出したい

iterator = iter(test_data)
for parted in zip(*[iterator]*size):
    print(parted)
```
上のコードの出力内容

```
('いちばん', 'にばん')
('さんばん', 'よんばん')
```
最後の要素が省かれてしまいます。
元々からしてzipは長さの違う複数のイテラブルを渡すな。という仕様なので、これはごもっともな動きです。
</div></details>

<details><summary>zip_longestを使った場合（これも失敗しました）</summary><div>
## zip_longestを使った場合
zip_longestだと渡されるイテラブルの長さがそれぞれ違っても、長い方に合わせてくれますが、長さが合わない場合、詰め物（無指定ならNone）をして返してくれます。

```python
test_data = ['いちばん', 'にばん', 'さんばん', 'よんばん', 'ごばん']
size = 2 # 最大で2つずつ取り出したい

iterator = iter(test_data)
for parted in itertools.zip_longest(*[iterator]*size):
    print(parted)
```
上のコードの出力内容

```
('いちばん', 'にばん')
('さんばん', 'よんばん')
('ごばん', None)
```
最後にNoneが付いてきました。ケースバイケースで、これでいい場合もあると思いますが、今回は残念ながら違いました。
とはいえ、詰め物をしてくるのは使う前に知っていたので、これは仕方ない。
</div></details>

# 結論
素直にスライス取っちゃおうよ。ということになりました。

zipを使う方法は、**シーケンスの長さが一度に取り出したい数の倍数ぴったりなら、うまく行きます。**それでいいというケースも多々あるはずで、目的が違うなら仕方ないですね。
しかし、わざわざスライスを取る1行を省略できないか？[^1]と思って探してみましたが、**私が見つけられなかっただけ**かも知れないので、もしあったら知りたいところです。

[^1]: いっそのことイテラブルなクラスを書いてしまおうかと一瞬考えましたが、それじゃ本末転倒ですね。よほど同じ処理を繰り返すのでなければコードが増えるだけです。そして、そこまでこの処理を繰り返すコードは、ちょっと考えたくないですw
Hashオブジェクト

#Hashオブジェクト
hashオブジェクトは任意の数のkeyとvalueで構成される。

```
user1 = {name: 'Suzuki', id: 1} 
```
上記のように、key名に`：`をつけた場合は、keyがSymbolとなるので以下のようにvalueを参照できる。

```
user1 = {name: 'Suzuki', id: 1}
puts user1[:name]
>Suzuki

#Stringで指定しても参照できない
puts user1['name']
>nil
```

明示的にkeyをStringで表す場合は、以下のように記述する。

```
user1 = { 'name' => 'Suzuki', 'id' => 1}
puts user1['name']
>Suzuki
```

#階層構造を生成する
valueには任意のオブジェクトを格納できる。

```
user1 = {
  name: 'Suzuki',
  score: {
    math: 70,
    science: 80
  }
}

puts user1[:score][:math]
>70

#特定のkeyに値を代入することで値を書き換えることができる
user1[:score][:math] = 90

puts user1
>{:name=>"Suzuki", :score=>{:math=>90, :science=>80}}

```
###keysメソッドとvaluesメソッド

```
#Hashオブジェクトがもつkeyとvalueそれぞれについての配列を取得する
user1 = {
  name: 'Suzuki',
  score: {
    math: 70,
    science: 80
  }
}

user1_keys = user1.keys
user1_values = user1.values

puts user1_keys
puts user1_keys.class
>name
 score
 Array

puts user1_values
puts user1_values.class
>Suzuki
 {:math=>70, :science=>80}
 Array

```
#Hashオブジェクトのeachメソッドを使う
```
#ブロックにはkeyとvalue2つの値が渡される
user1 = {
  name: 'Suzuki',
  score: {
    math: 70,
    science: 80
  }
}

user1.each do |key, value|
  puts "#{key} = #{value}"
end

>name = Suzuki
score = {:math=>70, :science=>80}
```

#Deleteメソッドで特定のkey, valueペアを削除する

```
user1 = {
  name: 'Suzuki',
  score: {
    math: 70,
    science: 80
  }
}

user1.delete(:name)

puts user1

>{:score=>{:math=>70, :science=>80}}
```
K-近傍法による訓練/テストセットに対する性能評価

```
# まず読み込む
from sklearn.datasets import load_breast_cancer

# インスタンス生成、データセット分割処理
cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
        cancer.data, cancer.target, stratify=cancer.target, random_state=66)

# 格納用リスト生成
training_accuracy = []
test_accuracy = []

# 1-10まででとりあえずやってみる
neigbors_settings = range(1, 11)

# n_neighborsをループ処理して各精度を追加
for n_neighbors in neigbors_settings:
    clf = KNeighborsClassifier(n_neighbors=n_neighbors).fit(X_train, y_train)
    training_accuracy.append(clf.score(X_train, y_train))
    test_accuracy.append(clf.score(X_test, y_test))
    
plt.plot(neigbors_settings, training_accuracy, label="training accuracy")
plt.plot(neigbors_settings, test_accuracy, label="test accuracy")
plt.ylabel("Accuracy")
plt.xlabel("n_neigbors")
plt.legend();
```
Qiitaで画像アップロード時、Bad Requestとエラーになるときの対応方法

2019.07.20追記
どうやらバグが修正されたみたいですね。
たくさんのいいね！ありがとうございました。

---

Qiitaで記事作成するとき、画像をアップロードしようとすると`![Bad Request]()`となり、うまく画像をアップロードすることができない現象が多々発生しております。


<img width="980" alt="スクリーンショット 2019-02-16 10.45.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/92083/9e9cee08-2d06-c83c-71bb-b982e00d36d2.png">
[実際に起こったエラー画面]


なぜ、このようなエラーが起こるのかは謎なのですが、
記事作成画面で一度**スーパーリロード**してから画像をアップロードすると解消されます。

Macでしたら、`Command + Shift + R`
Winでしたら、`Ctrl + F5`
でスーパーリロードできます。

お試しください〜。
abcjsでパーカッションを鳴らしてみる

参考
- https://abcjs.net/abcjs-editor.html
- https://ja.wikipedia.org/wiki/General_MIDI

```
T:Percussion notes
L:1/4
K:perc
B,,,    \%35    Bass Drum 2
C,,     \%36    Bass Drum 1
^C,,    \%37    Side Stick
D,,     \%38    Snare Drum 1
^D,,    \%39    Hand Clap
E,,     \%40    Snare Drum 2
F,,     \%41    Low Tom 2
^F,,    \%42    Closed Hi-hat
G,,     \%43    Low Tom 1
^G,,    \%44    Pedal Hi-hat
A,,     \%45    Mid Tom 2
^A,,    \%46    Open Hi-hat
B,,     \%47    Mid Tom 1
C,      \%48    High Tom 2
^C,     \%49    Crash Cymbal 1
D,      \%50    High Tom 1
^D,     \%51    Ride Cymbal 1
E,      \%52    Chinese Cymbal
F,      \%53    Ride Bell
^F,     \%54    Tambourine
G,      \%55    Splash Cymbal
^G,     \%56    Cowbell
A,      \%57    Crash Cymbal 2
^A,     \%58    Vibra Slap
B,      \%59    Ride Cymbal 2
C       \%60    High Bongo
^C      \%61    Low Bongo
D       \%62    Mute High Conga
^D      \%63    Open High Conga
E       \%64    Low Conga
F       \%65    High Timbale
^F      \%66    Low Timbale
G       \%67    High Agogo
^G      \%68    Low Agogo
A       \%69    Cabasa
^A      \%70    Maracas
B       \%71    Short Whistle
c       \%72    Long Whistle
^c      \%73    Short Guiro
d       \%74    Long Guiro
^d      \%75    Claves
e       \%76    High Wood Block
f       \%77    Low Wood Block
^f      \%78    Mute Cuica
g       \%79    Open Cuica
^g      \%80    Mute Triangle
a       \%81    Open Triangle
```
picoCTF 2018 Mr. Robots - Points: 200

#問題

https://2018game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/999ad8f0-7bd8-a690-2313-2eea0f813b27.png)

#解いてみた

リンクにアクセスしてみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/a3c54452-b153-b171-15a0-92ac0e45e201.png)

これだけのサイトです。
ソースを見てみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/64df387f-67d6-2ef9-5fa4-0219226757d1.png)

このhtml自体には何もなさそうです。
CSSを見てみても特に不審な点はありません。

「robot 制限」とかで検索するとrobots.txtというファイルで制御できるようです。
Googleとかの検索エンジン用ロボットの制御ファイルだとか。

このファイルがあるかチェックしてみます。

```
http://2018shell.picoctf.com:29568/robots.txt
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/368e7af1-9cac-3b7f-f65a-7f5ee6454183.png)

アクセスできました。
書かれている/74efc.htmlにアクセスしてみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/22523eaa-bb0e-07b8-d3e5-4768459daadd.png)

ありました。
Arrayオブジェクトとループ

#Array(配列)オブジェクト
```
#種類の違うオブジェクトを混在させることができる
arr1 = [1, 'string', 1.5]

#要素の追加(pushと<<)
arr = []
arr.push('1つ目')
arr << '2つ目'
```

**文字列やSymbolで配列を初期化(新たに生成？？)する場合は積極的に%記法を使うと良い。**　
```
# %を使った記法？(以下2つの配列生成は同じ意味となる)
arr1 = ['文', '字']
arr2 = %w[文 字] 
```

```
# 大文字Wを使うと変数を認識できる
one = 1
two = 2
arr = %W[a#{one} b#{two}]
```
```
#Symbolの配列を生成する%記法
sym_arr = %i[a b c]
```

#ループ
###each
```
arr = %w[a b c]

arr.each do|str|
  puts str
end

# ループはbreakで止めることができる
arr1 = %w[あ い う]

arr1.each do|str|
  break if str == 'う'
  puts str
end

#nextを使って、ある条件に合致する場合は飛ばす
arr2 = %w[x y z]

arr2.each do |str|
  next if str == 'y'
  puts str
end
```

#mapメソッド
###mapメソッドを使って、配列を加工する
```
arr = %w[a b c]

arr2 = arr.map { |str| "(#{str})"}
puts arr2

```
一般的にプログラミング言語ではreturnで戻り値を返すが、**Rubyではブロックの最終行の式の結果が自動的に戻り値となる。**

#多重代入
```
foo, bar = [1, 2]
puts foo
puts bar

>1
 2

#以下も同じ結果となる
foo_1, bar_1 = 1, 2

#右側の数が足りない場合は変数にnirが格納される
foo_2, bar_2 = 1
puts foo_2
puts bar_2

>1
 nil
```
nilはNilClassのオブジェクトで値の設定されていない状態を表す

```
foo_2, bar_2 = 1

puts bar_2.class

>NilClass
```

```
#左側の変数が足りない場合は右側の値が無視される
foo, bar = 1, 2, 3
puts foo
puts bar

>1
 2
```
QGIS3.4でGoogleMapSatelliteのLayerを作る

#はじめに
QGIS3.4をインストールしてみて、
GoogleMapSatelliteを表示しようと、
以前あったOpenLayerPluginが見つからないので
他の方法があるようなので、試してみました。

#XYZ tilesに新しい接続を追加
QGIS3.4上で、Browserウィンドの中の
XYZ Tilesを右クリックして
「新しい接続」をクリック。

#URLを設定する
立ち上がるウィンドウで
名前に「Google Map Satellite」などを入力
（特に何でもよい）
URLに「https://mt1.google.com/vt/lyrs=s&x=%7Bx%7D&y=%7By%7D&z=%7Bz%7D」
を入力。

その他はとくに設定せず、「OK」を選択。

#レイヤーを追加して、確認
XYZ Tilesの中に
先ほどの名前（Google Map Satelliteなど）ができるので
レイヤーに設定すればOK!

#参考
https://www.youtube.com/watch?v=67ZruLlGdJs

#作業スクリーンショット
![QGISforGoogleMapSatellite3.jpg](https://qiita-image-store.s3.amazonaws.com/0/162684/8096cc6e-ab01-e396-e40b-5b08b498b31e.jpeg)

![QGISforGoogleMapSatellite4.jpg](https://qiita-image-store.s3.amazonaws.com/0/162684/5ae7853c-5451-f115-1c26-5ad2372ff70f.jpeg)
picoCTF 2018 ssh-keyz - Points: 150

#問題

https://2018game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/d142cd48-1798-cf37-a2f6-8634c173c918.png)

#解いてみた

SSHのキーを作成してそれをサーバに保存してクライアントからログインする。
という問題でしょうか。

```
ssh-keygen
```

でキーを作って

```
ssh -l CTFman 2018shell2.picoctf.com
```

やるとフラグが出ました。
Docker Hub で自動ビルドするときに Git のコミットIDをイメージに埋め込む

`Dockerfile` からの相対で `hooks/build` というファイルに次のようなスクリプトを置きます。

```sh
#!/bin/bash

docker build --build-arg SOURCE_COMMIT=$SOURCE_COMMIT -f $DOCKERFILE_PATH -t $IMAGE_NAME .
```

例えば次のようなレイアウトです（Build Context が `hoge/` な例）。

```
./hoge/
    Dockerfile
    hooks/
        build
```


`Dockerfile` で `SOURCE_COMMIT` がビルドの `ARG` として使えるようになります。

```sh
FROM busybox

ARG SOURCE_COMMIT

ENV SOURCE_COMMIT $SOURCE_COMMIT

CMD ["env"]
```

## 詳細

[Advanced options for Autobuild and Autotest](https://docs.docker.com/docker-hub/builds/advanced/) の **Custom build phase hooks** を用いたものです。

`hooks/build` というファイルがあれば `docker build` の代わりに呼ばれます。このスクリプトでは以下の環境変数が利用可能です。

- `SOURCE_BRANCH`: the name of the branch or the tag that is currently being tested.
    - e.g. `master`
- `SOURCE_COMMIT`: the SHA1 hash of the commit being tested.
    - e.g. `5852b96005ac94839ac828b0771e5338cc7e9376`
- `COMMIT_MSG`: the message from the commit being tested and built.
    - e.g. `first commit`
- `DOCKER_REPO`: the name of the Docker repository being built.
    - e.g. `index.docker.io/your/awesome`
- `DOCKERFILE_PATH`: the dockerfile currently being built.
    - e.g. `Dockerfile`
- `CACHE_TAG`: the Docker repository tag being built.
    - e.g. `latest`
- `IMAGE_NAME`: the name and tag of the Docker repository being built. (This variable is a combination of `DOCKER_REPO:CACHE_TAG`.)
    - e.g. `index.docker.io/your/awesome:latest`

これらを `docker build` の `--build-arg` で渡せば `Dockerfile` で ARG として使用できます。

`hooks/build` 以外に `hooks/test` や `hooks/push` で自動ビルドの各フェーズが上書きできるようです。

また、以下のようなスクリプトでビルドの各フェーズ間に処理を挟むことができます。

- `hooks/post_checkout`
- `hooks/pre_build`
- `hooks/post_build`
- `hooks/pre_test`
- `hooks/post_test`
- `hooks/pre_push`
- `hooks/post_push`

例えば `hooks/post_push` を次のような内容で作成しておけば、自動ビルドの Build Rules とは別に Git のコミットIDを Docker タグにできます。

```sh
#!/bin/bash

docker tag $IMAGE_NAME $DOCKER_REPO:$SOURCE_COMMIT
docker push $DOCKER_REPO:$SOURCE_COMMIT
```

## 参考

- https://docs.docker.com/docker-hub/builds/advanced/
- https://github.com/docker/hub-feedback/issues/600
picoCTF 2018 Irish Name Repo - Points: 200

#問題

https://2018game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/18401934-01eb-d245-4090-57ccd32d8b5c.png)

#解いてみた

やっと200点問題になりました。

指定されたWebサイトにログインしましょう。
という問題。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/96afdaca-45a1-022d-eacd-5525dbdddefc.png)

こんな感じのサイトでした。
左上のメニューを開くとログイン画面へのリンクがあったので遷移してみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/35bc62d3-0a68-cc3b-2a51-c7d5aeca50ae.png)

ログイン画面に移動しました。
ソースを見てみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/b7e95f5b-9405-6c24-5e17-b91875e8650f.png)

submitしたときにlogin.phpに遷移するってことが分かる程度でしょうか。

何も入力せずにログインボタンを押すとログイン失敗します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/9df75835-1972-ada3-1047-9a6828d4b231.png)

「a」とか適当な文字を入れてログインボタンを押しても同じ挙動でした。

SQLインジェクションでしょうか。
ユーザ名に「' or 1 == 1 --」を入力してみます。パスワードは空欄です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/36063e8d-1ace-a94d-a579-21356a2b6a97.png)

できました。
ARマーカーを使った位置決めスコープ作り　

#　はじめに
ある物体を決まった位置に動かしたいといった要望があったので、
ラズベリーパイ＋Picameraを使い、物体にARマーカーを貼り付け、
作業のアシストをしようと思い、ツールを製作しました。
#　概要
まず固定されている目標の座標を出し、カメラでARマーカーの座標を取得します。
この２つの座標が一致すれば、決められた位置に移動したことになります。


実際のレイアウトは以下の感じです。
黄色の物体の底面にARマーカーを張り付け、下から固定されたカメラで見上げています。
ユーザーは目の前にあるモニタを見ながら、コントローラーで黄色の物体を四角いテーブルの中心線まで移動させます。

![20191565.png](https://qiita-image-store.s3.amazonaws.com/0/361605/36d21360-8e7a-f32a-af21-96fc21cd38e3.png)

このツールを使う人はコントローラーを操作しながら位置決めをします。
あまりゴチャゴチャした見た目だと視覚的に操作し辛いので、
出来るだけシンプルなグラフィックにする必要があります。


そこでpythonにturtleという機能使って位置決めスコープを作ってみようと思います。



```py
import cv2
import numpy as np
import turtle
#座標設定
#ループの前に変数宣言をして処理を軽くする狙い。
x2,y2,xa,ya= 0,0,0,0
#画面設定
side,length = 800,600
size = (side , length)
#画面の中心に線を引きたいので、その座標
px,py=side/2,length/2

#turtleの生成
wn = turtle.Screen()
tur = turtle.Turtle()
#タートルの姿を設定（丸）
tur.shape('circle')
tur.pencolor('red')


tur.tracer=(0)
#画面にスコープ用の十字線を引く
tur.goto(0,0)
tur.goto(side,0)
tur.goto(0-side,0)
tur.penup()
tur.goto(0,0)
tur.pendown()
tur.goto(0,length)
tur.goto(0,0-length)
tur.goto(0,-20)

#位置合わせ用の丸を描く
tur.pencolor('red')
tur.circle(20)
tur.penup()

tur.goto(0,0)
tur.turtlesize(2,2,2)


#ARマーカーの設定
aruco = cv2.aruco 
dictionary = aruco.getPredefinedDictionary(aruco.DICT_4X4_50)
cam = cv2.VideoCapture(0)

try:   
    while True:
        ret, img = cam.read()
        img = cv2.resize(img,size)
        corners, ids, rejectedImgPoints = aruco.detectMarkers(img, dictionary)
        aruco.drawDetectedMarkers(img, corners, ids, (255,0,255))
        try:
　　　　　　　#ARマーカーの四角の端の座標を取得
            x = int(corners[0][0][0][0])
            y = int(corners[0][0][0][-1])
　　　　　　　#マーカーに動きがあった場合の処理
            if (x != x2 or y != y2):
                xa,ya=px-x,py-y
                print("x= ",xa,"y= ",ya)
　　　　　　　　　#移動後の座標をセットして
                x2,y2=x,y
　　　　　　　　　#タートルを移動させる
                tur.goto(xa,ya)
                tur.seth(0)
        except:
            pass

        
except KeyboardInterrupt:
    pass
```

#　プログラム起動後
しばらくturtleが十字線と中心円を引いて忙しく動き回り、ARマーカーの座標に移動します。
視覚的に、ARマーカーが中心円からどれだけ離れているかが確認できます。

![python__AR__Turtle.jpg](https://qiita-image-store.s3.amazonaws.com/0/361605/a6c0e158-f95a-031a-853a-0bcb0f7d7a35.jpeg)


これがARマーカーが中心線と合う位置まで来た場合、

![2019215105520194.png](https://qiita-image-store.s3.amazonaws.com/0/361605/0539e793-c97b-3a17-27b7-28b4fb488e73.png)

turtleが円の中心に来て、位置決め完了です。

![python__AR__Turtle2.jpg](https://qiita-image-store.s3.amazonaws.com/0/361605/1f052ac8-b0e5-4bfd-347d-24e4ce869883.jpeg)



#　まとめ
位置決め精度はカメラとマーカーの距離によって変わりますが、
2mほど離した状態でもかなり高い精度でした。


このプログラムは、カメラと目標座標が固定されていることが条件だったので、
幸い何とか形になりました。
ループ内で変数宣言するとpythonの型変換の仕様上重くなるとどこかの記事で見たので、
コード始めに宣言していますが、体感的にそこまで差はありませんでした。

ラズパイのスペックではレスポンスに0.3秒ほどラグがありますが、
ボードのスペックが高くなればレスポンスも速くなりそうです。
postmanで、postリクエストを送り、createアクションを通じてjsonで返すまで

#postmanで、postリクエストを送り、createアクションを通じてjsonで返すまで

createアクションは以下

```
projects_controller

def create
    @project = Project.new(project_params)
    @project.save
    render json: @project
end

private

def project_params
     params.require(:project).permit(:title, :status)
end
 
```

postmanにpostのURLを入力

URLの下のバーから「body」を選択

下の「row」を選択

右端のタブの中から「json」を選択

入力フィールドにjson形式でデータを入力

```
projectモデルの、titleカラムとstatusの例
{
    "project": {
        "title": "first project",
        "status": "closed"
    }
}
```

これでpostリクエストを選択し、sendするとcreateアクションが実行され、jsonでデータが返ってくる。

DBにも正常にオブジェクトが保存されている。

```
irb(main):003:0> Project.all
  Project Load (0.7ms)  SELECT  "projects".* FROM "projects" WHERE "projects"."deleted_at" IS NULL LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Project id: 11, title: "first project", deleted_at: nil, created_at: "2019-02-16 00:21:17", updated_at: "2019-02-16 00:21:17", status: "closed">, #<Project id: 12, title: "test P", deleted_at: nil, created_at: "2019-02-16 00:22:07", updated_at: "2019-02-16 00:22:07", status: "closed">]>
```

updateアクションの場合

```
def update
    @project.update_attributes(project_params)
    render json: @project
end

def project_params
     params.require(:project).permit(:title, :status)
end
```

postmanでputchリクエストを選択

URLはprojects/:idにしてsend

参考

https://www.xlsoft.com/jp/blog/blog/2017/06/23/post-1638/
postmanでpostリクエストを送り、createアクションを通じjsonで返すまで

#postmanで、postリクエストを送り、createアクションを通じてjsonで返すまで

postmanにpostのURLを入力

URLの下のバーから「body」を選択

下の「row」を選択

右端のタブの中から「json」を選択

入力フィールドにjson形式でデータを入力

```
projectモデルの、titleカラムとstatusの例
{
    "project": {
        "title": "first project",
        "status": "closed"
    }
}
```

これでpostリクエストを選択し、sendするとcreateアクションが実行され、jsonでデータが返ってくる。

DBにも正常にオブジェクトが保存されている。

```
irb(main):003:0> Project.all
  Project Load (0.7ms)  SELECT  "projects".* FROM "projects" WHERE "projects"."deleted_at" IS NULL LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Project id: 3, title: "third p", deleted_at: nil, created_at: "2019-02-15 11:16:26", updated_at: "2019-02-15 11:16:26", status: "open">, #<Project id: 10, title: "test P", deleted_at: nil, created_at: "2019-02-16 00:21:14", updated_at: "2019-02-16 00:21:14", status: "closed">, #<Project id: 11, title: "test P", deleted_at: nil, created_at: "2019-02-16 00:21:17", updated_at: "2019-02-16 00:21:17", status: "closed">, #<Project id: 12, title: "test P", deleted_at: nil, created_at: "2019-02-16 00:22:07", updated_at: "2019-02-16 00:22:07", status: "closed">]>
```
picoCTF 2018 hex editor - Points: 150

#問題

https://2018game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/00be17c6-4347-2382-95bc-9c22f51c1ffd.png)

#解いてみた

ファイルをダウンロードしてみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/23221776-5bb2-226e-c72a-b24624085251.png)

猫の画像です。
Bzで開いてみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/6259aff0-9e88-bfb7-1585-4b10da37acc4.png)

ファイルの最後のところに書かれてました。
HTTPサーバのHTTPS化

#これは何？
ドメイン名でアクセスできるApache HTTPサーバをHTTPS化する方法の一つ、フリーの証明書を発行する「Let's Encrypt」を利用する方法が書かれています。ただし、まだApache HTTPサーバを構築していない場合は、こちらを参照してください。
> [クラウドでWebサーバを構築する](https://qiita.com/__THANKS_JP__/items/d3182922a30c582a8ed7)
> クラウドコンピューティングを利用してWebサーバを構築する方法の一つ、GoogleCloudPlatformを使う方法が書かれています。

#ドメインでアクセスできるApache HTTPサーバをHTTPS化する
手順は次の通り
1. Let's Encryptのクライアントソフト「Certbot」をインストール
2. Certbotを使ってLet's Encryptから証明書を受け取る
3. ApacheでSSLに対応するための「mod_ssl」モジュールをインストール
4. mod_sslでさっき受け取った証明書を使うよう設定する
5. Apache HTTPサーバを再起動する

## Certbotをインストール
例えば、CentOS7の場合は、次のコマンドでインストールできます。

``` shell:
$ sudo yum install epel-release
$ sudo yum install certbot python-certbot-apache
```

他の環境については、こちらを参照してください。
> [Certbot クライアントのインストール - Let's Encrypt 総合ポータル](https://free-ssl.jp/usage/install-certbot.html)
> Certbot クライアントの適切なインストール手順は、OS（ディストリビューション）によって異なります。使用している OS を選んでください。

## Let's Encryptから証明書を受け取る
次のようなコマンドで、Apache HTTPサーバを停止することなく証明書を受け取ることができます。

``` shell:
$ sudo certbot certonly --webroot -w /var/www/html -d www.qiita.com
```

- `/var/www/html`の部分は、サーバのドキュメントルートなので、Apacheで設定されているパスに置き換えてください。
- `www.qiita.com`の部分は、サーバのアドレスに紐付けられた実際のドメインに置き換えてください。
- 途中でメールアドレスを入力したり、質問に答える部分があるかもしれないので、画面の指示に従ってください。

例：

``` shell:
Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): xxxxx@qiita.com
(A)gree/(C)ancel: A
(Y)es/(N)o: N
```

## mod_sslをインストール
次のコマンドで、ApacheでSSL証明書を利用するための、「mod_ssl」モジュールをインストールできます。

``` shell:
$ sudo yum install mod_ssl
...
Is this ok [y/d/N]: y
```

## mod_sslで証明書を使うよう設定する
例えば、次のコマンドで「viエディタ」を起動し、設定ファイルを書き換えます。

``` shell:
$ sudo vi /etc/httpd/conf.d/ssl.conf
```

書き換える箇所は次の通り
SSLCertificateFileで始まる行を探し、次のように書き換えます。`www.qiita.com`を実際のドメインに書き換えてください。

``` /etc/httpd/conf.d/ssl.conf
SSLCertificateFile /etc/letsencrypt/live/www.qiita.com/cert.pem
```

SSLCertificateKeyFileで始まる行を探し、次のように書き換えます。

``` /etc/httpd/conf.d/ssl.conf
SSLCertificateKeyFile /etc/letsencrypt/live/www.qiita.com/privkey.pem
```

SSLCertificateChainFileで始まる行を探し、次のように書き換えます。

``` /etc/httpd/conf.d/ssl.conf
SSLCertificateChainFile /etc/letsencrypt/live/www.qiita.com/chain.pem
```

## Apache HTTPサーバを再起動する
例えば、CentOS7の「Apache httpd」の場合は、次のコマンドで再起動できます。

``` shell:
$ sudo systemctl reload httpd.service
```

# Let's Encryptから受け取った証明書を自動更新する
証明書には有効期限がありますので、無効になる前に更新する必要があります。証明書の更新は、次のコマンドでできます。

``` shell:
$ sudo certbot renew --post-hook "sudo systemctl reload httpd.service"
```

`--post-hook`オプションで、証明書が更新された直後に再起動するようにします。このコマンドをCronに登録すれば、自動で定期的に証明書を更新できます。

## Cronに登録する
まずは、cronが動作中かどうか確認します。

``` shell:
$ systemctl statuc crond
```

例えば、次のように、Viエディタで`/etc/cron.d/certbot`ファイルを新規作成すると、登録できます。

``` shell:
sudo vi /etc/cron.d/certbot
```

``` shell:/etc/cron.d/certbot
# letsencrypt renew
0 4 * * 3 root certbot renew --post-hook "systemctl reload httpd.service"
```

# 余談
Let's Encryptを利用すれば、無料でSSL証明書を発行してもらうことがます。したがって、ドメインを所有していれば、自分のWebサイトを無料でHTTPS化することができます。
Go+cgoをMacでクロスコンパイル

go-sqlite3 を使った Go のプログラムを Mac でクロスコンパイルして Linux や Windows に持っていくと、次のようなエラーが出て実行できませんでした。

> Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub

そこで cgo を使った Go のプログラムを Mac でクロスコンパイルして Linux や Windows で実行できるようにした時のメモです。

## Linux

### musl-cross をインストール

```
brew install FiloSottile/musl-cross/musl-cross
```

### ld-musl-x86_64 をスタティックリンクしてビルド

```sh
GOOS=linux GOARCH=amd64 CGO_ENABLED=1 CC=/usr/local/bin/x86_64-linux-musl-cc go build --ldflags '-linkmode external -extldflags "-static"' -a -v hoge.go
```
上記の方法を使うと実行時に必要なライブラリがスタティックリンクされ、コンパイルして出力された実行ファイルを Linux にコピーするだけで実行されました。

### ld-musl-x86_64 をダイナミックリンクするようにビルド

一方、次のようにすると、ライブラリが実行時に参照されるためか、実行ファイルは少し小さくなりますが、ライブラリファイルを Linux 環境に配置しておく必要がありました。

ビルド

```sh
GOOS=linux GOARCH=amd64 CGO_ENABLED=1 CC=/usr/local/bin/x86_64-linux-musl-cc go build -a -v hoge.go
```

ld-musl-x86_64.so を配置

```sh
scp -p /usr/local/Cellar/musl-cross/0.9.7_1/libexec/x86_64-linux-musl/lib/libc.so root@192.168.1.1:/usr/local/lib64/ld-musl-x86_64.so
ln -s /usr/local/lib64/ld-musl-x86_64.so /lib/ld-musl-x86_64.so.1
```

ld-musl-x86_64.so がないと、次のようなメッセージが表示され、実行できませんでした。

> /lib/ld-musl-x86_64.so.1: bad ELF interpreter: そのようなファイルやディレクトリはありません

普通にビルドして実行するぶんには、スタティックリンクがおすすめかと思います。

## Windows

Windows の場合は、次の手順で実行できるようになりました。

### mingw をインストール

```
brew install mingw-w64
```

### ビルド

```sh
GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc CGO_ENABLED=1 go build -a -v hoge.go
```
UIViewを簡単にキャンバス化する

<img src="https://qiita-image-store.s3.amazonaws.com/0/25727/db76d56e-ccc7-966f-dc89-7a97884e3b2e.png">

ビューに図形を描きたい場合、

* `UIGraphicsImageRenderer` を利用し、 `UIImage` に図形をレンダリング
* `UIImageView` を配置し、レンダリング画像を設定

のような方法を取るのが一般的かと思いますが、実は `UIImageView` を配置しなくても、 `UIView` だけでレンダリングした図形を表示する方法があります。

> `UIColor` のイニシャライザのひとつに `init(patternImage: UIImage)` というものがあり、これを `UIView` の `backgroundColor` に設定すると、 `UIView` に画像を表示することができるのです。

```UIView+Render.swift
extension UIView {
    func render(actions: (UIGraphicsImageRendererContext) -> Void) {
        let renderer = UIGraphicsImageRenderer(size: self.bounds.size)
        let image = renderer.image(actions: actions)
        self.backgroundColor = UIColor(patternImage: image)
    }
}
```

上記のような extension を追加すれば、図形を簡単にレンダリングできるようになります。

```swift
// 楕円をランダムに描画
view.render { (context) in
    context.cgContext.clear(view.bounds)

    for _ in 0...50 {
        let rect = CGRect(
            x: .random(in: 0...300),
            y: .random(in: 0...600),
            width: .random(in: 50...100),
            height: .random(in: 50...100)
        )

        let color = UIColor(
            red: .random(in: 0...1),
            green: .random(in: 0...1),
            blue: .random(in: 0...1),
            alpha: 1.0
        )
        color.setFill()
        context.cgContext.fillEllipse(in: rect)
    }
}
```

[Playground](https://github.com/imk2o/DrawableViewPlayground)も置いておきます。
WSLでDockerを動かす

# WSLでDockerを動かす

Windows10には、WSL(Windows Subsystem for Linux)と呼ばれる、Linux環境を動作することが出来る機能が備わっています。この環境でDockerを動かすことを確認します。

**すみません、私の環境では、以下の手順だとコンテナからインターネットへ通信することが出来ません。要調査。ネットワーク疎通をしないものであれば動作可能です**

## とりあえず普通にやってみる

とりあえず普通に、WSL(Ubuntu18.04) で Docker(18.06.2) を動かしてみたら、エラーでうごきませんでした。docker pull の時に、以下のエラーが発生します。

```
root@tora-PC:~# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
a02a4930cb5d: Extracting [==================================================>]  75.17MB/75.17MB
failed to register layer: Error processing tar file(exit status 1): invalid argument
```



## Docker Install

現時点では、Dockerバージョン17.09.1 以降のものは、WSLでは動作しないようで、17.09.0 を Installすると正常に動作します


Repositoryの設定

```
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   bionic \
   stable"
sudo apt update
```





docker-ce(17.09.0)のdebファイルをダウンロードします

```
wget https://download.docker.com/linux/ubuntu/dists/xenial/pool/stable/amd64/docker-ce_17.09.0~ce-0~ubuntu_amd64.deb
```



DockerをInstallします

```
sudo dpkg -i docker-ce_17.09.0~ce-0~ubuntu_amd64.deb
```

Userの設定。ログインユーザをdocker group に所属することにより、dockerコマンドを sudo 無しで実行を出来るようにする

```
sudo cgroupfs-mount
sudo usermod -aG docker $USER
```


Dockerを開始します。systemctl は WSLでは動作しないため、serviceコマンドで開始します。
**WSL や ターミナルソフトを管理者権限で動作させると正常にDockerを開始できます**

```
sudo service docker start
```



正常に開始されたことを確認します

```
> sudo service docker status
* Docker is running
```



Dockerの動作確認のために、hello-world コンテナを稼働します

```
docker run hello-world
```



実行例

```
> docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
```



# 参考URL

どうしても Docker on Ubuntu 18.04 on WSL したかった
https://qiita.com/guchio/items/3eb0818df44fdbab3d14

http://www.nuits.jp/entry/docker-on-wsl

http://j-levia.hatenablog.jp/entry/2019/01/02/234032
Google Colaboratory でR言語を使う

ディープラーニングをR言語でやるときに，Google ColaboratoryのGPUを使いたくなるかと思います．そのためには，Google ColaboratoryでR言語を使えるように設定しないといけません．
本記事ではその方法を紹介します．

[こちらの英語のサイト](https://discourse.mc-stan.org/t/r-jupyter-notebook-rstan-on-google-colab/6101)を参考にしました．

まず，ノートブックに以下をコピペします．

```
!apt-get install libssl-dev > /dev/null
!wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh
!chmod +x ./Miniconda3-latest-Linux-x86_64.sh
!./Miniconda3-latest-Linux-x86_64.sh -b -p /conda  > /dev/null 2>&1 
!/conda/bin/conda install -c r r-rstan r-irkernel gxx_linux-64 -y -q > /dev/null 2>&1
!/conda/bin/R -e "IRkernel::installspec(name = 'python3', displayname = 'R', user = FALSE)"  > /dev/null 2>&1
!mkdir /root/.R/
!echo "CXX14FLAGS=-O3 -mtune=native -march=native -Wno-ignored-attributes -Wno-deprecated-declarations" > /root/.R/Makevars
import os
os._exit(00)
```

ただし，上から6行目の'python3'はpython2系を使っている場合，'python2'に直す必要があります．

これを実行すると，数分後に以下のような画面が表示されます．
![google_colab.PNG](https://qiita-image-store.s3.amazonaws.com/0/317052/26972270-de77-c8ea-f02e-18b54e973a1c.png)

「不明な理由により，セッションがクラッシュしました」と表示されるはずです．

次に，上部の「ランタイム」から「セッションの管理」を選びます．
![アクティブなセッション.PNG](https://qiita-image-store.s3.amazonaws.com/0/317052/d12d0600-eda2-a62d-af07-9b01d151ccd5.png)
すると，アクティブなセッションの一覧が出ますので，「終了」ボタンを押します．

この後に，ノートブックを再接続すればR言語を使うことができます．
例えば次のようなhelloと言うRの関数も動きます．
![hello.PNG](https://qiita-image-store.s3.amazonaws.com/0/317052/3e5ed328-b395-2389-3741-758bc7e90e50.png)
とあるエンジニアの問題意識 2019-02-15


# プログラミング言語の死。

死んだかどうか噂される時点で既に死にかけている。だが周りが思うよりしぶとく生き残る場合もある。枯れたスタンダードになる可能性も。ロック然り。紙の書籍然り。テレビ業界然り。いちど浸透したフォーマットはわりとしぶとい。枯れるか切るかも我次第。#エンジニア <https://t.co/KWyHq4rOR2> <http://twitter.com/YumaInaura/status/1096177831258742784>

# Twitterと著作権。

法律か何かが変わったらしい。それを注意喚起する人。だがその人の他のツイートを見ると思いっきり映画ホームアローンの模写イラストが描かれている。元のブログは削除されていた。何か指摘があったのだろうか。だから僕は著作権絶滅を支持する。プログラマならそう思う。#エンジニア <http://twitter.com/YumaInaura/status/1096188907803136000>

# 言葉はモジュール。

実験に成功すれば、たやすくメンタルモデルを構築できる。言葉は歴史を持っている。歴史あるもの同士が結合し発火する。例えば錯覚資産という表現。もともとの意味を知らずとも意図を推し量れる。優れた技術選択。巨大なモジュール同士が働きあいロボットが動く。#エンジニア #言葉 <https://t.co/h2qrpi1B4T> <http://twitter.com/YumaInaura/status/1096207727880134656>

# 焦らない技術。

会社に入ってから、焦る癖が露呈した。深刻な問題だった。マインドフルネスの技術でどうにか直した。むしろ周りと比べても落ち着きが最大化した。

だが時は経ちまた感じる。スピード感を上げると後遺症で焦りが生まれる。本当はハイウェイを降りているのに気づかない。

# 自分の身体感覚を反射しているだけなのに世界本体のように感じる。

# 日々の業務に流されずにいかに自覚的になるか。

僕には絶対に必要なこと。すべての人に理解されるとは限らない。

チームでのKPIなど振り返りの手法は受け入れられているが、個人的においての振り返り手法を説明できる自信はない。なにかと人に伝わらない事が多い。

# タスクを次から次へと切り替えると、注意残余の起こり方が激しい。

人間はそもそもマルチタスキングは出来ないというが、僕の場合は顕著だ。ワーキングメモリが少ない。

だがディープワークではなくマルチタスキングの方が、偽りの刺激がある分だけ、誘惑が強い。テレビのチャンネルをザッピングするだけで、仕事をしている感じだけは出るからだ。

# 注力を担保したいときはSlackのサイドバーをそっと隠す。

単にウィンドウの端っこに持ってくる。これは一番手軽なやり方だ。前に自分で編み出した。

こうやって無限のワークハックを利用する。これを技だと思うだけで煩雑さが感じられて辛いが、世界をベールで覆う自己保全だと考える。

# 自分に起こっている注意残余をしみじみと感じる。

Slackのチャンネル一個を切り替えるだけで、脳の状態が変わる。

マインドフルネスの技術で、感情や体の状態だけではなく、意識状態にまで敏感になることができる。今ならば。余裕があるときは。

# 物事を理解するために絵や図を描くことを嫌う。時に。だめな習慣だ。

なんだか裏技を使うようでずるい気がする。頭の中だけで考えるものぐさをしたい。

なぜなのか。単に手近にホワイトボードを置いておらず、コストが高い。それに後から頭が言い訳をつけているだけなのかもしれない。

# SQLのクエリをレビューするときは、Githubではなくてエディタにコピーしたほうが見やすい。

こんなごく簡単なハックさえ、夢のように世界を変える。脳に厳しい北風の世界から、優しい太陽の世界へ。

なぜ僕らは自分自身に優しくしないのだろう。もっと彩れよ color coder

# SQLクエリのレビュー。クエリが粘土みたいに手にとれて、こねこねと出来たら良いのに。

柔軟性の高い物理世界で理解したい。平面からの立体理解にはかなりのコストがかかる。ずっと立ち止まってしまう場合もある。

そもそもコードリーディングは平面からの立体化技術なのだけれど。難易度が高い場合は。

# 体が弱ると涙もろくなる。

最近は会社でも。

数分間目を閉じて休めると、今日はニット帽の下でうっすらと涙がこぼれた。

給与問題もアイデンティティの問題よりも今は死の問題が浮かぶ。

いつか死ぬ命がまるで、永遠に続くかのように擬態している奇跡が、こわい。

# エンジニアでも、コーダーに近い作業と、狭義のエンジニアリングに近い領域がある。

後者のエンジニアの生産性は一撃必殺。ためてためて撃つ。シャローワークでは無理な領域。

手を動かさずして勝つ。プログラミングしていない時間がエンジニアリングだ。

# タスク切換えによる注意残余が起こると、それが体内のほんの1%ほどのゆらめきであっても、体が引き裂かれるFlavorを感じる。

注意残余をいかに減らすか。いかに注意力の波に乗るか。切実な課題だ。

マルチタスキングではなく、一本の物語のように、1日の業務を渡り歩く。細い糸。

# 頭は良くならない。絶対に。

汎用的な知性は存在しない。どこにも。

脳トレ時代に生まれた僕は、IQを高めようとしてしまう。無駄な努力。

存在するのは適応と戦略と工夫だけ。

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/594








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Power Query の数値を丸める関数

どうして？って話があったのでまとめておくかと思った次第。数値の端数処理。ムキーっとなることがあるのです。慎重にというか忘れなければよいだけのこと。

# 先に、数値丸めにあるある結論
Power Query で数値の四捨五入を特段の指定なく計算した結果はいわゆる **銀行型丸め**。なので、Excel ワークシート関数の [ROUND 関数](https://support.office.com/ja-jp/article/round-%E9%96%A2%E6%95%B0-c018c5d8-40fb-4053-90b1-b3e7f61a213c) などの"四捨五入"とは異なる。ちなみに、[ROUND function - DAX](https://docs.microsoft.com/en-us/dax/round-function-dax)もいわゆる算術型丸めで"四捨五入"。

```text:すべてTRUE
Number.Round( 1.4 ) = 1
Number.Round( 1.4, 0, RoundingMode.ToEven) = 1
Number.Round( 1.4, 0, RoundingMode.AwayFromZero) = 1

Number.Round( 1.5 ) = 2
Number.Round( 1.5, 0, RoundingMode.ToEven) = 2
Number.Round( 1.5, 0, RoundingMode.AwayFromZero) = 2

Number.Round( 2.4 ) = 2
Number.Round( 2.4, 0, RoundingMode.ToEven) = 2
Number.Round( 2.4, 0, RoundingMode.AwayFromZero) = 2

// チョットチガウ
Number.Round( 2.5 ) = 2
Number.Round( 2.5, 0, RoundingMode.ToEven) = 2 
Number.Round( 2.5, 0, RoundingMode.AwayFromZero) = 3
```

# Power Query の数値を丸める関数
丸めの種類はたくさんあるので便利ですよね。と、言ってもすべてを使いこなすイメージは持ち合わせていない。
## **Number.Round**

>**Number.Round**
>丸めた数値を返します。桁数と丸めモードを指定できます。
>RoundingMode.Type (丸めモード)
>*RoundingMode.Up*
>*RoundingMode.Down*
>*RoundingMode.AwayFromZero*
>*RoundingMode.TowardZero*
>*RoundingMode.ToEven*

中間の値(例えば、丸め桁数 0 で 0.5 とか 0.0)でどのように丸めるか。丸め方を選ぶことができるので必要な結果に合わせて選ぶ感じでしょう。
*RoundingMode.ToEven* が "最近接丸め(偶数)" で"銀行型丸め"
*RoundingMode.AwayFromZero* が "最近接丸め(0から遠い方へ)" いわゆる四捨五入
*RoundingMode.TowardZero* は 0に近い方へって感じでしょうか
*RoundingMode.Up* と *RoundingMode.Down* は "方向丸め"だけど切り捨て/切り上げとちょっと違う

## そのほか
>**Number.RoundAwayFromZero**
.正の数値の場合は切り上げた結果を返し、負の数値の場合は切り下げた結果を返します。桁数は指定できます。

>**Number.RoundDown**
.次に小さい数値を返します。桁数は指定できます。

>**Number.RoundTowardZero**
>正の数値の場合は切り下げた結果を返し、負の数値の場合は切り上げた結果を返します。桁数は指定できます。

>**Number.RoundUp**
>次に大きい数値を返します。桁数は指定できます。


```text:比較するテーブルを出力
let
    Source = List.Transform(
        {-10 .. 10},
        each
            [
                _Value = _ / 100,
                RoundAwayFromZero = Number.RoundAwayFromZero(_Value, 1),
                ModeAwayFromZero = Number.Round(_Value, 1, RoundingMode.AwayFromZero),
                RoundTowardZero = Number.RoundTowardZero(_Value, 1),
                ModeTowardZero = Number.Round(_Value, 1, RoundingMode.TowardZero),
                RoundDown = Number.RoundDown(_Value, 1),
                ModeDown = Number.Round(_Value, 1, RoundingMode.Down),
                RoundUp = Number.RoundUp(_Value, 1),
                ModeUp = Number.Round(_Value, 1, RoundingMode.Up),
                ModeToEven = Number.Round(_Value, 1, RoundingMode.ToEven)
            ]
        ),
    Custom1 = Table.FromRecords(Source)
in
    Custom1
```

# その他
- [Power BI 勉強会 - connpass](https://powerbi.connpass.com/)
- [Power BI Desktop を使い始めるには](http://qiita.com/PowerBIxyz/items/6c4735cb5b5712e70981)
- [Excel で Power Query を使い始めるには](http://qiita.com/PowerBIxyz/items/52e563037b855a099ca9)
「ブロックチェーンアプリケーション開発の教科書」を読んで

金融系IT系企業に務める身としてはブロックチェーン上で動くアプリケーションくらい作ってみたいと思い、ブロックチェーンを学ばなければと思い、[「ブロックチェーンアプリケーション開発の教科書」](https://www.amazon.co.jp/dp/B0794WJYGW/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)を読み始めたので、知識整理のため、投稿。

## ブロックチェーン概要
- サトシ・ナカモトが投稿したビットコインのデザインペーパーから生まれた技術
- 最初はビットコインを支える仕組みとして生まれたが、暗号通貨の枠を超えたP2Pアプリケーションを開発するための技術としても普及し始めた(※ 暗号通貨以外のシステムに使われているブロックチェーン技術をブロックチェーン2.0とも呼ばれるらしい)
- ブロックチェーンは分散管理を行う技術のため、システム参加者を限定したり、パフォーマンスが必要となるシステムには不向き。


## ビットコインプラットフォームのブロックチェーン技術の主な要素

### タイムスタンプ
- 管理者を必要としないアプリケーションを目指したため、イベントが発生した時刻を中央集権的に管理することができない。
- これに対する解として、「絶対時刻」ではなく「相対時刻」を扱うハッシュチェーンがある。

`ハッシュチェーン`

```

order1 → hash(order1)
↓
order2 → hash(order2)・hash(hash(order1))
↓
order3 → hash(order3)・hash(hash(order2))・hash(hash(hash(order1)))

```

イメージ的には上記だと思っている。
注文が入るたびに、その注文、以前の注文をハッシュ化していく。
この仕組みによって、order2がハッシュ化されているということはorder1がハッシュ化されていることだ、と再帰的に判定していくことができる。これにより出来事の順序をシステムで理解できる仕組み。

これでは分散アプリケーションで担保するべき以下の二つが担保できないかもしれない

- P2Pネットワークに参加しているノード全てが最新のタイムスタンプを参照できるか？
  - これができないとノードごとに見ている最新断面が異なってしまう。

- 過去データを改ざんされた場合に、それを検知、拒否できるのか
  - これができないと取引履歴の時系列改ざんやら、取引内容の改ざんやら、やりたい放題。

`ブロックチェーン`

上の二つの問題に対する解決策としてブロックチェーンで使われている仕組みは以下。

### マークルツリーによるブロックの概念
  - データを一つずつハッシュ化するのではなく、いくつかのデータを束ねてハッシュ化し、ブロックという単位で再帰的にハッシュ化していく。
  - 受け取ったデータを一個一個ハッシュ化していくより、効率的に送信元データと今ハッシュ化したデータが破損・改ざんされたことを検知できる。

### Proof of Work
 - 最新ブロック + トランザクションデータ + nonce(ワンタイムパスワード的なもの)をハッシュ化した値が規定された値以下になる様なnonceを見つけることができたノードのみが新しいブロックを作成できるという仕組み。
 - このブロックを作成することを「マイニング」という。ここで新しいブロックに取り込まれたトランザクションデータはブロックチェーン上で承認された取引となる。
 - これを全ノードが一斉に行う。で、このnonceを見つける難易度は平均的に10分程になる様に調整される。この10分というのが世界中の全ノードに最新断面のブロックが伝播するまでにかかると仮定されている時間だそうな。
 - でも必ず10分間隔で新しいブロックができる訳ではないので、ネットワーク環境のせいなどで同時に二つの最新ブロックが作成されたりした場合は、その後に続くブロックが長く続いたほうが採用される。ただ、採用されなかったブロックに含まれるトランザクションはブロックチェーン上で承認されていないので、またマイニングされて新しいブロックとして作成される。
 - 時間稼ぎと取引の承認を同時に行ってる仕組みかなと思う。すごい。

### UTXO
 - 通貨の送信ではデータ(お金)を自分の口座から削除し、相手の口座に追加する方式(残高記録方式)とデータ(お金)自体に所有者情報を記録しておき、その所有者を書き換えることによって送金を実現する方式(コイン識別方式)があり、ブロックチェーンではコイン識別方式をベースにしたUTXOという仕組みを導入している。
 - これはトランザクション管理を容易に行うための手段。
 - UTXOではデータ(お金)の所有者情報の書き換えを行う時に、公開鍵認証の文脈での送金したい相手の公開鍵で自分の送金したいデータ(お金)をロックする。そして送金相手がロックされたデータ(お金)を自分の秘密鍵で解除し、自分の所有者情報に書き換えることで自分のデータ(お金)にすることで実現する。
 - 自分の送金したいデータ(お金)のうちいくらかを手数料としてロックしたままにしておくと、マイニングに成功したノードが報酬として受け取れる。この手数料を多くしておくとマイニングするノードとしては魅力的なトランザクションとなるため、迅速に新しいブロックとしてブロックチェーン上で承認される。

## 終わりに
ブロックチェーンを理解する書籍として非常にわかりやすかった。
ここで記載した内容は、書籍のメインのブロックチェーン上で動作するアプリケーションを作る前提としてのブロックチェーンについて理解するための章の部分。
実際にブロックチェーン上で動作するアプリケーションを開発するとしたら、その分野に特化したイーサリアムのプラットフォームを使うのが良さそうだけど、一旦ブロックチェーンを理解するためにビットコインのブロックチェーンについて勉強してみたが、とても面白い。
業務アプリケーションを作る上で扱う技術とは違って新鮮な気持ちになった。
とりあえず何か作れる様になれるまでは勉強してみようと思う。
Macの画面を散らかさない5つの鉄則 【Mac生産性アップ-画面の使い方編-】

Macで生産性を上げる方法はいくつかありますが、今回は「画面の使い方」にフォーカスして記事を書いてみました。この5つすべてをやったところ、かなり画面移動のストレスが減りました。トラックパッドに手を移動しなくて良くなったのも大きいです。以下、順に説明します。


## 1. よく使うWebアプリはDesktopアプリ化する。
次に出てくる2.と3.を有効にするために、よく使うwebアプリはDesktopアプリ化しておくことをおすすめします。NativefierやFluidなどを使えば、Desktop版が提供されていないWebアプリをDesktopアプリ化出来ます。詳細は下記記事を参照してください。
自分はTask管理に使用しているAsanaやGoogleカレンダーなどをNativefierでDesktopアプリ化しています。

▼ References
- [MacでWebサービスをデスクトップアプリ化して利用する方法](https://blog.rokuzeudon.com/entry/mac-desktop-app-maker)
- [Nativefierでどんなウェブアプリも一撃Macアプリ化！ブラウザとアプリの用途を分けて仕事を効率化しよう](http://c16e.com/1511170923/)

## 2. アプリはDockから開かない
アプリはAlfredで開きましょう。(せめてSpotlightで。)
[option+space]でAlfredの検索画面を立ち上げ、立ち上げたいアプリorファイル名を入力で立ち上げるように癖付けると作業効率が大幅に上がります。
これを有効にするためにも、よく使うアプリは1.で説明したとおりDesktopアプリ化しておきましょう。

▼ References
- [開発におすすめの Alfred Workflows ○○選](https://qiita.com/DriftwoodJP/items/6bee03df0a0da499320a)

## 3. Desktopごとに役割を与え、[control+数字キー]で瞬間移動する。
これが一番大事です。Desktopを複数枚開き、作業しやすいように割当てます。
例えば今の自分の設定は次のような感じ。（空白は自由スペース）

- Desktop 1 : ブラウザ (Google Chrome)
- Desktop 2 : メインの作業場所
- Desktop 3 : iTerm2
- Desktop 4 : エディタ系
- Desktop 5 : 
- Desktop 6 : チャットアプリ
- Desktop 7 : メモアプリ (Simplenote)
- Desktop 8 : Todo管理アプリ (Asana) 
- Desktop 9 : スケジュール管理アプリ (Google Calender)
- Desktop10 : メールアプリ

ここで大事なのが各Desktop間を瞬間移動できるようにMission Controlで設定することです。
[control+数字キー]でデスクトップ間を瞬間移動できるように設定します。
詳細は下記記事に譲りますが、普段使うアプリは立ち上げ場所を設定しておくことで、どのDesktopから立ち上げても指定したデスクトップで開かれるため、画面が散らかりません。

※ TotalSpacesなどを使用している方もいるかも知れませんが、この方式ではテンキーを使用しないのでTotalSpacesのタイル状にDesktopを並べる機能は不要と判断し、僕は使っていません。

例えば、Desktop 1でブラウザで調べ物をしていたときに思い立ってメモを開きたくなった場合、
これまでの設定をしておれば
[control+space]→[メモのアプリ名を入力]
の操作だけでDesktop 7に自動で切り替わり、アプリが立ち上がっています。
再度ブラウザに戻りたければ
[control+1]
を押すだけです。

▼ References
- [macOSでディスプレイ1枚で作業する技術](https://qiita.com/saboyutaka/items/d6cfd2a2b60f1a374d60)


## 4. 再起動時に前開いていたアプリは再度開かない設定にする。立ち上げ時に開くアプリのみ個別に設定する。
常駐させたいアプリは個別にDockで「右クリック>オプション>ログイン時に開く」で設定しておきます。これと同時に再起動時に前開いていたアプリを開かないように設定しておきます。（再起動時に出てくるチェックマークを外すだけ）
すると、起動と同時に3.で設定した通りの配置で、設定しておいたアプリのみが立ち上がっている状態でスタート出来ます。

僕はGoogle Chrome, Simplenote, Asana, Google Calender, Airmailはログインと同時に開く設定にしているので、起動と同時に3.で設定した配置で各アプリが立ち上がります。
すぐに作業に取りかかれるので非常に快適です。

## 5. Dockに置くものは最小限にする。
基本中の基本でおまけみたいなものですが、Dockが散らかると目も散るのでDockに置くものは最小限にするようにしています。
Alfredでアプリを立ち上げるので普段は使いませんが、どうしてもDockを使わなければ行けない場合に最短時間で見つけられるように、Dockは整理しておくことをおすすめします。
シフトレフトサイン

# HIISU のテーマソング(非公式)

- 米津玄師 の「ピースサイン」の替え歌で「シフトレフトサイン」

- 2019/03/27 #HIISU のお知らせを受けて内容更新

- 元の曲は⇒https://youtu.be/1oMxrHXzOsY



### いつか僕らの上をスレスレに 通りすぎていった個人情報を
不思議なくらいに憶えてる 被害もないのになぜか

改ざんされて泣いた日の夜に ただ堅牢化したいと願ってた

そのために必要な技術を探し求めていた


#### 残酷な会見が定まっているとして
記者や経営層にガチで問い詰められるとして

#### ただ一瞬 この一瞬 説明責任を

果たせるならいいと思えた その心を

もう一度 札幌へ行け 沖縄へ行けと 僕の中の誰かが歌う

どうしようもないほど堅牢に

#### いつだって目を腫らした社長が二度と 悲しまないように笑える
そんなエンジニアになるための歌

さらば掲げろ シフトレフトサイン 転がしていくDevOpsを

### 「衛りたい」だなんて言えるほど チームが弱くはないの分かってた

それ以上にサーバが弱くてさ パッチ当ててなかったんだ

#### 「僕だって被害者だ」なんてさ 口をついて叫んだあの日から
変わっていく僕を笑えばいい ハッカーになりたい僕を

DNS いじられて pingも打てなくて
#### 騒ぐ顧客と サポートの関係が ぐしゃぐしゃになったって

ペッパーもアレクサも消えてしまうくらいに

#### 今は触っていたいんだ このエクスプロイトに

僕たちはきっといつか 遠く離れたCAにすら手が届いて

証明書を手に入れて笑おう

#### そうやって青く燃える鍵に染まり 暗号化通信の向こうへ
スリーウェイハンドシェイクしていけるはずだ

君と組織を衛り描く 捻りのないSREを

#### DDoSだらけ荒くれた日々が 削り削られ 擦り切れたサーバ
バックアップで蘇る 鮮やかにも 売り上げが立つ

#### TORのネットで眠る情報も やりかけのまま 止めた更新も もう一度 取り戻せ

もう一度 淡路へ行け 宮古へ行けと 僕の中の誰かが歌う

どうしようもないほど堅牢に

いつだって目を腫らしたエンジニアが二度と 悲しまないように笑える
#### そんな経営層になるための歌

さらば掲げろ シフトレフトサイン 儲かっていけ売り上げよ

#### 君と世界を衛り描く 捻りのないシフトレフト
laravel controller作成してみた

## artisan コマンドでControllerを作成する。

```
$ php artisan make:controller HogeController
```


自動生成されたHogeController

````HogeController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HogeController extends Controller
{
    //
}

```

### indexアクション追加

```HogeController.php
class HogeController extends Controller
{
    public function index()
    {
        return 'indexぺーじです';
    }
}
```

```web.php
Route::get('hoge', 'HogeController@index');
```

### http://127.0.0.1:8000/hoge
正常に表示された。
<img width="339" alt="スクリーンショット 2019-02-16 1.58.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/278474/d7704335-2b7c-d23f-601f-dd6644b1764f.png">


## パラメータ付きアクション

```HogeController.php

class HogeController extends Controller
{
    public function index($name)
    {
        return $name . 'さんこんにちは。indexぺーじです';
    }
}
```

```web.php
Route::get('hoge/{name}', 'HogeController@index');
```

### http://127.0.0.1:8000/hoge/aaaa
<img width="433" alt="スクリーンショット 2019-02-16 2.01.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/278474/8969315e-9f01-1a07-5fac-f2276062f604.png">


## シングルアクションコントローラー作成

```
$ php artisan make:controller SingleController
```

```SingleController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class SingleController extends Controller
{
    public function __invoke()
    {
        return 'シングルコントローラーです';
    }
}

```

```web.php
Route::get('single', 'SingleController');
```

### http://127.0.0.1:8000/single

<img width="294" alt="スクリーンショット 2019-02-16 2.06.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/278474/f8b5ec0e-89df-d988-ac44-d8e3412456e0.png">


## RequestとResponseを使う
preタグでrequest変数を囲むことで$requestの中身を見やすくしてる


```HogeController.php
use Illuminate\Http\Request;
use Illuminate\Http\Response;

class HogeController extends Controller
{
    public function index(Request $request, Response $response)
    {
        $response->setContent("<pre>$request</pre>");
        return $response;
    }
}
```

```web.php
Route::get('hoge', 'HogeController@index');
```

### http://127.0.0.1:8000/hoge
<img width="1016" alt="スクリーンショット 2019-02-16 2.13.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/278474/b796c6b0-4d15-899e-c0b9-95f40994e02f.png">
Windows 10 Pro x64 + Excel2016 x86 VBA で Seleniumbasic + chromedriver を使ってみる

#目的
pythonで試したコードを Excel VBA で書き直してみる
※TODO

```python
element = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.NAME, "q"))
)
```
上記のコードは driver.Until で書くのかな？？
ここをsleepで待つのだけは避けたい(Examples以下は全部見てない)
##インストール
[Seleniumbasic](https://florentbr.github.io/SeleniumBasic/)の Release page より SeleniumBasic-2.0.9.0.exe をDLする
exeを実行すると、C:\Users\user_name\AppData\Local\SeleniumBasic にインストールされる
[ChromeDriver - WebDriver for Chrome](https://sites.google.com/a/chromium.org/chromedriver/downloads) より使用中のChromeのバージョンに合わせてDLする
chromedriver_win32.zip を解凍後 chromedriver.exe は SeleniumBasic フォルダに上書きする
##Excel VBA で使用する
VBAのIDEの　tool -> 参照設定より C:\Users\user_name\AppData\Local\SeleniumBasic\Selenium32.tlb を追加する
##サンプルコード
操作する要素は最小限に切り詰めています
※Pythonのコードはどうなのかいな？

```vb
Sub ChromeDriver2()

    Dim driver As New ChromeDriver

    driver.Start
    driver.Get "http://www.google.com/xhtml"
    driver.FindElementByName("q").SendKeys ("ChromeDriver")

    Sleep 3000
    driver.Quit

End Sub

Sub ChromeDriver3()
'
    Dim driver  As New ChromeDriver
    Dim elm     As WebElement
'
    driver.Get "http://example.selenium.jp/reserveApp/"
'
    '年 を入力する
    Set elm = driver.FindElementByName("reserve_y")
    Debug.Print elm.Attribute("value")
    'textbox に入力する clear() -> send_keys()
    elm.Clear
    elm.SendKeys ("2020")
    Debug.Print elm.Attribute("value")
'
    ' radio button をクリックする
    Set elm = driver.FindElementById("breakfast_off")
    Debug.Print ("breakfast_off : " & IIf(elm.Attribute("checked"), "on", "off"))
    ' breakfast_off をクリック
    elm.Click
    Debug.Print ("clicked")
    Debug.Print ("breakfast_off : " & IIf(elm.Attribute("checked"), "on", "off"))

    ' checkbox をクリックする
    Set elm = driver.FindElementById("plan_b")
    Debug.Print "plan_b:" & IIf(elm.IsSelected, "on", "off")
    elm.Click
    Debug.Print ("clicked")
    Debug.Print "plan_b:" & IIf(elm.IsSelected, "on", "off")
'
    Sleep 1000
    driver.Quit
End Sub

Sub ChromeDriver4()
'
    Dim driver  As New ChromeDriver
    Dim elm     As WebElement
    Dim lst     As List
'
    driver.Get "http://192.168.5.48:8088/"
    ' 検索ワードの入力
    driver.FindElementById("contentQuery").SendKeys ("Postgres")
    
    ' 検索ボタンクリック
    driver.FindElementById("searchButton").Submit
    
    ' 検索結果を取得する
    Set lst = driver.FindElementsByClass("link")
    
    ' 検索結果を表示する
    For Each elm In lst
        Debug.Print elm.Attribute("href")
    Next
    Sleep 1000
    driver.Quit
End Sub
```