OmniAICreator/Qiita-1.07M huggingface dataset:
【初心者向け】RailsのActive Recordの解説&メソッドまとめ

# はじめに
いつも何気なくコントローラに`@blog = Blog.new`とか`@user = User.find(params[:id])`とかよく考えずに書いていました。
Railsすごいなあ、楽だなあとか思ってたんですけどこれって厳密にいうとRailsじゃなくてActiveRecordのおかげなんですよね。
そこで今回はいつも何気なく使っているActiveRecordについてできるだけやさしく解説してみました。

# ActiveRecordとは
一言で言えば**「RubyとSQLの翻訳機」**です。

基本的にDBにはDB言語として**SQL**が使われています。
SQLでないとDBの操作ができません。

しかし、RailsにはModelにActiveRecordが適用されているおかげで、**Ruby**を用いてDBからデータを探したり、持ってきたりすることができます。
(厳密にはModelにApplicationRecordを介してActiveRecordが適用されているため)

```ruby:app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base #ここでApplicationRecordにActiveRecordを継承
  self.abstract_class = true     
end
```

```ruby:app/models/blog.rb
class Blog < ApplicationRecord #BlogモデルにそのApplicationRecordを継承
end
```

図で表すとこんな感じ

<img width="1194" alt="スクリーンショット 2018-10-05 8.30.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/276589/960a8237-002f-e39d-33ed-c36932ec7210.png">


# ActiveRecordのメリット
###○ Rubyで直感的に書ける
例えば、みなさんが何気なくこの名前のユーザーをDBから探したいなあとか思って書くこれや

```ruby
User.find_by(name: "ryokky")
```

値をDBに保存したいときに書くこれ

```ruby
User.create(name: "ryokky")
```

このようにDBの中をのぞいたり、レコードを作成するときにSQLではなく、みなさんにより馴染みのあるRubyで書けるようになります。

###○どのDBを使用してもRubyで統一できる
DBにはMySQL、PostgreSQL、SQLite、SQL Server、Oracleなどいろんな選択肢があります。
また、それぞれのDBごとに書き方が微妙に違います。
その書き方をすべて**Ruby**で記述できるようにしてくれます。

# ActiveRecordでよく使うであろうメソッド

冒頭にも書きましたがいつもコントローラに書いているものたちは大体ActiveRecordのメソッドです。
今回はCRUD（「Create：生成」、「Read：参照」、「Update：更新」、「Delete：削除」）に沿って紹介します。
紹介しきれないので主要なものだけ

###○Create（生成）に関するメソッド

```ruby
@blog = Blog.new(title: "タイトル", content: "内容")
#blogモデルのインスタンスを作成

@blog = Blog.build(title: "タイトル", content: "内容")
#newと同じ、可読性を上げるため関連モデルのインスタンスにするときによく使われる

@blog.save
#newやbuildで作った@blogをDBに保存する

Blog.create(title: "タイトル", content: "内容")
#newとsaveを組み合わせて生成と同時にDBへ保存する。
```


###○Read（参照）に関するメソッド

```ruby
@blog = Blog.all
#blogsテーブルから全レコードを配列として取得

@blog = Blog.first
#blogsテーブルのidが一番小さいレコードを取得

@blog = Blog.last
#blogsテーブルのidが一番大きいレコードを取得

@blog = Blog.find(1)
#引数に入っている数字と同じidのレコードを取得

@blog = Blog.find_by(title: "タイトル")
#引数に入っている条件と合っているもので一番若いidのレコードを取得

@blog = Blog.where(title: "タイトル")
#引数に入っている条件と合っている全てのレコードを取得

@blog = Blog.order(id: :desc)
#引数に入っているカラムを:asc(昇順)または:desc(降順)に並び替えてレコードを取得

@blog = Blog.select(:title)
#引数に入っている名前のカラムのみを取得

@blog = Blog.limit(3)
#引数に入っている数字の数だけidの若い順にレコードを取得
```

参照系のメソッドは便利なものが多くあります。
また、メソッドチェーンでもっと細かく指定することも可能です。

###○Update（更新）に関するメソッド

```ruby
@blog.update
#findやfind_byで取得したレコードを元に更新
```

###○Delete（削除）に関するメソッド
```ruby
@blog.destroy
#findやfind_byで取得したレコードを削除
```


