OmniAICreator/Qiita-1.07M huggingface dataset:
US配列ライクなJISキーボードにするカスタムキーコードを作った

初めまして、初投稿です

# US配列ライクなJISキーボードとは

自作キーボード作ってる人は **US配列** と **JIS配列** の違いは当然ご存じかと思います
OSに認識されるキーボードがUS配列かJIS配列かによって同じキーコードでも入力される文字は違いますよね
例えばこんな感じ

* JIS配列
  + `KC_2` -> `2`
  + `LSFT(KC_2)` -> `"`
* US配列
  + `KC_2` -> `2`
  + `LSFT(KC_2)` -> `@`

これのせいで「印字されてる文字と入力される文字が違うんだけど！」みたいなこともよくあるそうですね
まあ、OS側の設定でキーボードの言語を正しく設定すれば問題ないですが、使ってるPCで全部その設定するの面倒じゃないですか
それに、US配列で半角/全角切り替えするには ``Alt + ` `` 入力しないといけないし（そういうカスタムキーコード作れば解決しますがそれはそれで）

<font color="LightGray">あと、US配列の40%キーボードとかでリモート環境に入ると打てない文字とかあるし、勝手に設定も変えられないし、つらい……</font>


というわけで、 **JIS配列キーボードとして認識されるけど、物理的な配列はUS配列** というキーボードにしたいという意欲が高まったわけです

<font color="red">**なお、私は Windows 環境しか持っていないため、他の OS で正常に動くかは未検証です**</font>


# ソースコード

ソースコードは GitHub に公開しています

https://github.com/koktoh/jtu_custom_keycodes

# 定義されているキーコード

|キー|説明|
|:-:|:--|
|`JU_2`|`2` / Shift で `@`|
|`JU_6`|`6` / Shift で `^`|
|`JU_7`|`7` / Shift で `&`|
|`JU_8`|`8` / Shift で `*`|
|`JU_9`|`9` / Shift で `(`|
|`JU_0`|`0` / Shift で `)`|
|`JU_MINS`|`-` / Shift で `_`|
|`JU_EQL`|`=` / Shift で `+`|
|`JU_LBRC`|`[` / Shift で `{`|
|`JU_RBRC`|`]` / Shift で `}`|
|`JU_BSLS`|`\` / Shift で <code>&#124;</code>|
|`JU_SCLN`|`;` / Shift で `:`|
|`JU_QUOT`|`'` / Shift で `"`|
|`JU_GRV`|`` ` `` / Shift で `~`|
|`JU_CAPS`|英数の大文字/小文字切り替え|

# 使い方

ここでも簡単に説明しますが、詳しくは GitHub の README.md をお読みください

## 必要なもの

* rules.mk
* jtu_custom_keycodes.h
* jtu_custom_keycodes.c

これらのファイルを好きなディレクトリに配置してください（適用したいキーマップディレクトリの下とか）

## keymap.c の編集

まずはヘッダーファイルを include します

```cpp
#include "jtu_custom_keycodes.h"
```

カスタムキーコードが定義されている部分を、以下のように書き換えてください

#### before

```cpp
...

enum custom_keycodes {
  CUSTOM_KEY_CODE_A = SAFE_RANGE,
  CUSTOM_KEY_CODE_B,
  CUSTOM_KEY_CODE_C
};

...
```

#### after

```cpp
...

enum custom_keycodes {
  CUSTOM_KEY_CODE_A = JTU_SAFE_RANGE, // 変更
  CUSTOM_KEY_CODE_B,
  CUSTOM_KEY_CODE_C
};

...
```

最後に、 `process_record_user(...)` を書き換えます

```cpp
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  // 以下追加
  bool continue_process = process_record_user_jtu(keycode, record);
  if (continue_process == false) {
    return false;
  }
  // 追加ここまで

...
```

## キーマップ変更

あとは好きなようにキーマップをいじってください

## BLE Micro Pro について

[BLE Micro Pro 標準ファームウェア][bmp]用のものも用意しています

https://github.com/koktoh/jtu_custom_keycodes/tree/master/ble_micro_pro

# おわりに

これで、 **US配列ライクなJISキーボード** の完成です
また、実装面では [BLE Micro Pro 用 QMK Firmware][bmp_firm] の実装をかなり参考にさせていただきました

なお、 [QMK Firmware][qmk] についてはまだまだ素人同然なので、「こんな風にしたらもっと効率いいよ」とかあれば、じゃんじゃんプルリクや編集リクエスト送ってください

[qmk]: https://github.com/qmk/qmk_firmware
[bmp]: https://github.com/sekigon-gonnoc/BLE-Micro-Pro/tree/master/AboutDefaultFirmware
[bmp_firm]: https://github.com/sekigon-gonnoc/qmk_firmware/tree/nrf52
Go　makeとnewの違い

###makeとnewの違い

違いはポインタを返すかどうか

make → ポインタを返さない

new → ポインタを返す

```main.go
package main 

import(
	"fmt"
)

func main(){
	var p *int = new(int)
	fmt.Printf("%T\n", p) => *int

	s := make([]int, 0)
	fmt.Printf("%T\n", s) => []int
	
}
```
Herokuへのデプロイでエラー発生 ⇨ ExecJS::RuntimeError: SyntaxError: Unexpected token punc «;», expected punc «)»

##はじめに
- RailsチュートリアルでHerokuにデプロイする時にハマったエラー。  
- エラー発生箇所の特定に役立つ知識が得られた<br/><br/><br/><br/> 

ではエラー内容を見てみましょう。<br/><br/><br/>


##エラー内容 １
```terminal:コンソール
：
：
remote:  !
remote:  !     Precompiling assets failed.
remote:  !
remote:  !     Push rejected, failed to compile Ruby app.
：
：
```

「アセットのプリコンパイルが失敗してますよ〜」  
とのこと。  <br/><br/><br/>

またエラーを上から見ていくと、こんなことも書かれている


##エラー内容 ２
```terminal:コンソール
：
：
rake aborted!
ExecJS::RuntimeError: SyntaxError: Unexpected token punc «;», expected punc «)»
：
：
```

なるほど。どこかのJavascriptファイル内で構文エラーが発生しているらしい。  
でもどのファイルかは教えてくれてないのね（T T）   
じゃあ自分で調べて見ますか〜
<br/><br/><br/>



##エラー発生箇所の特定
```terminal:Railsコンソール

JS_PATH = "app/assets/javascripts/**/*.js";
Dir[JS_PATH].each do |file_name|
  puts "\n#{file_name}"
  puts Uglifier.compile(File.read(file_name), harmony: true)
end

```
Railsコンソールを立ち上げて上のコードを実行します。

あーら不思議。エラーが発生しているファイルが表示される（はず）  
あとは
➡︎ 特定したファイルを開く 
➡︎ エラー箇所を修正
➡︎  Herokuへ push!

私はこの方法でエラー解消しました。
仙台CTF 2019 Opw5.感染PC 100

#問題

http://ctf.sectanlab.jp/2019/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/74d7cc99-71cd-b54b-f5d6-af6e9fc33761.png)

#解いてみた

メールを受け取ったのがスズキさんとハチベさん。
スズキさんはメールを開いていない。

となるとハチベさんが正解ですね。
仙台CTF 2019 Opw4.不審URL 100

#問題

http://ctf.sectanlab.jp/2019/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/7a16641e-5e93-97ca-0b87-08c57f452cf3.png)

#解いてみた

さっきの答えのファイルを開いてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/c3802b6b-ce66-e933-e4ee-8a6d43465c18.png)

5行目の最初のほうにpowershellって書いてあって7行目にrunってあるのでpowershellで何かを実行するんでしょう。
通信先は5行目を解読すればよさそうです。
7行目をalertに変えてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/5690d571-4160-79ca-6d21-84cc8a6ba88b.png)

ダメでした。
javascriptではなくてjscriptだったか。

ちょっと調べてみます。

WSH(JScript) 外部入力関連 - バグ取りの日々
https://www.bugbugnow.net/2019/01/wsh-input.html

ここに載っている方法で書き換えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/7a5ed515-f9b1-0a2f-22db-623ddf36d50d.png)

これでできるはず。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/7547e5fe-4572-25bc-f673-ca5b1191d8ec.png)

ポップアップはできたけど、変数がそのまま出てる。。。
中身を別で計算する必要がありそうです。

とにかく見づらいので「;」単位で開業します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/d8191f4c-cd49-17f2-a6d5-7f94d8d778d5.png)

16行目でopenしているので文字列を完成させればそれが答えです。
RESTfulとは。。。

Ruby on Rails初心者です。
RESTfulという言葉をよく耳にするので自己理解も兼ねてまとめたいと思います。

# RESTfulとは
RESTの規約に従った、Webサービスのこと。
このRESTは以下のような特徴を持っています。

**◉アドレス可能性**
リソースをURIとして一意に指し示すことができる

**◉ステートレス性**
一つ一つのリクエストに処理に必要な情報を全て含める性質（自己完結型）

**◉統一インターフェース**
URIで指し示したリソースに対する操作を、GETやPOSTといった8つメソッドに絞り込み、限定的なインターフェースを行う

**◉接続性**
リソースをリンクで接続し、一つの情報に他のリンクの情報なども含めることができること

# RESTfulにすることのメリット
○　URIの部分などで、美しくわかりやすいインターフェースを表現できる
○　他の開発者が設計を理解しやすくなる
○　いちいちURLやHTTPメソッドを考えないで済む
○　サーバがクライアントの情報を共有しないことにより、スケーラビリティが向上する。
  （サーバがクライアントの情報を記憶するようにしてしまうと（ステートフル）、クライアントが増えていった際にサーバを増加させる必要がありますが、その際にクライアントの情報をサーバ間で同期する必要があり、オーバヘッドが発生してしまいます。）

# まとめ
RESTfulな設計をしていくことで、わかりやすいWebアプリケーションをつくることができるようになる（と感じました)
Glitchが全く動作しない時または誤作動でコード変えても反応しないときの対処法

#対処方法
1. Terminalを開く

コマンドライン

```javascript
  $ killall node
