OmniAICreator/Qiita-1.07M huggingface dataset:
Spring Boot で Rest API 構築 その4 - MySQL への接続設定

# Outline

- Spring Boot のアプリケーションから MySQL への接続設定を行う

## 元々の問題

Spring Initializr で構築したアプリケーションを起動するとエラーが発生していた
https://qiita.com/sawa-@github/items/292a665fecf212ccc38a#とりあえず起動してみる


# 設定

## MySQL への接続情報を設定ファイルに追加する

```yml:src/main/resources/application.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/rest_api?useSSL=false
    username: root
    password: root
    driverClassName: com.mysql.cj.jdbc.Driver
```

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html

# アプリケーションの起動

## docker-compose で MySQL コンテナを起動

```shell
$ docker-compose up -d
Starting rest-api-mysql ... done
```

https://qiita.com/sawa-@github/items/09d108f7b540ff86b2dc#起動コマンド

## アプリケーション起動

Run ボタンを押す

![190817-0005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21296/a82891bd-aede-14b7-4b50-5b8c6eb775ea.png)


```

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.7.RELEASE)

(省略)

2019-10-06 22:25:18.208  INFO 43050 --- [  restartedMain] c.e.s.SpringBootRestApiApplication       : Started SpringBootRestApiApplication in 4.536 seconds (JVM running for 5.495)

```

起動するだけの空っぽなアプリケーションだけど起動まで出来るようになりました
Gitについて勉強する。第七弾 (リベースでコミットの履歴を書き換えよう 編)

# リベースとは
履歴をきれいにしつつ、変更を統合するのがリベースです。

# コマンド
* git rebase "ブランチ名"

リベース元の履歴がリベース先のブランチの後ろに追加される形で一本化されます。

仮にブランチが「master」と「feature」の2つがあったとします。
(改修などを行う作業ブランチはfeatureと名付けるところが多いよ！)

featureで作業していてmasterに変更がありました。
featureにmasterの変更を取り込みたい場合、通常はmasterをfeatureにマージして取り込みます。
その場合、コミット状況が以下のようになります。

<img width="356" alt="スクリーンショット 2019-10-06 22.24.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418332/786504e6-51fc-d4f5-8d5c-a77551121b65.png">

                  
これをgit rebase masterで行うと以下のように一本化された状態になります。

<img width="498" alt="スクリーンショット 2019-10-06 22.24.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418332/acf11ce5-d410-2f10-a6e1-826619ec1516.png">


mergeであれば、featureコミット3の親コミットはmasterコミット1ですが、rebaseを使用する事によって、featureコミット3の親コミットが、masterコミット2となります。

# コミット履歴を変更する方法
GitHubにPushする前に、コミット履歴をきれいにする場合に使用します。

* git rebase -i "コミットID"
* git rebase -i HEAD~3 (直前のコミットから3つ前を変更)


## 修正する際の流れ
1. git rebase -i で修正対象を選択する。修正するものに関しては、pick→editのように書き換える。
2. git commit --amend で直前のコミットを修正する。
3. git rebase --continueで次のコミットに移動する。移動先がない場合、完了。

## コミットの順番を入れ替える
git rebase -i "コミットID"を使用すると、エディタが立ち上がり、履歴が表示されます。 ファイルを編集して、入れ替えればOKです。

## コミットをまとめる
git rebase -i を使用して表示されたファイルに、まとめたいものに対して、pick→squashを使用すれば、指定したものをすべてまとめることができます。

## コミットを分割する
1. git rebase -i "コミットID"
2. 対象のコミットをeditに変更
3. git reset HEAD^ でコミットを取り消す
4. git add と git commitで分割したい単位でコミットし直す。
5. git rebase --continueで終了

