OmniAICreator/Qiita-1.07M huggingface dataset:
#Slack に添付ファイル・画像がアップロードされると自動的に public の共有リンクを作成する #python + #Zapier の活用例

# やりたいこと

これ

![image](https://user-images.githubusercontent.com/13635059/54342304-750ba880-467f-11e9-8dd2-f5ada6f23c2f.png)

# 準備 Slack API で APP を作成しておく

- OAuth Access Token を作成しておく
- APP に files:write:user 権限を与えておく

![image](https://user-images.githubusercontent.com/13635059/54342395-a8e6ce00-467f-11e9-994c-7aaac20477b2.png)

# Zapier で Slack の New File をトリガーにする

![image](https://user-images.githubusercontent.com/13635059/54342230-42fa4680-467f-11e9-86be-ef408db44703.png)

# Code by Zapier > Python script をアクションにする

# Input 

![image](https://user-images.githubusercontent.com/13635059/54342340-8ce32c80-467f-11e9-9a0a-520bd3f8d633.png)


# Script

```py
out = {}

import requests, os

token = input_data['token']
channel = input['channel_id']

file_id = input['permalink'].split("/")[5]

share_api_url ='https://slack.com/api/files.sharedPublicURL?token=' + token + '&file=' + file_id + '&pretty=1'

res = requests.get(share_api_url)
results = res.json()

print(results)

output = [out]
```

# 結果

https://slack-files.com/T18TT376E-FGW42RZ4Y-0938563bb9

![image](https://user-images.githubusercontent.com/13635059/54342549-18f55400-4680-11e9-955c-93f01682e0bb.png)


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/775








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
描画の書き換え〜お楽しみはこれからだ！番外編:脱サッパリ系ビスケットプログラミング〜

こちらの記事はサッパリ系ビスケットプログラミング#4〜#7をご覧になった上で読んで頂けると幸いです。

#プログラムが先か、仕上げが先か
####まずは、こんな絵で良いのです
![D53CF6C2-C8EC-46E5-AB04-2A3C4A9FF669.jpeg](https://qiita-image-store.s3.amazonaws.com/0/373284/3eafab0c-bb67-0ee1-98eb-4678b990d72a.jpeg)
描画を後回しにしてサッパリしたプログラムを組む「サッパリ系ビスケットプログラミング」です。

##ゲーム制作の手順について考えてみる
どんなゲームでもそうですが、キャラクターデザインやステージデザインによって作品の仕上がりは全く別者になります。
自作のゲームの場合は特にそうですが、ステージやキャラクターなどに迷いがあったり、画力に自信がなかったりすることもあり、これだと決定するときに迷うこともあるかと思います。

###【ゲーム制作の悩みあるある】
・絵は自信があるが、プログラムは苦手（デザイナータイプ）
・逆、プログラミングは得意だが絵はあまり💦（プログラマータイプ）
・全部仕様が決定してからでないと行動する気にならない（All or Nothing タイプ）
・逆、なんでも良いのでとにかくとりあえずゲームを作って動かしたい（Hands onタイプ）
・空いた時間でコツコツ作っていきたい。考えすぎると進めない。（Small Stepタイプ）
と、こんな感じのお悩み、ないでしょうか？

プログラムが先か、描画が先か？

そんな方々に提唱するのが、描画を後回しにしてサッパリしたプログラムを組む「サッパリ系ビスケットプログラミング」でした。
今回は、プログラムが完成した後のお楽しみ、描画の書き換えです。ビスケットのプログラミングではコーディングは画像で全て行いますので、少しの労力で、元となるプログラムと違う画像のバージョン制作が楽しめます。

#お楽しみはこれからだ！カンタン画像書き換え
![F6B0781E-44FF-436E-815F-FE8A908CE519.jpeg](https://qiita-image-store.s3.amazonaws.com/0/373284/4f863e82-6b96-289e-3d48-9cebec6b34fe.jpeg)
こちらはまだ完成度50%くらいのマリオ風プログラムですが、前回ひと段落ついたので、描画の書き換えをしてみます。
![0603A7F9-4DE8-470B-B59E-65CA58E6DB64.png](https://qiita-image-store.s3.amazonaws.com/0/373284/9d346c55-edf6-a507-4c0f-d28c45a9be97.png)
約15分後にはこんな感じに。ビスケットはこのようにして、完成したプログラムを手軽に描画し直して雰囲気を変えるという楽しみ方があります。
##描画の書き換え方![01FC9E37-29E4-4783-B859-6904D1EADAC4.png](https://qiita-image-store.s3.amazonaws.com/0/373284/2c75de9f-4267-c369-03e5-c1452e1f3e61.png)
描いたパーツを長押しすると鉛筆マークが出現します。
![9D45F2AB-941F-4055-83B9-F67FD1227E29.png](https://qiita-image-store.s3.amazonaws.com/0/373284/bf3b1dc8-39e0-7181-3d1f-147ae466f3d7.png)
するとパーツ描画画面になるので↩️マークをタップすると描画をアンドゥできます。
![8F42EA46-39C9-410F-AB0C-C8590FCF7A7F.png](https://qiita-image-store.s3.amazonaws.com/0/373284/e3791f17-b25a-0e98-d75f-5f9615e20b0d.png)
描画を書き換えて⭕️で決定、プログラム画面に戻ると…![44E0CDE2-E9E6-416F-92CC-E0516B447138.png](https://qiita-image-store.s3.amazonaws.com/0/373284/779b1b08-9437-3ae4-f4b5-6d8abd40d21a.png)
これだけで、ステージの雰囲気はガラリと変わります。背景色をいじって、重力センサーを背景色に類似した目立たない小さなパーツにします。他のパーツも描画の書き換えをすると…
![A6E05DA8-CDE5-4863-9AA1-F44F704657B4.png](https://qiita-image-store.s3.amazonaws.com/0/373284/bea5dc01-3c49-9bcf-fa37-004e27a71755.png)
![0BE11A31-8FAE-43F9-946C-E0F3FF7A976E.png](https://qiita-image-store.s3.amazonaws.com/0/373284/0ebca3c2-4908-a2d0-5c33-425a63bef54d.png)
![640DE506-198F-4596-881A-83BA70D33006.png](https://qiita-image-store.s3.amazonaws.com/0/373284/bf2eedb9-2dff-4699-38c4-14cbef91337f.png)
![9707DC66-1383-4E6E-BF5B-C74FC75FD0AD.png](https://qiita-image-store.s3.amazonaws.com/0/373284/53607065-c68a-646a-284e-a7c845c13b33.png)
これはまだまだ描画の書き換え途中ですが、再描画に飽きたら描きたくなるまでプログラム制作に集中すれば良いのです。
こんな感じでサッパリ系のプログラミング後に描画の書き換えを進めていきましょう。

ビスケットは最初のプログラムが上書きされることはありません。保存しただけの全てのバージョンが残ります。
制作画面の場所をメモしておいて、エンピツマークで制作→保存→新しい制作画面の場所をメモ→以下ループ…

老舗の鰻屋のタレのように、継ぎ足していく感じで気楽にゲーム制作を進めていきましょう。

以上、サッパリ系ビスケットプログラミング番外編でした。
CSS box-shadow , position


# CSS
学んだことを忘れないように備忘録として残しています。

## box-shadow 影をつける

```CSS
 .box-shadow {
   box-shadow:2px 2px 4px -2px gray inset;
 }

```

### 指定場所・説明
　1番目:水平方向の影の距離　正の値→右へ、負の値→左へ影が移動
　2番目:垂直方向の影の距離　正の値→下へ、負の値→上へ影が移動
　3番目:ぼかし距離
　4番目:広がりの距離
　5番目:影の色
　6番目:指定すると影が内側に表示される。基本は省略

## position 表示位置を指定する

```CSS
 .header {
   position:fixed; /* 表示位置を固定*/
   position:absolute; /* 絶対位置に指定*/
   position:related; /* 相対位置に指定*/
 }
```
GitLab Jobsをfailedにする方法

# 概要
GitLab Jobsをコマンドとしては正常なんだけど、コマンドの結果を判定してfailedにしたい。
# 方法
exit 1を返せばいい。
判定した結果でfailedにしたい場合、exit 1を返せばいい。
<a href="http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2019/03/gitlab_jobs_01.jpg"><img src="http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2019/03/gitlab_jobs_01.jpg" alt="" width="1020" height="575" class="alignnone size-full wp-image-1124" /></a>
## .gitlab-ci.yml抜粋

```yaml
Deploy_03:
    stage: deploy
    script:
        - if [ "NG" == "OK" ]; then exit 0; else exit 1; fi
```
## 実行結果
<a href="http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2019/03/gitlab_jobs_02.jpg"><img src="http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2019/03/gitlab_jobs_02.jpg" alt="" width="1009" height="527" class="alignnone size-full wp-image-1125" /></a>
Gitの中身（動画シリーズ）

# 3年前に撮った動画

撮りっぱなしで放置してたものです。

我ながら話のリズムは悪いしダルい動画です、すみません。

活舌が悪いのは歯科矯正をしていたというのもありますが、純粋にベタってところもあり、あとは加齢で言葉が上手く出てこないってのがあります・・・（溜息・・・

でも内容はGit初心者や、Gitの内部に注意を向けてこなかった人には結構役立つ情報かもしれません。

# Gitの中身その１

動画リンク　https://www.youtube.com/watch?v=KknQgXfH_uM&t=14s

## 概要

動画では .git 隠しフォルダー（ディレクトリー）の中、得に .objects フォルダーの内容をコマンドラインで確認しながら解説してます。
.objects フォルダーの構成を理解すると私の場合、急にGitに親しみを感じるようになりました。要は、ハッシュ値を利用したファイルシステムであり、あるハッシュ値を渡すとオブジェクトが返ってくる、そのオブジェクトの内容が参照しているオブジェクトのハッシュ値を渡すとそのオブジェクトの値が返ってくる。ただそれだけなんですね。

ファイルとフォルダー、そしてコミットの基本的な関係、さらにコミットが積みあがっていく状態が具体的に理解できると思います。
それに対応する、blob、tree、そしてcommit オブジェクトを理解できれば、特定のコミットが表すレポジトリをより具体的にイメージ出来るようになると思います。


# Gitの中身その２

動画リンク https://www.youtube.com/watch?v=mpqblZVNof0

## 概要

この動画では特定のファイルをフォルダー間で移動した場合にGitはどのようにトラックしているかを解説しています。Gitの素敵な特徴の一つに「全く同じ内容は全く同じハッシュ値を持つ」というのがあります。これぞ、なぜGitが分散型の開発に強いかの理由です。例えば

```
void main()
{
   printf("hello\n");
}
```

という内容を複数の人が書いたとしたら、そのハッシュ値は完全に一致します。時間と場所に関わらずです。ですから、同じハッシュ値のオブジェクトがローカルのGitレポジトリに存在するならば、ネットワーク越しにそのオブジェクトを別の場所から取ってくる必要がなくなるからです。

あと、この動画ではサブフォルダーを含むフォルダーや、サブフォルダーとファイルを含むフォルダーがどのようにGitで記録されているかも解説しています。

# Gitの中身その３

動画リンク https://www.youtube.com/watch?v=1buKbzimhcI

## 概要

この動画では複数のユーザーで使う場合のGitを見ていきます。Gitはチームで使ってなんぼのものですから、中央レポジトリを作って、2人のユーザーになりすましてコミットを積んでいきます。

「裸(bare)」のレポジトリと、通常の作業ディレクトリがあるレポジトリの違いも分かると思います。

# まとめ

自分はYouTuberには向いてないなと確信した。
ただし、動画に撮るという作業は学習効率は悪くないなと思ったです。もうちょっと頑張ってみようかな（歯科矯正も終わったし！）
RubyでJSONを20倍速でprettifyするGemを作りました。gem 'safe_pretty_json'

## 概要

Github: https://github.com/contribu/safe_pretty_json

jsonが格納されたstringを受け取って、pretty jsonが格納されたstringを返すgemです。

ポイント

- キーの順序が変更されない
- 浮動小数点の表現が変更されない
- string -> stringがネイティブ側で行われるので、中間的なHashとかが作られなくて速い
- 不正なjsonが入力された場合の戻り値は文字列だが、中身は未定義

これらのポイントは以下の素直な実装と比較するとわかりやすいです

```ruby
def prettify(json_str)
  parsed = JSON.parse(json_str) # 中間的なHashが作られる
  JSON.pretty_generate(parsed)
end

# 浮動小数点の精度が落ちてしまう例
prettify('{ "a": 1.11111111111111111111111111111111111111111 }')
```

## インストール

Gemfileに以下を追加

```ruby
gem 'safe_pretty_json'
```

```bash
bundle install
```

## 使い方

### 基本

```ruby
SafePrettyJson.prettify('{"a":1}') == "{\n  \"a\": 1\n}"
```

### Rails (Rackミドルウェア)

以下をapplication.rbに追加。
content-typeがapplication/jsonのときだけ、prettifyする。

```ruby
config.middleware.use SafePrettyJson::RackMiddleware
```

## パフォーマンス

- simple: JSON.pretty_generate(JSON.parse(input))
- safe_pretty_json: SafePrettyJson.prettify

```
                 user     system      total        real
simple       9.840000   0.004000   9.844000 (  9.844245)
safe_pretty_json  0.484000   0.000000   0.484000 (  0.485056)
```

## 開発動機

Railsのjson出力を全てpretty jsonにしたい。
以下のGemを使うとできるが、浮動小数点の表現が変更されるし、遅い。
https://github.com/zeiv/rails_pretty_json/blob/master/lib/rails_pretty_json.rb
BootStrapのcardでフォームを開閉させる


![image.png](https://qiita-image-store.s3.amazonaws.com/0/66405/a000c19d-d9f0-5e57-7ac8-84f084a953a8.png)

Bootstrapのcardを使って、フォームを隠せるようにします。
card-headerの部分をクリックするとcard-bodyが開閉するようにします。

card-bodyを直接開閉させるとアニメーションがおかしいので、親にsearch-divを作ってそれを動かすとスムーズになります。


```erb
<div id="searcher" class="card">
  <div class="card-header toggle-mark" id="search-header">
    <a data-toggle="collapse" href="#search-div" class="collapsed">"検索条件"</a>
  </div>
  <div class="collapse" id="search-div">
    <div class="card-body">
      <%= form_tag issues_path, method: :get do %>
        <div class="form-group row" %>
          <%= label :product, t_issue[:product], class: 'col-sm-2 col-form-label' %>
          <div class="col-sm-10">
            <%= collection_select :searcher, :product_id, Product.all, :id, :name, { selected: @filter[:product_id] }, class: 'form-control' %>
          </div>
        </div>
        <div class="form-group row">
          <%= label :findword, t_issue[:findword], class: 'col-sm-2 col-form-label' %>
          <div class="col-sm-10">
            <%= text_field :searcher, :findword, { value: @filter[:findword], class: 'form-control' } %>
          </div>
        </div>
        <div class="form-group row">
          <div class="col-auto ml-auto">
            <%= submit_tag t("buttons.apply"), class: 'btn btn-outline-primary button__middle' %>
          </div>
        </div>
      <% end %>
    </div>
  </div>
</div>
```

toggle-markは右端の開閉アイコンになります。
`font-weight: 900` を指定しないと表示されません。

```css
<style>
.toggle-mark a::after {
  text-decoration: none;
  font-family: "Font Awesome 5 Free";
  content: "\f078";
  float: right;
  text-decoration: none;
  font-weight: 900;
}

.toggle-mark a.collapsed::after {
  content: "\f054";
}
</style>
```

ちょっと余白が多すぎてスペースが無駄ですが。

Rails 5
Bootstrap 4
Font Awesome 5
vue.js スクロール位置を指定して router push

まずは router.push。
この時、現在のスクロール位置も同時に渡す。

```

//console.log("現在のスクロール位置" + window.scrollY);
this.$router.push({
    path: "/mugen?page=" + page + "&y=" + window.scrollY,
});

```


で、
・ハッシュタグがあればハッシュタグへ飛ばす
・移動先に y があれば y の位置に飛ばす

```app.js

const router = new VueRouter({
    mode:'history',
    routes,
    scrollBehavior (to, from, savedPosition) {

        // <a v-touch="$root.linkTo('#saikabu')">最下部へ</a>
        if (to.hash) {
            return {selector: to.hash}
        }

        if (savedPosition) {
            return savedPosition;
        } else {

            if(to.query.y){
                return { x: 0, y: to.query.y }
            } else {
                return { x: 0, y: 0 }
            }

        }
    }
});


```

って感じ。
meta とかに渡してみたが、うんともすんとも行かなかったので。。。
animateで複数のプロパティと同時にtransformの値も変化させる

animateで回転を付ける時には、あまり見え方に影響のないプロパティ（z-indexなど）を0から1にした値をstepで取得して、必要な値になるよう乗算し、cssでtransform:rotate()の中に連続的に格納するという方法が一般的だと思うけど、回転以外の動きも同時につける方法が見つからなかったので、やってみました。

```javascript:jquery
$('#target').css({
   top:'10px',
   left:'10px',
   opacity:'0',
}).stop().animate({
   top:'100px',
   left:'200px',
   opacity:'1',
   dummyprop:'45'//ステップ用のダミープロパティを設定（初期値は0となる様子）
},{
   duration:1000,
   step:function(s,n){
      if(n['prop']=='dummyprop'){//n['prop']でanimateしているプロパティ名を取得できる
         //console.log(s);//dummypropの変化が取得できる
         $(this).css('transform','rotate('+s+'deg)');
      }
   }
});
```
- dummypropは$('#target')のどこかに格納されるようで、再度animateする時は変化した後の値（例の場合は45）からスタートとなる。
- 上記はダミープロパティ名をdegとかにしておいた方が保守性は高そう。
- dummypropは複数設定できる。
- 上記ではcssでまず初期化みたいなことをしているけど、ここにdummypropで初期値を設定しようとすると、おかしな挙動になる。

dummypropなんていう変なものを設定するのが嫌な時は、やっぱりz-indexあたりをanimateさせて、stepのなかでn['prop']=='z-index'で変化値を取得するのが良いかもしれない。step:function()の第二引数を取得することで、欲しいプロパティの値を選べるのがミソ。
日付の文字列をエポック秒に変換

```perl
use strict;
use Time::Local;
# $rhData->{EndDate} 2020/01/01 10:00:00

# my @format = ($year, $month, $day, $time);
my %rhData = (
    EndDate => '2020/01/01 10:00:00'
);

my @date = split(/\/|\s|:/, $rhData{EndDate});
# print "@date\n";

$rhData{year}  = $date[0];
$rhData{month} = $date[1];
$rhData{day}   = $date[2];
$rhData{hour}  = $date[3];
$rhData{min}   = $date[4];
$rhData{sec}   = $date[5];

print $rhData{year};
print $rhData{month};
print $rhData{day};
print $rhData{hour};
print $rhData{min};
print "$rhData{sec}\n";

my $sec_epoch = timelocal(
    $rhData{sec}, $rhData{min}, $rhData{hour},
    $rhData{day}, $rhData{month}-1, $rhData{year}-1900
);

print "$sec_epoch\n";

```
---
上の無駄な箇所を省いたもの。

```perl
use Time::Local;

%rhData = (
    EndDate => '2020/01/01 10:00:00'
);

my @date = split(/\/|\s|:/, $rhData{EndDate});

$rhData{year}  = $date[0];
$rhData{month} = $date[1];
$rhData{day}   = $date[2];
$rhData{hour}  = $date[3];
$rhData{min}   = $date[4];
$rhData{sec}   = $date[5];

my $sec_epoch = timelocal(
    $rhData{sec}, $rhData{min}, $rhData{hour},
    $rhData{day}, $rhData{month}-1, $rhData{year}-1900
);

print $sec_epoch, "\n";
```
SQLについての基本事項

#はじめに
今回は、SQLの学習内容を忘備録として記録する。
先月PHPを用いてデータベースを作成した際にSQLを使用した。
しかし、詳しく理解していなかったため学習しなおした。
初学者の為、内容に誤りがあればしてきしていただけるとありがたいです。

#データベースについて
###データベース管理システムとは？
まず、データベースとは、大量のデータを管理し、検索できるようにするもの。
**データベース管理システム**とは、このデータベースを作成したり管理したりするソフトウェア。
ちなみにデータベース管理システムは**DRBS**と略される。
また、二次元の表で管理するDBRMを**RDBMS**と呼ぶ。（←主流）
SQLとは、DRBSの主要な問い合わせ言語である。
要は、データベースに命令を送る言語。
###スキーマ
データをデータベースに格納するときに、データの性質や形式、他のデータとの関連といったような**データ定義**が集まったもの。
一般的に、「外部スキーマ」「概念スキーマ」「内部市スキーマ」の三層に分けた[三層スキーマ](http://db-study.com/archives/36)という方式が用いられている。
詳しくはリンク参照。
#データベースの仕組み
###一般的な名称
データベースを管理するの表のことを**テーブル**と呼ぶ。
また、テーブルにおいてタテ列を**カラム**、横の列を**レコード**と呼ぶ。
###キー
**キー**を用いて他の表と関連づけられる。
・主キー・・・データ列を特定できる行や列の組み合わせ
・外部キー・・・他の表の主キーと対応するキー
・複合キー・・・複数列の組み合わせでキーになるもの
詳しくは[こちら](https://www.sejuku.net/blog/54072)
#SQLについての基本構文
####SELECTとFROM
どのテーブルからどのカラムを選択するかを記述する方法。
ちなみに、カラム名は「,」で区切れば複数選択できる
全てのカラムを選択する際はカラム名の部分を「*」と表記する

```SQL
SELECT カラム名　FROM テーブル名;
```
####WHERE
抽出したい条件を加える。
例えば、ある列の単語が含まれるデータを選択したければ、選択する列名とその中で選択したい単語を以下のようにWHEREの後に記述する。
ちなみに、選択する単語が数字の際は「”」はいらない。（日付は「"」が必要）

```SQL
SELECT カラム名　FROM テーブル名 WHERE 列名="選択する単語";
```
####比較演算子
また、不等式を用いることで、選択した数値以上以下（日付なら以降、以前）を選択できる。

```SQL
SELECT カラム名　FROM テーブル名 WHERE 列名<=数字;
```
####BETWEEN述語
条件の上限と下限を選択できる。

```SQL
SELECT カラム名　FROM テーブル名 WHERE 列名 BETWEEN 下限値 AND 上限値;
```

####LIKE演算子
LIKEを用いることで、その文字列を含む条件のものをすべて抽出できる


```SQL
SELECT カラム名　FROM テーブル名 WHERE 列名　LIKE　文字列;
```
また、「%」を用いると以下のように条件を絞れる。
・%文字列・・・前方一致
・%文字列%・・・完全一致
・文字列%・・・後方一致

####NOT演算子
記述する条件に一致しないデータを抽出できる。

```SQL
SELECT カラム名　FROM テーブル名 WHERE NOT 条件;
```
####NULL
NULLとは、存在しないデータのこと。（データ表における空欄）
NULLには「＝」を用いることができない。
例えば、NULLを含まないカラムを抽出したい場合は以下のように記述する。

```SQL
SELECT カラム名　FROM テーブル名 WHERE 列名　IS NOT NULL;
```

####AND演算子
両方を満たす条件を書く際に使用。

```SQL
SELECT カラム名　FROM テーブル名 WHERE 条件 AND 条件;
```

####OR演算子
どちらを満たす条件を書く際に使用。

```SQL
SELECT カラム名　FROM テーブル名 WHERE 条件 OR 条件;
```

####ORDER BY
データを昇順（ASC）か降順（DESC）に並べる。

```
ORDER　BY カラム名　並べ方;
```

####LIMIT
データ数を決める。

```SQL
SELECT カラム名　FROM テーブル名 LIMIT データ数;
```

####表の結合
複数のテーブルを結合する方法。
テーブル1とテーブル2を結合する場合以下のように記述。
条件には、二つのテーブルで共通の列を指定する。

```SQL
SELECT カラム名　FROM テーブル1名, テーブル2名 WHERE 条件
```

####IN値
IN内のどれかと一致したデータを抽出する際に使用。

```SQL
SELECT カラム名　FROM テーブル名 WHERE 列名　IN(数値,数値,数値);
```

####SUM関数
選択したカラム名の合計

```SQL
SELECT (カラム名)　
```

####GROUP BY
選択したカラムごとにグループ化する。

```SQL
SELECT カラム名　FROM テーブル名 GROUP BY カラム名;
```

####HAVING
グループ化したデータをさらに絞り込みたい際に使用

```SQL
SELECT カラム名　FROM テーブル名 GROUP BY カラム名　HAVING 条件;
```

####データの実行順序
「WHERE」→「GROUP BY」→「関数」→「HAVING」の順番で実行される。

#まとめ
今回はSQLについての基本事項について記述した。
もっと実践的に使っていけるように精進したい。
再度ではあるが、ミスや間違いがあればご指摘いただいたければ修正します。
Azureのrole assignmentで `~ does not have authorization to perform action 'Microsoft.Authorization/roleAssignments/write' ~` が出たとき

## 前置き

AzureのRBACをちゃんと理解していれば調べるまでもないことで，Microsoftのドキュメントをちゃんと読んでいれば理解できることではあるのだが，同じことを過去に一度調べた記憶があるので，自分用に記録を残しておくことにする．


## 経緯

AKSでInternal Load Balancerを使おうと，[ここ](https://docs.microsoft.com/en-us/azure/aks/internal-lb)を参考に`kubectl apply`したのだが，`EXTERNAL-IP`が`<pending>`のままである．

考えてみれば当然で，LBの配備先にAKSの管理下に無いサブネットを指定しているのだから，クラスタのサービスプリンシパルに対象サブネットを操作する権限が必要である．

前述のマニュアルにもバッチリと「`Network Contributor`ロールをクラスタのサービスプリンシパルを当てる必要があるよ」と書かれている．ドキュメントはちゃんと読もう．

## 問題

さて，意気揚々と実行してみると次のようなエラーが出た．

```
$ az role assignment create --assignee ********-****-****-****-************ --role "Network Contributor" --scope /subscriptions/********-****-****-****-************/resourceGroups/RG_SAMPLE/providers/Microsoft.Network/virtualNetworks/sample
ERROR: The client 'firstname.sirname@domain.local' with object id '********-****-****-****-************' does not have authorization to perform action 'Microsoft.Authorization/roleAssignments/write' over scope '/subscriptions/********-****-****-****-************/resourceGroups/RG_SAMPLE/providers/Microsoft.Network/virtualNetworks/sample/providers/Microsoft.Authorization/roleAssignments/********-****-****-****-************'.
```

どうやらお前のアカウント（client）はロールを書き込む権限が無い．と怒られているようだ．

しかし，このアカウントはサブスクリプション上で`Contributor`ロールが割り当てられており，展開済みのリソースは全てこのアカウントから展開している．

何の権限が必要なのだろうか．

## 解決

RBACのアクセス権付与，つまり`Microsoft.Authorization/roleAssignments/write`へのアクセス権限は，組み込みのロールのうち

- Owner
- User Access Administrator

この2つのロールしか持っていないと[公式ドキュメント](https://docs.microsoft.com/en-us/azure/role-based-access-control/role-assignments-rest)に書いてある．

つまり，Contributorではアクセスできない．

わかってしまえば単純な話で，`az role assignment create`を実行するユーザに`User Access Administrator`ロールを割り当て，`az logout`と`az login`を実行後[^1]，再度`az role assignment create`を試すとうまくいった．

[^1]: ログイン・ログアウトが必要だったのかはわからない．時間が経てば問題なかった可能性はあるが，私の環境では `User Access Administrator` ロールの割当直後 `az role assignment create` が同じエラーで失敗していたので，再ログインすればcredentialが更新されるんじゃないか？とやってみたらうまくいった
Nuxt.jsとaxiosでエラーTypeError: Cannot read property '$get' of undefined

## エラー内容

```
TypeError: Cannot read property '$get' of undefined
```

Nuxt.jsでaxiosを導入したのに…何で！？

## 導入手順

1. `npm install --save @nuxtjs/axios`でaxiosをインストール
2. nuxt.config.jsの設定ファイルを編集
3. async, await, `$axios.$get`などで使える！

### エラー原因

> 2.nuxt.config.jsの設定ファイルを編集

原因は**「設定ファイルの追記をしていない」**もしくは**「デフォルトの記述より上に書かれている」**でした。

どれだけアホなミスなんでしょうか…笑

```js:nuxt.config.js
import pkg from './package'

export default {
  mode: 'universal',

  // デフォルトで色々書いてる

  // ↓↓↓ デフォルトの末尾に追記 ↓↓↓
  modules: [
    '@nuxtjs/axios',
  ],
  axios: {
  },
}
```
はじめてのC++【18日目】

#はじめに
外出先にwifiが飛んでいないというまさかの環境です。
pcが使えないためスマホで投稿しているので、教科書の内容に沿って進めることだけにします。
##ロベールのC++【18日目】
###07-01　昨日の続き
昨日作った```InputStream```と```ArrayStream```は、同じような形である。大ざっぱに見れば「0以上の値を順次取得していく処理」という同じ処理のクラス。
これは、その値の源がキーボードからの入力か、それとも配列からのという違いがあるだけでほとんど同じ。こういう場合は、その共通部分を抜き出していつ1つクラスを作ることができる。そして、その共通部分をまとめたクラスを```基底クラス```という。また、基底クラスを基にして作られたクラスを```派生クラス```という。そして、基底クラスを基にして派生クラスを作ることを「継承」あるいは「派生」と言う。

派生クラスはその基底クラスのメンバを引き継ぐ。派生クラスでは、足りないメンバを定義すればいいことになります。基底クラスから派生クラスへとメンバが受け継がれることを「継承」という。

基底クラスStream.hを作る。

```Stream.h
#ifndef STREAM_H_
#define STREAM_H_

//0以上の値を順次取得していく処理行うための基底クラス
class Stream {
public:
  double Get() const;//設定された値を取得

public:
  double m_n; //現在の値
};

#endif 
```

```Stream.cpp
#include "Stream.h"

//設定された値を取得
double Stream::Get() const {
  return m_n;
}
```

```Average2.cpp
#include "InputStream2.h"
#include <iostream>

bool
Average(InputStream& stream) {
  int count;
  double avr = 0;

  for(count = 0; stream.Set(); ++count) {
    avr += stream.Get();
  }

  if(count == 0){
    return false;
  }

  avr /= count;
  std::cout << "平均値は " << avr << "です。" << std::endl;
  return true;
}

int main(){
  while(true){
    InputStream stream;
    if(!Average(stream)){
      break;
    }
  }
}
```
```InputStream2.h
#ifndef INPUTSTREAM2_H_
#define INPUTSTREAM2_H_

#include "Stream.h"

//入力クラス
class InputStream :
  public Stream
{
public:
  bool Set(); //入力関数
};

#endif
```
```InputStream2.cpp
#include "InputStream.h"
#include <iostream>

//入力関数
bool
InputStream::Set(){
  std::cin >> m_n;
  return m_n >= 0;
}
```
これで実行すると前とおなじ実行結果が出てきた。


```ArrayStream2.h
#ifndef ARRAYSTREAM2_H_
#define ARRAYSTREAM2_H_

#include "Stream.h"

class ArrayStream :
  public Stream
{
public:
  ArrayStream(const double* array);
  bool Set(); //新しい値を設定

private:
  const double* m_array;//配列
  int m_i; //現在のインデックス
};

#endif
```
```ArrayStream2.cpp
#include "ArrayStream2.h"

ArrayStream::ArrayStream(const double* array) {
  m_array = array;
  m_i = 0;
}

bool ArrayStream::Set() {
  m_n = m_array[m_i];
  if(m_n >= 0){
    ++m_i;
    return true;
  }else{
  return false;
  }
}
```
```Average3.cpp
#include "ArrayStream2.h"
#include <iostream>

bool
Average(ArrayStream& stream) {
  int count;
  double avr = 0;

  for(count = 0; stream.Set(); ++count) {
    avr += stream.Get();
  }

  if(count == 0){
    return false;
  }

  avr /= count;
  std::cout << "平均値は " << avr << "です。" << std::endl;
  return true;
}

int main(){
  static const double ARRAY1[] = { 1, 2, 3, -1};
  static const double ARRAY2[] = { 1.5, 0.5, -1};
  static const double ARRAY3[] = { -1 };
  static const double* ARRAY[] = { ARRAY1, ARRAY2, ARRAY3};
  static const int SIZE = sizeof ARRAY / sizeof *ARRAY;

  for(int i = 0; i < SIZE; ++i){
    ArrayStream stream(ARRAY[i]);
    if(!Average(stream)){
      break;
    }
  }
}
```

このように継承を利用したら複数のクラスの共通部分を一箇所にまとめることができる。

#終わりに
今日はここまで！
おやすみなさい
driver側でデバイス認識時にインターフェースを制御する

## はじめに

デバイス認識時になんやかんやしたい時。通常はudevで色々やればいい話なんですが搭載されていない環境(Androidとか)での制御方法について
せっかくdriverのコードを読んだので覚書

## driver動作の流れをざっくり

- `module_init`でdriverの処理を登録
- `module_exit`でdriverの処理を削除(デストラクタのようなイメージ)
- その他driverの種類や用途によって登録処理の内容が異なる
    - USBデバイスなら`module_usb_driver`とか、`module_XXX_driver`が多そう
    - これらで関数ポインタを登録して、対応するドライバのアクセスがあったら関数が呼ばれる

特に登録する関数ポインタの中で.probeがデバイス認識時に呼ばれます。

オブジェクト指向の言葉で言い換えると、

`module_init`⇒コンストラクタ
`module_exit`⇒デストラクタ
`module_XXX_driver`で使う構造体(関数ポインタの定義)⇒インターフェースクラス
`module_XXX_driver`⇒インターフェースクラス実装

って感覚が近い気がします。例えばUSBデバイス系のdriverなら`usb_driver`インターフェース(`struct usb_driver`)で、以下のように関数を代入することでメソッドを定義する感じ。

```C
static struct usb_driver ax88179_178a_driver = {
        .name =         "ax88179_178a",
        .id_table =     products,
        .probe =        usbnet_probe,
        .suspend =      ax88179_suspend,
        .resume =       ax88179_resume,
        .reset_resume = ax88179_resume,
        .disconnect =   usbnet_disconnect,
        .supports_autosuspend = 1,
        .disable_hub_initiated_lpm = 1,
};
```

というわけで、デバイス認識時で何かしたい⇒デバイス認識時に呼ばれる`.probe`でなんやかんやすればいいというわけです。

## デバイス認識時にインターフェース制御したい

netdevice.hの`int dev_change_flags(struct net_device *, unsigned int);`を使います。
第一引数はdriverの関数ポインタの引数で渡ってくるdev構造体を利用。USBデバイスドライバの場合の引数は`struct usb_interface *udev`なので、中身を参照する必要があります。
usbnet.cを参考に、こんな感じでnet_deviceを取り出します。

```c:
struct usbnet *dev = usb_get_intfdata(intf);
struct net_device * net = dev->net;
```

後はflagを弄るだけ。flagの定義は[ioctl、netdevice](https://linuxjm.osdn.jp/html/LDP_man-pages/man7/netdevice.7.html)のflagと同じです。
今のflagは`dev->flags`に詰まっているので、そちらにflag追加するだけ。例えばIFF_UPをor演算で追加すればデバイスがupします。

```C
        unsigned int flags = dev->flags;
        int ret;
        ret = dev_change_flags(dev, flags | IFF_UP);
```

### これで完了。と思いきや

何も考えずにこちらを実行するとこんなエラーログが出ます。`RTNL: assertion failed at`。
ログの原因は`ASSERT_RTNL`。!rtnl_is_locked()の条件に引っかかっています。エラー要因としては`rtnl_lock`してないから。`rtnl_lock`、`rtnl_unlock`を実行してあげる必要があるようです。

```C
        unsigned int flags = dev->flags;
        int ret;
        rtnl_lock();
        ret = dev_change_flags(dev, flags | IFF_UP);
        rtnl_unlock();
```

ただ他のdriverコードを見ると、例えば`linux-4.9/drivers/net/vrf.c`なんかは`rtnl_lock()`呼んでないケースもあったり。
どこでlockを読んでるのか、コードを読んだ上で追加が必要ですね。

## 参考

[linux-4.9 driverコード](https://cdn.kernel.org/pub/linux/kernel/v4.x/)
linux-4.9.tar.gz、
kernelのdriverコード:linux-4.9/drivers/net/usb/usbnet.c, linux-4.9/drivers/net/vrf.c等
文字コードの確認と変更

#文字コード確認
文字コードを確認するためには
```
SHOW VARIABLES like 'char%';
```
と入力することで確認することができます。

#文字コードの変更
調べたところ他にも変更する方法があるようですが僕は
```
SET character_set_database=utf8mb4;
```
のようにしてcharacter_set_databaseの文字コードを変更しました。
JavaScriptのsortについて理解を深める

## はじめに
JavaScriptのsortメソッドが直感的に少しわかりにくいと感じたので、アウトプットしておきたいと思います。

## sortメソッドの注意点
sortメソッドは**破壊的メソッド**ということに注意が必要です。

これを間違えるとバグを引き起こしてしまう原因になってしまう可能性があります。

## 実際に見てみる
sortメソッドはデフォルトではUnicodeコードポイント(文字列比較)の昇順にソートされます。みてみましょう。

```javascript
const months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort();
console.log(months);
// expected output: Array ["Dec", "Feb", "Jan", "March"]

const array1 = [1, 30, 4, 21, 100000];
array1.sort();
console.log(array1);
// expected output: Array [1, 100000, 21, 30, 4]
```

上のコードの`array1`のように数字の場合でも、数的なソートではなく文字列比較に基づきソートされることに注意が必要です。

そして、ちょっと理解しずらいのが引数にcallback functionをとる場合です。

MDNのドキュメントでは、以下のようにcallback functionの引数がaとbで書いてあり少しわかりずらいと個人的に思いました。

```javascript
function compare(a, b) {
  if (ある順序の基準において a が b より小) {
     return -1;
  }
  if (その順序の基準において a が b より大) {
     return 1;
  }
  // a は b と等しいはず
  return 0;
}
```

実際にはa→previous value, b→current valueを表しているので、これからa→pre, b→curと書いていくことで理解を深めたいと思います。
最初の要素からArray.prototype.reduceのように一つづつずらしていくイメージです。

重要↓
そして、以下の３パターンのみ覚えればJavaScriptのsortはマスターできます！
1. callback functionが0未満を返す場合、pre を cur より小さい添字にソートする。
2. callback functionが0を返す場合、pre と cur は変化しない。
3. callback functionが0より大きい値を返す場合、cur を pre より小さい添字にソートする。

これを、具体例で見て行きます。

```javascript
const items = [
  { name: 'Edward', value: 21 },
  { name: 'Sharpe', value: 37 },
  { name: 'And', value: 45 },
  { name: 'The', value: -12 },
  { name: 'Magnetic', value: 13 },
  { name: 'Zeros', value: 37 }
];

// 名前順にソート
items.sort((pre, cur) => {
  const nameA = pre.name.toUpperCase(); // 大文字と小文字を無視する
  const nameB = cur.name.toUpperCase(); // 大文字と小文字を無視する
  if (nameA < nameB) {
    return -1;
  }
  if (nameA > nameB) {
    return 1;
  }

  // names must be equal
  return 0;
});
```

このように書くことができます。慣習的に0未満の値には-1, 0より大きい値には1を用います。

## 補足
単に数字を比較する場合はもっと単純に次のようにも書くこともできます。(これも上の理論と原理は一緒です。）

```javascript
const numbers = [4, 2, 5, 1, 3];
numbers.sort((pre, cur) => {
  return pre - cur;
});
console.log(numbers);

// [1, 2, 3, 4, 5]
```

この書き方も覚えておくと良いと思います！

最後まで読んでいただきありがとうございました！
pythonでもtictocしたい

# 実行速度を測りたい

pythonとmatlabの実行速度計測の話です

# tictocとは?

tiktokではない。
matlabにある区間を指定して実行速度を測る便利なやつ。
こんな感じで実行速度が見れる。

```matlab:matlab
tic
% 計測区間
toc

>> 経過時間は 0.000157 秒です。
```

## matlabのtictoc便利......

でもpythonではtictocできない。
コード中のボトルネックどこー？ってなった時にめんどくさい。
ある区間の実行速度を計測しようとするとこんな感じになる。

```python:python
import time

start = time.time()
# 計測区間
print(time.time() - start)
```

jupyter使ってると楽なんですけどね。セルの先頭にちょろっと書いて終わり。

```python:jupyter
%%time
# 計測区間
```

でもjupyterで動かさないことも多いし、パッとこの区間の実行速度知りたい！って時にめんどくさい

# 本題

これでいいや

```python:tictoc
import time

def tic():
    #require to import time
    global start_time_tictoc
    start_time_tictoc = time.time()


def toc(tag="elapsed time"):
    if "start_time_tictoc" in globals():
        print("{}: {:.9f} [sec]".format(tag, time.time() - start_time_tictoc))
    else:
        print("tic has not been called")
```

## 使い方

大体同じ。表示内容にタグつけれる分優位。"()"をつけなきゃいけないのでちょっとつらい。

```python:tictoc
tic()
# 計測区間
toc("task1")  # 何も入れずに toc() でもいい

>> task1: 0.000114918 [sec]
```

これをDashとかでスニペットに登録しといて「うわー実行速度知りてー」って時に召喚すれば良いと思います。
detox でテストを直列に実行する

# はじめに
`detox`に関する連続投稿になります。
[前回](https://qiita.com/dhythm/items/1299cd0751c54b8ff728)の冪等性云々の話とは少し逆の内容なります。

メンテナンス性を考慮し、テストファイルを細かく分けることは実運用では起こり得ます。
その際、前のテストの状態を引き継いで検証したいケースもあるかと思います。
`e2e`テストでは、ユーザの流れを意識し、前の状態が必要な場合が出てきます。
状態を引き継げないとなると、すべてのテストで同様の処理を走らせることとなり、処理時間やメンテナンス性が非常に悪くなると考えられます。

`detox`でこれを実現する際に嵌った部分について備忘も兼ねて記事にしました。

# 処理の直列化について
`Jest`には`--runInBand`オプションがあり、それを用いることでテストを直列化することができます。
> Run all tests serially in the current process, rather than creating a worker pool of child processes that run tests. This can be useful for debugging.

テストランナーに`Jest`を採用できる`detox`はというと、[公式ドキュメント](https://github.com/wix/Detox/blob/master/docs/APIRef.Configuration.md#jest)に以下のように書いてました。
> NOTE: jest tests will run in band, as Detox does not currently supports parallelization.

つまり`detox`はデフォルトで`--runInBand`として処理されるようです。

次に、ファイルを分割した際の処理順です。
[GitHub の issue](https://github.com/wix/Detox/issues/754#issuecomment-393232525) には、「ファイル名を順番にしておくことでその名前順に処理されるよ」と書かれていました。

**それを信じて試してみると………、あれ？ファイル名順に処理されない……？**

何度か試してみたしたがどうもダメでした。
[`Jest` 側の issue](https://github.com/facebook/jest/issues/4032#issuecomment-315210901) を見ると、処理順は保証すべきではないというコメントも発見しました。

# テストを名前順に処理する
前述の通り、テストを記載したファイル名を規則的に並べてもテストは名前順に処理してくれませんでした。
これでは、前の状態を再利用してテスト（ログインのテスト→ログイン後の画面のテスト、など）をおこなうのが困難です。

色々と試行錯誤する中で、とある [GitHub の issue](https://github.com/facebook/jest/issues/6194#issuecomment-419837314) を発見しました。
それは、各テストを個別のファイルとして定義し、テストスイートとして各テストを順序別に呼び出して実行する、という方法でした。
[StackOverflow の記事](https://stackoverflow.com/questions/32751695/how-to-run-jest-tests-sequentially)によると `describe` のブロックは、次の `describe` の処理をブロックするというものでした。
これを信じて実装してみたところ、ちゃんと直列・呼び出し順に処理がされていることが確認できました。

最終的なテストスイートは下記のような内容になりました。

```typescript
import { testA } from './../scenarios/01_testa';
import { testB } from './../scenarios/02_testb';
import { testC } from './../scenarios/03_testc';

describe('test A', testA);
describe('test B', testB);
describe('test C', testC);
```

個々のテストは下記のような形で定義します。

```typescript
export const testA = () => {
  beforeEach(async () => {
    // something...
  });

  it('can access', async () => {
    // something...
  });
};
```

# おわりに

色々と試行錯誤したり、公式 issue で「この方法でできるよ」って言われている方法ではできなかったりで苦労しました。
この方法だとテストスイートが肥大化していきますが、とりあえず現時点でやりたいことは実現できました。

もっと良い方法をご存知であればご教示いただけると嬉しいです。
古い日付を扱うのはめんどくさいという話

# 概要
一般的に、プログラミングにおける日付の処理はけっこう面倒な部類の処理だと思いますが、古い日付を扱う場合はもっと面倒になるよという話をします。
サンプルコードはJavaで書いていますが、他の言語でも同様の問題は起こると思います。

# 動作環境
- Java11
- JShellを使用

# 本文
## ケース1：タイムゾーンオフセットが「+09:18:59」になる
```java
LocalDateTime.of(1887, 1, 1, 0, 0).atZone(ZoneId.of("Asia/Tokyo"));
// 1887-01-01T00:00+09:18:59[Asia/Tokyo]
```
日本標準時のタイムゾーンオフセットは基本的に「+09:00」なのですが、1887年を指定すると、なんとタイムゾーンオフセットが「+09:18:59」となっています。
秒も含まれていて一般的なフォーマットと違うため、たとえばこの値をサーバで生成してクライアントに返すなどした場合、フロントエンド側のJavaScriptのコードでパースした時に失敗するといった問題が起こり得ます。（起こりました）

### 原因
tz databaseで実際そうなっているためです。tz databaseとは、名前の通りタイムゾーン情報のデータベースです。JavaではJREに同梱されており、Javaで日時を扱うライブラリから参照されています。

現在の日本標準時は1888年1月1日から始まっており、その前は違ったので、tz databaseにそのことが反映されているということです。

## ケース2：日付が10日間すっ飛ぶ
旧APIとJava8以降の新APIで結果が変わるという例です。

まずは旧APIから。

```java
var cal = Calendar.getInstance();
cal.clear();
cal.set(1582, Calendar.OCTOBER, 4);

var sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.format(cal.getTime());    // "1582-10-04 00:00:00"
```

1582/10/4を指定し、それがそのまま出力されました。では新APIではどうなるのでしょうか？

```java
var cal = Calendar.getInstance();
cal.clear();
cal.set(1582, Calendar.OCTOBER, 4);

LocalDateTime.ofInstant(cal.toInstant(), ZoneId.of("Asia/Tokyo"));
// 1582-10-14T00:18:59
```

なんと、10日間もずれてしまいました。

### 原因
ライブラリによって、1582年10月15日より前の扱いが異なるためです。1582年10月15日は特別な日付で、現行のグレゴリオ暦が導入された日です。
それよりも前はユリウス暦という暦が使われていました。それで、1582年10月15日より前の日を実際通りにユリウス暦として扱うライブラリと、擬似的にグレゴリオ暦（先発グレゴリオ暦）として扱うライブラリに分かれていて、Javaにおいては旧APIが前者、新APIが後者と違いがあるため、結果が変わってしまったということです。

また、ユリウス暦からグレゴリオ暦への移行は、ユリウス暦における1582年10月4日の翌日を、グレゴリオ暦の1582年10月15日とする形で実施されました。つまり実際に10日間すっ飛んだので、その差が日付ライブラリの処理結果としてそのまま出たわけです。

## ケース3: タイムゾーンオフセットが1時間ずれる
```java
LocalDateTime.of(1950, 8, 1, 0, 0).atZone(ZoneId.of("Asia/Tokyo"));
// 1950-08-01T00:00+10:00[Asia/Tokyo]
```

日本標準時のタイムゾーンオフセットは基本的に「+09:00」です。（2回目）
しかし、この結果だと「+10:00」となっています。

### 原因
ケース1と同じなのですが、tz databaseが実際そうなっているからです。
時事ネタですが、少し前に東京オリンピックのためにサマータイムを導入しようと騒がれていたことがありますよね。その時にニュースなどを見て知っている方も多いかもしれませんが、日本でも1949年〜1951年頃、実際にサマータイムが導入されていました。
そのことが忠実にtz databaseに反映されているわけです。

# まとめ
- 日本標準時では、日付が古い場合はズレが発生したり、タイムゾーンオフセットが変わったりする可能性がある
 - 1888年より前の日付ではタイムゾーンオフセットが「+09:18:59」になる
 - 1582年10月15日より前の日付の処理結果がライブラリによって変わる
 - 1949年〜1951年まではサマータイムが導入されていたため、タイムゾーンオフセットが「+10:00」になる
- これらを考慮するのは面倒なので、可能であれば扱わずに済むようにすべき
 - Webシステムなら一定より古い日付は入力できないようにするとか
- どうしても扱う必要がある場合は、日付処理のライブラリの仕様をよく確認する
 - ユリウス暦か、先発グレゴリオ暦か
 - 特にJavaは、旧APIと新APIで異なるので要注意

# 参考リンク
http://nowokay.hatenablog.com/entries/2015/01/09
https://ja.wikipedia.org/wiki/Tz_database
http://www.mwsoft.jp/programming/other/time_mendoi.html
https://qiita.com/sota2502/items/e8df68d9cfebd01af809
Android Stutioがボヤった時の話

#Android Studioが燃え盛った

MacBookの容量がヤバくなってきたのでSDK周りを削除してたら炎上しました。

エラーは2つで、
**(1)ビルドできなくなってRunを押すと以下
・Unknown run configuration type AndroidRunConfigurationType
のメッセージが出現**

**(2)エミュレータが選択できねぇ**


暴力的にプロジェクトが真っ赤になり手を焼いたので、エラーの様子と対応策のメモ（日本語版で）

##エラーの様子と対処
対応策は以下の3つです。

###・消したSDKのプラットホームのインストール
→意味なし

###・Pulguinの有効化(Preference>Pulgin)
（参考URL:https://stackoverflow.com/questions/37908267/plugin-error-required-plugin-android-support-is-disabled#40055520）
→意味あり？

Preference(環境設定)>Pulginでenableなプラグインをとりあえずわぁぁと全部有効化すると上記のエラーメッセージが消滅。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/267121/3d9e7b54-f966-8730-0a55-bcccf167b61a.png)

しかし次はエミュレータが選択できなくなっている状況だったので、

###・ファイル>プロジェクト構造>SDKロケーションで埋め込みJDKを使用にチェック
(参考URL：http://turanukimaru.hatenadiary.com/entry/2017/12/15/200606)
→勝ち、無事RUN実行できました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/267121/615fde9c-cfdd-7a77-36d0-77ad9578b85b.png)


便利な反面ミスるとすぐボヤるので気をつけて取り扱おう
【動物会話】カラスとの遭遇に向けて「カラスにオウム返し」作ってみた♬

###何年か前のイグノーベル賞でこんなのあったよなぁ～

ということで、対面しているカラスにカラス自身を撮影した動画をほんの少し遅れたタイミングで、カラスの音声とともに動画を流す「カラスにオウム返し」を作ってみた。
もちろん、カラスに限定せず、これは「鏡よ鏡よ鏡さんの。。。」あの魔女の愛用のミラーの現代版である。
ここから、検索もできるしショッピングも可能になるという未来型商品への入り口になるものだと考えられる。
。。。Alexaなんかのサービスのカメラや動画提供版はそういうイメージの商品だと考えられる。
。。。今回は、あくまで「動物会話」のワンシーンとして、フィールドに出た時カラスと遭遇、動物と遭遇を想定し、彼らに素直におのれの姿をフィードバックできるアプリを目指している。このアプリは以下の４につながるアプリである。
###とりあえずの目標
１．[犬・猫の音声認識](https://qiita.com/MuAuan/items/5bbe6caba2b3544f9283)
２．動物の音声認識
３．犬の種類・猫の種類の認識
４．犬・猫・カラスの声にそれぞれの声で反応を返す
５．犬・猫・カラスの話を翻訳して、人の声で返すと翻訳して返す
。。。
最終目標；「動物と日常会話ができるようになる」
###やったこと
・動画と音声の同時リアルタイムな動画出力と保存
・コード解説
###コードは以下に置きました
・[hirakegoma/camera_input_movie.py](https://github.com/MuAuan/hirakegoma/blob/master/camera_input_movie.py)
###・動画と音声の同時リアルタイムな動画出力と保存
今回のアプリはほぼ先ほどアップした無音動画にカラスの音声を乗せるアプリの素直な拡張としています。
つまり、動画と音声を同時に収録して一定時間経過後に終了すると音声付き動画として保存する仕組みです。
ここで、本来なら並列化して一定時間ごとに裏側で保存する仕組みとしたいが、将来の課題とします。
###・コード解説
使うものは前回と同じです。

```py
# -*- coding: utf-8 -*-
import cv2
import pyaudio
import sys
import time
import wave
import pydub
from pydub import AudioSegment
import moviepy.editor as mp
```
今回はUSBカメラを利用して動画と音声を収録します。

```py
cap = cv2.VideoCapture(0)
fps = 30
# 録画する動画のフレームサイズ（webカメラと同じにする）
size = (640, 480)
# 出力する動画ファイルの設定
fourcc = cv2.VideoWriter_fourcc(*'XVID')
output_file='output.avi'
video = cv2.VideoWriter(output_file, fourcc, fps, size)
```
今回はハウリングにてこずりました。また音声が綺麗に発生するかということも気を使い、以下のパラメータに落ち着きました。
streamの定義では、output=Trueにより出力をオンにしています。

```py
CHUNK = 1024*5 #1024
FORMAT = pyaudio.paInt16
CHANNELS = 1  #monoral
#サンプリングレート、マイク性能に依存
RATE = 22050  #44100
p = pyaudio.PyAudio()

stream = p.open(format=FORMAT,
            channels=CHANNELS,
            rate=RATE,
            input=True,
            frames_per_buffer=CHUNK,
            output = True)
```
動画はframe、音声はframesに格納します。
また、キー入力待ちを少し長めにしてかつ音が変な音にならない100ms程度としています。
そして、終了後は速やかにvideoの終了処理を実施します。
これをやらないとoutput.aviがクローズせずエラーの原因になります。

```py
frames = []
while (cap.isOpened()):
    ret, frame = cap.read()
    input = stream.read(CHUNK)
    # 書き込み
    video.write(frame)
    # キー入力待機
    if cv2.waitKey(97) & 0xFF == ord('q'):
        break
    # 画面表示
    cv2.imshow('frame', frame)    
    output = stream.write(input)
    frames.append(input)
# 終了処理
cap.release()
video.release()
cv2.destroyAllWindows()
```
以下で音声をout.wavにまとめて保存します。

```py
wf = wave.open('out.wav', 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))  #width=2 ; 16bit
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
```
前回と同様に、以下で無声動画output.aviと音声ファイルout.wavを使って音声付動画output.mp4を作成します。

```py
base_sound = AudioSegment.from_file('out.wav', format="wav")
base_sound.export("out.mp3", format="mp3")  # 保存する
clip_output = mp.VideoFileClip(output_file).subclip()
clip_output.write_videofile(output_file.replace('.avi', '.mp4'), audio='out.mp3')
```
###まとめ
・カラスとの遭遇に備えて「カラスにオウム返し」アプリを作成した

・カラス語識別機能を追加して、返事を行うように機能追加する
・詳細は控えるが、これをベースにいろいろな発展が期待できる
redux-persit を使わずに Redux と localStorage を同期

redux-persist を使うと Redux のstate をlocalStorage に自動的に反映してくれるので便利。
しかし state のネストの深いところの数箇所くらいしか永続化しない場合、 redux-persist では難しい。(できなくはないが書き方がまわりくどくなる印象)
なのでredux-persist を使う代わりに、自前で Middleware を書いて実装してみた。

Middleware で action発火前と発火後のstate を見て、 `auth.user.jwt` state に変化があったら localStorageを操作する。

```typescript
// store.js

// ...

const localStorageMiddleware: Middleware<
  {},
  State
> = store => next => action => {
  const prevJwt = store.getState().auth.user.jwt
  next(action)
  const nextJwt = store.getState().auth.user.jwt
  if (prevJwt === nextJwt) return
  if (nextJwt) {
    localStorage.setItem('jwt', nextJwt)
    return
  }
  localStorage.removeItem('jwt')
}

const store = createStore(
  reducer,
  composeEnhancers(applyMiddleware(thunk, localStorageMiddleware)),
)

// ...
```

該当 state の初期値に localStorage.getItem() の値を入れる。

```typescript
// auth/reducer.js

// ...

const initialState: State = {
  isLogin: false,
  user: {
    jwt: localStorage.getItem('jwt') || '',
  },
  // ...
}

// ...

```

これで指定したstate が localStorage に自動的に反映され、同期するようになる。
ビッグデータ向けプラットフォームに入門する - DWH

こちらのページは[ビッグデータ向けプラットフォームに入門する](https://qiita.com/mito_110/items/0a275ecbddb9fd678ed1)の子記事です。

next: [ビッグデータ向けプラットフォームに入門する - Hadoop](https://qiita.com/mito_110/items/b83a2e38cef505b306d6)

---

DWHはいわゆる「データの倉庫」です。
時系列データを格納することを目的とし、分析・集計(OLAP)用途に特化したRDBです。

オペレーション(OLTP)用途で用いられる一般的なRDBとは大きくことなる点として以下の2つが挙げられます。

- **列指向DBであること**
- **MPPを採用している(ことが多い)こと**

この2つの特徴によりDWHは「分析に特化している」といえます。

### 列指向DB
簡単な例として、ショッピングサイトで扱うデータについて考えましょう。

![データ処理プラットフォーム入門_素材.001.png](https://qiita-image-store.s3.amazonaws.com/0/303946/0048cc07-f30f-1b30-9dba-06f61734bf7c.png)

ある商品についての情報にアクセスする場合、その商品についての行を参照することになります。
また、新たな商品を登録したり、購入処理後に在庫数を変更する場合も行単位のアクセスとなります。
**OLTP用途のRDBではこのように行単位でレコードのR/Wを行うことに特化**し、行指向のDBとなっています。

一方商品数を集計するような場合、列方向にアクセスを行うことになります。
このように**集計・分析を行う場合は列単位でのアクセスを行う**ことになります。
このような列方向でのアクセスに特化しているのが列指向DBです。

列指向DBではカラムごとにデータをまとめて保持しているため、
集計の際に必要なカラムにのみまとめてアクセスでき、高速に集計を行うことができます。
さらに、列指向DBは圧縮効率が高いという長所もあります。
これは列方向には同じ型のデータが並び、かつ似た値が入ることが多いためです。

また図からもわかるように、**OLAP用途のDBでは格納するデータの構造(スキーマ)も異なります。**
RDBでは図のような現在の状態を示すレコードが保持される一方、DWHでは購入履歴のような時系列のデータが格納され、基本的に更新処理が行われることはありません。
またRDBでは正規化が行われた形式でデータを格納しますが、
一般的にDWHでは集計効率を考えて非正規化が行われた冗長な状態でデータが格納されます。

### MPP
近年では多くのDWHがMPP(Massive Parallel Processing)と呼ばれる処理方式を採用しています。
MPPでは1システムが独立した複数のCPU, メモリ, ストレージを持ち(=shared nothing architecture)、
分散してデータの保持及び処理を行います。

**メモリ・ストレージを共有しないため処理中の競合が発生せず、高速に分散処理を行うことができるという特徴があります**。
また、後述するHadoopやNoSQLなどの分散ストレージほど容易ではないものの、スケールさせることが可能です。

MPPについては、DWHの一つであるTeradataのアーキテクチャについての記事がわかりやすいです。

(https://www.teradata-jp.com/single-post/col05b)

### DWHの特徴・プロダクト
DWHは列指向ストレージ、MPPにより、分析・集計を非常に高速に行うことができ、
大容量でスケールが可能なRDBです。一方でOLTP用途で使うことには向いていません。
またRDBであるためACID特性を有し、データの整合性を保証しています。

なおNoSQLの節で触れますが、**データの整合性を担保しつつ、分散処理を行い十分な性能を持たせることは本来困難です**。
前述の特性に加え、データの格納の仕方も工夫することでDWHでは効率的に分散処理を行うことができます。
具体的には非正規形でデータを格納してデータ間の依存を減らし、
なおかつ更新処理は基本的に行わずに追加のみ行うことで、処理を分散しやすいようにしています。
このデータの更新を行わない、というのは現在の状態を保持するのではなく時系列の記録を格納するという目的と合致しています。

**DWHは一般的にソフトウェアとハードウェアが一体となった形で提供されており**、
代表的なプロダクトはhttps://www.trustradius.com/data-warehouse から見ることができます。
Apacheを用いたWebサーバ構築

# サーバとは
サーバとは、サービスを提供するコンピュータのことで、クライアントからの要求に対して情報や処理結果を提供する機能を果たす側のコンピュータやソフトウェアを指す。([Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%B5%E3%83%BC%E3%83%90)より)
このように、サーバはクライアントからの要求に対してレスポンスを返すサービスまたはそのコンピュータのことを指します。

## サーバの種類
サーバにもいろいろな種類があり、専用のソフトウェアをインストールすることによりサーバ機能を提供しています。代表的なサーバの例をあげると、

* Webサーバ
Webサイトの機能を提供します。HTMLファイルや画像ファイルなどをおいておき、動的なサイトの場合は、プログラムもおいておきます。クライアントからのアクセスがあると、それらのファイルを提供します。

* メールサーバ
メールのやり取りをするためのサーバです。メールの送受信を担当するSMTPサーバとクライアントにメールを受信させるPOPサーバやIMAPサーバがあります。一般的にはこれらをまとめてメールサーバと呼ぶことが多いです。

* プリンタサーバ
コンピュータネットワーク上に配置されたプリンタを複数のクライアントコンピュータから使用する際にリクエストを適切に処理し、効率よく印刷を行わせるためのサーバです。

* ファイルサーバ
ファイルを保存して共有するためのサーバです。アクセス権を設定することもでき、一部の人だけが読み書きできるようにすることもできます。

* FTPサーバ
FTPプロトコルを用いて、ファイルの送受信を行うサーバです。Webサーバと同時に設置されることが多く、ファイルなどのアップロードに用いられます。

* DNSサーバ
ホスト名やドメイン名などとIPアドレスを結びつけるサーバです。

* DHCPサーバ
IPアドレスを自動的に割り振るサーバです。

などがあります。
1台のサーバPCに複数のサーバソフトウェアを稼働させ、サービスを提供することも可能となっています。


## サーバOS
サーバOSとは、サーバを稼働させるために必要なソフトウェアをインストールするためのOSです。サーバOSを大まかに分類すると次のようになります。

* Windows系列 (Windows Server)
* Unix系列
    * Linux
        * CentOS、RHEL
        * Debian、Ubuntu
        * SUSE
        * Arch Linuxなど
    * BSD
        * OpenBSD
        * FreeBSD
        * NetBSDなど
    * Solaris

Windows系列はMicrosoft社が提供するサーバOSで、Windowsと同じようにGUI操作で設定を行うことができます。
Unix系列はベル研究所によって開発されたUnixをベースに作られたOSで似たようなコマンドで動作します。
また、Unix系列はCLIで操作することを前提としているため、コンソール画面でコマンド入力することで設定を行います。
CentOSは、Linuxのオープンソース規約に基づき、Red Hat社が販売しているRHEL（Red Hat Enterprise Linux）の有償部分（サポートなど）を取り除いたOSです。そのためCentOSはRHELとほとんど同じで、サーバOSとしてよく用いられます。

# サーバ構築
今回は普段から使用しているArch LinuxをサーバOSとして用いてWebサーバを構築します。

## Apacheのインストール

```
# pacman -S apache
```

## サービスの開始と有効化
```
# systemctl start httpd.service
# systemctl enable httpd.service
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.
```
![test1.png](https://qiita-image-store.s3.amazonaws.com/0/369816/e2b16692-2da2-d49f-fba3-d3a99101a50f.png)

ウェブブラウザで [local host] (http://localhost/) を開いて、この画面が出ればApacheの起動に成功です。
link_toにパラメータを渡す

link_toで検索条件などGETでパラメータを渡す場合です。

html.erb

    <%= link_to "AAA", issues_path(searcher: { product_id: product.id }), class: 'nav-link' %>

    issues_path	GET	/issues(.:format)

htmlでの表示

    <a class="nav-link" href="/issues?searcher%5Bproduct_id%5D=1">AAA</a>

paramsの中身

    {"searcher"=>{"product_id"=>"1"}

controllerでのアクセス

    params[:searcher][:product_id]
Tensorflowのkeras.layers.Layerの変数宣言について

## 注意
以下に書くことはTensorflowの仕様の体系的な理解に基づいているわけではなく、現段階の不完全なメモです。後日気が向いたら加筆修正するかもしれません。

## はじめに
`tf.keras.layers.Layer`を継承することで独自のlayerクラスを定義できます。この時変数を`__init__`内で定義するか、`build`内で定義するかで挙動が変わります。（原則として変数は`build`内で定義することになっている）

一方Tensorflowには`tf.layers.Layer`と言うクラスも存在します。こちらは公式リファレンスに

```
It is considered legacy, and we recommend the use of tf.keras.layers.Layer instead.
```
とあることから、新たな使用は避けた方が良いようです。このクラスも`__init__`、`build`、`call`により設定されるなどインターフェースは似ていますが、その挙動は`keras.layers.Layer`とはやや異なっており互換性はありません。

## メモ

- そもそもLayerクラスとは
    - レイヤーと変数の所有関係を明確にする
    - レイヤーをオブジェクトとして扱う（オブジェクト指向）
    - 変数の再利用が容易（name scopeを記述しなくていい）

- `__init__`、`build`、`call`の役割
    - `__init__`：レイヤーの設定（出力次元数など）の保存
    - `build`：変数の宣言。初めてグラフに組み込まれる際に一度だけ実行される。
    - `call`：グラフの構築。グラフに組み込まれるたびに実行される。

- `tf.keras.layers.Layer`と`tf.layers.Layer`
    - `tf.keras.layers.Layer`
        - `Layer.weights`に変数を格納していく
        - 当該レイヤーを内包する`tf.keras.models.Model`の`Model.weights`にも当該レイヤーの変数が格納される
        - 変数の名前は`layer_name/variable_name`になる（スコープの制御は自動で行われる）
        - 別のレイヤーを内包することはできない
    - `tf.layers.Layer`
        - `layer1/layer2/layer3/layer3_variable0`のような名前付けを自動で（ユーザーが`tf.variable_scope`を意識することなく）行う
        - 別のレイヤーを内包できる
homebrew

# はじめに
はじめてQiitaに投稿します。基本的に備忘録的なメモとなっています。
私と同様にMacで開発されている方に役立てれば、幸いです。

# homebrewとは？

wikipediaによると...
> Homebrew（ホームブルー）は、macOSオペレーティングシステム上でソフトウェアの導入を単純化するパッケージ管理システムのひとつである。
> MacPortsやFinkと同様の目的と機能を備えている。LinuxのDebianのAPTに似た使用感で急速に利用が広がっている。

私の理解では

* アプリケーションやソフトウェアを一元管理できる(パッケージごとの依存性を解決し、依存しているパッケージも合わせてダウンロード・インストールしてくれる)
* 本来欲しいアプリケーションやソフトウェアをインストーラを使用せず、インストールでき、アンインストールも容易にできる
* それらをコマンドひとつで実現できる

という感じです。

# インストール

## Command Line Tools

まず、**Command Line Tools**を導入します。
そもそもCommand Line Toolsって何？

>コマンドを入力して操作するアプリケーション・CUIのこと

これを導入しないと始まりません。
通常、Command Line Toolsは*XCode*をインストールしないと使えないのですが
*XCode*自体、サイズが大きく、普段macAppやiOSAppを開発しない人にとっては、不要です。

Command Line Toolsはターミナル上でもインストールできるので、*XCode*を利用しない人は、ターミナルからインストールしましょう。
ターミナルを起動し以下のコマンドを入力・実行。

```bash:terminal
$ xcode-select --install
```

インストールができたか、以下のコマンドで確認。
確認できれば、インストール完了。

```bash:terminal
$ xcode-select -version
xcode-select version 2354.
```

## homebrew

さて、Command Line Toolsのインストールが終わったら、**homebrew**をインストールしましょう。
[homebrewの公式サイト](https://brew.sh/index_ja)にもコマンドが書いてありますが

```bash:terminal
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

を実行し、インストール。
インストールができたか以下のコマンドで確認。
確認できれば、インストール完了。

```bash:terminal
$ brew -v
Homebrew 2.0.3
```

## homebrew-cask

homebrewはCGIで扱うようなツールのインストールですが、**homebrew-cask**をインストールすると
GUIのアプリケーションも管理・インストールすることができます。

あまりゴミを出したくない性分としては、ありがたい限りです。

homebrewをインストール後、以下のコマンドでインストール。

```bash:terminal
$ brew tap caskroom/cask
```

インストールができたか以下のコマンドで確認。

```bash:terminal
$ brew -v
Homebrew 2.0.3
Homebrew/homebrew-core (git revision ec529; last commit 2019-03-09)
Homebrew/homebrew-cask (git revision 6dba1; last commit 2019-03-09)
```

**Homebrew/homebrew-cask (git ...)**が確認できれば、インストール完了。

## homebrew-caskでChromeのインストール

homebrew-caskで[**Google Chrome**](https://www.google.com/intl/ja_ALL/chrome/)をインストール。

```bash:terminal
$ brew cask install google-chrome
```

## homebrew-caskでSlackをインストール

homebrew-caskで[**Slack**](https://slack.com/intl/ja-jp/)をインストール。

```bash:terminal
$ brew cask install slack
```

## homebrew-caskでSublime Textをインストール

homebrew-caskで[**Sublime Text**](https://www.sublimetext.com/)をインストール。

```bash:terminal
$ brew cask install sublime-text
```

## homebrew-caskでiTerm2をインストール

homebrew-caskで[**iTerm2**](https://www.iterm2.com/)をインストール。

```bash:terminal
$ brew cask install iterm2
```

# 終わりに

homebrewと書きつつ、homebrew-caskの内容になってしまった…
内容は少しずつ、充実していきます。
Get-ChildItemの出力形式はパラメータによって変わるという話

趣味でPowershellを触っているのですが、もっともよく使うコマンドレットのひとつであろう`Get-ChildItem`で最近得た知見がありました。<b>`-Name` パラメータを使うと出力オブジェクトが変わる</b>というものです。

オンラインヘルプには以下とあります。

[Get-ChildItem](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-5.1)
> Outputs
> System.Object
> The type of object that Get-ChildItem returns is determined by the objects in the provider drive path.
> 
> System.String
> <b>If you use the Name parameter, Get-ChildItem returns the object names as strings.</b>

確かに「`-Name`を付けるとSystem.Stringで出力するよ」と書いてあります。これはつまり`GetChildItem`の情報を名前でフィルタして出力したい場合に
`Get-ChildItem -Name "*hoge*"`
と
`Get-ChildItem | Where-Object {$_.Name -match "hoge"}`
で結果が異なるということです。知らないと嵌りそう…。

# 確認する

## `-Name`無し = DirectoryInfo
```Powershell
PS C:\Users\Public> Get-ChildItem


    ディレクトリ: C:\Users\Public


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-r---       2019/03/12      8:19                Documents
d-r---       2019/01/26     10:22                Downloads
d-r---       2019/01/26     10:22                Music
d-r---       2019/01/26     10:22                Pictures
d-r---       2019/01/26     10:22                Videos


PS C:\Users\Public>
PS C:\Users\Public> (Get-ChildItem)[0].GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     DirectoryInfo                            System.IO.FileSystemInfo


PS C:\Users\Public>
```

## `-Name`有り = String
```Powershell
PS C:\Users\Public> Get-ChildItem -Name "Do*"
Documents
Downloads
PS C:\Users\Public>
PS C:\Users\Public> (Get-ChildItem -Name "Do*")[0].GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object


PS C:\Users\Public>
```

実際に確認することができました。

出力内容がパラメータによって変わるということは
- `Get-Help Get-ChildItem -Full` のように`-Full`パラメータ付きで`Get-Help`する
- [オンラインヘルプ](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-5.1) 見る
- 自力で気付く
しかない気がしています。~~なんでこんな仕様になってるんや…~~
オンラインヘルプを読むことの重要性を感じた一件でした。

---

なお上記の検証は以下の条件で行いました

```Powershell
PS C:\Users\Public> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.17763.316
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.17763.316
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1


PS C:\Users\Public>
```