```
を実行する。
2. しばらくたってそれ以上動かなかったら、
`package.json` の一部の空白一文字消す。
3. しばらくたつと動く。
M5StickV on Mac

MacOS MojaveでM5StickVを使うメモ

- [Switch science製品ページ](https://www.switch-science.com/catalog/5700/)
- [公式のQuickStart](https://docs.m5stack.com/#/en/quick_start/m5stickv/m5stickv_quick_start?id=m5stickv-quick-start)

## ファームウェア更新
### ファームウェアのダウンロード
公式QuickStartに従って `M5StickV_Firmware_v5.1.2.kfpkg` をダウンロード

### ファームウェアのflash
QuickStartからダウンロードできるKflash_GUIはMojave(10.14.6)では起動しなかったので、CLIのkflash.pyで書き込んだ

```
$ pip3 install kflash
$ kflash -B goE -p /dev/cu.usbserial-<FOOBAR> -b 1500000 ~/Downloads/M5StickV_Firmware_v5.1.2.kfpkg
```
pやBは自動検出してくれるようなので指定しなくても動くかも

<追記> [githubの方のkflash_gui](https://github.com/sipeed/kflash_gui)
は起動できた

```
$ git clone  --recursive https://github.com/sipeed/kflash_gui.git
$ cd kflash_gui
$ pip3 install -r requirements.txt
$ python3 kflash_gui.py
```

## シリアル接続

1. M5StickVをMacに接続
2. cuやscreenでシリアル接続 ex. `$ sudo cu -l /dev/cu.usbserial-FOOBAR -s 115200`
3. M5StickVのMaixpyにつながる
4. `[MAIXPY]: find ov7740` のメッセージでコンソール出力が止まる (boot.pyが動き出す？) 
5. ここでctrl+cするとboot.pyが止まってpythonのインタプリタで色々できる
6. Quickstartに従ってhello world表示したりとか

カレントディレクトリは `/flash` でファイルが4つあった

```
>>> import os
>>> os.getcwd()
'/flash'
>>> os.listdir()
['ding.wav', 'startup.jpg', 'freq.conf', 'boot.py']
```

- startup.jpg: 起動時に表示されるVっていう画像
- ding.wav: 起動時に鳴るベルの音
- boot.py: デフォルトで入ってる顔認識のコード?
- freq.conf: よくわからない

このコンソール上でもテキストエディタでコードを編集できる。けど辛そう、、


## 挙動

- 自分でboot.pyファイルを書いて既存のものと置き換えればいいらしい
- 機械学習のモデルもsdカードやflashに書き込んでおけば読み込めるらしい
- MicroSDにboot.py入れて起動するとそっちを動かしてくれるらしい

## ファイルの書き込み

[uPyLoader](https://github.com/BetaRavener/uPyLoader)でMac-M5StickV間でファイルをやりとりできる

1. Githubから0.1.3のreleaseバイナリをダウンロードして起動
2. Connectionのプルダウンから対応するポートを選択
3. M5StickVのディスプレイ横のボタンを押しながらuPyLoaderの `connect` をクリック
4. M5StickVが再起動、うまいくとuPyLoaderのステータスがconnectedになる
5. uPyLoaderのツールバー File > NavigateでMac側のディレクトリを移動
6. デバイスとMac相互にファイルをやりとりできる

Macのbluetoothが有効になってるとGUIが立ち上がらないことがあった。謎

デフォルトで入ってるboot.pyを取り出して見てみると参考になる
起動音が大きめなので書き込みのテストがてら `player.volume(100)` を10にして上書きしてみたらちゃんと静かになった。素敵

## boot.py以外のpythonファイルの実行

公式Quickstartによると以下の2つの方法で自動起動時にboot.py以外のファイルも実行できる

- boot.pyからimportで呼ぶ or
- execでファイルごと実行する

```
with open("hello.py") as f:
    exec(f.read())
```


## 学習モデルのロード
デバイスから持ってきたデフォルトのboot.pyを読むと

```
task = kpu.load(0x300000) # Load Model File from Flash
...
kpu.init_yolo2(task, 0.5, 0.3, 5, anchor)
```
となってて、yoloのモデルファイルをFlashから読み込んでるみたい
このアドレスはどうやって知るんだろう？
SDに入れてる場合は `kpu.load("/sd/xxx.kmodel")` とパス指定でいけるらしい
https://maixpy.sipeed.com/en/libs/Maix/kpu.html


## Todo
- MicroSD
   - 相性問題があるらしい
   - 自前のkmodelはsdカードに入れて動かしてる人が多い模様
- API勉強する
- 自前のkmodel作って入れてみる
- V-Training試す

## References

参考になりそうなサイトがたくさん
https://github.com/elloza/awesome-k210

TipsとQ&Aが参考になる
http://community.m5stack.com/topic/1226/m5stickv-link-info-dump
仙台CTF 2019 Opw3.不審添付ファイル 100

#問題

http://ctf.sectanlab.jp/2019/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/12c8713a-742b-f8a0-b070-0d6a86263049.png)

#解いてみた

スズキさんのPCを見てみます。
thunderbirdの受信メールを見ます。

```
\sendaictf2019day2\Opw\PC05\PC05\Users\user05\AppData\Roaming\Thunderbird\Profiles\oob69yqk.default-release\Mail\mail.sendaictf.invalid\Inbox
```

これを開くと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/6b596ffb-467b-7cfa-a71b-5a6a40c43fe5.png)

こんな感じのメールになってまして、下のほうに添付ファイルがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/798cf47f-863f-33eb-1d59-d109df753196.png)

48行目を見るとbase64でエンコードしていることがわかったので、52行目から67行目までコピーしてCyberchefに入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/432dff06-1232-35a4-f29e-86e7df0925f1.png)

ファイルとして保存します。
PKから始まるのでzipファイルです。
zipファイルを解凍して中に入っているファイル名が答え。
LTE→5Gはブレークスルーにはならない〜ドコモ6Gコンセプトに見る5Gの弱点〜

2020/1/22にNTTドコモが6Gの技術コンセプトを出しました。実は、このコンセプトの裏返しが「プロが考える5Gの弱点」になっています。皮肉ながら、5Gの弱点を整理する意味で、とても秀逸なコンセプトあり、解説します。

[（お知らせ）ドコモ、6Gに向けた技術コンセプト（ホワイトペーパー）公開](https://www.nttdocomo.co.jp/info/news_release/2020/01/22_00.html)

#1. <6G>コンセプトの各項目へのコメント

##1.1. 超高速大容量通信

ここは、5Gの量的な拡張であるため、特筆すべきところはありません。

##1.2. 超カバレッジ拡張

###1.2.1. どこでもGbpsレベルのサービス提供、エリアカバー率100%

逆にいえば、5Gはエリアカバレッジに課題があるということです。これは、私の記事での主要論点の１つであり、追認されました。

###1.2.2. 新たなサービスエリア（空、海、宇宙、・・）

本領域は5Gとは大きな関連はありませんが、日本ではソフトバンク社が強くアピール[^1]している分野であり、現時点から数年後までのフロンティアです。ドコモとしてもキャッチアップを図る意思だと考えます。10年後で良いのでしょうか・・？

[^1]: [ソフトバンク、OneWebの低軌道衛星通信サービス提供に向けて事業展開を推進](https://www.softbank.jp/corp/news/press/sbkk/2019/20190723_01/)

##1.3. 超低消費電力・低コスト化

###1.3.1. 充電不要な超低消費電力端末

逆にいえば、5Gは低消費電力化が難しいということです。私の記事ではカバーされていない話題ですが、関連記事がありました[^2]。

[^2]: [5Gスマホ、電力を消耗しやすい理由は？](https://spc.jst.go.jp/news/190201/topic_4_02.html)

###1.3.2. 低価格ミリ波デバイス

逆にいえば、ミリ波デバイスは高い、ということです。私の一連の記事では、カバレッジを理由にミリ波の普及はかなり厳しいと論じていますが、細かいデバイスコストまでは言及していませんでした。

##1.4. 超低遅延

###1.4.1. E2Eでの超低遅延<1ms

逆にいえば、5Gは無線網内区間だけ超低遅延なのであり、クライアント〜サーバーのエンドツーエンドの遅延には課題が残る、ということになります。これは、私の記事での主要論点の１つであり、追認されました。

私の記事では、さらに、アプリケーション含めたエンドツーエンドの遅延にも言及していますが、そこまで対応するのは6Gでも無理なのですね。

###1.4.2. 常時超低遅延

逆にいえば、5Gの無線網区間超低遅延というのも、保証値ではない、ということです。私の記事ではカバーされていない話題です。

##1.5. 超高信頼通信

逆にいえば、5Gでは、製造ラインの制御とか、自動運転（の制御）とかに使うのは、無理であるこということになります。私の記事でも言及しています。

##1.6. 超多接続&センシング

###1.6.1. 超多数AIデバイス > 1000万デバイス/1平方km

ここは、5Gの量的な拡張であるため、特筆すべきところはありません。AIに文脈上の意味はありません。

###1.6.2. 超高精度位置情報サービス < 誤差10cm

逆にいえば、5Gの位置情報は誤差数10cmである、ということです。この分野もソフトバンクは現時点で訴求しています[^3]が、10年後でよいのでしょうか？

[^3]: [ソフトバンク、誤差数cmの測位サービスを11月末に開始](https://k-tai.watch.impress.co.jp/docs/news/1188068.html)

#2. まとめ

まとめると、今回の6G技術コンセプトは、以下で構成されていました。

+ 私の記事の追認
+ 私の記事でもカバーできていない5Gの弱点の明確化
+ 5Gの単純な量的拡張
+ 5Gの範疇ではないが、他社がすでに別手段で実現していることを6Gの中で再発明したいとドコモが考えるもの

狙いと異なる使い方をして申し訳ありませんが、ドコモの技術者は5Gの限界を深く理解しており、高い技術力を持っていると思いました。
Vue.js computedとmethodの違い

この記事は初心者向け Vue.jsでcomputedとmethodsの違いについて記述した自分用メモになります。
誤っている点がありましたらご指摘をお願いいたします。

この記事は以下の方向けの記事となっております。

推定読者：
・computedとmethodのそれぞれの使い方は分かるが、２つの違いが分からない人
・どんな時にどちらを使えばいいのか分からない人

##computedとmethodの違い
computedとmethodの違いは「キャッシュされるかどうか」です。
computedはキャッシュされ、methodはキャッシュされません。つまり、computedとmethodsは実行されるタイミングが異なります。

computedは参照先の値が変わった時のみ実行され、methodsはテンプレートの中身が再描画される度に実行されます。
この違いがどのような差をうむのかを以下に記述します。

##キャッシュされるcomputedとキャッシュされないmethodsの違い
以下、全く同じ値を返すcomputedとmethodです。

```
    <button @click="counter += 1">カウンター</button>
    <button @click="otherCounter += 1">他のカウンター</button>
    <p>{{ otherCounter }}</p>
    <p>{{ counterMethod() }}</p>
    <p>{{ counterComputed }}</p>

 <script>
