OmniAICreator/Qiita-1.07M huggingface dataset:
Ardublockでつくる利口なガジェット　テキスト


Arduinoでつくる利口なガジェット　テキスト
https://togetter.com/li/354192
を、Ardublockで作り直し。



# れんしゅう


![IMG_20190616_023601.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a1980d2a-c512-e24b-2309-e2d56f61cf90.jpeg)


![IMG_20190616_023537.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/31ccabf5-e3f2-4909-8d0e-5cdfcf9a210a.jpeg)


# ほんばん

さいしょに、Arduinoの5VとGNDにあかとくろのせんをつなげます。


![IMG_20190616_114112.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/e33176fa-dbc1-dd96-e875-cb95c7d6c706.jpeg)

LEDはむきがあります。あしのながいほうがプラスです。

いまはArduinoはつないでいますがぷろぐらむはつかっていません。


では、![IMG_20190616_114820.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/85be2e13-9e64-1f38-a1fe-2ecbd09dd5fd.jpeg)
2ばんぴんにしろいせんをつなぎ、ぷろぐらむでひからせます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/5572b6fc-0481-ae04-8e4e-4ab6ff5099b7.png)


つぎに、


D5は元々5Vになっているため、10kΩの抵抗を通してゼロレベルにしておきます。

SWオンで5VとD5が繋がるので、それを検出してLEDが光るようにしてみましょう。 

![IMG_20190616_120626.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/97a42b78-fb2a-aaba-584f-994cdd6d54aa.jpeg)


SWを押すとLEDが光るスケッチはこの通り。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/0ee4dbbb-633a-299a-e85c-4c5f9c00135a.png)

どんどん早くしてみましょう。



はやくしすぎるとめがおいつかなくなります。なみがはやくなるので、めでみえなくてもみみできくことができます。

あつでんスピーカー　をLEDのかわりにつなげてみます

![IMG_20190616_121307.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/1e0586f4-4bd9-0334-08e8-b7939455fb68.jpeg)

もっとはやくしてみましょう。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/0ee4dbbb-633a-299a-e85c-4c5f9c00135a.png)

１よりはやくするには？
マイクロびょうまつが使えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/4e7e755f-4888-802d-7187-c8589241e27e.png)

時定数を変えていろんな音を試してみましょう。
でも、いちいち２かしょをかえるのはめんどくさいですよね。へんすうをつかってみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d6e5af52-a032-8c1c-92c7-b48cdab05d57.png)

スイッチを押すと音が変わるようにしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/110d3532-b168-c5fc-2c89-fd072017c2b1.png)



段々音が高くなって最後に変な音になります。もしループの　まつ　ミリびょう(300)とあるのはスイッチのチャタリングという現象を防ぐためです。これがなければどうなるでしょうか。 



次にスピーカを元に戻し、スイッチを外して代わりに光センサであるCDSを取り付けます。

![IMG_20190616_133417.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c1512c6a-2f3c-14b9-5b75-988d65dec0a4.jpeg)
黄色の線を今度はA0につなげます。analogRead(0);の値をそのまま音の時定数にしてみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/5bb6d9e4-1b04-789e-dcf1-432973915a8a.png)

またLEDもONOFFしてみるにはどうしたらいいでしょうか？
 

人間の体は電気を通します。アルミホイルで作ったセンサに触って、タッチセンサになるのを確認してみましょう。
AmazonLinux(CentOS)に最新版Mavenのインストール手順 

# はじめに
AmazonLinux(CentOS)は、yumコマンドでインストールしたMavenがバージョンが古い(3.0.5、2019/06/16現在)ので、より新しいバージョンが必要の場合は、手動でインストールする必要があります。
今回は現時点最新版である3.6.1のインストール手順を紹介します。

# JDK8のインストール
  JDKがすでにインストールされている場合はスキップします。  

## インストール  
   OpenJDK8をインストールします。

  ```bash
  sudo -E yum install java-1.8.0-openjdk-devel -y
  java -version
  ```
## 環境変数設定
   環境変数にJAVA_HOMEを追加します。

  ```
  echo "JAVA_HOME=$(readlink -f /usr/bin/java | sed "s:bin/java::")" | sudo tee -a   /etc/profile
  source /etc/profile
```

# Mavenのインストール
## ダウンロード 
  Mavenをダウンロードして解凍します。

```
curl https://archive.apache.org/dist/maven/maven-3/3.6.1/binaries/apache-maven-3.6.1-bin.tar.gz | tar zxv
```

## Mavenの配置 
  配置フォルダを作成して配置します。まだ、今後簡単にバージョンを切り替えるため、/opt/maven/defaultのシンボリックリンクを作成します。

```
sudo mkdir /opt/maven
sudo mv apache-maven-3.6.1 /opt/maven/
sudo ln -s /opt/maven/apache-maven-3.6.1 /opt/maven/default
```

## PATH追加
  /opt/maven/default/binをPATH環境変数に追加して結果を確認します。

```
echo 'export PATH=$PATH:/opt/maven/default/bin' | sudo tee -a /etc/profile
source /etc/profile
mvn --version
```
問題がなければ、下記のような内容が出力されます。  

```
Apache Maven 3.6.1 (d66c9c0b3152b2e69ee9bac180bb8fcc8e6af555; 2019-04-04T19:00:29Z)
Maven home: /opt/maven/default
Java version: 1.8.0_201, vendor: Oracle Corporation, runtime: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.201.b09-0.amzn2.x86_64/jre
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "4.14.114-105.126.amzn2.x86_64", arch: "amd64", family: "unix"
```

# 参考資料

