OmniAICreator/Qiita-1.07M huggingface dataset:
菱形星タワーを印字 Print Stars Tower In Rhombus

# Question
- 下記の菱形★タワーを印字する(△はスペース)
- Conditions:  奇数の整数を輸入
- Example:

```text:input_5        
        △△★△△
        △★★★△
        ★★★★★
        △★★★△
        △△★△△
```
 
```text:input_3      
        △★△
        ★★★
        △★△
```

```text:input_9        
        △△△△★△△△△
        △△△★★★△△△
        △△★★★★★△△
        △★★★★★★★△
        ★★★★★★★★★
        △★★★★★★★△
        △△★★★★★△△
        △△△★★★△△△
        △△△△★△△△△
```

# Solution

```cpp:solution.cpp
#include <iostream>
#define SKIP 2
using namespace std;

void printStar( int stars ){
    
    for( int i = 0; i < stars; i++ )
        cout << "*";
}

void printSpace( int spaces ){
    
    for( int i = 0; i < spaces; i++ )
        cout << " ";
}

int main(void){

    int times;
    cout << "Input an ODD number to print star tower:\n";
    cin >> times;

    if( 0 == times % 2 ){
        cout << "Please input an ODD number!" << endl;
        return 0;
    }

    int stars, spaces, revPos;
    
    // reverse point is the most stars of lines
    revPos = times / 2;
    
    for( int i = 0; i < times; i++ ){

        // count stars and spaces in this line
        if( i < revPos ){
            stars = 1 + i * SKIP;
            spaces = times - stars;
        }else{
            stars = times - ( i - revPos ) * SKIP;
            spaces = times - stars;
        }
        
        // stars always start from the center, insert spaces in the front and tail of stars
        printSpace(spaces/2);
        printStar(stars);
        printSpace(spaces/2); // this line can be commented out
        
        // change line
        cout << endl;
    }
}


```
Junitの導入方法

忙しくてすっかりここの存在を忘れてましたすみません。
とは言え、いま携わっている業務の作業内容的に特にこれといったネタもないので、自分用メモがてらJunitの導入方法でも書いていくことにします。
わたしはいつもeclipseでJunitを使っているので、その方法で。

1.まずはeclipseでプロジェクトを作成します。
「ファイル」→「新規」→「Javaプロジェクト」を選択してください。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/72ff36ca-23c5-eafa-b7e3-519a6a707f25.png)

2.プロジェクト名を入力して「完了」ボタンを押下します。
これで「パッケージ・エクスプローラー」にプロジェクトが作成されます。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/7c88142b-3f0a-f068-4935-e17c27026381.png)

3.クラスを作成します。
「パッケージ・エクスプローラー」に表示されているプロジェクトを右クリックし、「新規」→「クラス」を選択してください。
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/7dc5e685-5d68-95a3-1a43-6aaa724256db.png)

4.名前を入力して「完了」ボタンを押下します。
先ほどと同様に、「パッケージ・エクスプローラー」の中にあるプロジェクト内にクラスが作成されます。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/d5be24a4-a200-1aec-6819-278309dbc0d3.png)

5.テストクラス用のフォルダを作成します。
プロジェクトを右クリックし、「新規」→「ソース・フォルダー」を選択します。
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/96c8766b-99c3-fbc9-a5d0-502e1667871a.png)

6.フォルダ名を入力して「完了」ボタンを押下します。以下略。
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/7b414289-7be1-d9ca-e624-7a0465d686b5.png)

7.いよいよJunitを追加します。
プロジェクトを右クリックし、「ビルド・パス」→「ビルド・パスの構成」を選択します。
![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/e67d6bc5-6133-1046-e87a-8f32a08cd169.png)

8.「ライブラリ」タブに移動し、「ライブラリの追加」ボタンを押下します。
![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/8486aba9-1f28-6fc0-a0d8-3b6a53c48083.png)

9.「Junit」を選択し、「次へ」ボタンを押下します。
![09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/19b0d74c-f119-0490-d1fe-19b0d8427e2a.png)

10.そのまま「完了」ボタンを押下します。
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/43965c49-9e43-02e2-41f9-8af5e53cc4a2.png)

11.ライブラリにJunitが追加されます。
「OK」を押下してウィンドウを閉じてください。
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/304ed533-548e-2ea5-8401-a1ea35957090.png)

12.テストクラスを作成します。
プロジェクトを右クリックし、「新規」→「その他」を選択してください。
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/b8d2768c-6246-190b-e49b-bb15dbfe1848.png)

13.「Java」を展開します。
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/5ab69a82-8630-e5ba-45d7-5236bac3a616.png)

14.さらに「Junit」を展開し、「Junitテスト・ケース」を選択して「次へ」ボタンを押下します。
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/85be7936-be31-9e06-64a0-d73c4dac5dd4.png)

15.名前を入力して「完了」ボタンを押下します。
![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/29435d32-6e04-cd72-b8b9-5cf396791557.png)

16.テストクラスが作成されます。
ここまででひとまず必要なものは出揃ったので、Junitの導入は完了です。
![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/b04d2a88-26cc-6b11-9114-6b1d20147349.png)
eclipseで作成したGradleプロジェクトのgradlewのバージョンアップ

gradle本体をインストール、chocolatelyならコマンドプロンプトでcinst -y gradle、結果として例えば5.4.1とかになる
eclipseプロジェクトのホームディレクトリでコマンドプロンプトで例えばgradle wrapper --gradle-version 4.10.3
webの設計使用 RESTを理解する

## RESTの原則
RESTはネットワークシステムにおける設計の方法のこと。

### 統一インターフェイス
あらかじめ定義、共有された方法で情報がやりとりされる(webだとHTTP)。みんなで決められた同じものをつかおうってこと。
HTTPにはメソッドが八つと限定していますが、HTTPの拡張性に対して制限が加わった結果HTTPがシンプルなものとなりました。
統一インターフェイスの利点として、システム全体が階層化しやすいことがあります。例えばサーバーとクライアントの間にリクエストをどのサーバーに処理してもらうかを誘導してくれるロードバランサーを設置することで負荷分散をしたり、プロキシ(検問所)を設置して特定のリクエストのみアクセスを許可したりします。これらは同じインターフェースを使っているため可能なことです。


### アドレスの可能性
すべての情報が一意なURLの構文で示される。

### 接続性
やりとりされる情報にはリンクを含むことができる。
情報の中にいくつも別のURLを付けることができるためクライアントがアクセスしやすくなる。

### ステートレス性
やりとりは一度で完結し、前のやり取りの結果に影響を受けない。
サーバーがアプリケーション状態を持たない(リクエスト先が同じでも前回の通信内容を覚えてないこと)ステートレス性によってサーバー側の実装を簡略化することができるようになりました。結果クライアントからのリクエストに対してすぐにサーバーの計算機リソースを解放できるようになりました。

上記の四つの原則に従い設計されたシステムをRESTfullなシステムという。
Rails6 のちょい足しな新機能を試す29（ActiveRecord::Result.to_a編）

# はじめに

Rails 6 に追加されそうな新機能を試す第29段。 今回は、 `ActiveRecord::Result.to_a` 編です。
Rails 6 では、 `ActiveRecord::Result.to_hash` は `DEPRECATION WARNING` が出るようになります。
代わりに、 `ActiveRecord::Result.to_a` が用意されました。
`ActiveRecord::Result.to_hash` が `Array` オブジェクトを返していたため、それに合わせてメソッド名を変更するということみたいです。

Ruby 2.6.3, Rails 6.0.0.rc1 で確認しました。Rails 6.0.0.rc1 は `gem install rails --prerelease` でインストールできます。

```shell
$  rails --version
Rails 6.0.0.rc1
```

# Rails プロジェクトを作る

```shell
$ rails new rails6_0_0rc1
$ cd rails6_0_0rc1
```

# User モデルを作る

```shell
$ bin/rails g model User name
```

# migration の実行

```shell
$ bin/rails db:create db:migrate
```

# データを作る

ちょっと試すために、データを2件登録します。件数に深い意味はありません。

```irb
bash-4.4# bin/rails c
Running via Spring preloader in process 109
Loading development environment (Rails 6.0.0.rc1)
irb(main):001:0> User.create(name: 'Taro')
 ...(略)
irb(main):002:0> User.create(name: 'Hanako')
 ...(略)
```

# select_all を使って ActiveRecord::Result オブジェクトを取得する

selec_all を使って、データを検索し、ActiveRecord::Result オブジェクトを取得します。

```irb
irb(main):003:0> conn = ActiveRecord::Base.connection
   ... (長いので略)
irb(main):004:0> users = conn.select_all("SELECT * FROM users")
   (0.5ms)  SELECT * FROM users
   ... (長いので略)
```

取得した `users` は ActiveRecord::Result オブジェクトです。

```irb
irb(main):005:0> users.class
=> ActiveRecord::Result
```

# to_hash と to_a

`to_hash` と `to_a` メソッドを実行してみます。
`to_hash` を実行すると DEPRECATION WARNING が表示されます。

