OmniAICreator/Qiita-1.07M huggingface dataset:
PHPUnitの"expectException()"は、例外を発生させる箇所より前に記載する

# 環境

```
$ vendor/bin/phpunit --version
PHPUnit 9.1.5 by Sebastian Bergmann and contributors.

$ php --version
PHP 7.4.0 (cli) (built: May 27 2020 22:16:49) ( NTS )
```

# expectException()を記載したのに、例外を発生させてもテストが成功しなかった

記載する位置、順番を間違えていたのが原因でした。

PHPUnitには、テストコード内で例外が生成されたかを確認する`expectException`メソッドが実装されています。
https://phpunit.readthedocs.io/ja/latest/writing-tests-for-phpunit.html#writing-tests-for-phpunit-exceptions

このメソッドは、例外発生箇所より手前で定義する必要があります。
上記公式ドキュメントのサンプルコードを借りて説明すると、

こうではなく、

```ExceptionTest.php
<?php
use PHPUnit\Framework\TestCase;

class ExceptionTest extends TestCase
{
    public function testException()
    {
        throw new \InvalidArgumentException("ここでわざとエラーを出します。");
        $this->expectException(\InvalidArgumentException::class);
    }
}
```

こうやって変更して

```diff
- $this->expectException(\InvalidArgumentException::class);
throw new \InvalidArgumentException("ここでわざとエラーを出します。");
+ $this->expectException(\InvalidArgumentException::class);
```

こうすべきです。

```ExceptionTest.php
<?php
use PHPUnit\Framework\TestCase;

class ExceptionTest extends TestCase
{
    public function testException()
    {
        $this->expectException(\InvalidArgumentException::class);
        throw new \InvalidArgumentException("ここでわざとエラーを出します。");
    }
}
```

## 出力

実行結果です。こちらは、誤った順番で実行した場合

```
$ vendor/bin/phpunit ./tests/TDDPractice/ExceptionTest.php 
PHPUnit 9.1.5 by Sebastian Bergmann and contributors.

E                                                                   1 / 1 (100%)

Time: 00:00.026, Memory: 4.00 MB

There was 1 error:

1) ExceptionTest::testException
\InvalidArgumentException: ここでわざとエラーを出します。

/home/taro/projects/phpsample/tests/TDDPractice/ExceptionTest.php:8

ERRORS!
Tests: 1, Assertions: 0, Errors: 1.
```

こちらが、正しい順番で実行した場合です。

```
$ vendor/bin/phpunit ./tests/TDDPractice/ExceptionTest.php 
PHPUnit 9.1.5 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 00:00.045, Memory: 4.00 MB

OK (1 test, 1 assertion)
```

# おわりに
メソッド名をよくよく考えれば、 "assertHoge()" のような名前ではなく、 "**expect**Exception" という名前が利用されています。
このニュアンスに気づいていれば、順番をひっくり返すこともなかったかもなと思います。

# 追記
`@expectedException`という形式で、テストケースを記載することもできます。
...と書こうと思ったら、手元で動きませんでした。8.x系で非推奨となり、9.x系で削除されたようです。
https://github.com/gordalina/cachetool/issues/141

`$this->expectException()`と仲良く暮らしていきましょう。
Nginxのバーチャルサーバ設定

#目的
Nginxを用いてアプリケーションを動作させようとしたが、
バーチャルサーバの設定ファイルが読めずに苦戦したため、備忘録として纏める。

<font color="Silver">*この記事は備忘録ですので、詳しく知りたい方は、記事下部の参考サイトを見て頂ければと思います。</font>

#概要
バーチャルサーバ設定ファイルの内容をまとめる。
この記事では、デフォルトで生成される設定ファイルを用いて説明する。

#環境
ubuntu 18.04
nginx 1.14.0(ubuntu)

#バーチャルサーバ設定ファイルの内容

```
$ vi /etc/nginx/sites-enabled/default
```

```rb:default
server {
        #webサーバのポート番号を指定する
        listen 80 default_server;
        listen [::]:80 default_server;

        #デフォルトのrootを指定する
        root /var/www/html;

        #デフォルトで表示するファイルを指定する
        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                try_files $uri $uri/ =404;
        }
```

#注意点
デフォルトで生成されるバーチャルサーバの設定ファイルは、
OSの種類とバージョンによって格納先が変わるため、/etc/nginx/nginx.confから確認する必要があります。
ubuntu18.04では、/etc/nginx/sites-enabled/にdefaultとして生成されましたが、
centOS7等では、/etc/nginx/conf.d/にdefault.confとして生成されます。