- [How to Install Apache Maven 3.5 on CentOS 7](https://www.vultr.com/docs/how-to-install-apache-maven-3-5-on-centos-7)
JavaScriptでtableタグを操作する

DOMのtable要素には、こんなメソッドがあるという豆知識

## 行操作

&lt;table&gt;から``<tr>``を取得・操作する

| 動作| プロパティ/メソッド | 戻り値 |
|:--:|:--:|:--:|
|&lt;tr&gt;を取得|rows|&lt;tr&gt;のHTMLコレクション|
|&lt;tr&gt;を追加|insertRow(index)|追加された&lt;tr&gt;|
|&lt;tr&gt;を削除|deleteRow(index)|-|

※index：追加時は省略可。最初は0から
## セル操作

&lt;tr&gt;から``<td>``を取得・操作する

| 動作 | プロパティ/メソッド | 戻り値 |
|:--:|:--:|:--:|
|&lt;td&gt;を取得|cells|&lt;td&gt;のHTMLコレクション|
|&lt;td&gt;を追加|insertCell(index)|追加された&lt;td&gt;|
|&lt;td&gt;を削除|deleteCell(index)|-|

※index：追加時は省略可。最初は0から
## 使用例

```js:全セルの内容を表示する
for(const tr of $table.rows){
    for(const td of tr.cells){
        console.log(td.textContent)
    }
}
```

```js:縦3×横2のテーブルを作成する
for(let y=0; y<3; y++){
    const tr = $table.insertRow()
    for(let x=0; x<2; x++){
        const td = tr.insertCell()
    }
}
```
```js:データからテーブルを構築する
const data = [
    [1, 2, "up", "Python", 15.42, "+3.56"],
    [2, 1, "down", "C", 14.59, "+2.03"],
    [3, 3, "", "Java", 12.40, "+1.96"],
    [4, 4, "", "C++", 10.17, "+2.81"],
    [5, 5, "", "C#", 5.59, "+0.45"],
]

for(const list of data){
    // <tbody>にもinsertRow()がある    
    $tbody.insertRow().innerHTML = list.map(v => `<td>${v}</td>`).join('')
}
```


```js:テーブルの行数・列数を取得する
//行数
$table.rows.length

//列数
$table.rows[0].cells.length

//自身のインデックス番号
td.cellIndex
```
AWS summit Tokyo 2019 参加レポート

6/12〜14にかけて開催されたAWS Summit Tokyo@幕張メッセに行ってきました。

この記事では、具体的な発表内容というより、初参加の私が行ってみて感じた、AWS Summitってこんな感じのイベントだよって内容をお伝えしています。



# イケイケドンドン！AWS
私は初めて参加したので、色々と驚かされることばかりでした。想像以上に大規模なイベントで、Amazonの勢いを感じました。

心のどこかで、これが日本企業だったらな〜なんて事を思ってしまいます（苦笑）


初日の基調講演へ参加しようと会場に行くと、30分前なのに長蛇の列。

まあ、なんとなく予想はしてましたけどね！


会場に入ると「ここはクラブですか？」と聞きたくなるような、アップテンポな音楽が流れる真っ暗なエリアへと案内されました。

基調講演はおしゃれなダンスから始まり、AWS Japan CEOの長崎さんによる1時間半のトーク・トーク・トーク。

これだけの情報量を紙も見ずに喋り続けるんだから、相当な量の練習をされたんでしょうね。

合間でゲストスピーカーによるAWS関連のスピーチもありましたが、製品紹介・ゆるいAWS導入例といった感じであまり参考にはならないように思いました。

一方で、長崎さんのスピーチでは、AWSの成長率、考え方、世の中の流れみたいなものが伝わってきて参加してよかったなと思わされました。

基調講演がおこなされた会場以外にも、セミナーエリアが8つほどあり、さらにスポンサー企業によるブースがたくさん。広い幕張メッセの会場を埋め尽くしてました。


止まらないクラウド化の流れとAWSの成長を肌で感じることになりました。



# AWSサービスありすぎ問題が解決

AWSを使っていく上で、正直サービスがありすぎで「なんじゃこりゃ」と思う部分が少なからずあった私。

他にもそういう方っているんじゃないでしょうか？

似たようなサービスありすぎだし、ちょっと用途が違うだけで別サービスになってるしで、何使えばいいのかわからん。困る！って感じていました。


でもそれは、AWSの考え方を理解することで、「なるほど」という気持ちに変わりました。

それは、「子供がブロックを組み合わせて遊ぶように」システムを作れる、というAWSの考え方でした。

小さいものを沢山組み合わせて、独自のシステムを大きく組み上げていけるように考えられていたんですね。

通りで、各社のシステム概要図なんかを見ていると、AWSサービスのロゴがあっちゃこっちゃに登場する、パズルゲームみたいなものばっかりだったのね。


# AWS Summitの出席者層

私は初めてAWS Summitに出席しましたが、スーツのサラリーマンが多くて驚きました！

てっきりガツガツとクラウドネイティブシステムを作りながら、AWS使いこなしているような人たちばかり集まっているかと思っていたので。そういう人たちってラフな格好で仕事してそうじゃない？（偏見）

ところが実際は、大企業の社員さんがメインと言った感じで、年齢層も結構高め。

とあるセッションで挙手制でアンケートを取っていたのですが、Web屋さん1割・大企業7割・ベンダー2割みたいな感じでした。

周りから聞こえてくる会話も、AWS初心者っぽい内容ばかりでしたね。

なので、イベントの内容もそういった層を狙っているようで、初心者向けのセッションがかなり多い印象を受けました。

実際、自分もAWSをこれから使い始める感じなので、これは嬉しい誤算でした。


# AWSサービスの違いを知るならもってこい

先ほども書きましたけど、AWSサービスって今は165個もリリースされているらしく、とにかく細分化されてて差異がわかりにくいんですよね。

AWSのHP見てても、「XXXを提供するフルマネージドサービスです」とか書いてあって、結局何ができるのか分からないものが多い。

フルマネージドってなんだよ！？ってモヤモヤするばかり。


AWSは無料枠が充実してるので、とりあえず触ってみてよ。っていうの、AWS側の気持ちなんでしょうが、企業に勤めるしがない社員には結構これがハードル高かったりするわけですよね。

試してみるには、会社の承諾受けなきゃならなかったり（しかも前例なし）、そもそも社内からは繋げなかったり、結局自宅の自分のPCで、自分のクレカで契約しなきゃだったりって感じで二の足を踏んでしまいがち。


AWS Summitだと、その辺りデモを見せながら進めてくれたり、各サービスの内容を具体例を使って教えてくれたり、サクッと概要がつかめちゃう！

なので、AWSサービスの違いについて、ざっくり理解したいぜって人には、下手にネットをウロウロするよりずっとおすすめですね。


# あれ？でも資料って全部ネットで公開されるよね？

そうなんです。

この資料、リアルタイムではありませんが、後々（多分、2週間後くらい）には、ネットでほとんど公開されるんですよ。

基調講演など、一部のプログラムは動画もついてます。

他にも、リアルタイムではストリーミング配信なんてのもやってました。


ってことはですよ？

ぶっちゃけ、AWS Summitに参加する意味なくないですか！？

わざわざ遠い幕張まで時間をかけて出かけて行って、メモを取りながら、狭いパイプ椅子にぎゅうぎゅうに詰め込まれることもなく、自宅で同じくらいの情報量が取れちゃうんですもん。


私、資料がほとんどWeb公開されるって、幕張行ってから知ったので、この部分ではだいぶ凹みました。まあ、一度くらいは現場の雰囲気を体験しておこうと思って、そのまま出席しましたが。


なので、もしもこれから参加される方は、以下の条件に当てはまる方だけでいいんじゃないかな、と個人的には思いますね。

- AWS Summitの雰囲気を感じたい
- AWS Summitでもらえるお土産類やお弁当が欲しい
- AWS Japanの人に色々質問したい
- スポンサー企業のブースを回って、コネクションを作りたい
- アフターパーティーでAWS好きの人と繋がりたい

私はこのリストのどれにも当てはまらないので、来年はリアルタイムストリーミングだけで十分かなと思っています。

今年の資料はまだ公開されていないので、去年のものを参考までに貼っておきますね。

- [AWS Summit Tokyo 2018資料一覧](https://aws.amazon.com/jp/summit2018-report/)



今年分も、一部資料のみ既にアップされてるみたいですね。

- [AWS Summit スタートアップ各社によるキーノート](https://aws.amazon.com/jp/blogs/startup/summit2019_day3_recap/)


# まとめ

完全なる個人的な主観になってしまいましたが、とりあえず初めての参加…疲れました！

面白い内容もいくつかあったので、いい経験や情報収集にはなりましたが、それ以上に体力持っていかれました。


とはいえ、今回参加することがなかったら、資料一覧が公開されていることすら見つけられたなかったと思うので、一回経験できて良かったです。

参加できなかったセッションで気になるものもあったので、資料が公開されたらそちらはチェックしようと思います。
Macにnodebrewを使って最新のNode.jsを入れる

# 概要

Macで、`nodebrew`を使ってNode.jsをインストールするための手順です。

「Mac nodebrew インストール」等で検索すると、
ページによってパスやコマンド、手順が若干違ったり、昔書かれた記事だったりで不安だったため、
2019年6月時点で一番スマートで簡単な手順をまとめます。

最後に、gistをシェルスクリプトとして実行する手順もあります。

また、ここではまっさらなMacにNodeをインストールするものとします。
すでにNodeがインストールされている場合は、先にアンインストールしてください。

# 手順

## nodebrewのインストール

公式の手順の通りに`nodebrew`をインストールします。

```console
$ curl -L git.io/nodebrew | perl - setup
```

## nodebrewで使うディレクトリの作成

よく`mkdir`で1個ずつディレクトリを作っている方がいますが、
`nodebrew`コマンドから作成できるので、こちらを使いましょう。

```console
$ nodebrew setup
```

## node実行用にパスを通す

`nodebrew`はそのまま動きますが、肝心の`Node`はパスを通さないといけません。

```console
$ echo "export PATH=$HOME/.nodebrew/current/bin:$PATH" >> ~/.bash_profile
```

zshの方はこちら

```console
$ echo "export PATH=$HOME/.nodebrew/current/bin:$PATH" >> ~/.zshrc
```

## bash_profileを読み直す

```console
$ source ~/.bash_profile
```

zshの方はこちら

```console
$ source ~/.zshrc
```

## Node最新版のインストール

`latest`で最新版、`stable`で安定版をインストールできます。
`install`ではなく`install-binary`でも良いようですが、簡単なので`install`で覚えましょう。

```console
$ nodebrew install latest
```

## 使うNodeの指定

インストールするだけでは使えないので、使いたいNodeのバージョンを指定します。
このコマンドで指定したバージョンのシンボリックリンクが、上でパスを通した`$HOME/.nodebrew/current`に貼られます。

```console
$ nodebrew use latest
```

これで`Node`が使えるようになっているはずです。

## 動作確認

2019/6/16時点での`latest`をインストールしています。

```console
$ node -v
v12.4.0
```

`npm`もちゃんと動くか試しましょう

```console
$ npm -v
6.9.0
```

## gistにおいたシェルスクリプトからインストール

１つ１つコマンドをコピペして実行して〜は大変なので、
gistにシェルスクリプトとして用意しておいて、まとめて実行できるようにしましょう。

### gistを作る

以下のURLから新しいgistを作成します。
https://gist.github.com/

1. 適当なgist名をつける。
2. 適当なファイル名をつける。
3. シェルスクリプトとして上に書いた内容を入力する。

最後に、今回は非公開にする必要がないので、`Create public gist`をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212694/9318dac9-72c4-bc6a-3b04-b8ed7ff6443e.png)

### gistのURLを取得する

gistを開いて、ファイルのRAWボタンから、gistのファイルごとのURLを取得できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212694/a28bdb3d-f902-3ebc-97a6-04bac04ae38e.png)

### 実行する

`curl`でもってきて実行します。

bashの場合

```console
$ curl -sf https://gist.githubusercontent.com/ayatec/89e740247d5c956f078653933e3f3eb1/raw/ea2b15d08f5682aad51268974befe85e8614e77c/install_nodebrew_bash.sh | sh -s
```

zshの場合

```console
$ curl -sf https://gist.githubusercontent.com/ayatec/89e740247d5c956f078653933e3f3eb1/raw/ea2b15d08f5682aad51268974befe85e8614e77c/install_nodebrew_zsh.sh | sh -s
```

gistからシェルスクリプトを実行するのは結構便利なので、さらっと使えるようになっておきましょう。
Dockerのコンテナから抜ける in VSCode

Dockerのコンテナからコマンドを使用して抜けるには、2つの方法がある。

- `exit`

`exit`を実行すると、コンテナ自体が終了してしまう。

- デタッチする

Ctrlボタンを押しながら、Pキーを押して、その次にQキーを押すとデタッチすることができる。デタッチとは、起動しているコンテナに入る[`docker attach CONTAINER_ID `](https://qiita.com/voluntas/items/68c1fd04dd3d507d4083#docker-attach)の逆で、起動させたままコンテナから抜けることができる。

# VSCodeでやろうとすると、ショートカットが勝ってしまう

VSCodeのデフォルトでは、`Quick Open View`などが`Ctrl + Q`に指定されており、その状態だとデタッチができない。そのため、ショートカットを上書きする必要がある。

`Preferences => Keyboard Shortcuts`より、`ctrl q`で検索を書け、適当なコマンドに変える。

これで、コンテナから抜けられるようになった万歳

# 参考
[Dockerコンテナからのデタッチ](https://tech.withsin.net/2015/09/30/docker-container-detach/)
Unityで視線誘導のための矢印をつくる②

#はじめに
[前回](https://qiita.com/E-CAT/items/9e6c8b4253bac1cff909) （Unityで視線誘導のための矢印をつくる①）の続きです。

また、シェーダーは前回使用したものを使いまわしています。
※HTC VIVEを使って開発してます。

#完成イメージ
矢印が赤い玉の場所を知らせています。

前回と異なる点は、矢印が赤い玉の場所を、カメラから上下左右どの方向にあるかは示していますが、奥（カメラの前方）または手前（カメラの後方）にあるかは示していません。

HMDをで違いを確認すると、それぞれの場合でプレイヤーが受け取る印象は、結構違うと思います。
![20190616_DescriptionArrow2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285370/db0f4fe6-4cbf-2a43-3896-3e565ed894bf.gif)

#実装について
以下を考えました。

① 座標A（CameraのZ軸直線とtargetの垂線の足）に GameObject を作り、Transform.LookAt(target)で赤い玉の方向を向かせます。
② カメラ前方の矢印の向きは座標Aの向きと同じにします。

例1）
![DescriptionArrow_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285370/ee738f3a-f5ac-5063-d9e0-80fb7f809653.png)

例2）
![DescriptionArrow_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285370/0777c195-f57b-29fd-4368-daf8c2218c37.png)

例3）
![DescriptionArrow_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285370/3ff7bfe1-3c02-3ecd-fabc-9fe707b46581.png)

実装にあたり、[こちら](https://sleepygamersmemo.blogspot.com/2019/03/perpendicular-foot-point.html) のサイトを参考にさせていただきました。

#スクリプト
HTC VIVEの場合、Camera の子階層に配置した矢印に下記スクリプトをアタッチして、target を指定して使用します。

```
using UnityEngine;

public class MyLookAtTarget2 : MonoBehaviour {

    [SerializeField] private Transform target;

    private GameObject point_A;     // 座標A（CameraのZ軸直線とtargetの垂線の足）
    private GameObject vec_B;       // 座標A作成のための中間生成物

    private void Start()
    {
        vec_B = new GameObject("Vec_B");
        vec_B.transform.parent = this.gameObject.transform.parent.transform;
        vec_B.transform.localPosition = Vector3.forward * 100;

        point_A = new GameObject("Point_A");
    }

    void Update()
    {
        // 座標A（CameraのZ軸直線とtargetの垂線の足）を求める。
        point_A.transform.position = PerpendicularFootPoint(
            this.gameObject.transform.position,
            vec_B.transform.position,
            target.position
            );

        // 座標AのGameObjectがターゲットの方向を向く
        point_A.transform.LookAt(target);

        // 矢印の角度を座標Aの角度と同じに
        this.gameObject.transform.rotation = point_A.transform.rotation;
    }

    Vector3 PerpendicularFootPoint(Vector3 a, Vector3 b, Vector3 p)
    {
        return a + Vector3.Project(p - a, b - a);
    }
}
```

#おわりに
視線誘導の方法は、今回紹介したもの以外に様々あると思います。
プレイヤーにとってストレスを感じない方法を模索していきたいです。

[次回](https://qiita.com/E-CAT/items/ae1c61442c2d0a0c8bb3)：Unityで視線誘導のための矢印をつくる③
Unityで視線誘導のための矢印をつくる①

#はじめに

例えば、ゲームの作者がプレイヤーに対して
「左側にボタンあるよ！ そっち向いて！！！」
と思っていたとします。

私は思いました。
なのでディスプレイに矢印を表示してプレイヤーの見る方向を誘導したいと思います。
※HTC VIVEを使って開発してます。

#完成イメージ
矢印が赤い玉の場所を知らせています。
![20190616_DescriptionArrow1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285370/43a0b108-a11e-9c16-f4c5-fc54148ef493.gif)

#前準備
矢印の３Dモデルを用意します。
![arrow.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285370/8b4d3b41-34c3-ff22-1af6-6637fb5e56a6.jpeg)

#スクリプト
矢印に赤い玉の方向を向いてもらうスクリプトです。
Transform.LookAt は、「あるオブジェクトの方向を向いてほしい！」という時に便利です。

矢印に下記スクリプトをアタッチして、Unityエディタから矢印の向き先となる赤い玉を指定します。
HTC VIVEの場合、矢印を [Camera Rig] 内の Camera の子階層に配置して位置を調整します。

```
using UnityEngine;

public class MyLookAtTarget : MonoBehaviour {

    [SerializeField] private Transform target;

    void Update () 
    {
            this.gameObject.transform.LookAt(target);
    }
}
```

#シェーダー
カメラを動かしたとき、矢印の位置が床の奥にいったり、その他のオブジェクトの奥にいったとしても、矢印は常にカメラに表示されていてほしいです。

以下がそれを実現するシェーダーです。
シェーダー勉強中のため詳しくは語れません。コピペしたら使えるはずです。

（シェーダーで頑張らなくても、もう一台カメラを置いて、Culling Mask をいじってあげると同じようなことができるはずです。）

```
Shader "Costom/MyOverlayNoZTest" 
{
	Properties
	{
		_Color("Color", Color) = (1,1,1,1)
	}

	SubShader
	{
		Tags
		{
			"Queue" = "Overlay"
			"RenderType" = "Transparent"
		}

		Lighting Off
		ZTest Off

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			struct appdata {
				float4 vertex   : POSITION;
				fixed4 color    : COLOR;
			};

			struct v2f {
				float4 vertex   : SV_POSITION;
				fixed4 color    : COLOR;
			};

			fixed4 _Color;

			v2f vert(appdata IN) {
				v2f OUT;
				OUT.vertex = UnityObjectToClipPos(IN.vertex);
				OUT.color = _Color;
				return OUT;
			}

			fixed4 frag(v2f IN) : SV_Target
			{
				return _Color;
			}
			ENDCG
		}
	}
}
```
#おわりに
[次回](https://qiita.com/E-CAT/items/1afd3cc58a4a314c2483)：視線誘導のための矢印をつくる②
![20190616_DescriptionArrow2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285370/8a80c576-8b3d-5fc1-3566-4076fad7f0e7.gif)
Ajaxを分かりやすく解説！（用語解説と準備編）

個人的にAjaxを理解するのに苦労したため、備忘録も兼ねてなるべく簡潔にまとめました！

ご意見等ございましたらコメントお願いします:relieved:

ではさっそく初めていきます...

---

そもそも...

### Ajaxってなんぞや？
って疑問の方も多いと思うのでそこから説明していきます！！！

### Ajaxとは
Asynchronous JavaScript + XMLの略で、JavaScriptによる非同期通信を用いたプログラミングの手法のことを言います。

（ん、、、これだけ言われてもなんのこっちゃ。。。そもそも非同期って何、、、）:sweat_smile:

順序を追って詳しく説明していきます！

---

### 非同期通信とは
リクエストを投げた直後からブラウザ側での操作ができるような通信をいいます。
ユーザーがアクションを起こした際に、ページ全体を書き換えるのではなく、JavaScriptにサーバとの通信をさせ、ページの一部を書き換える。
つまり毎度毎度ページ全体が書き換えることがないので、通信中にもブラウザ上での操作ができ、ユーザビリティを高めることができます。


（ふむふむ、なんとなく分かったけども、具体的な例がほしい、、、）:frowning2:

###### ◯非同期通信を実装している有名なアプリケーションといえば、、、
### Twitter
Twitterのタイムラインでは、ツイートを投稿すると、ページ全体が書き換わるのではなく、ページ内の必要な部分（投稿した新しいツイートの分）だけが書き変わますよね？

まさにあれです！！！

（理解できました！）:relaxed:

反対用語として同期通信という言葉もあるからそちらもついでに理解しておきましょう！

---
### 同期通信とは
リクエストを投げ、サーバからの応答があるまでブラウザ側の表示が変化しないような通信です。サーバからの応答があるまで、ブラウザ側の処理が止まるため、その間ユーザーは処理を行うことができません。

###### ◯具体的な例を挙げるとしたら、webページの遷移のこと！

（ふむふむ、こちらはとても分かりやすい）:relaxed:

---

以上がAjaxに関する説明となります！！！

ごちゃごちゃ用語を説明するよりも実際に手を動かしながら学んでいった方が理解が深まると思うので、実装していきたいんですが、、、

Ajaxを実装するに当たって準備が必要なので、本編では準備と完成品の確認をしていきます！！！（本格的な実装は次編）

それではさっそくスタート！

---
### 完成品の確認
<img width="1015" alt="b07b7c4a5a06dd3da688bcd13c787ac9.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438981/36b956d2-0fa5-6f14-48b2-71679afe1188.png">

投稿フォームがあってそこに文字を記述して投稿ボタンを押すと上のタイムライン上に反映されるといったとても簡易的なアプリケーションとなっています！

##### ポイント
今回はAjaxを使った非同期通信が目的なので、投稿ボタンを押した時にページが再度読み込まれてからタイムライン上に反映されるのではなくて、ページの読み込みがない状態でタイムライン上に反映されれば完成です。

##### 非同期通信が行われているかの確認
<img width="37" alt="d3ce2622ea822c3a625a8e79b9364e5f.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438981/b823cd6e-380b-3f4a-4e56-a54efc8cb23a.png">

URLバーの左にあるこの記号に変化がない状態でタイムライン上に反映されれば非同期通信が実装されていることが確認できます。

---
### Ajaxを実装する上での準備
##### ➀jQueryをインストールする！

```gemfile
gem "jquery-rails"
```
Gemfileに追記したら、***bundle install***を忘れずに！！！
(これ忘れがち）

##### ➁jQueryを呼びための記述！

```javascript:application.js
//= require rails-ujs
//= require jquery ←追記
//= require activestorage
//= require turbolinks
//= require_tree .
```

・ポイント
　require_tree .より上に記述する！
　そうしないと反映されません...

---
以上でAjaxを実装するための準備は終了です！！！
（あっという間）

いよいよ次編から本格的な実装に入っていきたいと思います！！！
Arduino Leonardo をMacが認識しなくなった時の対処法

# Arduino Leonardoが認識されなくなった

- 環境
    - Arduino Leonardo
    - Arduino 1.8.9
    - macOS Mojave 10.14.5

- 症状
    - Arduino IDEの`Tools > Port`に接続したArduinoが表示されない

# 試したこと
- Arduino Leonardo本体のリセットボタンを押す
- Arduino IDEの再起動
- Macの再起動
- USBケーブルの交換

以上を試すも症状は解決せず。

# 解決方法
1. Arduino Leonardo本体のリセットボタンをダブルクリック
2. ボード上の"L"のLEDが点滅している間にからのスケッチを書き込む
kintoneで長文markdownを編集するために外部エディタと接続する

# はじめに
技術系の仕事では、製品のドキュメンテーションからメモ取りに至るまで、markdownの利用範囲が拡がってきています。そのため、そこで使われるサービス・製品ではmarkdownのサポートが進んでいますが、翻って業務系のサービス・製品を見渡すと、markdownの影も形もありません。

markdownで済む文書をWordや方眼紙Excelで作成させられるのは苦行でしかありませんし、修飾が無いと説明できない文章だからと言って添付ファイルを付けたく無いのです。
もちろん、10年来進歩のない、Webアプリのクソ雑魚「リッチテキスト」テキストエリアなど願い下げです。

# 動機
kintoneに於いても、標準機能としてはmarkdownのサポートはありません。
しかしながら、公式のTipsでも[Aceエディタの埋め込みかた](https://developer.kintone.io/hc/en-us/articles/360008175233-Embed-Code-Editors)や[markdownのレンダリング方法](https://developer.cybozu.io/hc/ja/articles/212117746-Marked-js%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E7%A4%BE%E5%86%85%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88%E3%82%92%E6%9B%B8%E3%81%8D%E3%82%84%E3%81%99%E3%81%8F%E3%81%97%E3%82%88%E3%81%86-)を紹介しており、数行の文章であれば、これらを活用して十分実用的なmarkdown編集・表示ができることが分かります。
しかし、編集対象が長文 (e.g. 議事録) となると、(画面の狭さゆえに)親画面とテキストエリアの両方のスクロールが発生したり、プレビュー表示の場所が確保できなかったりします。

いっそのこと、外部エディタで編集できれば苦労が無いのにと考えた次第です。

# 準備
エディタには、拙作の [mdne](https://www.npmjs.com/package/mdne) を使用します。
mdne自体は[carlo](https://github.com/GoogleChromeLabs/carlo)を使ったデスクトップアプリなのですが、ローカルファイルへのアクセス等以外はChromeで動作しているので、webでも動かすことができます。実際に[playground](https://shellyln.github.io/mdne/online.html)として動作しています。

このweb版の永続化処理部分をkintoneへのアクセスに置き換えれば良いわけです。

# 挫折
kintoneって REST APIあるし、 [OAuth2もβ版ながら機能提供されている](https://developer.cybozu.io/hc/ja/articles/360015955171-OAuth%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%81%AE%E4%BD%BF%E7%94%A8-%CE%B2-)し、余裕！
と思っていた時期もありました。甘かったのです。タピオカミルクティーくらい大甘でした。

> `Authorization Code Grant`のみに対応しています。

OAuth2には[複数のユースケースとそれぞれのシーケンス](https://www.buildinsider.net/enterprise/openid/oauth20)が定義されていますが、バックエンド・サーバーを持たないwebアプリケーションでは`Authorization Code Grant`を使うことができません。`client_secret`を安全に保持できないためです。

# 解決
kintoneの REST API は、実はセッション認証をサポートしており、cookieさえ渡すことができれば認証は通るのです。それには、エディタ・アプリ自体をkintoneのドメインで動作させる必要があります。
アプリのカスタマイズ機能で無理やりウィンドウ全体にdivを重ね、その上にレンダリングします。

# 完成

markdown項目を持つ画面です。
![kintone-md-edit-1a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185253/2876ab05-1611-faae-b9d1-42f1192d88a6.png)
先ほどの画面から`Edit`ボタンを押すと外部エディタが起動します。
2ペインでプレビューしながら編集できます。
`Ctrl+S` でkintoneに保存されます。
![kintone-md-edit-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185253/aba9e6f9-15c4-90a8-bdb6-40ced9185707.png)

履歴管理もできます。
![kintone-md-edit-1b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185253/f5021c1b-fc82-c15b-9785-f78a5a5c12f3.png)

印刷もOK
![kintone-md-edit-print-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185253/d486b069-3565-cdd4-c1ee-fb20aaf1c0af.png)
![kintone-md-edit-print-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185253/5ce8249d-5553-a8ad-b7dc-935bb8f4691d.png)

# さいごに

今回のコードは [mdne-for-kintone](https://github.com/shellyln/mdne-for-kintone) にあります。


# 参考文献
* [OAuth 2.0＆OpenID Connectユースケースと関連仕様まとめ](https://www.buildinsider.net/enterprise/openid/oauth20)
* [OAuthクライアントの使用（β）
](https://developer.cybozu.io/hc/ja/articles/360015955171-OAuth%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%81%AE%E4%BD%BF%E7%94%A8-%CE%B2-)
45日目、PythonでCSVを読みたいのに、`IndexError: list index out of range`になってしまう（解決！）

こちらの記事を参考に、途中まで順調にCSVを読んでいたのに、途中からエラー、エラー、エラー！

[PythonでCSVの読み書き](https://qiita.com/okadate/items/c36f4eb9506b358fb608)

何でだろう。
**ちゃんとしたCSV**のはずなのに。

###エラーを確認
```
$ python test1.py
Traceback (most recent call last):
  File "test1.py", line 20, in <module>
    print(row[5])
IndexError: list index out of range
```

```test1.py
import csv
csv_file = open("test.csv", "r")
f = csv.reader(csv_file)
for row in f:
	print(len(row),row[5])
```

CSVの説明書を読んでみたけどさっぱり何だかわからない。

###CSVを読むにはもう１つ`pandas`という方法があるらしい。
pandasを試してみます。

```test2.py
import pandas as pd
df = pd.read_csv('service.csv')
print(df)  
```

```
$ python test2.py
Traceback (most recent call last):
  File "test2.py", line 3, in <module>
    df = pd.read_csv('test.csv')
  File "/anaconda3/lib/python3.7/site-packages/pandas/io/parsers.py", line 678, in parser_f
    return _read(filepath_or_buffer, kwds)
  File "/anaconda3/lib/python3.7/site-packages/pandas/io/parsers.py", line 446, in _read
    data = parser.read(nrows)
  File "/anaconda3/lib/python3.7/site-packages/pandas/io/parsers.py", line 1036, in read
    ret = self._engine.read(nrows)
  File "/anaconda3/lib/python3.7/site-packages/pandas/io/parsers.py", line 1848, in read
    data = self._reader.read(nrows)
  File "pandas/_libs/parsers.pyx", line 876, in pandas._libs.parsers.TextReader.read
  File "pandas/_libs/parsers.pyx", line 891, in pandas._libs.parsers.TextReader._read_low_memory
  File "pandas/_libs/parsers.pyx", line 945, in pandas._libs.parsers.TextReader._read_rows
  File "pandas/_libs/parsers.pyx", line 932, in pandas._libs.parsers.TextReader._tokenize_rows
  File "pandas/_libs/parsers.pyx", line 2112, in pandas._libs.parsers.raise_parser_error
pandas.errors.ParserError: Error tokenizing data. C error: Expected 5 fields in line 69, saw 6
```

###カラム名を指定してみる
`pandas.errors.ParserError: Error tokenizing data. C error: Expected 5 fields in line 69, saw 6`で検索してみると、カラム名を指定するとよいというものがありました。

[<Python, pandas> 列が一定でないデータを読み込む時、、](http://nekoyukimmm.hatenablog.com/entry/2016/06/17/115408)

試してみます。

```test3.py
import pandas as pd
col_names = [1,2,3,4,5,6]
df = pd.read_csv('service.csv',names=col_names)
print(df)       # show all column
```
いい感じ！

```
$ python test3.py
0                                                    NaN
1                                                    NaN
2                                                    NaN
3                                                    NaN

(中略)

223                                                    5
224                                                    5
225                                                    5
```

出力できましたた！

###「NaN」ってなんだ？？？？

CSVをよくみると、ところどころ欠けているセルがありました。
**ちゃんとしたCSV**と思っていたら、エラーが込みで、エラーになっていたのでした。
うぅーん、めっちゃくちゃ遠回りして青い鳥が足元にいた感じ！

###CSVの形を整えて再度読ませみる。

オッケーでした！

#（解決）`IndexError: list index out of range`
これがでたらデータセットを確認するといいみたいです。
いやー大変でした。
（所要時間 ２時間）

###本日のドリル
Progate python 3 

関数、def、importについて。
じゃんけんゲームを作りました。
関数の作り方がわかりました。
この後、手元で作っているスクリプトを関数にして整理。
スッキリしました。
（27分）
ViewModel + DataBinding で文字数をカウント

## DataBinding サンプルの続編
[Kotlin DataBinding メモ](https://qiita.com/katafuchix/items/fcb78caee9232c2b07f0)
ここと同様にプロジェクトを作成し、ライブラリ＆クラスをロード。

## View 編集
テキスト入力欄と文字数を表示するTextViewを配置。双方向では@={vm.name}のように@の後ろに=をつける。

```activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools">
    <data>
        <variable name="viewModel" type="com.example.kotlindatabindingsample2.viewmodel.MainViewModel"/>
    </data>
    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            tools:context="com.example.kotlindatabindingsample2.MainActivity">
        <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@={viewModel.messageEditText}" />
        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@={viewModel.messageLength}" />
    </LinearLayout>
</layout>
```

## ViewMoel作成

```MainViewMoedl.kt
package com.example.kotlindatabindingsample2.viewmodel

import androidx.databinding.BaseObservable
import androidx.databinding.Bindable
import androidx.databinding.library.baseAdapters.BR

class MainViewModel: BaseObservable() {

    var messageEditText: String = ""
        set(value) {
            field = value
            notifyPropertyChanged(BR.messageLength)
        }

    @Bindable
    var messageLength: String = "0"
        get() = "${messageEditText.length}"
}
```
@Bindableをつけることにより、監視用の定数BR.<name>が生成されます。
呼び出し側へnotifyPropertyChanged(BR.<name>)を追加し、BR.<name>に対応するget()が呼ばれるようにします。
SwiftでいうComputed Propertyっぽく書ける。 notifyPropertyChangedメソッドは更新が通知する。
messageEditTextに値が入ったときに、そのことをmessageLengthへ通知する。

## MainActivity
viewModelセット。

```MainActivity.kt
package com.example.kotlindatabindingsample2

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import com.example.kotlindatabindingsample2.databinding.ActivityMainBinding
import com.example.kotlindatabindingsample2.viewmodel.MainViewModel

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val binding: ActivityMainBinding =
            DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
        binding.viewModel = MainViewModel()
    }
}

```

## 実行結果
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266239/215bfd2c-6cc6-e004-5f4e-448fa5513a78.jpeg" width="250">

[サンプルコード](https://github.com/katafuchix/KotlinDataBindingSample2)
Arduinoでステッピングモーター28BYJ-48を動かす

# 目的

Arduinoに、ステッピングモータを繋いで動かした際の記録です。
# 準備
Arduino Uno
[ステッピングモーター28BYJ-48](https://www.amazon.co.jp/4相5線-ステッピングモータ-ギアモーター-28BYJ-48-12V-DIY用/dp/B00HGZUFHA/ref=pd_lpo_vtph_421_tr_t_2?_encoding=UTF8&psc=1&refRID=CKWRJZ5T2PHKFAYHTFMR)

# 回路図

モータドライバのPIN1,2,3,4と、Arduinoピン4つを接続します。
今回は、Arduino側のピンは8,9,10,11を使用しています。
※他Webサイトに詳しい接続方法はたくさん載っていますので、ここでは詳しくは割愛

# コード
サンプルコードのStepper_SpeedControlを参考にしています。

```
#include <Stepper.h>

const int stepsPerRevolution = 200; 
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11); // initialize the stepper library on pins 8 through 11:

void setup() {
  Serial.begin(115200);
}

void loop() {
  int motorSpeed = 100;
  Serial.print("motorSpeed : "); Serial.println( motorSpeed );
  
  // set the motor speed:
  if (motorSpeed > 0) {
    myStepper.setSpeed(motorSpeed);

    // step 1/100 of a revolution:
    myStepper.step(stepsPerRevolution/100);
  }
}
```

# テスト
とりあえずモータが回転すればOKとしています。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">play stepping motor 28bjy-48 <a href="https://t.co/mLSKpSbjPR">pic.twitter.com/mLSKpSbjPR</a></p>&mdash; st (@st17890027) <a href="https://twitter.com/st17890027/status/1095543772987813889?ref_src=twsrc%5Etfw">2019年2月13日</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 


# 参考
・[組み込みエンジニアでなくても週末にArduinoを使って遊ぶ](https://qiita.com/seigot/items/958d3f2817a4bdac8754)
[Arduino と ステッピングモーター 28BYJ-48 使ってみた](http://dd647.blogspot.com/2016/02/arduino-5v-28byj-48.html)
[Stepperライブラリでモータを動かす　その1　1個だけ](https://www.denshi.club/cookbook/output/motor/stepping/stepper1.html)
sessionとcookieの違い

セッションとcookieの違いが理解できていなかったので自分用にまとめました。

## HTTPプロトコル
> HTTPはステートレスなプロトコルです。文字通り「ステート (state)」が「ない (less)」ので、HTTPのリクエストひとつひとつは、それより前のリクエストの情報をまったく利用できない、独立したトランザクションとして扱われます。

上記で書かれている通り、HTTPプロトコルは状態を維持できない、つまりリクエストを送ってレスポンスを受け取った時点で通信が終了します。
そのため、ログイン画面でログインしても記憶されないため、次の画面でログイン情報を引き継げません。

これ、すごくめんどくさい。。

じゃあ、記憶させればいいのだ。ということで、、、

## セッション
>セッションとは、ユーザーがwebサイトを表示して離脱するまでの一連の流れ。
30分間、何かしらのアクションがないとセッションは切れます。

セッションはサーバー側に情報を持たせる仕組み。
なので、ログインして次の画面にログイン情報を引き継ぐことができます。
しかし、ブラウザを閉じたり、ある程度何もせずに時間を置くと、セッションは切れます。

記憶はできたけど、高頻度で使用するサイトで毎回毎回ログインをさせられるのはめんどくさい。。。


じゃあクライアント側に持たせて、ブラウザが閉じても状態を維持できるようにすればいいんじゃね？

##Cookie
>CookieとはwebサイトからスマホやPCの中にデータを保存させる仕組み。
次回以降にCookie発行元のWebサイトを訪れた際に前回の続きのページを表示できます。

Cookieはクライアント側に情報を保持させる仕組み。
なので、ブラウザを閉じても状態を維持できます。

↑ということはsessionいらなくね？となりそうですが問題があります。



**Cookieはクライアント側に保存する。**


つまり、クライアント側で変更可能なので、改ざんできてしまいます。

セッションはサーバー側に保存されるため、安全性が高いが、ブラウザを閉じたら、情報は破棄される。Cookieはブラウザを維持できるが、データの改ざんができるため、安全とは言えない。。。

どうしたらいいのだ。。

##解決策
組み合わせればいいのだ。
セッションのIDをCookieに持たせればいい。
CookieにsessionIDを持たせれば、セッション側が持つ情報と照らし合わせることで情報保持が可能になります。
さらに、クライアント側はsessionIDを改ざんできてもサーバー側のデータは改ざんできないので、安全。

これで安全な通信が可能になる訳です。


うまくまとめるの難しいけど整理はできたかな。
勉学励みます。。

##参考文献
[セッションとクッキーの違い](http://ohs30359.hatenablog.com/entry/2015/09/04/235027)
[今さら聞けないセッションとCookie、ログイン・ログアウト(Rails編)](https://qiita.com/SpicyCoffee/items/de9de9a5427adf81817a)
【Vue.js】スタイルのバインディング

#はじめに
最近Vue.jsの勉強をしています。
現場で作られているソースは見てはいるものの、理解せずに改修しちゃうのは、ないなと
思って初級編からではありますが勉強していこうと思います。

#今回のお題
スタイルのデータバインディングです。
何かのアクションをしたときに、特定の色を変更したり、場所を移動させたりすることがあると思います。
これは、ユーザがアクションを起こしたことでアクションしたことが反映されましたよーと教えるには
良い方法です。

# できたもの
ボタンを押すことで、「選択した位置はここです。」の文字が移動します。

<img width="646" alt="skitch.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154145/08681c9d-065f-fb50-eec5-f067a09fbd35.png">

# ソース
今回は、ボタンを押したときに文字の位置を変更するプログラムです。
まずは、htmlを記載します。
スタイルは、v-bindを使って操作可能です。


```style02.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8" />
    <title>スタイルテスト</title>
</head>

<body>
    <div id="app">
        <div>
            <button @click="setPosition('left')">左</button>
            <button @click="setPosition('center')">真ん中</button>
            <button @click="setPosition('right')">右</button>
            <p v-bind:style="styleObject">{{msg1}}</p>
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
    <script src="./style02.js"></script>
</body>

</html>
```

上記の

```
<p v-bind:style="styleObject">{{msg1}}</p>
```

部分は、
＜div v-bind:style="{ color: activeColor, fontSize: fontSize・・・・＞　のように直接記述することも可能みたいですが、オブジェクトとして置き換えた方が綺麗になります。



```style02.js

var app = new Vue({
    el: '#app',
    data: {
        styleObject: {
            color: 'red',
            textAlign: 'center',
            fontSize: '13px',
            background: 'black'
        },
        msg1: '選択した位置はここです。'
    },
    methods: {
        setPosition : function(position) {
            this.styleObject.textAlign = position;
        }
    }
});
```

#まとめ
VueインスタンスとHTMLのテンプレート構文に記述した値がバインドされる。
データ変更とともにDOMツリーに即座に反映し、画面描画されるあたりが凄いですね。
リアクティブシステムなフレームワークって凄いなと実感します。
OpenEXR画像ファイルをpythonで読みこむ

仕事で扱うことになった画像データが見慣れない拡張子「.exr」のファイルだったのでなんだろうと思ったらHDR用の画像フォーマットであるopenEXR形式でした。openCVのcv2.imread()で読んでみたところfloatの値が整数で取得されちゃって上手くいきませんでしたので、OpenEXRパッケージを使って読み込みました。なお、以下のOpenEXRのドキュメントにあったコードをベースにやってます。

OpenEXR packageのドキュメント
https://excamera.com/articles/26/doc/intro.html

## 試行環境
Windows10
python 3.6

## 読み込み手順

まず、OpenEXRをインストールします。pipで簡単に入ります。

```terminal:terminal
pip install OpenEXR
```
Windows環境の人はpipで入らなかったりするので、その時は私的ビルドバイナリを使うと入るかも
https://www.lfd.uci.edu/~gohlke/pythonlibs/#openexr

画像を読んできて表示します。

```python:python
import numpy as np
import matplotlib.pyplot as plt
import OpenEXR, Imath, array

filePath = 'hoge.exr'

# ファイルを読み込む
pt = Imath.PixelType(Imath.PixelType.FLOAT)
img_exr = OpenEXR.InputFile(filePath)

# 読んだEXRファイルからRGBの値を取り出し
r_str, g_str, b_str = img_exr.channels('RGB', pt)
red = np.array(array.array('f', r_str))
green = np.array(array.array('f', g_str))
blue = np.array(array.array('f', b_str))

# 画像サイズを取得
dw = img_exr.header()['dataWindow']
size = (dw.max.x - dw.min.x + 1, dw.max.y - dw.min.y + 1)
print(size)

# openCVで使えるように並べ替え
img = np.array([[r, g, b] for r, g, b in zip(red, green, blue)])
img = img.reshape(size[1], size[0], 3)

# 画像を表示
plt.figure(dpi=300)
plt.imshow(img)
plt.show()
```

なんだか回りくどい読み方だなと思うんですが、ほぼ公式のサンプルコードそのままなのでこれで良いようです。僕の用途もそれほどスピードを求められないのでこれで問題ない筈ですが、速さを求められる用途だとarrayで一旦変換するなんてのは無駄に思えちゃいますよね。
https://excamera.com/articles/26/doc/openexr.html

えんじょい
firstResponderのviewを取得するextension

# firstResponderのviewを取得するextension

```swift

extesion UIViewController //あるいは UIView {
   func getFirstResponder(view: UIView) -> UIView? {
        if view.isFirstResponder {
            return view
        }
        return view.subviews.lazy.compactMap {
            return self.getFirstResponder(view: $0)
        }.first
    }
}

```

# 使いかた
```swift
getFirstResponder(view: self.view)?.resignFirstResponder()
```

# 参考
【Swift】firstResponderを取得する
https://qiita.com/wai21/items/edb795dc783ef779d642
クエリを書かずにBigQueryを操作したい

最近非エンジニアからの依頼でSQLを書いたりBigQuery上のデータを検索するツールを保守したりすることが多い。
頼まれた要件を満たすSQL書いて一番最初にその答えを見れるので知的好奇心が満たされるから仕事自体は楽しいのだけど分析するSQLには似通ったパターンが存在することがわかってきたのでこの辺を自動化したいなと思い始めた。

そこで表題のツールを作ろうと思い至ったのであった。


## 開発のゴール
目下の目標は自分がSQLを書くとき楽ができるようになることだが非エンジニアの人たち(運営さんとか)が簡単にSQLを使えるようになることが最大の目標だ。
(BigQueryの検索容量を減らすためにWHERE句に `_PARTITIONDATE`を書いたりUTCとJSTのことを考えながらクエリを書くのは御免こうむりたい。)
することもあるし...(´・ω・｀)

なので機能的には以下のものが要求される

- [ ] テーブルを指定して抽出条件を選択すると自動的にクエリが出力される
  - [ ] 日付はカレンダー、真偽値はチェックボックスなどフォームは動的に生成されてほしい
- [ ] 生成したクエリを自作ツールから実行できるようにしたい
- [ ] 実行するクエリがどの程度の容量を消費するのか確認したい
  - [ ] あまりに思いクエリは実行前に警告を出すなどの対策を組み込む

ついでに↓も対応したい

- [ ] 指定したdatasetに紐づくテーブル一覧とスキーマをまとめて取得したい
- [ ] 取得したテーブルに対して説明を追記できるようにする
- [ ] テーブルの説明やスキーマを検索できるようにしたい
- [ ] ツールはGKEで動かしたい


## Metabaseではだめなん？

先に要件をまとめたときこれってMetabaseじゃない？って思った。
実はMetabaseでも問題ないなって思ってるんだけど `実行するクエリがどの程度の容量を消費するのか確認したい`をMetabaseで見たことがなかったのとSQLを動的に生成するGemを書いたのでせっかくならこれを使いたいと思ったことが開発の動機だったりする


## どこまでできたん？

<img width="858" alt="スクリーンショット 2019-06-16 13.27.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189219/1b0b2e95-d554-66bb-faa4-3b1180eecba9.png">

* ↑初回アクセス時に環境変数に登録してあるdatasetに紐づくテーブルを自動的に取得してくれる様になった

<img width="1499" alt="スクリーンショット 2019-06-15 18.45.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189219/8487f8e3-f930-c523-1a5d-5775c609a909.png">

* ↑まだ自分でクエリを書く必要はあるものの実行時に必要な容量を動的出す機能とその結果を動的にテーブル表示してくれるところまでできた


なので
- [ ] テーブルを指定して抽出条件を選択すると自動的にクエリが出力される
  - [ ] 日付はカレンダー、真偽値はチェックボックスなどフォームは動的に生成されてほしい
- [x] 生成したクエリを自作ツールから実行できるようにしたい
- [x] 実行するクエリがどの程度の容量を消費するのか確認したい
  - [ ] あまりに思いクエリは実行前に警告を出すなどの対策を組み込む

ついでに↓も対応したい

- [x] 指定したdatasetに紐づくテーブル一覧とスキーマをまとめて取得したい
- [x] 取得したテーブルに対して説明を追記できるようにする
- [ ] テーブルの説明やスキーマを検索できるようにしたい
- [ ] ツールはGKEで動かしたい

部分的には出来てる


## ここまでやってみてどうだったか
土曜日は雨だったので1日使ってここまで作った。
さっさと完成させたい。
【Scalaで競技プログラミング】便利なコレクションメソッドメモ

最近、[会社](https://qiita.com/organizations/nextbeat) で **[Codility](https://app.codility.com/programmers/lessons/1-iterations/) をScalaで解く会**を毎週昼休みにやっています！
競技プログラミングっぽい問題をScalaで解くときに、個人的に便利だと感じたコレクションメソッドの使い方をまとめてみます！（毎回ググっているので…）

追記：2019/6/22　scanLeftが間違っていました。初期値で設定した値も結果のコレクションに入るのですが、そのようになっていませんでした。失礼しました。

# 【zipWithIndex】コレクションをforeachなどで走査する際に添え字も使って処理する
`zipWithIndex`を使う

```scala
val lst = List(3, 10, 1, 6, 9)
lst.zipWithIndex.foreach { v => // vは(要素, 添え字)のタプルになっている
  println(s"index: $v.2, value: $v._1")
}

lst.zipWithIndex.foreach { case (value, idx) => // こうやって書くと可読性高い
  println(s"index: $idx, value: $value")
}
```

```
index: 0, value: 3
index: 1, value: 10
index: 2, value: 1
index: 3, value: 6
index: 4, value: 9
```

# 【sorted, sortWith, sortBy】 Seqをソートする
## sorted
```scala
val lst = List(3, 10, 1, 6, 9)
// 暗黙のOrdering[Int]を引数としてソートされる
lst.sorted // List(1, 3, 6, 9, 10)
```

## sortWith
自分でソート用の関数を定義できる

``` scala
lst.sortWith((v1, v2) => v1 > v2) // List(10, 9, 6, 3, 1)
```

## sortBy
変換結果の値でソートする

```scala
val lst2 = List((3, 6), (10, 1), (1, 2), (6, 5), (9, 4))
// タプルのコレクションをソートするときに便利
lst2.sortBy(_.2) // List((10, 1), (1, 2), (9, 4), (6, 5), (3, 6))
```

# 【foldLeft, scanLeft】 たたみ込み
`foldLeft`はいつも引数の順番に混乱してしまう…
（累積値, コレクションの値）の順番！

## foldLeft
```scala
val lst = List(3, 10, 1, 6, 9)
// foldLeft
lst.foldLeft(0) { (acc, v) =>
  val newSum = acc + v
  println(newSum)
  newSum
}
```

```
3
13
14
20
29
```

## scanLeft
foldLeftした途中結果を格納したコレクションを返す。
✨累積和をシュッと書ける優れもの✨

```scala
val lst = List(3, 10, 1, 6, 9)
val accSum = lst.scanLeft(0)((v1, v2) => v1 + v2) // List(0, 3, 13, 24, 20, 29)
```

# 【sliding】 n要素ずつの部分列を見ながら走査する
`sliding(size, step)`で、stepずつずらしながらsize個ずつのコレクションを返すような**イテレータ**を得ることができる

```scala
// 隣り合う2要素の和を求める
val itr = List(3, 10, 1, 6, 9).sliding(2)
itr.foreach { slicedList =>
  println(slicedList.sum)
}
```

```
13
11
7
15
```

# 参考
https://www.scala-lang.org/api/current/
http://www.ne.jp/asahi/hishidama/home/tech/scala/collection/method.html

# TODO
Stack, Queue, Set, Map関連のメソッドとか、性能特性もまとめたい
TypeScriptの型は「構造的部分型」という種類らしい。

TypeScriptのクラスは「Structural Subtyping(構造的部分型)」という型の実装らしい。

- https://www.typescriptlang.org/docs/handbook/interfaces.html
 - ```
One of TypeScript’s core principles is that type checking focuses on the shape that values have. This is sometimes called “duck typing” or “structural subtyping”.
```

- [TypeScriptの型入門](https://qiita.com/uhyo/items/e2fdef2d3236b9bfe74a)
- [Typescript の Structural Subtyping](https://qiita.com/tell-k/items/1a93acbb42e39377cd48)

一方JavaとかSwiftでよく知ってるのは「Nominal Subtyping(公称的部分型？)」らしい

アバウトな理解

- Nominal Subtyping
 - 名前が重要
 - "Adult"や"Child"は、"Human"を継承している
  - "Human"を継承しているものしか、"Human"の所には入れられない
  - JavaやSwiftで見慣れたのはこっち
- Structural Subtyping
  - 構造が重要
  - "Adult"や"Child"は、"Human"の構造(brain()やbody())が実装されている
  - "Human"と同じ構造ならば"Human"の所に入る。
  - だから、同じ構造をしたObjectを放り込んでもおっけー。

```typescript

  interface Human {
    brain(): string;
    body(): string;
  }

  class Adult implements Human {
    private me = "大人";
    body = () => this.me;
    brain = () => this.me;
  }

  class Child implements Human {
    private me = "子供";
    body = () => this.me;
    brain = () => this.me;
  }

  function cry(one: Human): string {
    return "見た目は" + one.body() + "、頭脳は" + one.brain();
  }

  const adult = new Adult();
  const child = new Child();
  console.log(cry(adult)); // 見た目は大人、頭脳は大人
  console.log(cry(child)); // 見た目は子供、頭脳は子供

  const chimera = {      // ←Interfaceを継承していない、ただのオブジェクト
    brain: () => "大人",
    body: () => "子供",
    age: () => 1000
  };
  console.log(cry(chimera)); // ←これが通る
```
https://gist.github.com/taktamur/52e4faaf4de9b1f104873976129d959e
UWP Tips - IP over USB Transport serviceのエラー

#概要
Custom VisionのUWPサンプルアプリを動かしてみようと思ったらエラーが出たので、
その対処法についての備忘録


#エラーの内容
こんな感じの内容

```
SmartDeviceException - The IP over USB Transport service (IpOverUsbSvc) is not available. Retry after installing the IP over USB Transport service (Windows IP Over USB) through the Windows SDK installer.

```
Windows Ip over USB？
そんなサービスは見当たらない・・・。
検索してみると、正確には「Windows Phone IP over USB Transport Service」が
必要とのこと。


#実施したこと
Visual Studio Installerから、以下のコンポーネントを追加。

![IPoverUSB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/ab533c6b-972d-89dc-69e6-963a03204bda.png)

これ以外にもエラーが出たのですが、それはまた別の機会に・・・。
Golangの「<<」「>>」について

「A Tour of Go」というチュートリアルサイトを進めていくうちに、下記のように`<<`という知らない記述方法が出てきたので調べました。

```basic-types.go
MaxInt uint64 = 1<<64 - 1

fmt.Printf("Value: %v", MaxInt)
```
※「A Tour of Go」の**Basic types**（11/17） から抜粋

## `<<`や`>>`の意味
`<<`や`>>`は**「ビット演算子」**と呼ばれるものです。
**「ビット演算子」**を使うことで、数値を2進数で表記したときに`<<`は左へ、`>>`は右へとずらすことができます。

### `1<<64 - 1`の計算結果
`1<<64`は、2進数として`1`を左に`64`ずらすことになります。
そして、`1`を左に`64`ずらした値を2進数から１０進数に変換して`-1`を計算した結果、`MaxInt`は`18446744073709551615`という値で出力されることになります。

```go
Value: 18446744073709551615
```

## 参考にさせてもらった記事
[Go言語、「>>」の意味。 - teratail](https://teratail.com/questions/18602 "Go言語、「>>」の意味。")
Docker で CentOS6-i386 (32bit版CentOS6) のイメージを使う

仕事で急遽 32bit版の `CentOS6` が必要になったのでメモ

# Docker Hub からイメージを pull する

```
$ docker pull i386/centos:6
```
- CentOS の公式ビルドから作られたイメージ
- こちらでサポートされている  
[GitHub - CentOS/sig-cloud-instance-images: CentOS cloud images](https://github.com/CentOS/sig-cloud-instance-images)

# 動作確認

```
$ docker run -it --rm i386/centos:6 /bin/bash

[root@dcf50c6c410b /]# cat /etc/redhat-release
CentOS release 6.10 (Final)

[root@dcf50c6c410b /]# date
Sun Jun 16 03:31:41 UTC 2019

# DockerコンテナはホストOSのカーネルを使って動作するためマシンネームは x86_64 で表示される
[root@dcf50c6c410b /]# uname -a
Linux dcf50c6c410b 4.9.93-boot2docker #1 SMP Thu Jul 19 18:29:50 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

[root@dcf50c6c410b /]# uname -m
x86_64

# 実際は 32bit
[root@dcf50c6c410b /]# getconf LONG_BIT
32

# インストールされているパッケージは 32bit版だが、リポジトリの向き先が 64bit版になっている
# repo ファイルの $basearch の値が x86_64 になっているため
[root@dcf50c6c410b /]# yum list | grep '^rpm\.'
rpm.i686                                4.8.0-59.el6                @CentOS/6.10
rpm.x86_64                              4.8.0-59.el6                base

# 直接 32bit版のリポジトリを指定すると期待した動作となる
[root@dcf50c6c410b /]# sed -i 's/$basearch/i386/g' /etc/yum.repos.d/CentOS-*.repo
[root@dcf50c6c410b /]# yum clean all
Loaded plugins: fastestmirror, ovl
Cleaning repos: base extras updates
Cleaning up Everything
Cleaning up list of fastest mirrors
[root@dcf50c6c410b /]# yum list | grep '^rpm\.'
rpm.i686                                4.8.0-59.el6                @CentOS/6.10
```
# このイメージの使い方

このような `Dockerfile` でベースイメージを作成してから使うのが良さそう

```dockerfile:Dockerfile
FROM i386/centos:6

RUN sed -i 's/$basearch/i386/g' /etc/yum.repos.d/CentOS-*.repo && \
	ln -sf /usr/share/zoneinfo/Japan /etc/localtime
```
- `uname -m` で動作環境を判定してるスクリプトを動かす場合は修正が必要

# 参考

- [CentOS 5.11 32bitイメージ作った - Qiita](https://qiita.com/tukiyo3/items/29898a52d1063383c57d)
- [Docker i686 image broken · Issue #94 · CentOS/sig-cloud-instance-images · GitHub](https://github.com/CentOS/sig-cloud-instance-images/issues/94)
Spring boot temporary upload location [/tmp/tomcat ・・・ is not valid]

# 事象
いつも動いていたファイルアップロードがある日突然動かなくなった。
※Spring boot embedded Tomcatを使っている時は要注意。

### エラー内容

```application.log
ERROR 39865 --- [http-nio-20080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is 
org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.io.IOException:
The temporary upload location [/tmp/tomcat.12071915071708668548.20080/work/Tomcat/localhost/ROOT] is not valid] with root cause
```
## 原因
SpringのembeddedTomcatが一時フォルダ(ファイルアップロード時などのWORK)として利用するディレクトリをOSが削除していた。。(OSの削除対象ディレクトリとかぶっていた)
そのため、突然アップロード時に使用する一時フォルダが存在しないと言う状態に。
今回はCentOSを使用していた。
embeddedTomcatの場合一時フォルダはデフォルトだと/tmp/tomcat.xxxxxx　で作成される(tomcat起動時に自動生成)

## 対応
一時フォルダを/tmpから変更する

```application.yml
server:
  tomcat:
    basedir: /xxx/xxxx/xxxx   # ここでパスを指定
```
gasで月初日と月末日を取得する

gasで、というかjavascriptで月初日と月末日を取得するのにどうしたら良いんだろう？と悩んでいたので備忘録。

## 月初日

`Date`関数を呼び出すときの第三引数(日付)に`1`を入れる事で、当月の1日を取得できる。

```js
  var today = new Date();
  
  // 月初日取得
  Logger.log(new Date(today.getFullYear(), today.getMonth(), 1));
```

#### アウトプット

`[19-06-16 12:24:55:673 JST] Sat Jun 01 00:00:00 GMT+09:00 2019`

## 月末日

以下の2点

* `Date`関数の第二引数を、`+1`して翌月にする
* 第三引数を`0`にして、1日の前日を取得
    * ここを`1`にすると、6月なら7/1が取得できるが、その前日の6/30を返してくれる

```js
  var today = new Date();
  
  // 月末日取得
  Logger.log(new Date(today.getFullYear(), today.getMonth()+1, 0));
```

#### アウトプット

`[19-06-16 12:24:55:674 JST] Sun Jun 30 00:00:00 GMT+09:00 2019`

## フォーマットする

これだけだと使えないんですよ。
私は`2019年6月1日(土)`というフォーマットにしたいんですよね。

これをjsで頑張るとこんな感じになります。

```js
  // 月初日取得
  var firstDate = new Date(today.getFullYear(), today.getMonth(), 1);
    
  var year = firstDate.getFullYear();
  var month = firstDate.getMonth() + 1;
  var date = firstDate.getDate();
  var day = firstDate.getDay();
  var dayList = ["日", "月", "火", "水", "木", "金", "土"];
  
  Logger.log(year + "年" + month  + "月" + date + "日(" + dayList[day] + ")");
```

#### アウトプット

`[19-06-16 12:30:37:663 JST] 2019年6月1日(土)`

出来たけど、面倒臭いｗ

## moment.jsという便利なライブラリがあった

gasにはライブラリを使う機能があるので、「リソース」 > 「ライブラリ」で、以下のプロジェクトキーを入門してmoment.jsライブラリを追加します。

`MHMchiX6c1bwSqGM1PZiW_PxhMjh3Sh48`

```js
  var today = new Date();
  
  // 月初日取得
  var firstDate = new Moment.moment(new Date(today.getFullYear(), today.getMonth(), 1)).format("YYYY年MM月DD日(dddd)");

  Logger.log(firstDate);
```

`format`を使えばこんな感じで出せます。

#### アウトプット

`[19-06-16 12:37:44:770 JST] 2019年06月01日(Saturday)`

日本語で曜日を出力するには結局`dayList`みたいな配列を作るしかないのかな。。それも面倒だな。。
何か良い方法知ってる人いたら教えてください。
if文による、条件文の組み合わせ！

##### 初めてのQiita投稿ということで簡単な備忘録

##### if文の条件の組み合わせについてまとめていきます！

*初心者のため書き方で気になる点等ありましたらご意見下さい...

---

そもそも...
### 条件式の組み合わせとは？？？

##### 「条件式1が真」*かつ*「条件式2が真」や、「条件式1が真」*または*「条件式2が真」というもの！
そして.....

### 条件式の組み合わせは３種類存在する！！！

ざっーと言葉だけで抽象的に説明してしまったので、ここからは具体的な例を出しながら説明していきますね！

---
種類その1...

### ➀　＆＆
##### これは条件式1と条件式2の両方が真であることで初めて、真になる演算子です！

例を出していきましょう！

```ruby:qiita.rb
if (パスポートを持っている) && (体調不良ではない)
    海外旅行に行ける
end
```
上の例では条件1「パスポートを持っている」と条件2「体調不良ではない」の両方ともが真であるとき初めて、if文が実行される(海外旅行に行ける)。

---
種類その2...

### ➁　||
##### これは条件式1、もしくは条件式2の片方でも真であれば、真になる演算子です！

またしても例を出していきましょう！

```ruby:qiita.rb
if (無料クーポン券を利用する) || (５００円払う)
    うどんが食べられる
end
```
上の例では条件1「無料クーポン券を利用する」か条件2「500円払う」のどちらかの条件が真であると、if文が実行される(うどんが食べられる)。もちろん両方が真でも実行される！

---

種類その３...

### ③　&&　と　||　の組み合わせ

組み合わせの注意点としては、***&&の優先順位は||よりも高い***ので、解釈の仕方に気をつけましょう！

例を見てましょう！

```ruby:qiita.rb
条件式１　&& 条件式2 || 条件式3 && 条件式4
```

上の式は、***「条件１かつ条件２が真、または条件３かつ条件４が真なら真」***という意味になります！

もし！優先順位を変えたい場合は***（）***を使います！
例えば、次のように記述すると、***「条件１が真かつ、条件２または条件３が真かつ、条件４が真なら真」***という意味になります！

```ruby:qiita.rb
条件式１　&& （条件式2 || 条件式3） && 条件式4
```


---
### はい！以上となります。
簡単ですよね！
##### これらの演算子が使えるようになると条件式がより簡潔に記述することができると思います！
##### 利用場面は比較的多いと思うので覚えておいて損はないですね！

ご静聴ありがとうございました:relaxed:

何かご意見とうございましたらご気軽に意見お待ちしております！