```irb
irb(main):006:0> users.to_hash
DEPRECATION WARNING: `ActiveRecord::Result#to_hash` has been renamed to `to_a`. `to_hash` is deprecated and will be removed in Rails 6.1. (called from irb_binding at (irb):5)
=> [{"id"=>1, "name"=>"Taro", "created_at"=>2019-06-01 07:17:28 UTC, "updated_at"=>2019-06-01 07:17:28 UTC}, {"id"=>2, "name"=>"Hanako", "created_at"=>2019-06-01 07:17:37 UTC, "updated_at"=>2019-06-01 07:17:37 UTC}]
```
`to_a` を実行すると `DEPRECATION WARNING` は表示されません。

```irb
irb(main):006:0> users.to_a
=> [{"id"=>1, "name"=>"Taro", "created_at"=>2019-06-01 07:17:28 UTC, "updated_at"=>2019-06-01 07:17:28 UTC}, {"id"=>2, "name"=>"Hanako", "created_at"=>2019-06-01 07:17:37 UTC, "updated_at"=>2019-06-01 07:17:37 UTC}]
```

# 試したソース

試したソースは以下にあります。
https://github.com/suketa/rails6_0_0rc1/tree/try029_activerecord_result_to_a

# 参考情報

* [What is new in Rails 6.0](https://bogdanvlviv.com/posts/ruby/rails/what-is-new-in-rails-6_0.html)
* [Deprecate ActiveRecord::Result#to_hash in favor of #to_a](https://github.com/rails/rails/pull/33912)
海外イベントで初登壇する際に取ったアプローチ

# はじめに
このqiita記事に期待する効果としては
特に優秀でもないエンジニアが、海外のエンジニアイベントに登壇のチャンスが来た場合に
うまく自信を持って承諾する人が増えるようになることを狙っています。
「英語が多少苦手」、「人前で英語を使って喋ったことなどない」と物怖じし断ってしまう方の背中をそっと押せるような記事を目指します。

# どういう状態で受けたのか
学生時代から特に英語に得意意識があった訳ではないですが、苦手意識もありませんでした。
大学院在籍時のTOEICは550、新卒入社からTOEICを定期的に受けており現在835点です。
しかし、これは試験勉強の賜物と言いますか、リアルタイムでのコミュニケーションに使えるものではありません。
日本人の典型的な、読むのはそこそこできるけど、書く・話す・聞くはちょっと・・・というタイプです。


# どういうイベントに参加したのか
2019年5月7日〜9日にBostonで開催された、Red Hat Summit 2019というイベントです。
イベントレポートは、別qiita記事を投稿しましたのでそちらをご参照ください。

[RedHatSummit2019で学んだたった一つの大切なこと](https://qiita.com/hikkie/items/8733b43638881f7ed934)


登壇したのは以下2セッションです。
・APAC Media Round Table
・Breakout Session 「Automated workload migrations to Red Hat infrastructure」


# なぜ登壇依頼を受けたのか。
社会人、、ましてや意思決定をする立場になると、メリットデメリット、リスクの有無の整理は欠かせません。

そこで整理したメリットデメリットは下記の通りでした。
**[メリット]**
・この経験は自分の財産になる。
・自分の市場価値向上に繋がる。
・所属する会社のブランディングに貢献できる。
・うまく行けば、社内にも取り組んだ事自体の評価が高くなる。

**[デメリット]**
・失敗した場合、自分が惨めな思いをする。
・あまりにもやらかすと、所属会社のブランディングを低下させる。


・・・そんなにデメリットありませんね。。
自分が惨めな思いをするなんて、道端の小石のようなものですし
所属会社のブランディングを低下させる程のやらかしを海外でするのは逆に難しいでしょう。

つまり、デメリットは0に近く、メリットしかない。

これは承諾するしかなかったです。

# 登壇当日までに行った準備

とはいえ、やるからには良いOUTPUTを出せなばなりません。
事前準備として取り組んだ事を共有します。

ポイントは以下の4点です。
1. 英語スクリプト準備
2. プレゼン練習
3. coolな質問の返しができるようボキャブラリー強化
4. あとはひたすら練習


## (1) 英語のトークスクリプト準備
　前述の通り、人前で英語で話した経験などありません。
　流石に台本がないと厳しいだろうと考え、プレゼンテーションスライド作りと並行して英　語のトークスクリプト作成を行いました。

　実際に本番で、どこまでトークスクリプト通りに話すかは個人の裁量ですが
　私は、ある程度流れだけ覚えて多少アドリブや時間の調整がきくようにしました。

　あまりに丸暗記しすぎると、忘れた場合に頭が真っ白になるパターンになり得るからです。（ここは個人の特性にもよります）

## (2) プレゼン練習/スライドおよびトークスクリプトの改善活動
　(1)で準備した資料を元に、プレゼンテーションの練習を、社内で実施しました。
　幸運な事に社内には海外勤務経験者、海外の学会に頻繁に参加するメンバ、native speakerが所属しており、彼らの前で練習し、表現の見直しやプレゼンの極意についてフィードバックを受けました。

この時に「発音に問題はない」と言ってもらえたのでちょっと自信がつきました。

フィードバックの例は以下です。

- え〜、あ〜　は不要。むしろ無言になる時間を作る
- 強調する時は、日本語以上に大きくゆっくり話す。
- プレゼンで過去形とか現在形に悩む必要はない。
- とにかく自信があるように見せて話す事が大事。

特に最後の
**とにかく自信があるように見せて話す事が大事。**
は本当に大事です。

## (3) coolな質問の返しができるようボキャブラリー強化
ここは余談ですが、質問時に返す表現やアイスブレイクにうまく使えるボキャブラリー強化を狙ってAtsuEigoさんのDistinctionを購入し勉強しました！
1ヶ月前に購入だったため、本番までに全てやりきれなかったのですが、こう言うスパイスも自信につながったと思います。


![IMG_3723 2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157354/402751e6-2cb5-8632-44b0-67e7caeb1b72.jpeg)


[Astueigo](http://distinction1.atsueigo.com/)

## (4) あとはひたすら練習
ここまで終わったらあとはひたすらプレゼン想定の時間で話す練習をするのみです。
聴衆のリアクションを想像しながら、何回も何回も練習しました。直前のGW10連休中は練習しなかった日はないです。
行きで向かう飛行機でも2時間に1回はエア練習しました。
現地到着後ホテルでも就寝前、起床後に練習。。。と
後悔しないように練習を繰り返すのみです。


# やった感じどうだったのか。
準備が功を奏したのか、大きなトラブルなく2つのセッションを無事終える事ができました。
笑いを誘ったアイスブレイクもあれば、大滑りしたジョークもありましたが、
全体を通しては当時の自分の力を想定通りに出す事ができたと思います。
特に自信を持っているように話すところ（笑）

[参照　※twitter](https://twitter.com/RedHatJapan/status/1125860484845113345)


# 結論
あとでRed Hatの社員の方に伺いましたが、こう言う登壇の依頼は断られるケースも少ないないそうです。
しかし、自分は「やった方がいい。」と断言します。

理由は先述のメリットデメリットの通りです。

正直やる前は、「受けなきゃよかった」と何度思ったか分かりませんが
やった後では、「もう一度やりたいな」と思ってしまいます。

とはいえ、自分も本当に特別に優秀な人間でもないので
上記プラクティスが少しでも貢献して
日本から海外での登壇者がもっともっと増える事を望みます。





# 今後の野望


何ともミーハーと言うが熱しやすいと言うか
今回の登壇を通して

- 英語の仕事
- 海外の人と働きたい

と言う欲は少し出てきました。

と言うのも、自分は言葉足らずなところがあるので日本語だと省いてしまうことも
英語だとちゃんと言語化しようと自然になるなと感じました。
自分が弱い言語だからこそ、慎重に使おうとする表れでしょうか。。

もちろん、これらは働き方の一つの手段でしかないので興味と言う段階です。
今後も自身・チームの研鑽と良いサービス作りに貢献できるように頑張ります。
GitBucket の データベースを H2DB から PostgreSQL に移行

# 0. 基本的には竹添さんのブログを参照してください。

[GitBucketをPostgreSQLやMySQLで動かす](https://takezoe.hatenablog.com/entry/2016/07/16/025154)

※プラグインを入れている場合やデータ量が多い場合は、こちらも参照すると参考になるかもしれません。

# 1. PostgresSQL に GitBucket 用 User と DB を 用意してください。

[Postgres SQL で ユーザとデータベースを作成し、ユーザにデータベースを割り当てる方法](https://qiita.com/kouji-kojima/items/fe6ac5dc233586d15f6d) を 参照。

# 2. GitBucket 用 のテーブル・その他を用意する。

2-1. [gitbucket.warをダウンロード](https://github.com/gitbucket/gitbucket/releases) します。
2-2. ローカルPCから、一度「java -jar gitbucket.war」なりで、GitBucketを立ち上げて、GitBucket ホームを作成します。
2-3. GitBucket ホームにできた「database.conf」に 先ほど作成した、PostgreSQL の gitbucket 用の接続先を指定してください。

```:database.conf
db {
  url = "jdbc:postgresql://[PostgreSQL URL]:5432/gitbucket_db"
  user = "gitbucket"
  password = "xxxxxxxx"
}
```

##### 2-4. もう一度「java -jar gitbucket.war」を実行することで、自動でテーブル・その他が作成されます。


# 3. GitBucket から データをエクスポートします。

GitBucket の 管理者機能である **Data Export/Import** 機能を使ってSQLを取得してください。

![DataExport.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45117/74b1fc92-a1a4-9ef6-313b-e886746e8103.png)

# 4. 既存のGitBucketを止めてください。

# 5. GitBucket の データをインポートします。

5-1. 既に root というユーザは作成されているので、Export した SQL から削除してください。
5-2. 初回インポートの場合が多いはずなので、DELETE FROM の部分も必要ないので削除してください。
5-3. データ量が多いと Data Export/Import 機能からインポートできないので、
[pgAdmin](https://www.pgadmin.org/) なりを 利用して Export した SQL を実行してください。

# 6. シーケンスの更新をしてください。

竹添さんのブログに書かれてあるシーケンスの更新以外に更新する必要があるものがあります。プラグインを利用していないとしても **priority_priority_id_seq** は新規リポジトリを作成する際に必要になるのでご注意ください。

```:pgAdmin(QueryTool)
SELECT setval('access_token_access_token_id_seq', (select max(access_token_id) + 1 from access_token));
SELECT setval('activity_activity_id_seq', (select max(activity_id) + 1 from activity));
SELECT setval('commit_comment_comment_id_seq', (select max(comment_id) + 1 from commit_comment));
SELECT setval('commit_status_commit_status_id_seq', (select max(commit_status_id) + 1 from commit_status));