[次・第八弾](https://qiita.com/hajime_manul/items/bb4a17898c1fae33c2a6)
【OCI】Ansibleでdockerの環境構築までを行う。

# Ansibleとは
構成管理ツールの1つです。
Ansibleは冪等性を担保するように作られており、
管理対象サーバに対して「あるべき状態」を記述します。

## Ansibleの定義ファイル
| concept          | 役割              |
|:-----------------|:------------------|
| inventory        | インフラとスタック(グループ)の対応づけを記述する|
| playbook         | スタックをロール(role)の組み合わせとして記述する |
| role             | ロールの設定(ミドルウェアとか)をtaskの組み合わせとして記述する|

## 前準備

### githubからリポジトリをクローンします。

[github:oci-ansible-template](https://github.com/manaki-naoe/oci-ansible-template)

```bash
$ git clone https://github.com/manaki-naoe/oci-ansible-template.git
```

### 構成

- inventory
    - production
        - group_vars
            - all.yml.default
        - hosts.default
    - staging
        - group_vars
            - all.yml.default
        - hosts.default
- playbooks
    - admin-servers.yml
    - firstrun.yml
    - web-servers.yml
- roles
    - common
        - handlers
        - tasks
            - firewall.yml # SELinux無効化、firewallの無効化を行う
            - japanese.yml # ロケール、タイムゾーンの確認変更を行う
            - main.yml # 各ymlの呼び出しを行う
            - volume.yml # インスタンスの作成時にカスタム・ブート・ボリュームサイズを変更してもボリュームサイズは拡張されないので拡張を行う。
            - yum.yml # 共通するパッケージのインストールを行う。
        - templates
    - docker
        - handlers
            - main.yml
        - tasks
            - main.yml
        - templates
            - docker-ce.repo.j2
        - vars
            - main.yml
- ansible.cfg
- setup.sh
- site.yml

### inventoryの編集

#### production/hosts
hosts.defaultをコピーしてhostsにする

```:hosts
adminserver ansible_ssh_host=内部IPアドレスを記入

webserver1 ansible_ssh_host=内部IPアドレスを記入

[all:vars]
ansible_ssh_private_key_file=~/.ssh/***.pem
ansible_ssh_user=work

[admin-servers]
adminserver

[web-servers]
webserver1
```

#### production/group_vars/all.yml
all.yml.defaultをコピーしてall.ymlにする

```yaml:all.yml
work_user: "work"
work_user_password: "お好きなパスワード"
```

### ansibleのインストール

プロジェクト直下にあるsetup.shを実行する

```bash
# sh setup.sh
```

### ansibleの実行

#### firstrunプレイブックの実行

ロケールの設定、ユーザ作成を行うプレイブック

```bash
# ansible-playbook -i inventory/production/hosts playbooks/firstrun.yml
public key path::/root/.ssh/***.pub #パブリックキーを入力します。

#~~~
#省略
#~~~

PLAY RECAP *************************************************************************************************************************adminserver                : ok=7    changed=6    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```

#### site.ymlの実行

システム全体でどのPlaybookを利用するかを制御します。

```bash
# ansible-playbook -i inventory/production/hosts site.yml

PLAY RECAP *************************************************************************************************************************adminserver                : ok=16   changed=8    unreachable=0    failed=0    skipped=2    rescued=0    ignored=1
```

#### 確認

dockerがインストールされているのが確認できます。

```bash
# docker --version
Docker version 19.03.2, build 6a30dfc
```
Emacsで絵文字と他の字の幅を合わせる

自分用メモ。

Emacsで文書を作成する時のフォントに、IPA明朝を使っている。
特に気に入っているわけではないが、

- JIS X 0213:2004の難しい漢字が全部入っていること
- 等幅であること
- 明朝体なのでとめはねが分かること

が理由で、消極的に選択していた。

しかし、絵文字でSymbolaというフォントを理由すると、幅がずれるので気になっていた。
以下のように設定した。

# init.el
（実際にはorg-modeで運用しています）

```.emacs.d/init.el
#+BEGIN_SRC emacs-lisp 
  (defun koko-font ()
    (interactive)
    (princ (font-xlfd-name (font-at (point)))))
  (global-set-key (kbd "C-c f") 'koko-font)

  ;;; ずれ確認用 半角40字、全角20字
  ;;; AIfUEaiueoAIUEOaiueoAIUEOaiueoAIUEOaiueo ASCII英字
  ;;; 0123456789012345678901234567890123456789 ASCII数字
  ;;; ｱｲｳｴｵｱｲｳｴｵｱｲｳｴｵｱｲｳｴｵｱｲｳｴｵｱｲｳｴｵｱｲｳｴｵｱｲｳｴｵ JIS X 0201ｶﾅ
  ;;; あいうえおあいうえおあいうえおあいうえお JIS X 0208ひらがな
  ;;; アイウエオアイウエオアイウエオアイウエオ 同カタカナ
  ;;; ＡＢＣＤＥＡＢＣＤＥＡＢＣＤＥＡＢＣＤＥ 同英字
  ;;; 亜唖娃阿哀亜唖娃阿哀亜唖娃阿哀亜唖娃阿哀 同漢字
  ;;; 𠀋𡈽𡌛𡑮𡢽𠀋𡈽𡌛𡑮𡢽𠀋𡈽𡌛𡑮𡢽𠀋𡈽𡌛𡑮𡢽 JIS X 0213漢字
  ;;; 🀄🀅🀆🀇🀈🀄🀅🀆🀇🀈🀄🀅🀆🀇🀈🀄🀅🀆🀇🀈 絵文字

  ;;; デフォルト
    (set-face-attribute 'default nil :family "msmincho" :height 210)
    (set-fontset-font (frame-parameter nil 'font) 'katakana-jisx0201 (font-spec :family "IPA明朝" :size 28))
    (set-fontset-font (frame-parameter nil 'font) 'japanese-jisx0208 (font-spec :family "IPA明朝" :size 28))
  ;;; 絵文字の設定　🀄🀅🀆🀇🀈 1f004～1FFFD
    (set-fontset-font (frame-parameter nil 'font) '(#x1F004 . #x1FFFD) (font-spec :family "Symbola" :size 35))
#+END_SRC
```

`(font-xlfd-name (font-at (point))`という関数を評価すると、カーソル位置のフォントの名前、サイズなどの情報が返る。
上では`koko-font`という関数を作り、`C-c f`にバインドした。

次にフォントの設定。
デフォルトはすべてIPA明朝で、`height`を210にした。
`set-face-attribute`関数では、heightで指定する。

絵文字はSymbolaフォント（Emacs用の、フリーの白黒フォント）を設定した。
`size`を35にした。
これで他の文字種と幅が揃う。（高さが変わるんだけど。。
絵文字はUnicode 12がサポートするU+1F004～1FFFDということにした。

# フォントのダウンロード元

__IPA明朝：「IPAフォントのダウンロード」__

https://ipafont.ipa.go.jp/old/ipafont/download.html

ダウンロードしたIPA明朝のTTF（ipam.ttf）を~/.fonts/に置く。

__Symbolaフォント：「Unicode Fonts for Ancient Scripts」__（※絵文字は古代文字ではないが。。

http://users.teilar.gr/%7Eg1951d/

2019-12-28追記：現状では下の場所でダウンロードできた。

https://www.wfonts.com/font/symbola

ダウンロードしたSymbola.ttfを同じ場所に置く。

2019-12-18追記：上では~/.fonts/において、Linuxの自分のユーザーだけで使う方法を説明しているが、Windowsにフォントをインストールして、それを見に行ったほうが手軽な場合もある。このことについては以下の記事を参照。

https://qiita.com/query1000/items/6ea7665529b022eb5f45

# フォントキャッシュの更新
置いたら以下のコマンドを実行してフォントキャッシュを更新する。

```
$ sudo fc-cache -fv
```

これで以下の画面のように表示される。

![SnapCrab_NoName_2019-10-6_22-0-0_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107571/e98a8074-142a-b573-611f-0014ec3f7a64.png)

たったこれだけのことをするのに、数時間も掛かってしまった。。
人間シンボーラ

(10/7 追記）

昨日公開した版のinit.elでは、絵文字以外は全部IPA明朝にしていた。

```
;;; デフォルト
    (set-face-attribute 'default nil :family "IPA明朝" :height 210)
```

でもIPA明朝の半角英数字だと半角英数字が私の環境（Windows10＋WSL＋Ubuntu＋Emacs26）では見えなくなるので、MS明朝にした。
MS明朝はmsmincho.ttcをC:/Windows/fontsからコピーしてWSLの~/.fonts/に格納した。

```
    (set-face-attribute 'default nil :family "msmincho" :height 210)
    (set-fontset-font (frame-parameter nil 'font) 'katakana-jisx0201 (font-spec :family "IPA明朝" :size 28))
    (set-fontset-font (frame-parameter nil 'font) 'japanese-jisx0208 (font-spec :family "IPA明朝" :size 28))
```

サイズを調整すれば他のフォントと調和すると分かったので英数字の等幅フリーフォントでカッコイイのを探すつもり。
本記事の中のinit.elはしれっと直しました。スミマセン
第0回ETロボコン講座

#ETロボコン講座
ぼくたちの学校にはETロボコン部があるのですが毎年結果出せていないです（~~2019年も出せませんでした、、、~~）
理由はさまざまあれど一番足りてないのは**後輩への引継ぎだ**と感じました。
毎年の積み上げがあるはずのなのにそれは引き継がれておらず僕らは0から手を付ける状態でした。
そんな思いをこれからETロボコンに入る後輩たちにさせたくないので僕らが積み上げていったことをここに綴って糧にしてもらえたらなと思って書くことにしました。
**これからETロボコンに参加するよなんて方の参考にもなれば幸いです。**

#今回は練習
いかんせんQiitaで文章をかいたことがないので今回は書き方の練習だけします。なので読み飛ばして次の章へいってくださいm(__)m

#遊びます
---
|２０１７|２０１８|２０１９|
|:--:|:--:|:--:|
|電池ぶた忘れる|電池ぶた忘れる|電池ぶた忘れる|     
 
###ETロボコン公式サイト  
[ev3way-et](https://www.google.com/url?sa=i&source=images&cd=&cad=rja&uact=8&ved=2ahUKEwiP-6611oflAhXR7GEKHcIhD_QQjB16BAgBEAM&url=https%3A%2F%2Fwww.etrobo.jp%2F&psig=AOvVaw2wCnmEdXbysFqztme7cKHS&ust=1570452716954214)
###ロボットの写真
![alt](https://www.google.com/url?sa=i&source=images&cd=&cad=rja&uact=8&ved=2ahUKEwiP-6611oflAhXR7GEKHcIhD_QQjB16BAgBEAM&url=https%3A%2F%2Fwww.etrobo.jp%2F&psig=AOvVaw2wCnmEdXbysFqztme7cKHS&ust=1570452716954214)

`こんにちはキータ`

~~~C:test
printf("Hello Qiita")
~~~

#満足です
初の開発合宿_201910

初の開発合宿で新人＋フリーエンジニア（10名参加）が集まり一緒に楽しく行いました。
今回はそれぞれ目標を立てて個人プロジェクトの作業をしました。達成できた人、できてない人もいましたが、良い経験になったと思います。エンジニアとして成長できるきっかけになった合宿でした。

## 次戦準備
* 温泉予約
* 課題を決める
* 開発環境の準備、確認
* ゴールを決める（これが重要）

## 場所
あの有名な「土善温泉」
http://www.dozenryokan.com/

本当に開発の施設は素晴らしかった。でも次回はairbnbを利用してやってみたい。

## 今回の目的
会社の仕事でなかなか集中できなかった個人プロジェクトを１日でこつこつやってみる。

* Must課題
    * iOS Hakenman復活(リリースまで)
    * Android Hakenmen機能追加(リリースまで)
    * 会社紹介HP改善（.comへ公開まで）

* 個人課題
    * raspberry pi + face recognition AWS　(Python)
    * iOS１３対応紹介(Dark mode)
    * その他

## スケジュール

| タイム | やること | 備考 |
|:---|:---:|:---:|
|13:00 |~~乾杯~~ ＆ 開発スタート | |
|19:00 |宴会 | |
|21:00 |開発 ＆ 自由時間 | |
|翌日 | - | - |
|08:00 |朝食 | |
|11:00 |結果LT | ３分以内で合宿結果の報告 |
|12:00 |合宿終了＆解散 | |

## 合宿記録

いよいよ到着！
![IMG_1326.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32323/c07d1e3d-0763-f52c-4864-d1c6c7f46fb6.jpeg)

作業中の様子。
以外とすぐ集中できて開発が始まりました。
<img width="1024" alt="8693E3C3-2165-47C1-86EC-47851BFA2BB2.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32323/36eb8b7d-ff25-b428-0c19-2df4238c6e2f.jpeg">

夕食タイム
お料理は美味しかった。ビールを飲みたかったですが、我慢我慢。
終わった後には引き続き開発をしたり、お風呂に入ったり、ビールをのんだりなどして過ごしました。

<img width="1024" alt="902647E4-2D10-4794-93EC-0977CD7F4E76.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32323/96ea3d5a-21ea-a1b6-39bc-7d244019236c.jpeg">


## 翌日のLT
結果報告。

<img width="1024" alt="F1A82909-BEF6-40DE-8AAD-7C35C7FBB270.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32323/4a2d7fa8-9384-c438-ae9f-c0a7a5181d1e.jpeg">


## 最後に(感想＆意見)

* また行きたい！
* 良い経験ができた。
* コードを書くのが楽しい。
* みんなとコミュニケーションができてよかった。
* 準備不足
* 未経験の人に情報が足りなかった。
* 短い合宿でどこまでできるのかの目標設定が難しかった。
* やはり個人プロジェクトより、グループでやった方が良い。
* お酒の飲み過ぎ問題
* 自分のおもちゃプロジェクトを作りたい
* 現場で使っているスキルを活用したい
* チームのスキルをあげたい
* 合宿にきてから１からスタートするのが良い。
* 自分の目標をみんなに共有する
* 終わったらアンケートをとる
* チーム単位での合宿も良いかも。
* 合宿では開発要件だけでもよい。コード書くのは宿題で持ち帰る。
Vue.js メモ

<h1>.bind(this)</h1>
スコープのブロックの外から値を持ってくるとき、functionに.bind(this)をつけることによって正常に持ってこれる。（説明が下手）
コールバック関数でthisを使うときに必要

<h1>$routerと$routeの違い</h1>

\$router: Routerインスタンス。Webアプリケーションに１つだけ存在する。全般的なRouter機能を管理。
\$route: Routerオブジェクト。ページ遷移によるルーティングが発生するごとに生成される。現在動いているルートの状態を保持したオブジェクトで現在のパスやURLパラメーターなどの情報を取得できる。
laravel インストール ~ 運用まで（備忘録）

# インストール

```php:
composer create-project --prefer-dist laravel/laravel 名前
```
# インストール後
```php:
composer update
cp .env.example .env
php artisan key:generate
```

# 良く使うライブラリ

```php:
"barryvdh/laravel-debugbar": "^3.2",
```


# 良く使うコマンド
## マイグレーション

```php:
php artisan make:migration create_users_table --create=users
php artisan migrate
```

## コントローラの作成
```php:
 php artisan make:controller HelloController
```
LaravelでjQuery-UIのダイアログ（dialog）を使おうとすると「TypeError: $(...).dialog is not a function」エラーになる

周知の通りLaravelにはビュー生成のエンジンとしてBlade機構が備わっています。ログなどを見ていると中身はVue.jsのようなのですが、とにかくこのBladeテンプレートの中でjQuery-UIのダイアログ機能を使おうとするとブラウザーコンソールに謎の（想定外の）「TypeError: $(...).dialog is not a function」というエラーが出て期待動作しない現象が起きました。

```html:jQuery-UIを使おうとした際の謎の（想定外の）エラー
TypeError: $(...).dialog is not a function
```

playcode.ioにフィールドを移して少しずつLarabelの生成HTMLをシュリンクしていったところ、

```html:Laravelによって生成されたHTML
    <!-- Scripts -->
    <script src="https://laravel-mysql-base.herokuapp.com/js/app.js"></script>
```

というフレームワークが提供しているJSスクリプトの参照が存在していると期待動作しないということが分かってきました。
これを手がかりに更に確認（検索）を進めたところ以下のようなissueエントリーを発見しました。同じ現象です。

https://github.com/laravel/framework/issues/28984
└─ jQueryUI incompatible with js/app.js #28984 

<img width="738" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206965/d7e1a687-e795-9f77-53be-97f8b4c0c34f.png">

残念ながらこのエントリーはクローズされていて、問題の根本解決には至っていないように見えました。

ここで注目したのは `app.js` への参照が `app.blade.php` の最後に記されている点です。勿論、JSの参照は最後に書くという作法もあるのですが今でも多くはheadに書く事が多いです。
実際、私が編集して管理していた `app.blade.php` も次のように `app.js` への参照を尊重して（？） `app.js` への参照よりも前に参照を書いていました。勿論、この場合競合する関数などがあれば `app.js` の内容が優先されます。

```html:app.blade.phpの概要
    <!-- Custom Scripts Ref -->
    @yield('scripts')
....
    <!-- Custom Scripts -->
    @yield('postscripts')
    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}"></script>
```

そこで、仕方ないので以下のjQUery-UI関連の記述を `app.js` への参照よりも後に記すことにしました。


```html:jQUery-UI関連の記述
@section('scripts')
<noscript>You must <a href="https://www.enable-javascript.com/ja/" target="_blank">enable JavaScript</a> in your web browser in order to pay via Stripe.</noscript>
<script src="//checkout.stripe.com/v2/checkout.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
@stop
```

```html:修正後のapp.blade.phpの概要
    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}"></script>
    <!-- Custom Scripts Ref -->
    @yield('scripts')
    <!-- Custom Scripts -->
    @yield('postscripts')
```

これで無事にダイアログを表示することが出来ました。ただ、オーバーライドの影響でLaravelのBlade（HTML）動作に何らかの悪影響が出る機能が今後確認されるかもしれません。

<img width="312" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206965/058f403d-6a89-d9d1-ab88-f3d542019503.png">

今回学んだ知見は以下の通りです。
1. 謎のJSエラーに遭遇したら `app.js` への参照との順番を疑ってみる。
2. 以下のように、`app.blade.php`のセクションを分けておいて、テンプレートからJSの挿入位置をコントロールできるようにしておくと良い。

```html:修正後のapp.blade.phpの概要
    <!-- Custom Pre Scripts Ref -->
    @yield('preScriptsRef')
    <!-- Custom Pre Scripts -->
    @yield('preScripts')

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}"></script>

    <!-- Custom Post Scripts Ref -->
    @yield('postScriptsRef')
    <!-- Custom Post Scripts -->
    @yield('postScripts')
```
appleScriptで定期的に休憩行けと怒ってくれるダイアログを作った話

# 背景

私は休憩の取り方が下手です。タスクから離れて頭を冷やしたほうが全体的な効率が上がるの知っているのに、
没頭してしまうのと、タスク終わしたいという逸る気持ちからモニターから離れられません。

そこで、少し触りたいなと思っていた**appleScript**で「休憩して頭冷やしなさいよ」と一定時間おきに言ってくれるダイアログを作ることにしました。

ダイアログ出すまでは一瞬でできました。

# 用意するもの
- 既存の**Script Editor** （スクリプトを書くだけなら好きなエディタでもOK）
- 今回は`crontab`で定期実行を登録したので**Terminal**

以上

# フロー

## 1. Script Editorを起動

こいつを起動する。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274090/341543de-6de8-b119-9edc-424e6382b805.png" width=500> 

New document にするとブランクファイルが作成できます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274090/02d83b2d-f5b7-b388-b8dd-828920954349.png" width=500> 

## 2. ダイアログを出すフローを書く

コードを書いていきます。
今回、一定時間おきにアラートを出すという目標は`terminal`で`cron`を設定することで達成します。
ので、以下コードはそれを前提としています。
時間指定、OKボタンタップ時のイベントなどスクリプトにかけると思いますが、それはこれからカスタムしていこうと思ってます。

#### コード
```
tell application "System Events"
	activate
	display dialog "一回休憩しろ、休め、冷やせ、風に当たれ"
end tell
```
以上

少ないですね。解説は以下。

**tell application "System Events" ~ end tell**
""にはアプリケーション名が入る。そのアプリケーションに対して命令しますよ、という命令文。
end tell の間に処理を書く。
これがないと、`cron`設定をした時`“No User Interaction Allowed”`というエラーが出て起動しない。
参考：　https://forum.keyboardmaestro.com/t/no-user-interaction-allowed-in-execute-an-applescript/5728

**activate**
上記で指定したアプリケーションが最前面に来ることを指定する。今回はダイアログが最前面に来るようになる。

**display dialog "foo"**
ダイアログを出す記述。””にはダイアログ内テキストを入れる。

編集が終わったら保存したい場所に保存してください。拡張子は`.applescript`です。
`.scpt`でも起動しますが、再編集した際に上書き保存できないと怒られます。

##  3. 定期起動する設定をする
今回は、上記の通り`cron`として定期実行を行うように設定します。

**1. terminalで`export EDITOR=/usr/bin/vim`を入力して使用エディタを`vim`に設定する**

```
export EDITOR=/usr/bin/vim
```

これをやらないと以下で`crontab`に記載しても管理者権限で入れるcronを格納している大元に記載されないらしく、コピーに記載されてしまうようです。なので最初に設定しておきます。
これで一応大元に記載されているか確認できます。


**2. `crontab -e`でcrontabを編集する**

```
crontab -e
```

-e で編集モードを開けます。

**3. `*/1 * * * * cd /fileまでのpath/ && osascript Alert.applescript`を記入、保存して閉じる**

```
*/1 * * * * cd /fileまでのpath/ && osascript Alert.applescript
```

上記では１分毎にと設定してます。
書式はこちらが参考になります：https://www.server-memo.net/tips/crontab.html

コマンドで`.applescript`を起動させるためには`osascript`コマンドを使用します。

しっかり大元に記載されているかは以下で確認できます。
`sudo cat /usr/lib/cron/tabs/USER_NAME`
or
`crontab -l`


# 4. ダイアログがでる

指定時間後、ダイアログが出ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274090/5c753773-6563-eb3a-ca8c-39fde05a827d.png)

# 終わりに

今回はただダイアログを出すまでしか`appleScript`には記述していませんが、一定時間経つまで他の動作させないとか、休憩時間終了したら送られてくるパスワード入れないと操作できないとかルナティックモードにしても良さそうです。

色々カスタムできそうなので、現状の実装でもダイアログ無視し始めたら対応を厳しくしていこうと思います。
平面上の多角形中に点があるかどうか判定する

下記の図のように、(5,5), (10,5), (10,10), (5,10)の青い点で囲まれた矩形があったとする。

![f1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88357/b88c319d-82ac-f908-5867-0a543a99dd79.png)

ここに、以下のように(7,8)のオレンジの点と(12,10)の緑の点があったときに、矩形中にあるかどうかを判定する方法を紹介する。

![f2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88357/80197c99-20d7-ae21-260e-3c40277af845.png)




`Shapely`というライブラリを利用する。
これは、GEOSをベースとしたpythonライブラリで、平面上の幾何学図形の分析と操作のために使われる。


参考: https://pypi.org/project/Shapely/



```
$ pip install shapely
```

## 矩形の中に点があるかどうか

以下のコードで確認できる。

```py
from shapely.geometry import Point
from shapely.geometry.polygon import Polygon

point = Point(7,8)
polygon = Polygon([(5,5), (10,5), (10,10), (5,10)])
print(polygon.contains(point)) # True

point = Point(12,10)
polygon = Polygon([(5,5), (10,5), (10,10), (5,10)])
print(polygon.contains(point)) # False
```

境界上の点は、矩形内の点ではないと判定される。

```py
point = Point(5, 5)
polygon = Polygon([(5,5), (10,5), (10,10),(5,10)])
print(polygon.contains(point)) # False
```

## 5点以上の場合

以下の図のように、5点ある場合はどうするのか？（ (7.5, 12.5)を追加した。）

![fig3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88357/03bd7392-1d3b-e5a5-5495-df5d846169ef.png)

```py
point = Point(7.5, 7.5)
polygon = Polygon([(5,5), (10,5), (10,10),(5,10), (7.5,12.5)]) # ここに追加するだけ。
print(polygon.contains(point)) # True
```

対象の図形を凸包として判定したい場合は、以下で確認可能だ。

```py
from shapely.geometry import Point
from shapely.geometry.polygon import Polygon
from shapely.geometry import MultiPoint


point = Point(7.5, 7.5)
polygon = MultiPoint([(5,5), (10,5), (10,10),(5,10), (7.5,12.5)]).convex_hull
print(polygon.contains(point)) # True
```

この場合も、境界上の点はFalseと判定される。
CentOS 7でApacheをインストールし起動する

## ■ はじめに
CentOS 7でApacheをインストールして起動し、ブラウザでページを表示するまでの基本的な流れを紹介します。

## ■ 環境
- CentOS Linux release 7.6.1810 (Core)

## ■  Apache HTTP Server
Linuxで使われているWebサーバーとしてもっとも高いシェアを持つのは、Apache HTTP Server(Apache)です。
Apacheは様々なオープンソフトウェアを開発しているApache財団が開発しているソフトウェアです。

- Apache HTTP Server のWEBサイト
<img width="1081" alt="apache01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381808/6efa6df0-6788-cd9d-4096-0d83ee9a0e38.png">

Apacheにはいくつものバージョン系統があるが、大きく分けて、2.0系、2.2系、2.4系があります。
バージョンが異なると機能や設定がことなるが「2.2」「2.4」の部分が同じであれば、大きな違いはないと考えてよいです。
CentOS 7では2.4.6が採用されている。

## ■ Apacheのインストール

### 1. インストール

``` shell
$ sudo yum -y install httpd
```

### 2. 確認

以下のコマンドで確認できます。

``` shell
$ sudo yum list installed | grep httpd
```

また、以下のように実行することでインストールパスを確認できます。

``` shell
$ which httpd
```

実行結果として上記のようにhttpdのパスである「`/usr/sbin/httpd`」が表示されることを確認します。
これでhttpdのインストールが正常に終了したことが確認できます。

## ■ 設定ファイル httpd.conf

Apacheの設定ファイルは、`/etc/httpd/conf/httpd.conf`にあります。

- 設定の書式  
　`ディレクティブ 設定値`

ディレクティブとは設定項目のことです。
Apacheの設定では、設定変更に必要なディレクティブを確認し、その設定値を変更します。

| ディレクティブ | 説明 |
|:--|:--|
| ServerRoot | 設定ファイル等を配置するトップディレクトリ |
| Listen | Apacheが待ち受けるポート番号 |
| User | Apacheの実行ユーザー |
| Group | Apacheの実行グループ |
| ServerAdmin | Apacheの管理者 |
| ServerName | Webサーバー名 |
| DocumentRoot | ドキュメントルート |
| DirectoryIndex | インデックスファイル名 |

## ■ 設定ファイルの変更

今回は、ServerNameのみ設定します。
このディレクティブが設定されていないと、Apache起動時に警告エラーが表示されてしまいます。

### 1. httpd.conf を編集

``` shell
$ sudo vi /etc/httpd/conf/httpd.conf
```

### 2. httpd.conf の編集

- 変更前

``` shell:/etc/httpd/conf/httpd.conf
#ServerName www.example.com:80
```

- 変更後

``` shell:/etc/httpd/conf/httpd.conf
ServerName www.example.com
```

### 3. 構文チェック

`httpd -t` を実行する事で設定ファイルのシンタックスチェックが可能です。
実行結果に『 Syntax OK 』と表示されれば問題ありません。

``` shell
$ httpd -t
```

## ■ Apacheの起動

Apacheを起動します。

``` shell
$ sudo systemctl start httpd
```

Apacheを自動で起動したい場合は、

``` shell
$ sudo systemctl enable httpd
```

## ■ ファイアウォールの設定

デフォルトのファイアウォールの設定では、Webサーバーへのアクセスは許可されません。
そのため、Apacheを起動しただけでは外部からアクセスはできないので、ファイアウォールの設定を変更し、80番ポートのアクセスを許可します。
ファイアウォールの設定では、`firewall-cmd` コマンドを使います。

### 1.ファイアウォールの設定変更

``` shell
$ sudo firewall-cmd --permanent --add-service=http
$ sudo firewall-cmd --reload
```
これでWebブラウザからアクセスできます。

### 2. ブラウザからアクセス
Webブラウザのアドレス欄で「`http://IPアドレス`」を入力してください。
テストページが出れば成功。

<img width="1078" alt="apache02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381808/ed9cb772-c03d-09bf-38f9-229d5c4f2183.png">

## ■ HTMLファイルの作成

HTMLファイルを作成し、それを表示させてみます。

### 1. index.html の作成

``` shell
$ sudo vi /var/www/html/index.html
```

### 2. index.html の記述

``` html:/var/www/html/index.html
<html>
<head>
    <title>Test Page</title>
</head>
<body>
    <h1>Hello Apache</h1>
</body>
</html>
```

保存したら再度アクセスをしてみる。

<img width="1079" alt="apache03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381808/d1019a5d-db6f-d7ac-571d-d648ff3269d4.png">

ページが表示されれば成功です。
GitHub Desktopでローカルリポジトリを作成する手順

GitHub Desktopからgit-appのローカルリポジトリを作成する手順

1.GitHub Desktopを起動する。
2.左上の「Current Repository」→「Add」→「Add Existing Repository」を選択する。
3.ディレクトリを指定する。
※「Add Repository」がクリックできない場合は、以下の作業をターミナル上で行ってから、1~3の作業を行うこと。

```
$ cd ディレクトリの選択
$ git init
```
git initをしないと、リポジトリが作れないみたいです。

4.「Add Repository」をクリックする。
5.最初のコミットメッセージを入力して、コミットする。
※今回は、「Initial commit」と入力する。
6.[Publish repository]ボタンをクリックする。
7.GitHubのリモートリポジトリが作成できた確認する。
小学生のプログラミング教育について


## 小学生のプログラミング教育

2020年度小学校プログラミング教育の全面実施

(プログラミングという科目ができるわけではなく、算数や理科や総合的な学習の時間の中でプログラミング教育がスタートする)

-------
## なぜ今回このテーマ？
きっかけは日曜参観で小学3年生が
プログラミングの授業をしていた！
(他学年だが少し見学させてもらいました)
今後の子供たちが習うことを知ること
→将来の若い世代がどういう考え方をするか
(することを期待されているか)を知る
→未来を予測する一つの手がかり

-------

## 何を習うの？
文部科学省[小学校プログラミング教育の手引き](http://www.mext.go.jp/a_menu/shotou/zyouhou/detail/1403162.htm)
狙いとしては以下の3つ

- 「プログラミング的思考」を育むこと
- プログラムの働きや良さ、情報社会がコンピュータ等の情報技術によって支えられていることなどに気づく。コンピュータ等を上手に活用して身近な問題を解決したり、よりよい社会を築いたりしようとする態度を育むこと
- 各教科等での学びをより確実なものとすること

https://www.itmedia.co.jp/news/articles/1905/22/news114.html

-------

## 一方で、下記のように明記

- プログラミング言語を覚えたり、プログラミングの技能を習得したりすること自体が狙いではない
- 実際にコンピュータを使ってプログラミングすること必須
- 具体的な例示をあげているが、これにとらわれずに実施すること推奨

-------
## Google Blockly（グーグルブロックリー）
ビジュアルプログラミング言語
命令ブロックを組み合わせるだけでプログラミングできる

Scratch3.0もBlocklyがベースになっている
https://developers.google.com/blockly/

-------
## Scratchとは

Scratchは小学生のプログラミングの大定番

Scratch3.0はHTML5とJavaScriptで開発
旧バージョン2.0で必須だったFlash Playerが不要
つまり我が家のiPadちゃんでScratch利用可能に！！

-------
## Scratchをまずは触ってみよう

下記はNHKさんで放送されていた番組です。

>Why！？プログラミング
https://www.nhk.or.jp/sougou/programming/?das_id=D0005180301_00000

授業参観でも使用していてニャーニャーでした

-------
## Scratch実習

iPad or PCを用意したので
皆さん猫ちゃんの動きを色々変えてみてください。
もちろんコスチュームや背景も！
https://scratch.mit.edu/projects/322125727/
https://scratch.mit.edu/projects/322130943/

-------
## Microsoft MakeCode
Microsoft
https://www.microsoft.com/ja-jp/makecode

>MakeCode（メイクコード）は、「Microsoft MakeCode（マイクロソフト メイクコード）」とも呼ばれる、Microsoftが開発したプログラミング環境。あらかじめ準備されている命令ブロックを組み合わせることでプログラムを作成することができ、「MakeCode for Minecraft」や「MakeCode for micro:bit 」など、プログラミングするものにあわせて様々なバージョンが存在する。

-------
## Swift Playgrounds

>Swift Playgroundsは、楽しくインタラクティブな方法でSwiftのコードの書き方を学べるiPad用のアプリケーションです。アプリケーション上で直接ロボットやドローンを動かすプログラムを作れます。

-------
## 次回

実は本当に紹介したかったのはmicro;bitだったりするのです
今回はそのための導入ということで
初KotlinでHello Worldしようと思ったらinvalid argumentで怒られた

## はじめに
Kotlinを少し勉強してみようと思い、既にインストール済みのVisual Studio Codeに拡張機能を入れて試してみました。

##動作環境
* Windows 8.1
* Visual Studio Code
* Kotlin 1.3.50

##参考記事
* [Windows PC に Kotlin をインストールする](https://qiita.com/toastkidjp/items/16ca39cc83e888a95256)
* [VSCodeでKotlinの実行環境を作る](https://qiita.com/k-yamada-github/items/fe2d16211bacfcf6f2db)

##インストール

1. Visual Studio Codeの拡張機能でKotlinを検索し、Kotlin Languageをインストール。
2. コンパイラを入れていないことに思い至り、[GitHub](https://github.com/JetBrains/kotlin/releases/tag/v1.3.50)からダウンロード。
3. 解凍して、パスを通せばOK。

試しにターミナルでkotlincを実行しましたが、表題のエラーで怒られました。

```
kotlinc test.kt -include-runtime -d test.jar
error: invalid argument: -include-runtime
info: use -help for more information
```

##原因

使用するコンパイラの間違いです。
GitHubには複数のリンクがありますが、最初にインストールしたのはこちら。
kotlin-native-windows-1.3.50.zip

nativeをインストールしていたのが間違いでした。
ただしくはこちら。
kotlin-compiler-1.3.50.zip

参考記事にはちゃんとkotlin-compiler-.zipって書いてあるのに、安易にWindowsの文字が含まれているリンクに引っ張られました。

同じ間違いをする人は少ないと思いますが、将来、再度環境構築する時のためのメモとして残しておきます。
Nuxt.js + TypeScriptでvue-awesome-swiperを使う

Nuxtでスライダーを使いたかったので、良さげなライブラリを導入してみる。

## 環境
* Windows 10 Pro
* WSL Ubuntu
* `yarn -v` -> `1.17.3`
* `node -v` -> `v12.10.0`
* `npm list nuxt` -> `nuxt@2.9.2`
* `npm list vue` -> `vue@2.6.10`

## セットアップ
コマンドを打ってインストール

```
yarn add vue-awesome-swiper
```

### plugins
```javascript:plugins/vue-awesome-swiper.js
import Vue from 'vue' 
import VueAwesomeSwiper from 'vue-awesome-swiper' 

Vue.use(VueAwesomeSwiper)
```

### nuxt config
```typescript:nuxt.config.ts
import { Configuration } from '@nuxt/types'

const config: Configuration = {
  css: [
    'swiper/dist/css/swiper.css',
  ],

  plugins: [
    { src: '~plugins/vue-awesome-swiper', ssr: false },
  ],
}

export default config
```

## 動かしてみる
```vue:hoge.vue
<template>
  <div>
    <swiper :options="swiperOption">
      <swiper-slide>う</swiper-slide>
      <swiper-slide>ん</swiper-slide>
      <swiper-slide>ち</swiper-slide>

      <div class="swiper-button-prev" slot="button-prev"></div>
      <div class="swiper-button-next" slot="button-next"></div>
    </swiper>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator'

@Component
export default class Hogeeeeee extends Vue {
  swiperOption: object = {
    navigation: {
      nextEl: '.swiper-button-next',
      prevEl: '.swiper-button-prev'
    }
  }
}
</script>
```

オプションとかは、https://surmon-china.github.io/vue-awesome-swiper/ を参照してみてください。


## 参考
[こちら](https://qiita.com/IKEMAKI/items/c68e094f412b04b1afc2)の記事を参考にさせていただきました！
@IKEMAKI さん、ありがとうございました。
pythonコマンドでpython3を実行したい

###現状
vmにubuntu serverを入れたら、python2とpython3がインストールされてた。pythonコマンドでpython3を実行したい！ついでにpipも。
pythonではpython2が実行される。
<img width="372" alt="1.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509180/e03e6049-7254-1ae1-56a4-e24c4c034b4e.png">
###変更
.bashrcを開く

```
vim ~/.bashrc
```
以下のコードを最後の行に追加します

```vim:.bashrc
alias python="python3" 
alias pip="pip3" 
```
保存したら、sourceします。

```
source ~/.bashrc
```

###確認
終わったら確認します。
<img width="364" alt="5.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509180/4a9ba682-e66d-52b4-0dd9-c5206bd88484.png">
変わっていることが確認できました。
Borutaが使うCPUスレッド数を指定する(Python版)

# はじめに
前回、R版の「[Borutaが使うCPUスレッド数を指定する](https://qiita.com/kimisyo/items/71416a3a20102c3c15a3)」を書いたが、Python版で同じことをしたいときの話

# 環境
- Python 3.X
- Boruta 0.3

# やり方
Borutaのクラスにそのような引数はなかったため、Borutaに与える予測器側のスレッド数をn_jobsで指定する。

以下はコード断片である。Borutaに与えるRandomForestRegressorのn_jobsを指定している。
これをうまく調整することによって、Borutaで特徴選択中に他の作業が何もできないという事態は防ぐことができる。

```python
rf = RandomForestRegressor(n_jobs=10, max_depth=5)
feat_selector = BorutaPy(rf, n_estimators='auto', verbose=3, random_state=100, max_iter=30)
feat_selector.fit(x, y)
```
Twitchのコメントを取得して解析するプログラム

今回(と言っても結構前に作ったやつだけど)、Twitchのコメントを取得して特定の言葉が何回出てきたかカウントするプログラムを作りました。
実行にはTwitch APIが必要です、[ここ](https://dev.twitch.tv/docs/authentication#registration)から作れます。

```python
import socket
import logging
import re
from emoji import demojize


server = 'irc.chat.twitch.tv'
port = 80
nickname = 'your twitch id'
token = 'your api id'
channel = '# channel id you want to get comments'
formatter = '%(asctime)s - %(message)s'
logging.basicConfig(level=logging.DEBUG, format=formatter)

def main():
    sock = socket.socket()
    sock.connect((server, port))
    sock.send(f"PASS {token}\r\n".encode('utf-8'))
    sock.send(f"NICK {nickname}\r\n".encode('utf-8'))
    sock.send(f"JOIN {channel}\r\n".encode('utf-8'))
    word_counter = 0
    patterns = [some word]
    try:
        while True:
            resp = sock.recv(2048).decode('utf-8')
            word_list = []
            if resp.startswith('PING'):
                # sock.send("PONG :tmi.twitch.tv\n".encode('utf-8'))
                sock.send("PONG\n".encode('utf-8'))
            elif len(resp) > 0:
                resp = demojize(resp)
                index = resp.rfind(' :')
                chat = resp[index:] 
                for pattern in patterns:
                    word = re.findall(pattern,chat)
                    [word_list.append(i) for i in word if len(word) >0]
                if len(word_list) >0:
                    logging.info(chat)
                    word_counter += len(word_list)
                    print(word_list)
                    print(word_counter)

    except KeyboardInterrupt:
        sock.close()
        exit()

if __name__ == '__main__':
    main()

```
あなたのツイッチのID(nickname)とAPI(token)、カウントしたいワード(複数可能 patterns)、コメントを取得したい配信者の名前を#の後に続けて入力(channel)して実行します。
実行後はワードが含まれるコメントと今までのカウント数が出ます。
　
今回はただカウント数だけ知りたかっただけでしたが、CSVに出力したり、時間と一緒に取得してグラフを作ってみるのもいいし、色々汎用性がありそうです。
argparseで複雑なバリデーションを行う

Pythonの引数解析モジュール、argparseを使う際、引数にちょっと複雑な書式を要求したい場合もあります。

そのような場合に、独自の検証コードを書くことで、正規表現など様々な方法でバリデーションを行うことができます。

## まずはプログラム

まずはプログラムから。

```python
import argparse

class rex_check(object):
  # バリデーションのためのクラス
  def __init__(self, pattern):
    # 初期化
    self.pattern = pattern

  def __contains__(self, val):
    # マッチ処理を行う
    return re.match(self.pattern, val)

  def __iter__(self):
    # エラー時にコンソールに表示される(invalid choice: 値 (choose from なんとか)
    # print_help()のmetavarでも表示されるので、metaverオプションを使って隠す
    return iter(("str", self.pattern))


parser = ArgumentParser()
parser.add_argument("-r", "--rect",
  type=str
  metavar="RECT",
  choices=rex_check(r"(?:\d+:){3}\d+"),
  default=[])
# ・・・そのほかのオプション指定・・・
```

と、しておくと・・・

```python
parser.parse_args(["-r", "abc"]) # NG
parser.parse_args(["-r", "1:1:1"]) # NG
parser.parse_args(["-r", "1:1:1:"]) # NG
parser.parse_args(["-r", "1:1:1:1"]) # OK
```

ちゃんと正規表現のパターンマッチが行われていることがわかると思います。

### 仕組み

`ArgumentParser#add_argumnet()`メソッドの引数`choices`は、本来配列を渡すことで、パラメータのとりうる値をその値に限定することができるというオプションですが、`__contains__()`と`__iter__()`を実装しているオブジェクトを渡すことで、そのオブジェクトによる検証を行うことができます。

内容はコメントに書いたとおりですが。

* `__contains__(self, val)`：valがパラメータの値。バリデーションOKの場合はTrue
* `__iter__(self)`：戻り値はパラメータの解析に失敗したときに出るエラーメッセージおよび、`metavar`に使用される。

`__iter__(self)`は`ArgumentParser#print_help()`メソッドで表示される`metavar`にも利用されるため、基本的にはここにクラスを指定した場合は、`metavar`もセットで指定するようにしておくと良いでしょう。


## 参考ページ

* [argparseの数値引数バリデーションチェックで無限個の許容範囲を指定する方法 \- Qiita](https://qiita.com/LyricalMaestro0/items/80e6ec2d58c828977172)
GridSearchCVでHoldOutを使いたい

#はじめに
scikit-learn の GridSearchCV の Cross Validation方法として、N-Fold Cross Validation や Leave One Outを指定する場合、本家のドキュメントを見ればすぐにやり方は分かるが、HoldOutについてはあまり情報がなかったため、調べたときのメモ。

#環境
- python 3.X
- scikit-learn 

#やり方
split数=1 の ShuffleSplit を GridSearchCV の cv に与えればよい。
HoldOutの割合は、ShffuleSplitのtest_sizeで指定する。

# コード
以下はコード断片である。最後の学習部分は省略。

```python
from lightgbm import LGBMRegressor
from sklearn.model_selection import ShuffleSplit
from sklearn.model_selection import GridSearchCV

params = {
  "num_leaves": [50, 100, 200],
  "max_depth": [50, 75],
  'min_data_in_leaf': [10, 20, 30],
  "num_leaves": [100, 200],
  "learning_rate": [0.01],
  "n_estimators": [2000, 2500, 3000],
}

estimator = LGBMRegressor()
ss = ShuffleSplit(n_splits=1, test_size=0.2, random_state=123)
GridSearchCV(estimator, params, cv=ss, scoring=r2)
```

# 参考
-[Using GridsearchCV () with holdout validation](http://stackoverflow.com/questions/48963813/using-gridsearchcv-with-holdout-validation)
ExecuteとExecuteTemplateはどっちを使えば良いのか (goのhttp/template)

# まず結論
違いは使用するTemplateを明示するか否かです。

`template.ParseFiles`で読み込んだファイルが

- 1つのみの場合
  - `Execute`もしくは`ExecuteTemplate`を使う
- 複数の場合
  - `ExecuteTemplate`を使う

基本的に`ExecuteTemplate`を使っておけば良い気がします。

# 実行してみる
Goのversionは1.12.9です。

### 使用するhtmlファイル
内容は適当です。

```html:one.html
<!DOCTYPE html>
<title>one</title>
************************
```

```html:two1.html
<!DOCTYPE html>
<title>two1</title>
************************
```

```html:two2.html
<!DOCTYPE html>
<title>two2</title>
************************
```

### Executeの場合
Templateを明示しなくても良い。

```go:main.go
package main

import (
	"html/template"
	"log"
	"os"
)

func main() {
	executeExample()
}

func executeExample() {
	tpl := template.Must(template.ParseFiles("one.html"))

	// Templateは明示しなくてよい
	// 面倒なので標準出力する(本来はサーバーのResonance writerを使用)
	err := tpl.Execute(os.Stdout, nil)
	if err != nil {
		log.Fatalln(err)
	}
}
```
```terminal:実行結果
<!DOCTYPE html>
<title>one</title>
************************
```

### ExecuteTemplateの場合
Templateを明示する。

```go:main.go
package main

import (
	"html/template"
	"log"
	"os"
)

func main() {
	executeTemplateExample()
}

func executeTemplateExample() {
	// 複数パースする
   	tpl := template.Must(template.ParseFiles("htmls/two1.html", "htmls/two2.html"))

	// Templateを明示する
	err := tpl.ExecuteTemplate(os.Stdout, "two1.html", nil)
	if err != nil {
		log.Fatalln(err)
	}

	err = tpl.ExecuteTemplate(os.Stdout, "two2.html", nil)
	if err != nil {
		log.Fatalln(err)
	}

	// Executeを使うと最初の一つが出力される
	err = tpl.Execute(os.Stdout, nil)
	if err != nil {
		log.Fatalln(err)
	}
}
```

```terminal:実行結果
<!DOCTYPE html>
<title>two1</title>
************************
<!DOCTYPE html>
<title>two2</title>
************************
<!DOCTYPE html>
<title>two1</title>
************************
```

# もう一度結論
`ExecuteTemplate`だけ使用すれば問題ないと思います。

# ちなみに
一度`Execute` or `ExecuteTemplate`を実行したあとに`ParseFiles`を行うとエラーを吐きます。  
使うTemplateは予めすべて`ParseFiles`で読み込みましょう。 

```go:main.go
package main

import (
	"html/template"
	"log"
	"os"
)

func main() {
	executeMultiExample()
}

func executeMultiExample() {
	tpl := template.Must(template.ParseFiles("htmls/one.html"))

	err := tpl.ExecuteTemplate(os.Stdout,"one.html", nil)
	if err != nil {
		log.Fatalln(err)
	}

	tpl, err = tpl.ParseFiles("htmls/two1.html")
	if err != nil {
		log.Fatalln(err)
	}

	err = tpl.ExecuteTemplate(os.Stdout, "two1.html", nil)
	if err != nil {
		log.Fatalln(err)
	}

}
```

```terminal:実行結果
<!DOCTYPE html>
<title>one</title>
************************
2019/10/06 20:43:30 html/template: cannot Parse after Execute
```

# おわりに
補足等あればコメントして頂けるとありがたいです。
VMwareでKaliLinuxをインストール

# TL;DR
Mac版VMware Fusion上でKaliLinuxをインストールする際にちょっと詰まったのでメモ。
# インストール
https://www.kali.org/downloads/ で64bitのISOイメージをダウンロードし、Fusionを起動。
<img width="752" alt="スクリーンショット 2019-10-06 20.18.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291089/ca4ba52f-c089-93e0-32d7-57c7488ec34f.png">
ISOファイルを選択し、"続ける"を押す。
"オペレーティングシステムの選択"では"Linux 5.x以降のカーネル(64ビット)"を選択。
<img width="752" alt="スクリーンショット 2019-10-06 20.24.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291089/a18505e8-07c7-8483-3c70-14349560b457.png">
"続ける"を押し続け、仮想マシンファイルを作成する。
起動後、Installを選択、キーマップの設定やrootのパスワードを設定し、適当にEnterを押しながら進めていくと、ディスクイメージのコピーが始まる。プログレスバーが70％まで進んだあたりでこの画面が表示される。
<img width="912" alt="スクリーンショット 2019-10-06 20.32.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291089/04f2cd9a-f6fb-fada-69bc-e859e11026cc.png">
何度再開しても事態が改善しないので、検索を続けていると https://unix.stackexchange.com/questions/311176/an-installation-step-failed-kali-linux-2016-2-64-bit に30GBまで仮想ディスクの容量を増やせばいいと書かれている。メニューバーの"仮想マシン"、"シャットダウン"を選択した後、レンチのアイコンからハードディスクを選択。
シークバーで30GBにディスクサイズを変更する。
<img width="752" alt="スクリーンショット 2019-10-06 20.45.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291089/0c27e8f9-c6d1-7fb0-757d-1903dd9858c8.png">
再び起動し、インストールをする。
Scrapy 1.7 document 適当訳

# Scrapy 2.5.0 文書 適当訳あります
https://qiita.com/kuma35/items/df2a5ae70c16198045d5
# Scrapy 1.7.3 document 適当訳

Scrapyは既に1.2を訳された方 Scrapy 日本語ドキュメント( https://qiita.com/hatai/items/b68d717199364c718255 )がいらっしゃいますが、バージョンごとに機能の追加とか、非推奨・非推奨削除が結構あるようなので車輪の再発明とあいないりました。

文書はこちら

https://doc-ja-scrapy.readthedocs.io/ja/latest/

※リリースノートの翻訳はつまみ食いレベルです。
※まだ未校正です。ぼちぼち直していきます(2019.10.06現在)

githubの方は autodoc 絡みで Scrapyリポジトリをまるごと持ってきた上で、
そのリポジトリを継承するのはうまく行かなかったので翻訳用に新規リポジトリでやっています。よって本家とは繋がっていません。本家のバージョン上がったときは手動でなんとかするハメになるでしょう。
【Docker】Docker for Macでデータをコンテナに渡す場合、パイプ渡しとファイル渡しではファイル渡しの方が速い

# 検証したかったこと
ある程度大きな動画ファイルを処理する場合、以下2つのコマンドでどちらが高速かを検証したかったです。
長々と書いてますが、要するに`Docker`経由で`ffprobe`を動かしてファイルを解析しています。

```bash:パイプ渡し
cat ${ファイルのパス（相対パス可）} | docker run --rm -i alpine-ffmpeg ffprobe -hide_banner -v error -print_format json -show_streams -i pipe:0
```

```bash:ファイル渡し
docker run --rm -i --mount type=bind,src=${ファイルの絶対パス},dst=/tmp/a,readonly alpine-ffmpeg ffprobe -hide_banner -v error -print_format json -show_streams -i /tmp/a
```

## 検証に用いたDockerfile
`docker build -t alpine-ffmpeg ./`としてビルドしています。

```dockerfile
FROM alpine:3.10.2

# ffmpegのインストール
RUN apk add --update --no-cache ffmpeg=4.1.4-r0

# ユーザー追加
RUN adduser -D ffmpeg_user -G nogroup
# docker run時に使われるユーザーに追加したものを指定
USER ffmpeg_user
```

## 実行環境
Dockerは`CPUs: 2`, `Memory: 4.0GiB`, `Swap: 2.0GiB`の設定で動かしました。

| 環境 | バージョン |
|:-:|:-:|
| OS | macOS Mojave 10.14.6 |
| Docker | Docker for mac 2.1.0.3 |

# 計測結果
計測は`Time`コマンドで行い、計測値は10回連続で実行して一番小さいものとしています。

## mp4(17.5MB)
| 手法 | real[s] | user[s] | sys[s] |
|:-:|:-:|:-:|:-:|
| パイプ渡し | 1.226 | 0.038 | 0.029 |
| ファイルマウント | 1.147 | 0.029 | 0.015 |

## mkv(432.4MB)
| 手法 | real[s] | user[s] | sys[s] |
|:-:|:-:|:-:|:-:|
| パイプ渡し | 1.870 | 0.068 | 0.095 |
| ファイルマウント | 1.292 | 0.037 | 0.019 |

## 考察
傾向的には明らかにファイルマウント式の方が高速でした。

また、パイプ渡しの場合ファイル内容によってかなり動作が遅くなる場合があり、`ffprobe`の結果が変になることが以前あったという話も聞くので、安定を取るならやはりファイル渡しの方がベターかなと思います。

この傾向が出る原因や、ホスト/コンテナを他OSにしてやるとどうなるかに関しては検証していないので分かりません。

# 感想
「パイプ渡しのが速い」と勝手に思ってましたがそうでもなかったです。

後、前に試した時は検証に使ったmp4ファイルの場合パイプ渡しがマウント渡しの10倍程度実行時間かかってたんですが、今になって試すとそこまで酷い差は出ませんでした。
OS・`Docker`共に下1桁までバージョン違ってないはずなのになぜだ……。

ここまで書いた通り、パイプ渡しの挙動に色々と疑問が残る結果になってしまいましたが、動かして確認するなら以下1 ~ 3をホスト/コンテナのOSの組み合わせを変えながら検証すると思うと物凄く時間がかかりそうです。

1. ホスト -> `Docker`の挙動
2. `Docker` -> コンテナの挙動
3. 1, 2がファイル種別によってどう変わるか

なので、ファイル渡しの方がベターを結論として一旦検証は諦めます。
【Swift】TelloとUDP通信①- Telloにメッセージを送信する -

#概要
Ryze Tech社のドローン「Tello」は、[Tello SDK](https://terra-1-g.djicdn.com/2d4dce68897a46b19fc717f3576b7c6a/Tello%20编程相关/For%20Tello/Tello%20SDK%20Documentation%20EN_1.3_1122.pdf)でプログラミングを行い、ドローンを操作することができます。

Tello SDKでは、Tello(IP:192.168.10.1 PORT:8889)とUDP通信を行いTelloを操作しています。

今回は、Tello SDKを参考に、Swiftでのドローンのプログラミングを行います。


#Telloに接続する
SwiftはNWConnectionを使用することででUDP通信を行えるため、
Networkをimportし、NWConnectionを使用できるようにします。

```
import Network
```

まず、NWConnectionを使用し、UDPでTello(IP:192.168.10.1 PORT:8889)との接続を開始します。

```
//Telloへの接続の初期化
let connection = NWConnection(host: "192.168.10.1", port: 8889, using: NWParameters.udp)
```

```
//Telloへの接続開始
connection.start(queue: .global())
```

接続開始後にTelloとの接続状態の更新を受け取ります。接続が確立された場合、stateがreadyになります。

```
connection.stateUpdateHandler = { state in
            
     switch state {
          case .setup:
               ()
          case .waiting(let error):
               print(error)
          case .preparing:
               ()
          case .ready:
               ()
          case .failed(let error):
               print(error)
          case .cancelled:
               ()
     }

}
```


#コマンドをTelloに送信する
Telloとの接続状態がreadyになった時、Telloにcommandを送ることでTelloを操作することが可能になります。

```
//コマンドをdataに変換
let text = "command"
let message = text.data(using: .utf8)!

//Telloに送信
connection.send(content: message, contentContext: .defaultMessage, isComplete: true, completion: .contentProcessed({ error in if let error = error { print(error) } }))
```

以下のコマンドを使用することで、Telloの離陸、着陸の操作ができます。

|  コマンド  |  操作  |
| ---- | ---- |
|  command  |  SDKモード開始  |
|  takeoff  |  離陸  |
|  land  |  着陸  |



#参考

[NWConnection](https://developer.apple.com/documentation/network/nwconnection)
[Tello SDK](https://terra-1-g.djicdn.com/2d4dce68897a46b19fc717f3576b7c6a/Tello%20编程相关/For%20Tello/Tello%20SDK%20Documentation%20EN_1.3_1122.pdf)
[[WWDC18] iOS 12で登場するNetwork Frameworkでネットワークプログラミングが容易になりそうです #WWDC18](https://dev.classmethod.jp/smartphone/iphone/wwdc18-introduce-network-framework/)
[PythonによるTello操作（基本、及びクラウドからのMQTTによる操作まで）](https://qiita.com/makotaka/items/e3ed92e58e9bc15cefbf)
俺流・C++コーディングマネージメント

初投稿になります。今回は、自己流のC++のコーディング規約です。
自分はアマチュアC++書きデス。

#C++の危ない話。
C++はC言語の流れを組む言語です。しかし、Cとは大分かけ離れた言語になりました。そこでC++はベターCもこなせるので初学者はC言語を先にやるよりC++を先にやったほうがいいのではないかと思っています。
C/C++の便利で危険な機能は絶対的にポインタ関連です。
これは、直接！機械のナイーブなところを触りに行くので、コンピュータの構造を物理的に簡単に破壊しうるというのが一つの要因です。
しかし、例えば、とあるハードウエアのAPIがついてきたりしたなどすれば、それはある種マネージされた構造であり、ポインタで直接そのハードウエアを叩き行くということは構造が壊れるのでで避けるべきです。
なので、ポインタの使用は自分はあまりしません。
基本的に、ライブラリがやってくれるからです。

#C++の安全な話。
C++の安全なところは本当にほかのスクリプトと同じように純粋計算領域はどの言語でも大体安全です。
要するに、整数と浮動小数ではプログラムを破壊する作用を発揮するのにそのように書いて、純粋構造を破壊しに行かなければなりません。
なので、一般的に数値計算をするだけなら割り算でゼロで割る以外の不具合には会いにくいです。
基本的な事はSTLで。ローカルで共有したければ、スマートポインタで。

#メモリとライブラリの話。
C++はハードに添えつけられたメモリにダイレクトに触りにいくことができます。
これがかなりもどかしく、変数の連なりである配列もメモリのブロックでしかないです。なので、いろんな人がメモリをnewしたがるのですが、基本的にはやめてください。じゃあ配列は使えないかというと、いや違います。newをしたら、しっかりdeleteするのが作法なのですがそれらについては、先人が便利な構造を持った配列にも使える機構を標準ライブラリとして用意してあるのです。

・vectorは必ず1本のメモリブロックの配列になるようになっています。追記は尻尾に追記しか基本的にはしてくれません。
・dequeueはvectorに近いですが、前方にも挿入が可能です。
・setは集合などといいますけど、構造としてはツリー構造だったと思います。
・mapはsetのに近い構造ですが、検索に使う要素と実用される要素が分離しています。2値運用します。
・listは挿入と削除が早い構造ですが、各要素に対するアクセシビリティはあまり良くないです。

先人の知恵によってこのような構造はすでにあるのです。なのでそれをありがたく利用して自分のタスクをこなすのです。
ちなみに標準ライブラリ内ではnewやdeleteは利用されていますが、ライブラリを作るのであればnewやdeleteを使わざるを得ない状況はママあります。

アルゴリズムとデータ構造はプログラミングの基礎の基礎なのでかじっておきましょう。

#C++の文字列の話。
文字列は配列です。単純に。Nバイトのブロックを基準とした配列です。Nは1の時もあります。
これは変数一つで一つのモノしか原則表せないのでその変数一つに一文字を当てて配列にしたものが文字の列です。
なので、100という数字を文字列で表すときは、整数であれば1バイトで済みますが、文字列であれば最低3バイト使います。
それで文字列もまた整数の羅列であるので、超長規模の文字列を検索するのは遅いです。何か構造を考えなければ終わりません。
ほとんどのC++の環境ではAsciiコードというモノを採用しています。詳細はググってください。

#C++のエラーの話。
筆者が良く出会うエラーの代表的なものは、ゼロで数字を割ったときに出るものかstd::auto_of_range()の例外を投げられた時です。ほかのエラーは、基本的にアルゴリズムが間違ってるロジックエラーです。
はっきり言って例外は遅いです。
C++のクラスにはコンストラクタとデストラクタがあるのでそれさえキッチリ書いてあればおかしなことにはなりにくいですが、例外は大域ジャンプなのでプログラムの流れをぶっ壊します。
あと、まじめにすべての例外を処理するためのコストを渋って握りつぶす人の話を聞いたことがあります。
なので、筆者はエラーの返却には関数の戻り値を使っています。
基本的に戻り値は3種類に分けられます。成功、失敗、どうでもいい。です。
どうでもいい。は成功とは言いたくないけど明確にエラーでは無いということを通知します。極まれにそういうことがあります。
これを表現するのにtriboolという概念はなくないのですが、コンピュータとしては3値は半端すぎます。「悔しすぎる。」
なのでちょっと譲って、成功と失敗程度のモノしか扱えない、bool型の変数を使います。まぁ、これもほとんどの実装が速度のために1ビットでは無いのだけど。

正直言うと、アルゴリズムのエラーではプログラムは仮初に動いてしまうので、エラーで落ちたら感謝しましょう。
そして、エラーを潰しながら妥当性を喪失しないようにデバッグを完了させてください。

#CとC++の違いの話。
CとC++はC++がCをフォークしたときに道を分かちました。
C++がCの最新機能を使うには、標準委員会という機構が話し合っていれるので少しディレイがあります。
Cはシンプルです。整数と浮動小数と配列とポインタと構造体等といったら大体機能が網羅できる程度に小さいです。
そして、標準ライブラリも基本的にシンプルなので大きなものを作るにはどうしてもオレオレ実装をしなければならないです。
C++はCにはないクラスという機構によって大幅な拡張の余地を得ました。

CとC++の違いは基本的にはクラス機構があるか無いか程度ですがそれが一つのパラダイムシフトだったのです。

#C++とJavascriptの違い。
C++とJavascriptの違いは、用途方面が違うのを除いて、型システムが明示されているか暗示されているかという違い程度しかないです。
しかし、Javascriptは型システムが暗示されている程度なのでデバッグするのが筆者は大嫌いです。
Javascriptは言語仕様がシンプルでまとまっていて多様性に富みます。まるでlispの様です。
筆者の雑念ですが、Javascriptは型システムが明になったときにコンパイラを書く人が出てくるのではないかと思います。

#C++への願望。
筆者は一つ過去に消えた機能で入ってほしかった機能があります。それがUnifyed call syntaxです。
詳細は省きますが、「これがあったらコンパイルタイムのマクロオペレーションかけたのにチキショー」って感じです。
未練たらたらですよ。マジで。

#総括の話。
今回は以上です。
基本的にプログラミングというのは書いた通りに動くものです。その中には欺瞞も嘘もありません。
あと、雑記になってしまったので読む人がいるかはわかりませんけど。
「ここまで読んでいただきありがとうございました。」
ということにしておきます。

この記事が肥やしになりますように。良かれ悪かれ。
Android用YouTubeクライアントアプリ「NewPipe」の紹介

#「NewPipe」とは
タイトルにあるように、Android用のYouTubeクライアントアプリです。
[NewPipe - a free YouTube client
](https://newpipe.schabi.org/)

公式のYouTubeアプリと同様にYouTubeの動画を視聴できるのはもちろんのこと、以下のような機能も持っています。

- バックグラウンド再生機能
- ダウンロード機能（動画or音声） 

# インストール方法
F-Droidで、入手が可能なようです。
また、NewPipeはOSSなため、ソースをAndroid Studioなどでビルドして、インストールすることもできます。
GitHubにソースコードがホスティングされています。
[TeamNewPipe/NewPipe](https://github.com/TeamNewPipe/NewPipe)

ちなみに、筆者はソースコードをビルドしてインストールしました。minSdkVersionは19ですが、16に下げてビルドするとJelly Beanでも動作しました。

# 使ってみた
画面はこんな感じです。再生画面で、バックグラウンド再生やダウンロードの機能を実行することができます（赤枠の部分）。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189330/eb468e14-9e3f-e5fd-e672-c86022b57a17.png" width=35%> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189330/e4d632e3-db4d-985b-d58e-ac33057d8933.png" width=35%>

再生画面では、スライド操作で音量や明るさを調節できます。画面右半分でスワイプ操作をすると、音量が調節され、画面左半分でスワイプ操作をすると、画面の明るさが調節されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189330/4b9ce2e7-67a2-756b-5440-06ab5a0dc524.png" width=35%>
IP Geolocation とは

# DAZNで見れなかった件
### もともとはこんな話がありました
「NURO光(ニューロ光)を契約した友人が元海外IPを割り振られて大手動画配信サイトや子供のゲームなどいろいろなサービスを利用できなくなってしまいました。」。
https://nekonko2.com/nurohikari-demerit/

### どうしてこういうことになるのか
IPアドレスから、位置情報を判定してコンテンツを制御しているサービスがありますが、そういったものはどのように位置判定をしているのかは気になりませんでしょうか。
私の所属する組織では、そういったことを常に調査し、データベースを提供しています。その更新している仕組みをかんたんに説明したいと思います。

# そもそもIPアドレスから位置がわかるのか
(*)ここで説明するIPアドレスは、v4のみになります。
IPアドレスの割当てに関しては、大元はICANNが管理していて、その配下にある5つのRIR(ARIN, RIRENCC, APNIC, LACNIC, AfriNIC)へ割当ては終わっています。さらに、APNICではにおいてもその配下のNIRへの割当は終わっています。
日本においては、IPアドレスを管理する組織としてJPNICが存在し、以前はそこから直接割当てが行われていましたが、現在においては通常はIP指定業者へ割り振りを行い、そこからエンドユーザへ割当てが行われています。
つまり、あるIPアドレスがあったときに、それがどの国で使われているのか、その国の中では、どの組織が所有しているかというのは、把握されています。
しかし、そこでは、住所までは管理されてはいません。

# コマンドやサービスからわかること
## whois からわかること
上記のような内容を検索するためのデータベースとして、「whois」というものが存在しています。whois自体はサービスですが、UNIX(Linux)などでは、コマンドとしても存在しています。
このwhoisコマンドを使ったりして、IPアドレスの所有してしている組織を検索することができます。
[JPNIC WHOIS Gateway]
https://www.nic.ad.jp/ja/whois/ja-gateway.html

ドメインがわかっているときには、ドメインからの検索もすることが可能です。
「JPRSが 提供するドメイン名登録情報検索」
https://whois.jprs.jp/

ここからわかることとしては、IPアドレスがどの組織(プロバイダだったり、企業など)が所有しているかということはわかります。しかし、国内であれば、都道府県やそれ以下の細かい住所などの位置情報はわかりません。

## traceroute からわかること
ネットワーク系のコマンドとして、pingやtraceroute(Windowsではtracert)というのを利用したことがある方もいると思います。どちらもICMPのパケットを送出し、到達したかなどの結果が得られます。
ping応答がなくても、目的の機器への経路が不達とは限らず、そのパケット自体をdropする設定がされていることもあります。

当社からtraceroute を実行した結果の画面
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9808/2e79b6a2-a071-6d13-866c-1967034d9293.png)

ここで、IPアドレスだけではなく、ホスト名も表示されているところがあります。このホスト名が手がかりになります。途中のプロバイダ(回線)情報がわかるのと、プロバイダごとに地域名の付け方に一定の規則性が見えたりします。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9808/dc4aeb83-162c-f7a6-f53d-3b5386ad7fd8.png)


# 当組織のデータ
当組織では、定期的に下記のようなことを実施しています。
(1) 国内のすべてのIPアドレスに対して、whois情報を取得
(2) tracerouteを実施し、途中の経路情報を取得
(3) 「キーワード」を整理し、上記から得られた情報から位置情報や回線情報を判定
上記の内容はほぼ自動化(プログラム)で整理し、その後専門調査員が企業情報などを確認して付加しています。ここで「キーワード」と書かれていますが、ここもポイントで、専門調査員が常にその内容を更新しています。

また、これらに加えて、
(4) JPNICのIP移転リストのサイトを定期的に取得し、変化があったかをチェックする
[JPNIC IPv4アドレス移転履歴]
https://www.nic.ad.jp/ja/ip/transfer/ipv4-log.html
を行っています。最近は、国内でのIP移転だけではなく、海外からの移転も増えてきています。
ここで、日本国内へ移動してきた場合、上記の(1)〜(3)の処理の対象としています。

このようにしてまとめたデータを<font color="Red">**「SURFPOINT」** </font>として提供させていただいています。
最初に書きました事象も当組織においては、2019年2月から国内判定がされており、地域情報も判定されています(ちょっとした自慢)。

このような情報を提供させていただいている企業様からもフィードバックを頂き、それをもとに更新することも行っています。したがって、ぜひ当組織のデータをご利用いただき、お互いに精度を高めていただければと思います。

その他の情報は下記を参考にしていただければと思います。
[どこどこJP ラーニング]
https://www.docodoco.jp/learn/index.html
MatplotlibでJpegで保存できない時


■環境
Windows10
Python 3.7
matplotlib　3.1.1
pycharm

■内容
以下のようにmatplotlibでJPEGで画像を保存しようとすると


     Fig.savefig(”Test.jpg", bbox_inches="tight")


こんなエラーがでるときがあります。

     ValueError: Format 'jpg' is not supported (supported formats: eps, pdf, pgf, png, ps, raw, rgba, svg, svgz)

■解決策
このときは、pillow をインストールすれば解消します。

      py -m pip install pillow

■参考ページ
https://stackoverflow.com/questions/48186616/open-a-jpg-image-in-python-using-matplotlib-image-in-python-3-6
Feature specでJavaScriptのコンソールログを確認するときのリンクメモ

基本的には↓リンクの通りで

JavaScript が動作する Capybara の feature spec でブラウザのコンソールを確認する - valid,invalid https://ohbarye.hatenablog.jp/entry/2018/03/17/121231

- `binding.pry` を仕込んで
- `page.driver.browser.manage.logs.get(:browser)` を実行


すれば確認できた。
ただし、以下ページ等を確認するとデフォルトでは ERRORかWARNのログしか出力されないそうなので、 `console.error` で出力する。

javascript – capybaraでブラウザのコンソールログをキャプチャする - コードログ https://codeday.me/jp/qa/20190729/1336441.html