#参考
[Nginxとは？インストールや設定ファイルの仕組みを解説【CentOS】](https://kitsune.blog/nginx-install)
[How To Install Nginx on Ubuntu 18.04](https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-18-04)
type: :mailer以外のrspecだとActionMailer::Base.deliveriesが空っぽ

# 困った
request specなどでも
`ActionMailer::Base.deliveries` を使ってテストがしたいのに
`type: :mailer` 以外のrspecだと `ActionMailer::Base.deliveries`が []のままで困った

きっとtype: :mailerの時は何かが裏で勝手にincludeとかしてるんだろうなーと思って

# 調べてみる
[rspec の type: :model とかについて](https://blog.kyanny.me/entry/2016/03/15/025321)
という記事を見つけた
どうやらそういうことらしい

typeに応じてここにあるものが読み込まれるのかな？
https://github.com/rspec/rspec-rails/blob/master/lib/rspec/rails/example/

ってことで試してみる

# 解決
```rb:rails_helper.rb
RSpec.configure do |config|
.
.
.
  config.include RSpec::Rails::MailerExampleGroup
.
.
.
```
ってやると
お、 `ActionMailer::Base.deliveries` に積まれるようになった〜〜
よかったよかった

### 常に読み込ませたくないなら
`ActionMailer::Base.deliveries` を使いたいrspecの中でのみ

```rb
include RSpec::Rails::MailerExampleGroup`
```

でおk
Docker for Mac の Mutagen-based cachingを使ったらホスト側のファイルの変更が反映されなくなった

# 何が起きたか
[Docker for Mac の Mutagen-based caching で Volume のパフォーマンスが劇的に改善した](https://qiita.com/nanasess/items/16ab9274c34bdc34e567)
こちらの記事を見て試してみたらrspecとかrubocopとか爆速になってうおおおおおおってなったけど
`swagger.ymlのホスト側での変更がredocのコンテナ内に反映されなくなってしまった`
しかし、railsプロジェクトの方は問題なく反映されていてなんでだろうと思ったら

# 原因
```yml:docker-compose.yml
version: '3'
services:
  redoc:
    image: redocly/redoc:latest
    volumes:
      - ./swagger.yml:/usr/share/nginx/html/swagger.yml
    environment:
      SPEC_URL: swagger.yml
    ports:
      - 8081:80
```
volumesで
`- ./swagger.yml:/usr/share/nginx/html/swagger.yml` と書いていたこと
どうやらファイル単位での指定をすると反映がされなくなるようだ
なんでかはわからん、暇な時に気が向いたら調べる

# 解決策
ディレクトリ単位でマウントする

```yml:docker-compose.yml
version: '3'
services:
  redoc:
    image: redocly/redoc:latest
    volumes:
      - ./swagger:/usr/share/nginx/html/swagger
    environment:
      SPEC_URL: swagger/swagger.yml
    ports:
      - 8081:80
```

# ちなみに
Mutagen-based caching使ったらrspecとか4倍ぐらい早くなるので
railsをdocker使って開発してて遅いなぁって困ってる人にはとてもおすすめ
もうdocker for mac遅いなんて言わせない！！！！！

edge版なので何があるかわからんけど
天界の様子が見れる秘密のサイトつくった。

![FireShot Capture 001 - Email_Password Authentication Example - stupefied-almeida-771bd9.netlify.app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603301/43668ed4-dbf4-27a8-b081-b3794b09c11a.png)
秘密だから特定の人しか見れないようにしてます
---
サイト:<b>www.tenkai.ml</b>
[Emall:demo@demo.jp Pass:demo00 でログインできます。(怖くないよ)]


ログインすると...
---
![FireShot Capture 003 - Email_Password Authentication Example - stupefied-almeida-771bd9.netlify.app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603301/e637fa71-1bce-27b1-2bb2-69c3182ccd53.png)

天界の様子(大阪エリア）が確認できます。
えぇ...。天界とは、<b>天気です。</b>

天界(大阪エリア)の窓をスクロールすると...
---
![FireShot Capture 004 - Email_Password Authentication Example - stupefied-almeida-771bd9.netlify.app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603301/6ef6f59c-414f-c0f4-bc94-6fa55c536f1c.png)
猫。
(天気によって、出てくる猫が変わります。ぜひ、晴れの日にサイトを覗きにきてください。)




サイトの仕組み
---
1.最初のログイン画面は Firebase Authentication 使ってます。
参考にさせていただいた記事->https://qiita.com/shima-07/items/2c344b0ad306b201a065

2.天界(大阪エリア)の情報は OpenWeatherMap の API を取得しています。
参考にさせていただいた記事->https://www.tam-tam.co.jp/tipsnote/html_css/post16405.html

3.天界(大阪エリア)の小窓は、html を、もう一つデプロイして、それを埋め込んでいます。
参考にさせていただいた記事->https://gray-code.com/html_css/view-another-html-on-current-html/

4.サイトのデプロイは Netlify というサービスを使いました。
参考にさせていただいた記事->https://qiita.com/oganyanATF/items/7fb681e863d8681c9039
(Netlify で html をデプロイする時は、index.html の名称でないと、うまくデプロイできないので気をつけてください。)
 
おまけ
---
今回のサイトの GitHub を公開します。
・メインサイト(ログイン機能含む)のリポジトリ->https://github.com/cazmura/ten-kai-login
・埋め込みサイトのリポジトリ->https://github.com/cazmura/ten-kai


最後まで読んでいただきありがとうございました。
[競プロ用]UnionFind木まとめ

# いつ使うのか

* グラフが同一の根を持つか → 全てのor特定の点同士が繋がっているかを考える問題
* 複数の要素が同一の集合に含まれているかを考える問題

# 何がいいのか

O(α(N))の非常に少ないオーダー。
α(n)はアッカーマン関数A(n, n)の逆数。

# テンプレート

とても便利なライブラリを作ってくださっている。。
https://note.nkmk.me/python-union-find/
https://github.com/nkmk/python-snippets/blob/ec0e770a72135b12840ea02f1e74101785faf700/notebook/union_find.py#L1-L46

`union()`で要素の併合→`same()`や`group_count()`で求めたい結果を得る。
難しくなさそう

# 使用例

## [ARC032 B - 道路工事](https://atcoder.jp/contests/arc032/tasks/arc032_2)

```python
def main():
    N, M = map(int, input().split())
    uf = UnionFind(N)
    for _ in range(M):
        aa, bb = map(lambda x: int(x) - 1, input().split())
        uf.union(aa, bb)
    print(uf.group_count() - 1)
```

## [ABC075 C - Bridge](https://atcoder.jp/contests/abc075/tasks/abc075_c)

```python
def main():
    N, M = map(int, input().split())
    a, b = [], []
    for _ in range(M):
        aa, bb = map(int, input().split())
        a.append(aa - 1)
        b.append(bb - 1)
    count = 0
    for i in range(M):
        uf = UnionFind(N)
        for j in range(M):
            if j == i:
                continue
            uf.union(a[j], b[j])
        if uf.group_count() != 1:
            count += 1
    print(count)
```

## [ABC157 D - Friend Suggestions](https://atcoder.jp/contests/abc157/tasks/abc157_d)

```python
def main():
    N, M, K = map(int, input().split())
    connection = [[] for _ in range(N)]
    uf = UnionFind(N)
    for i in range(M):
        a, b = map(lambda x: int(x) - 1, input().split())
        connection[a].append(b)
        connection[b].append(a)
        uf.union(a, b)

    for i in range(K):
        c, d = map(lambda x: int(x) - 1, input().split())
        if uf.same(c, d):
            connection[c].append(d)
            connection[d].append(c)

    ans = []
    for i in range(N):
        ans.append(uf.size(i) - len(connection[i]) - 1)
    L = [str(i) for i in ans]
    print(" ".join(L))
```

## [ARC097 D - Equals](https://atcoder.jp/contests/arc097/tasks/arc097_b)

こういう問題でもUnionFind。
i = p[i]となるかどうかが`uf.same(i, p[i])`と置き換えられる。

```python
def main():
    N, M = map(int, input().split())
    p = [int(i) - 1 for i in input().split()]
    uf = UnionFind(N)
    for _ in range(M):
        x, y = map(lambda i: int(i) - 1, input().split())
        uf.union(x, y)

    count = 0
    for i in range(N):
        if uf.same(i , p[i]):
            count += 1
    print(count)
```

# 参考

* https://www.slideshare.net/chokudai/union-find-49066733
* https://note.nkmk.me/python-union-find/
* https://github.com/nkmk/python-snippets/blob/ec0e770a72135b12840ea02f1e74101785faf700/notebook/union_find.py#L1-L46

# Appendix

map関数の第一引数にはlambda式を使える。
これまで入力を文字列で受けてintに変えるくらいにしか使っていなかったが、リストの0-indexedか1-indexedかの問題で入力値をマイナス1する時にlambda式にすると一括してできそう。

```python
map(lambda i: int(i) - 1, input().split())
```
ChromebookでPythonとSeleniumを使いChromeを自動化しよう

ChromebookでSeleniumを使うのに最初少し手こずったのと、
手順についてあまりまとめられているものがなかったのでまとめてみました。




!! point !!
--------------------------------------------------------------------------------------
★crostiniからやる場合、debian側にもgoogle-chromeをインストールしなくてはならない。
★chromedriverは’/usr/local/chromedriver/’に設置。


1.google-chromeをインストール(chromebookの最初から入ってるchromeとは別で必要)
--------------------------------------------------------------------------------------
    $ wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
    $ sudo apt install ./google-chrome-stable_current_amd64.deb

2.google-chromeのバージョンを確認
--------------------------------------------------------------------------------------
	$ google-chrome -version

3.chromedriverはlinux用のものをダウンロード。
--------------------------------------------------------------------------------------
先程確認したバージョンに対応したものを入れること。
https://chromedriver.chromium.org/downloads
ここでダウンロードしたものをとりあえずLinuxファイルに突っ込む。
(コマンドで入れてパス指定してもよかったかもしれない。)

4.chromedriverのディレクトリを作成
--------------------------------------------------------------------------------------
    $ sudo mkdir /usr/local/chromedriver

5.作ったディレクトリにchromedriverを移動
--------------------------------------------------------------------------------------
    $ sudo mv chromedriver /usr/local/chromedriver

6.権限を付与
--------------------------------------------------------------------------------------
    $ sudo chmod ugo+x /usr/local/chromedriver/chromedriver

7.後はseleniumが入っていないなら入れる
--------------------------------------------------------------------------------------
    $ pip install selenium

<br>
これでいけるはず。
後は適当にスクレイピングしてみてください！

    from selenium import webdriver

    driver = webdriver.Chrome('/usr/local/chromedriver/chromedriver')
    driver.get(url)
    html = driver.page_source.encode('utf-8')

    # 適当に処理を入れる

    driver.quit()
unable to import django

##vscode で unable to import djangoと言われた
解決の参考にしたサイトはこれ
[Unable to import 'django.db'](https://stackoverflow.com/questions/53007637/e0401unable-to-import-django-db)


`Ctrl+Shift+P`を押し`Python:Select Interpreter`を選択、その後pythonのバージョン選択を求められる。
自分は`which python`で出力されたバージョンを選択しました。
 -> Select Interpreter select the environment that starts with ./env or .\env run Ctrl+Shift+` to activate it

share  improve this answer  follow
ssh接続をする際に「WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!」

同じIPアドレスでサーバを用意した場合、SSHで接続するときに下記のようなエラーがせることがある

```
$ ssh root@123.123.123.123
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
9a:33:31:63:13:85:d3:32:c1:bb:d9:0f:cc:d9:c5:f6.
Please contact your system administrator.
Add correct host key in /Users/hideaki/.ssh/known_hosts to get rid of this message.
Offending RSA key in /Users/hideaki/.ssh/known_hosts:51
Password authentication is disabled to avoid man-in-the-middle attacks.
Keyboard-interactive authentication is disabled to avoid man-in-the-middle attacks.
Permission denied (publickey,password,keyboard-interactive).
```

## 解決方法

```
$ ssh-keygen -R 123.123.123.123
```
↓
再度接続！
herokuデプロイ 

データベースをpostgreSQL以外を使っている場合はそのデータベースのgemをコメントアウトして、
Gemfileの一番下に本番環境ではpostgreSQLを使うことを宣言してbundle installする。

```ruby:Gemfile
# gem 'mysql2', '>= 0.4.4', '< 0.6.0'

group :production do
  gem "pg"
end
```

jQueryにてテンプレートリテラルを使用した場合は下記の文章をコメントアウトする。

```ruby:environments/production.rb
# config.assets.js_compressor = :uglifier
```

あとはherokuで登録が完了していればログインする。

```ruby:ターミナル
$ heroku login
```

その後、GitHubで管理しているアプリをheroku上に作成する。

```ruby:ターミナル
$ heroku create アプリ名
```

GitHubでcommitとPushをしてmasterにマージを済ました状態で下記のコードを実行する。

```ruby:ターミナル
$ git push heroku master
```

heroku上にデータベースを作成する。

```ruby:ターミナル
$ heroku run rails db:migrate
```

そして最後にアプリを開く

```ruby:ターミナル
$ heroku open
```
Macデフォルトでインストールされているアプリを削除する

`Books.app`とか、`Mail.app`とか`Siri.app`とか、要らないので削除。

<img width="836" alt="Screen Shot 2020-06-08 at 4.54.45 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39529/a9ff85c2-d19f-d9c1-fa94-49bca7705ac7.png">

--------------------

# macOS Catalina

## 1. Macをリカバリーモードで再起動する

(もしくは再起動時に **[Cmd]** + **[Option]** + **[R]**) 

```
sudo nvram "recovery-boot-mode=unused"
sudo reboot
```


## 2. MacのSystem Integrity Protectionを無効にする

`Utilities > Terminal`から実行

```
# csrutil enable --without fs
```
<img width="836" alt="Screen Shot 2020-06-08 at 5.01.32 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39529/a67a0cad-f43f-ca76-9298-5e0029b12779.png">


## 3. 再起動後、ルートの読み込み権限を再マウント

```
sudo mount -uw /
```

## 4. 不必要なアプリを削除

```
$ cd /System/Applications 
$ sudo rm -rf Mail.app Books.app
```
<img width="836" alt="Screen Shot 2020-06-08 at 5.04.28 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39529/1222bec5-c4ab-8179-a7b8-1d1fc164e598.png">

`rm -rf`した直後では、まだアプリのアイコンが表示される
<img width="836" alt="Screen Shot 2020-06-08 at 5.04.46 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39529/6eb0aa29-468f-1bd5-8740-6d2e03bd1e68.png">

再起動後に再び開くと、ちゃんとアイコンが消えている
<img width="836" alt="Screen Shot 2020-06-08 at 5.06.21 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39529/209e81e7-03da-be76-f0d1-b311fe4989ff.png">


--------------------

# macOS Catalinaより前のバージョン

## 1. Macをリカバリーモードで再起動する

(もしくは再起動時に **[Cmd]** + **[Option]** + **[R]**) 

```
sudo nvram "recovery-boot-mode=unused"
sudo reboot
```


## 2. MacのSystem Integrity Protectionを無効にする

`Utilities > Terminal`から実行

```
# csrutil disable
```
<img width="778" alt="Screen Shot 2020-05-28 at 9.54.28 AM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39529/ddf6870a-ec9f-3051-4e26-629fbf5ece79.png">

## 3. リカバリーモードを終了して、再起動

```
# nvram -d recovery-boot-mode
# reboot
```

## 4. Terminalから削除

```
$ sudo rm -rf /Applications/Mail.app
```

すっきりした　(^^)
<img width="836" alt="Screen Shot 2020-05-28 at 10.16.02 AM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39529/86951223-09e7-cb9a-c2f4-7c6d31afdfac.png">
【Golang】interface②タイプアサーション

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

```
package main 

import (
	"fmt"
)

//interface2の使い方
func do(i interface{}){
	//1
	/*
		//int型に直す。正しければ復元する
		//タイプアサーション　
		ii := i.(int)
		// i = ii * 2
		ii *= 2
		fmt.Println(ii)

		//str型に直す
		ss := i.(string)
		fmt.Println(ss + "!")
	*/

	//2
	//interfaceをtype毎に条件分岐 vを変換
	//スイッチタイプ文
	//switch v := i.(type) はセットで覚える(型アサーション)
	switch v := i.(type) {
	case int:
		fmt.Println(v * 2)
	case string:
		fmt.Println(v + "!")
	default:
		fmt.Printf("%T\n", v)
	}
}

func main() {
	//1
	//まだint型でない interface型
	var i interface{} = 10
	var s interface{} = "Mike"

	//2
	//いろんな型で実行
	do(i)
	//>>20
	do(s)
	//>>Mike!
	do(true)
	//>>bool
	


	//3
	//タイプアサーション、コンバージョン
	var i2 int = 10
	//タイプコンバージョンは書き換える
	ii := float64(10)
	fmt.Println(i2, ii)
	//>>10 10

	//タイプアサーション
	//interfaceの場合の変換
	//var i interface{} = 10
	//i.(int)で変換する

}
```
n!通りの全探索を学ぶ

#AtCoder 版！蟻本 (初級編)
今日から[AtCoder 版！蟻本 (初級編)](https://qiita.com/drken/items/e77685614f3c6bf86f44)の記事を読み進めましょう！
[蟻本](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%B3%E3%83%B3%E3%83%86%E3%82%B9%E3%83%88%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8%E3%83%96%E3%83%83%E3%82%AF-%E7%AC%AC2%E7%89%88-%EF%BD%9E%E5%95%8F%E9%A1%8C%E8%A7%A3%E6%B1%BA%E3%81%AE%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E6%B4%BB%E7%94%A8%E5%8A%9B%E3%81%A8%E3%82%B3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF%E3%82%92%E9%8D%9B%E3%81%88%E3%82%8B%EF%BD%9E-%E7%A7%8B%E8%91%89%E6%8B%93%E5%93%89/dp/4839941068)とはプログラミングコンテストチャレンジブックの事です。
この本を読み進めてAtCoderに類似する問題があれば挑戦していきます。

##特殊な状態の列挙
n! 通りの全探索を行う事です。
C++には「next_permutation」があります。

###サンプル１
```C++:C++
#define MAX_N 100
bool used[MAX_N];
int perm[MAX_N];

void permutation(int pos, int n){
    if(pos == n){
        /* ここにpermの処理を書く */
        
        return;
    }
    
    for(int i=0; i<n; i++){
        if(!used[i]){
            perm[pos] = i;
            used[i] = true;
            permutation(pos+1, n);
            used[i] = false;
        }
    }
}
```

###サンプル2
```C++:C++
#include<algorithm>
int perm[MAX_N];

void permutation(int n){
    for(int i=0; i<n; i++){
        perm[i]=i;
    }
    do{
        /* ここにpermの処理を書く */
    }while(next_permutation(perm, perm+n));
}
```

##枝刈り
探索しなくても解が存在しない条件がある分岐からは処理を行わない。

#問題

###[ABC 054 C One-stroke Path](https://atcoder.jp/contests/abc054/tasks/abc054_c)
問題文はAtCoderを参照してください。

- 無向グラフを使います。

```C++:C++
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<utility>
#include<iomanip>
#include<map>
#include<cmath>
#include<cstdio>

#define rep(i,n) for(int i=0; i<(n); ++i)
#define pai 3.1415926535897932384

using namespace std;
using ll =long long;
using P = pair<int,int>;

#include<algorithm>
#define MAX_N 8
bool G[MAX_N][MAX_N] = {false};
int order[MAX_N];

void permutation(int n){
    for(int i=0; i<n; i++){
        order[i]=i;
    }
    
    int res=0;
    do{
        if(order[0] != 0) continue;
        bool ok=true;
        /* ここにpermの処理を書く */
        for(int i=0; i+1<n; i++){
            int from = order[i];
            int to = order[i+1];
            
            if(!G[from][to]) ok=false;
        }
        if(ok) res++;
    }while(next_permutation(order, order+n));
    
    cout << res << endl;
}

int main(int argc, const char * argv[]) {
    int n, m;
    cin >> n >> m;
    
    rep(i, m){
        int a, b;
        cin >> a >> b;
        a--;
        b--;
        G[a][b]=true;
        G[b][a]=true;
    }
    
    permutation(n);
    
    return 0;
}

```
自宅サーバー構築メモ

# 概要

勉強がてら自宅サーバーで遊んだので、参考になったサイトや、導入したサービスをメモ程度に列挙する。(**※諸事情によりインターネットには公開せずに、自宅LAN内からのアクセスのみの想定です。**)


# 環境

- OS: Ubuntu 18.04.4 LTS Server
- メモリ: 8GB
- SSD: 500GB
- HDD: 1TB

# HDD

主にSquidのキャッシュと共有ファイル保存場所として利用。以下のコマンドでマウント。

```shell
$ mount /dev/sdb1 /mnt/sdb1
```
# ファイアウォール
 ufwを使って設定。ホワイトリスト形式で導入サービスのみローカルネットワークから許可。

(参考: [ufw コマンド 覚書](https://qiita.com/JhonnyBravo/items/f67d34c0ed8f2961919e), [ufw 基本のコマンド操作](http://www.green-pen.jp/ufw.html))


# 導入サービス

## SSH(Port:22)

Ubuntu 18.04 LTS Serverでは初期設定で設置できる。

## Web(Port:80)

Docker上で動作させたNginxを設置した。


## Samba(Port:445)

1TBのHDDを使いたかったので、`/mnt/sdb1/share`を共有ディレクトリにした。(参考: 
[Ubuntuでファイルサーバーをたてる（Samba）](https://qiita.com/msrks/items/1385cf13258dd1a0da08))

アクセスできるユーザーを限定的にする。(参考: [Sambaのユーザー認証とファイルアクセス権の設定](https://www.atmarkit.co.jp/ait/articles/0901/28/news153.html))
## Proxy

HTTPとSocksを切り替えたかったのでSquidとTor-Socksの２つを設置した。


### Squid(Port:8080)

HDDにcacheの保存先を`/mnt/sdb1/squid/cache/`に設定した。(参考: 
[Ubuntu Linux 18.04 LTSにSquidをインストールして、フォワードプロキシサーバーとして使う](https://kazuhira-r.hatenablog.com/entry/2019/10/04/004936))

HTTPSに対応するためはSSL Bumpの設定が必要。(参考: [Squidをソースから導入してSSL Bumpを設定する](https://www7390uo.sakura.ne.jp/wordpress/archives/777))


### Tor-Socks(Port:9050)

Tor-Socksを外部から利用できるようにするために`/etc/tor/torrc`に`SOCKSPort 0.0.0.0:9050`を追記


## DataBase(Port:3306)

Docker上で動作させたMySQLを設置した。

## DNS(Port:53)

BIND9を設置した。自宅内LANのみの設定を行った。(参考: [内部向けDNSサーバの構築](http://www.miloweb.net/bind.html), [LAN内DNSサーバを立てる](http://rina.jpn.ph/~rance/linux/bind/lan_dns.html))
【Lighthouse】schema.graphqlがキャッシュされて更新できない時の対処法【Laravel + GraphQL + Redis】

[Lighthouse](https://lighthouse-php.com/)を使っている時にローカルで実装して動作確認した後、AWS環境(+Redis)にデプロイしてECS確認したら`schema.graphql`の更新が全く反映されず、めっちゃハマりました。
この記事ではその解決策と簡単な解説をしていきたいと思います。

# 結論
`.env`または環境変数に`LIGHTHOUSE_CACHE_ENABLE=false`を設定するか、以下のコマンドを実行する。
ただし本番環境で上記の環境変数を設定するのは非推奨なので注意が必要。


```
php artisan lighthouse:clear-cache
```

# 環境
Docker 19.03.8
PHP 7.3.16
Laravel 6.18.3
Lighthouse 4.11

# 発生したこと
1. `Lighthouse`で[Resolver](https://lighthouse-php.com/4.6/api-reference/resolvers.html#resolver-function-signature)を使用してスキーマを実装し、GitHubからAWSのCode兄弟を使ってECSにデプロイ。
2. ローカルでは元気に動いていたプログラムがECS上では全く動かない。
3. デバッグログ仕込みまくって調べてみたら`schema.graphql`のファイルの更新が反映されてない。
4. ECSで動いているimageを確認してもちゃんと新しい`schema.graphql`が入っている。
5. キャッシュか？でもデプロイのたびにコンテナ作り直しているからそれはないよなぁ……
6. 原因がわからなくて詰む。

# 原因

**やっぱりキャッシュでした。**

`config/lighthouse.php`にキャッシュの設定があります。

```php:config/lighthouse.php
'cache' => [
    'enable' => env('LIGHTHOUSE_CACHE_ENABLE', env('APP_ENV') !== 'local'),
    'key' => env('LIGHTHOUSE_CACHE_KEY', 'lighthouse-schema'),
    'ttl' => env('LIGHTHOUSE_CACHE_TTL', null),
],
```

`enable`に書いてある通り、`.env`の`APP_ENV`を参照し`local`以外だったら自動でキャッシュを有効化します。

これによりGraphQLの全てのスキーマが一つのデータとしてキャッシュされます。

**で**、このキャッシュはどこに保存されるかというと、メモリではなく`.env`の`CACHE_DRIVER`で設定されているストレージに保存されます。
（詳細な実装は[こちら](https://github.com/nuwave/lighthouse/blob/master/src/Schema/AST/ASTBuilder.php#L96)に書いてあります。）

今回はRedisを使用してたので、そこに保存されることになります。

ローカルならDockerコンテナでRedisを管理しているので、コンテナを落とせば自然とリセットされますがAWSでの開発環境ではRedisを落とすことはほぼありません。

そのため永遠にキャッシュが残ることになってしまったのです。

# 最後に

注意点として`config/lighthouse.php`に書いてある通り、キャッシュをオフにするとパフォーマンスに影響がでます。
なので本番環境ではキャッシュを切らないように気をつけましょう。

```
/*
|--------------------------------------------------------------------------
| Schema Cache
|--------------------------------------------------------------------------
|
| A large part of schema generation consists of parsing and AST manipulation.
| This operation is very expensive, so it is highly recommended to enable
| caching of the final schema to optimize performance of large schemas.
|
*/
```

ECSを使用している場合はいちいちコンテナに入るのも大変なので、Dockerfileにコマンドを追加したり直接Redis上のキャッシュを削除するようにしましょう。

## 参考文献
[Schema caching](https://lighthouse-php.com/master/performance/schema-caching.html)
[GraphQL Server Cannot Be Reached Status Code 500](https://stackoverflow.com/questions/57540930/graphql-server-cannot-be-reached-status-code-500)
[nuwave/lighthouse](https://github.com/nuwave/lighthouse)
WioTerminalの激ムズゲームを改造する

# どんな内容か？
[WioTerminal](https://wiki.seeedstudio.com/Wio-Terminal-Getting-Started/)の購入時に遊べるレトロゲーム（Jumper）が激ムズですぐにゲームオーバーで進めないので簡単にするための改造方法です。

多分、購入すると5分間くらいはこのゲームで時間を消費することになります。昔懐かしいゲームウオッチを思い出します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143415/5de38fd7-a444-df59-a6a8-acc4bf28cd1e.png)

#やり方
このゲームのソースコードが公開されているので、そのソースコードの一部を修正することで、あんなことやこんなことができるようになります。ですので、まずはそのソースコードを入手してビルドできるようにする必要があります。

#環境の準備
1. ArduinoIDEの環境を準備します。（詳細は省きます）
2. ソースコード[Seeed_Arduino_Sketchbook](https://github.com/Seeed-Studio/Seeed_Arduino_Sketchbook)をダウンロードします。この中にJumperのソースが含まれます。
3. ビルドするのにライブラリが必要なので、[Adafruit_ZeroTimer](https://github.com/adafruit/Adafruit_ZeroTimer)もダウンロードします。
4. ライブラリをインストールするためにArduinoIDEを起動し、スケッチ→ライブラリのインクルード→.Zip形式のライブラリのインクルードで、ダウンロードしたZipファイル（Adafruit_ZeroTimer-master.zip）を選択します。（※下部写真）
5. jumper.inoをダブルクリックしJumperのコードを開きます。
6. ビルドしてWioTerminalに書き込んで動けば環境はOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143415/6298e458-fd57-27cf-816b-d776d0c0cf7f.png)

#改造方法その１：鳥を消す
ゲームをやっていると厄介なのが空を飛ぶ鳥です。この鳥がなかなか衝突判定も厳しくて邪魔キャラなので消し去ります。
コメントで//generate a birdとある下記の部分全てをコメントアウトすることで、鳥出なくなります。
つまり、抵抗の障害物をジャンプするだけのゲームにすることができます。（面白いかは別ですよ。）

```c 
//generate a bird
static bool once = true;
if (once)
{
    once = false;
    int i = 0;
    while (current_bird_count < max_bird_count)
    {
        bird[current_bird_count++] = object(
            pix_type_bird,
            point(screen_width - raw_bird[0]->width, jump_path[i].y - 16),
            raw_bird,
            x_bird_speed);
        i++;
    }
}
else if (
    current_bird_count < max_bird_count &&
    random(0, rate) == 0 &&
    can_generate(bird, current_bird_count))
{
    debug("generate a bird");
    auto i = random(0, max_jump_path);
    bird[current_bird_count++] = object(
        pix_type_bird,
        point(screen_width - 1, jump_path[i].y - 16),
        raw_bird,
        x_bird_speed);
}
```
上記を全部コメントアウト（削除）しちゃえば、鳥は出てきません。

#改造方法その２：無敵化
最終手段ですね。こちらは、１行コメントアウトするだけで無敵化することができます。単にゲームオーバーしなくするだけなんですけど。

ソースコードの中央部にこのゲームオーバーフラグを立てる場所があるので、ここをコメントアウトします。

```c 
        if (collide_mask & pix_type_actor)
        {
            flag = game::over;
        }
```

```c 
        if (collide_mask & pix_type_actor)
        {
            // こんな感じです。
            // flag = game::over;
        }
```

無敵はこんな感じになります。（動画でご覧いただけます。）

[![動画がみつかりません](http://img.youtube.com/vi/RVcU2y_gJpM/0.jpg)](http://www.youtube.com/watch?v=RVcU2y_gJpM)


# その他
ベースとなるソースコードが公開されていますので、これをベースにアレンジしたゲームを作りこむのも楽しそうですね。（自分が作るとは言ってない。）
PUN2のカスタムルームプロパティを変更する

#はじめに
Unity使ってゲーム作るぞ～　オンラインゲーム作るぞ～
と意気込んで、さっと調べて目についたPhoton Unity Networking(PUN)でオンライン要素を実装することにしました。

まあ、さっと調べた時に色んなブログさんで参考資料見つけたし、正直余裕でしょ！とか思っていたら微妙なところで躓いたので備忘録として書いておきます。

PUNにはVer 1.～とVer 2.～がありまして、PUNのスタートアップを紹介しているところだとPUN2をダウンロードしましょう！ってあるんですが、実際にPUNでこういうのを実装しました！ってとこだとPUN1のほうってことが結構ありました。
そんでもってPUN1とPUN2でマイナーチェンジがちょこちょこあるもんだから、実際にコード書くと「そんなクラスはない！」だとか「そんなメソッドはない！」って怒られます。

タイトルのカスタムルームプロパティもその類のもので、実装までに時間がかかりました。

##カスタムルームプロパティ

```C#
using UnityEngine;
using Photon.Pun;

public class RoomProperties : MonoBehaviourPunCallbacks
{
    ExitGames.Client.Photon.Hashtable roomHash;
    float time = 60.0f;

    void Start()
    {
        //ルームプロパティ設定
        roomHash = new ExitGames.Client.Photon.Hashtable();
        roomHash.Add("Time", time);
        PhotonNetwork.CurrentRoom.SetCustomProperties(roomHash);
    }

    void Update()
    {
        time -= Time.deltaTime;
        roomHash["Time"] = time;
        PhotonNetwork.CurrentRoom.SetCustomProperties(roomHash);
    }

    //ルームプロパティが変更されたときに呼ばれる
    public override void OnRoomPropertiesUpdate(ExitGames.Client.Photon.Hashtable propertiesThatChanged)
    {
        object value = null;
        //変更のあったプロパティに"Time"が含まれているならtimeを更新
        if (propertiesThatChanged.TryGetValue("Time", out value))
        {
            time = (float)value;
        }
    }
}
```

とりあえず注意するところは、
PhotonNetwork.CurrentRoom.SetCustomProperties(roomHash)と
OnRoomPropertiesUpdate(ExitGames.Client.Photon.Hashtable propertiesThatChanged)です。
この2か所がPUN1から変更があるのでうっかりすると、エラーを吐き続けます。

あと、どれだけ値が更新されようがPhotonNetwork.CurrentRoom.SetCustomProperties（ExitGames.Client.Photon.Hashtable HashTable）を実行しないとそのルーム内では共有されません。
更新する値は一つだけということもなく、同時に複数の値を更新した後にSetCustomPropertiesを実行すると変更された値が全て更新されます。
更新するカスタムルームプロパティの値の種類だけ、OnRoomPropertiesUpdateにif文を書いておけばそれぞれが更新されます。

ちなみに、上記のように毎フレーム更新なんてことしたら通信量がガンガン増えるのでやめておいた方がいいです。

##さいごに
困ったら公式リファレンスだ！
それでも無理なら現物のコードを追う！！
２次元配列の中から特定値の個数を導き出す

２次元配列から特定値の個数を見つける良い書き方がないかな、と考えていて
forEachで２重ループするのも考えたのだけど、
できるだけ使いたくないので一行で記述できる方法を考えてみた。

基本的には
1：[].concat(...array) or array.flat()を利用して異次元配列に変換
2：フィルターで特定の値だけの配列に変換
3：lengthで配列の個数を得る

という手順で行いました。

```javascript:２次元配列の中から特定値の個数を導き出す

// 5*5の二次元配列
const array = [
  [0, 0, 0, 0, 1],
  [0, 1, 0, 2, 0],
  [0, 0, 1, 0, 0],
  [0, 2, 0, 1, 0],
  [0, 0, 0, 0, 1]
];

/* ①スプレッド演算子を使う
- [].concat(...array) : 一次元配列にする
*/
const result1 = 
  [].concat(...array)
  .filter(number => { return number === 2; })
  .length


/* ②flat()を使う IE未対応
- array.flat() : １次元配列にする
*/
const result2 = 
  array.flat()
  .filter(number => { return number === 1; })
  .length

```
【Unity_3D】初心者がノンコードでできる。Third person controller を使って簡単にキャラクターを方向転換させたり移動させる方法

#この記事を見てできること
・3Dゲームでキャラクターを自由自在に動かせる
#この記事を見て欲しい人
・Unity初心者の方
#開発環境
・Mac book air 2015 (8GB)
・visual studio
・Unity 20184.22f1
←ここ重要だった気がします。1度2019でやったときにできなかった記憶があります。

#やり方
（１）まずはwebGL版にスイッチプラットフォーム
スマホゲーム作る人はiOSとかにスイッチプラットフォームしといてください。
私の場合は今回unity roomを通じてwebGLで公開しようと思っているのでwebGLにスイッチプラットフォームします。
![スクリーンショット 2020-05-28 23.50.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/74722495-85eb-973e-bc31-da280b6ccf22.png)

（２）地面を作る
3DオブジェクトからPlaneを選択する。
そうすると下の画像のように地面ができます。

![スクリーンショット 2020-05-28 23.52.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/643e5a35-b94f-06f3-419b-ece3efe23098.png)
![スクリーンショット 2020-05-28 23.52.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/b900c9b8-bb0d-b988-ff3f-983a5dfdd85e.png)

（３）プレイヤーを用意する
アセットストアから調達しようと思います。
好きなものを調達してください。
人間っぽくていい感じにアニメーションついてるやつがいいな。って思ってます。
window > asset storeからひらけます。
![スクリーンショット 2020-05-28 23.54.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/4031a546-cffb-2574-9260-d25db63f194a.png)
スタンダードアセットをダウンロード->インポートします。
![スクリーンショット 2020-05-29 0.20.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/28be31b7-9b5e-d7e1-ce91-bfbaf2788eee.png)
スタンダードアセットのインポートはちょっと時間かかります。
![スクリーンショット 2020-05-29 0.21.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/987b56b7-2cd3-cfff-00db-525d3524fcbd.png)
インポートし終わるとこうなってるはずです。
![スクリーンショット 2020-05-29 0.26.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/e1588fab-261b-467f-76b8-39e52e96325b.png)
そしたら下の画像みたいなファイル構想までいってThird person contorollerをヒエラルキーにドラッグします。
![スクリーンショット 2020-05-29 0.27.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/84b2d497-d9cd-5651-dbfe-ef296f82076a.png)
そうするとこうなります
![スクリーンショット 2020-05-29 0.29.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/e3c7a1d1-6e38-a2f5-db56-e4b4cefa8b20.png)
試しに再生ボタンをおして動かしてみるとスイスイ方向転換してると思います。
※プレイヤーの操作方法
移動：AWDS or 方向キー
ジャンプ：スペースキー
![スクリーンショット 2020-05-29 0.30.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/c2e2fe9e-0c1d-7c24-0ab6-9343ddb0a9d7.png)
（４）カメラをプレイヤー視点にする。
簡単すぎます
main cameraをプレイヤーの小要素にします
![スクリーンショット 2020-05-29 0.34.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/9526f7b7-6a38-2370-9569-159b000fc4df.png)
試しに再生してみる
![スクリーンショット 2020-05-29 0.35.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/ccaa4f57-2787-1b93-8815-53409557c0d1.png)
ちょっと遠い？？
main cameraのインスペクターで調整してやりましょう。
![スクリーンショット 2020-05-29 0.36.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/fb461e5d-7acd-a0b2-c6b0-08f3c0d0478f.png)
右下の画面をみながら、右上のインスペクターのTransform positionを変更してあげます。

（５）ジャンプ力を変更する
ヒエラルキーのThirdPersonControllerを選択して
インスペクターをみてください。（右下）
Third person Character(script)があるとおもいます。
そこでJump　Powerを変更すると変更可能です。
![スクリーンショット 2020-05-29 0.39.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/44023767-5607-68f0-72a4-2c6615bf5b7c.png)


#お問い合わせ
わからないことがあればこちらまで
Twitter：@e_san_desuyo
JavaScript/TypeScriptのasync/awaitを使ったコードの読み方

## 目的
`async/await`を使うと非同期処理を同期的に書けるが、それが故に実行順が直感的に読み取りにくいことがある。

もちろん`async/await`の実体はPromiseなのでそれに読み替えれば正確な実行順はわかるが、ここでは`async/await`のままでどう読んだら実行順が理解しやすいのかまとめる。

## 結論
- `await`キーワードに着目して読む。`await`の次の行から非同期の実行になる[^2]。
- `async`キーワードには着目しなくてよい。

## 詳細
### `async/await`とは
まず、`async/await`とは何かをまとめる。

`async/await`は非同期処理を同期処理のように書けるJavaScriptの構文。

`await`を書くことで非同期処理を同期処理のように呼び出せる。`await`を書けるのは非同期関数(async function)の中だけであり[^1]、async functionを定義するのには`async`を使う。

[^1]: 厳密にはasync functionの中以外で書けるケースがあるのだが、この記事ではそこまで立ち入らない 参考:[top-level awaitがどのようにES Modulesに影響するのか完全に理解する](https://qiita.com/uhyo/items/0e2e9eaa30ec2ff05260)

```js
// fuga()はPromiseやasync function

async function hoge() {
  await fuga();
}

hoge();
```

### `async/await`を使ったコードの挙動

結論を先取りすると、`async`が付いていようがいまいが`await`がない限り非同期実行はされないということが言える。

例えば次のようなコードを考える。

```js
async function fuga() {
  console.log('2');
  return;
}

async function hoge() {
  console.log('1');
  await fuga();
  console.log('3');
}

hoge();
console.log("4");
```

このコードを実行すると、結果はこうなる。

```sh
# 結果
1
2
4
3
```

`await fuga()`の次から非同期実行になっているので、その次の行の3だけ遅れて出力されている。

このコードから`await`を取り除くと、同期的に、順番通りに1、2、3、4が出力される。

```js
async function fuga() {
  console.log('2');
  return;
}

async function hoge() {
  console.log('1');
  fuga();//<-- awaitを取り除いた
  console.log('3');
}

hoge();
console.log("4");
```

```sh
# 結果
1
2
3
4
```


### 結論

- `await`キーワードに着目して読む。`await`の次の行から非同期の実行になる[^2]。
- `async`キーワードには着目しなくてよい。`await`がない限り、`async`が付いていても非同期実行はされない。[^2]

[^2]: ここで言っている非同期実行されない/されるというのは、「同期的に書かれたコードが」非同期実行されない/されるということ
JavaScriptフレームワークってなんなの？歴史から辿る

# JavaScriptフレームワークってなんなの？
最近vueやsvelteを学習し知識をつけているのですが、そこからスタートをしていることで色々な弊害が生まれています。
それは以下の点です。
・フレームワークの書き方なのかJavaScriptの書き方なのかわからない
・フレームワークの恩恵を感じられない
・そもそもJavaScriptってなにvueのことはわかるけど

このように今流行りの技術から学んでしまうと基となるJavaScriptが身についておらず汎用性がなく、そのフレームワークの書き方しかできません。
そこからJavaScriptを学んでいる中でそもそもフレームワークってなんなんすか？何を解決してんの？と疑問に感じ記事にさせていただきました。

# JavaScriptの歴史

## JavaScriptとは
JavaScriptは1995年に誕生しました。
当時はNetscape Navigator 2.0というブラウザに初めて実装されましたが、IEがJavaScriptと互換性のあるJScriptを開発しています。
当時はHTMLとCSSだけの静的ページが一般的で文字だけのシンプルなページばかりでしたが、JavaScriptの誕生によってリッチな表現が可能になりました。
しかし先ほど話したようにこの時点ではブラウザ毎によってJavaScriptの仕様が異なっており、フロントエンジニアを相当悩ませていました。（まじで死にたいレベルらしい）

## ECMAScriptとは
JavaScriptがブラウザ毎に仕様が異なることは先ほど言ったように開発者への負担が半端ないし、セキュリティ的にもダメだと言うことで標準化への取り組みが始まります。
そして1997年に国際標準化団体ECMAインターナショナルがJavaScriptのコアな部分を標準化しましたその言語をECMAScriptと言います。
現在では2016年6月にECMAScript2016(ES6)が公開されています。

しかし標準化されても弱点はありました。それは以下の点です。
・今では簡単にかけるコードが複数行に渡り書く必要があった（コードの複雑化）
・標準化されていてもブラウザが提供したweb APIの取得方法に差異があった

そのため標準化されていても開発者は常にブラウザの互換について考えた開発をしなければなりませんでした。

## jQueryの革命（と言っておきます）
先ほどお話しした課題を解決してくれたのがjQueryです。
ブラウザ毎のweb APIを１つにまとめたことで、ブラウザの差異を無くしてくれました。
またJavaScriptの記述量をより簡潔にしてくれました。
> Queryの最大の功績はなんと言ってもAjaxを簡潔かつわかりやすく書けることでしょう。
これによりサーバー↔クライアント間の通信がページ転移を伴わないでもできるようになりました。
これは現在のSPA（シングルページアプリケーション）の元となります。
>>引用元：[jQueryとは何なのか？　なぜ使わなくても（あるいは使わないほうが）いいのか？](https://qiita.com/ygkn/items/eed01ae9c01339d6086a)

僕自身はその時代を経験していないのですが、こういった声もあり学習を通してすげーじゃんjQueryと讃えたいです。（jQueryはクソではないと思っています）

## 時代が変わるjQueryは終わったのか？
フロントエンジニアの学習を始めた頃からよく耳にする言葉「脱jQuery」
僕はjQueryがダメだとは思いません。
でも、jQueryが解決したい問題はすでに解決され、今の時代は違う問題に注目されていると思います。

jQueryが解決したかった問題は「ブラウザの差異・コードの複雑さ」です。
しかし時代が進みブラウザの際は消え、標準化は進み今では気にしなくなりましたし、jQueryの機能はJavaScriptの標準APIに取り込まれています。

またjQueryはDOMへの依存という以下のデメリットがあります。
・DOMの変更に弱い
　ID以外のセレクタでの操作では影響範囲がでかすぎる
・HTMLとDOMの乖離によって狙った挙動ができない場合がある
・JSをコーディングしながらHTMLを気にしないといけない。

規模が大きくなればなるほど、これらを気にしないといけなく自分の首を締めることになってしまいます。

# 本題：JavaScriptフレームワークってなんなの？
JavaScriptフレームワークは以下の問題点を解決するためだと思います。
・jQueryの問題であったDOMへの依存を解消する
・影響範囲が分かるように役割ごとに閉じ込める
・JSだけでJS同士の依存関係を表現できる
・開発環境の統一

■DOM依存
先ほど説明したjQueryのDOMへの依存という課題から、「仮想DOM」と言う概念が生まれます。

■影響範囲
また影響範囲を役割ごとに閉じ込めるためにコンポーネント思考が採用されている。

■依存関係を表現
依存するライブラリはJavaScriptでimportできず、HTML側に`<script src="">`が必要になる。
フレームワークを利用することによって、1つの環境に閉じ込めることができます。

■依存関係を表現
また開発者がオリジナルのルールを作って開発を行ってきたが、それでは再利用性が低く品質と保守性に欠けます。
そのため予め必要な骨組みが構築され、開発環境の統一をしています。

結局のところJavaScriptフレームワークはJavaScriptの歴史の流れによって感じた課題感を解決するために今は必要なのかなと思います。
工数見積もりにPERT法を試してみた

## 皆さん工数見積もりってどうやってますか？

私は今まで完全に勘で見積もっていました。
特に根拠のない見積もりをしていたので、実際には見積もり時間の1.5~2倍くらいかかってしまうこともありました。

さすがにこのままではまずいと思い、工数見積もりの方法をググってみたところ、[PERT法](https://ja.wikipedia.org/wiki/Program_Evaluation_and_Review_Technique)なるものがあることを知りました。

ちょうど仕事で小規模なタスクがあったので、さっそくPERT法を試してみようと思いました。

PERT法は本来であればPERT図というものを作るのですが、今回は小規模なタスクのため、工数見積もりの部分だけを試してみました。

## PERT法における工数見積もり

PERT法における工数見積もりの特徴として、各タスクに4つの時間を見積もります。

>楽観的時間 (O)
タスク完了に必要な最小時間。先行する作業やイベントが予想よりうまく進行した場合の見積。

>悲観的時間 (P)
タスク完了に必要な最大時間。プロジェクトが崩壊するほどではないが、全てが予想より悪く進行した場合の見積。

>最確時間 (M)
タスク完了に必要と思われる最もそれらしい見積時間。全てが普通に進行した場合の見積。

>期待時間 (TE)
タスク完了に要する時間の最良見積もり値。全てが普通に進行すると仮定する（そのタスクを何度も繰り返し実施したときの平均時間）。
TE = (O + 4M + P) ÷ 6

期待時間を出す式が興味深いですね。
**期待時間 = (楽観的時間 + 4 × 最確時間 + 悲観的時間) ÷ 6**
最確時間に重みをつけているんですね。

## 実際にやってみて

これらの時間を見積もってみたところ、今まで私は楽観的時間に近い時間で見積もっていたことがわかりました。
エンジニアは工数を少なく見積もりがちという話を聞いたことがあります。
まさか自分がやっているとは思いもしませんでした。

また、悲観的時間を見積もるのが難しかったですね。
どのくらい悪い事態を想定するかは人によって基準が違うのではないかと思いました。

実際にPERT法の一部分を試してみて、今までの工数見積もりの甘さを痛感しました。
自分の工数見積もりを見直す良い機会になりました。
偉大な先人たちが編み出した知識はこれからも積極的に使っていきたいですね。

## 参考

[Program Evaluation and Review Technique - Wikipedia](https://ja.wikipedia.org/wiki/Program_Evaluation_and_Review_Technique)
はじめてのThree.js 6章 日記

[はじめてのthree.js](https://www.amazon.co.jp/dp/4873117704)

#新たに知った知識
- latheというのがツボを作る作業
- Three.BSPを使えばイラレのパス結合みたいなことができる(intersect, union, subtract)
- Three.BSPはcoffeescriptで書かれてるのでjsにコンパイルする必要がある。(csも学びたい)
- threejsがサポートするmergeとは違ってunionは新たなオブジェクトを生み出す

#気づいたこと
- uvはここでも出てくる

#wow moment
- ブーリアンができる喜び
- svgの押し出し！！

#まだ解決していない点
- convexgeometryでの点のつなぎ方
- fontのサンプル動かんかった。検証してないけどassetsのリンクがきれてそう


[7章はこちら](https://qiita.com/asadsexyimp/items/8401fe244cbffcbd69bd)
Siemens#VM内のSimAdvと繋ぐメモ

まずPLCSIM virtual Eth. Adapterを選択します。
そしてLocal Area Connectionを選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/45c2443e-2613-0b46-b1ef-4c71fb39cc4c.png)

VMがNATにしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/2da6244c-786c-28e7-4e9e-566a8d2d0043.png)

最後はAdpaterの設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154661/1841ea62-7815-52c7-fddb-d06a45a6a1b2.png)

もしThe NetGroup Packet Filter Driver service failed to startの問題が出たら、

WINPCAPをインストール直しください。

https://www.winpcap.org/install/
Machines Learning 学习笔记(Week7)

## Support Vector Machines (SVM)

###1. SVM Hypothesis

```math
min \, C\sum_{i=1}^m \Bigl[ y^{(i)}cost_1(\theta^Tx^{(i)})+(1-y^{(i)})cost_0(\theta^Tx^{(i)})\Bigr]+\frac{1}{2}\sum_{i=1}^n\theta_j^2
```

###2. Kernels

- Gaussian Kernel:

```math
f_1 = similarity(x,l^{(1)}) = exp\Bigl(-\frac {||x-l_j^{(1)}||^2} {2\sigma^2} \Bigr) = exp \Bigl(- \frac {\sum_{j=1}^n(x_j-l_j^{(1)})^2} {2\sigma^2} \Bigr)
```

- SVM with Kernels

Hypothesis: Given x, compute features $f \in R^{m+1}$

Predict "y=1" if $\theta^Tf \geq 0$

Training:

```math
min \, C \sum_{i=1}^m y^{(i)}cost_1(\theta^Tf^{(i)})+(1-y^{(i)})cost_0(\theta^Tf^{(i)})+\frac{1}{2}\sum_{j=1}^n\theta_j^2
```

Notes:

C (=$\frac{1}{\lambda}$):
Large C: Lower bias, high variance.
Small C: Higher bias, low variance.

$\sigma^2$:
Large $\sigma^2$: Higher bias, lower variance
Small $\sigma^2$: Lower bias, high variance

###3. Using an SVM
Use SVM software package to solve for parameters $\theta$. Need to specify:
 - Choice of parameter C
 - Choice of kernel: No kernel ("linear kernel"), Gaussian kernel, ...

###4. Logistic Regression vs. SVMs
n = number of features, m = number of training examples
- if n is large (relative to m): use logistic regression, or SVM without a kernel ("linear kernel") -- n=10,000, m=10...1,000
- if n is small, m is intermediate: use SVM with Gaussian kernel -- n=1,000, m=10-10,000
- if n is small, m is large: create/add more features, then use logistic regression or SVM without a kernel -- n=1,000, m=50,000+
- Neural network likely to work well for most of the these settings, but may be slower to train
形態素解析はデスクトップの整理に役立つ？

1.はじめに
---
文字×機械学習に興味を持ってきて個人範囲の用途を考え、フォルダ整理に使えないかと思い検討を始めました。
今回の検討ではフォルダ構成＆textの読みとり→mecab×wordcloudを行ってます。結果、特定の階層以下をwordcloudでまとめる事が出来ました。

2.分かったこと
---
形態素解析を使用すると頻出単語の傾向は分かるので、下記の条件化ではファイル整理が出来そうな感触をつかみました。
・text/csvもしくは意味のあるファイル名が全てにおいてつけられている。
・無法地帯のデスクトップになっており、人が時間をかけても管理できそうにない。
→各ファイルを用語が類似しているもの同士、同じフォルダに仕分ける。

ただし、管理されたPCでは実用性がなさそうと考え、検討一時STOPしました。(個人PC/共有PCともに、無法地帯なPCを見たことがない。。。)

3.参考文献
---
・形態素解析ライブラリmecabのインストール方法
https://qiita.com/menon/items/f041b7c46543f38f78f7
・mecab使用方法
https://qiita.com/iwashi-kun/items/18613dee168651ef8016
※なおインストールの環境設定が複雑？な事よりDocker記事も多くありチャレンジしましたが、mecabインストールがそれほど手間取らなかったりホスト-Docker間ファイル受け渡しが個人的に面倒であったので、今回はDockerは外しました。
4.ソース
---
・フォルダ階層とファイルの読み込み

```
import glob
import re
import os
import pandas as pd

#各層のfile名のみ抽出
list =[os.path.basename(p) for p in glob.glob('C:/Users/takat/Desktop/各種memo/**/*', recursive=True)
       if os.path.isfile(p)]

#textのみ、開いて文字列取得
for p in glob.glob('C:/Users/takat/Desktop/各種memo/**/*', recursive=True):
    if '.txt' in p:
        f = open(p,'r',encoding="utf-8",errors='ignore')
        list.insert(0,f.read()) # 1行毎にファイル終端まで全て読む(改行文字も含まれる)
        f.close()        
dflist = pd.DataFrame(list, index=range(len(list)),columns=["file"])
```
・mecabを使用(前述URLとほぼ同内容)

```
%matplotlib inline
import matplotlib.pyplot as plt
from wordcloud import WordCloud, STOPWORDS
import MeCab
import pandas as pd
#create mecab list
class_num = 0
word_classes = [u'名詞',u'動詞',u'形容詞',u'副詞',u'助詞',u'助動詞']

word_class = word_classes[class_num]
def create_mecab_list(text):
    mecab_list =[]
    mecab = MeCab.Tagger("-Ochasen")
    mecab.parse("")
 #   encoding = text.encode('utf-8')
    mecab.parse('')
    node = mecab.parseToNode(text)
    while node:
        if len(node.surface)>1:
            if node.feature.split(",")[0]==word_class:
                morpheme = node.surface
                mecab_list.append(morpheme)
        node = node.next
    return mecab_list
newstext = " ".join(create_mecab_list(",".join(dflist.file)))

```
・wordcloudを表示(前述URLとほぼ同内容)

```
wordcloud = WordCloud(
    max_font_size=140,
    relative_scaling=.5,
    width=1000,
    height=1000,
    stopwords = word_class,
    font_path='ipaexg.ttf'
    ).generate(newstext)
#fontファイルはipynbと同じ階層に保管もしくはパスを入れる
plt.figure(figsize=(10,10),dpi=200)
plt.imshow(wordcloud)
plt.axis("off")
plt.show()

```
5.出力
---
自分の頭の中が表示されているみたいで恥ずかしい。。。
LINEやメールをwordcloudにするもの作ったら爆死しそう。
せめて飲み会での会話をGCPとかで文字起こししながらwordcloud更新させていったらおもしろそう？
![wordcloud.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448643/e90fecfc-e623-8e18-9ab5-7ed40a1ed845.png)

6.次のアクション
---
自動で整理したくなるようなPCを見つけるまで一旦検討STOP～
Route53でドメインを購入方法

#目的
個人アプリを制作していてssl化が必要だったため
筆者の備忘録
##ssl化がどうして必要なのか

sllとはサーバとブラウザ間の通信を暗号化させる役割を担っているいます。
暗号化することにより、ハッカー、盗聴などを防ぎ、データ送受信を安全に行うことができるようです。
鍵のついたサイト下がsslしているサイトです。urlの頭にはhttpsと書いてあるサイトです。（httpではない）
<img width="105" alt="ssl.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589433/e6e81a49-4511-41b9-d7c5-d947b0afead1.png">

わかりやすく言うとsslは、
安全なサイトの証明！

今までは、決済（クレジットカード等）や個人情報に関わるページ等でsll化すればよかったが、セキリティーに対する高まりから「常時ssl化」が必要になっているようです。
Google ChromeでもSSL対応されていないWebサイトに対して警告アラートがでています。
つまり、サイトを作る際にはssl化をしていないとクライアントに使われないことが分かります。

##前提条件
AWS、ALB(Application Load Balancer)、ec2、を活用します。

##ssl化までの手順
[Route53でドメインを購入（有料です）](https://qiita.com/takashi8816/items/d6d7edc711494dd24e0d)　
[AWS Certificate Manager(ACM)でSSL証明書の発行](https://qiita.com/takashi8816/items/c82c7f69256863df5b38) <=今回はここ
[ロードバランサーでALBにhttpsの設定を入れて作成](https://qiita.com/takashi8816/items/6dbbfe1d91724be5f6bb)
Route53でAレコードのエイリアスを作成

#Route53でドメインの購入

AWSのサービスからRoute53を選択
ドメイン登録で好きな名前でドメイン名を記入　チェックを選択
<img width="773" alt="aws.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589433/fd39b996-fd8a-1e9c-9398-09103e6a0a7e.png">

ドメイン名がかぶっていいなければ
<img width="1089" alt="aws1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589433/b61f369d-c1da-3bda-72c7-4a179a65c1dc.png">
カートに入れて購入

続く[AWS Certificate Manager(ACM)でSSL証明書の発行](https://qiita.com/takashi8816/items/c82c7f69256863df5b38)
偶数か奇数か

# 偶数か奇数か判定するプログラム
言語習得の初期によく出てくる偶数か奇数かを判定するプログラムを改めて。

###プログラム
#####python

```python:pythonevenoroddjudge.py
def is_even(num):
    return num % 2 == 0


num = float(input())

print(is_even(num))
```

#####julia

```julia:juliaevenoroddjudge.jl
function is_even(num)
    return num % 2 == 0
end
function asknumber()
    print("Enter a number: ")
    parse(Float64, readline())
end
num = asknumber()
is_even(num)
```

juliaのコードではわざわざfunctionを使っているがif文でも書ける。それについてはまた違う記事で。

##### rust

```rust
use std::io;
use std::io::Write;
use std::io::stdout;
 
fn main() {
 
    println!("input number : ");
        stdout().flush().unwrap();
 
    let mut number = String::new();
 
    io::stdin().read_line(&mut number)
        .expect("failured!");
 
    let number: u32 = number.trim().parse()
        .expect("input number");
 
    if number % 2 == 0 {
        println!("{} is even",number);
    } else {
        println!("{} is odd",number);
    }
}
```


ほかの言語も後で書きます。
【Bash】ターミナル上で今いるgitのブランチ名を常に表示する

#やりたいこと
<img width="887" alt="スクリーンショット 2020-05-28 23.52.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296645/30172722-dc0a-b8f3-8e81-9757dc4c8dbd.png">

ローカルリポジトリで開発中、ちょくちょく今いるブランチを間違えてコミットしてぐちゃぐちゃになることがありました。ずっとターミナルにカレントブランチ表示してたら間違えないだろうと言うことでやり方を調べました。
#環境（念のため）
Mac
Bash
ターミナル

#手順

1.https://github.com/git/git/blob/master/contrib/completion/git-prompt.sh にアクセスしてソースをダウンロード（Rawボタン右クリック、ファイルを保存）

ダウンロードフォルダにあるファイルを以下コマンドで移動。

```bash
cp /Users/<ユーザ名>/Downloads/git-prompt.sh /usr/local/etc/bash_completion.d/git-prompt.sh
```

2.bash_profileに以下を追記

```bash
vi ~/.bash_profile
```

```vim
#show git branch
source /usr/local/etc/bash_completion.d/git-prompt.sh
GIT_PS1_SHOWDIRTYSTATE=true
export PS1='[\u@\h: $(__git_ps1 "(%s)")\W]\$ '
```

以上でカレントブランチが表示されるようになります！

ありがとうございました。
【シェルスクリプト】接続1回でSQLを繰り返し実行

大量データを投入する際に使用しました。
パイプで繋ぐことで接続回数を1回にしています。
参考にしていただければと思い記載いたします。

##シェルスクリプト

```sh:sample.sh
(for line in `cat list.txt`
do
  echo @dir/sample.sql $line
done) | sqlplus  -s  user/password@接続文字列
```

- テキストファイル(list.txt)を一行ずつ変数(line)に代入。
- 変数(line)をsqlファイル(sample.sql)の引数に渡す。
- パイプで繋ぐことでechoの出力をsqlplusにする。

##PL/SQL

```sql:sample.sql
DECLARE
  -- 引数を受け取る
 vNUM  NUMBER(2) := &1;
BEGIN
  -- 実行
	INSERT INTO TABLE (NUM) 
        VALUES (vNUM) ;
	COMMIT ;
EXCEPTION
  -- 例外処理
END;
/
```

- 変数(vNUM)に受け取った引数(&1)を代入。
- 変数(vNUM)を値にし実行

##参考
シェルスクリプト内でsqlplusを実行する
https://qiita.com/mon_tu/items/c85e92c019c5ee505121

まずはこれだけPL/SQL【第1回 変数・制御構文・カーソル・例外処理まで】
https://qiita.com/ikep/items/fd710bb5645d90c5b77d
【Ruby on Rails】Gemfail メモ

#目次
・Gemとは

・Gemfileとは 

・bundle install コマンド

・Gemの一例
1.device
2.haml-rails
3.sprockets
4.font-awesome-sass
5.rails-i18n
6.carrierwave




#Gem 
Rubyで書かれたプログラムをパッケージ化したもの。
複雑な機能実装でも、Gemをアプリへ読み込ませることによって、非常に簡単に実装をすることができる。


#Gemfile 
Railsアプリケーション内で使用するgemはGemfileに記載して管理する。
そして、それらのgemはbundlerによって管理されている。



#bundle install コマンド
Gemfileに記載されているgemを、アプリケーションに適用するためのコマンド。

```
% bundle install
```

以下はGemの一例
#1.device
ユーザー管理機能を簡単に実装できるようになる。

#2.haml-rails
railsでhamlがかけるようになる。

#3.sprockets
アセットファイル（JS, CSS, 画像など）を効率的に管理するための Asset Pipeline という仕組みの基盤。
※Asset Pipelineとは
javaScript や CSS、画像ファイルといった HTML に付随する細々としたファイル達（アセットファイル）を連結したり圧縮することで効率的にアクセスできるようにする仕組み。

#4.font-awesome-sass
無料で使えるwebフォントアイコンであるFont Awesomeを簡単にrailsで使うことができるようになる。

#5.rails-i18n
Railsアプリを作成する際、validateのメッセージや、ボタンの文言などは通常英語で表示されている。
これを日本語に切り替えることができる。

#6.carrierwave
画像をサーバにアップロードするしくみを簡単に実装できるようになる。

#7.mini_magick
アップロードした画像のリサイズ等を簡単に実装出来るようになる。
前提として、MiniMagickを使うにはImageMagickというものをインストールする必要がある。