SELECT setval('deploy_key_deploy_key_id_seq', (select max(deploy_key_id) + 1 from deploy_key));
SELECT setval('gist_comment_comment_id_seq', (select max(comment_id) + 1 from gist_comment));
SELECT setval('gpg_key_key_id_seq', (select max(key_id) + 1 from gpg_key));

SELECT setval('issue_comment_comment_id_seq', (select max(comment_id) + 1 from issue_comment));
SELECT setval('label_label_id_seq', (select max(label_id) + 1 from label));
SELECT setval('milestone_milestone_id_seq', (select max(milestone_id) + 1 from milestone));

SELECT setval('priority_priority_id_seq', (select max(priority_id) + 1 from priority));
SELECT setval('release_asset_release_asset_id_seq', (select max(release_asset_id) + 1 from release_asset));

SELECT setval('ssh_key_ssh_key_id_seq', (select max(ssh_key_id) + 1 from ssh_key));
```

# 7. database.conf を 書き直して GitBucket を起動してください。

```
db {
  url = "jdbc:postgresql://localhost/gitbucket_db"
  user = "gitbucket"
  password = "xxxxxxxx"
}
# PostgresSQL が localhost の 場合はポート5432は不要です（ポートを変えていたら必要になります）
```
sbtでGitリポジトリ上のライブラリを使う

Gitリポジトリで公開されているが、JARが提供されてないライブラリを使いたい。

- [Github 上のライブラリや sbt plugin を使う (sbt 0.13 以降用)](https://qiita.com/kawachi/items/71af20a102ecca41561d)

という記事があるが、最近のsbtではビルドできなかった。
元の例を使うと、以下で動いた。

```scala
lazy val root = project.in(file(".")).dependsOn(githubRepo)

lazy val githubRepo = RootProject(uri("git://github.com/user/repo-name.git#commit"))
```

# 別解 GitHubのリポジトリに限ればJitPack

JARで欲しい場合など[JitPack](https://jitpack.io/)を使う手もある。

# 参考文献

- [Scala Cookbook by Alvin Alexander - 18.10. Using GitHub Projects as Project Dependencies](https://www.oreilly.com/library/view/scala-cookbook/9781449340292/ch18s11.html)
- [sbt API(1.0) RootProject](https://www.scala-sbt.org/1.2.8/api/sbt/RootProject.html)
- [ローカルのsbtプロジェクトをインポートする方法](https://qiita.com/lamrongol/items/8c9dfb877ab60be5794f)
- [Github 上のライブラリや sbt plugin を使う (sbt 0.13 以降用)](https://qiita.com/kawachi/items/71af20a102ecca41561d)
Cloud Functions + TypeScriptでHot Reloadを行うためのちょっとしたTips

Gakuです。
firebaseのCloud FunctionsをTypeScriptで記述すると、HotReloadがかからない現象に陥ったので、無理くりHotReloadを行う方法を記載したいと思います。

# なんでCloud FunctionsをTypeScriptで記述するとHotReloadできないの？
JavaScriptでfunctionsを記述すれば何も設定せずとも、HotReloadが可能です。
ですが、TypeScriptだとJavaScriptへのトランスパイルを行う必要があり、デフォルトの設定ではshellコマンドの起動時の一度だけbuildをする設定になっているのでHotReloadがかからないというのが原因になります。

# 解決方法
package.jsonにwatchコマンドを追加します。

```json:package.json
"scripts": {
    "lint": "tslint --project tsconfig.json",
    "build": "tsc",
    "watch": "yarn build --watch", // これを追記
    "serve": "npm run build && firebase serve --only functions",
    "shell": "npm run build && firebase functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log"
},
```

あとは、terminalを2つ立ち上げて、一つを「yarn watch」で自動ビルドを行うようにします。
もう一方のterminalで「yarn shell」を立ち上げれば、HotReloadの感覚でデバックをすることが可能です。

# おわりに
ちょっとしたTipsですが、開発が結構快適になるのでお試しあれ。
あと、terminalを複数立ち上げるのが面倒なので、「yarn shell」単体でHotReloadとかできる方法とかあればな～。
知っている方いましたら、コメントいただけると嬉しいです！

それでは　(/・ω・)/
AWS Lambdaの関数から別のLambda関数を呼び出すときのNode.js実装とServerless設定

毎回調べてる気がするのでメモ。


## 前提

AWSアカウントがあって`aws configure` でアカウントキーの設定済み。

```console
> node -v
v10.11.0

> npm -v
6.9.0

> aws --version
aws-cli/1.16.153 Python/3.6.6 Darwin/18.6.0 botocore/1.12.143

> sls -v
1.43.0
```

## 環境構築

serverlessで環境を作成します。

```console
> sls create -t aws-nodejs \
  -p invoke-lambda-fcn-on-lambda

> cd invoke-lambda-fcn-on-lambda

> npm init

# ローカルでテストするならインストールする
> npm i -d --save-dev aws-sdk
```


## 実装と設定

```js:handler.js
'use strict';

module.exports.hello = async (event) => {

  let AWS = require('aws-sdk');
  let lambda = new AWS.Lambda();

  let result = await lambda.invoke({
    FunctionName: 'invoke-lambda-fcn-on-lambda-dev-hoge',
    InvocationType: 'RequestResponse',
    Payload: JSON.stringify({"hoge": "hoge"})
  }).promise();
  console.log('invoke function', result);

  return {
    statusCode: 200,
    body: JSON.stringify({
      message: result,
      input: event,
    }, null, 2),
  };
};


module.exports.hoge = async (event) => {
  return {
    statusCode: 200,
    body: JSON.stringify({
      message: event.Body,
      input: event,
    }, null, 2),
  };
};
```

`iamRoleStatements` になに設定するんだっけなーって毎回悩みます。

```yaml:serverless.yml
service: invoke-lambda-fcn-on-lambda

provider:
  name: aws
  runtime: nodejs10.x
  stage: dev
  region: us-east-1

  iamRoleStatements:
    - Effect: 'Allow'
      Action:
        - 'lambda:InvokeFunction'
      Resource:
        - '*'

functions:
  hello:
    handler: handler.hello

  hoge:
    handler: handler.hoge
```


## デプロイと動作確認

`sls invoke local` でローカル実行させたいのですが、`lambda.invoke` メソッドで実行できるのはデプロイ済みの関数だけっぽいです。(未調査)

```console
> sls deploy

(略)
Serverless: Stack update finished...
Service Information
service: invoke-lambda-fcn-on-lambda
stage: dev
region: us-east-1
stack: invoke-lambda-fcn-on-lambda-dev
resources: 8
api keys:
  None
endpoints:
  None
functions:
  hello: invoke-lambda-fcn-on-lambda-dev-hello
  hoge: invoke-lambda-fcn-on-lambda-dev-hoge
layers:
  None

> sls invoke -f hello -log

