OmniAICreator/Qiita-1.07M huggingface dataset:
Rrailsにcsvファイルを簡単に読み込めるgemを作る

# 背景
とあるサービスをrailsで作っていたが、初期データが多くてseedにすべて書くのは大変&エンジニア以外にも手伝ってもらいたかったので、csvファイルでseedデータを作ることにしました。
csvファイルをseed.rbで読み込む方法はすでに存在しますが、csvファイル1つずつ読み込んだり、一括で読み込むものもvalidationを無視するものが多いです。かといって、validationを守りつつcsvファイルを読み込むためには、読み込む順番を制御しなければなりません。
コードを書いてると60行ぐらいになり、rubyのメタプログラミング的手法(カッコイイ)も使ったので、練習も兼ねてgem化することにしました。

# 成果物
https://github.com/aitaro/csv_seeder
(よかったら使ってね)

# 他のcsv読み込み系qiita
無限にあったので[検索結果](https://www.google.com/search?q=rails+seed+csv+qiita)から探してください。

# 準備
[RubyGemsの作り方](https://qiita.com/chamao/items/9813e18d82b51c99422c)を参考に初期設定をしていきます。
ちなみにgem名はcsv_seederにしました。

# 設計
まず、想定するcsvファイルは下のようなものです。(csvにidまで含めているのは、relationで指定することができるからです。)

```csv:posts.csv
id,name,status
1,プログラミングの書き方,release
2,rails基礎,draft
```

```csv:comments.csv
id,post_id,body,rate
1,1,よく分かった,5
2,1,少し分かった,4
3,2,わからなかった,3
```

基本的な設計方針として、csvファイルを順番に読み込みつつ、依存関係(belongs_to等)によりvalidationに引っかかるcsvファイルを後回しにします。

例えば以下のようなモデルのとき、

```ruby
class Post
  has_many :comments
end

class Comment
  belongs_to :post
end
```
先にCommentを読み込むと、指定したPostがないよと怒られます。なのでPostを先に読み込んでからComnmentを読まないいけません。

このように"validationに引っかかるもの"のほとんどはbelongs_toによるものです。

# 実装
基本ループの実装です。

```ruby
def initialize(folder_path, orders)
  @folder_path = folder_path
  @orders = orders
  @dirs = Dir.glob(folder_path + "/*").shuffle 
end

def dirs_loop!
  while !@dirs.empty?
    if invalid_order?
      postpone!
      next
    end
    if has_relations?
      postpone!
      next
    end
    /db\/seeds\/(\w*)\.csv/ =~ @dirs[0]
    model = $1.classify
    CSV.foreach(@dirs[0], headers: true) do |row|
      Object.const_get(model).create!(**row.to_hash)
    rescue => e
      p "Error! During #{model}"
      p e
    end
    p "#{model} saved!"
    @dirs.shift
  end    
end
```
`@dirs`にcsvのpath一覧が入っています。これから`invalid_order?`や`has_relations?`等の条件を適合したものだけをcreateしています。
CSV.foreachによりcsvファイルの読み込み、Object.const_get(model)により動的にクラスを呼び出しています。

has_relations?の実装です。親クラスがまだ読み込まれていない場合は後回しにします。

```ruby
def has_relations?
  CSV.open(@dirs[0], &:readline).any? do |header| 
    id_list = @dirs.map do |dir|
      dir_to_plural(dir).singularize + '_id'
    end
    id_list.include? header
  end
end
```

invalid_order?の実装です。`@orders`はhas_relations?で補足できない依存関係を、ユーザーからのインプットパラメータとして受け取ったものです。`@orders`に禁止するものを後回しにしています。

```ruby 
def invalid_order?
  @orders.each do |order|
    index = order.index(dir_to_plural(@dirs[0]).to_sym)
    next if !index || index == 0
    return true if @dirs.any?{|dir| order[0..(index-1)].map(&:to_s).include? dir_to_plural(dir)}
  end
  false
end
```

## 所管
簡単なgemですが、公開するとやりきった感があってたのしいです。なにか提案等あればこの記事のコメントかissueかに書いてください。(反応できるかわからないですが、、)

## TODO
個人的メモです。ここまで書いて力尽きました。以下のことはまた今度やります。

- gem使い方の説明を書く
- 依存関係をはっきりさせる。
- gemのtestコードを書く
PHPのビルトインサーバ

# どういうときに使うか

ブラウザでPHPからの出力(HTMLなど)を確認したいとき

# どのようにするか

- 以下をターミナルから打つことで簡易的なウェブサーバを立てることができる。

```php
php -S localhost:8080
```
- このコマンドの後に出てくる"Listening on"以降がURLとなる。
- 何も指定しなければドキュメントルートはカレントディレクトリとなる。
- -tオプションを使えば明示的にドキュメントルートを指定できる。

```php
php -S localhost:8080 -t /var/www/test
```
# 参考
https://xn--web-oi9du9bc8tgu2a.com/php-web-server/
SinatraとRailsの特徴の違いについて

今日は"簡単なアプリ"を作りたいと思います！
って意気込んだものの、根本的な疑問がでできてしまいました:sweat:

そもそも、Rubyを使ってウェブアプリケーションを作成するけど・・・
→Rubyだけでは膨大な量のコードの記述が必要なため、時間も手間もかかって大変
そんな時に併用するのといいのが「ライブラリ」ですよね！

:mega:ライブラリってなにかな
プログラミング言語の機能を追加できるツールのこと
→言語を増やせば、よりアプリ作成の手間を省くことができるんだってさ！
ここでよく目にする「Gem」が登場するわけだけど・・・

:mega:Gemってなんだっけ？
Ruby専用のライブラリ、つまりRubyに言語機能を追加できるツールのこと
→Gemによって機能が異なるから、欲しい機能を備え持つGemをインストールして作業の効率を上げるよ！
例） Ruby on Rails , bundler , Devise , Sinatra …


ここまでは復習できたけど、私「Sinatra」って初めて聞いたかも:eyes::sweat_drops:
よし、今日はアプリを作る前にこのSinatraについて調べてみようかな！

ということで、ここではSinatraについてまとめる上で、Railsとの違いを紐解いていきます。

話をちょっと戻して、
さっき“欲しい機能を備え持つGemをインストールする”って言ってたけど、
つまり「Sinatra」と「Rails」には異なる機能(性格)が備わっているわけで、それぞれの違いってなんだろう？

よし、Sinatraさんに直接聞いてみよう.


———————————————————————————————————————————

[ Sinatraさんの自己紹介 ]

こんにちは、僕の名前はSinatra(シナトラ)です:v:
いつもRailsくんの陰に隠れて存在感ちょい薄いかもしれないけど、割と活躍できるんですよ！

そもそもRailsくんって、機能は豊富かもしれないけどその分ルールも多くない？
なんかちょっとでもルールに反することするとすぐ指摘(エラー)してくるし、僕ちょっと仲良くなれないんだよね・・・
だからRailsくんのことは皮肉も込めて「フルスタックフレームワーク」なんて呼び方もしてるよ！

じゃあ僕はっていうとね、すっごい単純な性格だよ:grin:
ルールだって少ないし、単純な記述だけで簡単に使用できるってことが売りだからね。
だから僕は「軽量フレームワーク」なんて呼び方されてるよ。

でももちろん、こんな僕にだって欠点はあるんだよね・・・:zap:
ぶっちゃけ記述は簡単だけどその分コード量は多くなっちゃうし、Railsくんほどできること多くないから複雑なアプリ開発の時はNG出してるんだ。
それに悔しいけどまだまだ認知度も低くて、Railsくんたちみたいに使い方に関するマニュアルが少ないんだ、これ最近の僕の悩み。
だからみんなのこと行き詰まらせちゃうこともあるの、ごめんね・・・

だけど最後に自慢させて欲しいんだ:sparkles::sparkles:
僕のこと、あの「Apple」とか「BBC」、「Heroku」みたいな大手企業さんもアプリ開発の時に呼んでくれたんだよ！これってすごくない！？
それにこんな僕だからこそ、プログラミング初心者さんからの人気はあるから、僕も期待に応えられるよう頑張ってるんだ。
つまりみんなは僕のことを呼んでくれれば、ウェブアプリケーションの仕組みについて１から丁寧に学ぶことができるよ！

ぜひ、僕のこと必要な時には呼んでね！
使い方とか、もっと詳しいことはその時説明するから:pencil2:
———————————————————————————————————————————

なるほど〜Sinatraさんにもこんなに魅力があるのか！
まとめるとこんな感じかな。

:star:Rails
・機能が豊富
・コード量も少ない
・複雑なアプリにも対応
・その分ルールが多く難しい

:star:Sinatra
・機能は少ない
・コード量は多い
・シンプルなアプリに対応
・その分簡単で分かりやすいから初心者向け

私は今回どっちを使うべきかな・・・
”簡単なアプリ”だから、Sinatraを学習して使ってみようかな:writing_hand:
Flexboxを使って要素をスクロールさせるときの高さを可変にする

要素をスクロールさせる時の高さを可変にする方法です。
Flexboxを使うことで高さを固定値で指定せず、レスポンシブ対応のレイアウトにできたのでざっくりですが方法を書いていきます。

##要素をスクロールさせたい
まずはやりたいことの基盤となるスクロールの実装を書きます。

:point_down_tone1:要素のスクロール自体はこのcssでできるはず。

```scss:style.scss
.box-scroll {
  height: 80px;
  overflow: scroll;
}
```
しかし、これだと要素の高さをが固定値（px指定）のため、ブラウザを縮小させると要素が隠れて見えなくなります。

レスポンシブ対応（ブラウザを縮小させても要素全部が見える状態）にしたい場合は、Flexboxを使うことで高さを固定せずに要素のスクロールができます。

#Flexboxで縦並びにする
Flexboxを使って縦並びのレイアウトにする。
このとき、親要素の高さを`height: 100vh;`、子要素に`flex: 1;`とすることで各要素の高さが均等に画面いっぱいに広がる。

```html:index.html
<div class="flex-box">
　<div class="box">1</div>
　<div class="box">2</div>
　<div class="box">3</div>
</div>
```

```scss:style.scss
.flex-box {
  display: flex;
  flex-direction: column;
  height: 100vh;
  > .box {
    flex: 1;
  }
}
```

装飾などのコードは省いていますが、レイアウトは下の画像のようになります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227740/5d53af8f-26f8-d861-67fb-ea555348f37b.jpeg" alt="結果" width="600">

###この仕組みを使って高さを固定せずに要素をスクロールさせる
先ほどと同じ、１画面でブラウザのスクロールをしないイメージのレイアウトです。
２つの要素があり、下の要素がスクロールできるようになっています。

<p class="codepen" data-height="320" data-theme-id="dark" data-default-tab="html,result" data-user="mnk_o7" data-slug-hash="LYVoMzE" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="LYVoMzE">
  <span>See the Pen <a href="https://codepen.io/mnk_o7/pen/LYVoMzE">
  LYVoMzE</a> by mnk (<a href="https://codepen.io/mnk_o7">@mnk_o7</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

Flexboxを使って親要素の高さを指定するだけで子要素の高さが決まります。
なので、スクロールしたい要素の高さを計算したりして指定する..と言った手前がなくて楽かと思います。

#### おまけ
実際にこの方法でコーディングする機会があり、便利だなと感じたので書いてみましたが、はじめての投稿でグダグダ、かつ説明不足な部分が多いと思います..
ほかに良さげな方法、ご指摘などあればいただけると嬉しいです。
iPhoneのショートカットAppを使って、ヘルスケアに体温を楽々で記録する

みなさんこんばんは、スズキです。コロナ流行ってますね。怖いです。

## 求められる検温

さて、世の中的にはリモートが広まりつつありますが、友人の会社は作業開始時の日報に検温の記録が求められ始めたそうです。いやまぁ確かに学校と保育園は既にそうではあった。
そして、**「検温記録で検索したらルナルナしか出ない、そうじゃないんだ」**という声が飛び込んできました。

検温の記録自体は、iOS標準のヘルスケアアプリに記録することが出来ます。ですが、辿り着くまでのUIUXがちょっと分かりにくいんですよね。ご婦人系のカテゴリの中に入ってしまっていて…。（あんまり言うのも野暮なので各自確認してくれ）。
結論として、**iPhone標準のヘルスケアアプリで体温の記録の蓄積は行なえます。**
ちょっと調べてみたところ、ショートカットAppのAPIがあったので、気不味い画面を開くこと無くスムーズに健康を管理出来るよう、レシピを作ってみたので公開します。

尚、本件は以下のサイトを大いに参考にさせて頂きました。
ありがとうございます。

 [何となく風は爽やか](https://kazesawayaka.com/)  /  [conyline](https://conyline.tumblr.com/about) 様
 [ヘルスケアに現在の体温を記録するショートカットを作成する。（iOS13 ショートカット）](https://kazesawayaka.com/gadget/764) 
 [｢if文｣と｢繰り返し｣を使ってショートカットレシピを作成する。（iOS13 ショートカット）](https://kazesawayaka.com/gadget/797) 


## ショートカットAppとは
iOS12だか13で追加された機能です。
コードの書かないプログラミングというか、IFTTTの凄いやつというか、起動して値を入れたらBに変換されてCに収まっていく、ということを、アプリを跨いでやってくれる機能です。詳しくは以下。

[iPhone や iPad でショートカット App を使う - Apple サポート](https://support.apple.com/ja-jp/HT208309)

## 手順
### 1. アプリの準備
[‎「ショートカット」をApp Storeで](https://apps.apple.com/jp/app/%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88/id915249334)
まずこの「ショートカット」アプリを入れて下さい。
気付いてないだけで、放置されている可能性もある。

### 2. ショートカットレシピのダウンロード
[ショートカット](https://www.icloud.com/shortcuts/5b27ebbab7ec4c889199bdd8ba022586)
今回作成したのはこちらになります。
iPhoneから接続するとダウンロードして、諸々聞いてくるので差し支えなければYESで進めて下さい。
諸々とは、ショートカットアプリがヘルスケアデータの書き込みと読み込みの許可を求めているよ、とか、インターネ
ットで公開されているレシピだから気をつけてね、とかそういう話です。

また、オフィシャルではない公開アプリは予め許可設定を入れておかないと弾かれます。
こちらだけ、どうか自己責任ということでご承知おき下さい。
<img width="372" alt="IMG_83B313E0DF37-1.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165009/11c0a6e4-a854-ecdb-f547-73cca3e2cbb7.jpeg">


### 3. 実行する
ショートカットを実行します。
こんな感じで動作します。
![20200409scapp.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165009/704a5a40-c197-97c2-237e-f3c314570637.gif)

数値を入れる、記録される、直近の記録も見たければ、ヘルスケアに飛ばすのでご確認下さい。

### 4. 実は他にもある起動方法
詳細は割愛しますが、大きく分けて３つ、起動する方法があります。

1. オートメーション（＝指定した時間や目覚ましと同時に起動する）
2. ホームボタン化ショートカット内のアプリそのものをホーム画面に配置して、タップ一つで起動出来ます
3. 画面左のウィジェットに配置。フリックしてボタンぽちーで完結

ちょっと弄れば、「検温を開始して下さい」（３分待機）「入力してください〜移行続く」みたいな動きにも出来るので、遊べて楽しいです

## 動作の内容について

ざっくり書きます。
![IMG_3942.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165009/a084ea8b-524a-e09c-35d2-00134b299e22.jpeg)
![IMG_3943.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165009/ad602c61-3d2f-f790-3705-7d54fbe800f5.jpeg)
![IMG_3944.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165009/5f14cbd4-62f6-403d-1e76-851f5bc46262.jpeg)
![IMG_3945.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165009/fe80b33c-ffe9-4225-13e6-e432e9ebff90.jpeg)
![IMG_3946.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165009/0511e111-7de5-c901-00fa-3002102f6544.jpeg)

慌てて作ったのですごい見にくくてすいません。

## その他
ざっくり以上です。
体温のパラメータを基礎体温とかに変えれば、そのまま流用出来たりすると思うので、自由度高いと思います。
Kinx ライブラリ - Double

# Double

## はじめに

**「見た目は JavaScript、頭脳(中身)は Ruby、（安定感は AC/DC）」** でお届けしているスクリプト言語 [Kinx](https://github.com/Kray-G/kinx)。言語はライブラリが命。ということでライブラリの使い方編。 

今回は Double です、... と言いつつ、Double 組み込み特殊メソッドは少ないので、短い記事です。

* 参考
    * 最初の動機 ... [スクリプト言語 KINX（ご紹介）](https://qiita.com/Kray-G/items/ca08b6fb40d15dd0ec76)
        * 個別記事へのリンクは全てここに集約してあります。
    * リポジトリ ... [https://github.com/Kray-G/kinx](https://github.com/Kray-G/kinx)
        * Pull Request 等お待ちしております。 

## Double 特殊オブジェクト

Double オブジェクトに対して関数定義する例は以下の通り。

```javascript
Double.minus1 = function(value) {
    return value - 1;
};
var val = 100.5.minus1();
System.println(val);
```

実行してみよう。

```
99.5
```

他の特殊オブジェクトと同様、レシーバーが第 1 引数に来ます。

## Double

### 組み込み特殊メソッド

|           メソッド           |                                                                意味                                                                |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| Double.toString(val, format) | `val` を文字列に変換する。`format` は `%` で始まり、`a`、`A`、`e`、`E`、`f`、`F`、`g`、`G` のいずれかで終わる文字列。省略時は `%g` |
| Double.toInt(val)            | `val` を Integer に変換する。                                                                                                      |

> `format` は現在プレビュー版ではサポートされていません。正式版ではサポート予定です。というのも、これを書いていてあったほうが良いなー、と思ったということで。

### Math オブジェクト・メソッド

Double オブジェクトには Math オブジェクトと同じ特殊メソッドが存在する。詳細は以下を参照。

* [Kinx ライブラリ - Math](https://qiita.com/Kray-G/items/be251d0a3c0bcaa5ba79)

具体例で書くと、例えば以下のように書ける。

```javascript
var a = 2.0.pow(10);   // Math.pow(2.0, 10) と同じ  => 1024
var b = (-10.8).abs(); // Math.abs(-10.8)   と同じ  => 10.8
```

単項マイナス(`-`)は関数呼び出しより優先順位が低いため、カッコで括る必要があることに注意。

## おわりに

Integer 同様、[ここ](https://docs.ruby-lang.org/ja/latest/class/Float.html) を見ながら今サポートしてないメソッドとかを順次サポートしていこうかなー。

ではまた次回。
【スタジオしまづ】>Udemy >セ5:C#基礎>配列List型

#教材番号20　Listとforeachを粛々とまとめる

###配列との違いは？？
要素追加、削除したり出来る

###1.　基本の書き方
```csharp 
        //宣言と初期化　numbersがこの配列の名前
        List<int> numbers = new List<int>(){-1,21,23};
```
###2.　Debug.Logの書き方
```
        Debug.Log(numbers[0]);
        Debug.Log(numbers[1]);
        Debug.Log(numbers[2]);
```
👆-1,　21,　23が順に表示される。

###3.　代入の書き方
```csharp 
        numbers[1] = 0;
```
👆配列の1番目に0が代入される様子
　配列は0から始まるので1番目の21が0になる

###4.　追加の書き方
```csharp
        numbers.Add(100);
```
新参者なので末尾に追加される
###5.　削除の書き方
```csharp
        // 削除方法1　配列番号を指定　
        numbers.RemoveAt(3);
        // 削除方法2　直接呼ぶ
        numbers.Remove(-1);
```
###6.　Listの長さの調べ方
```csharp
        Debug.Log(numbers.Count);
```
###7.　相性の良い「for文」をつかう
```csharp
        for(int i=0; i<numbers.Count; i++)
        {
            Debug.Log(numbers[i]);
        }
```
ここまでの結果で、-1,　0,　23,　100が表示される

###8.　更に「for文」レベルアップ！！
```csharp
        // （1）1-9までの配列を作るとこ
        List<int> numberList = new List<int>();
        for(int i=0; i<10; i++)
        {
            // 0-9までをAddでListに加える
            numberList.Add(i);
        }

        //（2） 1-9までの配列をコンソールに出力するとこ
        for(int i=0; i<numberList.Count; i++)
        {
            // 配列の長さの分、表示させる
            Debug.Log(numberList[i]);
        }
```
配列を「作る」forと「出力」させるforが2人います。

###9.　foreachを使うと簡単にアジフライを呼び出せる
```csharp
        List<string> nameList = new List<string>(){"イカ", "アジフライ", "ブリ"};
        foreach(string Name in nameList)
        {
            Debug.Log(Name);
        }
```
イカ, アジフライ, ブリがコンソールに表示されるよ！

###10.　演習：0-99までの3の倍数を要素にもつListを作れ（確認しろ）
やってみた結果

```csharp
List<int> supernumberList = new List<int>();
        for(int i=0; i<100; i++)
        {
            if(i%3==0)
            {
                supernumberList.Add(i);
            }
        }
        foreach(int Name in supernumberList)
        {
            Debug.Log(supernumberList);
        }
```

正解はこう

```csharp
        List<int> testList = new List<int>();
        for(int i=0; i<100; i++)
        {
            if(i%3 == 0)
            {
                testList.Add(i);
            }
        }
        foreach(int number in testList)
        {
            Debug.Log(number);
        }
```

###11.　演習でつまづき、間違えたところ
・最初のつまづきは、空白必須。
newList<int>();　×
new List<int>();　〇

・間違え箇所、呼ぶ方そっちじゃない
Debug.Log(supernumberList);　×
Debug.Log(Name);　◎

##学習教材
[Unityゲーム開発入門：インディーゲームクリエイターが教えるマリオのような2Dゲームを作成する方法【スタジオしまづ】]（https://www.udemy.com/course/studio_shimazu_sideview_action/）
Google App Script で Google カレンダーの一部を秘匿化しながら共有する

在宅勤務が推奨される世界で生きるようになったのはいいものの、子供がいる我が家では、どちらかが子供の相手ができるようにビデオ会議の時間をかぶらせない運用をすることになりました。

しかし、セキュリティの関係でお互いの業務予定を完全に共有するわけにはいきません。
口頭で「何時からビデオ会議したいねんけど、予定空いてる？」などを毎日確認し合うのは大変です。

* いつ妻がビデオ会議を始めるのか
* いつ自分が子供の面倒をみないといけないのか
* お互いにバッティングしている予定はないか

などを自分のタイミングで好きな時に判断できるようにしたい。

そこで、Googleカレンダーの予定のうち、**共有したい一部のみを、秘匿化しつつ時間だけ共有したい**、みたいなことをしたくなりました。

※ Googleカレンダーの共有設定に「予定の表示（時間枠のみ、詳細は非表示）」オプションがあるので、一部に限定する必要がない方はそちらをやった方が早いと思います。

## やりたいこと

1. **業務アカウントに登録されてる予定の一部を個人アカウントにコピーして**
2. **個人アカウントを妻アカウントに共有する**

* 予定を読み取りたいアカウント
    * 業務アカウント1
    * 業務アカウント2
    * 業務アカウント3
* 媒介するアカウント
    * 個人アカウント
* 予定を共有したいアカウント
    * 妻のアカウント　　

## Google App Script(GAS) でちょちょいのドン

まず、業務アカウントの向こう2週間分の予定を読み取り、タイトルでフィルター（XXXXを含み、YYYYを含まない）し、個人アカウントに「予定あり」予定として登録する

```js
function createEvents() {
  // カレンダーを取得
  const myCal = CalendarApp.getDefaultCalendar(); // 個人アカウント
  const cals = [
    CalendarApp.getCalendarById('業務アカウント1のカレンダーID'),
    CalendarApp.getCalendarById('業務アカウント2のカレンダーID'),
    CalendarApp.getCalendarById('業務アカウント3のカレンダーID')
  ];

  // 2週間
  const now = new Date();
  const twoWeeksFromNow = new Date(now.getTime() + (14 * 24 * 60 * 60 * 1000));

  // 個人アカウントの2週間分の予定のうち、前にコピーした「予定あり」予定をいったん消す
  let myEvents = myCal.getEvents(now, twoWeeksFromNow);
  for (let mev of myEvents) {
    if (mev.getTitle() === '予定あり') {
      mev.deleteEvent();
    }
  }
  // 各カレンダーから予定を取得し、条件で除外して、個人アカウントに「予定あり」で登録する
  for (let cal of cals) {
    let events = cal.getEvents(now, twoWeeksFromNow);
    for (let ev of events) {
      const startTime = ev.getStartTime();
      const endTime = ev.getEndTime();
      // 好きな条件
      if (ev.getTitle().includes('XXXX') && !ev.getTitle().includes('YYYY')) {
        continue;
      }
      myCal.createEvent('予定あり', startTime, endTime);
    }
  }
}
```

次に、毎日8時ごろに動くようにトリガーを設定する。

<img width="760" alt="スクリーンショット 2020-04-09 21.44.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29717/96b5d92d-68c3-131d-040b-f27122c03842.png">

## あとは個人アカウントを共有するだけ

Googleカレンダー上で、個人アカウントのすべてを妻アカウントに共有する設定を行ったら、完了です。

<img width="1075" alt="スクリーンショット 2020-04-09 21.58.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29717/74dd2dd9-37a6-350f-2d25-536500907b38.png">


これで、口頭で「何時からビデオ会議したいねんけど、どう？」など聞かずに、カレンダーを見れば、

* いつ妻がビデオ会議を始めるのか
* いつ自分が子供の面倒をみないといけないのか
* お互いにバッティングしている予定はないか

などを判断できるようになりました。
たまにある、

* 「（午後4時のつもりで）14時から会議あんねん」
* 「わかった」
* 「あれ、14時なったで」
* 「え、あ、16時の間違いやった」
* 「ええー、16時からこっちが会議あんねんけど」

みたいなことも起きません。

無事、円満な在宅勤務生活を過ごしていけそうです。
あとは、高性能なノイズキャンセリングマイクのついたヘッドセットがあれば完璧です。
GnuPG(PGP)を利用した、暗号メール(Outlook編)

# 最近、テレワークが流行っていますね

お久しぶりです。
新型コロナウイルスによって、テレワークが流行っているみたいです。
といっても、一部の人だけですが。
そこで気になるのが、セキュリティです。

そこで、GnuPG(PGP)を利用した、暗号メールの手順を紹介したいと思います。

# LTGM(いいね)176ありがとうございます

執筆現在、[セットアップ編](https://qiita.com/karkwind/items/9cb2907060f210fc940a)にLTGM(いいね)176もいただきありがとうございます。
はてなブックマークでも、結構ブックマークしてくれる人がいて、嬉しいかぎりです。

これを機に、平文のメールが無くなればいいかなと思っております。

# 今回は、Outlook編です

さて、今回は、Outlookで、暗号化から復号化までを行いたいと思います。

# なぜOutlook?

ちょっと、古い資料ですが、以下のサイトにこのようなことが書いてありました。

https://www.pi-pe.co.jp/solution/article/mail/48/

> 2017年の調査では『Apple Mail』が50%、『Outlook』が41%、『Thunderbird』が3%という結果が出ています。

Windowsユーザーのほとんどが、Outlookユーザーらしいです。
＃Apple MailはMacを利用していないのでわかりません…

今回は、Outlook2016を使用しております。
たぶん、他のバージョンも同じかと思いますが、違っていたら、すみません。

# GPG4WINをインストールしておく

前提条件になりますが、GPG4WINをインストールしておく必要があります。
以下のサイトを参考にしてください。

https://qiita.com/karkwind/items/9cb2907060f210fc940a

# 送信手順

## メール作成画面に注目

リボン(?)に、GpgOLというのあります。

![01-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221663/3d08a79e-ba53-cd93-ecb3-063d7e47b1cc.png)

そこをクリックすると、こんな感じに表示されます。

![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221663/54148e44-9bfc-a2df-418d-aa9c400b701b.png)

上が署名(Sign)で下が暗号化(Encrypt)です。

## 黒くなっているのが有効になっている

私も使っていて、気がついたのですが、背景が黒ずんでいるのが、有効化されています。
上記の例ですと、署名+暗号化になります。

トグルになっていますので、無効化有効化をしたいときは、クリックすると切り替えができます。

下記の例ですと、署名だけになります。

![03-sign-nomi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221663/9d6ca3d6-78a6-a80d-3635-6bdc042b6d50.png)

両方OFFにすることもできます(下記の図参照)

![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221663/6e7b9e97-8d53-78e0-d2d8-e22f4ac1c6ea.png)

相手が対応していれば、署名+暗号化しておきましょう。

## 送信するときに、パスワード入力される

送信するとき、パスワード要求のダイアログが出ますので、自分のパスワードを入力してください。

![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221663/04ea00e5-5865-f9e2-cd12-d0a950acaf58.png)

送信されたら、送信済みトレイにこんな感じで入っています。

![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221663/943f3964-c15c-229d-0cf0-7899c63ebd47.png)

# 受信手順

受信されたファイルを選択すると、パスワード入力画面が出ることがありますので、自分のパスワードを入力してください。

![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221663/c48f1944-a982-29b9-4cae-f1e9b7b7f981.png)

パスワードがあっていたら、メッセージが読めます。

![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221663/0b24df4f-29ab-c4d8-08bf-05e68a21cf51.png)

# ということで、力尽きましたorz

実をいうと、私は、Becky!派なので、Outlookの操作がよくわかっておりません。
もしかしたら、変なことを書いている可能性がございますが、ご理解のほどよろしくお願いいたします。

LGTMやシェアしてくださいますと、モチベーションが上がりますので、よろしくお願いいたします。

ここまで読んでいただきありがとうございました。
Invalid hook call warningへの対処（重複を減らす / gatsbyとの相性）

何度、くじけそうになったか…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169861/9604f787-131a-73a4-4f01-3e082a736790.png)

React Hooksを使い始めた頃、CRAなどで作ったサイトはともかく

**Gatsby**を使った時など、かなりの頻度で*Invalid hook call warning*に見舞われ、最悪の思いをした人も少なくないでしょう。

この記事では、*Invalid hook call warning*となかよくなるための「いくつかのルール」を教えます。

※ 原因は、こちらを読んでください

https://ja.reactjs.org/warnings/invalid-hook-call-warning.html

# Yarnを使う

「いろんなReactが混じっている」は、Yarnを使うことで解消されます。

`yarn dedupe`と打ってみてください。

```
error The dedupe command isn't necessary. `yarn install` will already dedupe.
```

`yarn install`とした時点でパッケージの重複がなくなり*Invalid hook call warning*の確率が減ります。

# yarn workspaceを使う

複数のリポジトリを管理していると、下みたいにReactが被ります。

```:フォルダ構成
root
  ├ packageA - React@^16.13.2
  └ packageB - React@16.12.0
```

例えば、「packageBでカスタムフックを用意して、packageAで使っている」ような状況です。

` packageA -> packageB ` (依存関係)

こうした状況で、*Invalid hook call warning*は起きやすいです。

こうした場合は、Yarn Workspaceを使いましょう。

少しフォルダ構成を変えましょう。

```:フォルダ構成
root
  └ packages
    ├ packageA - React@^16.13.2
    └ packageB - React@16.12.0
```

`root`のフォルダに`packages`フォルダを作っただけです。

#### バージョンは揃えておきましょう

`packageA`と`packageB`のReactのバージョンは、どちらかに揃えましょう。

```:例
cd packages/packageB

yarn upgrade React
```

#### yarn workspaceを導入しましょう

`root`フォルダに移動しましょう

```
cd <path to root>
```

初期化します。

```
yarn init -y
```

`package.json`に`workspaces`を足します。

```json:package.json
{
   ...,
   workspaces: ["packages/*"]
}
```

＊＊

ここで、**事前に各パッケージの node_modules / yarn.lock / package-lock.json を削除**しておきましょう

＊＊

さて、`root`にて

```
yarn
```

を実行します。

これで、`React`がルートフォルダの`node_modules`に集約され、*Invalid hook call warning* の確率が減ります。

# Gatsbyでの Invalid hook call warning

**Gatsby**で*Invalid hook call warning*が起きたときは、何か別の原因が邪魔をしている場合があります。

とりあえず

```
gatsby build
```

と打ってみましょう。

そうすると「真のエラー」が出てくると思います。

それを調べ、直してから、もう一度 `gatsby develop`で開発に戻りましょう。

# おわりに

たぶん、ここまでやっても起こるときは起こるのですが、多少はエラーでスタックする時間を減らせると思っています。

お役に立ちますように。
[R] Visual Studio Codeで%>%のショートカット

# はじめに
Rstudioでは`Ctrl+Shift+M`でパイプ演算子`%>%`を挿入できます。
Visual Studio Codeでも同じショートカットキーで`%>%`を挿入できるように設定します。

# keybindings.jsonを開く
`Ctrl+Shift+P`でコマンドパレットを開きます。
`key`と入力すると` Preferences: Open Keyboard Shortcuts (JSON)`が出てくるのでクリックします。

# `%>%`を登録する
JSONに下記のキーバインディングを追記します。

```json
  {
    "key": "ctrl+shift+m",
    "command": "type",
    "args": {
      "text": "%>%"
    },
    "when": "editorTextFocus && editorLangId == 'r'"
  },
```

以下は`keybindings.json`の中身です。

```json
// 既定値を上書きするには、このファイル内にキー バインドを挿入しますauto[]
[
  {
    "key": "ctrl+shift+m",
    "command": "type",
    "args": {
      "text": "%>%"
    },
    "when": "editorTextFocus && editorLangId == 'r'"
  },
  {
    "key": "ctrl+shift+enter",
    "command": "workbench.action.terminal.runSelectedText"
  },
  {
    "key": "shift+enter",
    "command": "-python.execSelectionInTerminal",
    "when": "editorTextFocus && !findInputFocussed && !python.datascience.ownsSelection && !replaceInputFocussed && editorLangId == 'python'"
  },
  {
    "key": "ctrl+meta+enter",
    "command": "python.datascience.execSelectionInteractive",
    "when": "editorTextFocus && python.datascience.featureenabled && python.datascience.ownsSelection && !findInputFocussed && !replaceInputFocussed && editorLangId == 'python'"
  },
  {
    "key": "shift+enter",
    "command": "-python.datascience.execSelectionInteractive",
    "when": "editorTextFocus && python.datascience.featureenabled && python.datascience.ownsSelection && !findInputFocussed && !replaceInputFocussed && editorLangId == 'python'"
  },
  {
    "key": "ctrl+shift+capslock ctrl+shift+alt+m",
    "command": "workbench.actions.view.problems"
  },
  {
    "key": "ctrl+shift+m",
    "command": "-workbench.actions.view.problems"
  },
  {
    "key": "ctrl+shift+enter",
    "command": "-r.runSourcewithEcho",
    "when": "editorTextFocus && editorLangId == 'r'"
  },
  {
    "key": "ctrl+shift+enter",
    "command": "-editor.action.insertLineBefore",
    "when": "editorTextFocus && !editorReadonly"
  },
  {
    "key": "ctrl+enter",
    "command": "-r.runSelection",
    "when": "editorTextFocus && editorLangId == 'r'"
  },
  {
    "key": "ctrl+enter",
    "command": "-r.runSelection",
    "when": "editorTextFocus && editorLangId == 'rmd'"
  }
]
```


以上です。
webpack-dev-serverのhot reloadでCPU使用率が上がる問題対応

# 概要
タイトル通り
nodeの使用率が100%前後になってMacが高熱になってて辛かった

# 方法
webapck-dev-serverのconfigに以下を追記する

```
watchOptions: {
  poll: 1000,
  ignored: ['node_modules']
}
```

# 結果
追加前は100%前後だったCPU使用率が20%前後に落ち着いた
Macが熱くて火傷しそうだったので助かった

# 参考
github issueにあった
https://github.com/webpack/webpack-dev-server/issues/2140
AWSソリューションアーキテクト学習方法

#はじめに
本記事は社内でAWSやろうぜ！という空気が生まれたので、
それに伴い作成した学習ガイダンスとして作成しました。
内容は書きすぎず極力シンプルに書いておきます。
※先人様の情報ソースや公式に一杯書いてありますしね。

#AWS経験
- 提案、製品比較、自己学習で触った程度。ガッツリは触ってないです。むしろ触りまくりたいお年頃。

#試験難易度
- 初学者が初受験合格は難しいかもしれない。
    - 開き直って一度落ちて感覚掴む程度がちょうど良いかと。
      ※一回落ちました。

#取得したAWS資格
- AWS 認定ソリューションアーキテクト – アソシエイト
- AWS 認定 SysOps アドミニストレーター – アソシエイト<br>
※次はAWS 認定ソリューションアーキテクト – プロフェッショナルを取得予定。

#学習方法
◆ポイント
実環境を可能な限り触ること。※必須ではないですが、イメージはつきやすくなると思います。

##基本編
- 概要→詳細→理解の流れで把握すること。<br>
- 次の流れが一番内容を理解しやすいと思う。
　
* **概要：Blackbelt資料　**
    * 概要把握だけならこれでもOK。
* **詳細：Udemyの模擬テスト問題　**
    * 過去問題などのユースケース詳細を知る。
* **理解：Udemyの模擬テスト問題　**
    * テスト結果に書かれている解説理解。説明内に公式リンクの説明が書かれているので、それらも合わせて読む。それ以外の情報リソースや実機操作も交えて理解の浅い箇所について補習しておきます。

##AWS クラウドサービス活用資料集(Blackbeltシリーズ)
[サービス別資料 | AWS クラウドサービス活用資料集](https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/)
この資料を一通り読めばAWSの概要把握は何とかなると思う。ただ資料が多いため、試験対策や主要サービスだけを抑えたいという目的なら対象は絞ること。

##Udemyテスト問題
[AWS Certified Solutions Architect Associate模擬試験| Udemy](
https://www.udemy.com/course/aws-certified-solutions-architect-associate-amazon-practice-exams-saa-c02/)

Udemyでは日本/海外などで色々な学習リソースが乱立していますが、個人的には英語ですがJonBonsoさんの模擬問題が一押しです。知ってる限り、2018年のリリース後もメンテナンスが今なお(2020/4時点も)高頻度で続けられており、ただのテスト問題ではなく鍛え上げられた解説に基づいたテスト問題集となっております。

英語なので困ったときはChrome翻訳に任せながら進めば、特に困ることはないと思います。
もし数問やってさっぱりわからないとかであれば、試験を終了させて解説を読んで参考書代わりにしてから再戦した方が良いです。

なお、Redditでも結構評判は良かったです。
https://www.reddit.com/r/AWSCertifications/comments/b9gyhp/jon_bonso_practice_exams/

##TutorialDojo(JohnBonsoさんのラーニングポータル)
[TutorialDojo](https://tutorialsdojo.com/)
Udemyで紹介された方のラーニングポータルです。スタディガイドで学習フローを見て、チートシートで各機能単位の詳細を把握できます。これもChrome翻訳に任せましょう。

##Jayendra's Blog
[Jayendra's Blog](https://jayendrapatil.com/aws-solution-architect-professional-certification-exam-preparation-guide/)
過去問を検索すると高確率でヒットします。AWS試験を高得点で試験をクリアした方のブログですが、情報量が多く検索リソースとして秀逸です。

##Linux Academy
[Linux Academy](https://linuxacademy.com/)
日本の同名の団体とは別物。比較したことはないですが体系だった内容で学習ができるのがポイントです。ただし有料であり英語のため、翻訳なども駆使しながら英語が何となく読み解ければコスパは良いと思います。新し目の動画であれば字幕表示機能があり(古いものにはついてないのが残念)、少し見にくいですがChrome翻訳によりスクリプト表示枠で翻訳しながら見ることはできるため、英語学習もできます。
※ブラックフライデーのタイミングなどで割引サービスを利用しても年間数万はかかるので要覚悟。ですがAWSだけでなく様々なラーニングコースが充実しているのでスキルの底上げに良いと思います。

#受験に向けて
申込方法は公式を見れば分かるので、注意をするポイントだけ。
試験会場予約時に「キオスク」と会場の末尾に書いてある会場は要注意。
困ったときは英語チャットで助けを求める必要があるので自信のない人は避けたほうが無難。

東京圏内では「**銀座CBTS歌舞伎座テストセンター**」をおすすめしておきます。
最近受験された方がわかりやすい紹介を書かれていたのでご紹介します。

[AWS認定試験（ソリューションアーキテクト・アソシエイト）受験しました | たろさん7890のブログ - 楽天ブログ]
(https://plaza.rakuten.co.jp/taro3chidayo/diary/202003190000/)

当然私もお奨めする通常のPC(非キオスク端末)で受験可能です。こちらの試験会場は更に日本語で受付対応してくれるので試験環境周りで困ったときはヘルプしてくれます。
※実は一度ネットワークトラブルでフリーズしたのですが無事再開できました。
　これキオスク端末だったら時間内に解決できなかった恐れすらあります。

##その他
本資格を取得したからと言って、業務に直結するスキルが直ちに身につくわけではありませんが、AWSを使用した業務に携わる際の瞬発力が身につく内容だとは思いますので、取得後は社内外へのアピールや履歴書に書く際、付加価値は多少なりとも上がるのではないでしょうか。また新しく取得したら追記します。
Numpy100本ノックで出会った「こりゃあ、便利だなぁ～」と思った関数一覧

# 概要
会社の研修中にNumpy100本ノックに取り組みさせられましたが、そもそも関数を知らないと倒せない問題が数多くあり、知識不足を痛感しました。
その、僕が初めましての関数の中でも「便利だなぁ～」と思ったものを備忘録を兼ねてご紹介するのがこの記事になります。

# 筆者プロフィール
プログラミング歴：約1年(Pythonのみ)
Numpyは[この本](https://www.oreilly.co.jp/books/9784873118451/)で勉強しました。

# 初めに
初めての関数に出会ったら、ググるよりも先にhelpを見た方が圧倒的に理解が早いです。
helpは

```python
np.info([関数名])
ex) np.info(np.add)
```
jupyter notebookであれば

```python
[関数名]?
ex) np.add?
```
で表示されます。
関数の説明のみならず、引数の種類や使用例まで載っており、情報量がとても多いです。
英語なので慣れていないと苦痛に感じるかも知れませんが、是非参考にしていただきたいです。

# 「便利だなぁ～」な関数
### np.flip
配列を反転します。

```python
a = np.arange(10)
np.flip(a)
-> array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
```
ベクトルであればスライス（[::-1])で事足りますが、行列の場合などに重宝しそうです。
行列の場合、axisを指定すると任意の方向にひっくり返すことができます。

```python
a = np.arange(9).reshape(3,3)
np.flip(a)
-> array([[8, 7, 6],
          [5, 4, 3],
          [2, 1, 0]])

np.flip(a, axis=0)
->array([[6, 7, 8],
         [3, 4, 5],
         [0, 1, 2]])

np.flip(a, axis=1)
-> array([[2, 1, 0],
          [5, 4, 3],
          [8, 7, 6]])
```

### np.eye
単位行列を生成します。

```python
np.eye(3)
-> array([[1., 0., 0., 0.],
          [0., 1., 0., 0.],
          [0., 0., 1., 0.],
          [0., 0., 0., 1.]])
```

### np.diag
対角成分を抽出します。

```python
a = np.random.randint(0,10, (3,3))
print(a)
-> [[5 2 8]
    [2 7 5]
    [5 1 0]]
p.diag(a)
-> array([5, 7, 0])
```
### np.tile
配列を敷き詰めます。

```python
a = np.array([[0, 1], [1, 0]])
np.tile(a, (2,2))
-> array([[0, 1, 0, 1],
          [1, 0, 1, 0],
          [0, 1, 0, 1],
          [1, 0, 1, 0]])
```
### np.bincount
配列中の数値（非負、int型）をカウントし、その値のindexに格納します。

```python
a = np.random.randint(0, 10, 10)
print(a)
-> array([8 6 0 8 4 6 2 5 2 1])
np.bincount(a)
-> array([1, 1, 2, 0, 1, 1, 2, 0, 2], dtype=int64)
```
### np.repeat
要素を指定した数だけ繰り返します。

```python
np.repeat(3, 4)
-> array([3, 3, 3, 3])
```
### np.roll
配列を指定した数だけ右にシフトします。

```python
a = np.arange(10)
np.roll(a, 2)
-> array([8, 9, 0, 1, 2, 3, 4, 5, 6, 7])
```
### np.flatten
元の配列を1次元配列に直します。

```python
a = np.arange(9).reshape(3,3)
print(a)
-> [[0 1 2]
    [3 4 5]
    [6 7 8]]
b = a.flatten()
print(b)
-> [0 1 2 3 4 5 6 7 8]
```
### np.nonzero
0以外の値が含まれているindexを教えてくれます。

```python
a = np.array([1,0,0,1])
b = np.array([1,1,1,1])
print(np.nonzero(a))
-> (array([0, 3], dtype=int64),)
print(np.nonzero(b))
-> (array([0, 1, 2, 3], dtype=int64),)
```
### np.copysign
第1引数の符号を第2引数と同じ符号に変換します。

```python
a = np.arange(10)
b = np.repeat([1, -1], 5)
np.copysign(a, b)
-> array([ 0.,  1.,  2.,  3.,  4., -5., -6., -7., -8., -9.])
```

### np.intersect1d
2配列の共通する要素を取り出します。

```python
a = np.arange(10)
b = np.arange(5, 15)
np.intersect1d(a, b)
-> array([5, 6, 7, 8, 9])
```

#最後に
こういった関数は暗記するものではありませんが、そもそも知らないと使うことができません。
ご紹介した関数達が皆様の頭の片隅にでも残っていただけるととても嬉しいです！
ドキュメントを書こう - メリットと誤解

ポエムです。

## ドキュメントを書くことのメリット 

### 1. 時間的制約から解かれる。
- 同じことを何度も言わなくてよくなる。
- その場に居られない人、将来一緒に働く人にも伝わる。

### 2. 空間的制約から解かれる。
- 良いことを多人数に広められる。
- 他事業所の人にも広められる。

### 3. 自分にとって
- 浮いた時間でもっと好きなことや新しいことができる。



## ドキュメントに依存することの誤解

### 誤解: ドキュメントに依存してはコミュニケーションの機会が減るのでは？

コミュニケーション、チームビルディングと情報共有は別物。

#### 情報共有は仕事。

 例: 〇〇で〇〇のようなトラブルが起こっている。原因は〇〇にありそうで、〇〇までに解決の必要がある。
 例: 〇〇の場合には〇〇の承認フローを経てプログラムを修正する。

 →皆が均等に必要とする情報

#### コミュニケーションがむしろできるようになる。

 例: 〇〇のこどもが何歳になった。

 →皆が均等に知らなくても良い。あるいは、嬉しい話なら何度言っても良い。

### 誤解: それでも「言ったほうが早い」のでは？

#### 書いておけばもっと早い。

例: 「ここに書いてあるよ。」で、余った時間で雑談できる。


## 参考

https://qiita.com/yasuoyasuo/items/1eb7298f91a44dce7abc

### [GitLab Communication](https://about.gitlab.com/handbook/communication/)

https://qiita.com/e99h2121/items/ea5822922d83d00ebc4a

https://www.itmedia.co.jp/enterprise/articles/2010/22/news048.html


等など。以上参考になればさいわいです
Oculus Questで3Dアバターを動かしたい

<img width="480" alt="スクリーンショット 2020-01-02 0.21.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348026/276c5527-02f8-d9e1-884c-c9a26282371d.png">



---

##はじめに
- VRChatっぽい感じで3Dアバターを動かしたいです
- Final IK(知らない方はスルーで構いません)は使わず、無料でやっていきたいです(90ドルはなかなか気合い入れないと買えないですね...)
- 3点(頭と両手)が追従され、自分の動きに合わせて動くことをゴールとします
- 結論から言うと、OVRPlayerControllerの下にunitychanのオブジェクトを入れるだけでした...
- ので、下はまじめに読まず読み飛ばすことをお勧めします。

##環境
- Windows 10
- Unity 2019.3.6
- ユニティちゃん 1.2.1
- XR Mecanim IK Plus
- Oculus Integration ver.15

##まずは3点の追従
```(補足)そもそもユニティちゃんとは...
「ユニティちゃん」はUnity Technologies Japanが
提供する開発者のためのオリジナルキャラクターです。(公式サイトより引用)
```

開発者のために無料配布されています(規約あり)。開発がはかどりますね。


本筋の3点追従ですが、[こちら](https://qiita.com/Satoshi_Takahama/items/9d8effe5f1261b9fc498)の記事などがとてもとても参考になりました。

注意点としては、
こちらの記事で登場する○○AnchorというGameObjectは自分でCreate Emptyして生成しなければならないということくらいですかね

##できた！あれ...？
<b>このままだと鏡の前で直立しているところから一生動けません。(たぶん)</b>
<img width="480" alt="スクリーンショット 2020-01-02 0.21.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348026/d4794487-88d8-f4d3-642f-8c8ea717eed0.png">


OculusのSDKのOVRCameraRigというものを使っているからですね。
動きたい場合には、代わりに、OVRPlayerControllerというPrefabを使います。

このPrefab、よくみるとOVRCameraRigを内包しています。
<img width="480" alt="スクリーンショット 2020-01-02 0.21.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348026/4b55e305-a5a1-8ec8-786c-1d286da3daef.png">

ので、このPreafabをScene上に生成したうえで、上の記事で見たやり方と全く同じことをここのOVRCameraRigでやればいいわけですね。
もう一度やるのが面倒な人はすり替えるだけでもokだと思います。


##できた！あれあれ...？
グロいのでスクショは控えますが、<b>PlayerControllerとユニティちゃんが分離してしまう瞬間が出てしまいます。</b>悲しい...
ユニティちゃんの体もControllerについてくるようにしたいです。

ので、以下のようにOVRPlayerControllerの中にunitychan_VRAvatarを置きます。
<img width="480" alt="スクリーンショット 2020-01-02 0.21.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348026/c6374b14-1872-6ca0-0b81-c57199087b98.png">


これで、自分の体の動きに合わせてユニティちゃんの身体も追従してくれるようになりました。
(微妙に身体の位置がずれる場合は、CameraRigの高さを変えるなど地道なパラメータ調整がむばってください

##動きが微妙に変...
追記します。

##追記1
↑このあと紆余曲折あり、ユニティちゃんがまともに動くようになるまで1日溶かしました。。。
最終的な構成は以下です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348026/d659a47e-49d1-ce1f-998e-d9724d5510b8.png)

また、MechanimIKK Plusのスクリプトは「unitychan_VRAvatar」以外には<b>つけない</b>のがポイントです。
unitychan_VRAvatarにつけたMechanimのスクリプトはこんな感じです。

<img width="480" alt="スクリーンショット 2020-01-02 0.21.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348026/b8a0abc0-4598-3496-a427-7dc77fd09fe5.png">

今後追記したいこと
- 足の動きが微妙に変なのでなおす
- idleやrunのアニメーションをつける




##参考
[OculusQuestでXR Mecanim IK Plusを使用してユニティちゃんを動かしてみる](https://qiita.com/Satoshi_Takahama/items/9d8effe5f1261b9fc498)
[Mechanim IK Plus](http://chobi-glass.com/Unity/XR_MecanimIKPlus.html)
rspecで実行している動作をbinding.pryを確認する方法【メモ】

```ruby
$ pry(..)> val
```
have_content()メソッドでビューのテストもしている場合、テストでは画面が出てこないので、変数の中身がわかるだけではデバッグしようがない。

そんなときは今見ているURLを確認。なんらかの原因で違うURLを見てる場合もある。

```ruby
$ pry(..)> current_url
```
URLは問題ないとなれば、実際にHTMLをチェック。

```ruby
$ pry(..)> page.html
```
か、もしくはテキストだけをチェックもできる。

```ruby
$ pry(..)> page.text
```

[Capybaraチートシート](https://qiita.com/morrr/items/0e24251c049180218db4)
Railsでデフォルトのアプリケーションサーバ、Pumaについて

##はじめに
今まではあまり気にしてこなかったのですが、そろそろ $ rails server したときに表示されるpumaについて知っていた方がいいなと思い調べたのでまとめておきます。

筆者は初学者なので間違いがあれば優しく教えていただけると幸いです。
##Pumaとは何か
Pumaとは、webサーバとしての機能もあるアプリケーションサーバです。

と言われて、自分は何言ってるのか分からなかったので1から説明します。

###・webサーバとは
ユーザーからのリクエストを必要に応じてアプリケーションサーバに渡すプログラムです。
有名なものではNginx(エンジンエックス)などがあります。
###・アプリケーションサーバとは
webサーバからのリクエストをrailsアプリケーションに渡す橋渡し的な存在です。
例えばユーザーがなんらかのリクエストをwebページに送ったとします。このリクエストは
#####webサーバ → アプリケーションサーバ(Pumaなど) → Rack → Railsのrouter → controller
という風に受け渡されて、アプリケーションで処理が行われます。

Rackについてはアプリケーションサーバとアプリケーションを繋ぐ魔法と思ってください。
##Pumaの特徴
マルチスレッドで大量のアクセスを効率的に処理することができるそうです。
複数のことを同時に(並列処理で)できるので、速いのだと思います。
##終わりに
自分用にまとめてみた感じなので、読みにくいかもしれません。
参考にした記事たちを紹介しておきます。僕みたいな初学者におすすめの記事たちです。

https://qiita.com/jnchito/items/3884f9a2ccc057f8f3a3
https://kitsune.blog/rails-summary
VeeValidate3のfile|image系バリデーションの@change="validate"を関数で呼び出す

↓下記の記事にたどり着けたなら正直このQiitaは不要かも知れません。
https://logaretm.github.io/vee-validate/advanced/file-validation.html#html-file-validation

この記事はVeeValidate3の記事です。
VeeValidate2では書き方が異なります。

# refを使ってVeeValidateのvalidateを外の関数から呼び出そう！

ref属性にはDOM要素のオブジェクトとコンポーネントインスタンスが登録されています！
中を追って見るとfileもちゃんと入ってるから関数側で色んな事ができますね！！

[vm.$refs](https://jp.vuejs.org/v2/api/index.html#vm-refs)

validate関数はただ呼び出して上げるだけでruleに則したエラーを吐いてくれます！

```vue
<template>
  <ValidationProvider rules="required|image" ref="provider" v-slot="{ validate, errors }">
    <input type="file" @change="handleFileChange" />
    <p>{{ errors[0] }}</p>
  </ValidationProvider>
</template>

<script>
export default {
  methods: {
    handleFileChange(e) {
      // NOTE: refはValidationProviderタグで定義したproviderの中にslotのvalidateが入ってる！
      this.$refs.provider.validate(e);

      // ここ以降に自由にfile changeした時にやりたい処理を書こう！！
    }
  }
};
</script>

```

## まとめ
最初に紹介したこのVeeValidate公式を読めばオールオッケイ！！
https://logaretm.github.io/vee-validate/advanced/file-validation.html#html-file-validation

この記事マジでいらねえぞ！？
せっかく書いたし消すのもあれだな…。

検索苦手な方の手助けになれば…なるかな？？

参考にこの一休.comさんの記事も読んで見てください！
[VeeValidate 2から3へのアップデート](https://user-first.ikyu.co.jp/entry/2019/12/03/000000)
初心者のKubernetes入門（書籍 Kubernetes 実践入門の写経から学ぶ）ReplicaSet 編

# 背景
個人的にインフラの知識以上にこれからのアプリケーションが動く環境を作ってデプロイしたりしてこれからの知識を身に着けたい。そしてより一層、自分の知識のアップデートをしたいと思いました。

その中でこの本に出会い、これから少しずつやったことを残し、未来の自分への手紙としてもあり、見つめ直せればと思いました。

# 引用や参考と今回の自分の勉強用の書籍の紹介
[技術評論社『Kubernetes実践入門』のサンプルコード](https://github.com/kubernetes-practical-guide/examples)
[Kubernetes実践入門 プロダクションレディなコンテナ＆アプリケーションの作り方](https://gihyo.jp/book/2019/978-4-297-10438-2)
![](http://image.gihyo.co.jp/assets/images/cover/2019/9784297104382.jpg)


## 実際の学びについて

書籍を読みながら、章ごとに少しずつ進めていきたいと思います。
GitHub のソースコードも使いながら学んで行きたいと思います。

# 勉強開始

ここから ReplicaSet を学んでいきます。

- https://github.com/kubernetes-practical-guide/examples/tree/master/ch1.3.4

```yaml:my-rs.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: my-rs
spec:
  replicas: 3 #Podレプリカ数 (1)
  selector:
    matchLabels:
      app: my-rs
  template: #Podレプリカの元となるPodテンプレート (2)
    metadata:
      labels:
        app: my-rs
    spec:
      containers:
      - name: nginx
        image: k8spracticalguide/nginx:1.15.5
```

# コマンド郡

## ReplicaSet のマニュフェストファイルを適用する

```
$ kubectl apply -f my-rs.yaml
```

## Pod を削除してみる
```
$ kubectl delete pods my-rs-zkhfd
```

## Dashboad からの確認

<img width="1113" alt="スクリーンショット 2020-04-08 22.00.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174596/f0ed2743-a30e-c243-f745-4b60bb69d625.png">

一つの Pod を削除してすぐにスクリーンショットとったので見ずらいかもしれませんが、上から４番目が削除されている状態だっと思います。

## 次は Deployment をやっていきます。
今は多分コツコツと基礎部分だとおもいます。

ブルーグリーンデプロイメント、カナリア、イミュータブルとか色々あると思うけど、一旦はデプロイを学び
コンテナでのリリース方法として親和性が高いものがなにかを自分なりに学んで行きたいと思います。

# 最後に

世間は色々と今の時期（2020/04/09）時点で大変な時期ではありますが、エンジニアリングで未来の自身に少しでも明るくなれるように！
ユニークなIDを生成するuuidの3系 -> 7.0.3に対応(Deep requiring like `const uuidv4 = require('uuid/v4');` is deprecated)

## ユニークなIDを付与したい

例えば、あるオブジェクトに対して、ファイル名などの被りによって処理に競合が発生してしまうとしましょう。

そんな時に使うパッケージがuuid。

使い方は皆さん下記参照。


[uuid | npm](https://www.npmjs.com/package/uuid)

### uuid 3系 -> 7.0.3にアップデート

importの仕方が変わります。
これをしないとdeprecationのWarningが出続けます。

```
console.js:39 Deep requiring like `const uuidv4 = require('uuid/v4');` is deprecated as of uuid@7.x. Please require the top-level module when using the Node.js CommonJS module or use ECMAScript Modules when bundling for the browser. See https://github.com/uuidjs/uuid#deep-requires-now-deprecated for more information.
```

importは以下のように変更します。

```
- import uuidv4 from 'uuid/v4';
+ import { v4 as uuidv4 } from 'uuid';
```

これで、Warningは消えます。

以上、久々に仕事で記事を書くネタがあったので戦闘力(Contributions)を上げるために投稿してみました。
リバースプロキシを設定しててもSpringでFlashAttributeしたい！（しない）

# 結論
アクセスするURLとSpringが受け取るリクエストURLが異なると、FlashAttributeしてもリダイレクト先にパラメータを渡せないぞ！！

# 事の始まり

例えば、`domain/~`のリクエストを`domain/hoge/~`に変更するプロキシが組まれていたとします。
きっとこんな感じ:kissing:（適当）

```nginx.conf
  location / {
    proxy_pass http://tomcat:8080/hoge/;
  }
```

その中で、RedirectAttributesのaddFlashAttributeを実行したところ、リダイレクト先でマッピングされない事態に遭遇しました。
たぶんこんな感じ:kissing_heart:（さらに適当）

```HogeController.java
@RequestMapping(value="/hoge/save", method = RequestMethod.POST)
public String save(@ModelAttribute("form") HogeForm form, RedirectAttributes redirectAttributes) {
        :
        :
    redirectAttributes.addFlashAttribute("form", form);
    return "redirect:/complete";
}

@RequestMapping(value="/hoge/complete", method = RequestMethod.GET)
public String complete(@ModelAttribute("form") HogeForm form) {
    log.info(form); // 空っぽ！！
    return "hoge.html";
}
```
FlashAttributeなんて余裕やろ！と思っていた矢先に起きた問題。
リバースプロキシ方面から調査したのですが、原因が全くわからず。。。

:thinking:　:thinking:　:expressionless:　:sleepy:　:sleeping:

# 数日後

:desktop:「RedirectAttributesがダメなら、FlashMapを直接使えばいいじゃない」

なんという暴論！と思いながら実装方法を眺めていると、setTargetRequestPathというメソッドを呼んでいる。。。

:hushed:・・・ターゲットの・・・・パス？

# 説明しよう！！
何が起こっていたかというと、リダイレクト先のパス(`/complete`)と、リダイレクトされたパス(`/hoge/complete`)が不一致であったため、FlashMapの値がバインドされていなかったのだ！！

# 改修例
こういう改修をすれば、リバースプロキシを設定していてもリダイレクト先へパラメータを渡せるようになる。

```AbstractController.java
protected String redirect(String path, Map<String,Object> attributeMap) {
	// 内部パス(@RequestMapping(value)の値)
	String innerPath = "/hoge" + path;
	// FlashMapに詰め替え
	FlashMap flashMap = new FlashMap();
	attributeMap.forEach(flashMap::put);
	// FlashMapのターゲットを内部パスに設定
	flashMap.setTargetRequestPath(innerPath);
	// FlashMapのセット
	RequestContextUtils.getFlashMapManager(request).saveOutputFlashMap(flashMap, request, response);
	// リダイレクト先は外部パス(ブラウザからのアクセス先)
	return "redirect:" + path;
}
```
```HogeController.java
@RequestMapping(value="/hoge/save", method = RequestMethod.POST)
public String save(@ModelAttribute("form") HogeForm form) {
        :
        :
    return redirect("/complete", Map.of("form", form));
}
```
rewriteを使っていて、今回のように内部パスと外部パスが単純に置き換えられない場合も、原理は一緒なので**頑張って**内部パスと外部パスを指定してください。

FlashMapについては、以下の記事でわかりやすく書いてありました。もっと早く見つけたかった。。。:innocent:
[SpringMVCでRedirectAttributesを使用せずにリダイレクト先に値を渡す](https://qiita.com/d-yosh/items/98acd27a396042b0c139)
windows DvorakJ dvorakとqwertyの切替

### 前書き
windows10で、画面をタッチするタイプのソフトウェアキーボードのレイアウトをレジストリ変更で変えた。
この場合、いわゆるwindows設定GUIから日本語配列・英字配列の切り替えができなくなる事象が発生した（そもそも再起動して切り替えるのを億劫に感じた）ので、DvorakJでの切り替えの個人設定をメモしておく。

正攻法は[こちら](https://qiita.com/shimizu14/items/000cceb9e72a492b9176)(Windows10日本語版で英語配列キーボードを使用する - Qiita)

の通り、GUIの[時刻と言語設定]→[言語]→[優先する言語：日本語]→[オプション]→[ハードウェア キーボード レイアウト]→[レイアウトを変更する]
で、[日本語キーボード(106/109 キー)]と[英語キーボード(101/102 キー)]を切り替え再起動。


## 日本語配列使用時※記号は英字配列

設定は
\data\lang\eng\Dvorak
└Dvorak 配列 (blechmusik 版).txt
を選択。

qwertyが使用したくなったら[DvorakJの実行を停止/再開する]を切り替えると良い


## 英字配列キーボードを使用時
[ウィンドウを表示する]→[キーボード]→[101キー（英語配列）のキーボードを使用している]にチェック

これをすると
[DvorakJ:レファレンスマニュアル:キー配列:直接入力用配列](https://blechmusik.xii.jp/dvorakj/wiliki.cgi?DvorakJ%3A%E3%83%AC%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9%E3%83%9E%E3%83%8B%E3%83%A5%E3%82%A2%E3%83%AB%3A%E3%82%AD%E3%83%BC%E9%85%8D%E5%88%97%3A%E7%9B%B4%E6%8E%A5%E5%85%A5%E5%8A%9B%E7%94%A8%E9%85%8D%E5%88%97)
で言及のある、
> ただし、英語配列の最上段左端のキー `~ については、三段目右端の項目を使用し、二段目右端のキー \|については、一段目右端の項目を使用します。
が有効になる。（しないと打てない記号が発生する）

設定は
\data\lang\eng\Dvorak
└Dvorak 配列 (英語配列キーボード版).txt
を選択。

qwertyが使用したくなったら
\data\lang\eng\QWERTY
└QWERTY 配列 (ASCII 配列版).txt
を選択。

このやり方だと英字配列キーボード使用時のqwerty切り替えは[DvorakJの実行を停止/再開する]ではできないことに注意

### TIPS
英字配列キーボードだと半角/全角の切り替えはAlt+`であることが多いが、CapsLockのキー押下に代わりに割り当てると運指が多少減る運用ができそう
（英字キーボードでのCapsLock有効/無効切替はShift+CapsLockで、その意味では干渉しないため）
Maixduinoでストリーミングする

# はじめに

[Maixduino](https://www.seeedstudio.com/Sipeed-Maixduino-Kit-for-RISC-V-AI-IoT-p-4047.html) はマイク、WiFiが付いているので、マイクで拾った音をストリーミングしてみます。


![streaming.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555397/f5463f50-f69f-3605-095a-ea3c76d9e585.png)

# 準備

- [Maixduino](https://www.seeedstudio.com/Sipeed-Maixduino-Kit-for-RISC-V-AI-IoT-p-4047.html) まずはこれ
![Maixduino](https://media-cdn.seeedstudio.site/media/catalog/product/cache/ab187aaa5f626ad16c8031644cd2de5b/m/a/maixduino-kit_1.jpg)

# コード

WebSocketを使用してストリーミングするところは、[WebAudio+WebSocketでブラウザへの音声リアルタイムストリーミングを実装する](https://gist.github.com/ykst/6e80e3566bd6b9d63d19) を参考にさせて頂きました。

コードは [GitHub](https://github.com/fukuen/maixduino-audiostreaming-demo) をご覧ください。

SiPeed社から提供される標準のArduinoライブラリーに加えて、以下のライブラリーを使用しています。

### ESP32 WiFi

PlatformIOで使用するSiPeed社のArduino SDKはM1wに内蔵されているESP8265用のため、Maixduinoで使用しているESP32はそのままで使えない。そのため、[ESP32 WiFi](https://github.com/fukuen/Maixduino_WiFiEsp32) を使用する。（[MaixduinoでWiFiを使用する](https://qiita.com/fukuebiz/items/9cf9bd3d685a1a9ecf4b) 参照）

### Base64

[Arduino-Base64](https://github.com/adamvr/arduino-base64)

### SHA1

[SHA-1 implementation in C++](https://github.com/vog/sha1)

# 最後に

LAN内のPCのFirefoxで表示されるIPアドレスを、 http://192.168.xxx.xxx/ のように開くとマイクで拾った音がPCから聞こえます。
新型コロナウイルスと地価

COVID-19のプロット記事が多いので自分も何か一つ書いてみたいと思いました。
雑な記事ですみません。
#感染者の数
新型コロナの区別の感染者数は[ここ](https://www.fukushihoken.metro.tokyo.lg.jp/hodo/saishin/corona170.html)で見られます。
2020/04/07日付では以下の様になっています。
この表を見ての自分の感想は**人口に対して港区の感染者数は多すぎじゃないか**という事でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299928/aa9d48bc-5b27-01fc-89cb-8fb133c7eabd.png)


そこでよくよく見直してみると感染者の数を人口で割った数は区によってまちまち気付きました。
ここで**「地価」**の高い場所(人の集まる需要が高い場所)が感染率が高いのではと仮説を立てました。

#23区の人口、患者数、患者数/人口、公示地価
患者数/人口と各区の公示地価を比較したのが以下の表です。
港区はほかの高めの目黒、渋谷、中央区と比べても倍くらいの患者数/人口です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299928/55504b44-6ea3-2bc6-c568-4619f9a41049.png)

#地価vs(患者数/人口)プロット
横軸を地価の対数表示として縦軸(患者数/人口)をプロットしました。
ある程度、地価との相関は見られましたが、**それでも港区は多いです。**
地価ではなくもっと患者数を説明できる変数はないものですかね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299928/38d97e68-296c-7c7f-deb8-b80218f1b246.png)

#自省
金持ちへの妬みはやめましょう。
[Rails6.0 + Nuxt.js] response.headersにcorsのexpose（access-tokenなど）が入らない

## この記事を書くにいたるまで

現在Rails6.0とNuxt.jsを使って適当にアプリを作っています。（Nuxtの練習です
RailsはAPIモード、認証には`devise_token_auth`を使用しており、
Nuxtからaxios経由でpostしてtoken認証を行うアプリになっています。

今回loginをaxiosで行ったのですが、そのresponse（`response.headers`)の中に
`access-token`や`client`などが格納されていないというトラブルが発生しました。
解決すると「こんなことで…」と思いますが、ほぼ１日ハマってしまったので共有です。

## ぶつかった壁
まずnuxt側ですが、以下のようにloginアクションを実装しています。

```javascript:login.vue
  async login(vuexContext, data) {
    await this.$axios.post("/api/v1/auth/sign_in", data)
      .then(response => {
        console.log(response.headers)
      })
      .catch(e => {
        console.log(e)
      })
  }
```

次にrails側ですが、CORS対策としては`rack-cors`を導入しています。
以下corsの設定です。

```rb:config/application.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'localhost:3001'

    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head],
      expose: ['access-token', 'expiry', 'client']
  end
end
```

exposeに`'access-token', 'expiry', 'client'`を記述しています。
通常だとこれで`response.headers`内に上記３つの結果が表示されるはずです。

しかし以下のような結果しか表示されませんでした。

```console.log(response.headers)
headers:
  cache-control: "max-age=0, private, must-revalidate"
  content-type: "application/json; charset=utf-8"
```

chrome-devtools => [Network] => `Response Headers`を見たところ、
こちらにはaccess-tokenの情報が来ているのですが、
responseというオブジェクトから取り出すことができません。

## 解決策
調べたところ、rack-corsのissuesにたどり着きました。
するとどうやら`Rack::Cors`という設定が重複しているようです。

念のため`git grep Rack`を実行したところ、なんと`config/initializers/cors.rb`が見つかり
そこに同じ設定がありました…（それまで`config/application.rb`に書いていました）

コメントアウトされていたので重複はしていないはずですが、
そもそもの設定を書く場所が間違っていたことになります。

設定を`config/initializers/cors.rb`に移行し再ログインしたところ、
うまくheadersに反映されました。


```rb:config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'localhost:3001'

    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head],
      expose: ['access-token', 'expiry', 'client']
  end
end
```

結果

```console.log(response.headers)
headers:
  access-token: "VPPrzn2DnJuqJi_uDEI4hg"
  cache-control: "max-age=0, private, must-revalidate"
  client: "TVmLwY1GM23koi9r9HY17g"
  content-type: "application/json; charset=utf-8"
  expiry: "1587634926"
```

おわり
【SQL】LIKE / 関数

この資料は弊社後輩に説明するために扱った＆口頭説明の補助的資料です。
せっかく纏めたので記念に残しておくかだけのものです、悪しからず。

---

# 昨日の答え合わせ
6. 国名に 'United' を含む国の国名を特定する。

---

# WHERE - LIKE
文字列の検索を行う。
`LIKE` だけだと、完全に一致した結果しか出力されない。

「部分一致」や「前方一致」「後方一致」するような検索がしたい！
-> そんなときに「**ワイルドカード**」なるものが使える。

---

# ワイルドカード
何にでも代用が効く文字のこと。
トランプでいうとこのジョーカーみたいな。
SQL ではワイルドカード文字は2種類ある。

文字 | 意味
--- | ---
_ | 任意の1文字
% | 0文字以上の任意の文字列

### 使用例
「キューバ」を検索したいけど C のあとのスペルに自信ないな...って時。

```sql
SELECT *
FROM world
WHERE name LIKE 'C_ba'
```

「A」から始まる国名を検索したい時。

```sql
SELECT *
FROM world
WHERE name LIKE 'A%'
```

末尾が「Y」で終わる国名を検索したい時。

```sql
SELECT *
FROM world
WHERE name LIKE '%Y'
```

とりあえずどこの位置にあるか分からないけど「RI」を含んでいる国名を検索したい時。

```sql
SELECT *
FROM world
WHERE name LIKE '%RI%'
```

---

# シングルクォーテーション / ダブルクォーテーション
「どっちも一緒じゃね？🤔」に対する答えとしては
-> **扱う DBMS によって差がある**

だいたいの標準 SQL の仕様では
`''` : 文字列定数として扱う
`"" ` : カラム名として扱う

MySQL という DBMS では
`''` : 文字列定数として扱う
`"" ` : 文字列定数として扱う
``` `` ``` : カラム名として扱う

---

# ついでにエスケープ処理
例えば、ある値の中に「I'm」とか「Taro's」とか「100%」などの言葉が入っているものを調べたい...！というとき。
`'` や `%` は単体だと囲っている文字やワイルドカードとして認識されてしまう。
そこで、`'` や `%` を「ただの記号だよー意味ないよー」という印をつけてあげる必要がある。
その「ただの記号だよー意味ないよー」という印をつけてあげることを **エスケープ処理** という。

* `'` なら `'I''m Tsumako'` のように `'` を重ねる
* `%` なら `'100%%'` のように `%` を重ねる
* `'I\'m Tsumako'` や `'100\%'` のようにエスケープしたい文字の前に `\` をつける

---

# AND / OR
AND (∧) : どちらにも当てはまる
OR (∨) : どちらか一方当てはまれる

`+-*/` に計算の優先順位があるように、`NOT > AND > OR` の順で優先される。
意図通りに処理させたい場合は `()` を用いる。

---

# XOR

### 排他的論理和
(もはや数学の授業やんけ...)
2つのうち1つだけ正しければ正しい、というもの。
両方合ってる、両方間違っているものはダメになる。
数学的例でみると...

* A は真、B は真 -> 偽
* A は真、B は偽 -> 真
* A は偽、B は真 -> 真
* A は偽、B は偽 -> 偽

になる。

---

# 関数 - ROUND(数値関数)
端数を丸めてくれる関数。
ROUND(n [,m ]) というように使う。
n には端数を丸めたいものを入れ、m には小数点以下何桁で丸めるかを整数で指定する。
m は省略も可能で、省略すると 0 桁で丸める。
m にはマイナスの値も指定できる。

```sql
SELECT name, ROUND(population, -4)
FROM world
WHERE population >= 200000000
```

数値だけじゃなくて日付に対しても使える。

---

# 関数 - LENGTH
文字列の文字数を求めてくれる関数。
使用する DBMS によって `LEN` だったり `CHAR_LENGTH` だったり違うので注意。
今回は `LENGTH` で OK！

```sql
SELECT name, LENGTH(name)
FROM world
WHERE LENGTH(name) > 20
```