new Vue({
   el: '#app',
   data: {
     counter: 0,
     otherCounter: 0
   },
   methods: {
     counterMethod() {
          console.log('methodが実行されました')
          return this.counter > 2 ? '2より大きい': '2より小さい' 
      }
   },
   computed: {
     counterComputed() {
          console.log('computedが実行されました')
          return this.counter > 2 ? '2より大きい': '2より小さい'
      }
   }
 })
</script>  
```

![zerokai.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355738/0f8d3f1e-0d24-9037-0501-3a91171b1048.png)

上記のコードはカウンターボタンが押された時、counterの値が１足され、足された値に対してmethodとcomputedがそれぞれ2より大きい値かどうかを返すという内容になっております。
また、cmethodとcomputedが実行されるタイミングが分かるようconsole.logで実行タイミングを見れるようにしています。


では、カウンターボタンを3回クリックしてみましょう。

実行結果
![3click.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355738/7f83a3e1-1d70-7eb9-8b5f-50627e831de1.png)

赤枠で囲ったconsole.log結果に注目してください。
methodとcomputedの両方が実行されていることが分かります。


では、次に他のカウンターボタンを３回クリックしてみましょう。
実行結果
![otherclick.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355738/b2f84e22-5632-cafd-b6fc-74bdd5f02b09.png)

赤枠で囲ったconsole.log結果に注目してください。
methodだけが実行されていることが分かります。

以上の結果から、
・methodは全く関係ない要素の変化であってもテンプレートが再描画される度に実行
・computedは関係する要素（参照している要素）が変化した場合のみ実行
上記２点のタイミング差による違いがわかりました。


##参照したサイトさま
この記事を書くにあたり参照したサイト様、記事一覧です。

[りんごとバナナとエンジニア/【Vue.js】computedとmethodsの違い](https://udomomo.hatenablog.com/entry/2017/12/11/213904)

udemy教材
[超Vue JS 2 入門 完全パック - もう他の教材は買わなくてOK！ (Vue Router, Vuex含む)](https://www.udemy.com/course/vue-js-complete-guide/)
仙台CTF 2019 Opw2.不審メール受信者 100

#問題

http://ctf.sectanlab.jp/2019/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/21ed819f-32c5-7902-3578-08ef34d4daf7.png)

#解いてみた

さっきのオープンワールドのほかのところをクリックするみたいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/952f4719-0e5d-90da-e57e-955ce7202501.png)

ウイルスをくらったスズキさんと同じ営業所のハチベさんとカクノさんが怪しいのでクリックしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/6080a2a7-d232-8a96-5937-1b4f30b55894.png)

なるほど、1問目に添付されていたzipファイルの中身を見ていくわけですね。
見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/be3d7094-c34f-c725-fc4f-000eccc4e69c.png)

UsersとWindowsフォルダがありました。
さっきの問題のメールアドレスでgrepすると6件ヒットしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/06537aff-c4d2-65ae-c727-f96f1f058c7a.png)


Thunderbirdの中のメールなので、答えっぽいです。
カクノさんも同様にgrepしてみましたが、ヒットしませんでした。
ということで答えは一人でした。
URLSearchParamsで配列の検索パラメータを取り扱う

# `URLSearchParams`とは？

`URLSearchParams`は、検索条件を指定する際に使用されるURL`?`以降の文字列を取り扱う際に、様々な便利機能を提供してくれるAPIです。

```ts
const params = new URLSearchParams('?type=test&status=done');
console.log(Object.fromEntries(params));
// => {type: "test", status: "done"}
```

# 検索パラメータとして配列を指定したい場合はどうするのか

`?type=test&statuses=process&statuses=done`の`statuses`のように同じkeyに複数の値を含めて、OR検索を行いたい場合があると思います。
この場合は以下のようにパラメータを取得すると良いでしょう。

```ts
// ステータスは配列で取得したい
const isArrayField = (key: string) => key === 'statuses';
const params = new URLSearchParams('?type=test&statuses=process&statuses=done');
const keys = Array.from(new Set(searchParams.keys()));

let q: { type?: string, statuses?: string[] } = {}
for (const key of keys) {
  const values = params.getAll(key);
  if (values.length <= 0) {
    continue;
  }

  q = {
    ...q,
    [key]: isArrayKey(key) ? values : values[0]
  };
}