{
    "statusCode": 200,
    "body": "{\n  \"message\": {\n    \"StatusCode\": 200,\n    \"ExecutedVersion\": \"$LATEST\",\n    \"Payload\": \"{\\\"statusCode\\\":200,\\\"body\\\":\\\"{\\\\n  \\\\\\\"input\\\\\\\": {\\\\n    \\\\\\\"hoge\\\\\\\": \\\\\\\"hoge\\\\\\\"\\\\n  }\\\\n}\\\"}\"\n  },\n  \"input\": {}\n}"
}
--------------------------------------------------------------------
START RequestId: f83cec93-032a-4159-90a5-a4345fa68672 Version: $LATEST
   '{"statusCode":200,"body":"{\\n  \\"input\\": {\\n    \\"hoge\\": \\"hoge\\"\\n  }\\n}"}' } function { StatusCode: 200,
END RequestId: f83cec93-032a-4159-90a5-a4345fa68672
REPORT RequestId: f83cec93-032a-4159-90a5-a4345fa68672  Duration: 34.77 ms      Billed Duration: 100 ms         Memory Size: 1024 MB    Max Memory Used: 93 MB
```

はい。
環境のお片付けもお忘れなく。

```console
> sls remove
```


## 参考

amazon web services - AccessDeniedException: User is not authorized to perform: lambda:InvokeFunction - Stack Overflow
https://stackoverflow.com/questions/37498124/accessdeniedexception-user-is-not-authorized-to-perform-lambdainvokefunction
【メモ】JavaScriptで変数のスワップをする

一時変数を使わないどころかワンライナーでいける。

右辺が左から評価されて、まず`200 + (b = a, 0)`になり、そのあと右側が評価される。カッコの中ではまず`b = a`が評価され、変数bにaの値である100が入る。そして、`(b = a, 0)`全体の評価結果は0なので、`a = 200 + 0`になる。

```js

let a = 100;
let b = 200;

a = b + (b = a, 0);

console.log({ a, b });
/*
{ a: 200, b: 100 }
*/
```

### 追記

コメントでもう一つワンライナースワップを教えていただいたので追記。

```js

[a, b] = [b, a];
```
FBXファイル内のアニメーションをUnityで適応する際に注意する点１つ

最近、RADiCALという「スマホだけでモーションキャプチャーするアプリ」(当方はiPadでやっております)を使ってみようと思い、とりあえずFBXファイルまで生成したのですが…

Unity(2019.1.4f1)立ち上げてユニティちゃんにアニメーションさせようとしても

**なぜかずっとTポーズのまま立ち位置だけが変わってる…**

[Tポーズのままの動画を埋め込んだツイート](https://twitter.com/cyross4vocaloid/status/1135107184067457025)

ちゃんと取り込めていないのかと、設定を確認しましたが、基本「RigをHumanoiodにする」だけで、実際、それだけで動作するらしいのですが…

一晩悩んでようやく解決いたしました。

単純に「**Avaterにユニティちゃん標準のAvater(UnityChanAvater)を適応**」するだけの話でした。

FBXファイルをインポートすると、一緒にAvaterも生成されるので、これを使う必要があるという罠にハマってしまいました。
(そりゃそうだなぁ、そのAvaterはFBXファイルを作った元のモデルに適応すべきものなのに…)

(検証のためにAssetStoreでフリーのアニメーションを適応してもちゃんと動いていたので、Avaterは配布されていないのに気づいてようやく原因が判明しました…)

というわけで、無事にユニティちゃんが思い通りに動いてくれました。

[思い通りに動いた動画を埋め込んだツイート](https://twitter.com/cyross4vocaloid/status/1135329661242621953)

Avaterの適応は適切に…
Docker+MySQLで起きたバグ対処法忘備録

DockerでPHPとかMySQLとかいろいろ動かしてる状態で出会った不具合です。
検索しようにもどう調べたらいいのか、原因の切り分けをしようにもいまいちわからなかったので、忘備録的に載せます。

##不具合
####1.データが勝手に一律更新される
ストアドプロシージャ実行時に、Whereでidを指定しているにも関わらず、指定したテーブルのデータが全て変更されます。
→PHPからPDOでストアドプロシージャを呼び出し普通に実行します。するとデータが全て消えたり、全て書き変わったりします。MySQLで実行すると問題なく通ってしまうので、SQL文には問題はなさそうです。値をセットする箇所で問題が起きてるようでした。
また、phpMyadmin使用時限定で、MySQLコンテナに入って同じSQL文を実行しても正常に動作します。

####2.謎のシンタックスエラー
→クエリ文を見直しても渡すパラメーターを見直してもシンタックスエラーが消えません。しかもコーテーションをシングルからダブルに直すと通るようになりますが、今度はデータが取得できません。

##解決策

####1.データが勝手に一律更新される
実行時にデータが消えるのは、SQL文で使用する変数名は項目名と違う名前を使わなければならないのを守っていなかったからでした。
https://www.bnote.net/mysql/appendix/select_into.shtml

Where id=id　を、 Where id=update_idに直すと正しく実行されるようになりました。

####2.謎のシンタックスエラー
デバッグログを仕込んでない箇所で落ちていたため、落ちている箇所を勘違いしていました。なんとも間抜けなオチ…。
PDOでDB操作を行なっていたので、try catchで囲んでエラーの箇所はちゃんとメッセージを出すようにしておいた方がいいです。私はメッセージをvar_dumpで表示させる箇所とさせない箇所とが混在していました。

##最後に
初めてのPDOにめちゃくちゃハマりました。
bindParamとか取得できなくなるとかストアドプロシージャを使ってSELECTを実行しようとしたらPDOでは結果が受け取れないとか…正直PDO関連は暫く見たくないです。
ただ次同じことをやるとしたら、今回のような引っかかり方はしませんし、したとしても早く抜け出せるようにはなったかと思っています。




##おまけ
後日、別の条件でも同じバグを出しました。SQL文直打ちでも、引数を追加するのを忘れて変数を指定しても出ます…。
なので、全体的にSQL文を見直すことをおすすめします。
こんな事例もあったよ、ということで…。
ルーティングのリクエストの整理(POSTとかGETとか)

# はじめに
RailsのMVCモデルを理解するために、ブログサービスを作成する中で、ルーティングのリクエストの内容に対する理解が曖昧だったので、復習のためにまとめていきます。

# ルーティングとは
ブラウザーからの受け取ったリクエストを、コントローラで定義したアクションに結びつけてくれるもの。`config/routes.rb`に設定していく。

# GET
indexアクションやshowアクションのような、情報を表示するだけのアクション。

# POST
createアクションのように、情報を登録する際に使うアクション。

# PATCH/PUT
updateアクションのような、情報の更新の際に使うアクション。2つの違いはあんまりわからないが、railsではpatchの方が推奨されてるらしい。

# DELETE
destroyアクションのような、データを削除するアクション。

# resourcesという便利な書き方
上記のようなルーティングを一括で設定出来る、resourcesという便利な書き方がある。

# 設定されているルーティングの一覧を確認する方法
`$ rake routes` というコマンドを叩くと、設定されているルーティングを一括で確認することが出来る。

<img width="1124" alt="スクリーンショット 2019-06-03 8.01.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392294/bd5a3da9-73c1-5324-b0ab-437d28e189d1.png">

- `prefix`とは、pathが代入されている変数のようなものらしい。例えばpostsコントローラーのshowアクションを動かすときは通常のパスだと「posts/"ユーザーのid"」になりますが、Prefixを使って書くと「post_path(@post)」のような記述になります。「@post」はコントローラーで「@post = Post.find(params[:id])」などで記述してあげれば@postの中にはそのポストのidも含まれているのでpost_pathの引数として指定できます。
- `VERB`の部分に、HTTPのリクエストメソッドが記載されている。
- `URIPattern`は、URLのパターンが記載されている。例えば、`/posts/:id`の場合、id番号10のポストは、`posts/10`みたいなURLが付与される。
- `Controller#Action`は文字通り、どのコントローラーで、どのアクションが呼び出されるかが明記される。

#参考記事
- [【Rails入門】ルーティング （config/routes.rb）の書き方を説明！](https://www.sejuku.net/blog/13078)
- [【Rails】rake routesコマンドを徹底解説！](https://www.pikawaka.com/rails/rake_routes)
- [GETとPOSTの使い分け ついでにPUTとDELETE](https://qiita.com/qiita_taro/items/66f2930c5d1cc10722e7)
CloudFormationでスタック内の特定リソースを変更せずに変更扱いする方法 (超簡単で地味に実現)

#背景
AWS CloudFormationでスタックの更新(update-stack)を実行するとき、各リソースのコードに変更がなければ、そのリソースは変更されません。
ただ、Lambda-backed カスタムリソース(CloudFormationテンプレート内でLambdaを実行し、その戻り値を別リソースのパラメータとして使用する)のように、スタックを更新する度に毎回更新(実行)されないと困るものがあります。
そこで、超簡単に特定のリソースを毎回更新扱いにする方法を思いつきました。

#実現方法
実現方法は以下の通りです。
任意にパラメータを定義し、パラメータをDescriptionに含めるだけです。
万が一Descriptionがない場合は、そのリソースを説明する任意文字列を意味する代替パラメータに含めます。(そもそもDescriptionがないリソースがあるかは、途方も無いので調べていません。。。)
ものすごく地味な方法ですが、簡単に特定のリソースだけに更新フラグを付けることができます。
## Parametersの例
```yaml
Parameters: 
  ModifyStackDate: 
    Type: String
    Default: '201901010000'
    Description: Enter Date of Modify Stack.
```
## 変更を加えるリソース
以下のようにDescriptionにパラメータを含めます。
!Refでパラメータを指定するだけで、簡単にできます。
他の文字列と結合したい場合は、以下のように!Joinを使うだけです。

```yaml
HogeHoge:
  Type: "AWS::Lambda::リソースの種類"
  Properties:
    Description: !Join [ ":", [ 'リソースの説明', !Ref ModifyStackDate ] ]
    (以下略)
```
## update-stack
以下のように--parametersを含め、ParameterKeyとParameterValueでパラメータ名と値の組合せを指定するだけです。

```bash
aws cloudformation update-stack --stack-name Hoge-Stack --template-body file://hoge.yaml --capabilities CAPABILITY_NAMED_IAM --parameters ParameterKey=ModifyStackDate,ParameterValue=201906030600
```

# 実行結果
「[Lambda-backed カスタムリソースでLambdaのBoto3を自動で最新化する](https://qiita.com/nasuvitz/items/1875c964f750030be012)」で書いた、毎回最新化したいLambda Layerで試してみました。
以下のように、説明文に毎回任意のパラメータ値を付加することで、変更扱いとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211986/08eb7412-81f1-ca38-8f32-4474d5806ee7.png)

超簡単にCloudFormationのスタック内にある特定のリソースだけを変更扱いにできました。
超地味な方法ですが、Lambda-backed カスタムリソースで毎回実行させたい処理がある場合に、超簡単に威力を発揮します。
php-master-changes 2019-06-02

今日はテストの修正があった！

# 2019-06-02
## weltling: Don't involve output check in the test
- https://github.com/php/php-src/commit/7a64150921bec4af9a18346405d1fff4f1ea84ea
- [7.4~]
- sapi/cli で、Windows 用の CTRL のテストで期待出力に子プロセスの出力内容をチェックしていたのを終了コードを見るよう修正
Vue.jsだけで爆速に開発したい人へのヒント集

### 目的
仕事で知見がたまったので共有したい。

### 想定される読者
- Vue.jsを普段使っているひと
- とにかく早く実装したいひと
- きれいに実装したいひと
- まわりにVue使いがいないけどなぜかVue案件なひと

### 注意事項
効果には個人差があります。
開発メンバーのスキルや納期や規模感によります。
絶対の正解はないです。

### 著者のレベル感
- Vue.js半年ちょいぐらいのレベル感
- VuexとかNuxt.jsとか知らない
- バックエンドが好みなのでJSは雰囲気で書いてる
- コードの綺麗さよりも納期を優先されるところで働いています(泣)
- CSSも雰囲気で書いてる

---

### Component編
#### Componentを分けない	
必要な場合を除き、なるべく分けないで、書きましょう。
分けると親子の変数の受け渡し、メソッドを叩く処理を実装しなくてはならず、時間がかかります。


#### Componentを分ける
上記と、矛盾しますが、ひとつのComponentでつらくなってくるときがあります。
そのとき、初めて分けましょう。

- ロジックが複雑なときに分ける
実装がシンプルになり、見通しがよくなります。
１画面でも複数にわけるとよいです。

- 小さくてもロジックが複雑なときは分けるとよい
１機能１コンポーネントぐらいでもよいかも。
小さく作るとよいです。

- 孫まで作らない
ポイントとして親子までで、孫は作らないほうがよいと思います。
孫まで作ったらVuexなどのライブラリを利用を検討したほうがよいかもしれません。


### データ編

- なるべく親から子へデータを渡す。
- 入力されたデータは子から親へ渡す。
- その子コンポーネントしか使わないデータはその子コンポーネントでAPIを叩いてもってくる。
- ある程度まとめてAPIでデータをもってくるとよい。入力されたデータに動的にとかやると実装が大変になる


### ライブラリ編

- importは最小限にする
- 途中でやっぱ違うなと思ってライブリを変えない。書き直しで時間がかかる。
- できるだけVue.jsでやる。
- 本当につらくなってきたら、Vuexなどを使っていく。僕は使ったことありません。

### メソッド編

- できるだけ小さくメソッドをわける
- わけないほうが、簡単にかけて、読みやすければ、わけない
- 引数を少なくする。３個まで（諸説あります）
- if文は２回まで。（諸説あります）
- メソッドを早い段階で共通化しない
- ある程度、実装するメソッドがでそろってきて時間があったら共通化する


引数やif文が多くなればなるほど、ロジックが複雑になって可読性とメンテナンス性が落ちてきます。

### CSS編

- scopedを使う
- CSSフレームワークを使う
 CSSフレームワークを使って実装して、うまくできないところだけscoped内に書いて、調整していく。

### 心構え編
- 早く実装できる方法を考える
- 未経験なものを使わない。
- 家で、練習してから使う

### ライブラリ編
つらみが解消できるなら使ったほうがいいのですが、現実的に使ったことがあるひとがプロジェクト内にいないと学習コストが高すぎて破綻します。

### 最後に
やり方はひとつではないし、これも正解ではないかもしれません。
優しいマサカリをコメント欄でいただけますとうれしいです。
Dockerコンテナの操作に関するコマンドをまとめてみた

# はじめに

こんにちわ。
今さらですが、Dockerに入門し、学習メモを残していっています。

今回は「Dockerコンテナの操作」に関するコマンドをまとめています。

その他、Dockerに関する記事は以下ですので、こちらもご参照頂けるとありがたいです。

[Dockerの概要と特徴について調べてみたので、学習メモを残す](https://qiita.com/ya6maDev/items/612169ff46249c5520db 'Dockerの概要と特徴について調べてみたので、学習メモを残す')
[Dockerイメージの操作に関するコマンドをまとめてみた](https://qiita.com/ya6maDev/items/f216cd1052fa1a02e672 'Dockerイメージの操作に関するコマンドをまとめてみた')


# Dockerコンテナの操作に関するコマンド

## Dockerコンテナの作成と実行

「docker container run」はDockerイメージからコンテナを作成し、実行するためのコマンドです。

```docker
$ docker container run [options] イメージ名[:タグ] [コマンド] [コマンド引数...]
```


```docker
$ docker container run [options] イメージID [コマンド] [コマンド引数...]
```

## Dockerコンテナの一覧表示

実行中、および終了したコンテナの一覧を表示させるためのコマンドです。


```docker
$ docker container ls [options]
```

オプションなしでコマンドを実行すると、現在実行中のコンテナの一覧が表示されます。

また以下のように「-a」オプションをつけると、終了したコンテナの一覧を表示させることが出来ます。

```docker
$ docker container ls -a
```

## Dockerコンテナの停止

実行しているコンテナを停止する場合は、以下のコマンドを実行します。

```docker
$ docker container stop コンテナIDまたはコンテナ名
```

## Dockerコンテナの再起動

コンテナを再起動したい場合は、以下のコマンドを実行します。

```docker
$ docker container restart コンテナIDまたはコンテナ名
```

## Dockerコンテナの破棄

コンテナをディスクから完全に破棄する場合は、以下のコマンドを実行します。

```docker
$ docker container rm コンテナIDまたはコンテナ名
```

## ログの取得

Dockerコンテナの標準出力を得たい場合は、以下のコマンドを実行します。

```docker
$ docker container logs [options] コンテナIDまたはコンテナ名
```

## 実行中コンテナでのコマンド実行

実行中のコンテナで任意のコマンドを実行したい場合は、以下のコマンドを実行します。

```docker
$ docker container exec [options] コンテナIDまたはコンテナ名 コンテナ内で実行するコマンド
```

## ファイルコピー

以下のコマンドを実行すると、コンテナ間、コンテナとホスト間でファイルをコピー出来る。

```docker
$ docker container cp [options] コンテナIDまたはコンテナ名:コンテナ内のコピー元 ホストのコピー先
```

```docker
$ docker container cp [options] ホストのコピー元 コンテナIDまたはコンテナ名:コンテナ内のコピー先
```

「docker container cp」はコンテナの中で生成されたファイルをホストにコピーして確認するようなデバッグ用途でのユースケースが代表的のようです。

# 引用

[Docker/Kubernetes 実践コンテナ開発入門](https://www.amazon.co.jp/Docker-Kubernetes-%E5%AE%9F%E8%B7%B5%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80-%E5%B1%B1%E7%94%B0-%E6%98%8E%E6%86%B2-ebook/dp/B07GP1Q3VT/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=1559430603&sr=8-1, 'Docker/Kubernetes 実践コンテナ開発入門')
パソコンの選び方（Windows編）

今回はパソコンの選び方に焦点を当てた記事となります。
経緯として、よくパソコン買おうと思うんだけど何買えば良いかわからないや、職場で導入するPCのスペックの相談、ゲームしたいなど様々な話を聞いて一々説明するのが大変なのでまずはReadme的な感じでこちらの記事を見て大雑把にどういうスペックが必要なのか知ってもらうのが目的です。

---

* ネットサーフィン, 動画視聴, ドキュメント作業だけなら

```
CPU (Intel i3), RAM (8GB)
```

価格.com URL
https://kakaku.com/pc/note-pc/itemlist.aspx?pdf_Spec101=41&pdf_Spec307=128-256,256-512&pdf_Spec308=8&pdf_so=p1


* お絵かきや、簡単なプログラミング, 軽めのPCゲーム

```
CPU (Intel i5), RAM (8 ~ 16GB), GPU (MX150, GTX1050Ti etc...)
```

価格.com URL
https://kakaku.com/pc/note-pc/itemlist.aspx?pdf_Spec101=40&pdf_Spec103=10,2&pdf_Spec307=128-256,256-512&pdf_Spec308=8-16&pdf_so=p1

* 動画編集、仮想PC、ガッツリプログラミングとPCゲーム

```
CPU (Intel i7 ~ i9), RAM (16GB以上), (GTX1060 ~)
```

価格.com URL
https://kakaku.com/pc/note-pc/itemlist.aspx?pdf_Spec101=39,54&pdf_Spec103=10,2&pdf_Spec307=128-256,256-512&pdf_Spec308=16-32,32-&pdf_so=p1

* SSDは必須！！！！
* ゲームするならグラフィックボードは必須！！！！

---

### あとがき

基本はこんな感じですが、画面の解像度によってGPUの性能がより必要になったり、
使うアプリケーションによってメモリやCPUの使用率が変わるので一概にこの内容が正しいとは限らないです。
意外と正しいPC選びって難しいですよね・・・。
予算が許す限り一番スペックが良いものを選ぶのが確実ですよ！

---
俺言語 その29

#概要

俺言語をやってみた。
九九やってみた。

#サンプルコード

```
10 a=1
20 b=1
30 c=a*b
40 ?=c
50 ?=" "
60 a=a+1
70 #=a<10*30
80 ?=;
90 b=b+1
100 a=1
110 #=b<10*30

```

#結果

```
>#=1
1 2 3 4 5 6 7 8 9 
2 4 6 8 10 12 14 16 18 
3 6 9 12 15 18 21 24 27 
4 8 12 16 20 24 28 32 36 
5 10 15 20 25 30 35 40 45 
6 12 18 24 30 36 42 48 54 
7 14 21 28 35 42 49 56 63 
8 16 24 32 40 48 56 64 72 
9 18 27 36 45 54 63 72 81 
>      
```

#成果物

https://embed.plnkr.co/om5yDSv0zTOrC5Fm5rTd/

以上。
[Ubuntu 18.04] CUDA Toolkit 10.1のインストール

# 前提
Ubuntu 18.04に
nvidia-driver 418
cuda-toolkit 10.1
をインストールします

# 手順

## 古いドライバーの削除
まず古いnvidiaドライバー等を削除します

```
sudo apt --purge remove nvidia-*
sudo apt --purge remove cuda-*
```

## cuda-toolkitのダウンロード
以下よりcuda-toolkit をとってきます
Installer Typeはdeb(local)を選択してください
https://developer.nvidia.com/cuda-downloads?target_os=Linux&target_arch=x86_64&target_distro=Ubuntu&target_version=1804&target_type=deblocal

コマンドでとるのであれば

```
wget https://developer.nvidia.com/cuda-downloads?target_os=Linux&target_arch=x86_64&target_distro=Ubuntu&target_version=1804&target_type=deblocal
```

## CUDAリポジトリの登録
先ほどダウンロードしたdebファイルがあるディレクトリに移動し，以下のコマンドを実行
「\*」の部分はtabキーなどで補完して適切なファイル名にしてください

```
sudo apt install ./cuda-repo-ubuntu1804-10-1-local-*.deb
sudo apt-key add /var/cuda-repo-*/7fa2af80.pub
sudo apt update
```

## ドライバーのインストール
一旦以下のコマンドを試します

```
sudo apt install nvidia-driver-418
```

**うまくいった場合は**再起動後，次のCUDAのインストールに進んでください
RTX 2080Ti x2 の環境やTITAN Xの環境で試した際はこれでうまくいましたが，経験的にうまくいかない環境の方が多いです
色々調べた結果`apt`ではなく`aptitude`から入れるとなぜかうまくいくようです
（わかる人いたら教えてください）

```
sudo apt install aptitude
sudo aptitude install nvidia-driver-418
```

これでドライバーが入ると思います（5台で検証しました）
そしたら再起動します

**再起動後，ログインできない場合**
Ubuntu起動時のgrubの設定で`quiet splash`を`nomodeset`に書き換えます
そしてUbuntuを起動し，ログイン後に`/etc/default/grub`の内容も同様に`quiet splash`を`nomodeset`に書き換え，保存します
その後`sudo update-grub`を実行します
これで次回以降ログインの問題は解消されると思います
参考
https://qiita.com/bohemian916/items/8c7f0c4b3d3ea0958559


## CUDAのインストール
再起動が終わったらCUDAのインストールを行います

```
sudo apt update
sudo apt install cuda
```

## パスの設定
インストールが完了したら`~/.bashrc`にcudaのパスを設定します

```
echo -e "\n## CUDA paths"  >> ~/.bashrc
echo 'export PATH=/usr/local/cuda-10.1/bin:/usr/local/cuda-10.1/NsightCompute-2019.1${PATH:+:${PATH}}' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/cuda-10.1/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}' >> ~/.bashrc
source ~/.bashrc
```

ここでCUDAのパスが通っているか確認します

```
which nvcc
```

うまくいっていればパスが表示されると思います
俺言語 その28

#概要

俺言語をやってみた。
xor,and,orを実装してみた。

#xor

```
    
10 a=0
OK
20 b=0
OK
30 ?="0 0 "
OK
40 c=a^b
OK
50 ?=c
OK
60 ?=;
OK
70 a=1
OK
80 ?="1 0 "
OK
90 c=a^b
OK
100 ?=c
OK
110 ?=;
OK
120 a=0
OK
130 b=1
OK
140 ?="0 1 "
OK
150 c=a^b
OK
160 ?=c
OK
170 ?=;
OK
180 a=1
OK
190 ?="1 1 "
OK
200 c=a^b
OK
210 ?=c
OK
220 ?=;
OK
#=1
0 0 0
1 0 1
0 1 1
1 1 0
OK

```

#and

```
10 a=0
OK
20 b=0
OK
30 ?="0 0 "
OK
40 c=a&b
OK
50 ?=c
OK
60 ?=;
OK
70 a=1
OK
80 ?="1 0 "
OK
90 c=a&b
OK
100 ?=c
OK
110 ?=;
OK
120 a=0
OK
130 b=1
OK
140 ?="0 1 "
OK
150 c=a&b
OK
160 ?=c
OK
170 ?=;
OK
180 a=1
OK
190 ?="1 1 "
OK
200 c=a&b
OK
210 ?=c
OK
220 ?=;
OK
#=1
0 0 0
1 0 0
0 1 0
1 1 1
OK
```

#or

```
10 a=0
OK
20 b=0
OK
30 ?="0 0 "
OK
40 c=a|b
OK
50 ?=c
OK
60 ?=;
OK
70 a=1
OK
80 ?="1 0 "
OK
90 c=a|b
OK
100 ?=c
OK
110 ?=;
OK
120 a=0
OK
130 b=1
OK
140 ?="0 1 "
OK
150 c=a|b
OK
160 ?=c
OK
170 ?=;
OK
180 a=1
OK
190 ?="1 1 "
OK
200 c=a|b
OK
210 ?=c
OK
220 ?=;
OK
#=1
0 0 0
1 0 1
0 1 1
1 1 1
OK

```

#成果物

https://embed.plnkr.co/OUCw47ZoSSWJprJ6XlCw/

以上。
Java Calendarはなるべく控えよう

# tl;dr

Javaの日付系処理においては、Calendarクラスより<font color="Red">LocalDateクラスを利用</font>しましょう。


以上。


# おはなし

これは私の勤め先で起こった本当にあった話です。



## できごと

2019年5月31日金曜日、所属プロジェクトで定期実行しているCIが突然落ちた。

Java8で書いているソースコードの全テストをJenkinsを使って1日に4回動かしているのだが、つい昨日までオールグリーンだったのが突然エラーを吐くようになったのだ。

エラーログを見てみると、該当箇所はJava標準ライブラリのCalendarクラスの利用箇所。
使い方としては、現在月の当月日数を取得するためだ。

テストコードでは、2017年6月を現在日付としてモック化していたのだが、テスト対象コードは以下のようになっている。
（*※あくまでサンプルで、実際のコードとは違います。*）

```java
Calendar calendar = Calendar.getInstance();

calendar.set(Calendar.YEAR, LocalDate.now().getYear());
calenar.set(Calendar.MONTH, LocalDate.now().getMonth() - 1);  // 月は0から始まるため、例えば1月であれば0をセットする

// 当月の日数を取得
int days = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
```

6月なので当然、30が返り値となる訳だが、デバッグしてみるとそれが31となっていた。



## 問題

数年前の開発当初から動かし続けてきたテストコードがいきなりレッドになってしまったので、ライブラリに何らかの修正が入ったのかと思い色々調べてみたわけでだが、
該当するような記事は特に見当たらず。。


Google検索で「Java calendar b」まで入力すると、「Java calendar バグ」がレコメンドされるくらいには何やら問題がありそう、、

<img width="1440" alt="スクリーンショット 2019-06-03 4.56.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271259/06b79964-40eb-a139-3ead-f4ead99fb91a.png">


とりわけそれっぽい記事は見つけられなかったのだが、公式にdeprecatedになっている訳ではないもののあまり推奨されている訳でもなく、
**Java８で導入されたLocalDateを利用しましょう**というような記事が見つかった程度。


## 解決策

[LocalDate#lengthOfMonth](https://docs.oracle.com/javase/jp/8/docs/api/java/time/LocalDate.html#lengthOfMonth--)を利用する。

そもそも一旦現在日付を取得する処理にてLocalDateを利用しているのだから、そのままLocalDateクラスのメソッドを利用すればいい話なのだが、数年前ではあまりJava8で導入されたLocalDataの利用が普及されていなかったのでしょう。

以下のようにすればいいだけ。


```java
today = LocalDate.now();

// 当月の日数を取得
int days = today.lengthOfMonth();
```

これにてCIも無事回るようになった。安心して業務に取り組める訳。

おわり。
Twitter API で code 81 eror が表示される

# Twitter API で code 81 eror が表示される話
 
## 背景
 
Twitter API を利用して相互フォローでないユーザを定期的にフォロー解除するPythonスクリプトを作成したのだが、
一度に50人（APIの上限）までフォロー解除する処理をしていたら、途中で以下のエラーが表示された。
 
```
tweepy.error.TweepError: [{'code': 89, 'message': 'Invalid or expired token.'}]
```
 
試してみると、タイムラインの取得など行おうとしても
 
```
Error:401
```
 
となる。
 
HTTP 401 とは認証エラーだ。Twitter API のDevelopmentサイトでアクセストークンを確認すると、アクセストークンが割当されていない状態になっていた。
つまり、一度にTwitter API を利用してフォローやフォロー解除を繰り返しているとTwitterに不審がられてアクセストークンを削除される様だ。
 
## 解決策
 
なんてことは無く、単にアクセストークンを再発行すればよい。
だが、あまりに不審な処理を繰り返すと、Developer 登録自体がBANされる可能性もあるので注意が必要。
[Visual C++ 2017] ソートを可視化してみた #1

#はじめに
ソート処理をなんとなく使っていたため、視覚的に取り扱ってみたかった。
バブルソートやクイックソートは知っていたが、他のソートアルゴリズムには疎く、自己学習にもなり良い機会だと思った。

ソートアルゴリズムは、参考となるページがWeb上には多くあるため、この投稿では割愛。


#Winsowの作成
Windowsデスクトップアプリケーションで新規Windowが作成できる。
![New_Window.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282219/088c9be8-185d-52fb-088b-1bc45bb0a9b0.jpeg)
![New_Window2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282219/23b3d3f2-ed5b-ecab-aa75-59349a928131.jpeg)


#描画
`hPen` `MoveToEx()` `LineTo()` により枠組みを描画。
`hButtonWnd[]` でボタンを設置し、初期化やソート処理の開始などをコントロールさせる。
![Sample.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282219/f998e4c2-a6cb-27c3-243f-a8142d7bdaee.jpeg)
とても素朴なインターフェースですが、とりあえずはこれで。

#可視化
計算の度に画面の更新が必要なため、ソートアルゴリズム中に、`InvalidateRect()`　`UpdateWindow()`を入れた。

```sample.cpp
if (input_num[j - 1] > input_num[j]) {
    temp = input_num[j];
    input_num[j] = input_num[j - 1];
    input_num[j - 1] = temp;
    InvalidateRect(hWd, NULL, TRUE);
    UpdateWindow(hWd);
}
```

データ個数を100個用意し、乱数を生成。バブルソートを試してみる。
![sample_bubble.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282219/24da8e3e-d93b-aa4d-d57b-9c484d896b03.gif)


目的を達成できたようです。
他のソートも充実させていきたいと思います。


#リンク
以下リンク先では多くのソートを見ることができ、その影響を受けました。

15 Sorting Algorithms in 6 Minutes
https://www.youtube.com/watch?v=kPRA0W1kECg
[shell] 直下の全てのディレクトリの中身を取得し、リネームする

# 達成したいこと

以下のようなディレクトリ構造がある時に、

```
├DirA
| ├-- fileA1.pdf
| └   fileA2.pdf 
└DirB
  ├-- fileB1.pdf
  └-- fileB2.pdf 
```

各ディレクトリの中身である4つのpdfファイルをリネームし、
以下の形にファイル移動を行う。
（各ディレクトリの中身を取り出して、リネームした上で、カレントディレクトリに移動させたい。）

```
├DirA
├DirB
├DirA_fileA1.pdf 
├DirA_fileA2.pdf 
├DirB_fileB1.pdf 
├DirB_fileB2.pdf 
```

# コード

```sh
 for dir in `ls` 
 do 
   for file in `ls $dir` 
   do 
     mv $dir/$file $dir\_$file
   done 
 done
```

#one liner

```terminal
for dir in `ls`; do for file in `ls $dir`; do mv $dir/$file $dir\_$file; done ;done
```
[shell] ファイル名が7文字のものだけ、名前を変更する

# 達成したいこと
カレントディレクトリ中のファイル一覧を取得。
ファイル名が７文字のものだけ、頭に「0」をつけリネームする

# コード

```sh
for file in `ls` 
do 
  count=`echo $file | wc -c`

  if [ $count -eq 7 ]; then
   rename 's/^/0/' $file
  fi
done
```
【視聴メモ】Protecting Users from Deception (Google I/O ’19)

この記事は Google I/O '19 のセッションの視聴メモです。
想定読者は自分なので正確性や網羅率には問題があるかもしれません。

---

## References

https://www.youtube.com/watch?v=18g9RY-SpBI
Speaker(s): Emily Schechter and Christiaan Brand

## Abstract

> In this talk, you’ll see how Chrome has advanced its protection against deceptive sites, building on a decade of protecting billions of users with Safe Browsing. To proactively offer strong protection against phishing for your users, and even avoid password authentication altogether, you’ll learn about the use cases for WebAuthn, a new web API. This includes using fingerprint and biometric sensors to authenticate users, and support enterprise-grade hardware multi-factor authentication.


訳

> このトークではChromeがどのようにして詐欺サイトに対してユーザーを守ってきたか、またセーフブラウジングを達成してきたかをお見せします。フィッシングから積極的にユーザーを守るためにまたパスワード認証を避けるためにWebAuthと新しいWebAPIのユースケースを紹介します。これは指紋と生体センサでユーザーを認証し、エンタープライズでのハードウェアによる多段階認証を含んでいます。

## Contents

* リークしたことが判明しているユーザー名とパスワードの組は3.3億件以上
* Googleアカウントに対する99．9%の不正ログインは未然に防がれている
* パスワードの漏洩口は主に次の3つ
    * フィッシング、キーロガー、DBからの流出
    * 近年はマルウェアによる漏洩が激減して、フィッシングによる漏洩が増えている
* Unclear Subscription Protection
    * 二段階認証による電話番号入力と見せかけて法外な値段なサブスクリプションを契約させようとするサイトにChromeが警告を出す
* FIDO
    * フィッシングを防ぐためにGoogleやその他の企業が協力してできた
    * FIDOはオープンなのでどの企業でもFIDOに対応したデバイスを作れる
* Android端末が二段階認証の要素として使えるようになった
    * iPhoneみたいな感じ？
* WebAuthn
    * W3CとFIDO Allianceが協力してできたWeb API
    * ユーザーネームとパスワードの認証と、物理キーか生体認証
* FIDO module
    * Androidで利用できる認証モジュールの一つ
    * 従来どおりの認証方法（key storeにアクセスする方法）に加えこちらも使えるようになる
* WebAuthnによってWebで会員登録すると次回以降は指紋認証等だけでログインできるようになる
    * アプリ版をダウンロードしてログインしようとしたときもそれだけでいい（Asset Link）
    * WebもAppもFIDO層で認証するためクレデンシャルを共有できる
* Yahoo!JAPANが指紋認証による再認証をサポートしたところ37.5%ものログイン時間が削減された
* Googleでは認証の成功率自体が20%以上向上した

## Memo

* WebAuthn によるログイン時間の減少はユーザー体験に直結するので、対応してるサービスを使いたくなる
* 1Password に依存しきっている場合はどうなるんだ？
* スピーカーのテンションが高くて話すのが速すぎた…
畳み込みニューラルネット Part6 [TensorFlow2.0でDeep Learning 9]

([目次はこちら](http://qiita.com/kumonkumon/items/6fd05963df92e9eec8c0))

#はじめに
[畳み込みニューラルネット Part6 [TensorFlowでDeep Learning 9]](https://qiita.com/kumonkumon/items/9074d89d8c6c23570db4)をtensorflow2.0で実現するためにはどうしたらいいのかを書く(`tf.keras`)。

# コード
Python: 3.6.8, Tensorflow: 2.0.0a0で動作確認済み

[畳み込みニューラルネット Part6 [TensorFlowでDeep Learning 9]](https://qiita.com/kumonkumon/items/9074d89d8c6c23570db4)([mnist_cnn_ml.py](https://github.com/kumon/DeepLearningExercise/blob/master/src/tensorflow/mnist_cnn_ml.py))を書き換えると、

[v2/mnist_cnn_ml.py](https://github.com/kumon/DeepLearningExercise/blob/master/src/tensorflow/v2/mnist_cnn_ml.py)

```v2/mnist_cnn_ml.py
from helper import *

IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_DEPTH = 28, 28, 1
CATEGORY_NUM = 10
LEARNING_RATE = 0.1
FILTER_SIZE1, FILTER_SIZE2 = 5, 7
FILTER_NUM1, FILTER_NUM2 = 32, 64
FEATURE_DIM = 1024
KEEP_PROB = 0.5
EPOCHS = 20
BATCH_SIZE = 100
LOG_DIR = 'log_cnn_ml'


if __name__ == '__main__':
    sh = (IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_DEPTH)
    (X_train, y_train), (X_test, y_test) = mnist_samples(shape=sh)

    model = tf.keras.models.Sequential()
    model.add(tf.keras.layers.Conv2D(FILTER_NUM1, (FILTER_SIZE1, FILTER_SIZE1), input_shape=sh))
    model.add(tf.keras.layers.MaxPool2D(pool_size=(2, 2)))
    model.add(tf.keras.layers.Conv2D(FILTER_NUM2, (FILTER_SIZE2, FILTER_SIZE2)))
    model.add(tf.keras.layers.MaxPool2D(pool_size=(2, 2)))
    model.add(tf.keras.layers.Flatten())
    model.add(tf.keras.layers.Dense(FEATURE_DIM, activation='relu'))
    model.add(tf.keras.layers.Dropout(rate=1-KEEP_PROB))
    model.add(tf.keras.layers.Dense(CATEGORY_NUM, activation='softmax'))
    model.compile(
            loss='categorical_crossentropy',
            optimizer=tf.keras.optimizers.SGD(LEARNING_RATE), metrics=['accuracy'])

    cb = [tf.keras.callbacks.TensorBoard(log_dir=LOG_DIR)]
    model.fit(X_train, y_train, batch_size=BATCH_SIZE, epochs=EPOCHS, callbacks=cb, validation_data=(X_test, y_test))
    print(model.evaluate(X_test, y_test))
```

と書ける。
[v2/mnist_cnn_sl.py](https://github.com/kumon/DeepLearningExercise/blob/master/src/tensorflow/v2/mnist_cnn_sl.py) との違いは、

(`FILTER_NUM1`, `FILTER_NUM2`, etc...がダサいのはさておき、)
`Conv2D`と`MaxPool2D`を増やすだけ。

```diff
     (X_train, y_train), (X_test, y_test) = mnist_samples(shape=sh)

     model = tf.keras.models.Sequential()
-    model.add(tf.keras.layers.Conv2D(FILTER_NUM, (FILTER_SIZE, FILTER_SIZE), input_shape=sh))
+    model.add(tf.keras.layers.Conv2D(FILTER_NUM1, (FILTER_SIZE1, FILTER_SIZE1), input_shape=sh))
+    model.add(tf.keras.layers.MaxPool2D(pool_size=(2, 2)))
+    model.add(tf.keras.layers.Conv2D(FILTER_NUM2, (FILTER_SIZE2, FILTER_SIZE2)))
     model.add(tf.keras.layers.MaxPool2D(pool_size=(2, 2)))
     model.add(tf.keras.layers.Flatten())
```

ちゃんと動いている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127038/1a77194a-9080-5a6d-2a1f-fd697181a2fa.png)
NaNを使った条件分岐について

Qiita初投稿です！
よろしくお願いします。

#【javascript】　NaNを使った条件分岐について

NaNを使った、数値か数値でないかの条件分岐で少し時間を取られたのでここに記述しておきます。

**使った関数**
***parseInt(str)***
→対象の文字列を整数に変換する
戻り値：対象の文字列を数値に変換できない場合はNaNを返す(NaNはNot a Numberの略)

***isNaN(value)***
→対象の値がNaNかどうかを調べる
戻り値：対象の値がNaNならtrue, それ以外ならfalseを返す


まず、parseIntに文字列を入れた時の戻り値がNaNになるので、これを使い条件分岐しようとしましたが***失敗しました。***

***失敗のコード***がこちら。

```javascript
let num = 1;
let intNum = parseInt(num);

//intNumがNaNかそれ以外かで分岐
if(intNum !== NaN) {
    console.log('数字だよ');
} else {
    console.log('数字じゃないよ');
}
```
結果は
***数字じゃないよ***
と出力されます。

これは、***NaNを(不)等価演算子にかけると必ずfalseを返す為で、これではNaNかどうか調べられないのです。***
この事を知らず、かなり時間を取られてしまいました、、、


***成功のコード***

```javascript
let num = 1;
let intNum = parseInt(num);

//intNumがNaNならtrue,それ以外ならfalse
if(isNaN(intNum)) {
    console.log('数字じゃないよ');
} else {
    console.log('数字だよ');
}
```
isNaN関数を使い、NaNかそれ以外かで条件分岐ができるようになりました。

補足や訂正などありましたら、ぜひご教授いただければ嬉しいです。
最後まで見ていただきありがとうございます。

---
2019.6.05追記
コメント欄でご指摘いただいたtypeof演算子の使い方を記事にしました。
[【typeof演算子】データ型を文字列として取得する際の書き方と注意点](https://qiita.com/kouki-iwahara/items/a85b4c9260ef545b7a52)
畳み込みニューラルネット Part5 [TensorFlow2.0でDeep Learning 8]

([目次はこちら](http://qiita.com/kumonkumon/items/6fd05963df92e9eec8c0))

#はじめに
[畳み込みニューラルネット Part5 [TensorFlowでDeep Learning 8]](https://qiita.com/kumonkumon/items/bb9df35647fff8fee3b1)をtensorflow2.0で実現するためにはどうしたらいいのかを書く(`tf.keras`)。

# コード
Python: 3.6.8, Tensorflow: 2.0.0a0で動作確認済み

[畳み込みニューラルネット Part5 [TensorFlowでDeep Learning 8]](https://qiita.com/kumonkumon/items/bb9df35647fff8fee3b1)([mnist_cnn_sl.py](https://github.com/kumon/DeepLearningExercise/blob/master/src/tensorflow/mnist_cnn_sl.py))を書き換えると、

[v2/mnist_cnn_sl.py](https://github.com/kumon/DeepLearningExercise/blob/master/src/tensorflow/v2/mnist_cnn_sl.py)

```v2/mnist_cnn_sl.py
from helper import *

IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_DEPTH = 28, 28, 1
CATEGORY_NUM = 10
LEARNING_RATE = 0.1
FILTER_SIZE = 5
FILTER_NUM = 32
FEATURE_DIM = 100
KEEP_PROB = 0.5
EPOCHS = 20
BATCH_SIZE = 100
LOG_DIR = 'log_cnn_sl'


if __name__ == '__main__':
    sh = (IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_DEPTH)
    (X_train, y_train), (X_test, y_test) = mnist_samples(shape=sh)

    model = tf.keras.models.Sequential()
    model.add(tf.keras.layers.Conv2D(FILTER_NUM, (FILTER_SIZE, FILTER_SIZE), input_shape=sh))
    model.add(tf.keras.layers.MaxPool2D(pool_size=(2, 2)))
    model.add(tf.keras.layers.Flatten())
    model.add(tf.keras.layers.Dense(FEATURE_DIM, activation='relu'))
    model.add(tf.keras.layers.Dropout(rate=1-KEEP_PROB))
    model.add(tf.keras.layers.Dense(CATEGORY_NUM, activation='softmax'))
    model.compile(
            loss='categorical_crossentropy',
            optimizer=tf.keras.optimizers.SGD(LEARNING_RATE), metrics=['accuracy'])

    cb = [tf.keras.callbacks.TensorBoard(log_dir=LOG_DIR)]
    model.fit(X_train, y_train, batch_size=BATCH_SIZE, epochs=EPOCHS, callbacks=cb, validation_data=(X_test, y_test))
    print(model.evaluate(X_test, y_test))
```

と書ける。
[v2/mnist_fixed_cnn.py](https://github.com/kumon/DeepLearningExercise/blob/master/src/tensorflow/v2/mnist_fixed_cnn.py) との違いは、

入力のshapeを変え、

```diff
-    (X_train, y_train), (X_test, y_test) = mnist_samples()
+    sh = (IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_DEPTH)
+    (X_train, y_train), (X_test, y_test) = mnist_samples(shape=sh)
```

PrewittフィルタをConv2Dに変える。

```diff
-    model.add(Prewitt((IMAGE_HEIGHT * IMAGE_WIDTH, FILTER_NUM), input_shape=(IMAGE_HEIGHT, IMAGE_WIDTH)))
+    model.add(tf.keras.layers.Conv2D(FILTER_NUM, (FILTER_SIZE, FILTER_SIZE), input_shape=sh))
```

以上。
シェルの定義やスクリプトについて紹介！

今回はシェルの定義やスクリプトについて紹介します。
だだし、プログラミング初心者であるため、内容に誤りがあるかもしれません。
誤りがあればどんどん指摘してください。

### シェルの定義
シェルとは「オペレーティングシステムと対話するためのインターフェイス」であり、コマンドなどを制御する「環境」のことです。
具体的には、人間の入力をカーネルに伝え、またその逆を行うプログラムのことで、UNIX系OS（Linuxとか）のそのプログラムを「シェル」、そこで解釈できる命令文を記述したファイルを「シェルスクリプト」と呼びます。ちなみに、Windowsでは「コマンドプロンプト」、そこで使えるコマンドの寄せ集めファイルを「バッチファイル」と呼びます。

### スクリプトとは
書いて、すぐ実行できるプログラムのことです。
具体的には、人間語で書いたプログラムをコンピュータが分かる形に変換する作業（コンパイル）を人間が意識しないで済むプログラムのことです。

### BashとZshの違い
BashとZshは、UNIX/Linux系OSで標準的に使われるシェルですが違いがあります。
BashはGNUプロジェクトの一部として開発が進められ、オープンソースソフトウェアとして公開されているもので、UNIX系OSのデフォルトのシェルです。
Zshはbashやその他のshellの良いところをとりこんだUNIX系OSのシェルです。