OmniAICreator/Qiita-1.07M huggingface dataset:
WPF/C# で表示中の画像を A4 用紙いっぱいに印刷する

WPF/C# でアプリケーション内に表示している画像を A4 用紙いっぱいに配置して印刷する方法です。
印刷方法については、[こちらの記事](https://qiita.com/tricogimmick/items/133e9b6bcbcaa6c07d63) を参考にさせていただいてます。

# 事前準備
WPF アプリケーションのプロジェクトに「System.Printing」と「ReachFramework」の参照を追加します。

# 表示中の画像の印刷
WPF アプリケーションで System.Windows.Controls.Image クラスを使って画像を表示している場合、この ImageSource プロパティを渡すだけで表示中の画像が印刷されます。Viewbox を使っているので A4 用紙いっぱいに配置されます。

```C#
public static void PrintImage(ImageSource imageSource)
{
    using (var server = new LocalPrintServer())
    {
        // A4 縦の用紙を準備
        var queue = server.DefaultPrintQueue;
        var ticket = queue.DefaultPrintTicket;
        ticket.PageMediaSize = new PageMediaSize(PageMediaSizeName.ISOA4);
        ticket.PageOrientation = PageOrientation.Portrait;

        // 印刷可能領域を取得
        var area = queue.GetPrintCapabilities().PageImageableArea;
        if (area == null) throw new Exception("印刷可能領域の取得に失敗 ...");

        // 用紙いっぱいにイメージを配置
        var page = new FixedPage();
        var viewBox = new Viewbox
        {
            Child = new Image { Source = imageSource },
            Margin = new Thickness(area.OriginWidth, area.OriginHeight, 0, 0),
            Width = area.ExtentWidth,
            Height = area.ExtentHeight,
            VerticalAlignment = VerticalAlignment.Top
        };
        page.Children.Add(viewBox);

        // デフォルトプリンタで印刷
        PrintQueue.CreateXpsDocumentWriter(queue).Write(page, ticket);
    }
}
```

こんな感じに。
![印刷イメージ](http://drive.google.com/uc?export=view&id=1WJ8TeZl07b_p793jl4NULHzbeb94NUdU)
ここでは仮想プリンタに出力して PDF で保存したんですが、実際のプリンタを「通常使うプリンターに設定」しておけば、このメソッドを呼ぶだけで直接、印刷されます。
何をすればいいのかわからない!GO言語の第一歩。

直近でGo言語の知識が必要になりそう・・・。
とりあえず何から初めていいのかわからないので「[Progate](https://prog-8.com/)」で触りから学んでみた。

## Googleが開発したプログラム言語「Go言語」の特徴
文法がシンプルで学びやすくチーム開発にもおすすめ、実行速度が早いのも特徴。

## 基本的な記述
ファイル名は「.go」、JavaScriptのようにfunction(){}で関数を定義して実行するみたい。
ただし記述の仕方は若干短くてちょっと嬉しい。

```go
func main() {
  println("Hello, Go")
}
```
### Go言語ファイルの構成

- パッケージ定義部分
- 関数定義部分

上記の2つで構成されている。

※コメントの記述方法はJavaScriptと一緒。
※文字列はダブルクォーテションで囲む

```go
// ▼パッケージの定義
package main

// ▼関数の定義
func main() {
  println("Hello, Go")
}
```

## 変数
変数は「var 変数名 データ型」で定義します。

```go
var number int
var name string
```

変数の型が数字であれば「int」省略することができます。

```go
//　型の定義は省略することができる
// ※整数である場合は「int」を記述しなくても数字型として扱われる
var number = 100

// :=（コロンとイコール）で記述することでも「int」で定義するのと同じ意味になります
// varも省略できる
number := 100

```

### 変数に関する注意点
基本的には他の言語と大きく大差はない気がしますが、一応。

1. 同じ変数を定義するとエラーになる
2. 定義する前には利用できない
3. 使ってない変数があるとエラがでる

それぞれエラーが出た時にコンソールでは下記のようなエラー文が出力されます。

```go
// 1 「:= の左側に新しい変数がない」
no new variables on left side of :=

func main() {
  a := 100
  a := 100 ←エラー発生
  println(a)
}

// 2 「変数nが定義されていない」
undefinded:n

func main() {
  println(n)←エラー発生
  n := 100
  println(n)←ここでは使える
}

// 3 「変数bが使用されていない」
b declared and not used
func main() {
  a := 100
  b := 200
  println(a)←エラー発生
}

```

## if文
```go 
func main() {
  x := 5

  if x > 20 {
    println("xは20より大きいです")　
　} else if x == 20 {
    println("xは20です")　
  } else {
    println("xは20より小さいです")
  }
}

// 条件式を複数の条件とマッチさせたい場合は「&&（かつ）」や「||（または）」を利用する

```

## switch文
```go
func main() {
  n := 3
  switch n {
    // caseを追加し、nが0の場合、"凶です"と出力してください
    case 0 :
      println("nは0です")
        
    // caseを追加し、nが1または2の場合、"吉です"と出力してください
    case 1, 2 :
      println("nは1または2です")
        
    // caseを追加し、nが3または4の場合、"中吉です"と出力してください
    case 3, 4 :
      println("nは3または4です")
        
    // caseを追加し、nが5の場合、"大吉です"と出力してください
    case 5 :
      println("nは5です")  
  }
}
 
```

## まとめ
さわりだけやってみましたが、印象としてはJavaScriptとよく似ている気がします。
少しプログラミング言語をさわったことがある人にとってはとっつきやすい言語なんじゃないかと思います。
これからもう少し触ってみてもう少し複雑なことができるようになっていきたいです！
Filmarksから鑑賞済映画のスコア一覧を取得する

## はじめに

鑑賞した映画の記録に，[Filmarks](https://filmarks.com/)というサービスを利用しています．

鑑賞時の評価を0～5の11段階(0.5刻み)のスコアで残すようにしていますが，評価の一貫性を保つのが難しいです．過去に自分がつけた評価を見ていても，「厳しくつけすぎた」とか「甘くつけすぎた」というのが多々あります．


## スコア一覧を取得

現在の評価の分布を確認してみます．
Filmarksは「自分がつけたスコア毎に一覧を確認」的な操作がやり辛いので，BeautifulSoupを使用してhtmlから一覧を取得します．Jupyter Notebook を使用しました．

### import
~~~ python
import requests
from bs4 import BeautifulSoup
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
~~~

### スコア一覧取得
~~~python
dict = {"title":[], "infobar":[]}
for page in range(1, 11):
    rs = requests.get("https://filmarks.com/users/<ユーザ名>?view=poster", params={"page":page})
    soup = BeautifulSoup(rs.content, "lxml")
    
    titles = soup.select(".c-movie-item__title > a")
    infobars = soup.select(".c-movie-item-infobar__item.c-movie-item-infobar__item--star.is-active > a > span")
    
    for title, infobar in zip(titles, infobars):
        dict["title"].append(title.string)
        dict["infobar"].append(infobar.string)
    
df = pd.DataFrame(dict)
df.infobar = df.infobar.str.replace('-', '0')
df.infobar = df.infobar.astype("float64")
~~~

鑑賞済み映画一覧のページ数はハードコードです．(自分の場合10ページあった)   
 

### データの中身を確認

~~~python
df.info()
~~~
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326931/5ea9399c-3cb7-0908-4030-24488e86313f.png)

~~~python
df.head(10)
~~~
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326931/065cdcda-8df9-91a7-823c-47f8cfe051e4.png)
直近10件分のタイトルとスコア．きちんと取れてそう．


~~~python
df.hist()
~~~
![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326931/2e81468b-e890-5c1e-8fbf-adeb10c27cd1.png)

ヒストグラム．これが見たかった．
(昔に見た映画等スコアをつけていないものは便宜上0として処理．0.5, 5.0は実質欠番．)

## おわりに

「必要なら，分布がいい感じになるように過去の評価を微修正しよう」などと考えていましたが，面倒なのでやめました．（というより見ている映画がそもそも少ないので，あまり分布を気にしても仕方がない気がします）

全体のスコア平均と自分のスコアを比較したり，レビューを全て取得してきて字句解析とかすると面白そうです．
釈然としないelectron-vueでのmainプロセスのデバッグ

# electron-vueについて

諸々入ったセットである。今回はこれにさらにtypescriptを突っ込んで開発をしている。
`npm run dev`で開発時には以下のコードによりwebpack build in serverが立ち上がり開発が可能である。

https://github.com/SimulatedGREG/electron-vue/blob/master/template/.electron-vue/dev-runner.js

# VSCodeでのnodeデバッグ

一方でVSCode上でのでバッグは以下のように`launch.json`を書くことで可能だと言われている。

```json
{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Electron: Main",
      "protocol": "inspector",
      "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
      "runtimeArgs": [
        "--enable-logging",
        "--remote-debugging-port=9223",
        "."
      ],
      "outputCapture": "std",
      "sourceMaps": true,
      "preLaunchTask": "build"
    }
  }
}
```

しかしこれはあくまで、バンドルされたstatic fileをelectronから呼び出すだけなので、上記で devでビルドしたときのファイルが呼び出されない？模様。

# そこで

## 1. 以下をコメントアウトする。

https://github.com/SimulatedGREG/electron-vue/blob/master/template/.electron-vue/dev-runner.js#L183

## 2. Run Debug

上記 launch.jsonを用意して > を実行

## 3. うまくいく

という感じである。

# 理由

VSCodeからうまくWebPackのビルドインサーバを呼び出したり、main/rendererプロセスのビルドができなかった・・・とりあえずこれでMain Processのデバッグはできたのでよしとする。
next,websocketを使ったssrのアプリケーションをnetlifyにデプロイしようとしてハマった

nextとwebsocketをつかったssrのアプリケーションをnetlifyにデプロイしようとした。
ssr環境のアプリケーションをnetlifyにデプロイするには

```
next build && next export
```

を実行する必要があるとのこと。
参考：https://qiita.com/7ma7X/items/f8001f7ebac7862477e1

で、いざ実行して見ると、 `next export` の実行が終わらない状態になった。
websocketの通信がサーバー側と常時繋がった状態になってプロセスが終了しないため、 `next export` の実行が終わらないような感じだった。

`next export` の実行が終わらないため、netlifyでのデプロイも一向に進まない。そのため、netlifyでのデプロイは諦めて `now` を使うことにした。

`next export` の実行が終わらない状態になったら Ctrl+c でキャンセルし、バンドルされたファイルが吐かれたディレクトリを対象に `now` を実行

```
$ now dist/ -n gomoku-narabe
> WARN! Your project is missing a now.json file with a `version` property. More: https://zeit.co/docs/version-config
> WARN! You are using an old version of the Now Platform. More: https://zeit.co/docs/v1-upgrade
> Deploying ~/practice/kurohige-front/dist under tomohirosoga
> Using project gomoku-narabe
> Your deployment's code and logs will be publicly accessible because you are subscribed to the OSS plan.

> NOTE: You can use `now --public` or upgrade your plan to skip this prompt. More: https://zeit.co/account/plan
> Using project gomoku-narabe
> Synced 6 files (13.7KB) [1s]
> https://gomoku-narabe-bgoceldxyg.now.sh [v1] [in clipboard] [2s]
> Deployment complete!
$ 
```

デプロイできた。
Google Edge TPUをVirtual Box上のUbuntuで動かす

#1 はじめに
Google Edge TPUのUSB Acceleratorを購入しました。Virtual Box上のUbuntuで動かすのに一苦労ありましたので、ここに書き留めておきます。

#2 環境
Host OS: Windows 10
Guest OS: Ubuntu 18.04 LTS 
仮想化マシン：Virtual Box　ver.6.0.6

#3 手順
1. Virtual Boxのインストール
2. VirtualBoxにOracle VM VirtualBox Extension Packの追加  
ダウンロード先：https://www.virtualbox.org/wiki/Downloads  
3. Virtual BoxにUbuntuのインストール  
   参考：https://qiita.com/ykawakami/items/4bae371932110b2e25e3
4. Virtual BoxのUSBフィルタを編集  
4.1.    設定をクリック  
![VM1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242136/1e4617d3-4143-8a3e-64e1-19de9ed41384.png)  
4.2. サイドバーのUSBを選択し「USBコントローラーを有効化」にチェックを入れる  
4.3. USB Acceleratorを挿入しているUSBポートに合わせ、USBコントローラーのバージョンを指定する  
4.4. USBフィルタの追加をクリックし、Global Unichip Corp.[0100]を追加する
![VM2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242136/489209c6-794a-c7bb-b7c1-59ac43bd34d9.png)  
4.5. 4.4と同様の操作をし、Global Unichip Corp.[0100]を再度追加する  
![VM3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242136/0bae7baa-2e6d-9295-326f-68df465f5c07.png)
4.6. 2つのうち、1つを編集し以下のように設定する  
ベンダーID:18d1  
プロダクトID:9302  
![VM4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242136/27fd2873-e4a8-e33c-019b-995f08100a62.png)
![VM5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242136/754f5dad-44b8-84d0-0b07-2c372ac3a16d.png)
6. Ubuntuを起動  
7. 以下のサイトをもとにUSB Acceleratorの動作確認をする  
https://coral.withgoogle.com/docs/accelerator/get-started/

#4 結果
以下の通り、Virtual Box上でGoogle Edge TPUのUSB Acceleratorを動作させることができた。  
![VM6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242136/9ac7b503-8b0d-d1cc-675f-13b0a630f9a3.png)

#5 経緯
Virtual Box上のUbuntuで動作させるに当たり、2つの問題にぶつかった。
###5.1 "No Edge TPU Device detected!"エラー　　
これは、Virtual Box上でUSBデバイスを認識していないのが原因である。よって、USBフィルタにUSB Acceleratorを追加することで解決できた。  
###5.2 "RuntimeError: Failed to allocate tensors."エラー
この原因はさっぱりわからなかったが、githubのissueを見ているとサンプルプラグラム動作後にUSB AcceleratorのベンダーID、プロダクトIDが変わっているとの記載があった。また、サンプルプログラムを実行するとUSB Acceleratorがアンマウントされてしまうという現象が発生していた。このことから、試しにUSBフィルタに変更後のUSB AcceleratorのベンダーID、プロダクトIDを追加すると動作することができた。

#6 補足事項
* 3で作成した仮想環境をMacBookAirのVirtual Boxにインポートしたが、USB Acceleratorを動作させることができた
* debianでも同様のことを実施したが、5.2のエラーが表示され動作させることができなかった
Data Advanced CallbackでRFメタデータを取得する

2019年6月1日、SigfoxクラウドのDATA_UPLINK（上りメッセージ用）Callbackから受信基地局のRSSIやSNR等RFメタデータとduplication機能がなくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/361e704e-afdc-ecf0-584a-04d2f4a39bf6.png)

#duplication機能とは何だったのか？
DATA_UPLINK Callbackでは受信基地局のRSSIやSNRのRFメタデータが取得できていましたが、duplicationを有効にしていない場合は、複数の受信基地局の中でも、最も早くメッセージをSigfoxクラウドに届けた基地局のRFメタデータがCallbackされるだけでした。
一番受信感度が良かったものではなく、一番早く届けただけの基地局です。ですので、この情報だけでSigfoxネットワークの無線品質を評価していた場合は、評価に値しない結果を取得していたということになります。

では、duplication機能を有効にしていた場合はどうでしょうか？duplication機能は受信局数分だけCallbackを繰り返す機能です。
確かにこの機能を有効にすると、一番全RFメタデータを処理してネットワーク品質を評価することができます。
しかし、将来的なスケールアウトも考えると、ベストなソリューションではありませんでした。
基地局密度が高く10〜20局で受信するようなエリアで、10万台のデバイスが1日あたり50メッセージ送信する場合、1日あたり5,000万〜1億のCallbackが発生することになります。1秒間に1,150回のCallbackです。
これは、お客様のシステム運用コストにも、費用対効果が良くない仕組みでした。

#Data Advanced Callbackのduplication項目
Data Advanced Callbackの基本情報については、[こちら](https://qiita.com/ghibi/items/48613708c36a9fd6d893)を見てください。
Data Advanced Callbackのcontest bodyは下記のような設定が可能です。

```
{
  "device" : "{device}",
  "time" : "{time}",
  "data" : "{data}",
  "seqNumber" : "{seqNumber}",
  "lqi" : "{lqi}",
  "lat" : {fixedLat},
  "long": {fixedLng},
  "operatorName" : "{operatorName}",
  "countryCode": {countryCode},
  "computedLocation" : {computedLocation},
  "duplicates" : {duplicates}
}
```

ここで、duplicatesという項目は、下記のようなJSON構造を取ります。

```
[
  {"bsId":"ABCD","rssi":-120.0,"nbRep":3,"snr":24.25},
  {"bsId":"12EF","rssi":-115.0,"nbRep":3,"snr":27.55}
  ...
]
```

duplicates項目により、今まで、DATA_UPLINKのRFメタデータをduplication機能により取得していたRF情報をData Advanced Callbackのみで取得できるようになります。

※duplicates項目を有効にするためには、Sigfox Operatorに追加権限を依頼する必要があります。
是非、[KCCSパートナーに参加](https://www.kccs-iot.jp/partner/)し、duplicates項目をお試しください。
dockerの0からの入門としてはむずい 〜Udemy感想その７〜

# 概要
Udemyで受講した講座の感想を書いています
僕がまだまだエンジニアリングの知識が少ないので
同じような初心者の方の参考になれば幸いです
今回はdockerのコースの感想です

# 受講した講座
[ゼロからはじめる Dockerによるアプリケーション実行環境構築](https://www.udemy.com/docker-k/)

日本語の講座です
時間は５.5時間と割と短め
dockerのインストールの仕方など基本的なところからイメージの取得、作成方法、
docker-composeでrailsで開発環境を作るなど
ああ、実際に使えそう、便利そうだなといった使い方まで
実際に手を動かしながら勉強することができます

# 受講したときの自分のレベル

会社の研修でdockerを触ったことはあり、
run、exec、stop、lsはとりあえず知ってる

Dockerfileは一回書いたことある程度でした

# よかった点

- **機能紹介に止まらず、実際にrailsやdjangoを動かすことができた**

一応技術としては知っていて、便利そうなのもわかるんだけど
どう使えばいいかわからないって感じからのスタートだったので
imageをpullしてきたらすぐにmysqlが使えるようになったり、
数行のdocker-compose.ymlを書いたら
すぐにrailsとpostgresを使用した開発環境が出来上がりサーバーを起動できたなど
個人で開発を行う上で使えそうな技術を具体的に教わることができました

# 今ひとつだった点
- **更新されていない(反映されていない？)**

途中動画の通りに設定ファイルを作ったのにうまく動かないことがあり、
散々調べたんですが解決しないことがありました


結果的に講座のQAのところに同じような質問があり解決したのですが、
動かないことが判明しているのであれば動画に注意書きか何か欲しかった。。
最終更新は2019年1月と割と最近なのでただ単に動画は変更しなかっただけなのでしょうか
(最初からQA見ろよって話なんですがエラー出たらとりあえずログみたりググったりするのが癖なので、、)

- **ちょっと説明があっさりし過ぎかも**

imageとかの説明はわかりやすかったのですがswarmの部分の概念の説明は
もうちょっと時間かけて欲しかった

僕はk8sを知ってたのでなんとかついていけましたが
０からっていうからにはもう少し丁寧に説明があってもいいんじゃないかと思いました

# まとめ

少し説明が少ない部分はありますが多くのコマンドの使い方を説明してくれてますし
時間も5.5時間と短いのでdocker一通り触ってみようって時には
いいかもしれません
VCP-NV2019取得したぞい

VCP6-NVだと思ってましたがダウンロードしたPDFにはVCP-NV2019と記載されてました。
いつ取得したかがわかる資格名称になっているのは良いですね。

# 研修受講前の状態
今思うとこれでよく取得できたな感があります。が、逆に研修がちゃんとしていたとも言えるかもしれません。

- サーバサイドエンジニア（と思っている）
  - NWの知識はサーバ設定に必要（十分かどうかは知らない）な程度
  - NW機器は新人研修で触ったことがあるくらい
- 業務利用でVMware製品を使ったことがほぼない
  - vCenter触ったのは今のプロジェクトが初
  - 仮想スイッチをちゃんと理解できたのは研修受けてから

# 試験準備
- VMware NSX: Install,Configure,Manage [V6.4] の受講
  - 5日間で50万弱
  - 正直研修の受講が資格取得に向けての一番のハードルだと思ったり
- [Practice Exam](https://www.vmware.com/jp/education-services/certification/vcp6-nv-nsxv62-exam.html)
  - 英語
  - 問題の癖に慣れる、という意味では有用
- [VMware HOL Online](https://labs.hol.vmware.com/HOL/catalogs/catalog/1212)
  - 研修でやったことの復習に利用
  - 2時間くらい仮想環境使って勉強できるが、操作性は悪いので注意

# 試験の感想

- 初ピアソンVUE（テストセンター）受験
  - ローマ字表記の申請だったので念の為パスポート持って行ったけど免許証とクレカで十分でした。
  - 秋葉原のところの試験端末は可もなく不可も無く。
- 選択式なので気楽に受けられた感じ
  - 「1つだけ選択」と「複数選択」があるけど後者は割と面倒な印象。
  - 120分77問だけど悩んだのが10問くらいだったせいか、見直し含めて30分くらいで終わった気がします。
- 研修の内容が7-8割くらい
  - LSW, DLR, ESG, DFWの仕組み、仕様を理解していれば問題ないレベル。
  - 「どういう仕組みで動くのか説明を聞きつつ実際に設定する」という研修だったので、研修の内容を理解できていれば合格できる気が。
- 研修でカバーしきれていないもの（=自分で勉強が必要なもの）
  - **NW知識**（動的ルーティングプロトコルとか冗長構成に対する設計思想とか）
  - 要件と制約（重要なものは研修でも触れていたけど、多分それだと足りない）
  - vCNSからのアップグレード要件、手順
  - モニタリング関連、権限モデルとか細かいもの

# 今後
VCAP-NVは取りたいけども現状Deployしかなくて、実技＋英語らしいのでいつ取るかは保留かなぁ。
HoLのインターフェースにある程度慣れてから受験時期を考えたいところ。
【CraftCMS】エントリフィールドをキーとしてエントリを取得する

ちょっと何言ってるか分からない
==============================

誰もこんなことやらねーよな事案かもしれないが実際あったケースなので残す。

エントリフィールドを持つ、とあるセクションのエントリを起点として
そのフィールドに登録されているエントリを取得する

たった1文で3回エントリという言葉が出て非常にややこしいので図解

![名称未設定.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23195/041c4827-829e-2684-5923-b32dae0bc93c.jpeg)


親エントリとしてAというセクションがあり
子エントリBでは親エントリを選択するエントリフィールドがある

エントリBのページを開いた時にエントリAの情報を取得したいがためであった
ページ構成としては
**http\://xxxx.jp/エントリA.slug/エントリBの一覧/エントリB**

エントリAのページがあってそれぞれ子エントリにBがぶら下がってるケース
エントリAはカテゴリでよかったんじゃ？というのもあるが
投稿データをカテゴリとして増やしていくのはなんか違うと思ったからである


肝心のソースは？
==================

まずエントリBの一覧をどうやって引っ張ってくるかであるが
理屈としては**エントリフィールドにエントリAが登録されているエントリBを全部取得**である

簡単そうで難しい、まずエントリAのセクションを取得するところから
これはURL定義からsegmentの2番目(Indexとしては1)がslugなので単に文字列を取得することで解決
**セクション moyashi をエントリA群、セクション nira をエントリB群とする**

```twig
{% set parent_slug = craft.app.request.getSegment(1) %}
```
これをネタにエントリAを取得する

```twig
{% set parent_entry = craft.entries.section("moyashi").slug(parent_slug).one %}
```

エントリAを取得出来たらそれを紐づけているエントリB群を取得する
ここがリファレンス見てもよく分からず、またも中の人に泣きついて教えてもらった

> relatedToを使えば出来るよ！

それ使ってみたけど出来なかったよ…
↓最初に書いた処理

```twig
{% set entriesB = craft.entries.section("nira").relatedTo("moyashi:" ~ parent_entry).all %}
```
そもそもrelatedToメソッドがどういうデータを取得するのかドキュメント読んでてもよく分からないのである
ちなみに↑これでも一応それっぽいデータを引っ張ってきてはいたが、
slugが違うのに微妙に似てるエントリも取ってきてしまうポンコツ記述であった
（よく分かんなかったのでSearchみたいなもんかな？ってノリで書いた）

で、たどり着いた正解がこちら

```twig
{% set entriesB = craft.entries.section("nira").relatedTo({targetElement : parent_entry}).all %}
```

配列でtargetElementに親エントリを指定すると良いとのことだった。うーん、難しい。
[非常にありがたいことにリレーションの資料は日本語化もされている](https://docs.craftcms.com/v3/ja/relations.html#%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E8%A8%98%E6%B3%95)
が
ストレートに直訳されている部分も多いので結局どういうことなのか分からなかった

>
- 返されるエレメントが、渡したエレメントとソースまたはターゲットのどちらで関連付くかを気にしない場合、elementを使用します
- 与えられたエレメントのソースとして関連付くエレメントだけを見つけたい場合、sourceElement を使用します
- 与えられたエレメントのターゲットとして関連付くエレメントだけを見つけたい場合、targetElement を使用します

つまりどういうことだってばよ？
本当はtargetElementも不適切なのかもしれないが
何度も検証を重ねて**ヨシ!!**という結論に至ったので一旦良しとしているのである…
Alexa Reminder skillでリマインダー作成時にInvalid Token、DEVICE_NOT_SUPPORTED、UNAUTHORIZEDとなった場合の対策

AlexaのReminder機能が一般公開されましたが、私もReminderスキルを作成してみようとしましたが、なかなかうまくいかず、注意点をまとめておきます。

#権限の設定
Reminder機能を使うためには、権限の設定が2つ必要になってきます。
- Alexa developer consoleのアクセス権限付与
- Alexaアプリ上でのアクセス権限付与

「Alexa developer consoleのアクセス権限付与」は、アクセス権限の個所から下図のスイッチをONにすることで権限を付与することができます。
![アクセス権限.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/91617b75-d6f7-cf1e-280d-8ae2ad5ab605.jpeg)


「Alexaアプリ上でアクセス権限付与」は、スマートフォン（私の場合iphoneですが、おそらくスマートフォンも同じだと思います）のAlexaアプリ上のメニューの「スキル・ゲーム」から有効なスキルタブで、Reminderを設定するスキルを探して、そこで許可します。
![スマホ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/739d0585-3ebb-94d3-c69f-4cf93de6b7e9.jpeg)
この画面で、「設定」を押すと、下図が表示され、ここで、Reminder機能の活性化を設定できます。
![スマホ2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/870b04d3-571a-5200-a532-75808b4990e3.jpeg)

実は、この「Alexaアプリ上でアクセス権限付与」がわからなくて、困っていました。最終的にスキル・ゲームのメニューで、「開発中」というところを選択すると、開発中のスキルの設定ができ、Reminderを許可することができました。

#Amazon echoでの実施の必要性

Reminderのサンプルを見ながら、まずは作ってみようとはじめて見た。しかしながら、AWS LamdbaでReminderスキルをテストしても、どうしても「Invalid Token」がでてしまい、弱りました。
この理由は、Reminderを設定するJSONのAuthorizationで設定するアクセストークンが間違っていたためでした。Lamdbaのテストで作成したJSONは、Alexa developer consoleで実施したときに作成されたJSONファイルをそのままコピーして使っていましたが、アクセストークンは変わりうる値なので、そのまま使っていると、「Invalid Token」になってしまうようです。

それならばと、Alexa developer consoleで試してみたのですが、ここではUNAUTHORIZEDがでてしまい困りました。ならば、iphone上のアレクサアプリではどうかかと試してみましたがやはり同様でした。
結局は、上に書いた「Alexaアプリ上でのアクセス権限付与」ができていなかったことが要因だとわかりました。
その後、許可した後に再度Alexa developer consoleやiphone上のAlexaアプリで試してみましたが、今後はDEVICE_NOT_SUPPORTEDとなってしまいました。

最終的には、Amazon echo本体で実施すると正常動作しました。

なかなか難しいですね。
[環境構築編] scala入門にあたってやったこと[Mac]

## 流れ
scala の開発環境構築のためにはまず、 jdk が必要らしいのでこれを入れる。

その次に、ライブラリ管理や scala のバージョン管理をしてくれる sbt というものを入れ環境構築をしていく。

最後に IDE と連携するための設定をする。

## Mac に JDK を入れる
バージョンは適当に新しめのやつを入れた。とりあえず動いているっぽいので多分大丈夫だと信じてる。

JDK を入れるには brew を使った。ここでは brew のインストール方法については述べないので、各自入れてほしい。公式ページに行ったらすぐ入れられるはずだ。

### brew に cask リポジトリの追加
リポジトリの追加は tap コマンドでできる。 `brew update` で更新してから入れる。

```:sh
$ brew update
$ brew tap caskroom/cask
```

入れたリポジトリを確認する。

```:sh
$ brew tap
caskroom/cask
```

### JDK のインストール
下記でインストールできる。

```:sh
$ brew cask install java
```

## sbt のインストール
sbt のインストールも brew から行える。

```:sh
$ brew install sbt
```

実行確認

```:sh
$ sbt console
[info] Loading project definition from ~/src/github.com/IkezoeMakoto/etc-trial/scala/app/src/project
[info] Loading settings for project src from build.sbt ...
[info] Set current project to demoProject (in build file:~/src/github.com/IkezoeMakoto/etc-trial/scala/app/src/)
[info] Starting scala interpreter...
Welcome to Scala 2.12.7 (OpenJDK 64-Bit Server VM, Java 12.0.1).
Type in expressions for evaluation. Or try :help.

scala> 1 + 1
res0: Int = 2

scala> "Hello World"
res1: String = Hello World
```

## IntelliJ IDEA 連携
私は IntelliJ で開発しているのでこちらの IDE と連携するための設定もついでにしておく。

### Plugin のインストール
Plugin はひとまず下記の２つをインストールした。

* [Scala](https://plugins.jetbrains.com/plugin/1347-scala)
* [SBT](https://plugins.jetbrains.com/plugin/5007-sbt)

### SDK の設定
「File」 → 「Project Structure」 → 「Project SDK」

インストールしたバージョンを指定してください。

お疲れ様でした。
【Swift】!と?

# はじめに
最近Swift…というかiOSアプリ開発を始めました。
今までpythonをメインに使ってきたので、慣れない部分が多々あります。
その中で一番引っかかった「!」と「?」についてまとめたいと思います。

# ?
「?」をつけるとOptional型になります。
Optional型とは、nil(pythonならNone、javaならNull)が代入可能な型のことです。
「?」をつけてOptional型にすることを「ラップする」と言います。

```test.swift
var value: String? // valueという変数にはnil、またはStringが入る
```
上記のように宣言すると、valueという変数にはString、またはnilを入れることができます。
「nilが入るかもしれないよ」という意味で理解しています。

ラップした変数から値を取り出すことを「アンラップする」と言います。
アンラップは以下のように行います。

```test.swift
var value: String? // valueという変数にはnil、またはStringが入る
value = "Hello, World" // Stringを代入したけど、まだOptional型

if let value = value { // アンラップ
    // valueがnilでない時にここの処理が行われる
    // valueには"Hello, World"というString型が入っている
}

```

# !
Optional型に「!」をつけると、強制的にアンラップすることができます。

```test.swift
var value: String? // valueという変数にはnil、またはStringが入る
value = "Hello, World" // Stringを代入したけど、まだOptional型
print(value) // 出力は「Optional("Hello, World")」(Optional型)
print(value!) // 出力は「Hello, World」(String型)
```

「この変数はOptional型だけど、絶対に値は入ってる」という意味で理解をしています。
ちなみに、上記の例でnilのままだと、アンラップしようとした時点でエラーが生じます。

```test.swift
var value: String? // valueという変数にはnil、またはStringが入る
print(value) // 出力は「nil」
print(value!) // Fatal error: Unexpectedly found nil while unwrapping an Optional value
```

# なんであるのか
かの有名な「ぬるぽ」(NullPointerException)を回避するためだと思っています。
変数に自由にnullを代入することが可能な言語では、予期せぬタイミングでnullが入っていた場合、エラーを生じることが多々あります(Nullへの演算等)。
SwiftではOptional型以外でnilを代入できなくすることで、予期せぬnilを防ぎ、エラーを防いでいます。

# 最後に
まだ開発を始めたばかりで、慣れたとは言い難いですが、楽しくやっていきます。
誤り、指摘等ございましたらコメントをお願いいたします。

# 参考
[swift公式](https://docs.swift.org/swift-book/LanguageGuide/OptionalChaining.html)
[SwiftのOptional型を極める](https://qiita.com/koher/items/c6f446bad54442a28bf4)
javascriptのメソッドとコンストラクタ

# メソッドとは
 プログラム中は、意味や内容がまとまっている処理や、繰り返し現れる処理を、ひとつのグループとしてまとめます。

# コンストラクタとは
　あらかじめ定義されたクラスをインスタンスに転化する仕組みです。

# JavaScriptのメソッドとコンストラクタ

```js
function foo() {
    return 1
}
var v = foo(); // fooをメソッドとして扱う
var o = new foo(); // fooをコンストラクタとして扱う
```

JavaScript の 「function」キーワード はメソッド、コンストラクタ両方を宣言することが可能です。


##  メソッドオブジェクトとコンストラクタオブジェクト
**メソッドオブジェクトとは：a object with [[call]] private field**
**コンストラクタオブジェクトとは：a object with [[construct]] private field**

つまり、[[call]] private fieldをもつオブジェクは、メソッドとして呼び出すことができます。
 [[construct]] private fieldをもつオブジェクは、コンストラクタとして呼び出すことができます。

「function」キーワードで生成されたメソッド（実はオブジェクト）は必ず[[call]] private field、[[construct]] private field両方を持ち、メソッドまたはコンストラクタとして扱われます。

まだ例に戻りましょう

```js
var o = new foo(); // 何が発生したのか
```
[[construct]]を呼びされた場合、発生したことは以下になります：

- Object.protoypeをprotoypeとして新しいオブジェクトを生成する
- **step1で生成したオブジェクトの[[call]]を実行する**
- [[call]]の戻り値がオブジェクト->この値を返す
- [[call]]の戻り値がオブジェクト以外->step1で生成したオブジェクトを返す

ちなみに、[[construct]]を呼ぶことで新しいオブジェクトを返された場合は(step3)、このオブジェクトがクロージャになります。（外部からこのオブジェクトのプロパティをアクセスできないため）、例えば：

```js
function foo(){
    this.a = 100;
    return {
        getA: function() {
            return this.a;
        }
    }
}
var f = new foo;
f.getA(); //100
//f.a 外からアクセスできない

```
##  クラスの定義と関数の定義の切り分け
クラスの定義と関数の定義とも「function」キーワードを使っているのは何となく気持ち悪いのでなんかいい方法があります？
### 「class」キーワード
es6から「class」キーワードがサポートしているため、new class()でコンストラクタ処理を行えるようになります。
### アロー関数
アロー関数とは、より短く記述できる、通常の function 式の代替構文です（javaのlambda関数みたいなやつ）
アロー関数で生成したのは関数だけ、コンストラクタとして扱わないです。

```js
new (v => 0) // error
```

# まとめ
「function」キーワードで生成されたメソッドはメソッドまたはコンストラクタとして扱われます。
「function」キーワードを使わず、関数宣言の場合はアロー関数、クラス宣言の場合は「class」キーワードの方が個人的良いのではないかと思います。
Clovaで「抵抗値換算」のスキルを作ってみる（２）

# はじめに
[前回](https://qiita.com/ufoo68/items/f6b04e1ca89a931ca206)の続きです。今回は、1000Ω以上の値をキロ読みに変換する処理と、抵抗値からカラーコードへの変換を実装しました。
レポジトリは[ここ](https://github.com/ufoo68/clovaRegistorValueConverter)で公開しています。 

# 大きい抵抗値をキロ読みにする
抵抗値を話し言葉としてアウトプットさせるときは「キロ」などの読み変換させるほうが自然になると考えたのでキロ読みを実装しました。そこで`registorValue`への代入式を以下のように拡張させました。

```js
const registorValue = thirdValue => { 
    switch(thirdValue) {
        case '0':
            return `${firstValue}${secondValue}`;
        case '1':
            return `${firstValue}${secondValue}0`;
        case '2':
            if (secondValue === '0') {
                return `${firstValue}キロ`;
            } else {
                return `${firstValue}点${secondValue}キロ`;
            }                       
        case '3':
            return `${firstValue}${secondValue}キロ`;
        case '4':
            return `${firstValue}${secondValue}0キロ`;
        default:
            return '？';
    }
}
```
`firstValue, secondValue, thirdValue`はそれぞれ1番目～3番目のカラーコードに対しています。`case 5: ~ case 9:`の実装をしていませんが、元々スロットを用意していないので省略しました（[ここ](https://github.com/ufoo68/clovaRegistorValueConverter/blob/master/colorCodeValue.tsv)を参照してください）。

## キロ読みのテスト
`茶緑赤金`の並びの抵抗値は以下のようになりました。
![テスト５.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/bc643034-305f-c75a-5d89-46b950c583ac.jpeg)

実機では声のみでのアウトプットになるので小数点に「点」という漢字を使いました。また、`茶黒赤金`のときは「1キロΩ」と読んでもらうように実装したのでテストの結果は以下のようになりました。
![テスト４.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/5b6e9436-ad64-50e9-c1c4-dc0af2e6c63e.jpeg)


# 抵抗値 -> カラーコードへの変換
半角の数字スロットを受け取ったときに、その各桁の数値に対応する色のkeyを取得していくような処理を以下のように実装しました。スロットはビルトインスロットの`CLOVA.NUMBER`を使用しました。

```js
const registorValue  = String(slots.number);
if (typeof Number(registorValue) === 'number' && registorValue.length >= 2) {
    const firstColor = Object.keys(colorcodes).filter(key => { 
        return colorcodes[key] === registorValue.slice(0, 1)
    });
    const secondColor = Object.keys(colorcodes).filter(key => { 
        return colorcodes[key] === registorValue.slice(1, 2)
    });
    const thirdColor = Object.keys(colorcodes).filter(key => { 
        return colorcodes[key] === String(registorValue.length - 2)
    });
    const colorcode = `${firstColor}${secondColor}${thirdColor}`;
    speech.value = `${registorValue}Ωのカラーコードは${colorcode}金です。`
}
```

抵抗値を2桁以上と制限をかけていますが、通常は3桁以上の抵抗値をよく使うので実用上は問題ないと思います。今回は誤差の値は考慮しないので4番目のカラーコードをデフォルトで金にしました。

## カラーコード変換のテスト
`10000Ω`のときのカラーコードへの変換は以下のようになりました。
![てすと３.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/f69bbb48-ee8e-d373-4824-a98124c27adf.jpeg)

# 次に目指すこと
抵抗値からカラーコードへの変換は半角数字のスロットを受け取ったときのみに限定しましたが、これを「～キロ」と受け取ったときや、~~漢数字で受け取ったとき~~（←結局半角英数字に変換されるみたいなので特に考える必要は無さそうでした）の場合の処理も可能であれば実装していきたいです。
【Scala】悩ましいインターフェース問題

# はじめに
ScalaでDDDやらクリーンアーキテクチャやらまじめに考えると、リポジトリやサービスのインターフェースの設計に色んな手段が考えられて悩ましいという話。

# シンプルなインターフェース
ある意味でシンプルに環境依存も含めて宣言しちゃうパターン。

```scala

// 環境依存1 = DBSession
trait Repository[DBSession] {
  
  // 環境依存2 = Future
  def findOne(implicit session: DBSession): Future[Either[Throwable, A]]

}

```

型`DBSession`はインフラ層で決定されるとしても、なんだか「依存性逆転の原則」違反がチラチラしてる気がして気になります（違反はしてないとは思うけど）。
当然、環境が変化したらインターフェースも書き換えでしょう（FutureがTryになるとか）。

**ただ必要な型が全部見えてるので実装時に楽っちゃ楽だったりします。**

# モナディックなインターフェース
環境依存は悪だ！`Monad`が使えるんだから環境は抽象化できるはずだ！


```scala

trait Repository[M[_]] {

  def findOne: M[Either[Throwable, A]]

}

```

**2019年5月10日修正：実装しずらかったので`M[_]`の宣言位置を変えました。**

これが一番「クリーンアーキテクチャ」的で綺麗な宣言かと思います。
実装時に`M[_]`の型は`Kleisli[Future, DBSession, ?]`のようになることでしょう。
このパターンの一番の問題は、アプリケーション層等での利用時に`for comprehension`内で型揃えが頻発することです。

**全部`EitherT`でくるんで、`Future`じゃないやつは`Future.successful`でくるんで・・・`Task`と`Try`も？どうすんだこれ？**

# ExtensibleEffectsなインターフェス
モナディックなインターフェースの型合わせが面倒くさい！インターフェースが綺麗でも実装が汚いのは嫌じゃ！

・・・となった時に現れたのが[Eff](http://atnos-org.github.io/eff/index.html)こと`ExtensibleEffects`です。

```scala

// ふたたび現れるDBSession　← どうにかする方法を模索中
trait Repository[DBSession] {

  type _sessionReader[DBSession] = Reader[DBSession, ?] |= R

　// Eff <- from atnos-org/eff
  def findOne[R: _sessionReader]: Eff[R, A]

}

```

また環境がチラチラしてますが、まあ戻り値には影響を及ぼさないので良しとしておいてください。
`Eff`自体の詳しい解説は下部の参考先を見てもらうとして、`Eff`を用いた場合、モナディックなインターフェースと違い、`Monad`であることをキープしたまま実装時の`for comprehension`内での面倒な型揃えを回避することができます。

**ただし、インターフェース宣言時にcontext boundを明示したり、関数呼び出し時に型を明示したり、最終的な実行時に`runReader`やら`runEither`やらを必要分記述しなければいけません。・・・あれ？これ逆に面倒くさいんじゃ・・・**

# おわりに
それで、どれが良いのか結論は？

いや、だから悩んでるって話しでして・・・

- 「シンプルなインターフェース」は自分的にはScalaである必要なくなっちゃうんで無し。
- 「モナディックなインターフェース」は確かに見た目はよいし、クリーンアーキテクチャちっくな雰囲気ある。ただ実装は汚れがち。
- 「ExtensibleEffectsなインターフェス」は実は後の手間よりもインターフェースが汚れやすいのが問題だったりするかも？（環境分、context boundが増える）`for comprehension`はまじ綺麗になる。

「モナディックなインターフェース」と「ExtensibleEffectsなインターフェス」の2択かなぁ。

・・・もう気持ちの問題なのかもって気がしなくもない。

# 参考先

モナディックなインターフェース関連

- [purely_functional_play_framework_application](https://www.slideshare.net/AoiroAoino/purelyfunctionalplayframeworkapplication)


ExtensibleEffectsなインターフェス関連

- [Extensible Effects in Scala](http://halcat.org/scala/extensible/index.html)
- [Scala + CleanArchitecture に Eff を組み込んでみた
](https://tech.recruit-mp.co.jp/server-side/post-18728/)
Flutterでdrawerを利用した遷移時にdrawerを閉じる方法

onTap内で下記のようにpopした後、pushする。

```dart
            ListTile(
              onTap: () {
                Navigator.of(context).pop();
                Navigator.of(context).push(
                  MaterialPageRoute(
                    builder: (context) {
                      return ContactsPage();
                    },
                  ),
                );
              },
```

popでdrawerが開く前になり、pushで遷移先のページに移動するため、遷移先のページから戻ってきた際にdrawerが閉じられたページに移動できる。

## 参考
[How to close Scaffold's drawer after an item tap?](https://stackoverflow.com/questions/43807184/how-to-close-scaffolds-drawer-after-an-item-tap)
Javaコードをスクリプト的に実行する

# はじめに
皆さん、お風呂は好きですか？私は好きです。暖かいお風呂に浸かってリラックスする時間は良いものです。
不思議なもので、プログラミングから離れて別のことをしている時、プログラミングに関して何か閃くことってありますよね。今回もそうでした。
ある日、いつものようにお風呂に浸かってボーッとしていた時、突然閃きました。「JShellってJavaコードが書かれたファイルを読み込んで、その内容を実行させることはできるのだろうか？」「それができるのであれば、スクリプトのようにJavaコードを実行できるんじゃね？」って。

世の中にはお風呂に浸かりながらプログラミングする方もいらっしゃるそうですが、あいにく私はその域には達していないので、すぐに試すことはできません。仕方ないので、閃いたことを忘れないように意識しながら早めにお風呂場を出ました。

# 試す
部屋着を着て、MacBookを開き、それっぽいキーワードでググります。はたして、JShellはJavaコードが書かれたファイルを読み込んで、その内容を実行させることが可能であるようです。早速試してみます。
JShellを使うので、以降のサンプルはJava9以上でないと実行できません。あしからず。

コード

```java:test.jsh
System.out.println("Kitty on your lap")
/ex
```
JShellなのでコードはこれだけで済みます。セミコロンも不要です。 `/ex` はJShellの終了コマンドで、これがないとJShellの対話式実行の状態になってしまうとのことです。

実行

```
jshell test.jsh
```

`jshell` コマンドにファイル名を渡すだけで実行できます。
<kbd>Enter</kbd> を押してから実行されるまでにちょっと時間がかかりましたが、これだけでちゃんと「Kitty on your lap」が表示されました。素晴らしいですね。
なお、ファイルの拡張子は後掲の参考リンクに倣って.jshとしましたが、他の拡張子でも動作するようです。なんなら.javaでもいいです。（紛らわしいですが…）

# メリット

さて、この実行方法はJShellを使っているわけなので、JShell自体のメリットがそのままこの実行方法のメリットになるはずです。つまり、下記のようなメリットがあります。
（タブ補完のような、JShell上で直接実行する場合のメリットは除く）

* `javac` でコンパイルするといった手順なしで実行できる
* クラスとmainメソッドを書かなくてもJavaコードを実行できる
* 行末のセミコロンを省略可能
* よく使うパッケージについてはインポート済でそのまま使える（java.io.* や java.util.* など）
* チェック例外を無視できる

素晴らしいですね。（語彙力）
風呂上がりでただでさえ火照っている胸がさらに熱くなりました。

## もうちょっと試す

上記の4つ目や5つ目のメリットは前掲のサンプルでは確認できないので、別の例を書いてみます。
テキストファイルを読み込んで、「hoge」が含まれる行を表示するコードです。

```java:test2.jsh
try(Stream<String> lines = Files.lines(Paths.get("test.txt"))) {
    lines.filter(line -> line.contains("hoge"))
            .forEach(System.out::println);
}
/ex
```

Stream、Files、Pathsについて、明示的にインポートしなくても使えています。また、Files.lines()はIOExceptionを投げる可能性がありますが、IOExceptionを処理するコードを書かなくても動作しています。Javaにしては短く書けてなかなかいい感じです。
ただ、この例だとセミコロンを省略できないようでした。（エラーとなりました。たぶん内部的なコンパイル時のエラー）

# デメリット
体が冷えるにつれ、頭のほうも冷静になってきました。

Javaにしては短く書けて明示的なコンパイルなしで実行できるとはいえ、コードの短さや実行の手軽さという点ではPythonやRubyといったスクリプト言語には敵いません。
また、詳細は後掲の参考リンク先を読んでいただいたほうがよさそうですが、普通に `java` コマンドで実行するのと比べるとパフォーマンスの面で不利とのことです。

そうなると、あまりユースケースが思いつかないですね。ほとんどの場合はスクリプト言語を使ったほうがいいでしょうし、Javaのちょっとした動作確認のためにスニペットを実行する場合はJShell上での直接入力で事足りる場合が多いでしょうし。
Javaしか書けない人や、何かJavaにこだわりがある人がスクリプトを書きたい場合には使えるでしょうか。そのようなニッチな需要しかカバーできないのが大きなデメリットでしょうね…

# まとめ

* Java9以上なら、JShellを使うことでJavaコードをスクリプト的に実行可能
  * （明示的な）コンパイルが不要
  * 普通にJavaを書くのに比べると短く書ける
     * クラスやmainメソッドを省略可能
     * セミコロンを省略可能（省略できない場合もある）
     * よく使うパッケージは明示的にimportしなくてもそのまま使える
     * チェック例外を処理するコードを省略可能
* 
普通にPythonやRuby等を使えばいいと思う
  何かスクリプトを書く時に、どうしてもJavaで書きたい or そもそもJavaしか書けないという場合は重宝するかも

# 参考リンク
http://d.hatena.ne.jp/bitter_fox/20160703/1467577784

# 余談
* Java11以上なら、通常のJavaソースを `java` コマンドで直接実行可能とのこと
  * http://nowokay.hatenablog.com/entry/20180617/1529239404
* お風呂に浸かりながら寝るのは危険です。疲れがたまっている方は気をつけましょう
* お風呂に浸かりながらプログラミングするのは危険です。やるなら自己責任で
RTAIのComedi,EFLTK有効化

[RTAI-Lab tutorial: Scilab, Comedi, and real-time control](https://www.rtai.org/userfiles/downloads/RTAILAB/RTAI-Lab-tutorial.pdf)の「2.9 RTAI(2nd pass)」の内容です。

過去にRTAIをインストール済みの状態から、Comediおよび、EFLTKを有効化していきます。

```
# cd /usr/src/rtai
# make menuconfig
```

COMEDI supportにチェック
![Screenshot from 2019-05-02 14-41-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403008/750c8007-e7f8-bc20-180d-b9ee4a50533e.png)
RTAI Labにチェック
![Screenshot from 2019-05-02 14-40-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403008/d4cf488f-33f6-3f61-14d8-aef20616a6a2.png)

```
# make
# make install
```

最初、パスの指定を間違えて`make menuconfig`でエラーになっちゃいましたが、正しく指定したら問題なくビルドできました。
Fargate環境構築で困った点

# 概要
下記環境を新規作成しようとした際に諸々困った点があったので記載します。
インターネット - S3 - ALB(external) - Fargate(Task)

# 困った点
1.  ALBのタイプをexternalからinternalに変更しようとした時にFargateのクラスタ内のServiceを作り直さないといけなかった。
2.  上記の新規環境を作成しようとした際にALBからのhealthcheckが成功->失敗を繰り返す。

# 解決策

- 1. について
  「困った点」にも記載しましたが、文字通りServiceを作成し直さないといけない。また、ALBのDNS名に対してAliasレコードをコンテンツDNS上に記載していたら、そちらも修正しないと通信できない。

- 2.について
  - Taskにてメモリ制限（MB）が0になっていた。
  こちらタスク定義の新しいリビジョンの作成 -> コンテナの定義 から編集するが、コンテナの定義で作成 -> タスク定義の新しいリビジョンの作成で作成ボタンを押さないと反映されない。
  
  - コンテナの定義にてHEALTHCHECKの設定をするが、下記の通り、CMD-SHELLとcurlの間に,(カンマ)が必要である。編集前の画面上では,(カンマ)が表示されていないので要注意!
    
    ` CMD-SHELL,curl -f http://localhost:9000 || exit 1 `
連番のインスタンス変数をinstance_variable_getメソッドでDRYにしようとしたけど用途が違った

# 追記：DRY後（最終形）
@znz さんにコメントでご指摘をいただきました。ありがとうございます。
結局 `instance_variable_get` メソッドを使うより普通に配列でやるべきでした。
以下のように書けました。

```schedule_controller.rb
# day_1,day_2 に値をセットする過程は省略
@days = [day_1,day_2]
```

```erb:schedule.html.erb
<% @days.each do |day| %>

...中略（Rubyとは直接関係のないHTML、CSSの記述など）...

  <%= render 'day', day: day %>
<% end %>
```

# DRY後（一回目）

- コントローラー側で `@day_1` と `@day_2` の2つのインスタンス変数をセットしているとします。
- 下のコードでは `_day.html.erb` パーシャルを呼び出していますが、こう書くことで動的に生成したインスタンス変数名を指定できます。

```erb:schedule.html.erb
<% 2.times do |n| %>

...中略（Rubyとは直接関係のないHTML、CSSの記述など）...

  <% day_i = "@day_#{n + 1}" %>
    <%= render 'day', day: instance_variable_get(day_i) %>
<% end %>
```

# DRY前

- 下記のように `render` メソッドを並べても動きますが、中略にした部分も並べないといけませんので、やはりDRYにした方が良い感じですね。

```erb:schedule.html.erb
...中略（Rubyとは直接関係のないHTML、CSSの記述など）...

<%= render 'day', day: @day_1 %>

...中略（Rubyとは直接関係のないHTML、CSSの記述など）...

<%= render 'day', day: @day_2 %>

```

# 参考
- [instance method Object#instance_variable_get (Ruby 2.6.0)](https://docs.ruby-lang.org/ja/2.6.0/method/Object/i/instance_variable_get.html)
VagrantのNFSを3.7倍速くする設定

Vagrantの共有フォルダは、NFSにするとかなり速くなることはよく知られていますが、NFSも設定を変えると、更に3.7倍速くすることができます。

## デフォルトの設定

デフォだと、書き込み速度[^dd]が65MB/sでした。

[^dd]: `dd if=/dev/zero of=./test bs=1M count=100`で書き込み速度を検証した

```rb:Vagrantfile
  config.vm.synced_folder "/Volumes/dev", "/Volumes/dev", type: "nfs"
```


## 設定を追加した場合

下記の設定を追加した場合、書き込み速度[^dd]は240MB/sまで向上しました。

デフォルトと比べて、**3.7倍速くなって**います。

```rb:Vagrantfile
  config.vm.synced_folder "/Volumes/dev", "/Volumes/dev", type: "nfs",
    mount_options: ['rw', 'vers=3', 'tcp'],
    linux__nfs_options: ['rw','no_subtree_check','all_squash','async']
```

### udpではなくtcp

UDPのほうがパフォーマンス速そうですが、なぜかTCP over UDPのほうがなぜか速かったです。分かる人いたら教えてください。

### 非同期(async)

非同期なNFSは信頼性と一貫性をトレードオフして、パフォーマンスを向上します。

ホストOSとゲストOS間では、ネットワーク的なトラブルが発生することがまず無いと考えられ、データ破損のリスクもないと考えられるため、非同期のほうにアドバンテージがあると思います。

## 参考

* [Speed up Vagrant Synced Folders - Theodo](https://blog.theodo.com/2017/07/speed-vagrant-synced-folders/)
Railsで多対多のリレーションを作るときにはまったこと

## 概要
Railsで多対多モデルのリレーションを貼る際にハマったことを記載しておきます。

## 環境
* Ruby 2.5.1
* Rails 5.2.3

## モデル
下記のようなモデルを作るとします。

```
                      +------------+
+------------+        | PostTag    |
| Post       |        +------------+        +------------+
+------------+ 1    * | id         |        | Tag        |
| id         |--------| post_id    | *    1 +------------+
| content    |        | tag_id     |--------| id         |
+------------+        +------------+        | name       |
                                            +------------+
```

## ハマった内容
通常はPostからTag（その逆も）を参照できるように以下のようなリレーションを定義すると思います。

```ruby
class Post < ApplicationRecord
  has_many :post_tags
  has_many :tags, through: :post_tags
end
```
```ruby
class PostTag < ApplicationRecord
  belongs_to :post
  belongs_to :tag
end
```
```ruby
class Tag < ApplicationRecord
  has_many :post_tags
  has_many :posts, through: :post_tags
end
```

この際、上記のような記述順ではうまくいきますが、Postモデル、Tagモデルの`has_many`の順番が逆の場合は、上記の環境ではうまくいきませんでした。

```ruby
class Post < ApplicationRecord
  has_many :tags, through: :post_tags
  has_many :post_tags
end
```
多対多で検索すると下記のような順番で記述している例もたくさんあるのですが、Rails5になって厳しくなったんでしょうかね。
`ActiveRecord::HasManyThroughOrderError`エラーが出てしまうようです。

```ruby
[1] pry(main)> Post.find(1).tags
  Post Load (0.4ms)  SELECT  `posts`.* FROM `posts` WHERE `posts`.`id` = 1 LIMIT 1
ActiveRecord::HasManyThroughOrderError: Cannot have a has_many :through association 'Post#tags' which goes through 'Post#post_tags' before the through association is defined.
from /mnt/e/Development/gunplus/vendor/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/reflection.rb:943:in `check_validity!'
```
VsVimでINSERTモード中にカーソル移動できるようにする

Visual Studio上でVimで操作できるアドオン「VsVim」でINSERTモード中にカーソル移動できる方法の紹介です

```
C:\Users\ユーザー名\_vimrc
```
%userprofile直下に新しく_vimrc設定ファイルを作成する

```vim:_vimrc
inoremap <C-j> <Down>
inoremap <C-k> <Up>
inoremap <C-h> <Left>
inoremap <C-l> <Right>
```
_vimrcにカーソル設定を記述。Ctrl+ノーマルモードの移動キーにしています。

###Ctrlが効かない場合
Visual Studioのキーバインド設定が優先されるので、解除します。
メインメニューのツール➞オプションから左メニューの環境ー➞キーボードから割り当てを設定します。

<img width="535" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109300/1955de50-95b1-0c83-b71e-c7ff9bd775fd.png">

下の「ショートカットキー(P)」の下の欄でショートカットキーを入力すると現在使用されているショートカットが出力されます。
削除したいショートカットを「以下の文字列を含むコマンドを表示」の下の欄で検索し、該当するものを削除すればキーバインド設定を解除できます。

###参考

https://qiita.com/Shaula/items/0264fe6fb436f2525702
https://qiita.com/zimathon/items/d02e587466dbdc90c9d3
https://qiita.com/suin/items/aec243abfda17bfac013
https://qiita.com/motty93/items/12dc20a7a5385a17063f#_reference-ffd76f09cd5abe767a16
stack new叩いたらすぐhspecが使えるようにする

# はじめに

最近趣味でHaskellを書いています。
新しい言語を勉強をする時に、[TDDBC](http://devtesting.jp/tddbc/)で使われるお題（セマンティック・バージョニングなど）を利用することが多いのですが、HaskellでもHspecを使って書いています。

ただ、毎回`stack new`をしてpackage.yamlなどを書き換えるのも若干面倒だったので、
`stack new`したらHspecが設定済みのプロジェクトが作れるように、今回設定をしていきます。

####  2019/05/06追記

コメント欄でご指摘頂きましたが、
[標準のテンプレート集](https://github.com/commercialhaskell/stack-templates)に[hspec](https://github.com/commercialhaskell/stack-templates/blob/master/hspec.hsfiles)が用意されているようです。

hspecが設定済みのプロジェクトを使うのであれば、stack new のテンプレート名に`hspec`を指定して実行すれば使えます。

```shell
$ stack new プロジェクト名 hspec
```

# 前提

- stackがインストールされていること
- `$ stack install hspec-discover` で hspec-discover入れていること


# 手順

`stack new`のデフォルトテンプレートを開きます。

```shell
$ cd ~/.stack/templates/
$ vi new-template.hsfiles
```

テンプレートファイルを編集します。

```diff:new-template.hsfiles
tests:
  {{name}}-test:
    main:                Spec.hs
    source-dirs:         test
    ghc-options:
    - -threaded
    - -rtsopts
    - -with-rtsopts=-N
    dependencies:
    - {{name}}
+   - hspec  


{-# START_FILE test/Spec.hs #-}
- main :: IO ()
- main = putStrLn "Test suite not yet implemented"
+ {-# OPTIONS_GHC -F -pgmF hspec-discover #-}


+ {-# START_FILE test/LibSpec.hs #-}
+ module LibSpec (spec) where

+ import Test.Hspec
+ import Lib

+ spec :: Spec 
+ spec = do 
+    describe "テストケース" $ do 
+        it "somefuncが返ってくること" $ do
+            someFunc `shouldBe` "someFunc"

{-# START_FILE src/Lib.hs #-}
module Lib
    ( someFunc
    ) where

- someFunc :: String
+ someFunc :: IO ()
- someFunc = "someFunc"
+ someFunc = putStrLn "someFunc" 

{-# START_FILE app/Main.hs #-}
module Main where

import Lib

main :: IO ()
- main = someFunc
+ main = return ()


```

`{-# START_FILE ファイル名 #-}`で、プロジェクトを作ったときのデフォルトで作られるファイルと、その中身を設定することができます。

新規作成したらすぐテストが試せるように、デフォルトのファイルの中身を書き換えています。


テンプレートファイルを書き換えたあとは、実際にそのとおりにプロジェクトが出来たか試してみます。
問題がなければ以下のようにデフォルトで作ったテストが通ると思います。

```shell
$ stack new example
$ cd example
$ stack test

Progress 1/2: example-0.1.0.0
Lib
  テストケース
    somefuncが返ってくること

Finished in 0.0002 seconds
1 example, 0 failures

```

これで次回から、すぐテストができるプロジェクトが作成できるようになりました。
上記の説明だと、デフォルトのテンプレートを変更しましたが、
デフォルトを変更するのに抵抗がある人は、`~/.stack/templates/`に新しいテンプレートを作成しておき、`stack new`するときに指定をすればテンプレートの使い分けができます。

```shell
$ cd ~/.stack/templates/
$ cp new-template.hsfiles my-template.hsfiles

# なにかしらテンプレート編集したあと、任意のフォルダで下記を実行
$ stack new exampleProject my-template.hsfiles

```

# おまけ

`stack new`で作ったプロジェクトは当然ですがgitリポジトリではありません。
git管理する場合にはプロジェクト作成後に自分で`git init`コマンドを叩く必要があります。

作ったプロジェクトを自動的にgitリポジトリにしたい場合は、config.yamlを設定します。

```shell
$ vi ~/.stack/config.yaml
```

```yaml:config.yaml
templates:
  scm-init: git # 追加
```

この設定をしておくと、次回から`stack new`したときに、`git init`が自動的にされています。


以上です。
Pythonを使ってzipファイルからファイルを取り出す

#はじめに
Pythonのプログラム中でzipファイルからファイルを取り出したいことがあります。
この目的のためには、zipfileモジュールを使うことになります。そこで、簡単にzipfileモジュールの使い方をまとめてみました。Mac上のpython 3.6.8で動作を確認してあります。

#zipファイルからのファイルの抽出
zipfileモジュールを利用したいので、当然zipfileモジュールをimportします。
```
import zipfile
``` 
ZipFileオブジェクトを通して、zipファイルにアクセスすることになります。
例えば、zipファイルに含まれているファイルリストの取得、ファイルの取り出しなどができます。
プログラムを終了する前にcloseを呼び出さないといけないので、この面倒を避けるためにwith文を利用しています。

```
import zipfile

# zipファイルに含まれているファイル名の取得
with zipfile.ZipFile(zipファイル名) as myzip:
    print(myzip.filename) # zipファイル名の表示
    myzip.printdir()      # zipファイルに含まれているファイル名をsys.stdoutに出力

with zipfile.ZipFile(zipファイル名) as myzip:
    for f in myzip.namelist(): #zipファイルに含まれているファイルのリストを返す
        print(f)

# zipファイルに含まれているファイルの取り出す
with zipfile.ZipFile(zipファイル名) as myzip:
    myzip.extractall()    # zipファイルに含まれているファイルを全て取り出す

# zipファイルからファイル名を指定して取り出す
with zipfile.ZipFile(zipファイル名) as myzip:
    myzip.extract(ファイル名)    # zipファイルに含まれているファイルを取り出す

# zipファイルからファイル名を指定して取り出す（パスワード付きの場合）
with zipfile.ZipFile(zipファイル名) as myzip:
    myzip.extract(ファイル名, pwd="パスワード")    # zipファイルに含まれているファイルを取り出す
```

|           | 内容  |
|-----------|----------------|
|  filename |zipファイル名を保持|
| printdir() | zipファイルに含まれているファイル名をsys.stdoutに出力|
|namelist()|zipファイルに含まれているファイルのリストを返す|
|extractall() |zipファイルに含まれているファイルを全て取り出す|
|extract(ファイル名)|zipファイルからファイル名を指定して取り出す|

もしパスワードがかかっているzipファイルの場合には、extractなどの引数にpwdキーワードでパスワードを指定します。

# zipファイルに含まれるテキストファイルの処理
extractなどを利用するとzipファイルからファイルを取り出すことができます。
いちいちファイルを保存してから処理をすることが面倒な場合もあります。そこでopenを利用すると、ファイルを保存することなく処理を行うことができます。

```
import zipfile

# zipファイルに含まれているテキストファイルの読み込み
with zipfile.ZipFile(zipファイル名) as myzip:
    with myzip.open(処理をしたいファイル名) as myfile: # openを利用してファイルにアクセス
        print(myfile.read())  # この場合はreadで読み込みを行った
```

|         | 内容  |
|---------|----------------|
|  open() |ZipExtFileを返す。これを利用してファイルのように処理ができる|

# zipファイルに含まれる画像ファイル（バイナリファイル）の処理
画像ファイルのようなバイナリファイルを扱う場合は、ioモジュールも利用します。
下の例では画像ファイルの処理のためにPILモジュール(Pillow)を使用しています。
ここで利用しているio.ByteIOはメモリ上でバイナリデータを扱うための機能を提供しています。

```
import zipfile
import io
from PIL import Image

    with zipfile.ZipFile(zipファイル名) as myzip:
        with myzip.open(処理をしたいファイル名) as img_file:
            img_bin = io.BytesIO(img_file.read())  # メモリ上のデータを読み込む
            img = Image.open(img_bin) #読み込んだバイトストリームを利用して画像ファイルを生成
            
```

実のこのサンプルを少し変更することで、ネット上にある画像フィアルをファイルとして保存することなく処理をすることができます。こんな感じになります。

```
import io
from PIL import Image
import urllib.request

img_read = urllib.request.urlopen(url).read() # urlで指定され得た画像データを取得
img_bin = io.BytesIO(img_read)  # メモリ上のデータを読み込む
img = Image.open(img_bin) #読み込んだバイトストリームを利用して画像ファイルを生成
```

# おわりに
pythonを利用してzipファイルからファイルを取り出す方法に関してまとめてみました。ついでに、一旦ファイルとして保存することなく処理をする方法のサンプルを載せてみました。
React Nativeで複数のstyleを適用する

私があたったユースケース的には
「H3のText用Styleと、リンクを有効化したっぽいStyleを２つ適用したい」
でした。

一言で言うと「 `style={}` には配列で複数のスタイルを渡すことができる」です。

このようにします。

```typescript:App.tsx
<Text style={[styles.textH3, styles.textLink]}>ほげほげ</Text>

//...
const styles = StyleSheet.create({
  textH3: {
    paddingTop: 10,
    paddingBottom: 10,
    fontSize: 20,
    fontWeight: 'bold',
  },
  textLink: {
    color: 'blue'
  }
});
```

思っていたより簡単でした！

## ちなみに（ちょっと注意点）
パラメータは後勝ちのようです。
上記の場合、例えばtextLinkに `fontSize: 5` を入力すると、文字サイズが小さくなってしまいます。
注意しましょう！
PowerShell の Select-String で Grep っぽく強調表示する

PowerShell はオブジェクトを扱えるので、Grep のように正規表現マッチで String の検索を行うことは多くないものの、たまーーにコンソール出力内容の検索したくなることがあり、ハイライトしてくれればいいのにとずっと思っていたので方法をメモ。

環境は PowerShell Core 6.2。

## 結果から

### Before 

![before1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59544/ddab901c-d259-7291-d0bc-32558fb5a6bf.png)


### After

![after2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59544/0af7fd55-a00b-d849-c15c-0293f6ee121e.png)

Yay！


## 参考にしたスクリプト

以下の 2 つのスクリプトを参考にしました。多謝。

- [Davlind/PSColor: Provides simple color highlighting for some PowerShell output](https://github.com/Davlind/PSColor)

Get-ChildItem や Select-String の表示形式を変更するモジュール。ただし。正規表現マッチ部をハイライトする機能はない。

- [Out-Defaultをフックしてパイプラインに渡されたオブジェクトの型と値をホストに表示するサンプル](https://gist.github.com/stknohg/a0fabb9e10ddcc146672)

タイトル通り、PowerShell の既定出力である Out-Default をフックするサンプル。

## Profile.ps1

以下のコードを Profile.ps1 に書けば実現できます。

```powershell
function MatchInfo {
    param (
        [Parameter(Mandatory = $True, Position = 1)]
        $match
    )
    # 色の設定
    $PSColor = @{
        Default     = 'White' 
        Path        = 'Cyan' 
        LineNumber  = 'Yellow'
        Line        = 'White' 
        MatchedText = 'Red' 
        BackGround  = 'White'
    }

    # 行数表示
    Write-host $match.LineNumber -foregroundcolor $PSColor.LineNumber -noNewLine
    Write-host ":`t" -foregroundcolor $PSColor.Default -noNewLine

    # 該当行をマッチしたテキストで Split し、色を変えて出力
    $ParsedText = $match.Line -split $match.pattern
    Write-host $ParsedText[0] -foregroundcolor $PSColor.Line -noNewLine
    for ($i = 1; $i -lt $ParsedText.length; $i += 1) {
        Write-host $match.matches[0].value -foregroundcolor $PSColor.MatchedText -noNewLine
        Write-host $ParsedText[$i] -foregroundcolor $PSColor.Line -noNewLine
    }
    Write-Host
}


function Out-Default {
    [CmdletBinding(ConfirmImpact = "Medium")]
    param
    (
        [Parameter(ValueFromPipeline = $true)]
        [System.Management.Automation.PSObject] $InputObject
    )
    begin {
        $wrappedCmdlet = $ExecutionContext.InvokeCommand.GetCmdlet("Out-Default")
        $sb = { & $wrappedCmdlet @PSBoundParameters }
        $__sp = $sb.GetSteppablePipeline()
        $__sp.Begin($pscmdlet)
    }
    process {
        # 受け取ったオブジェクトが MatchInfo だった場合
        if ($_ -is [Microsoft.Powershell.Commands.MatchInfo]) {
            MatchInfo $_
        }
        # MatchInfo 以外ならパイプライン処理を続ける
        elseif (![string]::IsNullOrEmpty($_)) {
            $__sp.Process($_)
        }
    }
    end {
        $__sp.End()
    }
}
```
VSCode で 論文を書くための環境構築 (LaTeX)

# はじめに
普段 VSCode で開発していたら LaTeX も同じ環境でやりたくなりますよね．
実際に VSCode で LaTeX をするための環境構築について軽くまとめました．

# 手順

1．下記リンクで `VSCode` のインストーラをダウンロード．
指示に従ってインストール．
[Visual Studio Code](https://code.visualstudio.com/)

2．拡張機能タブから `LaTeX Workshop` を検索してインストールする．

```bash:拡張機能
LaTeX Workshop
james-yu.latex-workshop
James Yu
```

3．LaTeX を日本語対応するため，下記を `settings.json` に追加．
方法：ファイル -> 基本設定 -> 設定 -> settings.json で編集 をクリック．

```bash:settings.json
{
    "latex-workshop.latex.recipes": [{
        "name": "texify",
        "tools": [
          "platex",
          "dvipdfm",
        ]
    }],
    "latex-workshop.latex.tools": [{
        "name": "platex"
        "command": "platex",
        "args": [
          "-no-guess-input-enc",
          "-kanji=utf8",
          "-synctex",
          "-pdf",
          "-interaction=nonstopmode",
          "%DOC%.tex"
        ]
      },
      {
        "name": "dvipdfm",
        "command": "dvipdfm",
        "args": [
          "%DOC%.dvi"
        ]
      }
    ]
}
```
赤のうねうね線がでたら適宜カンマをつけて区切ること．

4．下記リンクで `abtexinst_X_XX.zip`をダウンロード．( X はバージョンを示す)
指示に従い，フルインストールすること．
[TeXインストーラ３](https://www.ms.u-tokyo.ac.jp/~abenori/soft/abtexinst.html)

5．適当に TeX ファイルを書いて，
`Build LaTeX project` をクリックするとコンパイル．
`View LaTeX PDF` をクリックすると Webブラウザ や VSCode のタブで生成した pdf が閲覧できる．

# 所感

VSCode で TeX やる一番のメリットは，使い慣れたエディタでサクッと書けるところにあると思います．
個人的に TeXworks は使い勝手が悪く感じ，操作も覚えないといけないので，初心者やプログラマーなら VSCode で書くことをおすすめします．