console.log(q);
// => {type: "test", statuses: ["process", "done"]}
```

`searchParams.keys()`は上記の例の場合`["type", "statuses", "statuses"]`となっているので、`Set`を使って重複を弾いたあと、`Array.from`で再び配列に戻しています。
(コンパイルオプションの`--downlevelIteration`フラグを`true`に設定すれば、配列に戻す必要はありません)

`getAll`関数は`statuses`に設定されている値の全てが配列で返してくれるので、配列で取得したいフィールドの場合は配列をそのまま格納すればOKです。

ちなみに、`get`関数もありますが、この関数は最初の1個目の値をstring型で返します。

```ts
console.log(params.get('statuses'));
// => "process"
```
仙台CTF 2019 Opw1.状況確認 100

#問題

http://ctf.sectanlab.jp/2019/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/6d937556-70fb-f99d-cdba-a9bfe317a429.png)

#解いてみた

久しぶりのCTFです。
新しい仙台CTFがあったのでやってみます。

オープンワールドにアクセスしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/a51e8e30-5a2f-e2c5-7a0b-d037a368f6d7.png)

右下あたりに鈴木さんがいたのでクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/28565faf-1af7-bcad-261c-104383d67f11.png)

そのまま答えですね。
画像なのでコピペできないのがちょっとつらい。
【備忘録】MacBookProのHDDをSSDに交換してみた。

##はじめに
MacBookProのHDDをSSDに換装する方法を記載します。
※尚、今回はあくまでSSDに交換するのみで、OSのインストール以降は行いません。
OSインストールから先は各自で行って頂けると幸いです。

##参考
以下のサイトを参考にしました。
『旧型MacBook ProをSSDで高速化、HDD時とは別物の快適さに - AKIBA PC Hotline!』
https://akiba-pc.watch.impress.co.jp/docs/column/noteextend/707303.html

『MacBook PRO 2011 SSD 換装手順(MC724J/A) HDD→SSD化手順 | Macガレージ』
https://satoshisgarage.tech/?p=268

##用意するもの
**SSD**
今回は、CrucialのSSD 500GBを用意しました。
https://www.amazon.co.jp/dp/B077PPN5NN/ref=cm_sw_r_tw_dp_U_x_kIdkEbXQ7APYT 
ノートPCには大抵、2.5インチのHDDが載っているので、2.5インチのSSDを用意します。

**精密ドライバー**
MacBook Proのフタにとまっているネジを外すために使用します。
今回使う、+00のドライバーを単体購入するのも良いと思いますが、
ドライバーセットを購入すると、他の用途でも使えるのでオススメです。

**トルクスドライバー**
MacBookProのHDDについているトルクスネジを外すために使用します。
形状が似ているからといって、ネジとあっていないトルクスドライバーを使うと、
ネジ山を潰してしまう事になりますので、十分注意してください。

##換装前のスペック
**MacBook Pro**
**13-inch, Early 2011**
プロセッサ: **2.3GHz Intel Core i5**
メモリ: **4GB 1333MHz DDR3**
グラフィックス: **Intel HD Graphics 3000 384MB**
ソフトウェア: **Mac OS X Lion 10.7.5**
ストレージ: **HDD 320GBシリアルATA、5,400rpm**

今回はストレージのみの交換になるので、メモリ等の他のパーツに変更はありません。

##手順
**1.ネジを外し、フタを外す**
10箇所のネジを+00ドライバーを使って外していきます。
ヒンジ近くの3箇所のネジは、他の7箇所と長さが異なるので、位置を覚えておきましょう。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519347/d007643c-00f7-a7d2-2de0-621e74149988.jpeg" width=75%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519347/b22601b9-e9f8-4f91-e286-efe1a71892e9.jpeg" width=75%>

**2.HDDの取り外し**
HDDを固定している部品のネジを、+ドライバーで外し、固定している部品を外します。
HDDについているSATAケーブルを外します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519347/f179084a-cf4c-6c3e-9ca2-31d04e4244ab.jpeg" width=75%>

**3.ネジの付け替え**
HDDについていたネジを、換装するSSDに取り付けます。これを怠ると、SSDが固定出来なくなるので、確実に行いましょう。
ネジを外す時は、トルクスドライバーのT6を使用します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519347/ff611d0e-0c83-bd8c-d232-d8a3139610a3.jpeg" width=75%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519347/8c6b8e47-cd3d-5170-6648-7fd18a8119e5.jpeg" width=75%>

**4.SSDの取り付け**
ネジの付け替えが終わったら、いよいよSSDの取り付けです。
SSDにMacBookProから生えているSATAケーブルをつけ、向きに注意しながら取り付けます。
SSDを固定する部品をつけ忘れないように気を付けましょう。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519347/b026a736-65df-fd70-bbce-d330d43300d8.jpeg" width=75%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519347/b7c315b0-33d0-226b-5aeb-6b691b23f643.jpeg" width=75%>

**5.フタをし、ネジをしめる**
取り付けが完了しましたら、フタをしめ、ネジをしめて完成です。

##まとめ
今回は、MacBookProのHDDをSSDに交換してみました。
メモリ交換に比べると、ドライバーを2種類使う等、少し難易度上がるかなという印象です。
ただ、HDDをSSDに変える事で、OSの起動は早くなりますし、
ドライバーの種類を間違えなければ、簡単に出来るので、試してみる価値はあると思います。
起動が遅いなと思う、HDD内蔵のMacBookProお使いの方は、ぜひ試してみてください。
Qiita始めました

#Qiita始めました
ひょんなことからIT業界に足を踏み入れた19卒新米エンジニアです。大学の研究でロボットを作っていたので割と低レイヤーにも興味があったりします。

#目的
今のところ主にアウトプットによる知識定着と思考整理が目的。
今までは気づいたこととか、調べてもなかなか出てこなかったことをtwitterに掃き溜めてましたが、Qiitaは便利なことに記事の編集や削除も出来るということで利用しない手はないと思いました。

編集も出来ることだしこのページを原点回帰用にメンテしていこうかな。

#参考

[Qiitaを始めるための背中を押してくれた記事](https://yuta-yamamoto.hatenablog.com/entry/2018/12/17/225249)
FirebaseのRemoteConfig使ってみた

#はじめに
最近になってFirebaseのRemoteConfigを使う機会があったので、
このサイトに残しておこうかと思います。
ほぼ、ドキュメント通りなので、
気になる方だけ読んでいただければと思います。
#RemoteConfigとは
アプリをアップデートすることなく、アプリの動作や外観を変更できる機能になります。
行なっている事としてはRemote Config Serverから設定されているパラメーターを取得して、
その値によって動作や外観を変更します。
[RemoteConfigとは](https://firebase.google.com/docs/remote-config?hl=ja)

#環境
Xcode 11.3
swift 5
Firebase 6.15.0
#FireBaseのインストール
インストール手順は省きます。
以下、公式ドキュメント
[Firebase を iOS プロジェクトに追加する](https://firebase.google.com/docs/ios/setup?hl=ja)
#RemoteConfig設定
[Remote Config ドキュメント](https://firebase.google.com/docs/remote-config/use-config-ios?hl=ja)

``` swift
remoteConfig = RemoteConfig.remoteConfig()
let settings = RemoteConfigSettings()
settings.minimumFetchInterval = 0
remoteConfig.configSettings = settings
```
ドキュメントにあるようにシングルトンオブジェクトを作成し、通信を抑えるために同期する間隔を設定します。。。。が、早速ハマりました、、、、

``` swift
settings.minimumFetchInterval = 0
```
フェッチ間隔を上記のように設定しても反映されいっぽい、、、（なぜ？）
一応、設定の優先度は以下のようです。

1. fetch(long) のパラメータ
2. FIRRemoteConfigSettings.MinimumFetchInterval のパラメータ
3. デフォルト値（12 時間）

別にfetch(long)のパラメータに設定してないんだけどなぁ〜
仕方ないのでfetch(long)のパラメータで設定すると、今度はうまく反映されるようになりました。

``` swift
var expirationDuration = 0.0

    func fetch() {
        self.remoteConfig.fetch(withExpirationDuration: self.expirationDuration) {
    (status, error) in {}
    }
```

ってことで続き

#デフォルト値の設定
``` swift
struct TestRemoteConfig: Codable {
    var isTest: Bool
}

class RemoteConfigTest {
    var defaultValue: NSObject {
        let encoder = JSONEncoder()
        encoder.keyEncodingStrategy = .convertToSnakeCase
        let value = try? encoder.encode(TestRemoteConfig(isTest: true))
        return value as NSObject? ?? "" as NSObject
    }
    
    func setDefault() {
        remoteConfig.setDefaults(["test_remote_config": self.defaultValue])
    }
}
```
デフォルト値を設定しておくことで、
RemoteConfigがバックエンドから値を取得していない場合や、
値が無い場合でも正常にアプリを動作させることができます。

デフォルト値はplistファイルから取得できますが、今回はNSDictionaryオブジェクトを作成してます。
#パラメータの設定
FireBaseコンソール画面でパラメーターを設定します。
Json形式の方が扱いやすと思うので今回はJson形式で設定。

![スクリーンショット 2020-01-22 21.02.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322831/6767ab97-6122-353a-7bd3-5e04d8b8da2d.png)
#値のフェッチと有効化
```swift
remoteCongig.fetch(withExpirationDuration: self.expirationDuration) { (status, error) in 
    if let error = error {
    	// error処理
     }

     if case .success = status {
         // 有効化
         self.remoteConfig.activate { (error) in
             if let error = error {
             // error処理
             }
         }
     }
}
```
#パラメータの取得
``` swift
remoteConfig.configValue(forKey: "test_remote_config").dataValue
```
上記のメソッドでfetchされた値を取得できます。

``` swift
    func configValue() throws -> TestRemoteConfig {
        let data = self.remoteConfig.configValue(forKey: "test_remote_config").dataValue
        let decoder = JSONDecoder()
        decoder.keyDecodingStrategy = .convertFromSnakeCase
        return try decoder.decode(TestRemoteConfig.self, from: data)
    }
```
Json形式で定義していたので、デコードすれば"isTest"の値を自由に使えるようになります。
以上がRemote Configになります。

この機能を用いてA/Bテストも実施できるので是非やってみましょう！！
SciPy KDTree vs 総当たりベンチマーク

#はじめに
k次元のユークリッド空間に点を空間分割で分類し、k次元領域の
点探索を効率的におこなうのがk-DTreeです。
SciPyにこんなのがあるとは知らなったので、どれくらい効率がいいか？
ベンチマークを行ってみたいと思います。
以降、2次元は2-D, 3次元は3-Dという風にk次元について
k-Dと表記します。


#比較条件
データ件数 100000件
検索回数 10000回
2-Dから8-Dデータまで行います。
各次元について4回ずつ探索を行います。
leafsizeは10固定。


#環境
Anaconda
Python 3.7.6
scipy.version.full_version 1.3.2
windows10

#プログラム

```:kdtbench.py
def search(S, pt):
	# 距離を求める
	distary = ss.distance.cdist([pt], S, metric='euclidean')
	# 最小のインデックスを求める
	idx = distary.argmin()
	return (distary[0, idx], idx)

def	benchmark(x, s, kdt, no, i):
	# k-DTree 探索
	kdstart = time.time()
	for search_cond in s:
		dist, hitindex = kdtree.query(search_cond)
	kd_elapsed_time = time.time() - kdstart
	print('%d:%d-D K-DTree(秒)  %.2f' % (i, no, kd_elapsed_time))

	# 総あたり 探索
	brstart = time.time()
	for search_cond in s:
		dist, hitindex = search(x, search_cond)
	br_elapsed_time = time.time() - brstart
	print('%d:%d-D 総当たり(秒) %.2f' % (i, no, br_elapsed_time))
	return	kd_elapsed_time, br_elapsed_time


count_data = 100000
count_key = 10000
numturns = 4

np.random.seed(0)

for n in range(2,9):	#2-D...8-D
	X = np.random.rand(count_data, n) * 1000.0
	S = np.random.rand(count_key, n) * 1000.0
	kdtree = ss.KDTree(X, leafsize=10)

	total_k = 0
	total_a = 0
	for i in range(0,numturns):
		ktm, atm = benchmark(X,S, kdtree, n, i)
		total_k += ktm
		total_a += atm

	print('Avg k-DTree:%.2f秒 総当たり:%.2f秒' % (total_k/numturns, total_a/numturns))
	print()
```


#ベンチマーク実施
プログラムを実行。

```
$ python kdtbench.py
0:2-D K-DTree(秒)  2.00
0:2-D 総当たり(秒) 6.61
1:2-D K-DTree(秒)  1.99
1:2-D 総当たり(秒) 6.62
2:2-D K-DTree(秒)  2.02
2:2-D 総当たり(秒) 6.78
3:2-D K-DTree(秒)  2.01
3:2-D 総当たり(秒) 7.33
Avg KDTree:2.00秒 総当たり:6.83秒

0:3-D K-DTree(秒)  2.71
0:3-D 総当たり(秒) 7.81

～～～　省略 ～～～

```


#ベンチマーク結果

条件ごとの測定結果の平均時間(秒)が下記です。

|   |総当たり(秒)|K-DTree(秒)  |
|:-:|:-:|:-:|
|2-D|        6.83|         2.00| 
|3-D|        7.65|         2.67| 
|4-D|        8.18|         4.17| 
|5-D|        9.29|         7.13| 
|6-D|       10.97|        12.67| 
|7-D|       11.51|        20.41| 
|8-D|       13.30|        46.03|

各PC事に性能が異なるため時間うんぬんは意味が無く、比較で見て下さい。


測定値をグラフ化
![graph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391380/1743069d-14bf-3db9-e128-73113920957a.png)

K-DTree searchがK-DTreeによる探索処理の結果を示し、
Brute force searchが総当たり探索処理の結果です。

5-D以降、性能が逆転することがわかりましたが、ここまで使うかは
今のところ分かりません。自分の場合は使ってもせいぜい3-Dくらいまで、
たぶんpythonではこういう使い方はしないかな。
ご清聴ありがとうございました。


#参考
[SciPy.org](https://www.scipy.org/)
[kd木 - Wikipedia](https://www.google.com/search?client=firefox-b-d&q=k-DTree)
【Python】 Hartreeからボルツマン分布を計算するプログラム

#イントロダクション
Gaussianの最適化計算の結果を入れて、存在比を計算するプログラムがよく必要になります。そのたびに作るがなくしてしまうし、単位変換とかめんどくさい。
解説ないです。間違いがあったら指摘してくれると嬉しいです。
#作った

```Python:dist.py

import numpy as np


def boltz(E_list, temp=298.15):
    """
    Gaussian Energy to Boltzmann distribution
    ---------------------------
    input
    E_list: Hartee numpy array
    temp: (K)
    ---------------------------
    output
    Distribution numpy array
    Normalized so that the sum is 10
    """
    E_list = E_list - np.amin(E_list)
    kb = 1.38064852e-23  # J/K
    h2J = 4.3597482e-18  # Hartree / J
    beta = 1 / (kb * temp)  # 1/J
    dist = np.exp(-beta * E_list * h2J)
    return dist / np.sum(dist) * 10


def main():
    E_list = np.array([-600.818043678, -600.817622812, -600.817222895])
    dist = boltz(E_list)
    print(dist)


if __name__ == "__main__":
    main()


```
boltzが今回作った関数
Hartreeをいれて、存在比(和が10になるように規格化)が帰ってくる。

#参考
[HPCシステムズ・計算科学ソリューションズ ](https://www.hpc.co.jp/chem/software/gaussian/help/keywords/constants/)
HartreeからJへの変換するときの値を参考にさせていただきました。accessed at 2020/01/22
01/22 学習内容

LP構築は、元サイトを忠実に内容を再現することが重要。
余白も再現する。
再現するために、手本のサイトのcssをまんまコピーして問題ない。

隣接セレクタ
親要素が同じで、隣接しているclassのみ適用させたい内容がある場合、
クラス名 + クラス名という形で記述する。

間接セレクタ
要素同士を結合子 [~] で結ぶことで、ある要素と同じ親要素に属する後続に出現する要素に対してスタイルを設定することができます
クラス名 ~ クラス名


直下セレクタ
ある要素の直下にあるcssのみ設定する。
クラス名 ~ クラス名、要素

https://webllica.com/css-combinators/
jQueryのメソッド

# jQueryとこの記事について


- 『jQuery』とは、効果やアニメーションを簡単に実装できるJavaScriptライブラリ。

- 　jQueryを使うとWEBページにアニメーションや効果を簡単につけることができる。

- 　jQueryを勉強中（ど素人）なのですが、復習も兼ねて学んだメソッドを
　下記にメモとして記述していこうと思います。随時更新していきます。


## hide

- セレクタ（HTMLのタグ名やclass名,idなどを指定する）で指定した要素を隠すことができる。

　例：　**$('h1').hide();**




## show
- セレクタで指定した隠れている要素を表示することができる。

　例：　**$('h1').show(slow);**



## fadeOut
- セレクタで指定した要素を徐々に隠すことができる。
- アニメーションの速度は（）内に引数として指定することができる。（1.0秒 → １０００、slowなど）

　例：　**$('.class').fadeOut(1000);**



## fadeIn
- セレクタで指定した要素を徐々に表示ことができる。

　例：　**$('.class').fadeIn(slow);**


## slideUp
- セレクタで指定した要素を下から上にスライドしながら隠すことができる。

　例：　**$('#id').slideUp(1000);**



## slideDown
- セレクタで指定した要素を上から下にスライドしながら表示することができる。

　例：　**$('#id').slideUp(slow);**


## css
- セレクタで指定したCSSを変更することができる。引数①にプロパティ、引数②にプロパティの値を設定する。

　例：　**$('p').css('color','blue');**

　※ちなみに、
　　　 **$('img').css('display','none');** ⇦　hideメソッドと同じ
　　　 **$('img').css('display','block');** ⇦　showメソッドと同じ

## text
- セレクタで指定した要素のHTMLの中身を引数で指定した内容に書き換えることができる。

　例：　**$('p').text('アイウエオ');**


## html
- セレクタで指定した要素の中身のHTMLを引数で指定したものに書き換えることができる。

　例：　**$('p').html('<span>アイウエオ</span>');**
  

## find
- セレクタで指定した要素の子孫要素から、引数で指定した要素を全て取得することができる。

　例：　**$('.class').find('p');**

　　この場合、'.class'というクラス内の'p'要素を取得することができる。

## children
- セレクタで指定した要素の子要素（１階層分）から、引数で指定した要素を取得することができる。

　例：　**$('.class').children('p');**


## addClass
- セレクタで指定した要素に引数で指定したクラスを追加することができる。

　例：　**$('.class1').addClass('.class2');**


## removeClass
- セレクタで指定した要素から引数で指定したクラスを取り除くことができる。

　例：　**$('.class1').removeClass('class2');**



## hasClass
- セレクタで指定した要素が引数で指定したクラスを持っているか判定することができる。

　例：　**$('.class1').hasClass('class2');**

 　・if文の条件式として設定することができる
　
　　　if($('.class1').hasClass('class2'))
　　　{
　　　　　// 処理内容
　　　}


## eq
- セレクタで指定したオブジェクトから引数で指定した数値と同じインデックス番号をもつ要素を取得することができる。

　例：　**$('li').eq(2).css('color','red');**


## index
- セレクタで指定したオブジェクトにおいて、引数で指定した要素が存在するインデックス番号を取得することができる。

　例：　**＄('li').index(＄('active'));**

## prev
- セレクタで指定したオブジェクトの同じ階層の１つ前の要素を取得することができる。

　例：　**$('#id').prev().css('color','red');**


## next
- セレクタで指定したオブジェクトの同じ階層の１つ次の要素を取得することができる。

　例：　**$('#id').next().css('color','blue');**




## attr
- セレクタで指定した要素に引数で指定した属性名・属性値を設定することができる。
- また、第２引数を指定しなかった場合、第１引数で指定した属性名の値を取得することができる。

　例：　**$('h1').attr('id','title');**

　　 　　**var url = $('a').attr('href');**

## val
- セレクタで指定した要素のvalue値を取得することができる。

　例：　**var text = $('#input').val();**




## animate
- セレクタで指定した要素に対して、引数１で指定したプロパティの値を設定することができる。
- また、引数２でアニメーションの速度を指定することができる。

　例：　**$('h1').animate({'font-size':'20px'},1000)**


## scrollTop
- リンク先への移動にアニメーションを付けることができる。

　例１：　**$('html,body').scrollTop(0);  ⇦　ページのTopに移動**

　例２：　**$('html,body').animate({'scrollTop':0},500);**
　　　　→　animateメソッドでプロパティにscrollTopを設定する方法でも可能


## offset
- セレクタで指定した要素の表示位置を取得することができる。

　例：　$('h1').offset().top; →　ページ最上部からの距離
イベントレポート（AWS re:Invent 2019 re:cap for Startups）

参加してきたAWSイベントの概要を纏めます。

・アジェンダ
https://awsreinvent2019recapforstartup.splashthat.com/

## ML
遅刻で聞けず

## コンテナ
遅刻で聞けず

## Serverless

### Lambda

* LambdaからRDSへの接続数問題
RDS Proxy with AWS Lambda（プレビュー中）
データベースの接続プールの役割
パスワードなどの秘匿情報はSecretManager経由でLambdaに理解させる

* スパイキーなアクセス（Lambdaのコールドスタートがネックになりやすい）
Provisioned Concurrency for Lambda Functions
事前ウォームアップが可能に。
今まではJava ランタイムロードに数秒やENI作成に10秒などかかることがあった。

* Lambda Supports Amazon SQS FIFO
順序性をアプリ側で気にしなくてよくなった

* Kinesis Datastream、DynamoDBイベントの並列化
今までシャードとLambda関数の実行数は１対１だったが１対Ｎの設定が可能になった

### API Gateway

* HTTP APIs for Amazon API Gateway
HTTPSのエンドポイントとして利用。
REST API以外でも利用可能。シンプルに利用できて安くて速い。


### Amplify

* Amplifyとは
本質的な作業に注力
モバイルアプリを最速でリリースするための仕組み
AWSの理解が浅くてもシステム構築を可能にする

* Amplify CLI
AWSに詳しくなくてもBuildingBlockを構築することができる
下記のコマンドで対話形式でシステム構築可能
amplify add api
amplify push

* Amplify Framework
ファイルアップロードにおけるセキュリティ対策などの機能を考えることなく実装可能

* Amplify Console
フロントエンドのCI/CD環境が瞬時に構築できる

* まとめ
Amplify CLIで作成した機能をAmplify Frameworkで呼び出したりできる

* Amplify Datastoreとは
デバイス側（iOS/Android）のストレージエンジン
GraphQLのスキーマを簡単に

* Amplify DataStore - Conflict Detection
コンフリクト解決手段も提供

## Big Data系
### Athena
* Federated Query
Lambda経由でクエリを投げることができる
データソースがAWSサービス（RedShift）などの場合はサーバレスアプリケーションリポジトリにAWSが用意したLambdaのコネクターが利用可能

* ユーザ定義関数(UDF)をサポート

* 機械学習モデルの呼び出しに対応

### RedShift

* 第３世代Redshift 
コンピュートとストレージの課金体系が分離した。
ストレージは利用分課金（S3のような）に変わった。
2倍の性能が同じ価格で利用可能になった。

* AQUA（Advanced Query Accelerator）
追加コストなしに10倍の速度を実現。プレビュー中。

### ElasticsearchService
* UltraWarm
例えば直近1か月のデータをHotDataとする
Hotノード：SSD
Warmノード：HDD

UltraWarmはWarmノードのストレージにS3が利用される。コスト、スケール、耐久性を実現

## その他のサービスアップデート
### SSO関連
* IDソースとしてSAML対応の外部IDプロバイダをサポート
AD以外でも利用可能

* SCIMを使ったIDの同期機能をサポート
ユーザの2重管理を無くして、おおもとのIDプロバイダだけの管理をすればよくなった。

* AWS CLI v2がAWSSSOでの認証をサポート（ベータ版）
ログイン
aws2 sso login --profile ～

### Wavelength
現状利用不可。AWSのロードマップを知っておく

* リージョンまでの通信で大きな通信遅延が課題
通信先を近くのAGに指定できる
[Rust] 識別子に日本語を使う

Rust では ASCII 以外の文字を含む識別子が 2020-01-22 現在 nightly で利用可能です. CJK 圏からの要望がないと永遠に安定化されない気がするので, みなさんこの機能を使ってフィードバックしてあげてください.

__2021-06-22 追記__ この機能は2021年6月17日にリリースされた Rust 1.53 で安定化されました. stable 版でも `#![feature(non_ascii_idents)]` なしで日本語識別子を使えます.

# 本論

現時点でこの機能を有効化するには `#![feature(non_ascii_idents)]` というアトリビュートをコードの冒頭で設定します. 例えば:

```rust:main.rs
#![feature(non_ascii_idents)]

fn main() {
    let あ = 'あ';
    println!("{}", あ);
}
```

そして nightly でコンパイルします: `cargo +nightly build` など.

## 識別子について

unicode 識別子は [Unicode Consortium 側で想定されていて](http://www.unicode.org/reports/tr31/), Rust では識別子としては次の 2 パターンが許されます (RFC または unstable book 参照).

* 最初の文字が [XID_start](http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B%3AXID_Start%3A%5D&abb=on&g=&i=) で, それ以降 [XID_continue](http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B%3AXID_Continue%3A%5D&abb=on&g=&i=) が続くもの.
* 最初の文字がアンダースコア `_` で, それ以降 [XID_continue](http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B%3AXID_Continue%3A%5D&abb=on&g=&i=) が 1 文字以上続くもの.

残念ながら絵文字は使えません. 日本語では句読点 `、`, `。` や括弧 `「`, `」` などは禁じられています. リンクを踏むと使用可能なコードポイントの一覧が見れます. また, 同一の見た目になるが複数の utf-8 表現が可能な識別子 ([合成済み文字](https://ja.wikipedia.org/wiki/%E5%90%88%E6%88%90%E6%B8%88%E3%81%BF%E6%96%87%E5%AD%97)を含む場合など) は同一の識別子として取り扱われます.

# 議論

何に使うんだ, と思われるかもしれませんが, 例えば円周率を `π` に束縛したりとギリシャ文字を使うのが自然な変数にギリシャ文字を使えたり, 適切な識別子を英語で捻り出す (そしてわかりづらい識別子になり可読性が落ちる) 手間が省けたりと, 少し考えただけでもメリットがいろいろと思い付きます. もちろんデメリットもいろいろありますが. このあたりのことは既に詳しく論じている方がいるので, そちらをご覧ください.

* [日本語識別子の必要性](https://www.slideshare.net/potimarimo/ss-12314191) (slideshare)
* [[コーディングスタイル]識別子を日本語に切り替えていく](https://qiita.com/mrdagon/items/2904a60ca43ceb18ad5d) (Qiita)
* [プログラム日本語で書けばいい気がするけど](https://anond.hatelabo.jp/20170421230333) (hateblo)
* [識別子に日本語を使うことについての考察](https://qiita.com/arai-ta/items/08d0fdb275ff0fcf68a6) (Qiita)


# 参考文献

* [RFC 2457-non-ascii-idents](https://github.com/rust-lang/rfcs/blob/master/text/2457-non-ascii-idents.md)
* [Tracking issue for RFC 2457, "Allow non-ASCII identifiers" #55467](https://github.com/rust-lang/rust/issues/55467)
* [non_ascii_idents - The Rust Unstable Book](https://doc.rust-lang.org/unstable-book/language-features/non-ascii-idents.html)
MacOS Catalina(10.15.2) で、旧OSからアップデートした環境でpython pipがOpenSSLのエラーになる問題の解決法

# TL;DR
`/Library/Developer/CommandLineTools` を `CommandLineTools.bak` とかに `mv` して、 `xcode-select --install` する。

# なぜそうするのか

Catalinaにupgradeする前から入れてあったCommandLineToolsがどうも古いのに新しいものと誤認識されているらしい。
なので `xcode-select --install` しても `already installed` って言われてしまう。
それを強制的に入れ直すため。

# いろいろ修正方法が書いてあるけどどれも関係なかった

以下は無関係だった。

* brewを入れ直す
* OpenSSLをbrewで入れ直す
* MacOS10.14.pkgを入れる → そもそもファイルが無いのでできない。

# 問題のエラー文字列

```
$ pip install --upgrade pip
pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not avai
lable.")': /simple/pip/
Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not avai
lable.")': /simple/pip/
Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not avai
lable.")': /simple/pip/
Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not avai
lable.")': /simple/pip/
Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not avai
lable.")': /simple/pip/
Could not fetch URL https://pypi.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with ur
l: /simple/pip/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.")) - skipping
Requirement already up-to-date: pip in /usr/local/lib/python3.7/site-packages (18.1)
pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
Could not fetch URL https://pypi.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with ur
l: /simple/pip/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.")) - skipping
```

# brewが悪いのか、MacOSが悪いのか…。

もうCloud Shell(GCP)上でやったほうが楽そう。泣ける。
初心者によるプログラミング学習ログ 217日目

#100日チャレンジの217日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

217日目は

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>217日目<br>・Vue.js<br>・Css設計<br><br>教科書的なインプット重視学習した<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1219712811246342146?ref_src=twsrc%5Etfw">January 21, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
最小のニューラルネットワークからバックプロパゲーションを理解する

# はじめに
CourseraでDeepLearningSpecializationを始めたのでアウトプットがてらに覚えておきたいことをメモしていきたいと思います。今回はシグモイド関数を使ったニューロンからバックプロパゲーションを書きます。MachineLearningの時よりも丁寧に解説されていました。

# シグモイド関数について
ロジスティック関数とは、特定の実数を受け取り0から1の値を返す関数です。以下のように定義されます。
$$g(z) = \frac{1}{1 + e^{-z}}$$
グラフは以下になります。グリッド線を表示させるのを忘れていましたが、$z=0$の地点で0.5を示すことがわかります。
![plot_sigmoid.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315055/fd6b1d4b-4bef-eae2-b43a-e98720d2a941.gif)

## フォワードプロパゲーション
入力値にサンプルデータである$x_1$、$x_2$とそれらの重みである$w_1$、$w_2$、さらにバイアス項の$b$を受け取って予測値$a$と実測値$y$とのコストを求めます。計算の工程は以下のようになります。
![LogisticFunction.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315055/7f275f8a-35ca-2a56-545b-bdcec788fee9.png)

また、それぞれの丸が表す式は以下のようになります。左から右に計算を進めていくためフォワードプロパゲーションと呼びます。
- $z = w_1x_1 + w_2x_2 + b$
- $a = g(z) = \frac{1}{1 + e^{-z}}$
- $L(a, y) = -(ylog(a) + (1-y)log(1-a))$

# コスト関数の最小化
予測値$a$と実測値$y$の誤差を最小とするために関数の傾きを利用してコスト関数の最小化を行います。この辺は[こちら](https://qiita.com/sssssssiiiiinnn/items/15e8a80ab61786565534)に書きました。バックプロパゲーションで行っているのもこれと同じことです。傾きを出すまでの工程がやや長いため複雑になっています。

# バックプロパゲーション
傾きを出すために微分を使います。
$L(a, y)$は合成関数であるため、$w_1$で微分するには右側から徐々に変化量を見ていく必要があります。これを式で表すと以下のようになります。
$$\frac{\partial L(a, y)}{\partial w_1} = \frac{\partial L(a, y)}{\partial a}\frac{\partial a}{\partial z}\frac{\partial z}{\partial w_1}$$

ここでは教師データは一つとしてバックプロパゲーションをすすめていきます。

## ステップ①
対数関数の微分公式は
$$\frac{d}{dx}log(x) = \frac{1}{x}$$
なので

```math
\begin{eqnarray}
L(a, y) &=& -(ylog(a) + (1-y)log(1-a)) \\
\frac{\partial L(a, y)}{\partial a} &=& -\frac{y}{a} + \frac{1-y}{1-a} \\
\end{eqnarray}
```
となります。
つまり$a$が、無限小分ずれるとL(a, y)は$-\frac{y}{a} + \frac{1-y}{1-a}$だけずれることになります。



## ステップ②
逆数の微分公式は
$$ \frac{\partial}{\partial x}\frac{1}{f} = \frac{-f'}{f^2} $$
なので、

```math
\begin{eqnarray}
a &=& \frac{1}{1 + e^{-z}} = g(z) \\
\frac{\partial a}{\partial z} &=& \frac{-(1+e^{-z})'}{(1+e^{-z})^2} \\
&=& \frac{e^{-z}}{(1+e^{-z})^2} \\
&=& \frac{1}{1+e^{-z}}\frac{e^{-z}}{1+e^{-z}} \\
&=&  \frac{1}{1+e^{-z}}(\frac{1+e^{-z}}{1+e^{-z}} - \frac{1}{1+e^{-z}}) \\
&=& a(1-a)
\end{eqnarray}
```

となり、

```math
\begin{eqnarray}
\frac{\partial L(a, y)}{\partial a}\frac{\partial a}{\partial z} &=& (-\frac{y}{a} + \frac{1-y}{1-a})(a(1-a)) \\
&=& a-y
\end{eqnarray}
```
となります。

## ステップ③
$$z = w_1x_1 + w_2x_2 + b $$
$$\frac{\partial}{\partial w_1}z = x_1$$
なので

```math
\begin{eqnarray}
\frac{\partial L(a, y)}{\partial a}\frac{\partial a}{\partial z}\frac{\partial z}{\partial w_1} = (a-y)x_1
\end{eqnarray}
```
となります。
同様の方法で以下も求められます。

```math
\begin{eqnarray}
\frac{\partial L(a, y)}{\partial a}\frac{\partial a}{\partial z}\frac{\partial z}{\partial w_2} = (a-y)x_2
\end{eqnarray}
```
```math
\begin{eqnarray}
\frac{\partial L(a, y)}{\partial a}\frac{\partial a}{\partial z}\frac{\partial z}{\partial b} = a-y
\end{eqnarray}
```

値が求められたら求めた値を使ってパラメータ$w_1$、$w_2$を更新していけばOKです。

# おまけ
サンプル数が増えた場合、コスト関数$J$は以下のようになります。
$$ J(w, b) = \frac{1}{m}\sum_{i=1}^{m}L(a^{(i)}, y^{(i)})$$
また、$J$を$w_1$で微分した値は以下で表せます。
$$\frac{\partial}{\partial w_1}J(w, b) = \frac{1}{m}\sum^m_{i=1}\frac{\partial}{\partial w_1}L(a^{(i)}, y^{(i)})$$
よく使いそうなPHPでのデータベースへのアクセス

# 引用
ドットインストール PHPデータベース入門
自分用にメモしてます。

# DBのセットアップ

```sql:最初のセットアップ
mysql -u root
create database new_db;
grant all on new_db.* to admin@localhost identified by 'password';
use dotinstall_db;

create table users (
  id int not null auto_increment primary key,
  name varchar(255),
  score int
);

mysql -u admin -p password
```

# PDOのセットアップ

DBの基本情報を定数で定義

```php
define('DB_DATABASE', 'new_db');
define('DB_USERNAME', 'dbuser');
define('DB_PASSWORD', 'password');
define('PDO_DSN', 'mysql:host=localhost;dbname=' . DB_DATABASE);
```

PDOは基本的にtryとcatchで記述
エラーが出た時にはExceptionを発生させるため、setAttributeというメソッドで設定する。
**PHPで定義済みのクラスを書くときは先頭に「\」を付ける習慣をつける。(※)**
※名前空間を使っている場合、PHPに標準で用意されているException()やDateTime()のようなクラスに関しては一番上の名前空間から呼び出さなければならない。

```php
try {
  // connect
  $db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
  $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (\PDOException $e) {
  echo $e->getMessage();
  exit;
}
```

# exec()

- 引数に与えられたSQL文を実行する。
- 返り値は更新・削除された行数を返す。作用しなかった場合は0を返す。
- **SELECT文からは結果を返さない**

```php
  // insert
  $db->exec("insert into users (name, score) values ('yamada', 28)");
  echo "success!";

  // disconnect
  $db = null;
```

# prepare() execute()
prepare()

- 複数回実行されるSQL、安全対策が必要なSQL文に適している。
- DBが正常に文を準備する場合は、PDOStatementオブジェクトを返す。もしDBが文を準備できなかった場合はFALSEかPDOExceptionを発行する(エラー処理の方法に依存)

execute()

- 配列型でパラメータを渡す。
- **何も指定しない場合は文字列で渡される。数値を渡したい場合はbindvalue,bindparam
型を指定する必要がある。**

```php
  $stmt = $db->prepare("insert into users (name, score) values (?, ?)");
  $stmt->execute(['taguchi', 44]);
  echo "inserted: " . $db->lastInsertId();
```

# 名前つきパラメータ

扱うカラムが多くなってきたときに整理しやすくなる。

```php
  $stmt = $db->prepare("insert into users (name, score) values (:name, :score)");
  $stmt->execute([':name'=>'hoge', ':score'=>80]);
  echo "inserted: " . $db->lastInsertId();
```

# bindvalue()

- 第一引数:パラメータid(1から始まる)
- 第二引数:バインドする値
- 第三引数:データの型
    - 文字列:PDO::PARAM_STR
    - 数値は:PDO::PARAM_INT
- これを使うとループなどで一部の値だけ違うレコードを一気に挿入できる。
- 名前付きパラメータの場合にも適用できる。

```php
  $name = 'yamada';
  $stmt->bindValue(1, $name, PDO::PARAM_STR);
  // $stmt->bindValue(':name', $name, PDO::PARAM_STR);
  $score = 35;
  $stmt->bindValue(2, $score, PDO::PARAM_INT);
  $stmt->execute();
  $score = 29;
  $stmt->bindValue(2, $score, PDO::PARAM_INT);
  $stmt->execute();
```

# bindParam()

- bindvalueは値をバインド、bindParamは変数への参照をバインド
- 実際に変数を参照するのはexecute()時。

```php
  $stmt->bindParam(2, $score, PDO::PARAM_INT);
  $score = 52;
  $stmt->execute();
  $score = 44;
  $stmt->execute();
  $score = 6;
  $stmt->execute();
```

# query() fetchAll() rowCount()
query()

- 何回も実行されないSQLに適する。
- 返り値はPDOStatementオブジェクトを返す。失敗した場合はFALSEを返す。
fetchAll()

- 引数に返り値の形式を指定できる。

rowCount()

- 取得したレコードの数を取得

```php
  // select all
  $stmt = $db->query("select * from users");
  $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
  foreach ($users as $user) {
    var_dump($user);
  }
  echo $stmt->rowCount() . " records found.";
```

# transaction

複数の処理により整合性を保つ必要がある場合に必要。

```php
try {
  // transaction
  $db->beginTransaction();
  //処理1
  //処理2
  $db->commit();

} catch (\PDOException $e) {
  $db->rollback();
  echo $e->getMessage();
  exit;
}
```
ビジネスで欠損値を扱うときの注意点（システム、機械学習予測モデル）

#欠損値の意味合いは色々ある
このタイトルを見ると、「機械学習　欠損値」で検索すると出てきそうな、欠損値の補完の仕方をイメージすると思いますが、情報がありふれているため、ここでは言及しません。ここで言及したいのは、機械学習の予測モデルに入れるデータの欠損値をどう処理するかというテクニカルなことではなく、データが欠損している意味合いが異なる場合に機械学習モデル自身を見直す、モデルを使ったビジネス上の運用も慎重に考える必要があるということです。

##欠損と未知は違う
いわゆる[欠損値の種類](https://techblog.gmo-ap.jp/2019/12/17/machine-learning-missing/)といったときに、MCAR, MAR, MNARがありますが、これはデータを取得しようと試みた結果様々な理由でデータが欠損しているときの欠損の仕方の違いです。これには「データを取得しようとした」という前提があり、データを選択するバイアスになっています。一方そもそもデータの取得の試み自体まだ行っていない場合はデータを取得しようとした結果の「欠損」ではなく、「未知」なのです。

##「欠損」と「未知」がなぜ重要か
ここまで見ると、当たり前じゃないかと思うでしょう。ただ、データ分析したり、データに関連した意思決定をしたりする際、データベースやシステムから出力されたデータを使いますが、意識して「欠損」と「未知」を区別しない限り、データの持ち方上欠損値になってしまっていることがおおいにあります。

例えば、ECサイトの会員ごとに再購買するか否かを予測する[2値分類](https://www.slideshare.net/tdev1/243-69787300)のタスクを行う予測モデルを作って、レコメンドに活用したいとします。そして、直近あるアンケートを順次会員に対して実施しており、週ごとに会員群を決めてアンケートを配信し、回答を得ます。アンケートの回答内容は各会員の嗜好や行動属性に関する情報があり、レコメンドのモデルを作成する人はその情報を活用してモデルの精度改善に生かそうとします。この時に、データベース上のアンケート結果が欠損ないし未知の違いを意識して設計されず、それを知らずにアンケート結果を用いて予測モデルを作成すると、おおいに実運用時で精度が悪化する可能性が高いです。
なぜなら、アンケートを取った会員群でアンケート結果が欠損している場合、そこには会員の何かしらの意図があり、回答しない結果欠損となっている一方、アンケートをまだ配信していない会員群のデータは、意図がなく単純に未知なので、これを欠損と同じように扱うと予測を誤るからです。

ECサイトに愛着があって利用する会員ならアンケートを丁寧に回答して、欠損値は少ないので、欠損値があると再購買しない方向に機械学習モデルは学習するでしょう。一方このモデルを、単純にアンケートに未回答ゆえに未知な会員に適用すると、本来アンケートが配信されていれば丁寧に回答するリピーターも欠損値の影響で予測モデルによって再購買しないと判定されてしまうのです。

##どう対処すべきか
以上を踏まえて、欠損と未知の違いを意識しつつ、要件に応じて対応を変える必要があります。

- 欠損と未知が混在した情報でもビジネスに活用したい
このような場合は、下記のような対応が考えられるでしょう。
 - システム設計時に、データが未知である事と、欠損している事を明示的に分けて定義する
 - システム側で対応が困難な時には、データの前処理で欠損と未知の違いを欠損値補完の方法を変える、ないし欠損している予測対象群と未知である予測対象群で分けて予測モデルを作成し運用に使う

- 上記以外の場合
無理して欠損と未知が混在した情報を使用する必然性がなければ、以下のようにすればよいでしょう。
 - そもそも情報として使わない
 - 欠損と未知の違いがなくなるまで待つ（前述の例でいえば、全会員のアンケート取得が終わるまで待つ）


#まとめ
ここまで、実際にモデルも作って、「欠損」と「未知」が混在した状況があった時に、全て一様に欠損値として扱った予測モデルを適用するリスクと取りうる対応案を提示しました。言われれば当たり前ですが、概念としての違いがデータベースの設計時には思い及ばなかったり、データとしてだけ渡された場合に、おおいに誤るリスクをはらんでいるため、記事にしました。また、機械学習モデルのみならず、データに欠損が関連し、それによるビジネス判断が必要な場合でも参考になる考え方ではないかと思います。
ご意見、フィードバック等あればぜひお願いいたします。
Q15.別のブックのセルを参照するには？

今回は別のエクセルファイルから値を参照していく方法を考えていきます。
以前は別のシートから値を参照する方法を扱いました。
それの少し応用したバージョンです。

![Q15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560479/7da24fdb-9c5d-0f52-319d-cb4243a87108.png)


このようにデータ.xlsxとマクロテスト.xlsmというファイルを用意しました。
マクロテストが読み込みを行うファイルで、データ.xlsxが読み込むデータが記載して
あるファイルとなります。


データ.xlsxの中身は以下のようになっています。

![Q15-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560479/47408f40-198c-013e-956e-dc520645fad0.png)


これを読み込んでマクロテストの中にある全体シートに追記していくには？というのを
考えていきましょう。
マクロテストの全体シートはこんな感じです。

![Q15-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560479/5c4198ce-ef68-9c93-c09a-1011b208e012.png)


ちょうどB16セルが開いているので16行目にデータを反映させたいですね。



###■ポイント
別のブックからセルを参照する場合、すでに開いているのと何も開いていないのでは
処理がことなります。
すでに開いている場合はそのまま
Range("B16").Value = Workbooks("データ.xlsx").Worksheets(1).Range("B3").Value
のように記述することができますが、この場合は対象となるブックが開いていない場合、
読み込めなくてエラーとなってしまいます。

例えば、開いているかいないかというのを前もって確認してそれに
合わせて処理を記述する方法などありますが、今回はシンプルに
もともと開いていない場合を想定して、
対象のブックを開く　→　特定のセルの値を参照する
という流れでマクロを作っていきましょう。


ブックを開くのは簡単です。
Workbooks.Open Filename:="絶対パス"
となります。ディレクトリによってはファイル名だけでも開くことができますので、
状況によって使い分けていきましょう。


###■回答
```VB
Sub Q15_Answer()
    Dim wb As Workbook
    Set wb = ThisWorkbook
    Dim ws As Worksheet
    Set ws = wb.Worksheets("全体")
    
    Workbooks.Open FileName:=("C:\Users\user\Desktop\work\VBAマクロ\データ.xlsx")
    ws.Range("B16").Value = Workbooks("データ.xlsx").Worksheets(1).Range("B3").Value
    ws.Range("C16").Value = Workbooks("データ.xlsx").Worksheets(1).Range("C3").Value
    ws.Range("D16").Value = Workbooks("データ.xlsx").Worksheets(1).Range("D3").Value
    ws.Range("E16").Value = Workbooks("データ.xlsx").Worksheets(1).Range("E3").Value
    
    ws.Activate
    
    Set wb = Nothing
    Set ws = Nothing
    
End Sub

``` 

###■解説
まず、 ワークブックとワークシートを格納する変数を宣言し、読み込み先である
全体シートを代入しています。
これは、シートを参照する記述をするときに短く見やすくする為です。
読み込み元も同様に変数に入れるとさらに見やすくなります。

次に Workbooks.Open FileName:=("C:\Users\user\Desktop\work\VBAマクロ\データ.xlsx")
で、読み込み対象となるブックを開いています。
パスは適宜、環境に合わせて変更してください。

ちなみに、すでに対象のブックを開いている状態で、この開く処理が実行されたと
してもエラーで止まるということはありません。そのまま後続の処理が流れます。


あとは、直接、対象のセルを参照するだけです。
最後のws.Activateは、データを代入したあとはデータ側のセルがアクティブになってしまうからです。
この1文を入れることで、最終的に全体シートをアクティブにしています。


実行結果はこのとおりです。無事にコピーできました。

![Q15-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560479/d44f51d6-f2a2-e7f3-c669-9a2984c3cdc9.png)
SteamVRがショートカットから起動しない場合の対処法

#SteamVRが起動中のため起動できない
PCを起動したばかりなのに，SteamVRが起動している扱いになって，ショートカットから起動できない場合があります

いくつかのPCで確認しています
原因究明はできていませんが，対象法がわかったので共有します

- SteamVRのprehabが入ったunityのSceneを起動する
- 何かしらのVRアプリケーションを実行する

すると，SteamVRが起動し，いつものWindowが表示されます

自分のPCでも発生していたのですが，なぜか通常通りに動作してしまうので，写真・詳細追加は後ほど