OmniAICreator/Qiita-1.07M huggingface dataset:
神Excelの神カレンダー(?)から日付を導く

## 神カレンダーとは

悲しいかな、日付に相当する部分がこうなってるExcelに遭遇することが、稀によくあります...

|年月|日|
|---|:-:|
||11|
||12|
||...|
||19|
|2020年4月|20|
||21|
||...|
||29|
||30|
||1|
||2|
||...|
||14|
|2020年5月|15|
||16|
||...|
||30|
||31|
||1|
||2|
||...|
||9|
|2020年6月|10|
||11|
||...|
||20|

年月や日は、書式設定でそうなっているのではなく、それぞれ文字列と数値で格納されています。
人間が読む分には問題ないExcelですが、データとして処理する際の苦しみポイントは、

- 年月の文字列は、その月内の特定の日の隣にあるわけでなく、「真ん中らへんのどこか」に入力してある。
- カレンダー開始日、終了日ともに月の途中の場合がある。

といったところでしょうか。
年月が必ずその月内の先頭の日の隣に入力してあれば、「下方向にフィル」でなんとかできるので、セルが結合されているほうが良いという珍しい(?)ケースでもあります。

## 神カレンダーから日付を導出する

### サンプル

```
let
    GodCalendar = #table(
        type table [年月 = text, 日 = Int64.Type],
        {
            {null, 11}, {null, 12}, {null, 13}, {null, 14},
            {null, 15}, {null, 16}, {null, 17}, {null, 18}, {null, 19}, {"2020年4月", 20}, {null, 21},
            {null, 22}, {null, 23}, {null, 24}, {null, 25}, {null, 26}, {null, 27}, {null, 28},
            {null, 29}, {null, 30},
            {null, 1}, {null, 2}, {null, 3}, {null, 4}, {null, 5}, {null, 6}, {null, 7},
            {null, 8}, {null, 9}, {null, 10}, {null, 11}, {null, 12}, {null, 13}, {null, 14},
            {"2020年5月", 15}, {null, 16}, {null, 17}, {null, 18}, {null, 19}, {null, 20}, {null, 21},
            {null, 22}, {null, 23}, {null, 24}, {null, 25}, {null, 26}, {null, 27}, {null, 28},
            {null, 29}, {null, 30}, {null, 31},
            {null, 1}, {null, 2}, {null, 3}, {null, 4}, {null, 5}, {null, 6}, {null, 7},
            {null, 8}, {null, 9}, {"2020年6月", 10}, {null, 11}, {null, 12}, {null, 13}, {null, 14},
            {null, 15}, {null, 16}, {null, 17}, {null, 18}, {null, 19}, {null, 20}
        }
    ),
    年月日のnullではない最初と最後の要素取り出す = List.Transform(
        {GodCalendar[年月], GodCalendar[日]},
        each
            let
                rn = List.RemoveNulls(_),
                fl = {List.First(rn), List.Last(rn)}
            in
                fl
    ),
    それらをガッチャンコして日付に変換する = List.Transform(
        List.Zip(年月日のnullではない最初と最後の要素取り出す),
        each Date.FromText(_{0} & Number.ToText(_{1}, "0日"))
    ),
    開始日と終了日がゲットできたのでリストにする = 
        let
            start = それらをガッチャンコして日付に変換する{0},
            end = それらをガッチャンコして日付に変換する{1}
        in
            List.Dates(
                start,
                Duration.Days(end - start) + 1,
                #duration(1, 0, 0, 0)
            ),
    元テーブルに追加 = Table.AddColumn(
        GodCalendar,
        "日付",
        each Function.ScalarVector(
            type function(dummy as any) as any,
            (inputTable) => 開始日と終了日がゲットできたのでリストにする
         )([0]),
         type date
    )
in
    元テーブルに追加
```

### 結果

![Results.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239258/f091a655-e1b6-36e5-d7d8-41f90acafb4c.png)

### 注意点

今回のサンプルの場合、神カレンダー側に余分な日(同じ日がダブってるなど)がある場合、エラーが出るので気づくことができますが、抜けている場合はエラーが出ません。
最初と最後だけ見てるので、途中の月の表記が間違っていれも問題ないというメリットはありますが、基本的には、神カレンダー側もカレンダーとして矛盾がない必要があり、想定される矛盾の内容によって、対応方法を変える必要がありそうです。

## そもそも

「日」の部分の「値」がちゃんと日付になってさえいれば問題ないわけで、**再利用しやすいExcelの作り方**を地道に啓蒙していくのも大切ですね(職場環境によってはそっちのほうが難しいかもしれませんが...)
application.controllerでのインスタンス変数設定

スクールでのチーム開発にて詰まった箇所を共有します。

●バージョン
　ruby 2.5.3
　Rails 5.2.4.2

# 詰まった箇所

チーム開発中のフリーマーケットアプリにて、アプリ全てのページに適用するheaderをview/layout/_header.html.hamlで作成。
上記ファイルに、items.controllerで以下のインスタンス変数をビューに渡し、ancestryを導入しカテゴリーのプルダウンメニューを実装。
その後、ログイン画面へ移動した際にエラーとなる。

以下、順番にコードを記載。

```
#items_controller.rb
def index
 @parents = Category.all.order("id ASC").limit(13)
end
```

ancestryを導入し、カテゴリー実装、headerにてjQueryを使用したプルダウンメニューを作成。
以下は、_header.html.hamlの記述。

```
        .head__in__nav__left__cate
          カテゴリー
          %ul.category1
            - @parents.each do |parent|
              %li.parent__list
                = link_to parent.name
                %ul.category2
                  - parent.children.each do |child|
                    %li.child__list
                      =link_to child.name
                      %ul.category3
                        - child.children.each do |grandchild|
                          %li.grandchild__list
                            = link_to grandchild.name
```

インデックスページではプルダウンメニューは問題なく動作。
https://gyazo.com/ce06546f7171b6814d343099c952770d

ここまで完成し、ログインして商品出品関連の実装に入ろうとしたところ以下のエラーと遭遇。
https://gyazo.com/ff22ac1a2e297e90f61cdf407c62c7e4

Devise::session#newで@parentsがnilと言われている。
確かに、今のままでは、items.controllerの範囲内でしか@parentsが飛ばせていない。


# 解決策

application_controllerに以下を記載することで解消

```
  before_action :set_category, if: :devise_controller?
  def set_category
    @parents = Category.all.order("id ASC").limit(13)
  end
```

if: :devise_controller?とすることで、deviseが動くときは必ず@poarentsが作成される形で記述しエラーは解消。
最終的には、アプリ全体で使用するheaderのため、if: :devise_controller?不要になると思われる。
このあたりはチームメンバーと相談して検討しようと思います。

# 最後に
解決してみれば当たり前すぎる結論だったのですが、自身で検索した際に目ぼしい情報に巡り合えなかったので、共有のため記事を投稿しました。

上記の他にも、deviseコントローラーを作成し、Devise::session#new等で@parentsを設定する形も可能ですが、わざわざこの記述のためだけに設定するのは大袈裟かと却下。
また、viewファイル内で@parentsを設定する方法もありましたが、コントローラーの役割をビューで
行うのもどうかとなり、上記結論に行き着きました。
vueで改行に合わせて伸縮するテキストフォーム

### 実装
textareaを利用することを想定。rowsの値を変更してformを伸び縮みさせている。

```typescript
function fitToForm(target: HTMLFormElement, text: string, defaultRows = 1): void {
    const lines = text.match(/\n/g)?.length || 1;
    if (defaultRows <= lines) {
      target.rows = lines + 1;
    }
    if (defaultRows > lines) {
      target.rows = defaultRows;
    }
}
```

### 利用イメージ
v-model渡しているstateをfitToFormの第二引数に渡しています。
第三引数にtextareaのデフォルトのrowsを設定すると、それ以上小さくなりません。

```vuejs
<textarea
    v-model="comment"
    placeholder="コメントを入力"
    rows="4"
    type="text"
    @input="fitToForm($event.target, state.comment, 4)"
/>
```


#### 完成gif
![May-17-2020 14-58-11.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54825/246a1683-1b4b-7384-4a69-269e77c475f2.gif)
PHPで画像をアップロード

学習をしていく中で、理解が難しかったので、要点をまとめてみました。

まず前提として、HTMLでフォーム画面に以下の記述が必要になります。

```HTML
<input type="file" enctype="multipart/form-data" method="post" name="img">
//nameは任意
//enctypeは画像の情報を送信するのに必要なおまじないと思ってください。

```



#画像をアップロードする流れ
①移動先のディレクトリを変数に格納する
②一時的に保存するファイルを変数に格納する
③アップロードしたい画像のファイル名を変数に格納する
④move_file_uploads関数でアップロードする

#①移動先のディレクトリを変数に格納する

```php
$uploads_dir = './uploads';

```
のちの記述をすっきりさせるために格納させています。

#②一時的に保存するファイルを変数に格納する

```php
$tmp = $_FILES['img']['tmp_name'];
//imgはinputで記述したnameの中身です
var_dump($tmp);
//string(14) "/tmp/phpimzszk"

```
tmp_nameとはアップロードした画像ファイルをサーバー上で一時的に保存する場所のファイル名です

