OmniAICreator/Qiita-1.07M huggingface dataset:
言語処理100本ノック with Nim 第1章: 準備運動

Nimを勉強することになったのでとりあえず[言語処理100本ノック](https://nlp100.github.io/ja/)をNimでやってみる。
Nimの文法などもメモしていく。随時更新予定。

## [00. 文字列の逆順](https://nlp100.github.io/ja/ch01.html#00-%E6%96%87%E5%AD%97%E5%88%97%E3%81%AE%E9%80%86%E9%A0%86)
> 文字列"stressed"の文字を逆に（末尾から先頭に向かって）並べた文字列を得よ．

[unicode](https://nim-lang.org/docs/unicode.html)モジュールの[reversed](https://nim-lang.org/docs/unicode.html#reversed%2Cstring)を使う。

```nim
import unicode

proc e_00*(s: string): string =
    result = s.reversed
```

- `proc`というキーワードを使って[プロシージャ（関数）](https://nim-lang.org/docs/tut1.html#procedures)を定義する
- [アスタリスク`*`](https://nim-lang.org/docs/tut1.html#modules)をつけた識別子はエクスポートされる
    - `import {モジュール名}` するとそのモジュールで[エクスポートされてる識別子をすべて取り込む](https://nim-lang.org/docs/tut1.html#modules-excluding-symbols)
- [返り値を表す`result`という変数](https://nim-lang.org/docs/tut1.html#procedures-result-variable)が暗黙に定義されている
- `method(obj, args)`を`obj.method(args)`のように書ける（[Method call syntax](https://nim-lang.org/docs/tut2.html#object-oriented-programming-method-call-syntax)）
    - 今回の`s.reversed`は`reversed(s)`と同じ

## 参考
- [Nim Tutorial (Part I)](https://nim-lang.org/docs/tut1.html)
- [Nim Tutorial (Part II)](https://nim-lang.org/docs/tut2.html)
- [Nim Tutorial Part Iを日本語訳してみた（前編）](https://qiita.com/KTakahiro1729/items/f4776f3a072c01f9086b)
- [Nim Tutorial Part Iを日本語訳してみた（後編）](https://qiita.com/KTakahiro1729/items/3f18811267bf4f8075d5)
- [Nim ざっくり勉強してみたまとめ](https://qiita.com/zk_phi/items/ab1ec2575f27f921dcf5)
「Pythonで順列（Permutation）を実装してみた」を参考に、wolframalphaで実行してみた。

(オリジナルポスト)itertoolsで

https://qiita.com/kkent030315/items/278148a283afe3aff4f1

#WolframAlphaで

https://ja.wolframalpha.com/input/?i=%281%2C2%2C3%29%E3%81%AE%E9%A0%86%E5%88%97

置換
{1, 2, 3} | {1, 3, 2} | {2, 1, 3} | {2, 3, 1} | {3, 1, 2} | {3, 2, 1} (合計: 6)
【Google Apps Script】トリガーによる定期実行の時間のズレをなくす方法

# はじめに
GASではプロジェクトのトリガーから定期的（毎時間や毎日など）に実行することができ、今まではこの機能を使用して定期的に関数を実行させていました。しかしこの機能は永久に定期的に関数を実行させていると少しずつ時間がずれていく問題があります。そこで時間ベースで決まった頻度でプログラムを実行することができたのでその方法のメモ。
# 前提条件
* スクリプトエディタからプロジェクトが既に作られている状態であること

# 手順
内容：処理を終了する際に再度プロジェクトのトリガーを設定しなおす。
まず、Main()関数があり、そこから実行しているものと過程します。
他の関数をトリガーとして指定する場合はsetTrigger("【実行したい関数名】")と入力します。

```js
function Main(){
  try{...} //任意のプログラムを記述
  catch(e){...} //任意のプログラムを記述
  finally{
    setTrigger("Main");//ここにトリガーとして実行したい関数名を記述
  }
}
```

## 毎時間実行させる方法
以下の関数を追加します。
ここでのsetTrigger()関数はプログラムを実行した際にその時点の**実行時間**をインクリメントしてトリガーを再設定する。
挙動としては、0:00, 1:00, 2:00...で指定した関数が作動する。

```js
function setTrigger(func_name) {
  // 指定のトリガーがあれば削除する。
  var triggers = ScriptApp.getProjectTriggers();
  for(var i = 0; i < triggers.length; i++){
    if(triggers[i].getHandlerFunction() == func_name)
      ScriptApp.deleteTrigger(triggers[i]);
  }
  // 1時間後の00分に起動されるようトリガーを設定
  var trigger_setTime = new Date();
  trigger_setTime.setHours(trigger_setTime.getHours() + 1, 0, 0, 0);
  ScriptApp.newTrigger(func_name).timeBased().at(trigger_setTime).create();
}
```
## 毎日決まった時間に実行する方法
以下の関数を追加します。
ここでのsetTrigger()関数はプログラムを実行した際にその時点の**実行日**をインクリメントしてトリガーを再設定する。
挙動としては、"2020/1/1 7:00", "2020/1/2 7:00","2020/1/3 7:00".....で動作する。

```js
function setTrigger(func_name) {
  // 指定のトリガーがあれば削除する。
  var triggers = ScriptApp.getProjectTriggers();
  for(var i = 0; i < triggers.length; i++) {
    if(triggers[i].getHandlerFunction() == func_name)
      ScriptApp.deleteTrigger(triggers[i]);
  }
  // 翌日の7:00にトリガーを設定
  var trigger_setTime = new Date();
  trigger_setTime.setDate(trigger_setTime.getDate() + 1);
  trigger_setTime.setHours(7, 0, 0, 0);
  ScriptApp.newTrigger(func_name).timeBased().at(trigger_setTime).create();
}
```

## トリガーを設定しなおす方法
1. setTrigger()関数の呼び出し元の関数を実行する
2. 既にトリガーで毎時間等を設定している場合はそのトリガーによって実行された時から次の日時に設定されている

# 最後に
初めての記事作成なので、見苦しいかと思いますが参考になれば幸いです。
Git入門 - 1

## 1. はじめに

当記事は全5回（+α）からなる **Git入門シリーズ** の第1回です。

今回は **そもそもGitとは何なのか** ということについて説明します。

- **1回: 概要**
- [2回: 導入手順とGitコマンド](https://qiita.com/AGadget/items/24c655fcbf9fc58625f0)
- [3回: データの保存](https://qiita.com/AGadget/items/6b1ccc036d682f5475a0)
- [4回: データの活用と便利な操作](https://qiita.com/AGadget/items/fbc2f67e8d6e3143d620)
- [5回: ブランチ](https://qiita.com/AGadget/items/b48983b7da16099eeba0)
- [番外編: GitHub](https://qiita.com/AGadget/items/1edc9f1f5da1dafe8325)





## 2. Gitとは？

**Git** は2005年12月21日に発表された **VCS** です。「ギット」と読みます。 ~~「ジット」だと思ってた。~~

開発元は、Linuxの生みの親であるLinus Benedict Torvalds氏と、Linuxコミュニティです。元々Linuxコミュニティでは、Linuxのソースコードの管理にBitKeeperというVCSを使用していました。ただ、様々な事情からBitKeeperの使用をやめることになり、その際BitKeeperの代替となるVCSを探したのですが、満足できるものが無かったため、新たにGitが開発されました。





## 3. VCSとは？

**VCS (Version Control System)** は **バージョン管理** を支援するアプリの総称です。もちろん、バージョン管理ができるならば、アプリでなくとも（Webサービスなどであったとしても）VCSたりうると思うのですが、主要なVCSは全てアプリという形を採っています。

Git以外のVCSには――

- 世界初のVCSである **SCCS (Source Code Control System)**
- 世界で2番目のVCSであり、今なお一部では現役と聞く **RCS (Revision Control System)**
- クライアントサーバー型VCSの祖として広く普及した **CVS (Concurrent Versions System)**
- CVSの改良型のように語られることが多い **SVN (Apache Subversion)**
- Gitのライヴァル **Mercurial**
- 悪評高き **VSS (Microsoft Visual SourceSafe)**
- VSSの汚名返上に成功した（？） **TFS (Team Foundation Server)**

――などがあります。





## 4. バージョン管理とは？

私が調べたかぎりでは厳密な定義はないようです。バージョン管理（version control）という呼び方すら絶対ではなく――

- software configuration management
- SCCM (Software Change and Configuration Management)
- source configuration management
- revision control
- source control

――といった色々な呼称が使われているようです。

ただ、それでは話が進まないので、私個人の解釈を申し上げますと、バージョン管理とは **ある成果物の状態の変遷を、特定の法則に基づいて記録・管理する手法および概念** ということになるでしょう。

プログラムの改修作業（変更作業）は常に成功するわけではありません。時には、変更を加えたことで新たなバグが生じたり、余計なところにまで手を付けてしまったり、そもそも変更内容自体が適切でなかったりします。そんなとき、変更前の状態が残っているのと残っていないのとでは、その後の対応状況・対応方法・対応難易度が変わってきます。言わずもがな、変更前の状態が残っているほうが対応が容易になります。

また、各状態を残すにしても規則性が必要です。例えば、新しい状態になるごとに「ソースファイルの末尾の数字を増やしていく（v1、v2、v3）」とか「変更を加えた日付を付ける（20200101、20200103、20200201）」といったようにです。これを徹底しないと以下のように収拾が付かなくなります。

- main.ps1
- main_v2.ps1
- main_20200203.ps1
- main-200204.ps1
- 【最新版】main.ps1
- 【最新版】main.ps1_バグ修正済み
- main.ps1_本番環境

上記例だと7つのファイルがありますが、結局どれが最新版なのか分かりません。どのように変更が加えられてきたのかも読み取れません。これではバージョン管理ができているとは言えません。





## 5. バージョン管理するのにVCSって要るの？

バージョン管理を行うのにVCSは必須ではありません。

実際、電子式コンピューターの生産、およびプログラミング言語の利用は1940年代から始まりましたが、世界初のVCSであるSSCSが登場したのが1972年のことです。つまり、およそ30年近くにわたって、VCSを用いないバージョン管理が行われてきたわけです（バージョン管理が1940年代から存在していたという前提に立つ）。

ただ、VCSを用いないバージョン管理は往々にして、VCSを用いたバージョン管理よりも問題を生じさせます。各バージョンを区別する方法（概ねファイル名で区別しますが）で悩んだり、旧バージョン・現行バージョン・開発中バージョンの分け方・管理体制で悩んだり、メンバーのなかからバージョン管理を無視する人が出てきたり、プロジェクトが進むにつれて管理が煩雑になってきたり、と色々と苦労する羽目になるでしょう。

このようなエンジニア職の本質ではない仕事はVCSというツールに任せてしまえばよいのです。





## 6. Gitの評価

他のVCSと比較したGitの長所として、よく聞くのは――

- 動作が軽快
- 多機能
- 大規模開発に耐えうる
- 現状、VCSはGitかVSNのツートップ
- ブランチを積極的に切っていく開発フローに適する
- マージ処理が賢い

――などがあります。反対に、短所としては――

- 覚えなければならない概念・仕様が多い
- Gitコマンドの抽象化が足りておらず使いにくい
- VCSのなかで最も学習難易度が高い

――などです。

私個人の考えも含めた総評としては **多機能、かつ高性能。それでいて様々プロジェクトで使われてきた実績もある、最も優れたVCSの1つ。ただし、学習コストも相応に大きい** といった感じでしょうか。

ちなみに、無料のアプリなので安心して使ってください。
Node-RED dashboard のボタンで押したときと離したときを検出したい

# 経緯

ラジコンのコントローラーのようなものをNode-REDのdashboardで作ろうとしたのだが、dashboardのボタンはclickイベントしか検出できないため、ボタンを押している間動くようなことが実現できない。
ui-templateを使えばできそうなのだが、Angular.jsとjQueryがわからず途方に暮れていた。

# 解決策を発見

いろいろ検索していたら以下のgistを発見した。

https://gist.github.com/Hugobox/badf32e71913b09a2d8e2488a1b101a5

> This ui-template creates a momentary button that outputs true on mousedown/touchstart and false on mouseup/touchend

とあるので、まさにやりたいことであった。しかも、スマホ操作touchdownとtouchendにも対応。

ui-templateノードの中身だけ抜き出させてもらった。

```html

<style>
.nr-dashboard-template {
    padding: 0px;
}
</style>
<div class="momentary">
   <md-button style="width:100%; height:48px; margin: 0px"> Momentary Button</md-button>
</div>

<script>

(function($scope) {
    
$('.momentary').on('touchstart mousedown', function(e) {
    e.preventDefault(); //prevent default behavior
    $scope.send({"payload": true});
});

$('.momentary').on('touchend mouseup', function(e) {
    e.preventDefault(); //prevent default behavior
    $scope.send({"payload": false});
});
    
})(scope);
</script>
```

これをui-templateノードの中に入れてデプロイすれば、ボタンを押したときはpayloadにtrueが、離したときにはpayloadにfalseが出てくるようになる。

# おわりに

node-red-dashboardのtemplateノードを調べたかったのだが、Node-REDにもtemplateノードがあるので検索性が悪かった。
loadイベントの中でDOMContentLoadedイベントをセットしても動いてくれません

DOMContentLoadedイベントはloadイベントよりも早く動いてくれるので、DOMContentLoadedイベントを使うことで処理のタイミングを早めることができますが、注意があります。
loadイベントの中でDOMContentLoadedイベントをセットしても、動いてくれません。

サンプルコード

```javascript
let log = (message) =>
  (document.getElementById("log").innerHTML += "<br/>" + message);

window.addEventListener("load", () => {
  log("load");
  window.addEventListener("load", () => log("load -> load"));
  window.addEventListener("DOMContentLoaded", () =>
    log("load -> DOMContentLoaded")
  );
});

window.addEventListener("DOMContentLoaded", () => {
  log("DOMContentLoaded");
  window.addEventListener("load", () => log("DOMContentLoaded -> load"));
  window.addEventListener("DOMContentLoaded", () =>
    log("DOMContentLoaded -> DOMContentLoaded")
  );
});
```

実行結果

```
DOMContentLoaded
load
DOMContentLoaded -> load
```

`load -> DOMContentLoaded` が出力されていないことがわかりますね。（他にも `load -> load` と `DOMContentLoaded -> DOMContentLoaded` も出力されていません）

当たり前のことなのですが、loadイベントが動くときにはDOMContentLoadedイベントはもう終わっているので、このタイミングでセットしても動いてくれないのです。

普通に実装しているとこんな書き方はしないのですが、DOMContentLoadedイベントを利用しているライブラリをloadイベント内で実行しようとする時など、気づかずにこの状態になっているかもしれないので注意です。

codepenでのサンプル

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="akiyah" data-slug-hash="poygVjW" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="DOMContentLoaded in load">
  <span>See the Pen <a href="https://codepen.io/akiyah/pen/poygVjW">
  DOMContentLoaded in load</a> by mizukoshi akiya (<a href="https://codepen.io/akiyah">@akiyah</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
Laravelアプリで管理者権限を追加する

##　Laravelで管理者権限の作り方をシンプルにまとめました
色々やり方があるようだったので、シンプルにまとめました。
Laravelプロジェクトが作成されている前提です。


### 環境
- mac OS Catalina 10.15.6
- Laravel 7.22.4


## Gateを使う
AuthServiceProviderの中にあるGateという機能を使います。
ちなみに同じファイル内にPolicyという似た機能を持つものもあります。

### 【GateとPolicyの使い分け】

- Policyは特定のモデルへのアクションに対して制限を加える場合
- Gateはモデルに関連しないアクションに対してユーザーの制限を加える場合

詳しくはこちら [Laravel 7.x 認可](https://readouble.com/laravel/7.x/ja/authorization.html)


## 手順

### 1. XXXXX_create-users-table.phpにroleカラムを追加

今回はroleが1を管理者、５を一般ユーザーに設定します。

```php:XXXXX_create_users_table.php
    // Role 1=admin, 5=normal user
    $table->tinyInteger('role')->default(5);
```

### 2. AuthServiceProviderに追加

isAdminという名前で定義して、管理者かどうか判断します。

 ```php:AuthServiceProvider.php
 public function boot()
        {
            $this->registerPolicies();

            // 管理者権限設定
            Gate::define('isAdmin',function($user){
                return $user->role === 1;
            });
        }
 ```

### 3. ルーティングを作成して完了

 管理者にだけアクセス許可したいページとコントローラーを作成します。
ルーティングをグループにまとめ、ミドルウェアを設定したら完了です。

 ```php:web.php
    Route::middleware(['auth','can:isAdmin'])->group(function(){
        Route::get('/admin','AdminController@index');
    });
 ```
[Laravel 7.x ルーティング](https://readouble.com/laravel/7.x/ja/routing.html)



その他参考：
[Laravel Gate(ゲート)、Policy(ポリシー)を完全理解 | アールエフェクト](https://reffect.co.jp/laravel/laravel-gate-policy-understand#i-3)
PHPで「ここはis_null？empty？isset？」ってなったので比較してまとめた。

is_null？empty？isset？ってなることが多々あったので、比較実験した。

## 実験内容
それぞれに以下を与えて結果を取得する。


* $string; //変数を宣言するだけ
* $string = 'test'; //文字列
* $string = null;　//null
* 未定義の変数
* 空文字

最終結果はページの最後に表にしています。

## is_null()
変数がNULLかどうか調べる。つまり、**null**ならば**true**が、それ以外であればfalseが返ってくる。

```php
$string;
is_null($string); // true
```

```php

$string = 'test';
is_null($string); // false
```

```php

$string = null;
is_null($string); // true
```

```php

//定義していない $a
 is_null($a); // true
```

```php

//空文字
is_null(''); // false
```

## empty()
変数が空であるかどうかを検査する。「変数が空」のイメージがしっくり来ないので、以下でテスト。

```php
$string;
empty($string); // true
```
```php

$string = 'test';
empty($string); // false
```

```php

$string = null;
empty($string); // true
```

```php

//定義していない $b
empty($b); // true
```
ここまでは、is_nullと挙動が同じだなーって思ったが、以下の挙動が違った。

```php

//空文字
empty(''); // true
```

空文字は「変数が空である」と捉えられるらしい。

## isset()
変数が宣言されていること、そして NULL とは異なることを検査する。

つまり、

* 変数が宣言されている
* その変数がnullではない

という2つの条件が整うと**true**が返ってくる。is_nullとemptyとは異なり2つ条件があるっぽい。

is_nullとemptyとは「あったらtrue」という感じでニュアンスが違う。

```php

$string;
isset($string); //false （変数は宣言されているが、nullなのでアウト)
```
```php

$string = 'test';
isset($string); // true （変数は宣言され、文字列が与えられているのでセーフ)
```

```php

$string = null;
isset($string); // false （変数は宣言されているが、nullなのでアウト)
```

```php
// 定義していない $c
isset($c); // false （変数が宣言されていないのでアウト)
```

なるほど。じゃあ変数としてではなく、直接文字列とか与えたらどうなる？？(以下のように)

```php

isset('');
isset('string');
```

結果は、

```
PHP Fatal error:  Cannot use isset() on the result of an expression (you can use "null !== expression" instead)
```

ダメらしい。

# まとめ

上の結果を以下の表にまとめました。

| |$string | $string = 'test' | $string = null |定義していない変数|空文字を直接|
| :---| :--- | :--- | :--- | :---|:---|
| is_null | true| false |true|true|false|
| empty | true | false |true|true|true|
| isset | false | true |false|false|空文字にかかわらず直接与えるとエラー|
Jestのpuppeteerサンプルを補足


下記ページのサンプルコードは説明不足に感じました。補足しましたので、うまく動かせなかった人は参考にしてみてください。

Using with puppeteer
[https://jestjs.io/docs/en/puppeteer.html](https://jestjs.io/docs/en/puppeteer.html)

## 1. First, install jest-puppeteer
ライブラリのインストールですね。これだけではjestがない、puppeteerがないとエラーになりました。

```
yarn add --dev jest-puppeteer
```

補足：実際には併せてjestとpuppeteerのインストールも必要でした

```
yarn add --dev jest-puppeteer jest puppeteer
```

## 2.Specify preset in your Jest configuration:
Jestの設定ファイルの指定ですね

```json
{
  "preset": "jest-puppeteer"
}
```

補足：この設定をどこに記述していいか分かりませんでした。実際はpackage.jsonに追記が正解でした。さらにjestで囲う必要があります。

```package.json
{
  "devDependencies": {
    "jest": "^26.4.0",
    "jest-puppeteer": "^4.4.0",
    "puppeteer": "^5.2.1"
  },
  "scripts": {
    "test": "jest"
  },
  "jest": {
    "preset": "jest-puppeteer"
  }
}
```

## 3.Write your test
Jestでpuppeteerを使ったテストのサンプルコードです。

```google.test.js
describe('Google', () => {
  beforeAll(async () => {
    await page.goto('https://google.com');
  });

  it('should be titled "Google"', async () => {
    await expect(page.title()).resolves.toMatch('Google');
  });
});
```

補足：ファイル名が分かりませんでした。google.test.jsで保存すると実行されました。*.test.jsが命名規則のようです。

## See documentation.

最後にjest-puppeteerライブラリの[READMEへリンク](https://github.com/smooth-code/jest-puppeteer)されていますが、これだけだと実行の仕方が分かりませんでした。

補足：[Jestの初歩のチュートリアル](https://jestjs.io/docs/en/getting-started)を参考にしました。まずはpackage.jsonに設定の追加が必要です。

```json
{
  "scripts": {
    "test": "jest"
  }
}
```

そして、実行するコマンドは次のとおりです。Puppeteerのサンプルページに書かれないのは納得の短さでした。

```
yarn test
```

## 実行の様子

```bash

% yarn test
yarn run v1.22.4
warning package.json: No license field
$ jest
 PASS  ./google.test.js
  Google
    ✓ should display "google" text on page (8 ms)
    ✓ should be titled "Google" (2 ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        1.58 s, estimated 3 s
Ran all test suites.
✨  Done in 3.45s.
```

私はJestの基礎をやらずに取り組んだせいで、動作させるまでに時間がかかってしまいました。つまづいた時点でJestのチュートリアルに戻ったらよかったと思います。

## 参考

* Jestの最初のチュートリアル https://jestjs.io/docs/en/getting-started
* JestのConfigの説明 https://jestjs.io/docs/ja/configuration
* Jestのpuppeteerのチュートリアル https://jestjs.io/docs/en/puppeteer.html
* jest-puppeteerライブラリ https://github.com/smooth-code/jest-puppeteer
Codeforces Round #584 Div2. A. Paint the Numbers


# 概要(ReadForce)
- 配列が与えられる。ある配列は最小の要素に割られなければならない(つまり、自分が最初なら自分で割っていい)
- このとき、割るのに使った数が一番少ないものを出力せよ

# 考察
- [2,3,4]を考えると、2で2,4はわれる。3は3でしか割れない。このため、2グループ2,4, 3グループ3と２つに分割できる。
- [1,2,3]は特殊。すべてが1で割れる。

# アプローチ
- 最小の割れる子を差がするだし、n,iも100以内と小さい。このため、sortをして、全探索をする。O(NlogN)である。
- 昇順に並んでいるのだから、小さい方から自分を含めてそれより上を探索する。尚、既に割れる値があるもののチェックが付いている者は相手にしない。、割り切れたものは、その要素を最小の除数と持つ通知である。

```Python
n = int(input())
dat = list(map(int, input().split()))
used = [False] * n
dat.sort()
res = 0
for i in range(n):
    if used[i] is True:
        continue
    used[i] = True
    res += 1
    for j in range(i + 1, n):
        if used[j] is True:
            continue
        if dat[j] % dat[i] == 0:
            used[j] = True
print(res)
```
https://codeforces.com/contest/1209/submission/89769155
【Swift】正規表現で含有判定

# 文字列を含んでいるのか
* 正規表現パターン：`pattern`を引数で渡し、含んでいるのか評価した結果をtrue/falseで返します。
* エラーがthrowされた場合、正規表現が間違えています

``` swift
extension String {
    func contain(pattern: String) -> Bool {
        guard let regex = try? NSRegularExpression(pattern: pattern, options: NSRegularExpression.Options()) else {
            return false
        }
        return regex.firstMatch(in: self, options: NSRegularExpression.MatchingOptions(), range: NSMakeRange(0, self.count)) != nil
    }
}
```

# 利用方法
### 実装

``` swift
print("apple".contain(pattern: "a.*e"))
print("apple".contain(pattern: String()))
print("".contain(pattern: String()))
```

### 出力
``` bash
true
false
false
```

# 参考
* [【Swift】正規表現による文字列の検索を行う方法](https://cpoint-lab.co.jp/article/201910/12411/)
* [Swift 3.0での基本的な正規表現を行うextension](https://qiita.com/KikurageChan/items/807e84e3fa68bb9c4de6)
カルマンフィルターは株価のトレンド予測に利用できるか

# カルマンフィルターは株価のトレンド予測に利用できるか

## この記事の概要について
株価のトレンドの予測のためのカルマンフィルターの実装とその感想です。
結論から言うと「短期については利用できるかも」です。
google colabの上で動かしてます。

## カルマンフィルターとは何か
もともとロボットやロケットの制御のためなどに使われてるもので、誤差のある観測値を利用して、そのシステムの状態がどうなっているか推定するためのものです。
今回はその中でも一番単純なものを使ってます。

## 前提
株価の変動をある確率分布に従って変動していると考えて、それに基づいて予測しているので指標の一つとしてみてください。

また、今回では株価の変動の潜在的な仕方およびそれが実際に変化する仕方は、正規分布に従ってると仮定しているので非現実的な仮定をしています。

なので、株価がある程度安定的に動いているものに対してはしっかり働いてくれる一方で、急な変化にはついていけないと思われます。

## 計算式(実装)
計算式がなぜそうなるかはめんどくさいので、見たい人は[wiki](https://ja.wikipedia.org/wiki/カルマンフィルター)を参考にしてください。
実装の上では、以下の関数を定義してあげれば問題ないです。
数列を引数として受け取り、それと同じ長さの数列を返します。

```python3:kalman.py
import numpy as np

def kalman(s,x,P):
    res_x=[]#その時点における推定される位置
    res_v=[]#その時点における推定される速度
    for i in range(len(s)):
        Z=np.array([s[i]])
        y=Z-H@x
        S=H@P@H.T+R
        K=P@H.T@np.linalg.inv(S)
        x=x+K@y
        P=(I-K@H)@P
        #predicion
        x=(F@x)+u
        P=F@P@F.T
        res_x.append(x[0,0])
    return res_x

x=np.array([[0.], [0.]])#一つ目が位置で二つ目が速度を表す
P=np.array([[1000., 0.], [0., 1000.]])#共分散行列
u=np.array([[0.], [0.]])#外力だけど今回はないと想定
F=np.array([[1., 1.], [0, 1.]])#位置と速度の関係の定義
H=np.array([[1., 0.]])
R=np.array([[1.]])
I=np.array([[1., 0.], [0., 1.]])

t=[1,2,4,3,7,4,6,5.2]#入れる数列
print(kalman(t,x,P))
```
結果は以下のようになりました。
```res.txt
[0.999000999000999,2.9980029930179533,5.332389258923225,4.500249550392171,7.299929903069252,6.400310235003376, 7.000316132748338, 6.886095984845674]
```
与えた数列に今回は特に規則性がないので、正しく予想できませんが、確率分布に従って乱数を発生させるとなかなかの精度で推定してくれます。

## 実際に株価に適用してみた
この記事を書いているのが8月14日で、コロナで株価が冷えて二番底?になってそろそろ上がってくれるかな？みたいな時期です。
カルマンフィルターによって得た値を、本来の株価であると想定すると、株価はそれに戻ろうとすると考えられます。

適用してみた銘柄で、特徴的だったものをあげます。
その一つが、ENEOSホールディングス(5020.T)です。
![5020.Tkalman-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638077/d88f8652-53ea-01ce-d2e8-7d1c6652e948.png)![5020.Tkalman-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638077/2ba47b8b-3405-fc7f-e6c0-92fbdbb30431.png)![5020.Tkalman.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638077/26ea260a-7bd5-119f-8c8b-e11520cffda5.png)

一見何かわからないのですが、フィルターに当てはめ始める時期が異なります。
2018年の12月ごろには、トランプ政権による影響で株式市場全体が急落し、2020年の2~３月頃には、コロナの影響で株価が急落しています。
これらのイベントは、外れ値もいいところなので、いきなりカルマンフィルタの推定が大きくずれてることがわかります。
なので、それぞれの急落のイベント後からまたカルマンフィルタを適用してあげることで、比較的良い推定ができているとわかります。

## 結論
特に大きなイベントが起きなければ、一つの指標（特に買いを入れるときの）として使えると思います。
個人的には、ある時点のカルマンフィルタの値と株価の中間まで上がると考えて他の指標も合わせて買いを入れてます。
ただ、株価が大きく変化した時は適用する初期値をずらさないとまずいでしょう。

## 追加
デイトレでも使えるんじゃないかなと思ってます。
むしろデイトレの方が値動きは正規分布に近そうなので...
何か意見があれば教えていただけるとありがたいです。

あとこのカルマンフィルタは、そのままロボットの方に利用できます。
[エラー対応]Could not find (GEM-XXXXX) in any of the sourcesってLOGに現れた時の対策

docker-composeを使用して、up -dをしても、すぐにExitedされる。

原因は、GEMを更新する必要があった。
対策は、```bundle update```を実行して、再度up -dする。

GEMが最新版になっていなかったために、インストールエラーが発生していた。
なので、http://rubygems.org/ にアクセスして、問題になっているGEMのバージョンを確認する。

Gemfileのバージョンを書き変え、更新を行う。


参考にさせていただいた記事
https://qiita.com/jnchito/items/44ab1df134369ed76911
MySQLのトリガーってなんなん？

##沈黙？それが正しい答えなんか？

ぼく「つまり、トリガーっていうのがストアドプロシージャーってことなんですか？」

先輩「・・・・・・。」

ぼく「(・・・沈黙？それが正しい答えなんか。)」
ぼく「(いや、流石にそれが答えじゃないことぐらいは分かるで・・・。)」
ぼく「(多分、エンジニアに必要なのは洞察力やということを暗に教えてくれてるんやろうな・・・。）」
ぼく「(ほんまにええ先輩やで！)」
ぼく「わかりました！とりあえずやってみます！」

先輩「はい。」

##とにかく調べてみる。

ぼく「ほーん・・・。」
ぼく「トリガーいうんはDBのテーブルにあるデータが更新されたときに走るプロシージャのことなんか」
ぼく「データの更新ってINSERT,UPDATE,DELETEが対象になるんやな。」
ぼく「プロシージャってそもそもなんやねん。」
ぼく「戻り値のない関数のことか、草属性のポケモンと名前似てるやん。」
ぼく「てことは、対象のテーブルのデータが更新されたタイミングにトリガーを設定すれば自分の更新したいテーブルに何かできるってことなんか。」
ぼく「で、ストアドプロシージャーはなんや・・・。」
ぼく「複数のSQLを一つにまとめてRDBMSに、この場合はMySQLやな？そこに保存して実行できるもの。」
ぼく「めっちゃ便利やん。」

##タイミングとかある。

ぼく「データ更新のタイミングいうけど、更新する前と後があるやん・・・。それも指定できんのかな？」
ぼく「ふんふん。BEFOREとAFTERでトリガーの起動タイミングを指定するねんな。」
ぼく「それで？データ更新は起動タイミングを記載した後にINSERT,UPDATE,DELETEのどれかを指定すると・・・。」
ぼく「対象となるテーブルはどこで設定すればええんや？」
ぼく「データの更新を記載した後にON 対象となるテーブル名みたいな感じで書くねんな。」
ぼく「で、使ってるのはMySQLやからFOR EACH ROWとその後に書くと・・・。」
ぼく「なるほどね。とりあえず作ってみるか。」

```
DELIMITER //
CREATE TRIGGER test1
BEFORE UPDATE ON items
FOR EACH ROW
BEGIN
	CALL 呼びたいストアドプロシージャー(引数);
END
//
DELIMITER ;
```

ぼく「これでitemsテーブルを更新するとストアドプロシージャーが自動で実行されんのか・・・。」

##トリガーの実行

ぼく「トリガーを実行するためには、自分で設定したテーブルの更新をしたらええねんな。」

```
UPDATE
	items  
SET 
	value=100
WHERE
	Items.id = 1;
```

ぼく「おお、ほんまにトリガーが起動して、自分が呼び出したいストアドプロシージャーが動いてるで！」

##トリガーの削除

ぼく「削除したいときは、DROP TRIGGERに自分が作成したトリガーを指定するねんな。」

```
DROP TRIGGER test1;
```

ぼく「トリガーと結びつけたitemsテーブルが削除されたときもトリガーは、一緒に削除されんのか。」

##ストアドプロシージャーとトリガーの違い

ぼく「トリガーで設定したタイミングにストアドプロシージャーを動かせるようになったで！」
ぼく「トリガーもプロシージャーやし、ストアドプロシージャーもそうやん・・・。」
ぼく「データベースで更新タイミングがあったときに実行されるストアドプロシージャーのことを・・・。」
ぼく「トリガーと呼ぶ。」
ぼく「先輩の沈黙もあながち答えとして間違ってないやん」

終わり
MacでEmacsを使う時のtips

[Emacs Mac Port版](https://github.com/railwaycat/homebrew-emacsmacport) emacs-27.1-mac-8.0 を使用しています。

# MacOSのキーボードショートカットに合わせる

* Macのアプリケーションには Cut, Copy, Paste, フォントサイズ変更など command キーを使った標準的なショートカットがあるので、Emacsもそれに合わせます。
* command キーを `super` にするので、 `meta` は option キーと function キーに割り当てています。

```
(when (equal window-system 'mac)
  (setq mac-function-modifier 'meta)
  (setq mac-option-modifier 'meta)
  (setq mac-command-modifier 'super)
  (global-set-key (kbd "s-x") 'kill-region)
  (global-set-key (kbd "s-c") 'kill-ring-save)
  (global-set-key (kbd "s-v") 'yank)
  (global-set-key (kbd "s-a") 'mark-whole-buffer)
  (global-set-key (kbd "s-s") 'save-buffer)
  (global-set-key (kbd "s-z") 'undo)
  (global-set-key (kbd "s-+") 'text-scale-adjust)
  (global-set-key (kbd "s--") 'text-scale-adjust))
```

# Finder

* ファイルのアイコンを Emacs にドラッグすると、次のような動作になります。
    * Dired mode のバッファにドラッグした場合は、そのファイルを Dired で表示しているディレクトリにコピーします。
    * それ以外の場合は、そのファイルを Emacs で開きます。
* Emacs で表示中のファイル(を内包しているフォルダ)を Finder に表示させたい時は、 `M-!` (shell-command)で `open .` を実行します。

# Mail.app

* Mail.app で表示されているメール（本文だとテキスト選択になるので、ヘッダのところ）を Emacs にドラッグすると、そのメールのメッセージIDが挿入されます。
  * それを編集して `(shell-command "open メッセージID")` としておけば、行末で `C-x C-e` を打つとメールを開くことができます。

# Chrome

* Chrome のテキスト入力欄の内容を Emacs で編集できます。（Mac限定ではないですが、ついでに書いておきます）

* 準備として次の二つが必要です。
    * Chrome の拡張機能 [Edit with Emacs](https://chrome.google.com/webstore/detail/edit-with-emacs/ljobjlafonikaiipfkggjbhkghgicgoh) をインストールする。
    * Emacs のパッケージ edit-server をインストールする。

* 実際に編集する時は次のようにします。
    1. Edit with Emacs にサイトの読み取り許可を与えます。設定によって、「拡張機能をクリックしたとき」とか「すべてのサイト」とか選べます。
    * Emacs で `M-x edit-server-start` を実行します。
    * テキスト入力欄の右下に Edit というボタンができるので、これをクリックします。
    * Emacs で新しいバッファが開き、テキスト入力欄の現在の内容が挿入されます。
    * Emacs でテキストを編集し、 `C-c C-c` を押します。
    * テキストが Chrome の入力欄に書き戻されます。

# QuickLook

* Dired mode でスペースキーを押すと QuickLook でプレビューを表示するようにできます。[What are the advantages of Emacs for Mac OS X users? - Quora](https://www.quora.com/Emacs/What-are-the-advantages-of-Emacs-for-Mac-OS-X-users)の Zhou hai Tao さんの回答のところにコードがあります。
bubbleでgoogle map api で詰まったのでメモ

bubbleで地名を入力したときに、存在するplaceを候補に出し、データに追加したくてgoogle map api を導入しようとしたら色々てこづったのでメモします。

8/15追記
データベースの型をtextにしていたのですが、geographip addressにしたらうまくいきました

keyの設定は[公式マニュアル](https://manual.bubble.io/working-with-data/setting-up-google-api-keys)を参考にしました。

エディター画面は以下のような感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515470/a5cc3cb8-247e-0c7a-56a5-354161427698.png)

searchBox でGeographic placesを選択すると入力したテキストに関連のあるplaceが表示されるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515470/2339d433-6d50-dfb9-f015-d4798ad0d918.png)

ここで東京タワーを選択した際のvalueなどは以下のようになりました。
した2つは意味が分からないのでテストとして表示してみましたが何も表示されませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515470/77a9960f-3f33-635e-bc6b-c98573b5e089.png)

それだけでなく謎のエラーも表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515470/9ebb346c-711c-b366-2b77-ba91de4026e1.png)

ここで、
1.「東京タワー」の値のみを取り出してデータベースに登録
2.データベースの「東京タワー」から、住所を検索してマップにピン表示＋住所表示
を行いたいが、わからない。

２に関して、serchbox内の文字列とvalueの文字列が違っていることが確認できる。
その影響なのかはわからないが、valueをデータベースに追加後、取り出してマップに表示しようとするとうまくいかない

左のマップがsearchboxから直接値を当てはめたもので、ピンが正しく打たれていることがわかる
右のマップはデータベースに保存したserach box's value を取り出して表示させようとしているが、うまくいっていない。
右のマップの下の「日本、・・・」は右マップのmarker addressに入れている値である。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515470/89ae5a33-26ae-aadc-7519-307aedd284da.png)
【Pythonで作ってみた】XMLデータ増殖ツール

テストデータを楽に作成したいので、大量のテストデータ作成用ツールをpythonで作成しました。
具体的にはtsvにファイル名とファイルの内容を格納しておき、これを読み込んで、xmlのテンプレートの対象のタグだけ書き換えて一括でテスト用のxmlファイルを出力するものです。

##入力ファイルの準備

１．sample.tsv（出力する際のファイル名と書き換え部分の配列）
　入力ファイルのサンプルです。

```
FILENAME	SENTENCE
sample_1.xml	ice cream
sample_2.xml	chocolate box
sample_3.xml	candy bar
```
２．templete.xml（出力するための元ネタとなるXML）
　出力用テンプレートのサンプルです。

```
<root>
  <Text>sweets</Text> 
  <originalText>sweets</originalText> 
  <head>sweets</head> 
</root>

```
##XMLデータ一括出力用ツールのソース

３．exportToXML.py

```
#!/usr/bin/env python 
import csv 
import xml.etree.ElementTree as ET 
import shutil 
import os 
import glob 
 
 
#出力フォルダの初期化 
for file in glob.glob('C:\\tools\\output\\*.xml', recursive=True):
    os.remove(file) 
    
#変数の宣言ファイル名と書き換えのワードを取得 
#ファイル名 
fName = "" 
#と書き換えのワード 
fDoc = "" 
 
#インプットとなるtsvファイルを開く 
tsv_file = open(r"C:\\tools\sample.tsv", "r", encoding="utf-8", errors="", newline="" ) 
#リーダーでファイルを解析する 
f = csv.reader(tsv_file, delimiter="\t", doublequote=True, lineterminator="\n", quotechar='"', skipinitialspace=True) 
data = [ v for v in f] 
 
for i in range(len(data)): 
    #ヘッダーは読み込まない 
        if i > 0: 
            fName = (data[i][0]) 
            fDoc = (data[i][1]) 
            fPath = 'C:\\tools\\output\\' + fName 
            #テンプレ―トをコピーする。 
            shutil.copy('C:\\tools\\templete.xml',fPath) 
            tree = ET.parse(fPath) 
            root = tree.getroot() 
            for name in root.iter('text'): 
                name.text = fDoc 
                print(name.text)
            for hname in root.iter('head'): 
                hname.text = fName 
            tree.write(fPath, encoding='UTF-8') 
        
     
```

##実行方法

４．上記のファイル(sample.tsv、templete.xml)を`C:\tools`に配置し、その配下に`output`フォルダを作成します。
　　<img width="581" alt="py7.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264141/a03258b6-a2b5-1c6d-f5b3-b914ef49e55e.png">

　python実行環境で３のソースを実行してください。
　環境作成・実行方法はこちらにまとめてあります。
[　■Python（anaconda）の開発環境構築手順（SpringToolsSuites ）_2020.6時点](https://qiita.com/kankigyo2/items/137689bf86a4879337e6)


##出力結果
tsvファイルの一覧の通り、テンプレートの内容を変更して一括でファイルを出力する事ができました。
　　<img width="526" alt="py8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264141/99eb161b-f4e3-a79c-f2f7-053c3765091d.png">

以上です。
Adobe の MIP プラグインについて

# 初めに
Adobe 社の Acrobat では MIP プラグインと組み合わせることで、Office ドキュメントのように AIP で保護されたドキュメントの閲覧や (Acrobat DCの場合) コンテンツの修正が可能となります。
(もちろん AIP ビューワーでの閲覧も可能です。最新の Edge ブラウザでも閲覧できます) 

# 対象バージョン
上記のプラグインがサポートされるバージョンは以下のラインナップとなっており、Adobe Acrobat 2017 はサポートされておりません。
[https://helpx.adobe.com/jp/acrobat/kb/mip-plugin-download.html](https://helpx.adobe.com/jp/acrobat/kb/mip-plugin-download.html)

Acrobat DC Continuous
Acrobat Reader DC Continuous
Acrobat 2020 Classic
Acrobat Reader 2020 Classic

# ログファイルはどこ？
ここあたり
プロテクトモードの時
%userprofile%\appdata\locallow\Microsoft\RMSLocalStorage\mip\logs
非プロテクトモードの時
%LocalAppdata%\Microsoft\RMSLocalStorage\mip\logs

# キャッシュファイルはどこ？
ここあたり
%USERPROFILE%\AppData\Roaming\Adobe\Acrobat\DC\Security

# 認証情報のクリア
[環境設定] → [セキュリティ] → "Microsoft Azure Information Protection"
[記憶したアカウント情報をクリア] でOK
【Rails】開発者とユーザー画像の保存場所と、使い方をまとめました


# 画像の保存場所


|保存するファイルの用途|保存場所|
|:---|:----|
|開発者が用意するファイル|app/assets/images配下
|ユーザーがアップロードしたファイル|public配下




# HTMLから、画像を呼び出したい時

```ruby:html.erb

# app/assets/images/logo.pngの場合
<%= image_tag 'logo.png' %>

<img src="/assets/logo.png" alt="" >
```

```ruby:html.erb
# public/logo.pngの場合
<%= image_tag '/logo.png' %>
```

# Sassから、画像を呼び出したい時

```scss:

// app/assets/images/logo.pngの場合
h1 {
  background-image: image-url('logo.png')
}
```
サービスプログラムとは？

#サービスプログラムとは

簡単にいうと、**OSだけでは実現できないサーバーの機能を提供してくれる「サーバーそのもの」ともいえるプログラムのこと。**

前提として、サーバーは複数のクライアントPCに向けて、必要な機能を提供するコンピュータである。

- PCに不足したハードディスク容量を補う「ファイルサーバー」

- PCから直接送信できないメールデータを集約する「メールサーバー」

- PCでは公開できないコンテンツを公開するのが「webサーバー」。

上記のような機能を、サーバー用語で**「サービス」**と呼ぶ。
例えばファイルサーバーはファイルを共有するのでファイル共有サービス、メールサーバーは電子メールの送受信を受け付けるので「webサービス」という具合である。

**※ 一般にはサーバーそのものを「〇〇」サーバー、サーバーで提供する機能を「〇〇」サービスと呼ぶ。**

また、一口にサービスプログラムと言ってもその種類はいくつかある。

- ex) メールサーバー機能を提供するサービスプログラム：「sendmail」、「qmail」、「Posfix」
iOSデータストレージガイドラインを翻訳してみる

# はじめに
[iOS Data Storage Guidelines](https://developer.apple.com/icloud/documentation/data-storage/index.html)を翻訳してみます。
このガイドラインに沿っていないシステムだと、アプリ審査の時に **<font color="red">リジェクト</font>** される恐れがあります。

# 翻訳

| 項番号 | 説明 | iTunes, iCloud バックアップ対象 |
|:-----------|:----|:-----------------------------|
| 1 | **/Documents** ディレクトリに、ユーザが作成したファイルやその他のデータ、またはアプリによって再作成できないデータのみを保存する | **<font color="red">YES</font>** |
| 2 | **/Library/Caches** ディレクトリに再ダウンロードや再作成可能なデータを保存する。例としては、データベースのキャッシュファイルや、雑誌、新聞、地図アプリケーションで使用されるようなダウンロード可能なコンテンツ | **<font color="blue">NO</font>** |
| 3 | **/tmp** ディレクトに一時的にしか利用しないデータを保存する。利用後はアプリがファイルを削除する必要がある。 | **<font color="blue">NO</font>** |
| 4 | どのディレクトリにあるかに関係なく、 **「バックアップしないでください(do not back up)」** 属性を指定することで、ストレージが少ない状況でもデバイス上に残すべきファイルを指定します。 再作成可能でオフラインでの使用中に利用できることを目的としている。デバイス上のストレージ スペースを使用するため、アプリは定期的にこれらのファイルを監視し、削除する責務があります。 | **<font color="blue">NO</font>** |

# まとめ
上記4項目に則ったアプリ設計をしていないアプリはリジェクト対象になる恐れがあります。

# 引用
* https://developer.apple.com/icloud/documentation/data-storage/index.html
* https://ja.wikipedia.org/wiki/Apple_File_System
* https://qiita.com/nnsnodnb/items/13642c4a8d55641f893e
* https://gist.github.com/y-takagi/9f2cea659fb3f55b56aa04530bf0af39
Debugging Gatling HTTP Requests with Logback

Gatlingの送信リクエストDebug、いくつか試したがlogbackでTRACEレベルをファイル出力するのがベスト。[Gatling公式ページ(Logback)](https://gatling.io/docs/current/general/debugging/?highlight=logback%20xml#logback)に従いlogback.xmlに次の定義を追加するだけ。

`GATLING_HOME/conf/logback.xml`

```xml
<configuration>

  <!-- このブロックを追加 -->　　
  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>PATH_TO_LOG_FILE</file>
    <append>true</append>
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern>
    </encoder>
  </appender>

  <!-- このコメントを外す-->
  <logger name="io.gatling.http.engine.response" level="TRACE" />

  <root level="WARN">
    <appender-ref ref="CONSOLE" />
    <!-- これを追加 -->　　
    <appender-ref ref="FILE" />
  </root>
```

これでgatlingを回すと、PATH_TO_LOG_FILEに次のリクエスト情報が出力される

- リクエストURL
- リクエストheader
- リクエストbody
- レスポンスheader
- Gatling sessionデータ

必要な情報は全てこれで取得できる。おわり
AWS初学者が往くAWS CLF(クラウドプラクティショナー)合格体験記

#はじめに
この記事はAWS実務未経験(AWSとは間接的に関わったことがあるが構築は未経験)のインフラエンジニアが約1ヶ月でAWS CLF(クラウドプラクティショナー)に合格体験記になります。
#経歴
###・インフラエンジニア歴
　1年4ヶ月
　専門学生の頃から計算するとインフラに触れている期間は3年ほどになります。

###・実務経験
　ネットワーク 1年4ヶ月
　サーバ(Linux) 1ヶ月

###・資格取得前のAWS知識
　VPC、EC2、セキュリティグループを少し使用したことがあるレベル
　RDS？Route53？なにそれおいしいのレベル
#受験した経緯
こちらの記事を書いた際に関わっていた案件で間接的にAWSに触れてみて、AWS凄すぎだろって思ったことと、クラウドがあったらオンプレミスの仕事減ってくるんじゃね？という危機感から自分の得意分野を増やすために受験しました。
[AWSとのVPN接続 ネットワーク側の冗長化について](https://qiita.com/Mattun_0226/items/1155a7843a577cdc60df)
#学習教材
###・参考書
　[AWS認定資格試験テキスト AWS認定 クラウドプラクティショナー ](https://www.amazon.co.jp/AWS認定資格試験テキスト-AWS認定-クラウドプラクティショナー-山下-光洋/dp/4797397403)
　本屋さんで2800円くらいで購入しました。
###・Udemy
　[この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集（7回分455問）](https://www.udemy.com/course/aws-4260/)
　こちらの教材は割引キャンペーン中に1700円くらいで購入しました。
###・AWSホワイトペーパー
　[アマゾンウェブサービスの概要](https://d1.awsstatic.com/whitepapers/ja_JP/aws-overview.pdf?did=wp_card&trk=wp_card)
　[AWS料金体系の仕組み](https://d1.awsstatic.com/whitepapers/ja_JP/aws_pricing_overview.pdf?did=wp_card&trk=wp_card)
　[AWS Well-Architected フレームワーク](https://d1.awsstatic.com/whitepapers/ja_JP/architecture/AWS_Well-Architected_Framework.pdf?did=wp_card&trk=wp_card)
　ホワイトペーパーのこの記事は軽く読みました。
#学習スケジュール
###・7/20~7/27(1週間)
　参考書を軽く一周読む→大体2日間くらいで読み終わりました
　参考書をじっくり読む→読みながら説明が理解しにくかったものはネットで検索し、理解を深める
###・7/27~8/3(1週間)
　Udemyで問題を解きつつ、分からなかったサービスについて調べる→1周目は正答率60%~70%でした
　他の方の試験合格体験記などを読みつつ、試験への心構えをする
　→ここでAWSホワイトペーパーを読んだ方がいいことを知る
###・8/3~8/10(1週間、試験当日まで)
　Udemyで2周目を行い間違えていた回答について、何故間違えていたのか解説を読んで理解を深める
　上記で紹介したホワイトペーパーを軽く読む
　試験当日(8/10)は受験時間1時間前くらいまで参考書を読んでいました
#試験当日
###・当日の持ち物
　ピアソンVUEで受験しました。(このご時世なのでマスク必須です)
　当日は本人確認書類を2点持って行ってください(免許証、保険証など)
###・心構え
　「ここまで学習して落ちるはずが無い！」と自分を鼓舞して受験してきました(自分に自信を持つことは大事です)
#試験結果
　![点数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612471/f3f40c7d-e7d6-aeb4-29c4-f9eff1c2b2bc.png)
　試験終了後モニターに合格の2文字が出ていた時は安心しました
　試験終了から1~5営業日の間でスコアが送られてきます
　700点台だと思っていたので意外と点数が高くて驚き・・・
#感想
自信を持って「これが正解だ！」と答えられたのは40問くらいだと思います。15問くらいは消去法で問題文で問われている内容と一致しない物は消して残ったものを回答、全く分からない問題は10問くらいでした。
試験の難易度的にはどのサービスが何をするのか、AWSの設計の考え方などを理解していれば合格できると思います。

Cisco系の資格(CCNA)やLPICを受験したときは日本語が滅茶苦茶で読解するのが大変でしたが、AWS CLFは普通に読めて内容が理解できる日本語だったのが一番の感動ポイントでしたw
#今後の目標
今後はもっとAWSの知識を深めるためにハンズオンやAWS SAAの取得をしようと思います。
AWSを使用したインフラ構築などの仕事に携われるように頑張らねば・・・
来月にはAWS Summit Onlineがあるのでそちらも視聴していきたいと思います。
aws 不正使用の恐れあり。ポリシー付与され権限をdenyされた件

（自分用）
ある日メールがawsから届く

8月7日
> Hello,
We have detected activity that indicates your AWS account has been compromised. Please take the necessary steps to re-secure your account. 
To protect you from unauthorized usage and charges, failure to reply or follow these steps within five days may result in the suspension of your account, and disruption of AWS service.
To re-secure your account, I have included below the necessary steps for you to re-secure the account. Please bear with us, as this is a long email, but rest assured every step in it is important to your account's security. You'll need to complete the following:

* Update your root account password.
* DELETE the exposed key


８月８日
> Hello, 
We have detected activity that indicates your AWS account has been compromised. Please take the necessary steps to re-secure your account. We have been unable to reach you by phone. 
For your convenience, I’ve summarized the information in this email. 


8月11日
> Hi there,
We've recently tried to contact you via email and telephone with regards to your account compromise.
Please review the correspondence sent to you via email which includes steps required to securing your account.
We are going to resolve this case for administrative reasons.
Please feel free to reach out to us via this case at any time.

8月13日にメールの内容を把握。
メールの通りに、
### ルートユーザーパスワード変更
### IAMユーザーアクセスキーを変更。再設定。

# 結果、アラートが消えない
対応したのが５日経過していたから？

# AWSサポートにメールする。
後日更新

８月13日メールが届く
> Dear AWS Customer,
Thank you for deleting your compromised AWS Access Key(s) of account ending with 0000. Please ensure that no unauthorized resources remain on your account, and we ask that you pay special attention to IAM users and EC2 instances. Please take steps to prevent any new credentials from being published in this manner again.
Thank you for trusting your business to AWS. We work hard to keep you safe!
Sincerely,
Amazon Web Services
This message was produced and distributed by Amazon Web Services, Inc. and affiliates, 410 Terry Ave. North, Seattle, WA 98109-5210.

これからは注意してください的な

# それでもアラートは消えない
<img width="965" alt="スクリーンショット 2020-08-14 9.05.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449720/964ca287-e9e1-3a8e-e930-115fe3ac7497.png">

### AWSサポート - Your support cases - Detailsで確認すると、

AWSExposedCredentialPolicy_DO_NOT_REMOVEポリシーが付与されて、
権限がdenyになるようになっていた。AWSすごすぎる
<img width="867" alt="スクリーンショット 2020-08-14 9.27.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449720/2affbe5b-9712-a888-3190-11b26affdc2c.png">





原因は、rails app にて、fog gem を利用してs3にアクセスするように仕込んだアクセスキーを環境変数化しないままpublicなgithubにあげてしまったことによる。

自業自得だなー。

漏洩したキーを変更。IAMユーザー削除、再作成。ルートユーザーパスワード変更。を行う

 - AWS_ACCESS_KEY_ID（再発行）
 - AWS_SECRET_ACCESS_KEY（再発行）
 - ルートユーザパスワード変更
 - IAMユーザ削除
 - IAMユーザ再作成
 - ポリシー削除
 <img width="905" alt="スクリーンショット 2020-08-14 9.32.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449720/9a8dfc2c-dc1c-1acd-9749-02a8761ca134.png">
github-pagesにnext.jsをdeployすると写真が読み取れなくなる事についての対処

#nextの写真が表示できなくなる事についての対処法
github-pagesにnextでdeployすると写真が表示できなくなる事についての対処法
ネットに日本語の情報がほぼほぼ無かったので、詰まった誰かの為に、、残します、

```:自分のファイル構成
.babelrc.js
.github
.gitignore
.next
env-config.js
next-env.d.ts
next.config.js
node_modules
package-lock.json
package.json
pages
public
README.md
tsconfig.json
```

以前はstaticというフォルダに画像などを入れるルールだったが
どこかのタイミングで変更になりpublicというフォルダに画像などの静的ファイルを入れます
私は、sitemap.xmlや引用する静的な物はなんでも入れました。


```:public
-images
  -main.jpg
  -header.jpg
-robots.txt
-sitemap.xml
-icon.jpg
```

publicフォルダ内は引用できるようになるが
srcの書き方は

```
<img src="/repository-Name/images/main.jpg" />
<img src="/repository-Name/icon.jpg" />
```

＊repository-Nameを各自のリポジトリの名前に変えてください

と書く必要があり、リポジトリ名/publicフォルダを飛ばして/その中のファイルを選択する

ただ、この書き方には難があり、ファイルの構造によって本番環境と開発環境で挙動が変わり、
開発時には画像を表示させることができない。

#解決策
この変数を使う

```
process.env.NODE_ENV　=== 'production'
```

この変数は、開発環境と本番環境を判別してboolean型で返してくれる
本番環境だとtrueが開発環境だとfalseが返ってくる。

```:env-config.js
const prod = process.env.NODE_ENV === 'production'

module.exports = {
  'process.env.BACKEND_URL': prod ? '/repository-Name' : '',
}
```

このようにして
本番環境だとリポジトリ名　　'/repository-Name'
テスト環境だと空白　　　　　'　'
が返ってきて、それを process.env.BACKEND_URL の変数に格納し外部にエクスポートしている。

それをindex.jsxなどにインポートして

```:index.jsx
const dir = String(process.env.BACKEND_URL)

<img src={dir+'/images/main.jpg'} />

```
 
このようにすることで
開発環境時は、'/images/main.jpg'、
本番環境では、'/repository-Name/images/main.jpg'
を作ることができ、本番環境と開発環境どちらでも写真を表示できる。
Node.jsのインストールからReactNative+Expo＋Typescript環境を構築しようね(2020/08/13 LTS対応)

#初学者との開発プロジェクト始動！

初学者との開発プロジェクトを始めるにあたって
手順書をざっくり作成したのでここに書き留めます。

##概要
- Node.jsインスト―ル
- Expoインスト―ル
- ReactNative+Typescriptでプロジェクト作成

##バージョン(記事作成時LTS)

| -         |     Version |
|:----------|------------:|
| Node.js   |     12.18.3 |
| npm       |      6.14.6 |
| expo      |      3.24.0 |

##Node.js
①最新Nodeのインストーラをダウンロード
https://nodejs.org/ja/download/releases/

②実行
node.jsがインストールされているのでアプリ実行
→真っ黒の画面が出たらOK（以下でnodeと呼びます）

③確認
nodeにて「node --version」と入力してEnter
→v12.18.3と出力されたらOK

##次にExpo！！
###▼PC
①インストール
nodeにて「npm install -g expo-cli」と入力してEnter
→Errorが出なければOK

②確認
nodeにて「expo --version」と入力してEnter
→3.24.0と出力されたらOK

###▼スマホ
①アプリ
「Expo Client」をインストールしておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630810/705afeab-c79c-7256-9b2a-16091767bfae.png)

#最後にプロジェクト作成！
①開発用フォルダ作成
適当な空フォルダを事前に作成

②開発用フォルダに移動
nodeにて「cd ○○○」と入力してEnter
　※○○○には①で作成したフォルダへのパスを指定

③プロジェクト作成
nodeにて「expo init ○○○」と入力してEnter
　※○○○には作成したいプロジェクト名を指定
　※以下templateにてblank（TypeScript）を指定
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630810/4d86242d-1c69-2232-5d24-4a1f6b4bfeb9.png)


④確認
nodeにて「expo start」を入力してEnter
→QRコードが表示されるのでスマホで読み取る
→「Open up App.tsx to start working on your app!」と表示された白い画面が出れば完了！お疲れ様でした！

##参考URL
https://nodejs.org/ja/download/
https://tech.fusic.co.jp/posts/2019-10-30-react-native-expo-typescript-native-base/
https://qiita.com/jeq/items/f16594ec99d675bed300
https://stackoverflow.com/questions/52476154/uninstalling-expo-cli
Passing 'const char *' to parameter of type 'char *' discards qualifiers警告の対処法

>Passing 'const char *' to parameter of type 'char *' discards qualifiers

このような警告がコンパイル時に出力された時の対応です。

## 必要なのにconst宣言していない

以下のソースの場合、今回の警告が出力されます。

```objective_c
typedef void (*callback__)(char*);
//~~~~~略~~~~~
callback__ callback;
//~~~~~略~~~~~
const char *path = [url UTF8String];
callback(path);
```

`UTF8String`関数の戻り型が`const char*`ですので、`const char*`で受け取る必要があります。


正しくは以下のように、`const char*`を受け取る所でconst宣言します。

### 誤

```objc
typedef void (*callback__)(char*);
```

### 正

```objective_c
typedef void (*callback__)(const char*);
```
3つの値の正誤を確かめる条件式~演算子,論理積~

【概要】
---------------------



<b>1.結論</b>

<b>2.なぜ単純にA=B=Cではいけないのか</b>

<b>3.ここから学んだこと</b>

<b>4.補足</b>

1.結論
---------------------
```ruby
if 変数[A] == 変数[B] && 変数[A] == 変数[C]
```



2.なぜ単純にA=B=Cではいけないのか
---------------------
ではここで、 
 
```ruby
if number[0] = number[1] = number[2]
```
にしたらいいのではないかと思うのですが、それではうまくいきません。
[0]と[1]と[2]がバラバラの数字をとってきた場合でもtrueを返します。
そもそも”=”が数学的意味のイコールではなく、
代入の意味となってしまうので、[2]➡︎[1]➡︎[0]へ代入するという意味になります。
なので、数が違ってもtrueを返すということになります。



また、

```ruby
number[0] == number[1] == number[2]
```

になりますとsyntaxerrorが起きてしまします。
構文エラーなので機械が上の式を認識しておりません。
おそらくA==Bだけにしか対応できないものと思われます。

rand(0)で強制的に同じ数にしてもsytaxerrorとなることから
”==”はやはりA、Bと二つの値（式）にしか使えないことだと思われます。



3.ここから学んだこと
---------------------
i)論理積をうまく使うことで、
　３つの数字をイコールにすることができることを知りました！

ii)自分でいろんなことを試す癖がつき、
論理積以外にも新たな知識を得ることができました！



4.補足
---------------------
丁寧に書くと、下記のようになります。

```ruby
class Machine
  def game_play
    number = []
    3.times do 
      number << rand(0..9)
    end
     puts "マシーンの数字は#{number.join}です！"




      こちらの式です➡︎ if number[0] == number[1] && number[0] == number[2]




       puts "大当たり"
    else
      puts "はずれ"
    end 
  end
end
```


==とは、A==Bであれば、"A=Bが等しければtrueを返す"という意味です。
&&とは、A&&Bであれば、"AかつB"であればtrueを返す"という意味です。
GitHubにアクセスしたらPornHubにアクセスしていた・・・？

`https://github.com` にアクセスしたら、pornhub[^1]にアクセスする方法を教えます。
ITオンチで君が嫌いな上司のPCをハッキングして、以下のようにすればいいゾ★
（ITオンチな上司がgithubにアクセスはしないと思いますが...）

[^1]: 海外のえっちなサイトです。ときどきMacにステッカーを貼っている人を見かけます...w

# 作業手順

- windowsの場合
    - `C:\Windows\System32\drivers\etc\hosts` を編集
- macの場合
    - `/etc/hosts` を編集

```bash:hosts
# 以下を追記
# 66.254.114.41はpornhubのグローバルIP
66.254.114.41 github.com
```

上記のように設定後、`https://github.com`にアクセスすると、pornhubが閲覧できます。
職場で見ちゃダメだゾ★

## ところでグローバルIPの調べ方

**ping**コマンドや、**traceroute(mac|linux) / tracert(win)**コマンドなどを使うとグローバルIPが調べられます。
自分の会社のIPを調べたいときにこのコマンドを思い出してみて下さい。

# 最後に

**不正アクセス禁止法** という言葉を思い出しつつ、自身のhostsの設定を変更したら、問い合わせの順番はどうなるんだっけ、DNSよりも前に実行されるんだっけ...？などなどを思い浮かべながら、戯れてもらえるとよいのではないかと思います。

...

# 真面目な話
**hosts**を変更して、見に行くIPアドレスを変更することはよくあると思います。
例えばローカルでの開発と、検証用のサーバのIPアドレスを併記したhostsファイルを例に考えます。

```bash:hosts
# original-serviceというドメイン名を127.0.0.1に設定
# 【ローカル開発環境】
127.0.0.1 www.original-service.com

# original-serviceというドメイン名を192.168.0.1に設定
# 【検証環境】
# 192.168.0.1 www.original-service.com
```

上記のような設定はよくあると思うのですが、ローカル環境と検証環境にhostsの設定を記載してあります。
大事なのは、ローカル・検証をともにコメントアウト（無効化）すると、DNSへの問い合わせとなり、結果としてwww.original-service.comというドメインに紐づくグローバルIPを返すように要求を行います。

hostsはDNSよりも優先して問い合わせを行うように指定するので、「ローカル向いてない？」「デモ向いてた！」みたいな不穏な動きをしているときには、hostsのことを思い出してあげるとよいでしょう。
２つの画像をイメージハッシュで比較する

# はじめに
２つの画像の同一性をイメージハッシュで比較方法を確認する。

# イメージハッシュについて
一般にハッシュは、文字列からハッシュ関数を使って得られた値を指す。
画像でも同じようなことができて、要約した値が生成できる。
そのため大量にある画像をイメージハッシュを使うことで、類似したパターンの画像を絞り込むことが可能。

ハッシュ関数は複数あるので、比較するためには１つに絞りこむ必要がある。
参照:
https://qiita.com/mamo3gr/items/b93545a0346d8731f03c

# ２つのイメージハッシュを比較する
ハッシュの距離を計算するには、排他的論理和（XOR）をとり、「1」をカウントする。

ソースコード例（Python）

```pytyhon:sample.py
hash_a = 'b69cbd89090b8f8e'
hash_a_value = int(hash_a, 16)
hash_b = 'b69c3d89090b0f8e'
hash_b_value = int(hash_b, 16)

hamming_distance = bin(hash_a_value ^ hash_b_value).count('1')
print(hamming_distance)
```

**上記ソース内のハッシュのハミング距離を計算する。**

hash_aを2進数に変換すると **1011011010011100101111011000100100001001000010111000111110001110**
hash_bを2進数に変換すると **1011011010011100001111011000100100001001000010110000111110001110**
排他的論理和をとると　　　**0000000000000000100000000000000000000000000000001000000000000000** となる。
1の数は2となり、ハミング距離は **2** になる。

# ハミング距離による画像の類似度
ハミング距離が10以下の場合、ほぼ同一画像となるが確実に同一とは言えない。
もし同一であることを確定させるのであれば、別の処理で確定させる必要がある。

# まとめ
画像の同一性を保証するには、イメージハッシュのみでは不足している。
画像の特徴量などを使う必要がある。

比較する画像数が少なければ、画像の特徴量を使って比較で事足りるが、
数千万画像などに対して比較するのであれば、イメージハッシュで比較対象を絞り込むのも有りではないかとおもう。

特徴量などの記事
https://qiita.com/hmichu/items/f5f1c778a155c7c414fd
https://qiita.com/hitomatagi/items/caac014b7ab246faf6b1
自作コンピュータの作り方 第5話

# 第5話　ゴールまでの道筋　

## 前回までの話題
**"自作の組込みマザーボードを作って自作のコンピュータを作りたい"**

第１話は以下より
https://qiita.com/nonNoise/items/c4800ac35c529c04e941
第2話は以下より
https://qiita.com/nonNoise/items/01427a281ceb7bdc0238
第3話は以下より
https://qiita.com/nonNoise/items/e4bcb08c4e86ab87d0d5
第4話は以下より
https://qiita.com/nonNoise/items/2130af358abaac70f270

# 現在の開発状況

現在開発中のボードは、**SAM9X60**　になります。

|　　　　　　　　 項目|           スペック |  
|:-----------------|------------------:|
|CPU 　　　　   　　|  AT9シリーズ ARM926EJ-S |
|ビット幅／コア数　　|        32bit 1コア|
|クロック 　　　　  |            600MHz|
|RAM 　　　　    　|         最大128MB|
|ROM 　　　　    　|      無し（外部回路にて）|

狙ってたCPUの中では**最弱**で**古いコア**を使っています。

ただ、チップの**生産は2020年**という、**我生きてたのか！**事案である。

とりあえず、回路図が出来、基板の配線を進めているが、先が長い気がしますので、
工程についてまとめておきます。

# 自作コンピュータを作るまでの工程

とりあえず、**自作コンピュータ**への工程をまとめてみる。

### ボードの作成

・回路の作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/03050ca0-8b3a-3955-4c8e-c7f67c7c41ec.png)

・部品ライブラリの作成　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/04865a15-7023-76e7-e223-1a53f324babf.png)

・部品の配置
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/c38f16c6-9dcd-812a-826d-daf51f14c707.png)

・基板配線　　　　　　　＜－★今ここ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/febb8fdc-43df-03b3-c48b-79b08fe2e49f.png)


・基板発注
・部品実装
・電源投入

### ボード到着後の内容
・CPU内蔵Bootローダーの動作確認
・評価ボード用のU-Bootのインストール
・評価ボード用のLinuxのインストール
・色々Linuxで遊ぶ

### カスタムボードへの道
・U-Bootのカスタム
・U-Boot用のデバイスツリーの確認
・Linuxのカスタム
・Linux用のデバイスツリーの編集
・動作確認
・必要ならばドライバ作成

### 自作コンピュータの完成
・オリジナルのU-Boot用のイメージファイル
・オリジナルのLinux用のイメージファイル
・オリジナルのボード
・オリジナルボードの販売開始！

正直、後半のU-BootカスタムやLinuxカスタムがものすごく難しいように思える。

通常は、**メーカーがある程度評価するためのOS**というものを用意しているが、
それは**メーカーの都合に合わせた物**だったりします。
その為、**必要ないのに宣伝のためについている機能**や、**需要が無いから削った機能**等があります。

その**メーカーが提供したもの**で満足する方は、正直**最初から評価ボードを買う**事が良いと思います。

ここは・・・**自分が使いたい機能を使うために作っている**という節があります。

**　CPUにはEthernet x2と書いてあるのに！
　　なぜボードには１ポートしかないのか！！
　　　2ポートあれば面白いじゃないか！！！**

とりあえず、ボードを作って動くのを確認したら・・・**共同開発者募集！**とかしましょうか。

今回のSAM9X60は**2020年登場**なだけあって、ネットの世界にもあまり情報が無いチップです。
なので、今触ると**世界中から興味を惹かれる**可能性があったりなかったり。

まぁ面白そうなので、この先も頑張っていこうかと思います～

# 次回は・・・

基板が届くまでないかなぁ。焦らず頑張ります～
Functions returning functionsを理解する

### 関数が関数を返すという内容です

まず、関数はオブジェクトなので、とても自由自在です。
関数を変数に格納したり、引数に渡したり、色々できちゃうということですね。

そして関数が関数返すということも出来ます。

「関数」だらけで、特に引数がどこに繋がってるのか混乱しますが、一つ一つ見ると意外とシンプルでした。

メソッドの内容：勝ってる動物によって異なる質問をする
名前はペットの名前です。飼い主に聞いてるイメージです。

```JavaScript:
function animalQuestion(animal) { //引数をanimalとしておきます
  if (animal === 'dog') { 
    return function(name) { //もし犬だったらconsoleにこの質問を表示
      console.log('How often do you walk for ' + name + ' ?');
    }
  } else if (animal === 'cat') {
    return function(name) { //もし猫だったらconsoleにこの質問を表示
      console.log('How many hours is ' + name + ' in outside?');
    }
  } else {
    return function(name) { //その他
      console.log('What does ' + name + ' like to do ?');
    }
  }
}
```

returnする関数は無名関数です。英語だとanonymous function。
その無名関数には name という引数を渡します。今回の場合はペットの名前に該当します。

```JavaScript:
var dogQuestion = animalQuestion('dog');
dogQuestion('Taro'); //結果： How often do you walk for Taro?

var catQuestion = animalQuestion('cat');
catQuestion('Maron'); //結果： How many hours is Maron in outside?
```
次に、動物がdogの場合の変数を定義し、そこにanimalQuestionを代入します。
その際、animalQuestionの引数に dog を与えます。（ifを機能させる為）
そのあと、定義したdogQuestionを呼び出すわけですが、既にanimalQuestionの関数が入ってます。
なのであとは returnする関数の name の部分に引数を与えるだけです。

```JavaScript:
dogQuestion('Ziro'); //結果: How often do you walk for Ziro ?
catQuestion('Momo'); //結果: How many hours is Momo in outside?
catQuestion('Koko'); //結果; How many hours is Koko in outside?
```
名前を変えるだけで、こんな感じになります。

もっとシンプルな呼び出し方があります。↓

```JavaScript:
animalQuestion('dog')('Taro'); //結果： How often do you walk for Taro?
animalQuestion('cat')('Maron'); //結果： How many hours is Maron in outside?
```

変数を定義する必要もないです！シンプルですね！

最初はどの引数に対して渡してるのか混乱するかもですが、慣れればとても便利そうです。