もっとメソッドの種類や使い方を知りたい方はこちらの記事が参考になりましたのでどうぞ
参考：[ActiveRecord CRUDサンプル](https://qiita.com/leon-joel/items/ab39f46cb374f57f7481)

# 終わりに
Railsを勉強し始めた方のためにほんとにさわりだけ今回は紹介してみました。
書いていて自分でもぼやっとしてたところが埋められた気がします。
他にもわかりやすい記事などありましたので紹介しておきます。
[Rails初心者が Active Reccordについてまとめてみた](https://qiita.com/kogriffey755/items/a7623d44e77012acdc35)
ここでは触れてないですがO/Rマッピングについても書かれているのでぜひ！
List<Integer>でremove(int),remove(Integer)するとどうなるか？

Listでは以下のメソッドが定義されている.
・remove(int index)
・remove(Object o)

前者はインデックス指定で削除するもので、後者はオブジェクト指定で削除するもの.

さて「Integerの場合にどのような動作になるのだろうか？」というのが問題.

結果を見てもらえば瞭然だが、引数がintの場合はインデックス削除になっており、Integerの場合はオブジェクト削除になっている.

一応常識的な結果ではあるが「List<Integer>の削除では、AutoBoxingを当てにしてはいけない」ということになる.

これでバグったら、ちょっと分かりにくいような気がする....

```Tips0004.java
package jp.avaj.lib.algo;
import java.util.List;
import jp.avaj.lib.test.L;

public class Tips0004 {
  public static void main(String[] args) {
    Integer[] integerArray = new Integer[] {
      9,8,7,6,5,4,3,2,1,0
    };
    List<Integer> integerList;

    // インデックスで削除(しているつもり).
    integerList = ArArray.toList(integerArray);
    integerList.remove(8);
    L.p(ArObj.toString(integerList));

    // オブジェクトで削除(しているつもり).
    integerList = ArArray.toList(integerArray);
    integerList.remove(new Integer(8));
    L.p(ArObj.toString(integerList));
  }
}
```

結果は以下の通り。


```実行結果
[9, 8, 7, 6, 5, 4, 3, 2, 0]
[9, 7, 6, 5, 4, 3, 2, 1, 0]
```
【python】波形からしきい値以上の値をしきい値に変更する

ある波形のしきい値以上の部分をカットします。
サンプルとして正弦波を生成しています。

```ruby:qiita.rb


# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
import math
import copy

def main():
    # データのパラメータ
    N = 10000             # サンプル数
    dt = 1*1e-4           # サンプリング間隔
    fq1, fq2 = 10, 10     # 周波数
    t = np.arange(0, N*dt, dt) # 時間軸
    pi = math.pi               # π
    phi = 90                   # 位相
    phirad = phi*pi/180        # 位相ラジアン

    # 時間信号を生成（周波数f1の正弦波+周波数f2の正弦波）
    f = 10*np.cos(2*np.pi*fq1*t) + 10*np.cos(2*np.pi*fq2*t+phirad) 

    F = copy.copy(f)  # 参照でなく複製する

    i = 0
    limit = 3 #しきい値

#    見直し前
#    for dummy in F:
#        if F[i] > limit:
#            F[i] = limit
#        i += 1

    for i in range(len(F)):
        if F[i] > limit:
            F[i] = limit

    # 確認用
    plt.plot(t, f)
    plt.show()       # 元波形

    plt.plot(t, F)
    plt.show()       # カット波形


if __name__ == "__main__":
    main()
    
```

実行前
![Figure_1.png](https://qiita-image-store.s3.amazonaws.com/0/298671/0a2a4a60-7ccf-f029-1cad-5576d1b2aa31.png)

実行後
![Figure_1-1.png](https://qiita-image-store.s3.amazonaws.com/0/298671/fef76a6c-f33f-e64f-a11d-dac4ef8b184d.png)
[Spring Boot] パラメータライズドテストの書き方

# 環境

|ライブラリ名|バージョン
|---|---|
|spring-boot|2.0.4.RELEASE|
|kotlin|1.2.60|
|junit|5|

# パラメータライズドテストとは？
一言でいうと、**一つのテストメソッドにパラメータを与えて複数のテストをするもの**
具体的にはコードで説明して行きます。

# テストコード
- 偶数かどうかを判定するメソッドが存在する
- 偶数の場合はtrueを返し、奇数の場合はfalseを返す

```kotlin
/**
* テスト対象のメソッド
*/
fun isEven(num: Int): Boolean {
  return num % 2
}


fun patterns(): List<TestDataPattern> {
  return listOf(
    TestDataPattern("数字が奇数の場合", 1),
    TestDataPattern("数字が偶数の場合", 2)
  )
}

/**
* @param message テストの際に表示するメッセージ
* @param parameter テストする値
* @param expected テストが期待する結果
*/
data class TestDataPattern(val message: String, val parameter: Int, val expected: Boolean)

@ParameterizedTest
@MethodSource("patterns")
fun testIsEven(pattern: TestDataPattern) {
  assertEquals(pattern.expected, isEven(pattern.parameter), pattern.message)
}
```

パラメータライズドテストをするメソッドにはアノテーションで`@ParameterizedTest`をつける。
`@MethodSource("patterns")`によって、`patterns`というメソッドの返り値が引数`pattern`に順番に入ることで実行される。
ターミナルでのファイルパス指定をpecoを使って高速にする

以前、[pecoを使って端末操作を爆速にする](https://qiita.com/reireias/items/fd96d67ccf1fdffb24ed)で紹介した`Ctrl + F`でのファイルサーチをもっと使い勝手よくしてみました。

Gitリポジトリ検索やコマンド履歴検索はとても快適だったのですが、ファイル検索が少し使いづらかったので改良してみました。

## 課題
- Homeディレクトリで検索すると、対象が多すぎてフィルタリングが辛い
- 検索して見つかったファイルと、その周辺のファイルを編集したいので、その近辺のディレクトリに移動したいが面倒

## 改良後
### `(何も入力せずに) <Ctrl + F>`

ファイルを選択した場合
![peco2_nocom_file.gif](https://qiita-image-store.s3.amazonaws.com/0/214526/331df83f-9e88-72f4-f710-4e4df69bf0d4.gif)

ディレクトリを選択した場合
![peco2_nocom_dir.gif](https://qiita-image-store.s3.amazonaws.com/0/214526/21627760-a578-547b-ba9b-4012d44d2a6b.gif)


ターミナルに何も入力していない状態で呼び出した場合、カレントディレクトリ以下のファイルが候補として列挙されます。

選択後はファイルのタイプに応じて挙動が変わります。

- ファイルを選択する
  - → vimで開く
- ディレクトリを選択する
  - → cdで移動

### `command <Ctrl + F>`
![peco2_command.gif](https://qiita-image-store.s3.amazonaws.com/0/214526/5c989859-3427-c3af-cb45-fefd557e025b.gif)


コマンド等を入力し、**スペースを入力した後**、呼び出した場合も、カレントディレクトリ以下のファイルが候補として列挙されます。

選択後は、入力途中だったターミナルの末尾にファイルパスが入力されます。


### `command /path/to/base/<Ctrl + F>`

![peco2_path.gif](https://qiita-image-store.s3.amazonaws.com/0/214526/f7a59e4b-277d-373e-83e6-8549492b08fe.gif)


ファイルパスの入力途中で呼び出した場合は、そのパス以下のファイルが候補として列挙されます。(これがやりたかった)

選択後は、入力途中だったターミナルの末尾にファイルパスが入力されます。

なお、入力中のパスが実在しない場合は、カレントディレクトリ以下が候補となります。

## .zshrc

.zshrc中に以下の関数を定義すると使えるようになります。

```zsh
export EDITOR=vi
function peco-find () {
    local base="."
    if [ -n "$LBUFFER" ] && [ ! "$LBUFFER" =~ " $" ]; then
        local last_path="$(echo $LBUFFER | sed -e 's/^.*\ //g')"
        if [ -d "$last_path" ]; then
            base="$last_path"
        fi
    fi
    local filepath="$(find $base | grep -v '/\.' | peco --prompt 'PATH>')"
    [ -z "$filepath" ] && return
    if [ -n "$LBUFFER" ]; then
        if [ "$base" = "." ]; then
            BUFFER="$LBUFFER$filepath"
        else
            BUFFER="$(echo $LBUFFER | sed -e "s#${base}\$##g")$filepath"
        fi
    else
        if [ -d "$filepath" ]; then
            BUFFER="cd $filepath"
        elif [ -f "$filepath" ]; then
            BUFFER="$EDITOR $filepath"
        fi
        zle accept-line
    fi
    CURSOR=$#BUFFER
}
zle -N peco-find
bindkey '^F' peco-find
```


## 動作環境
以下の環境で確認しました。

- Linux Mint 18.3
- peco v0.4.5
- zsh 5.1.1 (x86_64-ubuntu-linux-gnu)
入力されたマンセル値を要素ごとに分解する


プログラミングの勉強を初めて3日目でPython3の復習として何かできないかと思い, とりあえずマンセル値を要素ごとに分解してみた
# 前提とコード
- マンセル表色系は色を<b>色相</b> (Hue, h), <b>明度</b> (Value, v), <b>彩度</b> (Chroma, c) で色を表現する方法 ([Munsell Color System](https://munsell.com/)).<br>
- <b>「h v/c」</b>の形で表記される.<br> 
	- e.g.) <b>5YR 2.5/12</b><br>
		- 色相 (Hue): 5YR<br>
		- 明度 (Value): 2.5<br>
		- 彩度 (Chroma): 12<br>
- 無彩色の場合は, 色相「N」と明度のみで表される.
	- e.g.) <b>N 4.5</b><br>
		- 色相 (Hue): N<br>
		- 明度 (Value): 4.5<br>

入力値が, <b>「h c/v」(有彩色)</b> の場合と,<b>「h v」(無彩色) </b>の場合があるため,
1. まず, 入力値を「h」と「v/c」に分解し, 
2. 「h」の値で有彩色か無彩色かを判別して処理を分ける.

```python3
# coding: utf-8
#標準入力に"h v/c"の形式でマンセル値を入力し, munsell_code変数に代入
munsell_code = input()

#hとv/cを分離
divH_VC = munsell_code.split()

#Hue変数にhを代入, tempVC変数にv/cを代入
Hue = divH_VC[0]
tempVC = divH_VC[1]
print("Hue:" + Hue)

#無彩色と有彩色で条件分け
#無彩色の場合, tempVCをValueとして出力
if Hue == "N":
    print("Value:" + tempVC)
#有彩色の場合, v/cを/で分離
else:
    divV_C = tempVC.split("/")  
    #Value変数とChroma変数にそれぞれvとcの値を代入
    Value = divV_C[0]
    Chroma = divV_C[1]
    print("Value:" + Value)
    print("Chroma:" + Chroma)
```
#入出力例
入力1
`10YR 4.5/12`
出力1
`Hue:10YR`
`Value:4.5`
`Chroma:12`

入力2
`N 5.5`
出力2
`Hue:N`
`Value:5.5`
# 今後の目標
入力値が正しくない場合 (h v/cの間にスペースがない，不適切な場所にスペースがある等) の処理なども追加したい.
windowsにてanacondaでopencvを入れようとすると、pipがout-datedかつアクセス拒否

##背景
opencvでやりたいことがあったので、久しぶりのpythonでopencvをしようと、
anacondaでopencvを入れようとしたらpipのバージョンが古いとか、アクセスが許可されないとか。。。

##opencvを入れる

anacondaで
environments→rootか他のenvでTerminalを開いて、

```cmd.exe
pip install opencv-python
```
すると、以下のような記述が出てきました。

>PermissionError: [WinError 5] アクセスが拒否されました。: 'C:\\Users\\user\\.........

pipのversionが古いから、新しくしたらできるよってアドバイスを添えてくれていたので、pipを更新した。

```cmd.exe
pip install --upgrade pip
```

またさっきのエラーが出てきた。

>PermissionError: [WinError 5] アクセスが拒否されました。: 'C:\\Users\\user\\.........


##調べる
以下のようにするといいらしい。→https://code.i-harness.com/ja/q/1ead5fa

```cmd.exe
python -m pip install --upgrade pip
```
んーーー**無理だ。**



当たり前のようだけど、アクセスが拒否されたなら管理者権限で突っ込んでやれば良さそう。
　　→https://teratail.com/questions/90377
###管理者権限で突っ込もう。

```cmd.exe
'sudo' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
```

まあ、無理（windowsではsudoは使えない）
ってことでanacondaのterminalのまま管理者権限を得る方法を調べた。→https://qiita.com/fjtter/items/4b7fe797ae1155c69dd9

```cmd.exe
powershell start-process cmd -verb runas
```

このコマンドで、コマンドプロンプトを新しいウィンドウを開ける。
しかし、Anaconda Promptではなくなるので、仮想環境から出てしまうので不可。

###easy_installでいれる
```cmd.exe
easy_install -U pip
```
-Uは--upgradeと同じらしい。僕はこれでできた。ふぅぅ。


##まとめ
調べてる感じ、同じようなエラーでもエラーが出なくなる解決策は千差万別の模様。

##参考
このサイトが結局まとまってわかりやすさはあったが英語
　→https://stackoverflow.com/questions/15221473/how-do-i-update-pip-itself-from-inside-my-virtual-environment
GitLab で Mattermost を有効化する

## 概要
GitLab EE のOmnibus Installer でインストールされたMattermost を有効化し、同一サーバーでホストする。

## 手順
### Mattermost の有効化
* DNSの設定を変更し、GitLabと異なるURLで同じサーバーに到達できるようにする。 例: `gitlab.example.com` と`mattermost.example.com`

* GitLabの管理者画面でMattermost用のアプリケーションキーを作成する
  - GitLab `AdminArea` -> `Application` -> アプリケーションを作成するボタンを押す
  - Callback URLに`http://mattermost.example.com/signup/gitlab/complete` と`http://mattermost.example.com/login/gitlab/complete`を２行で入力する。mattermostのURLに書き換えて入力する。httpsを使用している場合はhttpsにする。
  - scopeは`api`にチェックを入れる。
  - 保存して表示される`Application ID`と`Secret`を控える。

* GitLabの設定ファイルを変更する

```rb:/etc/gitlab/gitlab.rb
mattermost_external_url 'http://mattermost.example.com'

mattermost['gitlab_enable'] = true
mattermost['gitlab_id'] = "<GitLabで作成したApplication ID>"
mattermost['gitlab_secret'] = "<GitLabで作成したSecret>"
mattermost['gitlab_scope'] = "api"
mattermost['gitlab_auth_endpoint'] = "http://gitlab.example.com/oauth/authorize"
mattermost['gitlab_token_endpoint'] = "http://gitlab.example.com/oauth/token"
mattermost['gitlab_user_api_endpoint'] = "http://gitlab.example.com/api/v4/user"

```
GitLabのURLは自分のものに書き換える。

* 同一サーバーでホストする場合、`/etc/hosts`を修正する

```bash:/etc/hosts
127.0.0.1 localhost gitlab.example.com mattermost.example.com
```
gitlabとmattermostにローカルループバックで接続できるようにしないと、この後のOAuthのトークン認証で失敗する問題があるため、この設定を行う。
参考： [Mattermost \- Token Request Failed when using Gitlab SSO \(\#2984\) · Issues · GitLab\.org / omnibus\-gitlab · GitLab](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/2984)

* GitLabを再構成する　`sudo gitlab-ctl reconfigure`

* Mattermost にアクセスする　例　`http://mattermost.example.com`

* GitLabアカウントでログインし、続いて表示される画面でGitLabの情報へのアクセスを許可する

### httpsの有効化
* SSL証明書と証明書キーを```/etc/gitlab/ssl```に置く
* GitLabの設定ファイルを更新する

```rb:/etc/gitlab/gitlab.rb
mattermost_external_url 'https:/mattermost.gitlab.example'

mattermost_nginx['redirect_http_to_https'] = true
mattermost_nginx['ssl_certificate'] = "/etc/gitlab/ssl/mattermost-nginx.crt"
mattermost_nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/mattermost-nginx.key"
mattermost['service_use_ssl'] = true
```

デフォルトの設定ファイルに記載されていない行は追加する。
証明書のファイル名は置いたものに合わせて更新する。
pem形式の場合は、`ssl_certificate`に`fullchain.pem`を、`ssl_certificate_key`に`privkey.pem`を指定する。

* GitLabを再構成する　`sudo gitlab-ctl reconfigure`

### メール通知を有効化する
* Mattermost にアクセスする　例　`http://mattermost.example.com`

* メインメニュー -> `System Console` -> `Notification` -> `Email`
* 各項目を設定して保存する。
    * 設定例(SendGridの場合):
    * `Enable Email Notification` : `Enable`
    * `SMTP Server` : `smtp.sendgrid.net`
    * `SMTP Server Port` : `587`
    * `Enable SMTP Authentication` : `Enable`
    * `SMTP User` : `apikey`
    * `SMTP User Password` : SendGridで作成したAPIキー
    * `Connection Security` : `STARTTLS`

    * 注意： Send Test ボタンは、パスワードが***の表示になっていると動作しないので、平文で入力された状態で確認する

## 参考
* [doc/gitlab-mattermost · cron-for-docker · GitLab.org / omnibus-gitlab · GitLab](https://gitlab.com/gitlab-org/omnibus-gitlab/tree/cron-for-docker/doc/gitlab-mattermost#gitlab-mattermost)
* [Mattermost - Token Request Failed when using Gitlab SSO (#2984) · Issues · GitLab.org / omnibus-gitlab · GitLab](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/2984)
SFTPのファイルオブジェクトを取得する (Perl/Ruby/Python)

| |URL|
|:--|:--|
|基本|https://qiita.com/cielavenir/items/9d068c49186060a47650|
|Pythonの.ssh/config読み出し|https://qiita.com/cielavenir/items/6aa9e6dc1166ae947c6f|
|大きいファイルの取得|https://qiita.com/cielavenir/items/f38223c156e4aaab58ad|

- Getting file object on SFTP.
- The situation to get my authorized_keys is arbitrary.

## Perl

```pl:sftp_file.pl
#!/usr/bin/perl
use strict;
use Net::SFTP::Foreign;
my $sftp = Net::SFTP::Foreign->new('localhost'); #,user=>$ENV{'USER'});
my $fh = $sftp->open('.ssh/authorized_keys',Net::SFTP::Foreign::Constants::SSH2_FXF_READ);
my $file_content;
for(<$fh>){$file_content.=$_;}
$fh->close;
print $file_content;
$sftp->disconnect;
```

## Ruby

```rb:sftp_file.rb
#!/usr/bin/ruby
require 'net/sftp'
Net::SFTP.start('localhost',nil){|sftp| # ENV['USER']
	sftp.file.open('.ssh/authorized_keys','r'){|file|
		puts file.read
	}
}
```

## Python

configで凝ったことをしている場合は https://qiita.com/cielavenir/items/6aa9e6dc1166ae947c6f が必要です

```py:sftp_file.py
#!/usr/bin/python
#Py2/Py3 are supported
import os,sys
import paramiko
with paramiko.SSHClient() as ssh:
	ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
	ssh.connect('localhost') #,username=os.environ['USER'])
	with ssh.open_sftp() as sftp:
		with sftp.file('.ssh/authorized_keys','r') as f:
			sys.stdout.write(f.read().decode('utf-8'))
```
LibTorch(PyTorch C++ API)を使う

PyTorch 1.0 のリリースが間近ですね!

PyTorch C++ API 使いたいですね!

PyTorch C++ API のドキュメントはここにあります.

https://pytorch.org/cppdocs/

しかしこれを参考に MNIST サンプルをビルドしようとしても `torch::data` が見つからないとエラーになります(2018 年 10 月 6 日時点)

Forum にレポートが上がっています.

C++ frontend has no member ‘torch::data’
https://discuss.pytorch.org/t/c-frontend-has-no-member-torch-data/26425

こちらの PR がマージされるのを待ちましょう.

https://github.com/pytorch/pytorch/pull/11918

=> マージされました！(2018 年 11 月 12 日確認) Happy libtorch C++ programming!
php-master-changes 2018-10-05

今日は昨日に引き続き Windows での readlink 周りの修正、zend_oparray_context からの不使用フィールドの削除、空の配列を複製する際のメモリ消費量改善があった！

# 2018-10-05
## weltling: Ensure target is \0 terminated
- https://github.com/php/php-src/commit/40979277c0bf17d83272e42ffb26c3c0dc38f913
- [昨日分](https://qiita.com/sj-i/items/4fccd5431a78841d6927#weltling-refactor-php_sys_readlink)　に引き続き Windows の readlink 周りの修正
- 文字列用の領域がヌル終端されることを確実に

## nikic: Remove unused backpatch_count field
- https://github.com/php/php-src/commit/a515f607906b25dee795a712097a0599e4aceedb
- コンパイル時に使われる zend_oparray_context から使われていない backpatch_count を削除

## pmmaga: Use HT_MIN_SIZE when duplicating an empty array
- https://github.com/php/php-src/commit/c2c202193ae6433d09234d2e45f04e62e51deb83
- 空の配列を複製する際に HT_MIN_SIZE をハッシュテーブルのサイズ指定に使うよう修正
- 一度大きなサイズに成長した配列を空にしてからコピーする際のメモリ効率に影響
- [PR](https://github.com/php/php-src/pull/3576) が出てスッとマージされたやつ
PC重たいのでターミナルでQiitaの記事検索・閲覧ツール[gota]を作った

こんにちわ

外で作業するときに使用しているMacBookのパワーが足りなくてブラウザがもっさりしているので、
Qiitaの記事を探したり見たりするのをターミナルでできたら、作業スピード上がりそうじゃない？と思ったので作りました。

こんな感じです。
[![asciicast](https://qiita-image-store.s3.amazonaws.com/0/66178/42a2fed4-30a4-0165-1ff5-bcd68ad40d10.png)](https://asciinema.org/a/204837)

# できること
- **記事の検索**
入力したキーワードがタイトルに含まれている記事一覧を表示します。
今はまだ検索条件を指定できないが、これからできるようにしていく予定です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/66178/2448ec68-b10b-23ce-ca30-67273749f34f.png)

- **検索結果の絞り込み**
検索結果から更にキーワードによる絞り込みができます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/66178/67a96e2a-3b83-42fa-63b2-fe611a7eea35.png)

- **記事閲覧**
browserを開いて閲覧するか、ターミナルに出力して閲覧するかを選択できます。
browserの場合はデフォルトブラウザが開きます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/66178/6e1fa069-3c77-4a3b-c77d-bd5e6e8da4f9.png)
terminalの場合は標準出力になります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/66178/f24db9d7-5d58-1076-071c-ccf975bf9d22.png)
ただし、ブラウザで開くのはWindowsとMacのみ対応しています。
それ以外のOSは手動で開くか、terminalで見るかになります。

- **操作方法**
    - **記事検索時**  
      `Ctrl+d`:終了  
      `Ctrl+c`:終了  
      `Enter`:検索  
    - **検索結果一覧時**  
      `Ctrl+c`:検索  
      `Ctrl+d`:終了  
      `jkhl` or `←↓↑→`:記事の選択  
      `Enter`:記事の閲覧方法選択  
    - **閲覧方法選択時**  
      `Ctrl+c`:検索  
      `Ctrl+d`:終了  
      `Enter`:閲覧  
      ※ターミナルで記事の中身が出力されたあと、任意のキーを押すと検索結果一覧に戻ります

# 導入方法
[README.md](https://github.com/skanehira/gota/tree/master)に書いてあります。
Goの環境があるなら、以下の様に`go get`するだけです。

```
go get -u github.com/samfoo/mdcat
go get -u github.com/skanehira/gota
```

mdcatはターミナル上でMarkdownを良い感じに表示してくれるツールになります。
これがないとターミナル上記事を見れないので注意してください。

Dockerを使っている方は`docker run --rm -it skanehira/gota`するだけで使えます。
上記通り、ブラウザで開けないので手動で開くかterminalで見るかになります。

# まとめ
作って見たものの、ターミナル上Markdownは見づらいですね…
画像も見れないし、リンクジャンプもできないし、長い内容だとターミナル自体がもっさりしてしまいます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/66178/20930502-2f31-15f3-5789-ffbab969c6a1.png)

検索はサクッとできますが、やはり見るのはブラウザが一番かなと思いました。
terminalでMarkdown閲覧はあまり役に立たないので、良ければ検索メインで使って頂ければと思います。
早い段階の失敗は成功の秘訣

## はじめに

技術開発をしている中で判断を迫られることは多い。その判断結果は、開発を成否に直結することが多い。

- なにかしらハードウェアの選択をしなければ、開発に着手することもできない。
- しかも開発の初期では、不十分な判断材料しかもたない。

その状況で、**「早い段階の失敗は成功の秘訣」**と主張する。

## ソフトウェアは入力・出力のハードウェア性能、演算のハードウェア性能に依存する。
ソフトウェアの開発だからといって、「ソフトウェアを書きなおせばなんとでもなる」ものではない。
計測や画像認識や機械学習は、使用するハードウェアで取得するデータの品質に依存する。
元々のデータの品質が劣化しているときには、できることが限られる。

顔照合をするときには、顔の画像の大きさと顔画像の鮮明さがいる。
撮影するときのレンズの視野とイメージセンサの画素数とが必要なことは誰でも気づくだろう。
それと同時に、レンズの鮮明さ(=線像強度分布（Line spread function）、点像強度分布、光学伝達関数のよしあし）が重要になってくる。同じ視野角のレンズであっても、fullHDのカメラ用のレンズと、NTSCのアナログカメラ用のレンズとは違うということだ。

深層学習が、いろんな画像認識を可能にしている。とはいっても、画像の画素数とフレームレートの組み合わせでは、検討しているハードウェアの演算性能で性能を達成できるかどうかは、設計の初期の段階では不明な場合もある。ソフトウェアを開発するからといって、「ソフトウェアを書きなおせばなんとでもなる」ものではないことがわかってもらえるだろう。


## 最初からうまくいく設計をできない
新しいものを作るときは、まだ経験していない要素があることは避けられない。
未知の要素があるものを扱うときに最初からうまくいくことはない。
そのことを覚悟しよう。
だから、失敗する要因を意識し続けよう。

## うまくいく設計は、うまくいかない条件を潰して見つかることが多い。
「うまくいく設計は、うまくいかない条件を潰して見つかることが多い。」と告白する。
これくらい処理を端折れば、計算量が削減できて、想定しているCPUでも処理しきれるだろうなどというもくろみをもって開発に着手したりする。

しかし、実際にそのアルゴリズムを検討すると、そこまで端折ると精度が確保できないとかわかったりするものだ。
そうすると、性能の高いCPUボードに置き換える必要が生じたりする。

他にも、実際に処理を開発してみると、他のハードウェアの性能が不十分だと気づくことがあったりする。そのような場合、その変更点の波及する範囲は広い。一般にハードウェアとソフトウェアからなる装置の場合、ハードウェアは後から置き換えるのが難しい。

計測や機械学習は、使用するハードウェアで取得するデータの品質に依存する。元々のデータの品質が劣化しているときには、できることが限られる。

深層学習などの進展があるから、いくらでも後でなんとかなるだろうというのは、傲慢な考え方だ。
例えば、ボケたナンバープレートで、文字を読み取るのは、ボケてないナンバープレートで文字を読み取るのに比べて、はるかに大変だ。
Topデータとしては、ボケた文字や低い解像度の文字を復元すればなんとかなる事例もあるだろう。しかし、一般的な状況では、そのような処理がうまくいくとは限らない。

問題が製品開発の後期に発覚するのは危険だ。もはや修正の時間的な余裕・金銭的な余裕ともになくなってしまっていて、命取りになってしまう。でも発覚するのが早い段階ならば、開発プロジェクトに与える影響は、修正可能な範囲にすることができる。

だから次のことを主張したい。

- 判断に失敗しないというのは難しい
- 自分の判断が間違えている可能性を常に意識すること
- 判断の妥当性を検証できる早いタイミングで検証すること。


早い段階での失敗は成功の秘訣。
そう主張したい。
java.nio.file.PathのTips

# 文字列からPathをインスタンスを作る
`java.nio.file.Paths.get(String first, String... more)`を用います。

```java
Path path = Paths.get("/var/temp/sample.csv");
Path path2 = Paths.get("/", "var","temp","sample.csv");
```
パスの分割記号（Unix系では'/'、Windowsでは'\'）は、Java側がうまいこと環境に合わせてくれます。
上記の`/var/temp/sample.csv`はWindowsではアプリケーションが動いているドライブをルートディレクトリとして解釈してくれます。
たとえば、C:ドライブのどこかでアプリケーションを動かしているのであれば、上記の例は`C:\var\temp\sample.csv`となります。
なお、Java 11からは`java.nio.file.Path.of(String first, String... more)`が使えます。

```java
// Java11
Path path = Path.of("/var/temp/sample.csv");
```

# パスをつなげる
`Path.resolve(Path other)`メソッドを用います。

```java
Path parent = Paths.get("/var/temp");
Path child = Paths.get("child");
Path file = Paths.get("sample.csv");
Path connected = parent.resolve(child).resolve(file); // -> /var/temp/child/sample.csv
```
`Paths.get(String first, String... more)`を使ってPathインスタンスを作成する場合、`/`で始めるとルートディレクトリからのパスと見なされてしまします。
なので、うっかり以下のようなコードを書くとうまくいきません。

```java
// /var/temp/childを作りたいとする
Path parent = Paths.get("/var/temp");
Path child = Paths.get("/child"); // "/"から始まっているため、ルートディレクトリからのパスと見なされる
Path connected = parent.resolve(child); // -> /temp
```

# java.io.Fileとの相互変換
## Path→File
`Path.toFile()`メソッドを用います。

```java
Path path = Paths.get("/var/temp");
File file = path.toFile();
```

## File→Path
`File.toPath()`メソッドを用います。

```java
File file = new File("/var/temp");
Path path = file.toPath();
```
Bootstrap4 初学者のメモ書き

#ドットインストールでBootstrap4の勉強を始めたので自分用のメモ書き。

まず公式サイトの雛形をコピペする
自分の使うcssなどはheadに適宜記載する。

https://getbootstrap.com/docs/4.0/getting-started/introduction/

```index.html

##Starter template

<!doctype html>
<html lang="ja">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

    <title>Hello, world!</title>
  </head>
  <body>
    <h1>Hello, world!</h1>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
  </body>
</html>

```

#各クラス
- text-center
文字を中央揃えにする（text-alighn: center;的な）

- bg-(color),text-(color)
背景色,文字色(background-color)を指定
 - primary(青)
 - secondary(灰色)
 - success(緑色)
 - danger(赤)
 - warning(黄色（オレンジ？）)
 - info(水色)
 - light(白)
 - dark(黒)
 - muted(薄い灰色？)
 - white(これも白)

- 要素の配置　text-(プロパティ)
    -  left
    -  right
    -  center
   
-  太字　font-weight-bold
-  細字　font-weight-normal(h2タグのようなもともと太字のものに対して)

- 見出し　display-(1~4)

- 要素サイズ　
    - 幅　w-(25, 50, 75, 100(%))
    - 高さ h-(25, 50, 75, 100(%))
   

- padding,margin
※ 基本形
######(p|m)(方向)-(size(rem)) ！方向を指定しないと全方向
######　top=t, bottom-b, left-l, right-r
######上下左右で指定 縦=y, 横=x
######size: 0~5rem ※marginのみauto指定可能
    - （例）pt-3, my-0, mx-auto
     
    !!bootstrapでpadding,marginを指定すると!important設定になる

- ボタン btn btn-(色) btn-(sm, lg)※buttonタグでなくてもOK

##グリッドレイアウト
###基本構造
rowの中のcol要素は12分割される。
何も指定しないと等分されるが、１２の割合を指定できる。

```index.html

<div clas="container">
  
  <div class="row">
    <div class="col-4"></div>
    <div class="col-６"></div>
    <div class="col-２"></div>
  </div>
　　　<div class="row">
    <div class="col-4"></div>
    <div class="col-６"></div>
    <div class="col-２"></div>
  </div>
　　　<div class="row">
    <div class="col-4"></div>
    <div class="col-6"></div>
    <div class="col-6"></div>
  </div>
</div>
```
12以上の値も指定できるが次の行に行ってしまう。


![スクリーンショット 2018-10-06 0.56.44.png](https://qiita-image-store.s3.amazonaws.com/0/224884/325beef6-3937-f8a9-a1fa-338ae07b387e.png)

##Bootstrapのブレークポイント
各画面サイズ幅に応じてクラスを指定できる。
- 
　　- 576px以上 = sm
　　- 768px以上 = md
　　- 992px以上 = lg
　　- 1200px以上 = xl

ex.)col-md-2, col-lg-4

※特定の画面サイズで非表示にする場合はd-none(display: none;)を使う
ex)d-md-none

逆にデフォルト非表示だけど特定の画面サイズで表示したい場合。

d-(画面サイズ)-blockを使用
（d-none, d-(画面サイズ)-2などと併用が必要）
Ubuntuの再インストールの備忘録

ubuntu18.04LTSでシステムに関わるところをあやまって触ってしまったので、再インストールした話。
LiveUSB等をすでに作ってあれば手順は簡単。
(LiveUSBは[この記事](https://linuxfan.info/make-linux-install-usb-on-windows)を参考に以前作成しました。）

##手順
1. 一度shutdownしてBIOS起動。 (PCによって違うが、自分のPCではF2押しながら起動)
2. USB HDDの優先順位を1番にする。
3. 紫色みたいな画面で4つぐらい選択肢が出てくる画面になるので（環境によってたぶん違うが）、「install ubuntu」的なものを選択。
4. LiveUSBが読み込まれて、インストールの画面が出てくる。（国の選択などから始まるはず。）
5. インストールが終わったら再起動するよう言われるので、それに従う。

以上。

注） 僕は何もかも消えて大丈夫だったのでこうしましたが、バックアップをとる必要がある方は別の方の記事を参照してください。

初期設定は別記事参照。
Tapを使った新感覚音ゲーの紹介

#追記
10/13 プロトタイプの映像を2本追加。譜面を作成し、実際に遊ぶところの映像。

#Tapというデバイスについて
主にこちらで説明していますのでどうぞ
[指につけるキーボードデバイスTap](https://qiita.com/PAD_meat_ball/items/8a36708f5f335c1e1adb)

#作った経緯
このTapというデバイス、買って試したはいいものの、パターンを覚えるのは大変だし、キーボード入力より速度は劣るし、どうしようという感じでした。
何かに使えないか、面白いことできないか？と考えていきついた先が音ゲーでした。

#プロトタイプ
こちらのTwitterでプロトタイプの説明しています。
[Tap音ゲー](https://twitter.com/PAD_meat_ball/status/1048235093028823040)
デモの映像撮ってもらいました！
[Tapを動かしてる映像はこちら](https://twitter.com/0304wataryo/status/1048453565767856129?s=21)
[譜面を作成＆作った譜面再生]
(https://twitter.com/PAD_meat_ball/status/1050693921230090245)
[譜面を再生して実際に遊ぶ]
(https://twitter.com/PAD_meat_ball/status/1050955703328731137)

#Tapならではの要素
これってスマホのタッチでもおんなじことできるんじゃない？って思いましたか？
スマホの音ゲーで例えば3点同時タッチがあったとします。右手の2本の指＆左手の1本の指で押すことが可能です。ほかにもいろんな押し方ができるでしょう。
これでは、製作者側からすると、難易度を調整しづらいのではないでしょうか？
しかし、Tapなら簡単に難易度を決めれます！！
日常生活では使わないような指での同時押し（例えば　J　）などで簡単に難易度調整が可能です。
![TapSample.jpg](https://qiita-image-store.s3.amazonaws.com/0/285567/72b059bb-8ad8-5c99-c20e-f93d9237a6ea.jpeg)
macOS のクリップボード（pbpaste）の改行コード

こんにちは。
macOS のクリップボード（の中のテキスト）の改行コードは、場合によっては ```CR``` となるようです。```pbpaste``` コマンドの出力を見ると、

```console
$ pbpaste | nkf --guess
ASCII (CR)
```

これを ```LF``` にさせるため、シェルスクリプトを作ってみました（```nkf``` 利用）。

```console
$ ./pbpaste_u.sh | nkf --guess
ASCII (LF)
```


```pbpaste_u.sh
#!/bin/sh
pbpaste | nkf -Lu | grep ^
exit 0
```
Pythonの基本的な型の階層構造を図にしてみた

GeneratorがSequenceでないことに少し疑問に思ったこともあり
Pythonの基本的な型の階層構造をGraphvizを使って図にしてみました。

![type_hierarchy.png](https://qiita-image-store.s3.amazonaws.com/0/40558/1ab48128-c368-6c17-dd55-f29234bf3bf0.png)


生成に使ったコードは以下

```type_check.py
from typing import *
from typing import IO, BinaryIO, TextIO
import collections
import datetime
import enum
import numbers
import decimal
import fractions
from itertools import groupby
from more_itertools import first
from graphviz import Digraph

G = Digraph(format='png')
types = [
    TypeVar,
    # Generic,
    Type, Iterable, Iterator, Reversible, SupportsInt, SupportsFloat, SupportsComplex, SupportsBytes, SupportsAbs,
    SupportsRound, Container, Hashable, Sized, Collection, AbstractSet, MutableSet, Mapping, MutableMapping, Sequence,
    MutableSequence, ByteString, Deque, List, Set, FrozenSet, MappingView, KeysView, ItemsView, ValuesView, Awaitable,
    Coroutine, AsyncIterable, AsyncIterator, ContextManager, Dict, DefaultDict, Counter, ChainMap, Generator,
    AsyncGenerator, Text, IO, TextIO, BinaryIO,
    # Pattern,
    # Match,
    NamedTuple,
    # Any,
    # Union,
    # Optional,
    Tuple, Callable,
    # ClassVar,
    # AnyStr
    collections.OrderedDict,
    int, float, complex, range, bytes, bytearray, memoryview,
    datetime.date, datetime.time, datetime.datetime, datetime.timedelta, datetime.tzinfo, datetime.timezone,
    enum.Enum, enum.IntEnum, enum.IntFlag, enum.Flag,
    numbers.Complex, numbers.Real, numbers.Rational, numbers.Integral,
    decimal.Decimal, decimal.Context,
    fractions.Fraction
]

subtype_pairs = [(t1, t2) for t1 in types for t2 in types if t1 is not t2 if issubclass(t1, t2)]
for t1, t2_list in groupby(subtype_pairs, first):
    t2_list = list(t2_list)
    for _, t2 in t2_list:
        if not any([issubclass(x, t2) for _, x in t2_list if x is not t2]):
            G.edge(t1.__name__, t2.__name__)

G.render('type_hierarchy')

```

ちなみに、Anaconda/Windows環境だからなのか、動作させるためにはPythonのgraphvizパッケージだけでなく、python-graphvizパッケージも必要でした。
Mac で ESPr Developer: ESP-WROOM-02開発キットのシリアルポートが表示されないとき

# ESPr Developer

スイッチサイエンスで販売しているESPr Developerは、ESP-WROOM-02の開発キット。
シリアルモジュールも実装されているから、USBでPCと接続するだけで、IoT開発を始められる…！

![IMG_20181005_231452.jpg](https://qiita-image-store.s3.amazonaws.com/0/75329/71bbd308-cd50-6371-84ab-3cb6d1d70cba.jpeg)

# 接続してもシリアルポートに出てこない

Arduinoを接続しているときは、シリアルポートのメニューにちゃんと、`/dev/cu.usbmodem1411`のようなポート名が表示されます。 
しかしながら、ESPr Developerを接続したときには、それらしいポートは見当たりません。ましてや、Bluetoothのはずがない…！

<img width="732" alt="スクリーンショット 2018-10-05 23.19.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/75329/cb5ae7ca-862f-fc9b-613f-94730fac2f80.png">

# FT231X のVCPドライバをインストール

VCP（仮想COMポート）が必要でした！
[FTDIのサイト](https://www.ftdichip.com/Drivers/VCP.htm)から、`Mac OS X 10.9 and above`の64bit用ドライバをダウンロードしました。

<img width="1680" alt="スクリーンショット 2018-10-05 23.42.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/75329/547c9e4a-e258-f2b3-0be1-82793081de16.png">

ダウンロードしたdmgを開き、インストールします。
インストールしたあとは、**再起動が必要です**（そうしないとArduino IDEのポートに表示されなかった）。

<img width="744" alt="スクリーンショット 2018-10-05 23.34.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/75329/13093d9d-f8a5-52df-864c-c36006f0efa6.png">

無事に表示されました！
（よくわかんないけど、きっとこれがポートなんだろう！とりあえず選択しておきます）

シリアルモニタを開いて、ボーレートを`115200 bps`にし、改行コードを`CRおよびLF`で設定します。
ESPr Developerのリセットボタンを押すと……**ESP-WROOM-02から`ready`のレスポンスが届きました！**

<img width="882" alt="スクリーンショット 2018-10-05 23.34.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/75329/4b5ae9e5-b124-6603-1bf9-1fc2d2c061b3.png">

これで、ESPr Developerで開発を始められます！

---

# なぜFTDIのVCPドライバをインストールしたか

USBに刺さっているものが、FT231Xだとわかったからですね。
（このMacについて > システムレポート... から行ける画面ですね）

<img width="751" alt="スクリーンショット 2018-10-06 0.05.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/75329/9189e4ba-f86a-8f06-5a16-74173aec82db.png">

この画面を開くきっかけになったのは、「Mac USB serial port not showing」のクエリでググっている時に見た、[Appleのサポートコミュニティのサイト](https://discussions.apple.com/thread/6551520)で、「設定のところから、USBに刺さってるものが何なのか見てごらんよ」って書いてあったので、「システムレポート」にたどり着きました。

とはいえ、それよりも前に、[Arduinoのフォーラム](https://forum.arduino.cc/index.php?topic=114305.0)のスレッド中に解決策が書いてあったのですが、気づかず読み過ごしていました……。なぜなら最後の投稿に、「ケーブル変えたら直ったよ！やいやらw」って書いてあったので……。

ひとまず、これで開発を始められます！
Riemann Zeta Function

# Page Link
[Riemann Zeta Function](http://salesforcexytools.com/maths/2018/09/28/Riemann-Zeta-Function/)



![RiemannZetaFunction](http://salesforcexytools.com/maths/images/clip_image001.png)


$$
1+2+3+4+... = -\frac{1}{12}
$$



![1  1 十 2 十 3 十 4 十 ·  12 ](http://salesforcexytools.com/maths/images/clip_image001-1538143700501.png)



![巜 2 ) =  7 讠 = 1  22 32  42 ](http://salesforcexytools.com/maths/images/clip_image001-1538143711418.png)

![n=l  十 一 十 一 十 一 十 ·  14 ](http://salesforcexytools.com/maths/images/clip_image001-1538143734542.png)

![1  Only defined  for s > 1 ](http://salesforcexytools.com/maths/images/clip_image001-1538143741864.png)



![re2 ](http://salesforcexytools.com/maths/images/clip_image001-1538143758517.png)



![1538143800311](http://salesforcexytools.com/maths/images/1538143800311.png)
Fermat's Last Theorem

# Page Link
[Fermat's Last Theorem](http://salesforcexytools.com/maths/2018/09/30/Fermat-Last-Theorem/)

# 费马大定理

**费马大定理**，也称**费马最后定理**（法语：Le dernier théorème de Fermat)；(英语：Fermat's Last Theorem），其概要为：
$$
当整数n>2时，关于 x,y,z的不定方程\\
x^n + y^n = z^n\\
没有正整数解
$$

以上陈述由17世纪[法国](https://zh.wikipedia.org/wiki/%E6%B3%95%E5%9B%BD)[数学家](https://zh.wikipedia.org/wiki/%E6%95%B0%E5%AD%A6%E5%AE%B6)[费马](https://zh.wikipedia.org/wiki/%E7%9A%AE%E5%9F%83%E7%88%BE%C2%B7%E5%BE%B7%C2%B7%E8%B2%BB%E9%A6%AC)提出，一直被称为“费马猜想”，直到[英国](https://zh.wikipedia.org/wiki/%E8%8B%B1%E5%9C%8B)[数学家](https://zh.wikipedia.org/wiki/%E6%95%B8%E5%AD%B8%E5%AE%B6)[安德鲁·怀尔斯](https://zh.wikipedia.org/wiki/%E5%AE%89%E5%BE%B7%E9%AD%AF%C2%B7%E6%87%B7%E7%88%BE%E6%96%AF)（Andrew John Wiles）及其学生[理查·泰勒](https://zh.wikipedia.org/wiki/%E7%90%86%E6%9F%A5%C2%B7%E6%B3%B0%E5%8B%92_(%E6%95%B8%E5%AD%B8%E5%AE%B6))（Richard Taylor）于1995年将他们的证明出版后，才称为“费马大定理”。



# 证明流程

​     费马大定理 

⇒ 改写成椭圆曲线方程

⇒ 改写成模形式(谷山－志村定理）



# 数学工具和理论

## 欧拉的无穷递降法

1770年，欧拉证明n=3时定理成立， 使用了 [无穷递降法](https://zh.wikipedia.org/wiki/%E6%97%A0%E7%A9%B7%E9%80%92%E9%99%8D%E6%B3%95)。无穷递降法，又名无穷递减法，是数学中证明方程无解的一种方法。

这个方法对`初中数学`计算非常有用。比如
$$
\sqrt {2}
$$
是无理数的证明。[证明方法](https://zh.wikipedia.org/wiki/2%E7%9A%84%E7%AE%97%E8%A1%93%E5%B9%B3%E6%96%B9%E6%A0%B9)

## 谷山－志村定理（英语：Taniyama-Shimura theorem）
志村五郎和谷山丰的理论

[Wiki](https://zh.wikipedia.org/wiki/%E8%B0%B7%E5%B1%B1%EF%BC%8D%E5%BF%97%E6%9D%91%E5%AE%9A%E7%90%86)

**谷山－志村定理**（英语：**Taniyama-Shimura theorem**）建立了[椭圆曲线](https://zh.wikipedia.org/wiki/%E6%A4%AD%E5%9C%86%E6%9B%B2%E7%BA%BF)（[代数几何](https://zh.wikipedia.org/wiki/%E4%BB%A3%E6%95%B0%E5%87%A0%E4%BD%95)的对象）和[模形式](https://zh.wikipedia.org/wiki/%E6%A8%A1%E5%BD%A2%E5%BC%8F)（[数论](https://zh.wikipedia.org/wiki/%E6%95%B0%E8%AE%BA)中用到的某种周期性[全纯函数](https://zh.wikipedia.org/wiki/%E5%85%A8%E7%BA%AF%E5%87%BD%E6%95%B0)）之间的重要联系。

![谷山丰](http://salesforcexytools.com/maths/images/1538277859716.png)



![志村五郎](http://salesforcexytools.com/maths/images/1538277903738.png)



世界上存在5种最基本的计算方法，加减乘除，还有**模形式**。

# 伽罗瓦群

**伽罗瓦群**（法语：Groupe de Galois）是[抽象代数](https://zh.wikipedia.org/wiki/%E6%8A%BD%E8%B1%A1%E4%BB%A3%E6%95%B0)中[域论](https://zh.wikipedia.org/wiki/%E5%9F%9F%E8%AB%96)的概念，表示与某个类型的[域扩张](https://zh.wikipedia.org/wiki/%E5%9F%9F%E6%89%A9%E5%BC%A0)相伴的[群](https://zh.wikipedia.org/wiki/%E7%BE%A4)，是[伽罗瓦理论](https://zh.wikipedia.org/wiki/%E4%BC%BD%E7%BE%85%E7%93%A6%E7%90%86%E8%AB%96)的基础概念。域扩张源于[多项式](https://zh.wikipedia.org/wiki/%E5%A4%9A%E9%A1%B9%E5%BC%8F)。通过伽罗瓦群研究域扩张以及[多项式](https://zh.wikipedia.org/wiki/%E5%A4%9A%E9%A1%B9%E5%BC%8F)的理论，称为[伽罗瓦理论](https://zh.wikipedia.org/wiki/%E4%BC%BD%E7%BE%85%E7%93%A6%E7%90%86%E8%AB%96)，是十九世纪[法国](https://zh.wikipedia.org/wiki/%E6%B3%95%E5%9B%BD)数学家[埃瓦里斯特·伽罗瓦](https://zh.wikipedia.org/wiki/%E5%9F%83%E7%93%A6%E9%87%8C%E6%96%AF%E7%89%B9%C2%B7%E4%BC%BD%E7%BD%97%E7%93%A6)为了解决“高次多项式方程是否有根式解”的问题而创造的。后世也以他的名字命名相关的概念。





# 其他

## 欧拉猜想x

![1538277467765](http://salesforcexytools.com/maths/images/1538277467765.png)

不过可惜命题是错的。。。实际上存在整数解

![1538277500751](http://salesforcexytools.com/maths/images/1538277500751.png)
微积分入门导数 Indeterminate - 0 divided by 0

# Page Link
[微积分入门导数 Indeterminate - 0 divided by 0](http://salesforcexytools.com/maths/2018/09/29/Indeterminate/)

# Overview

* `Derivative导数`是啥
* Indeterminate forms不定型
* 通过`洛必达法则L'Hôpital's rule` 计算各种导数不过就是各种`Indeterminate forms不定型` 的导数
* 基本导数公式



# Derivative and 0 divided by 0 

Derivative 导数 的最基本定义如图所示- 切线。
$$
不定型\frac{0}{0}
$$



![1538205326858](http://salesforcexytools.com/maths/images/1538205326858.png)





# 洛必达法则L'Hôpital's rule

![1538229668856](http://salesforcexytools.com/maths/images/1538229668856.png)

# Indeterminate forms 不定型

![1538206238601](http://salesforcexytools.com/maths/images/1538206238601.png)







# 导数公式

![1538205627316](http://salesforcexytools.com/maths/images/1538205627316.png)


$$
\frac{\rm {d} }{\rm {d} x}(x^n)=nx^{n-1}\\
\frac{\rm {d} }{\rm {d} x}(ln(x))=\frac{1}{x}\\
\frac{\rm {d} }{\rm {d} x}(sin(x))=cos(x)\\
\frac{\rm {d} }{\rm {d} x}(e^x)=e^x\\
$$

# 问问Siri什么是0/0

![1538206161460](http://salesforcexytools.com/maths/images/1538206161460.png)
CentOS73 Django環境作成

<https://qiita.com/estaro/items/5a9e4eb8f0902b9977e3>


<https://qiita.com/tinaba/items/01bc72c100f97438a36e>

```
[root@centos ~]# pip3.6 install Django
Collecting Django
  Downloading https://files.pythonhosted.org/packages/32/ab/22530cc1b2114e6067eece94a333d6c749fa1c56a009f0721e51c181ea53/Django-2.1.2-py3-none-any.whl (7.3MB)
    100% |████████████████████████████████| 7.3MB 161kB/s
Collecting pytz (from Django)
  Downloading https://files.pythonhosted.org/packages/30/4e/27c34b62430286c6d59177a0842ed90dc789ce5d1ed740887653b898779a/pytz-2018.5-py2.py3-none-any.whl (510kB)
    100% |████████████████████████████████| 512kB 1.2MB/s
Installing collected packages: pytz, Django
Successfully installed Django-2.1.2 pytz-2018.5
You are using pip version 9.0.1, however version 18.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
```

```
[vagrant@centos]$ cd /var/www/html/ 
[vagrant@centos html]$ django-admin startproject playground
```

```
[root@centos playground]# pip3.6 install PyMySQL==0.7.9
```

<https://codelab.website/python3-django-mysql/>



### mysql ユーザ作成
```
grant all on playground.* to playground@localhost identified by '******'
```
<https://techacademy.jp/magazine/5110>


```
[vagrant@centos playground]$ vi ./settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'playground', # DB名を設定
        'USER': 'playground', # DBへ接続するユーザIDを設定
        'PASSWORD': '&Q56oAUEW.', # DBへ接続するユーザIDのパスワードを設定
        'HOST': 'localhost',
        'PORT': '3306',
        'OPTIONS': {
            'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
        },
        'TEST': {
            'NAME': 'test_sample'
        }
    }
}

[vagrant@centos playground]$ python3.6 manage.py migrate
/usr/lib/python3.6/site-packages/pymysql/cursors.py:170: Warning: (3135, "'NO_ZERO_DATE', 'NO_ZERO_IN_DATE' and 'ERROR_FOR_DIVISION_BY_ZERO' sql modes should be used with strict mode. They will be merged with strict mode in a future release.")
  result = self._query(query)
/usr/lib/python3.6/site-packages/pymysql/cursors.py:170: Warning: (3090, "Changing sql mode 'NO_AUTO_CREATE_USER' is deprecated. It will be removed in a future release.")
  result = self._query(query)
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying sessions.0001_initial... OK
```
Illustratorのプラグイン開発で日本語の文字列を表示する

#はじめに
Illustratorのプラグインの開発のおはなし。
IllustratorのAPIを使ってポップアップウィンドウを表示する際に
日本語を表示するのにちょっとつまづいたのでメモ

#開発環境
Mac用のプラグインはXcode、Windows用のプラグインはVisualStudioを用いてビルド
推奨開発環境などはAdobeのサイト参照、基本的にそれに沿ってやってます。
IllustratorのAPIはAdobeのサイトから落とせます。

#ソースコード
基本的には下の感じでYes,Noの選択肢を持つポップアップウィンドウが出せるはず。

```c++:aiplugin.cpp
const char* str = "今日はいい天気ですね"
ai:::UnicodeString aiStr(str);
YesNoAlert(aiStr);
```
Windows、Mac共にビルドは通ったのだが
Mac版はプラグインを起動してポップアップを表示したときに文字化けしてしまった。

#解決策
下のように一文足したら文字化けが治った。

```c++:aiplugin2.cpp
ai:::UnicodeString aiStr;
const char* str = "今日はいい天気ですね"
aiStr = ai::UnicodeString::FromUTF8(str);
YesNoAlert(aiStr);
```

ただ、aiplugin2.cppのソースコードだと逆にWindowsで文字化けが発生した
同一のソースコードを利用する場合はマクロなんかで切り分ける必要があるようだ。

#まとめ
原因がいまいちつかめていないが、修正内容からするとおそらく文字コードだと思われる。
ただどちらのソースコードも文字コードはUTF-8のはず。
なのでaiplugin2.cppのソースコードを用いてもWindowsで正常に動くはずなのだが...。
ひとまず暫定対応としてFromUTF8のメソッドを使う事を覚えておく。
LAN外SSH接続でjupyter notebookを起動する

#はじめに
　どうも，和麿です．台風や地震がたくさん来る年ですね．お陰で旅行の予定がどんどん潰れていきます．運がないですね．（笑）
　さて，今回はSSH接続について記事を投稿したいと思います．以下，目的・環境を説明したあと，具体的な設定について書いていきたいと思います．

#目的
　今回はSSHサーバー内にjupyter notebookをインストールし，別端末からそれを使えるようにすることを目指しました．前提としてSSHサーバはすでに構築しているものとします．[^1]

##環境
　使用した環境，ソフトは以下に示す通りです．

* サーバー
 * OS:Ubuntu16.04
 * openssh-server
 * jupyter notebook[^2]
　
* 端末
 * OS:Windows10
 * MobaXterm[^3]
 * なんかブラウザ(今回はgoogle chrome)
 
　この環境を前提に話を進めていきます．

#具体的な設定
　それでは具体的な設定について解説していきます．今回は端末での操作のみを解説していきます．
## 端末での操作(with Moba Xterm)
　Mobaxtermを開きSSH接続を行います．[^4]そして，jupyter notebookを起動しましょう．ちなみに<>で囲われているところはご自分の端末PCで代入すべきところです．

``` @.MobaXterm
[20xx-0x-0x yy:zz.gg]  ~
[user.Kazumaro-PC] ➤ ssh <username>@<globa ip address>
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-137-generic x86_64)

...

Last login:...

username@user:~$ jupyter notebook
[I aa:bb:cc.ddd NotebookApp] Writing notebook server cookie ...

    Copy/paste this URL into your browser when you connect for the first time,
    to login with a token:
        http://localhost:<port>/?token=4f7c37eafdccaf2190f9d8dafcf05f0d11kakzuklajkljaj
[I aa:bb:cc.ddd NotebookApp] Accepting ...

```

　jupyter notebookはこのままでは端末では表示されません．そのため次のような操作を行います．まず，示されているtoken内のport番号を確認します．そして，別タブをMobaxTerm上で開き，以下のようにコマンドを打ってください．

```別タブ@.MabaXterm
[20xx-0x-0x yy:zz.gg]]  ~
[user.Kazumaro-PC] ➤ ssh -L <port>:localhost:<port> <username>@<globa ip address>
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-137-generic x86_64)

...

Last login: ...
username@user:~$ 

```

　ログインしたら，@.MobaXterm内にあるURLをコピペして，ブラウザにぶち込みましょう．今回でいえばこれをブラウザにコピペします．

```@.ご自分のブラウザに貼るURL
http://localhost:<port>/?token=4f7c37eafdccaf2190f9d8dafcf05f0d11kakzuklajkljaj
```

　そうすると次のような画像が出てきます．

![jupyter1.PNG](https://qiita-image-store.s3.amazonaws.com/0/297798/292762ad-8cc0-3690-93d7-6be256c81993.png)

　ここまで来たら成功です．快適なpython lifeを送ってください．（笑）

#おわりに
　本記事は自分の備忘録も兼ねて投稿しました．他の方法もQiitaでは掲載されています．でも僕はそれでうまくいかなかったので今回の方法を採用しました．[^5]手順が複雑で忘れそうだったので備忘録の意味もあります．
　読んでいただいた方のお役に立てれば望外の喜びです．ここまで読んでいただきありがとうございました．

以上

#注釈
[^1]: LAN外，内いずれもサーバー環境の構築方法は[この記事](https://qiita.com/rintarou/items/bef523c7c8f11097e577)を参考にしました．SSH接続は情報が大変少ないため参考になりました．特にLAN外部からの接続は大分苦労しました（笑）．
[^2]: Jupyter notebookはAnacondaでインストールしました．詳しくはリンク先の[記事](https://pythondatascience.plavox.info/python%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/anaconda-ubuntu-linux)を参考にしてください．
[^3]: SSH接続時に使用しました．PuTTYやTera Termよりも使いやすいと私は感じていて，おすすめです．
[^4]: 今回は<font color="SandyBrown">LAN外環境</font>を前提に説明していきます．LAN内で行う場合はglobal ip の代わりに local ipを使用してください．確認方法はgoogleで検索するとすぐ出てくると思います．
[^5]: 次のような[記事](https://qiita.com/Miggy/items/5466a2c1e968602f3ebe)です．僕の記事は[この記事](https://qiita.com/ytytgo/items/343b8c0f7aed9fdc0995)を参考にしました．
2018年10月5日 VBA学習

昨日から今日にかけてExcelでVBAをやっておりました。

![VBA-Macro-1004.JPG](https://qiita-image-store.s3.amazonaws.com/0/200171/b55bd91d-f320-b7af-b068-55e82deaf8bf.jpeg)

モジュールを生成して、ボタンモジュールをクリックすると

文字を入力するInputBoxが出てきます。

そのInputBoxにSampleと入力しOKボタンをクリックすると

Sampleという名前の新しいワークシートが生成されるような

マクロを組みました。

これが昨日やったことです。

今日やったことは、マクロで

For・IF構文とWithステートメントを使い

簿記で使う貸借対照表・合計残高試算表・現金出納帳・元帳などの

シートを生成するマクロを組みました。

それが下記の画像になります。

![VBA-Macro-1005(2).jpg](https://qiita-image-store.s3.amazonaws.com/0/200171/182a24b8-5705-c4c2-13a3-59726daa62c3.jpeg)

このように記述しまして

結果は以下の通りの画像です。

![VBA-Macro-Bookeeping.jpg](https://qiita-image-store.s3.amazonaws.com/0/200171/ee25159b-743b-c9e5-8637-8f01c3055792.jpeg)

それぞれの名前の通りにワークシートが生成されるようになりました。

今後は一つのブックで生成したマクロを次年度事の簿記のブックを

自動生成できるようにしていきます。
Spring Sleuthを導入してみた

## 経緯

- Springを使ったWebアプリケーションでログを出していたが、単にログを出すだけでは見づらかったのでSpring Sleuthをいれることにした

## 構成

- 構成は以下の通り
- バッチがAPIを呼び出し、APIがDBに登録・取得しに行く形
<img width="860" alt="スクリーンショット 2018-10-05 23.30.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/245191/39753a52-fbe7-d51a-1e35-b9bad8d1bc56.png">


## Sleuthのイメージ

#### Spring Sleuthのイメージはこんな感じ
<img width="933" alt="スクリーンショット 2018-10-05 23.48.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/245191/784f6db1-4b58-d2c9-4396-cc60638d8fb2.png">

- TraceIDとSpanIDと呼ばれるものがある
- TraceIDは1回のバッチの実行単位で生成され、共通のIDが同一リクエスト内で保持される
- SpanIDは1回のAPIのリクエスト単位で生成される


## 実際に導入してみた

#### 用意したもの

- MacBook Pro (13-inch)
- IntelliJ IDEA
- JAVA 1.8 
- Spring (2系)

#### gradleに設定を追加

- 基本的にはgradleに設定を追加するだけで動く模様

````gradle:build.gradle
buildscript {
    dependencies {
        classpath "io.spring.gradle:dependency-management-plugin:0.5.2.RELEASE"
    }
}

apply plugin: "io.spring.dependency-management"

dependencyManagement {
     imports {
          mavenBom 'org.springframework.cloud:spring-cloud-sleuth:2.0.2.BUILD-SNAPSHOT'
     }
}
dependencies {
    compile 'org.springframework.cloud:spring-cloud-starter-sleuth'
}
repositories {
    maven {
        url 'https://repo.spring.io/libs-snapshot'
    }
}
````

#### ハマったところ

- RestTemplateをBean登録していなかった
- SpringBoot1.5系を使っていたときに、最新バージョンのSleuthを入れていた

基本的にはハマる要素はないのですが、この2つだけ気をつければ簡単に導入できそう、、

## まとめ（個人的な所感）

- とりあえずSleuthを入れることは簡単である
- ただ、Sleuthだけ入れても特に恩恵は得られない
- むしろ、無駄に吐き出されるログが長くなるので監視がしにくくなる一面もある
- zipkinの導入を検討する必要がありそう


## 参照元

- [Spring Cloud Sleuth](https://cloud.spring.io/spring-cloud-sleuth/)
- [Tracing in Microservices With Spring Cloud Sleuth](https://dzone.com/articles/tracing-in-microservices-with-spring-cloud-sleuth)
- [Using the Spring Cloud Sleuth trace ID](https://blog.michaelstrasser.com/2017/07/using-sleuth-trace-id/)
varじゃだめなの?? constとletを使おう!

## はじめに
constやletやら良く見るけどvarじゃだめなの？？
ずっとvarでやってきたし、大きく困ったことないからいいじゃんって思いますよね！

そんなあなたもconstやletを使いたくなるように、constとletの便利な所をまとめて見ました！

## 対象読者
・ES2015をこれから使っていきたい

***注意点***
これから紹介する記法は主にES2015以降の記法です。
レガシーブラウザに対応させる場合は、トランスパイラ（Babel等）を使用し、
ES5記法にトランスパイルをおこなってください。
（参考記事）
https://qiita.com/mizchi/items/3bbb3f466a3b5011b509#%E3%81%84%E3%81%BE%E3%81%99%E3%81%90es2015%E3%82%92%E4%BD%BF%E3%81%86
https://qiita.com/hietahappousai/items/9570da4b9275425489b2


## 簡単にconstとletについて説明
constは定数を宣言するときに使用します。

どういうことかというと、
varを使って変数を宣言すると、

```js
var  hoge = 'りんご';

console.log(hoge);  // りんご

hoge = '再代入だ！！'; 

// 再代入が可能
console.log(hoge); // 再代入だ！！
```

こんな感じで再代入ができます。
対しconstを使うと

```js
const  hoge = 'りんご';

console.log(hoge);  // りんご

// 再代入してみる
hoge = '再代入だ！！'; // エラーになる Uncaught TypeError: Assignment to constant variable.
```

言語レベルで再代入を防いでくれます。
定数を宣言する場合に大文字で書くといったことをしなくても、
ひと目でわかりやすいですね！！

letは基本的にはvarと同じく、
変数を宣言する際に使用しますが以下に記載する、
constと共通のメリットがあります。


## スコープを狭くできる（ブロックスコープになる）

varでfor文やif文を書いた場合は、

```js
for (var i = 0; i < 10; i++) {
    i; // 0,1,2,3,4,5,6,7,8,9
}

// for文の外でもiにアクセスできてしまいます
i; // 10
```

for文の外でもiに対しアクセスが可能になってます。
このままですと、予想外の挙動をおこしてしまうかもしれません。。


letやconstを使うことで、

```js
for (let i = 0; i < 10; i++) {
    i; // 0,1,2,3,4,5,6,7,8,9
}

i; // is not defined
```

iの有効範囲がfor文の中だけになり、アクセスが出来なくなりました。
このようにconstとletを使うことで、スコープを狭めることができます。

## 変数の巻き上げ現象が起こらなくなる

変数の巻き上げとは、「宣言された場所に関係なくスコープの先頭で宣言されたことになる」というものなのですが、

詳しく見ていくと、

```js
console.log(hoge);
var hoge = 'xxx';
```
console.logが呼ばれた時にhoge変数が存在しないので、
`is not defined`とエラーが出そうなのですが、実際には

```js
console.log(hoge); // undefined
var hoge = 'xxx';
```

undefinedが出力されます。
実際のJavaScriptの解釈を見てみると、

```js
var hoge;
console.log(hoge); // undefined
var hoge = 'xxx';
```

上記のコードと同じ、処理が行われており、
コードの先頭で変数が宣言されていると見なされてます。
JavaScriptの仕様によるものなのですが、
このことを巻き上げ現象と呼びます。

巻き上げ現象もconstやletを使うことで、

```js
console.log(hoge); // ReferenceError: hoge is not defined
let hoge = 'xxx';

```

適切なエラーが発生し巻き上げ現象がなくなります。

## 二重宣言ができなくなる
同じ変数名を宣言してしまった場合、上書きされることがなくなりました。

varの場合

```js
var aaa = 'aaa';
var aaa = 'bbb';

// 後から指定した方に値が変わってしまっている
console.log(aaa); // bbb
```

letの場合

```js
let aaa = 'aaa';
let aaa = 'bbb';

// SyntaxError: Identifier 'aaa' has already been declared ;
// エラーがでる

console.log(aaa);
```

## まとめ
- constは定数
- letは変数
- ブロックスコープになる
- 変数の巻き上げ現象が起こらなくなる
- 二重宣言ができなくなる

よきJavaScriptライフを!