#③アップロードしたい画像のファイル名を変数に格納する

```php
$name = basename($_FILES['img']['name']);
//imgはinputで記述したnameの中身です
var_dump($name);
//string(9) "melon.jpg"　画像ファイル
```
basename関数でファイル名を取得します。この記事がかなり分かり易かったので参考にしました。
https://www.flatflag.nir87.com/basename-844
$FILES['img']['name']がファイル名です

#④move_file_uploads関数でアップロードする

```php
move_file_uploads($tmp, "$uploads_dir/$name");
//move_file_uploads(もとにあるファイル名, 移動先のファイル名)
```
詳しくはこちらをご参照ください
https://www.php.net/manual/ja/function.move-uploaded-file.php
rails server起動時に「Could not find a JavaScript runtime.」とエラーが出る場合の対処法について

windowsでは出来ていたサーバーの立ち上げが買ったばかりのMacでは出来ず・・・。
色々調べた結果なんとか出来たのでまとめました。

# エラー内容　
Progateの「Ruby on Railsの環境構築をしてみよう！(macOS)」の「5. ローカルでRailsサーバを立てる」を進め、rails sコマンドを実行したところ以下のエラーが発生。

 ``` 
% rails s
  (略)
Could not find a JavaScript runtime. 
See https://github.com/rails/execjs 
for a list of available runtimes. 
(ExecJS::RuntimeUnavailable)
　
```

ブラウザでlocalhost:3000と入力してもエラーで表示されず。
どうやらJavaScript runtimeとやらが存在しないためエラーが出ている模様。runtimeが分からず検索すると以下の記事を発見。

https://wa3.i-3-i.info/word13464.html

記事によると、
>ランタイム（英：runtime）とは

>プログラムとかを動かすとき（実行時）のこと。

>あるいは

>プログラムとかを動かすときに必要な部品のこと

とのこと。つまり、
<b>Ruby自体にはJavaScriptを実行する機能が存在せず、実行するためにはruntimeというものが必要</b>
ということらしい。

# 解決まで

とりあえずネットでCould not find a JavaScript runtime.と検索したところRuby on Railsチュートリアル の記事を発見。

https://railstutorial.jp/chapters/beginning?version=4.0#sec-rails_server

記事によると、
>(JavaScriptランタイムがインストールされていないというエラーが表示された場合は、GitHubのexecjsページにあるインストール可能なランタイムを確認してください。Node.jsが特にお勧めです)。

とのこと。早速エラー文中にあるGitHubのサイトへアクセス。

https://github.com/rails/execjs

Node.jsをクリックし、公式サイトからダウンロード後インストール。
その後もう一度コマンドでrails sを実行するとサーバーが立った。
Next.jsでconsole.logをproduction時にのみ消す方法

```
yarn add -D babel-plugin-transform-remove-console
```


# [.babelrc][1] envを有効に
```json
{
  "presets": ["next/babel"],

  "env": {
    "production": {
      "plugins": ["transform-remove-console"]
    }
  }
}
```

[1]: https://babeljs.io/docs/en/6.26.3/babelrc#env-option
PLAとナイロンの接着を調べてみました

## はじめに
[XYZ printing daVinci Mini w+](https://www.xyzprinting.com/ja-JP/product-level/EXPLORER/mini-series)という3Dプリンタを使って3D造形しています。製作物の都合でナイロン製のスペーサを造形物と接着させようとしたのですが、なかなか接着できないことに気が付きました。3Dプリンタの多くはPLAという素材で3D造形しますが、どうも難接着素材のようです。[セメダイン社も独自にレポートを出したりしています](https://www.cemedine.co.jp/cemedine_reports/3dFDM.html)。

この記事では、近所のホームセンターで入手したいくつかの接着剤で接着テストを行い、その結果をお伝えします。

## この記事で分かること
* どの接着剤なら接着するか、参考程度の情報が得られる。

## 用意した接着剤
![2020-05-17 13.51.16.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519489/1a286b10-9d9f-91d7-878d-e7565100070a.jpeg)
左から順に以下のとおりです。
* [アロンアルファ ゼリー状](http://www.aronalpha.com/product_search/jelly/)
* [アロンアルファ プラスチック用](http://www.aronalpha.com/product_search/plastics/)
* [セメダイン 3000多用途](https://www.cemedine.co.jp/home/adhesive/cyanoacrylate/3000wide.html)
* [セメダイン PPXセット](https://www.cemedine.co.jp/home/adhesive/polyolefin/ppx_set.html)
* [セメダイン スーパーXハイパーワイド](https://www.cemedine.co.jp/home/adhesive/superx/superx_hyperwide.html)
* [BONDIC](http://bondic-japan.com/) ※UVレジン接着

## 用意した素材
* PLAで造形したケース(表面はつるつるの状態)
* ナイロンの六角スペーサ
![2020-05-17 13.51.43.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519489/d43b1290-7c26-51d1-2bc0-427510c514a2.jpeg)

## テスト方法
1. それぞれの接着剤の取扱説明書に従って、PLA造形物にナイロン六角スペーサを立てて接着させる。
2. 24時間以上放置する。
3. ひっくり返して、少し振ってみる。
4. ひっくり返した状態で、少し固い振動を与える。
3. なるべく同じ力になるよう、1本ずつ押していくことを繰り返す。
4. 接着面が剥がれた音がした時点で脱落とする。

## 結果
ひっくり返したり、振動で取れてしまうほど軟弱なものはありませんでした。

指押しを開始して早々に脱落したのはアロンアルファ ゼリー状でした。力加減としては仮止め程度です。これは以前から所有していたものです。ポリエチレン系の接着には使えないと記されているので、相性の悪い組み合わせなのでしょう。

次に脱落したのはセメダイン スーパーXハイパーワイドでした。アロンアルファ ゼリー状に比べれば少し粘りましたが、力加減で言うとそれほど変わらない感じでした。これは意外でした。

3番目に脱落したのはBONDICでした。こちらもポリエチレン系の接着には不向きと書かれていますし、接着の方法も接着面ではなく、その周囲を固めるものなのです。その特徴の中ではよく持った方だと思います。仮止め+αくらいな感じでした。

4番目に脱落したのはセメダイン PPXでした。こちらはポリエチレン素材でも接着できるもので、プライマーと呼ばれる素材を溶かすものを使った上で接着剤を利用するものです。方法としては後で述べるアロンアルファ プラスチック用と同じなのですが、ここで脱落しました。プライマーの使い方が不十分だった可能性もあります。仮止めよりは十分接着されていましたが、少し力がかかるような場面では不安な感じです。

5番目に脱落したのはセメダイン 3000多用途でした。最後のアロンアルファ プラスチック用と比べても遜色のない接着力で、取扱のしやすさを考えればこちらの方がオススメと言えます。しかし、長時間強い力が加わるような環境では使えない感じです。

最後まで残ったのはアロンアルファ プラスチック用でした。先に述べたセメダイン PPX用途同じくポリエチレン素材でも接着できるもので、プライマーを使用するものです。プライマーで塗る作業はこちらの方が簡単に行えました。こちらもセメダイン 3000多用途と同じく長時間強い力が加わるような環境には適していませんでした。

最後に接着面の痕跡を見てみます。
![2020-05-17 14.03.27.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519489/a03b8a28-21f5-0fd2-4d81-77a7af091cf7.jpeg)
接着面の痕跡がほとんどないのが、アロンアルファ ゼリー状、セメダイン PPX、BONDICです。BONDICはその接着方法から痕跡は残りづらいです。他は、結果として接着の弱さを示しています。

しっかりと接着していて、PLA造形物にはっきりした傷をのこしているのは、最後まで残ったセメダイン 3000多用途とアロンアルファ プラスチック用です。これを見ると、接着剤の強さの問題だけでなく、造形物の造形の仕方にも工夫をしないと、長時間力に晒される環境での利用は難しいのではないかと思います。

## まとめ
* 今回の調査で一番強い接着剤はアロンアルファ プラスチック用
* 次点だがセメダイン 3000多用途は使いやすいので、オススメはこちら
* 力のかかる接合場所で、接着だけで解決するのは難しい
 
## 備考
* この記事で述べていることは、私の主観と力加減により書かれたものです。科学的検証としては全く不十分です。
* この記事の条件下の中での接着の力を評価しています。他のいかなる素材の接着力にも言及していません。
* 用途や素材に合わせた接着剤を利用しましょう。
* 力がかかる場面では接着ではない別の接合方法を考えましょう。

以上です。
AndroidのTwilio VideoViewの形をCircleにする

# はじめに
あるプロジェクトで[TwilioのVideoライブラリ](https://jp.twilio.com/docs/video/android)を使ったのですがTwilioのVideoViewはデフォルトでは、四角形でカメラ映像がレンダリングされます。
これをよくある丸形にするのが意外と苦戦したのでメモしておきます。

やりたいのはこういうやつ↓
<img width="201" alt="スクリーンショット 2020-05-17 14.34.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106116/ca693f78-bd7b-567e-fd63-8e2b83bb0ff5.png">


※ 今回の方法は下記のやり方を参考にしました。
https://github.com/twilio/video-quickstart-android/issues/291

# やり方

- 親のカスタムレイアウトを作成

```kotlin:CircleFrameLayout.kt
package com.xxxxx

import android.content.Context
import android.graphics.Canvas
import android.graphics.Path
import android.graphics.Region
import android.util.AttributeSet
import android.widget.RelativeLayout

open class CircleFrameLayout constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : RelativeLayout(context, attrs, defStyleAttr) {

    constructor(context: Context) : this(context, null, 0)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)

    private var circlePath = Path()

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        val radius = Math.min(w/2f, h/2f)

        circlePath.reset()
        circlePath.addCircle(w/2f, h/2f, radius, Path.Direction.CW)

        super.onSizeChanged(w, h, oldw, oldh)
    }

    override fun dispatchDraw(canvas: Canvas) {
        canvas.clipPath(circlePath, Region.Op.INTERSECT)
        super.dispatchDraw(canvas)
    }
} 
```

- twilioはVideoViewではなくVideoTextureViewを使います。  
 （VideoViewを使ってしまうと四角形の背景が残ったままになってしまうので注意）

```xml:activity_main.xml
        <com.xxxxx.CircleFrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toBottomOf="@+id/menu_top"
            app:layout_constraintStart_toStartOf="parent"
            android:layout_marginStart="@dimen/video_margin_small"
            android:layout_marginTop="@dimen/video_margin_small"
            >
            <com.twilio.video.VideoTextureView
                android:id="@+id/video_1"
                android:layout_width="@dimen/video_small"
                android:layout_height="@dimen/video_small"
                app:tviScaleType="fit"
                />
        </com.xxxxx.CircleFrameLayout>
```

これで最初に紹介したような丸形のViewに出来ます！
[Java] なんか出力に「-0.0」って表示される

#きっかけは偶然に
IntelliJで気の向くままにjavaしてたら「ん？」ってなった

```出力.コンソール
value = -0.0
```

#結論
0を負の数で割ると-0.0になるっぽい

```sample.java
public class Main {
    public static void main(String[] args) {
        double value = 0;
        System.out.println("value = "+value/-1);
        System.out.printf("value = %3.1f\n",value/-5);
    }
}
```
```出力.コンソール
value = -0.0
value = -0.0
```

#対処
if文つけるかぁ
割る値に対してif文で0代入すれば表示は正しく出る

```sample.java
public class Main {
    public static void main(String[] args) {
        double value = 0;
        value /= -1;
        System.out.println("対処前 = "+value);
        if(value == 0) value  =0;
        System.out.println("対処後 = "+value);
    }
}
```
```出力.コンソール
対処前 = -0.0
対処後 = 0.0
```
####追記2020/05/26
-0が出る可能性のある計算に「+0」すると修正できるって

```sample.java
public class Main {
    public static void main(String[] args) {
        double value = 0;
        value /= -1 +0;//+0すると-0にならない
    }
}
```
ドリル（自作）

## 経緯
　某プログラミングスクールのドリルはわかってなかったことだらけで勉強になるのですが，「問題は」出すけど，「解釈，解答の背景」は自分で調べろ的なスタンスなので公開記事で記述形式でまとめていきます。

　ちなみに前回の記事のようにスクールの問題は限定記事にまとめて復習しています。ちなみに下のを解く場合，自分が示した答えは最適解とは限りませんが，参考程度にして自分で調べていただければと。


### railsにおけるコールバックってなんなの？
＊
＊
＊
＊
＊
＊
＊
＊
＊
＊
＊
＊
###A
・オブジェクトはrailsのアクションで生成されたり削除されたりする。この過程をオブジェクトライフサイクルという。このサイクルのなかでオブジェクトが変化する前後で行われる処理がコールバック。
・乱暴に噛み砕くとはデータベースから抽出する時，登録する時に行われる処理。身近なものだとバリデーションとかもそう。データベースに登録する前になにか処理を行うなら，before_createとか，モデルにメソッド同様に記述。


###シンボルってなんなの？
＊
＊
＊
＊
＊
＊
＊
＊
＊
＊
＊
＊

＊

###A
見た目は文字列だけど処理では数値として扱われるよ。シンボルに対応する数値は１対１だからたくさん定義をしてもメモリを圧迫しないよ

###　selfってなんなの？
＊
＊
＊
＊
＊
＊
＊
＊
＊
＊
###A
・モデルを通過するオブジェクトそのものだよ
・モデルの中はインスタンスとか定義してないから@postをコントローラーで定義しても認識してくれない。だからselfがその代わりになってくれる。p self.nameってやったらTaroが出力される感じ。selfはわざわざ定義する必要なし。

###CSRFという攻撃の意味とrails上での対策
＊
＊
＊
＊
＊
＊
＊
＊
＊
＊
＊
＊
###A
クッキーを不正に利用して他人のアカウントで不正操作（投稿削除）を行うこと。（噛み砕き）
対策ー　protect_from_forgery with: :exception
これによってフォームからの投稿ごとに不正に利用されていないかトークンを発行して照合している。


### countの使い方(引数の有無でどう変わるか)
＊
＊
＊
＊
＊
＊
＊
＊
＊
＊
＊
###A
レシーバの要素数を返します。
引数を指定しない場合は、レシーバの要素数を返します。
引数を一つ指定した場合は、レシーバの要素のうち引数に一致するものの個数をカウント
ブロックを指定した場合は、ブロックを評価して真になった要素の個数をカウント
This module was most likely not flagged for being included in a precompiled build 【UE4】【エラー】【独自アセット】

UE4
---
もしタイトルのエラーが独自アセットを作った後などエディター拡張後パッケージを作ろうとして出た場合
UnrealEdを含めてパッケージは作れないので、エディター用のモジュールと分けた方が良いです。
https://qiita.com/herorinusu/items/478371c51c99418ab6c8
VSCode公式の機能で設定を同期する【Insiders Preview】

VSCode Version 1.44.0 Insiders Preview版より、設定ファイルの同期がVSCode公式機能として搭載されました。これまでは複数環境で設定ファイルを同期するには、[設定ファイルを独自にGit管理](https://github.com/s2terminal/visualstudiocode-usersetting)したり専用の拡張機能を使う必要がありましたが、それらが必要無くなります。

## 環境
- VSCode Insider Preview Version 1.46.0-insider
    - Windows版およびLinux版(ChromeOS)で動作確認

v1.46現在では、設定同期を利用するには下記から**Insider Preview版** のVSCodeを利用する必要があります。
[Download Visual Studio Code Insiders](https://code.visualstudio.com/insiders/)

VSCodeのInsiders buildは、緑色のアイコンが目印です。青色アイコンの安定バージョンVSCodeとは共存できますので、普段は安定版を使っていても特に問題はありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50391/079ecf71-3f46-2ef6-a33d-59a1504bc59d.png)
また、[利用規約](https://code.visualstudio.com/license/insiders)も安定バージョンのVSCodeと同様に通常の開発目的に利用することができます。「評価目的の利用に限る」ような事はありません。

## 設定同期方法
Windowsであれば非常に簡単です。画面左下の歯車マークから「Turn on Preferences Sync...(設定同期をオンにする)」を選択するか、コマンドパレット(Ctrl+Shift+P)から`>Turn on Preferences Sync`を入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50391/a1e7bddd-ac81-68e6-7228-74e62d0ef0d7.png)

同期する設定を選択した後、MicrosoftアカウントまたはGitHubアカウントでログインすると、設定の同期が開始します。

コマンドパレットから`>Preferences: Open Settings (JSON)`で設定画面を開き、適当な設定を入れてみます。たとえば、下記のように文字を大きくする設定を入れてみたりすると分かりやすいでしょう。

```settings.json
{
    "editor.fontSize": 20
}
```

他の環境のVSCodeで上記と同様に設定同期を有効にすると、ローカルにある既存の設定を置き換えるか、マージするかを問われます。好きな方を選択すると、さきほど元の環境で設定した`settings.json`の内容が、あたらしい環境にも反映されます。

### ChromeOS上Linux版での注意点
ChromeOS上のLinux(Chrostini)版VSCodeでは、GitHubアカウントでログインしたときにChromeブラウザ上の認証トークンをVSCodeで受け取ることができず、VSCodeでログインできませんでした。「Google Chrome OSではこのページを開けません」といったエラーが表示されてしまいます。

この場合は、GitHubの画面に表示されるトークンを画面上の指示に従ってVSCode上に入力するか、Firefox等の「Linux上にインストールしたブラウザ」にURLを入力することでうまく行きます。

また、設定同期を有効にした後、`Writing login information to the keychain failed with error 'The name org.freedesktop.secrets was not provided by any .service files'.`というエラーが発生することがあります。この時は、[公式ドキュメント](https://code.visualstudio.com/docs/editor/settings-sync#_linux)に貼られている[GitHubのIssue](https://github.com/microsoft/vscode/issues/92972#issuecomment-602919353)を参考に、`~/.xinitrc`というファイルを作成します(必須かどうか不詳)

```~/.xinitrc
eval $(/usr/bin/gnome-keyring-daemon --start --components=pkcs11,secrets,ssh)
export SSH_AUTH_SOCK 

source /etc/X11/xinit/xinitrc.d/50-systemd-user.sh
```

その後、`$ sudo apt install seahorse`でseahorseをインストールしたあと起動して「File」→「New」→「Password Keyring」からKeyringを構成します。ふたたび設定同期を有効にしてGitHubアカウントでログインすることでうまくいきます。

なおLinux版ではMicrosoftアカウントを使っての認証は、v1.46.0現在うまくいきませんでした。下記Issueのようにlocalhostへリダイレクトされようとしてしまいます。
[Settings Sync unable login to MS account · Issue \#95306 · microsoft/vscode](https://github.com/microsoft/vscode/issues/95306)

## 参考
- [Visual Studio Code March 2020](https://code.visualstudio.com/updates/v1_44#_settings-sync)
- [「Visual Studio Code」が設定の同期に対応、Insider版でテスト中 \- 窓の杜](https://forest.watch.impress.co.jp/docs/news/1240071.html)
raspbian install tool でドハマりしたこと

#背景
　はじめてRaspbian純正ツールでRaspberry　Pi　ZeroにHeadlessインストールしたら、どはまりしたので、
　メモ。

#ステップ
- [Raspberry公式](https://www.raspberrypi.org/downloads/https://www.raspberrypi.org/downloads/) で公式ツールをダウンロード。
- [RaspberryPi Raspbian ヘッドレスインストール](https://qiita.com/nori-dev-akg/items/a8361e728a66a8c3bdba)をみながら、ヘッドレスインストール。
- [初心者向！Raspberry Pi 最低限のセキュリティ設定【所要時間 30分】](https://qiita.com/mochifuture/items/00ca8cdf74c170e3e6c6)をみながら、初期設定を完了

#事象
- IFTTTのWebhookへのプログラムが動かない。
- Curlでうってみても、curl (7) couldn't connect to host 
  
#切り分け
- GoogleへのPing
    - --＞通る
- 他のラズパイからは、IFTTTのWebhook、Curlもとおる。（以前公式ツールが出る前にインストールしたラズパイ）
    - --＞IFTTTは動いてる。
- Yahooへのwget　yahoo.co.jp は 
    - -->200　OK。
-  ＜＜途方に暮れる＞＞
- [httpbin - HTTP通信のテストに便利なWebサービス＆ソフト](https://www.softantenna.com/wp/review/httpbin/)でのCurlもエラー。
-  ＜＜途方に暮れる２＞＞
-  [http://sc.ipsecdh.net/entry/710](http://sc.ipsecdh.net/entry/710)にたどり着く。
-  もしかして、DNSの設定エラーか。
-  [Raspberry PiでDNSサーバーを設定するにはどうすればよいですか？](https://qastack.jp/superuser/617796/how-do-i-set-dns-servers-on-raspberry-pi)にたどり着き。

#解消方法
- [Raspberry Pi に固定IPアドレスを割り当てる方法（Raspbian Jessie）](https://qiita.com/marie_khr/items/b088ffb252a92eee8f5d)を参照し、/etc/dhcpcd.confで
'Domain_Name_Server'をルーターのアドレスに設定。
　　
'Profile static_wlan0
static ip_address=192.168.1.29/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1'
【UE4】エディター用のモジュールを作るまで【UnrealEngine】【Module】

概要
----
UE4でアプリをパッケージ化する際に
実際のアプリでは使用しないエディター用のコードをパッケージに入れたくない時があります。
この問題を解決する方法として今回はモジュールを分割する方法を紹介します。


1.エディター用のモジュールを作る
---------
新しいモジュールのフォルダを元からあるモジュールのフォルダをコピペしてSourceの直下に作ります。
今回はモジュール名をMyProjectEdにしています。
![2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497331/8cebaa4e-260f-b63d-9ea7-00179345c7a9.gif)

作ったフォルダに最低限必要なコード MyProjectEd.Build.cs MyProjectEd.cpp MyProjectEd.h を用意します
ファイルの中身も全て新しいモジュール名でリネームを行います。
(デフォルトから存在するモジュールからコピーしてリネームするのが安全)
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497331/cd9e2abf-43a8-0da2-aa29-5211f4df7052.png)

2.作ったモジュールをビルドの対象にする
---------
エディターのみ追加されてほしいモジュールの場合〇〇Editor.Target.csが
エディター起動時用なのでこちらに作ったエディターのみ使用したいモジュール名を追加
MyProjectEditorTarget.cs

    public class MyProjectEditorTarget : TargetRules
    {
    	    public MyProjectEditorTarget(TargetInfo Target) : base(Target)
    	    {
		    Type = TargetType.Editor;

		    ExtraModuleNames.AddRange( new string[] { "MyProject" , "MyProjectEd" } );
	    }
    }

3.最後にGenerate VisualStudio project filesを実行
---
MyProject.uprojectの右クリックメニューからGenerate VisualStudio project filesを実行し、ビルドをすれば完成

![4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497331/ac6948ce-a4a7-1eb0-2fc0-8836c5012d6a.gif)

気を付けたい事
----
エディター用のモジュールでランタイム用のモジュールを使用したい場合は
エディター用のBuild.csのDependencyで参照する対象のModuleを指定する必要があります。
※これをしていないとエディター用のソースからパッケージ用のソースをインクルードした時エラーがでます。
![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497331/ef0229e6-ca1b-cb82-e896-207fe3513170.png)


まとめ
------------
エディター拡張に必要なUnrealEdをRuntime用のモジュールに含めたままだとパッケージが作れない問題が起きたりするので、
エディター拡張を行う場合は必要になりそうです。

参考にしたサイト
--------
[モジュールについて](https://historia.co.jp/archives/3097/)
[新しいエディターモジュールを作る](https://kazuhiro77unreal.hatenablog.com/entry/2018/01/28/083209)
【python】一次元配列のリストと二次元配列のリストを比較して、一致した値のみ抽出する方法3つ【json】

##概要
表題の通り。
**一次元配列のリスト（A）にある値が二次元配列のリスト（B）の【ID】列に存在するとき、Bの【name】列の値を取得する方法。**
上記はslackのapiで遊んでいたときに分かったことで、それを以下にまとめた。

```A.list
print(name_list)
['U012JDYRD2T', 'U012X478FNZ']
```
```B.list　#見やすいように修正しています。
print(data)
[['name',     'id'],
 ['Slackbot', 'USLACKBOT'],
 ['test_1',   'U012JDYRD2T'], #ここが欲しい
 ['test_5',   'U012JDYSN07'],
 ['kita',     'U012X478FNZ'],#ここが欲しい
 ['test_4',   'U012XQBE63X'],
 ['test_bot', 'U012YTNNPB5'],
 ['test_3',   'U012ZC8AQ8K'],
 ['tese_2',   'U013BQDLK6V']]
```
```期待する結果.py
print(result)
['test_1','kita']
```

##方法1
```1.py
result = []
for data_id in data:
    if data_id[1] in name_list:
        result.append(data_id[0])
```
①ループ分`【data_id in data】`は、dataを一つずつdata_idに格納。
②`【if data_id[1] in name_list】`は、【id】列（data_id[1]）とname_listが一致した場合という条件
③`【result.append(data_id[0])】`は【result】というリストに【name】列（data_id[0]）を追加

##方法2
```1.py
result = []
result = [data_id[0] for data_id in data if data_id[1] in name_list]
```
理屈としては方法１と同じ。スマート。

##方法3
```3.py
r = []
r2 = []
for i in data:
    r = r + i
for i in name_list:
    tmp = (r.index(i)) - 1
    r2.append(r[tmp])
```
①rにdataを一つずつ格納。`['name','id','Slackbot','USLACKBOT'…]`と格納される。
②name,idと順番に格納されていることを利用する。
　つまり`「U012X478FNZ」`の一つ前は`「kita」`であり、`「U012JDYRD2T」`の一つ前は`「test_1」`であるということ。
③なので`【tmp = (r.index(i)) - 1】`では、「U012X478FNZ」のインデックス（何番目か）から【-1】することで、その直前である「kita」のインデックスが取得できる。
④そして取得したインデックスの値を【r2】に追加している。

##わかったこと
　もっとループと条件分岐について理解する必要があるということ。
Intuneで、iPhone・iPadのOSアップデートを強制する方法ないの？

前回、[iPadのOSアップデートをブロックする方法ないの？](https://qiita.com/hisssa0102/items/72f34fe160955488ca9d)では、OSアップデートさせたくなくてブロックする手段がほしくて、MDMから一定期間延期するするという方法等をまとめてみた。13の時は iPadOS のリリースとその対応でヤキモキしたけど、もう13リリースされて半年以上経った。

今回は「組織内に上がっていないデバイスがあるとバージョン違いの問い合わせも増えるし、もしやっていない人がいる場合には強制アップデートさせたい」というシナリオ。

というわけで、Intune で iOS / iPadOS を強制アップデートする方法しらべてみた。

#MEM管理センター

Azure Portal でもまだいけるけど、8月にはMEM管理センターに移行されるらしい。私自身が慣れるためにも、こっちでベースで書きます。

※ Microsoft Endpoint Management 管理センター
MEM = クラウドベースのIntune + オンプレベースのSCCM、の両方をWebから一元管理できる、って捉えてる。

#ポリシーの作成

MEM https://endpoint.microsoft.com/ を開く。
デバイス - iOS または iPadOS のポリシーの更新 - プロファイルの作成 を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237698/4e62259b-f681-0a68-fd93-857bbc0fe467.png)

名前を付けて、次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237698/567f191d-1f68-f139-7f41-4822897a9ba7.png)

バージョンを選択して
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237698/9dacc81b-927e-09e3-ccc8-ec9aca5faea7.png)

スケジュールを選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237698/b1fdf25f-6c4a-b8b4-b663-97578abfbdcc.png)

スケジュールは、曜日別で時間帯で設定できる。
たとえば、月曜は会議が多いので、強制の曜日から除外する、なんてことも可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237698/318766f4-3972-ca27-c103-51eac48f369e.png)

対象グループ割り当てて、完了！

#注意点

自動でアップデートを強制する、だけです。
手動で実施すればアップデートできるし、アップデートをブロックさせる、という使い方はできない。

#まとめ

できれば、組織内デバイスはできれば最新メジャーバージョンあるいは、それの1つ前以上がベター。というか、それ以前はサポートされないし。

13では、200MB以上のアプリや更新が、LTEでもできるようになっている。(WiFiが必須じゃない！）アプリのバージョンが古いとサービスに接続できなくなるケースもある(OutlookアプリでOffice365のメールに接続できないとか）
なので、アップデートを強制するためにも13以上が望ましいかな。
WordPressで複数のカスタム投稿タイプの記事一覧を表示し、なおかつ特定のスラッグで絞り込む

備忘録として。表題のとおり
「WordPressで複数のカスタム投稿タイプの記事一覧を表示し、なおかつ特定のカテゴリ（ターム）で絞り込む」をやりたいときに。

例えばカスタム投稿、以下の２つがあったとする。
「shop」
「news」
んで、この中の「pickup」だけ集めてトップページに出したいときに使う。

```
<?php 
    $args=array(
          'post_type' => array('shop','news'), //カスタム投稿名を指定
          'tax_query' => array(
            'relation' => 'OR',
            array(
              'taxonomy' => 'shop-cat',//カスタム投稿内のカテゴリを指定
              'field' => 'slug',
              'terms' => 'pickup', //スラッグ名Aを指定
              ),     
            array(
              'taxonomy' => 'news-cat',//カスタム投稿内のカテゴリを指定
              'field' => 'slug',
              'terms' => 'pickup', //スラッグ名Bを指定
              ),     
          ),
          'paged' => $paged,
          'posts_per_page' => '5' // 5件を取得 
   );
?>
      <?php query_posts( $args ); ?>
      <?php if(have_posts()): ?>// ループ開始
      <?php while(have_posts()):the_post(); ?>
```

これでできた！
JavaScript（ブラウザ環境）でOAuth2 PKCE用パラメータを生成する

JavaScript（ブラウザ環境）でProof Key for Code Exchange (RFC 7636) のcode_verifier、code_challenge（code_challenge_methodがS256の場合）を生成するコードを作成した。

https://jsfiddle.net/unhurried/8vgk6fnr/

#### 実装の要点

[Crypto](https://developer.mozilla.org/ja/docs/Web/API/Crypto)が利用できないブラウザ（IE10以前など）でも動作するように実装している。（ただし、この場合は乱数生成に[Math.random()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/random)を使うため乱数の暗号強度はブラウザ実装によっては下がる可能性がある。）

ハッシュ生成には[crypto-js](https://www.npmjs.com/package/crypto-js)を使っている。

なお、乱数生成にもcrypto-jsを利用できるが、crypto-jsの乱数生成処理は[3.3.0](https://github.com/brix/crypto-js/blob/3.3.0/core.js#L304)ではMath.random()、[4.0.0](https://github.com/brix/crypto-js/blob/4.0.0/core.js#L52)ではCryptoを固定で利用するようになっているため、ブラウザのCryptoサポートによって切り替えるように独自実装している。
PHP 初心者向け実行環境(Local by Flywheel)と練習問題

# 対象者
初めてプログラミングを学習したい方
（用語の解説等はあえてしません）
※わからないことはすぐに調べる癖をつけよう！

Windows 10 64bit

# 事前準備
- Visual Studio Codeの導入（IDE）
- Local by Flywheelの導入

# Visual Studio Code（IDE）
https://azure.microsoft.com/ja-jp/products/visual-studio-code/
ここからVisual Studio Codeをダウンロード

インストールが終わったら**プラグイン**を導入しよう

### 最低限欲しいプラグイン
1. [Japanese Language Pack for VS Code](https://marketplace.visualstudio.com/items?itemName=MS-CEINTL.vscode-language-pack-ja)
日本語化のプラグイン
2. [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) 
コードのフォーマット自動でおこなってくれる


# Local by Flywheel

環境構築がめちゃくちゃ手軽なので選びましたが、XAMPPでもおっけーです。

[こちら](https://qiita.com/ntm718/items/e0c8ed27e5272b370689)を参考に
> PHPを実行する

まで進めて動作確認をしよう

#　練習問題
環境構築が既に終わってる方はこちらから

ちなみにですが、模範解答はまた後日


## その１
加算演算子を使用して以下の変数を計算して下さい

```php:study01.php
 $a = 2
 $b = 3
 $c = "答え"
```

## その2
   以下の変数とif, else if, else とループ文(for, foreach等)を使用し
   50点未満なら「不可」
   50点以上65点未満なら「可」
   65点以上80点未満なら「良」
   80点以上なら「優」というコードを作成してください。
   ***70点の場合の結果***を表示させてください。

```php:study02.php

<?php
$result = array("不可", "可", "良", "優");

?>
```

## その3
   ***study03.php***と***study04.php***を流用して、
   if文とループ処理分(for, foreach等)を使い***「"言語名"は"難易度"です」***と表示してください。
  例: C言語を選択したとき
　　　C言語は難しいです
  ※プログラムの難易度は実際と違います

C言語 = 難しい
Java = 普通
JavaScript = 優しい

```php:study03.php
<html>
<head>
    <title>プログラムの難易度</title>
</head>
<body>
    <form action="study04.php" method="post">
        習得したいプログラム言語を選択してください<br>
        <input type="radio" name="choice" value="1">C言語
        <input type="radio" name="choice" value="2">Java
        <input type="radio" name="choice" value="3">JavaScript
        <input type="submit" value="送信">
    </form>
</body>
</html>
```

```php:study04.php
<html>
<head>
    <title>プログラム言語難易度</title>
<body>
    あなたが選んだプログラム言語は
    <?php
    $program = array(
    "1" => "C言語", 
    "2" => "Java", 
    "3" => "JavaScript"
    );
    $difficult = "難しい"; // C言語 = 難しい
    $normal = "普通"; // Java = 普通
    $easy = "易しい"; // JavaScript = 優しい

   // ここにコーディング

    ?>
    です。
</body>
</html>
```
FBX SDK(Python)でunityちゃんを解析し、WebGLでアニメーションする！

# FBX SDK(Python)でunityちゃんを解析し、WebGLでアニメーションする！

## 前書き

### 最終目標

unityちゃんのfbxファイルを、Python版のFBX SDKを用いて解析し、WebGLにおいてスキンメッシュアニメーションを再生することを目指します
WebGL関連のライブラリは使いません

### 開発環境情報
Windows 10
Visual Studio Code
Python 2.7
FBX SDK 2017
(作成したPythonコードは、FBX SDK 2020.0.1でも動作することは確認済み)  

### 主な参考サイト
FBXの解析に関して
[「〇×(まるぺけ)つくろーどっとコム」さんの「FBX習得編」](http://marupeke296.com/FBX_main.html)

WebGLに関して
[WebGL 開発支援サイト webgl.org](https://wgld.org/)

これら二つのサイトに、目を通している、あるいは目を通しながら、本記事を読んでいることをほぼ前提としています  

### 対象者
WebGLでスキンメッシュアニメーションを組みたい方
FBX SDK を使って、fbxファイルから必要な情報を抽出する所から始めたい方  

### 未達成の内容について

同様のことがしたくて、既に色々調査された上で、本記事を見つけられた方のために、先んじて書いておくと、解決出来なかった問題が一つあります
それは、「Python版のFBX SDKを用いて、マテリアルからDiffuseに設定されているテクスチャのファイルパスを取得する」ことです

Pythonでのテクスチャのファイルパスの取得方法に期待して本記事を読まれている方には申し訳ないですが、Pythonだと多分不可能かと思われます

マニュアルを読む限り、「PythonではC++のtemplate関数は提供しない」と記載されており、かつ、FBX SDK 2017において、templateを使わない版の関数が削除されたらしいです

[テンプレート関数はPythonで使えない](https://help.autodesk.com/view/FBX/2017/ENU/?guid=__files_GUID_363E55D8_6EDB_40F8_8F58_E42F8D525D3D_htm)
[テンプレート関数ではないClassId指定の関数が削除された](https://help.autodesk.com/view/FBX/2017/ENU/?guid=__files_GUID_2A50CD0F_062D_4F80_88C7_BBA0483FBE0F_htm)

そのため、C++で作っても構わない方は、最初からC++版のSDKを使った方がよいと思います

（もし、Pythonで「GetSourceObject」関数を呼び出す方法をご存じの方がいれば、教えてください...）

## 本題

本記事は、「FBX解析編」「WebGL編」の2部構成になります
書いてみると長くなってしまったので、記事を分けて投稿することにしました  

### 1. [FBX SDK(Python)を使って、unityちゃんのfbxを解析する](https://qiita.com/kota017a/items/1cdc347dec9800ae66bd)

### 2. [unityちゃんをWebGL上でスキンメッシュアニメーションさせる](https://qiita.com/kota017a/items/071c8b085c758c769758)

## 備考

本記事の内容を実際に私が作成した際のソースコードを一応GitHub公開していますので、必要であれば、ご確認ください  
[ソースコード](https://github.com/kota017a/WebGLTraining_FBXSkinMeshAnimationProject)
CentOS6に Nginx 1.16.0 を導入する

最新版を利用するに越したことは無いが、一つ前のバージョンで動作確認をする必要があったために、1.16.0 を導入した時のメモ

Nginxで配布されているパッケージをインストールする。
`rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm`

`yum install nginx`
だけだと、最新版(1.18.0)がインストールされてしまう。

そのため、インストールしたいバージョンまで指定する必要がある。
`yum install nginx-1.16.0`
【開発ログ⑫】有休未消化のアラートを実装

# 前提について
はじめまして、 プログラミングスクールに通ういりふねと申します。この記事は、スクールの課題である個人アプリの開発の記録を書くことで、自身のアウトプットに利用しています。もし、読んでいただけた方がいましたら、フィードバックをしていただけたら嬉しいです。

開発するのは「有給休暇管理ツール」です。仕様は[過去記事](https://qiita.com/iczo32/items/97ad7d4baa985b3b99ca)をどうぞ。

アプリはデプロイまで行いますが、サービスとして提供するものではありません。あくまでも自学習の一環ですので、ご理解下さい。では本題へどうぞ。

# 今回実施する内容
前回までで、有休に関する簡単な計算までが終了しましたので、今回は有給休暇の未消化アラートを実装したいと思っています。以下の手順で実施します。今回は軽め。

- 未消化アラートとは？
- 未消化アラートの実装
- ビューに表示

# 未消化アラートとは？
働き方改革法案により、2019年4月1日より有給休暇を消化させることが、義務化されました。条件は有休を10日以上持つ社員に対して、毎年5日以上は時期を指定して計画的に消化させるというものです。毎年の期間については、就業規則により変わると考えられますが、今回は「直近付与日から次回付与日までの間」に５日未満しか消化していない社員については、有給休暇管理表のアラートカラムに「未消化」を表示させることにします。

# 未消化アラートの実装
今回も、モデルファイルに未消化アラートを表示させるメソッドを記述しておきます。

```ruby:employee.rb
class Employee < ApplicationRecord
〜中略〜
  def delete_days_alert
    a = total_delete_day
    b = total_add_day

    if b >= 10 && a < 5
      "未消化"
    else
      "-"
    end
  end
end
```

IF文の前のメソッド、total_delete_dayとtotal_add_dayは、[前回の記事](https://qiita.com/iczo32/items/40da609a8e4e3fbcc487)で定義済みです。これは、直近の付与日から現在までの日数を計算するメソッドになります。

そして、IF文の条件は、b（付与日数の合計）が10以上、かつ、a（消化日数の合計）が5未満のとき、ということになります。有休の付与日数が10日未満の方やすでに今年５日以上消化している方は対象外となります。

# ビューに表示

```haml:branches/index.html.haml
.main
  =render 'branches/mainheader'
〜中略〜
        %th{id: "short", class: "bgc"}
          5日消化
〜中略〜
        - @employees.each do |employee|
          %tr
〜中略〜
            %th{id: "short", class: "bgc"}
              = employee.delete_days_alert
〜中略〜
```

結果は、以下のとおりです。
<img width="762" alt="スクリーンショット 2020-05-17 13.28.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614723/4e4f75f9-43cd-0793-b309-c1ba0ceeb502.png">
未消化アラートは、目立ったほうが良いと思ったので、５日消化カラムには、class名bgcを追加し、黄色の背景色を設定しました。

# 今日の積み上げ
本来であれば、「未消化」と表示されている方だけに黄色を表示させたかったのですが、私の能力では調べても実装できませんでした。一応、hamlでclassを定義する際にIF文で条件を定義し、条件に合う時、classを追加するという方法があるようです。まだまだ未熟であると感じましたが、できる限りで頑張りたいと思います。

参考にさせていただいた記事
[「【Haml】条件（if）に応じてClassを変更させる方法」](https://qiita.com/nishina555/items/91033428300336851b0b)@nishina555様
[「Hamlで条件に合わせてclassを追加する方法」](https://qiita.com/day-1/items/74d5c5e57a7326742a4f)@day-1様
[「Hamlで条件に合う時だけ特定のクラスを加えたい」](https://qiita.com/aprikip/items/50475927a86d67805b60)@aprikip様
[shell] デザインファイルをpdfで納品しようとしてたら納品直前に130ファイル全部jpegにしてねって言われた

# 背景
数ヶ月のプロジェクト終了間際に、プロジェクト初期からpdfで共有していたデザインファイル。
納品直前にjpegにしてね　って言われました。130ファイルくらい。最初からいえよとは思いましたが、まぁシェルでやるか。。。なう。

あと、テーマごとにフォルダをキレイに階層化してたのですが、階層いらないので全部１フォルダ内で納品してくださいとのこと。。 

# やりたいこと
各フォルダに入ってるpdfファイルを全て洗い出してjpegにした上で１つのフォルダにまとめる

# シェル

```bash
# /bin/bash

PRE_IFS=$IFS
IFS=$'\n'

files=`find . -name *.pdf -type f`

for file in $files
  do 
    pdf=$(basename $file)
    jpeg=$(sed 's/.pdf/.jpeg/g')
 
    convert $file ${jpeg} 
  done
```

# 感想
事前に納品フォーマット調整しておけばよかったというマネジメントミスは置いといて、久々にシェル使いました。普段シェル使わないので、正しいやり方かわかりませんし、`awk`とか使えば１行でできるのだと思いますがあまり時間使いたくなかったので for文でやってしまいました。もっと簡単な方法がある等ありましたらアドバイスいただけますと幸いです。
【Rails 】画像必須のテストデータの作成方法

Rails５.2を用いてアプリケーションを開発中です。

プロフィール画像の設定が必須であるユーザーのテストデータを
作成した際に行ったことを記載します。

###行ったこと

プロフィール画像をテストデータに入れる必要があり、
どのフォルダにテストデータ用の画像をいれればいいのか・・と一瞬悩みましたが
行うことはシンプルでした。

####①dbフォルダの中に、fixturesというフォルダを新規作成


####②fixturesというフォルダの中に、テストデータとして登録したい画像を入れる

<img width="172" alt="スクリーンショット 2020-05-17 13.19.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565338/f72f9d89-0511-ab05-5c7e-40076545f703.png">


####③db/seeds.rb内に以下を記載。


```ruby:seeds.rb

(1..20).each do |n|
  Company.create!(
    email: "email#{n}@example.com",
    name: "#{n}名前",
    profile_photo: open("#{Rails.root}/db/fixtures/test.JPG"),
    profile:"#{n}test",
    password_digest:"#{n}test",
    industry:"#{n}test",
    occupation:"#{n}test",
    corporation_name:"#{n}test"
  )
end

*Companyモデルのデータを作成したかったので、この部分は任意で変更ください。
*(1..20)で20個のデータを作成するよう指定。
*profile_photoの部分で先ほど用意した画像のパスを指定しています。
```

####④ターミナルでrails db:seedを実行

以上でテストデータが作成できているかと思われます。
TeX Live 2020 用の日本語用Dockerコンテナ

# はじめに

TeX Live の日本語用 Docker コンテナとして alpine ベースの [paperist/alpine-texlive-ja](https://hub.docker.com/r/paperist/alpine-texlive-ja/) を使用しています。

TeX Live 2020 がリリースされたのを機にフォークして、TeX Live 2020 用のコンテナを作成し、DockerHub に [toshiara/alpine-texlive-ja](https://hub.docker.com/repository/docker/toshiara/alpine-texlive-ja) としてアップロードしました。

- 本当はDockerファイルのプルリクエストを送ったのですが、忙しいためか気いてもらえなかったので自分で作成しました。

## TeX Live 2020 の特徴（超抜粋）

TeX Live 2020 では[原ノ味フォント](https://github.com/trueroad/HaranoAjiFonts)がデフォルトとなりました
- 別途 Noto フォントをコンテナに追加して使用していたのですが、その必要がなくなりました。
- これまでの TeX Live 2019 でも問題ないのですが、TeX Live 2020 を使用するのはこの点が私にとっての理由です。

## インストールおよび使用例

### 必要なパッケージの追加

実際には、[toshiara/alpine-texlive-ja-plus](https://hub.docker.com/repository/docker/toshiara/alpine-texlive-ja-plus) のように個人的に必要なパッケージを追加して使用しています。

### インストール

```
docker pull toshiara/alpine-texlive-ja
```

タグは今の所`latest`と`2020`、`2020.5.10`（ビルドした日付）を用意しています。
コンテナを変更した場合には日付のタグだけを更新する予定です（今の所その予定はないです）。

### 使用例

``` bash
docker run --rm -it -v $PWD:/workdir toshiara/alpine-texlive-ja platex --version
```
11rep - contextパッケージでテンプレ

# contextパッケージとは何か
- Context は、APIのサーバーやクライアントを使うときに、コンテキストを提供してキャンセルや、タイムアウト、値を渡したり出来る仕組み

# 流れ

- (*sql.DB)Begin()でトランザクションを開始
- (*sql.Tx)Commit()でコミット、(*sql.Tx)RollBack()でロールバック


``` go
package main

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
    "context"
    "time"
)

func main() {
	db, _ := sql.Open("mysql", "user:password@tcp(host:port)/dbname")

	ctx := context.Background()
	ctx, cancel := context.WithTimeout(ctx, 1*time.Second)
        defer cancel()

	tx, error := db.Begin()
	if error != nil {
		log.Fatal(error)
		return
	}
        defer tx.Close()

	_, err := db.ExecContext(ctx, {Query})
	if err != nil {
	  tx.Rollback()
	} else {
	  tx.Commit()
	}
}

```
- defer cancel() 上記はタイムアウトの実装
- 1秒以上かかる場合はDone
- TimeOutの設定は下記

> Microsecond          = 1000 * Nanosecond  
> Millisecond          = 1000 * Microsecond  
> Second               = 1000 * Millisecond  
> Minute               = 60 * Second  
> Hour                 = 60 * Minute  



# 具体的な利用例からcontextとは何かを説明
- Goの典型的な利用例であるWebアプリケーションを考える
- Goのサーバにおいてリクエストはそれぞれ個別のgoroutineで処理される
- そしてリクエストHandlerは新たなgoroutineを生成しバックエンドのDBや別のサーバにリクエストを投げ結果を得てユーザに対してレスポンスを返す．

> 最初に注意するべきはその処理に適切なTimeoutやDeadlineを設定して処理が停滞するのを防ぐことである

- 例えば別のサーバにリクエストを投げる場合にネットワークの問題でリクエストに時間がかかってしまうことは大いに考えられる．リクエストにTimeoutを設定して早めにレスポンスを返しリトライを促すべきである．

> #### 次に注意するべきは生成したgoroutineを適切にキャンセルしリソースを解放することである．(※Must)

- 例えば別のサーバにリクエストを投げる場合に適切なキャンセル処理を行わないとTimeout後もネットワークリソースが使われ続けることになる（CPUやメモリを使い続けるかもしれない）
- この場合**net/httpパッケージレベルでリクエストをキャンセル**するべきである．
- さらにそのgoroutineは別のgoroutineを呼び出しそれがまた別の…と呼び出しの連鎖は深くなることが考えられる
    - その場合も親のTimeoutに合わせてその子は全て適切にキャンセルされリソースは解放されるべきである
> contextパッケージはこのキャンセルのためのシグナルをAPIの境界を超えて受け渡すための仕組みである．ある関数から別の関数へと，親から子へと，キャンセルを伝搬させる．



# 参考サイト
- [Tx.ExecContext](https://golang.org/pkg/database/sql/#Tx.ExecContext)
- [Duration.Microseconds](https://golang.org/pkg/time/#Duration.Microseconds)
- [contextパッケージ](https://deeeet.com/writing/2016/07/22/context/)
【Route53】 ドメイン作成〜常時SSL化 設定まとめ

#参考文献

- [AWSでドメイン、SSL証明書の取得、設定](https://qiita.com/masch/items/a5ef84998fb7784f9115)
- [【初心者だよ その2】 AWSで無料SSLをやってみた](https://qiita.com/gremito/items/2a416b042a0c94d4541d)
- [AWSでWebサイトをHTTPS化 その1：ELB(+ACM発行証明書)→EC2編](https://recipe.kc-cloud.jp/archives/11084)


#1. Route53 ドメイン作成

###作業内容

- ①「ホストゾーンの作成」からドメイン登録

- ②レコードセットで"レコードタイプ"を確認

#2. AWS Certificate Manager "SSL証明書"作成

###作業内容

- ①「証明書のリクエスト」から、ドメイン名に紐づく証明書を作成

- ②CNAMEレコードがない場合は、"レコードセット"に登録


#3. ロードバランサーの作成

###作業内容

- ①ALB（HTTP / HTTPS）を選択

- ②リスナー（ロードバランサーのプロトコル）に、"HTTPS"を追加

- ③セキュリティ設定で、"SSL証明書"を登録

- ④ターゲットの登録で、使用するインスタンスを登録

- ※EC2のインバウンドルールでも、"HTTPS"を指定する


#4. Route53 ロードバランサー紐付け

- ①Route53から、対象ドメインのレコードセットに移動する

- ②"Alias"を"Yes"に変更し、"Alias Target"から、ロードバランサーを選択


#5. Nginx起動

###Nginx起動コマンド
```
$ sudo systemctl start nginx.service
```

###Nginx起動確認
```
$ sudo systemctl status nginx.service
```

###Nginx停止コマンド
```
$ sudo systemctl stop nginx.service
```
[JavaScript] Symbolによるprivateを現実的にする

# はじめに
`#`を付ける方法は、対応ブラウザが少ないため、`#`を使用せずにprivateを実現する方法として、こちらの記事を参考にさせて頂きました。
[JavaScriptでprivate「Symbol」編](https://qiita.com/schrosis/items/edfcd7e6a6ad59a36e08)

# 問題点



* クラスを定義する前にprivateなプロパティ名を列挙しなければならない
* publicとprivateで書き方がだいぶ違う
* クラス作るたびにアロー関数作ってシンボル作ってとやることが多い
* 完全なprivateじゃない

上記の記事では、これらの問題点が挙げられていました。

# 解決策

これらの問題点は「完全なprivateじゃない」を除き

* Symbolの保持
* 保持したSymbolの参照

これらの書き方が異なることに起因しています。
つまり、これらの書き方を1つに統一することが出来れば、問題は解決すると言えます。

「完全なprivateじゃない」については

``` javascript
delete Object.getOwnPropertySymbols
```

このように記述しておくことで、Hard privateを実現出来なくは無いので特に問題はありません。

# シンプルなSymbol処理

``` javascript
const PrivateModifier = function() {
  return new Proxy({}, {
    get(obj, name) {
      if (obj[name] === undefined) {
        obj[name] = Symbol(name)
      }
      return obj[name]
    },
    set() {
      throw TypeError("PrivateModifier is read only.")
    }
  })
}
```

## 解説

通常、objectは存在しないプロパティにアクセスした場合、undefinedを返します。
Proxyを利用することで、デフォルトの挙動を変更出来ます。

`PrivateModifier`は、存在しないプロパティにアクセスした際、Symbolを動的に設定するobjectを作成します。

例えば

``` javascript
const _ = {}
_.hoge = Symbol("hoge")
console.log(_.hoge) // Symbol(hoge)
_.huga = Symbol("huga")
console.log(_.huga) // Symbol(huga)
```

``` javascript
const _ = new PrivateModifier
console.log(_.hoge) // Symbol(hoge)
console.log(_.huga) // Symbol(huga)
```

これらは同じ意味になります。

値はこのようになります。

``` javascript
const _ = new PrivateModifier
console.log(_.hoge === _.hoge) // true
```

## 使用方法

### パターン1 (prototype)

``` javascript
const ClassName = (function() {
  const _ = new PrivateModifier

  // constructor
  function ClassName(privateValue, publicValue) {
    // private instance
    this[_.privatePropertyName] = privateValue
    // public instance
    this.publicPropertyName = publicValue
  }

  // alias
  const proto = ClassName.prototype

  // private prototype
  proto[_.privateMethodName] = function() { }
  // public prototype
  proto.publicMethodName = function() { }

  return ClassName
})()
```

### パターン2 (class)
``` javascript
const ClassName = (() => {
  const _ = new PrivateModifier

  return class ClassName {
    constructor(privateValue, publicValue) {
      // private instance
      this[_.privatePropertyName] = privateValue
      // public instance
      this.publicPropertyName = publicValue
    }

    // private prototype
    ;[_.privateMethodName]() { }
    // public prototype
    publicMethodName() { }
  }
})()
```

## 対応状況

* IE以外のブラウザで使用できます
【JavaScript】ブラウザでJavaScriptが効かない時の対処法

プログラミングを勉強中です。

簡単なJavaScriptのプログラムを書いていたタイミングで、
ブラウザ（Googlechrome）でJavaScriptのコードが全く反省されない事態が発生し焦りました。

以下に私の対処法をまとめさせていただきます。

###状況
JavaScriptを用いて簡単な単語帳アプリ を作成中。

【front】の部分をクリックすると裏側の単語が表示される、という機能を
addEventListenerで設定しようとしていましたが、
画面の変化が全く無い状況。

<img width="1434" alt="スクリーンショット 2020-05-17 12.29.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565338/cb714434-ab80-65d3-9569-f5f0e4ec7ba3.png">


###試したこと①　JavaScriptが有効かどうかの確認

そもそも使用しているGooglechromeでJavaScriptは有効になっているのかどうか？を疑いました。
下記のサイトでJavaScriptが有効かどうかを簡単にチェックできます。

[あなたのブラウザでJavaScriptを有効にする方法](https://www.enable-javascript.com/ja/)

私のブラウザでもしっかり有効になっていました。

<img width="1406" alt="スクリーンショット 2020-05-17 12.34.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565338/008a57e7-5f1f-f114-8517-a35465af1c7d.png">


###試したこと②　consoleでのエラー文の確認

JavaScriptでも、デベロッパーツール上にエラーメッセージが表示される為、
comnsoleを確認しました。

Macの方であれば、右上のGooglechromeのボタンクリック→その他のツール→デベロッパーツールで
立ち上げることができます。
私はショートカットキーで、⌘（コマンドキー）＋Shiftキー＋「c」を使用しています。

<img width="1010" alt="スクリーンショット 2020-05-17 12.40.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565338/d58c8ce2-430b-9049-f516-3f7ccc416805.png">

エラーがいくつか出ていました。
一番上の、「ReferenceError: "x" is not defined」ですが、
これはXという変数が定義されていません。という意味になります

<img width="529" alt="スクリーンショット 2020-05-17 12.42.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565338/a27a9f78-234e-3047-bacf-9b891aa943ef.png">

今回の場合、「carnFrontという変数はないですよ」と教えてもらっているので
エラーが出ている行を確認、「cardFront」という変数を定義しているにもかかわらず、
呼び出すタイミングで、「carnFront」とtypoがあったことがわかりました。。。

###今後気をつけること

JavaScriptが効かない場合、consoleに答えがあることがわかったので、
確認する癖をつけること、
また、script内に'use strict';と記載することで文法チェックを行ってくれるので
便利なツールはどんどん使用していこうと思いました。
【Golang】for文

#【Golang】for文
Golangの基礎学習〜Webアプリケーション作成までの学習を終えたので、復習を兼ねてまとめていく。 基礎〜応用まで。

```
package main
//for

import "fmt"


func main() {
	//パターン１
	//for 初期化、 条件、 繰り返し式
    for i := 0; i < 100; i++{
        if i == 3 {
			fmt.Println(3)
			//繰り返し forの中に戻る
			continue
		}
		if i > 30 {
			fmt.Println("抜けた")
			//強制終了
			break
		}
		fmt.Println("30まで")
	}
	//パターン２
	//書き方、別パターン
	sum := 1
	for sum < 10 {
		sum += sum
		fmt.Println(sum)
	}
	fmt.Println(sum)

	//無限ループ
	/*for {
		fmt.Println("hello")
	}*/





	//range
	//配列、スライス、マップ
	/*arr := [3]int{1,2,3}
	slise := []int{4,5,6}
	map1 := map[string]int{"AAA":1, "BBB":2}
	fmt.Println(arr)
	fmt.Println(slise)
	fmt.Println(map1)

	for i := range arr {
		fmt.Println(arr[i])
	}*/

	//スライス
	l := []string{"python", "go", "java"}
	
	//中身を取り出す。長さ分になるまで
	for i := 0; i < len(l); i++ {
		fmt.Println(i, l[i])
	}
	/*
	0 python
	1 go
	2 java
	*/
   
	//長さ分繰り返す
	for i, v := range l {
		fmt.Println(i, v)
	}
	/*
	0 python
	1 go
	2 java
	*/
	
	//index省略
	for _, v := range l {
		fmt.Println(v)
	}
	/*
	python
	go
	java
	*/
	
	//map
	m := map[string]int{"apple": 100, "banana": 200}
	
	//map分繰り返す
	for k, v := range m {
		fmt.Println(k, v)
	}
	/*
	apple 100
	banana 200
	*/
	
	//値省略
	for k := range m {
		fmt.Println(k)
	}
	/*
	banana
	apple
	*/
	
	//key省略
	for _, v := range m {
		fmt.Println(v)
	}
	/*
	100
    200
	*/
}

```
CLionでrustをデバッグする方法

###CLionでrustをデバッグする
- TOOLBOX経由でCLionをインストールする
![tool_box.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/45515def-f8c5-7040-d34e-423ffbeeab46.png)

- Cコンパイラーを選択（インストール）する
![cgwin64_install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/7a60dc99-5c84-f773-3012-0712b1bdb2a7.png)

- msvcはデバッグ不可
`MSVC toolchain is not supported. Please use GNU toolchain.`というエラーは発生しました。
![msvc_error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/af91e136-cd8a-24af-0965-8b030a8ce7a8.png)

- エラー解消方法
`rustup toolchain install stable-x86_64-pc-windows-gnu`でgnu環境をインストールする
![rustc_install1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/9236d3de-b659-36f3-7270-1f3fb8e919b4.png)
`rustup default stable-x86_64-pc-windows-gnu`でデフォルトとして設定する
![rustc_install2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/3b41a1cb-bfe1-14e6-a4ab-a31fa40359e1.png)

- 正常にデバッグできる
![rust_debug.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/990927d8-88c2-3d8e-543c-03bd6eb805d7.png)
【rails】RSpecを用いた統合テスト

フューチャスペックを利用して、ブラウザ上の操作を再現し、期待する動作が行われることを確認する統合テストを行う。

### フューチャスペック
RSpecを使って統合テストを行うためのスペック。
テスト環境の仮装ブラウザを操作し、ボタンを押したときの挙動をテストできる。

gem ```Capybara```を導入し、フィーチャスペックを書く。
##### capybara
ブラウザの操作を再現するのに必要なgem。
特定の要素をクリックした利、フォームから値を入力したり、表示状態を確認したりできる。

### 準備
capybaraを導入する

```ruby:Gemfile
group :test, :development do 
  gem 'capybara'
end
```

```console:terminal
bundle install
```

```ruby:spec/rails_helper.rb
require 'capybara/rspec' #追記
```

テスト対象のビューにIDを付加

```ruby:app/views/tweets/_form.html.erb
<%= form.text_field :image, placeholder: "Image Url", id: "image" %>
<%= form.text_area :text, placeholder: "text" , rows: "10", id: "text" %>
<%= form.submit "SEND" %>
```

フォルダ```spec/features```を作成する。
ファイル```spec/features/tweet_spec.rb```を作成する。

### テストコード
を書く。

```ruby:spec/features/tweet_spec.rb
require 'rails_helper'

feature 'tweet', type: :feature do
  let(:user) { create(:user) }
  scenario 'ユーザー情報が更新されていること' do
    #ログイン前には投稿ボタンがない
    visit root_path
    # 投稿ボタンがないことを確認
    expect(page).to have_no_content('投稿する')

    # ログイン処理
    # ログインフォームのあるページに移動する
    visit new_user_session_path
    # emailを入力する
    fill_in 'user_email', with: user.email
    # パスワードを入力する
    fill_in 'user_password', with: user.password
    # ログインボタンをおす
    find('input[name="commit"]').click
    expect(current_path).to eq root_path
    expect(page).to have_content('投稿する')

    # ツイートの投稿
    expect {
      click_link('投稿する')
      expect(current_path).to eq new_tweet_path
      fill_in 'image', with: 'https://s.eximg.jp/expub/feed/Papimami/2016/Papimami_83279/Papimami_83279_1.png'
      fill_in 'text', with: 'フューチャースペックのテスト'
      find('input[type="submit"]').click
    }.to change(Tweet, :count).by(1)
  end
end
```

##### visitメソッド
引数にURLまたはプレフィックスを指定することで、そのページに移動することができる。

```ruby:example
# "/tweets"に移動する
visit("/tweets")

# tweet_pathに移動する
visit tweet_path
```

##### click_onメソッド
HTML要素をクリックすることができる。
引数にHTML要素のvalue属性を指定する。

##### fill_inメソッド
第一引数にHTMLのIDを、第二引数に　with：入力値をとることで、指定したフォームに値が入力される。
find('input[name="commit"]').clickでログインボタンのクリックを再現する。

```ruby:example
# <input type="submit" name="commit" value="こんにちは">という要素をクリック
click_on("こんにちは")

# <a href="/users/new">会員登録する</a>という要素をクリック
click_on("会員登録する")
```

##### フィーチャスペックの特製
・記法が単体テストと異なる

|フィーチャスペック|単体テスト|
|:----------- |------:|
|scenario|it|
|background|before|
|feature|describe|
|given|let|

・複数のexpectが同一テスト内に記述される。
１つの動作の結果として、期待する複数のexpectがある場合は、その通り書く。

### テスト
```console:terminal
$ bundle exec rspec spec/features/tweet_spec.rb
2020-05-17 12:00:08 WARN Selenium [DEPRECATION] Selenium::WebDriver::Chrome#driver_path= is deprecated. Use Selenium::WebDriver::Chrome::Service#driver_path= instead.

tweet
  ユーザー情報が更新されていること

Finished in 0.43572 seconds (files took 1.54 seconds to load)
1 example, 0 failures
```

期待する通り動作することが確認できた。