OmniAICreator/Qiita-1.07M huggingface dataset:
Dockerを使って5分でJupyter環境を構築する

# はじめに
連休中にPythonやPythonライブラリを勉強したのですが、その時にサクッとDockerで勉強用の環境を構築できたので、その時のメモを共有します。

環境構築が苦手だったり、自分のPC内を汚したくない人にとって役立つ記事になればと思います。

# 忙しい人向けまとめ
前提として、自分のPCにDocker環境はあるものとしますが、任意のディレクトリ下で下記3つのことをすれば環境が作れます。

```
1. $ docker pull jupyter/scipy-notebook
2. $ docker run -v `pwd`:/home/jovyan/work -p 10000:8888 --name jupyter jupyter/scipy-notebook
3. localhost:10000にアクセス ＋ トークン認証
```

# Jupyter Notebookを使えるようにするまでの流れ
## Jupyter Notebookのイメージを取得
今回は個人学習用程度のものを想定しているので、[jupyter/scipy-notebook](https://hub.docker.com/r/jupyter/scipy-notebook/)というイメージを使っていきます。

```
$ docker pull jupyter/scipy-notebook
$ docker images # イメージがあることを確認
```

## コンテナの起動
jupyterというコンテナ名を付けて10000番ポートでコンテナを作成＆起動します。
この時、**コンテナの中にカレントディレクトリにあるファイルをマウントしておくと便利です**。（とても地味ですがこの記事での一番のポイントです。）

```
$ cd <任意のディレクトリ>
$ docker run -v `pwd`:/home/jovyan/work -p 10000:8888 --name jupyter jupyter/scipy-notebook
```

起動時、コンソールの最後に以下のようなログが出てくるので、<トークン>の部分をコピーしておいてください。

```
Copy/paste this URL into your browser when you connect for the first time,
  to login with a token:
  http://7dae9a493ca7:8888/?token=<トークン>
```

また、コンテナの起動を確認しておきます。
以下のように、STATUS部分が「UP」になっていればOKです。（起動できてない場合は「Excited」となります）

```
$ docker ps -a
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS                     PORTS                     NAMES
fe7724bbe7f4        jupyter/scipy-notebook   "tini -g -- start-no…"   About an hour ago   Up About an hour           0.0.0.0:10000->8888/tcp   jupyter
```

## ブラウザでJupyter Notebookを開く
`localhost:10000`にアクセスします。
ここで、ブラウザに現れる`Password`の部分に4.で取得したトークンを入れると下図のようにJupyter Notebookにアクセスできるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307533/1aadff84-1503-7a16-af49-6538442c46cb.png)

そしてちゃんと指定したパスにあったデータがマウントされてます！
ここには載せませんが、もちろん、新規ファイルを作成したり、ファイルを編集してもローカルのデータに反映されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307533/8a64f1f7-cb46-6939-832c-fe909f7be8b4.png)

# 2回目以降の起動方法について
`docker start jupyter`でコンテナを起動し、上記と同様にブラウザでlocalhost:10000にアクセスします。
2回目以降はトークンを記憶してくれているため基本的にトークン不要ですが、要求された場合はコンテナに入ってログに出力すればOKです。

```
# コンテナ起動
$ docker start jupyter
　jupyter

# 状態を確認、STATUS: UPなら起動成功
$ docker ps

# もしトークンを確認された場合はコンテナに入ってログを出力する
$ docker exec -it jupyter bash
$ jupyter notebook list
　Currently running servers:
　http://localhost:8888/?token=<トークン>
```

# まとめ
以下の3ステップで簡単にJupyter Notebook環境を構築しました。
とても簡単なのでJupyterで勉強したい時は是非ご参考ください！

```
1. $ docker pull jupyter/scipy-notebook
2. $ docker run -v `pwd`:/home/jovyan/work -p 10000:8888 --name jupyter jupyter/scipy-notebook
3. localhost:10000にアクセス ＋ トークン認証
```

# 参考URL
- [(学習用環境構築メモ) DockerコンテナでJupyter Notebookを起動する。](https://qiita.com/takayu90/items/915d43fba41e31354145)
- [Dockerで基本的なData Science環境(Jupyter, Python, R, Julia, 定番ライブラリ)を構築する。](https://qiita.com/y4m3/items/c2703d4e131e05084b7b)
- [DockerでJupyter Notebookを使う](https://qiita.com/Brutus/items/a08c210b87ccb39379c2)
- [【Docker】Dockerでホストのディレクトリをマウントする](https://qiita.com/Yarimizu14/items/52f4859027165a805630)
- [Docker でカレントディレクトリをマウントして Flask の表示を変更してみるメモ](https://cortyuming.hateblo.jp/entry/2015/05/04/113156)
【WPF】Pathで線形を書く（直線のみ）

#目的
XAMLで適当な線形を書きたい。
なのでSystem.Windows.Shapes名前空間のPathを使って書いてみる。

#環境
・IDE :Visual Studio 2017

#方法
事前にPathタグにStrokeプロパティ(色)とStrokeThicknessプロパティ(太さ)を設定しておく。

そしてDataプロパティに線形の座標を設定する。
####線形の始点
線形の書き始めに"M"を書く。
そのうしろに始点を、親要素（Pathが置かれている要素）の原点から見た座標で書く。
座標は「0,50」のように、X座標とY座標をカンマで区切って書く
（空白区切りでも書けるようだが、見た目が分かりにくいので個人的に非推奨）。

例：親要素から見て右方向に5、下方向に10の座標から書き始める場合

```始点のみ.xml
<Path Stroke="Red" StrokeThickness="1" Data="M5,10"/>
```



####線形の終点
線形の続きを書くには、直前の座標から空白をあけて"L"か"l"（小文字のL）を書く。
そのあとに設定する座標を、このPathの親要素から見た位置(絶対座標)で書きたいときは"L"を、直前の座標から見た位置(相対座標)で書きたいときは"l"を書く。
また続けて直線を引く場合は、Lを再度書く必要はなく、座標だけ書けばよい。

```直線を続けて書く.xml
<Path Stroke="Red" StrokeThickness="1" Data="M1,0 l3,0 0,4 2,0 0,-4 2,0 "/>
```


***"L"か"l"を指定したときの座標の書き方の違いについての例***
どちらの例も始点から下方向に長さ10の垂直線をひくものである。
・”L"（絶対座標）で指定する場合

```絶対座標で指定する場合.xml
<Path Stroke="Red" StrokeThickness="1" Data="M5,10 L5,20"/>
```

・相対座標で指定する場合

```相対座標で指定する場合.xml
<Path Stroke="Red" StrokeThickness="1" Data="M5,10 l0,10"/>
```
　※2つ目の座標のX座標は"10"ではなく"l(エル)0"

描画される線形は以下の通り（赤線が線形）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424306/eda2a576-acf4-6050-0055-c843b0ceb704.png)




####線形を閉じる
線形の始点と終点をつなげて閉じた図形にする場合、最後に"Z"と書く（大文字小文字のどちらでもよい）。

例：三角形を書く場合

```三角形を書く場合.xml
<Path Stroke="Red" StrokeThickness="1" Data="M0,0 L10,0 5,8 z"/>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424306/49d63a9e-3940-b047-dcae-da4032e4e33b.png)



####線形を複数書く
同じPathタグ内でもう1本線形を引く場合は、その直前にかいた座標から空白をあけて、また始点を表す文字と座標を書く。
このとき"M"と書くと親要素から見た位置で、"m"と書くと直前に書いた線形終点から見た位置で座標を設定することになる。

例：

```複数の線形を含むPath.xml
<Path Stroke="Red" StrokeThickness="1" Data="M1,1 l10,0 m0,1 l0,5"/>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424306/935bc9f8-55c5-1ffc-b7ff-29fc9def9b6f.png)



***補足：***
・これまでに登場した”M"とか”L"という英文字は、コマンドを表す。
MはMoveコマンド、LはLineコマンド、ZはCloseコマンドというそうだ。

・直線をひくコマンドは他にもありVerticalLineコマンドとHorizontalLineコマンドがある。
VerticalLineコマンドは"V"か"v"と書き、座標はY座標のみで指定できる。
HorizontalLineコマンドは"H"か"h"と書き、座標はX座標のみで指定できる。
大文字と小文字の違いは他のコマンドと同様で、あとに指定する座標が絶対座標か相対座標かの違いである。
基本情報技術者試験の道のり[1](初学者編)

#基本情報技術者試験の道のり
8/13日の朝いきなり上司に基本情報の試験受けてねと言われその日のうちに
受験することが決定し、その場で申し込みをしました

自分は普段、IT企業でオペレーションマネジメントや人材開発に従事しています。

なので全く知識がないわけではありません(2017にITパスポート合格)

しかし、久方ぶりの資格試験といきなりの受験ということで備忘録としてこの
投稿をしていきます

とりあえず2019年秋期試験の受験なので10月20日が受験日なので約2ヶ月の戦いです

効率的で効果的なロードマップ作成をすることが必要です
戦略的に勉強せねば間に合いません

ということで先輩から参考書をもらい自分でも購入しました
ちなみに使う参考書は
『徹底攻略　基本情報技術者　教科書2017』　インプレス社
[https://www.amazon.co.jp/基本情報技術者教科書-平成27年度-ITエンジニアのための徹底攻略-Tettei-Kouryak/dp/484433705X]

『基本情報技術者　パーフェクトラーニング　過去問題集2019』　技術評論社
[https://www.amazon.co.jp/令和元年【秋期】基本情報技術者-パーフェクトラーニング過去問題集-山本-三雄/dp/4297106728]

の二冊をメインで使用します
とりあえず今回はここまで
次回は2ヶ月ロードマップと戦略を投稿予定です
初学者の頃に知っておきたかったVSCodeのショートカットキーをまとめた

#はじめに
友人がショートカットキーを使っていなかったので、共有用で軽くまとめました。
主に始めた頃知らなかったけど、わかりやすく効果の出るものをまとめました。
ショートカットキーはコツコツ使って慣れるのが一番だと思います。

#vscodeのショートカット
###⌘＋F　→　開いているファイル内の文字列検索
<img width="983" alt="2d99db21b97083cce0b7f7bf908de3e3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418390/98d5051b-8255-0e95-12e6-b58c7e18706e.png">
右上の奴です。
痴漢も出来ます。
###⌘+shift+F
全てのファイルに対して検索が出来ます。class名を検索かけて、CSSの編集したり、エラー文を入力して該当箇所を検索したりと何かと便利です。
###⌘+p
ファイルの検索。沢山のファイルの中から目で探すのは面倒なので検索した方が早いです！
###⌘+option+ ↑ or ↓
行を跨いでカーソルの指定が出来ます。上手く伝えられないので使ってみてください。
###⌘+F2
同じ文字列の選択が出来ます。名前を一律で変えたい時など便利。
###⌘+shift+Enter
上の行を改行します
###ショートカットじゃないけど、git使えるよ
基本的な事は出来ます。私はcommitはここで作業ついでにやっています。
すぐ出来て意外と便利です。

#普通のショートカット
###⌘＋R
更新。流石に使いましょう。
###⌘＋shift＋C
検証出来ます。クリックして、検証押して、ボタン押してと時間がかかるので結構効果の大きいショートカットだと思います。試しに押してみましょう。

#まとめ
共有用だったので少し投げやりになってました。
最初のうちはこの辺を使って、覚えたらちょこちょこ使いながら覚えていけば良いと思います。
日頃の積み重ねが重要です！
vueのtransitionが効かないとき

# Vueのtransitionが効かないとき

`<transition>`は、`v-if`や`v-show`による**実DOM**の変化をトリガーにするので、

下のソースみたいに、同じタグ同士が`v-if`で切り替わる場合、仮想DOMがお世話してくれて、実DOMは影響されないので、`<transition>`が働きません。

```vue
<template>
  <transition>
    <div v-if="condition">hoge</div>
    <div v-else>huge</div>
  </transition>
</template>
```

1個目と2個目の`<div>`は別もので、あることを示すには、`key`属性を付けましょう。

```vue
<template>
  <transition>
    <div key="hoge" v-if="condition">hoge</div>
    <div key="huga" v-else>huge</div>
  </transition>
</template>
```

これで、`<transition>`がうまく働いてくれます。
Spring Security認証周りについて

## 概要
Spring Securityの認証まわりについて調べたので備忘録です。

## 概略図
<img width="908" alt="Screen Shot 2019-08-14 at 19.52.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469184/9f4ac257-2583-c18b-7373-5e795633d34d.png">


リクエストに対して、SecurityFilterChainが適用されます。
認証に関してはデフォルトではUsernamePasswordAuthenticationFilterが担当します（指定パスに対して適用、例：/loginなど）。
FilterからAuthenticationManagerが呼ばれ認証の可否を決定します。
AuthenticationManagerは複数のAuthenticationProviderを持ち、各Providerに対して認証可否の処理を委譲します。

## AuthenticationFilter
認証処理を行うURLに対して適用されます。
ユーザー入力のnullチェックを行い、入力情報を元にUsernamePasswordAuthenticationTokenを発行、Managerに対して、認証可否を委譲します。
※通常、パラメータはID、パスワードのみとなっているので、それ以上のパラメータを使用して認証を行う場合は、カスタムフィルターを作成します。

## UsernamePasswordAuthenticationToken
AbstractAuthenticationTokenを継承した入力値と認証判断に使用するフィールドパラメータを持ったデータオブジェクトです。
各Providerはこのオブジェクトを受け取り、フィールドパラメータから認証可否を判断します。

## AuthenticationManager
インターフェースorg.springframework.security.authentication.AuthenticationManagerです。
このインターフェースには1つだけメソッドが定義されています。

```java:AuthenticationManager.java
Authentication authenticate(Authentication authentication)
			throws AuthenticationException;
```

デフォルトの実装クラスはorg.springframework.security.authentication.ProviderManagerです。

ProviderManagerは実際にパスワード一致などの判定を行うAuthenticationProviderを配列で持っており、各Providerのauthenticateメソッドを呼び、認証判定を行います。

## AuthenticationProvider
実際に認証判定を行うクラスです（例　パスワード一致など）。
前述の通り、Providerは複数登録することが可能です。

```java
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
	    auth.authenticationProvider(authProvider());
        auth.authenticationProvider(authProvider2());
    }

    public AuthenticationProvider authProvider() {
	    return new AbstractUserDetailsAuthenticationProvider() {

	        @Override
	        protected void additionalAuthenticationChecks(UserDetails userDetails,
		        UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
		      // 
	        }

	        @Override
	        protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)
		        throws AuthenticationException {
		        // ログインに使用したい特定のユーザーを作成する処理
		        return user;
	        }
	    };
    }
```
あまり使い時はないかもしれませんが、ProviderでUserDetailsを継承したユーザーを返すようにすると、
インメモリ認証のようにすることもできます。

Providerの登録はWebSecurityConfigurerAdapterを継承したコンフィグクラス下でBeanアノテーションをつけるだけでも良いです。

```java
    @Bean
    public AuthenticationProvider authProvider() {
	    return new CustomAuthenticationProvider(passwordEncoder, authenticationService);
    }
```

ProviderのretrieveUserメソッド内でDBへのユーザー情報を取得し、パスワードの一致確認を行うことで認証可否の判断を行います。


以上、簡単ですがまとめでした。
内部実装を見てみるとパスワードハッシュに対するタイミング攻撃対策などがあり興味深いですね。

SpringSecurity全体のまとめはこちらの記事が参考になります。
[Spring Security 使い方メモ　基礎・仕組み](https://qiita.com/opengl-8080/items/c105152c9ca48509bd0c)
jarのマニフェストファイルに変更が反映されない時の対処法

jarのマニフェストファイルの変更を以下のようなコマンドにより反映させる時、

```
jar -cfm Main.jar main.mf *.class
```

jarのマニフェストファイルの文末に空白行を入れる必要がある。

```text:main.mf
Main-Class : Main

```

以下のように文末に空白行が存在しない場合、

```text:main.mf
Main-Class : Main
```
jarのマニフェストファイルの変更は反映されない。

この時、特にエラーメッセージが表示されないため、初学者の頃ハマってしまった。

## 参考
Modifying a Manifest File (The Java™ Tutorials > Deployment > Packaging Programs in JAR Files) https://docs.oracle.com/javase/tutorial/deployment/jar/modman.html
Java のバージョンを上げるだけで、プログラムは速くなるのか

（この記事は [地平線に行く](https://yujisoftware.hatenablog.com/entry/2019/08/15/232500) とのマルチポストです）

よく Java の実行バージョンを上げるだけで速くなるという話を聞きます。
でも、本当にそうなのでしょうか。また、本当だとしたらどれぐらい速くなるのでしょうか。

そこで、簡単なプログラムで実験してみました。

# 実験概要

実験用に、[数独を解く Java のプログラム](https://github.com/YujiSoftware/SudokuJ/tree/jdk1.1)を作成しました。
このプログラムは単純な演算を繰り返し行ってるだけなので、Webアプリケーションのような複雑なプログラムとはおそらく傾向が違いますが、参考程度にはなるかなと思います。

これを**Java 1.1 でコンパイル**し、**Java 1.1 ～ 12** の各 Oracle JDK (32bit/64bit) で**[数独100万問のデータセット](https://www.kaggle.com/bryanpark/sudoku/version/3)を読み込んで解き終わるまでの時間を測定しました。[^compile]**

[^compile]: 後方互換性があるので、Java 1.1 でコンパイルしたクラスファイルは、以降のバージョンでもそのまま動きます。

細かい測定条件は以下の通り。

* 実行環境
    * Windwos 10 Home 1809 (64bit)
    * Intel Core i7-7500 CPU @ 2.70GHz
* Java の実行オプション
    * `-mx512m` `-ms512m`を付与[^jvmoption]
    * Java 1.3.1 以降は、`-server` を付与[^server]
* 測定方法
    * 各バージョンごとに5回測定し、中央値を取得

[^jvmoption]: 「あれ `-Xmx` `-Xms` じゃないの？」って思うかもしれませんが、Java 1.1 ではこのオプションは `-mx` `-ms` になっています。Java 1.2 で VM オプションの `-Xmx` `-Xms` に変更になったのですが、いまだに `-mx` `-ms` も使えます。
[^server]: このオプションがないと HotSpot Client VM が使われてしまい、倍ぐらい遅くなります…。

# 実験結果

処理は二つのパートに分かれているので、その処理ごとグラフ軸を分けました。

* 数独100万問のデータセットを読み込む処理 *(下図の青い部分)*
    * この部分は、**主に GC の性能に左右される**
* 数独を解く処理 *(下図の赤い部分)*
    * この部分は、**主に JIT 最適化の性能に左右される**

その実験結果がこちら。
![処理時間(ms)](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205989/108f6999-40ae-59dc-ae63-36287f044b27.png)

<details><summary>グラフの元データ...</summary><div>

|Java|Version|データ読み込み(ms)|数独解析(ms)|合計(ms)|
|--:|--:|--:|--:|--:|
|Java 1.1 (32bit)|1.1.8|8,313|4,231|12,544|
|Java 1.2 (32bit)|1.2.2_017|6,647|4,360|11,006|
|Java 1.3 (32bit)|1.3.0_05|10,747|6,905|17,652|
|Java 1.3.1 (32bit)|1.3.1_28|7,647|5,093|12,740|
|Java 1.4 (32bit)|1.4.0_04|8,061|4,741|12,802|
|Java 1.4.1 (32bit)|1.4.1_07|7,810|4,796|12,606|
|Java 1.4.2 (32bit)|1.4.2_19|3,437|3,281|6,717|
|Java 5 (32bit)|1.5.0_22|3,050|3,289|6,338|
|Java 6 (32bit)|1.6.0_45|3,530|4,077|7,607|
|Java 7 (32bit)|1.7.0_80|3,411|3,211|6,622|
|Java 8 (32bit)|1.8.0_202|3,239|3,257|6,496|
|Java 6 (64bit)|1.6.0_45|5,029|3,312|8,341|
|Java 7 (64bit)|1.7.0_80|7,019|3,148|10,167|
|Java 8 (64bit)|1.8.0_202|5,050|3,054|8,104|
|Java 9 (64bit)|9.0.4|2,101|2,961|5,061|
|Java 10 (64bit)|10.0.2|2,056|3,054|5,110|
|Java 11 (64bit)|11.0.3|1,922|3,343|5,265|
|Java 12 (64bit)|12.0.1|1,934|3,422|5,356|
</div></details>

# 考察

「今回のプログラムでは」という前提が付きますが、データから以下のことが見て取れます。

* Java 1.1 に比べて、最近の Java は2倍以上速くなっている
* Java 1.3 で急激に遅くなっている。まだ、HotSpot が成熟していなかった？
* Java 1.4.1 までは遅かったが、Java 1.4.2 でぐっと速くなっている
    * データ読み込みが速くなったのは、デフォルトの GC が CMS[^cms] に切り替わったおかげ？[^skrb]
    * リリースノートに[Use of SSE and SSE2 instructions on IA32 platforms](https://web.archive.org/web/20110320141919/http://www.oracle.com/technetwork/java/javase/changes-136374.html#vm)とあるので、数独解析が速くなっているのはこのおかげ？
* Java 6 ～ 8は、64bit VM より 32bit の方がデータ読み込みが速い
* Java 9 でぐっと速くなっている

[^cms]: Concurrent Mark Sweep Garbage Collector。このGCについての詳細は、[KUBOTA Yuji さんの資料](https://www.slideshare.net/YujiKubota/concurrent-marksweep-garbage-collection)を参照。
[^skrb]: https://twitter.com/skrb/status/1161642952420016130

# まとめ

**Java のバージョンを上げるだけで、プログラムは速くなる。**
【ＤＢ設計】論理削除フラグについて

データベースの設計について、最近思うところがあり備忘も兼ねて投稿します。
おそらく、誰しもが一度は目にしたことがあるものだと思います。

# 当方プロフィール
データベーススペシャリスト資格保有
oracleはブロンズ止まり。。。
主に業務（バックエンド）系のシステムの設計、開発をしています。

#導入
当方、不注意が多くミスが多いです。私のようなかわいそうな人間を生まないために開発しやすい、ミスが起きにくい設計について考えることが多いです。
テーブルのカラムは、必要な列をしっかりした名前、しっかりした定義とすることを旨としています。今回は、論理削除フラグについて考えました。

#前提
データには主にマスタ系とトランザクション系の二つに分かれます。
今回は、マスタ系のテーブルについて考えます。
詳細は省きますが、トランザクション系で論理削除フラグはありえないと考えています。

#結論
業務設計をきちんと行えば、論理削除フラグの設計に至ることは少ない。
よって、安易に定義するものではない。

私が論理削除フラグに持っている印象
危ない。危険が多い項目だと考えています。
一方、危ない割には当たり前のように見かける考え方な印象があります。
なぜ、危ないかは論理削除フラグのデメリットで説明します。

#論理削除フラグのメリット
- すぐに復旧できる
- 外部参照先に影響を与えないため安心して削除できる
- 処理速度が速い

#論理削除フラグのデメリット
- 開発時に参照するプログラム側で考慮が必要
- 外部参照先で論理削除フラグについて考慮する必要がある
- マスタが汚れる
- 論理削除フラグという名前の抽象度が高すぎてどういう状態か分かりにくい

#メリットについての深堀
##すぐに復旧できる
削除に関わらず、マスタがころころ変わることはないです。
ましてや消えたり、復活したりを繰り返すようなことは業務そのものに問題があると考えます。
###代替案
削除時にトリガー等でバックアップテーブルに保存しましょう。
もしくは、ＤＢそのもののバックアップから復旧しましょう。
マスタであれば、前日のバックアップから十分復旧できるでしょう。

##参照先に影響を与えないため安心して削除できる
論理だろうが物理だろうが、安易に削除しても良いのでしょうか。
間違えて登録したのであれば、参照しているトランザクション系のデータも
削除なり修正が必要ではないでしょうか。

###代替案
無いです。
マスタの削除は慎重に行いましょう。

##処理速度が速い
DELETEと比較しUPDATEの処理が速いということでしょう。
ざっと調べてみたら事実のようです。

###代替案
この手の話はよく聞きますが、まずパフォーマンスの要件に違反するかを検証しましょう。違反しなければ、DELETEしましょう。
もしくは、オンライン処理で論理削除フラグを立てて、バッチでまとめて削除する。

#デメリットについての深堀
##開発時に参照するプログラム側で考慮が必要
外部参照先で論理削除フラグについて考慮する必要がある
プログラムからリードするときにも、外部参照する際にも論理削除フラグについて考慮が必要になってきます。論理削除フラグの考慮漏れはよくある不具合のパターンです。
また、往々にして設計書への記載が無いことが多いです。論理削除フラグが当たり前のように存在しているため、プログラマーへの判断に委ねられていることが多い印象を受けます。また、機能要件なのか非機能要件なのか微妙な立ち位置が設計書への未記載を増長させていると想像しています。愚痴になってしまいました。。。

##マスタが汚れる
参照が不要になった死んだデータがマスタに残留します。
常に死んだデータについて、意識が必要となってしまいます。

##論理削除フラグという名前の抽象度が高すぎてどういう状態か分かりにくい
とりあえず消したことにしたい。ということなんでしょう。
いっそ、「間違えて登録したので消しましたフラグ」とかにしてほしいです。

#なぜ業務設計をきちんと行えば論理削除フラグの設計に至らないのか
マスタの状態が変わるのであれば「ステータス」という列がしっくりきます。
例えば担当者が着任した時には担当者マスタに「1:着任」。
退職等で離任した時には「2:離任」。退職と離任を分けたければ「3:退職」等を
設定すればよいです。
もしくは、退職済みフラグを設定するか。ただし、ステータスと同時に設定すると
現在の状態を表す「ステータス」と退職済みフラグの同期が必要なので注意が必要です。
というか設定すべきではないのでしょう。ステータス列が存在する時点で論理削除フラグは不要なものとなります。また、機能要件となるため設計書にも記載されるようになります。
以下だとどちらが分かりやすいでしょうか？
-退任した担当者は論理削除扱いとし論理削除フラグを参照しプログラムからは参照しない
-ステータスが（退任）のユーザーは一覧に表示しない

#最後に（最悪な論理削除フラグ）
CHARやNUMで定義されていると最悪で、「0」か「1」どちらが生きているのか
おびえながら、生きていく必要があります。
「2」や「3」が出てきたらもはや何も信用できません。
そして、未だかつて設計書やテーブル定義にきちんと明記されているものを見たことがありません。

#どうしても設定したい時は

名前が「IS_DELETED」で型がBooleanであればまだいいです。
見ただけで「True」が「削除済み」であることが分かります。
そして、設計書に明記しましょう。書かなくても分かるだろうは怠慢です。

#本当の最後
とはいえ、根本的な論理削除フラグの設計動機が「サボり」なので、考慮されることはマレです。。。
論理削除フラグに対するアンチテーゼとなってしまいました。
私の意思では論理削除フラグを設定することはまず無いです。

以上です
Arrowを使ってAndroidで関数型プログラミング〜型コンストラクタ、高カインド型について〜

関数型プログラミングの手助けをするKotlin製のライブラリである[Arrow](https://arrow-kt.io/docs/patterns/glossary/)を使うためには、基本的な用語を知っている必要があります。
今回は主に[Arrow](https://arrow-kt.io/docs/patterns/glossary/)に記載の内容を元に、型コンストラクタと高カインド型の概要をまとめます。

## Arrowにおける型コンストラクタについて
- **型コンストラクタ**とは少なくとも１つのジェネリックパラメータを持つクラス（インタフェース）である(例えば、 ```ListK<A>```、```Option<A>```(※1)の```A```がジェネリックパラメータに相当)
- ```ListK<A>```の```A```に対して、```Int```型を割り当てた場合、```ListK```は```ListK<Int>```となる。このとき、```ListK```にはジェネリックパラメータではなく、Intと言う具体的な型が指定されているため、型コンストラクタとは見なされなくなり、通常の**「型」**と見なされるようになる。
- 複数のパラメータを持つ型コンストラクタ（例：```Either<L, R>```)の一つのパラメータに対して型を適用した場合、その結果まだもう一方のジェネリックパラメータが残っているので、これは型コンストラクタと見なされる。（例えば、```Either<L, R>```の```L```に対して、```Throwable```を適用すると、```Either<Throwable, R>```となるが、これは```R```というジェネリックパラメータを持っているので、型コンストラクタと見なされる。）
- Kotlinでは型コンストラクタはファーストクラスとして扱われていないので、Arrowでは```Kind<F, A>```というインタフェースを利用して、それを表現している。

※1… ListK, OptionのいずれもArrowが提供するAPI。ListKはKotlin標準のListクラスをラップして、モナド則を満たす関数を提供する。

## Arrowにおける高カインド型とは
- カインドをざっくり言い表すと、**「型コンストラクタ」の「型」**のことである。
- 型パラメータを取らない型（Int、Stringなど)は```*```で表現され（零項の型コンストラクタと言う事もある）、```Option<A>```などの一つのパラメータを取る型コンストラクタ(１階の型コンストラクタと言う）は```* -> *```と表現される。
- n階の型コンストラクタは、型パラメータに具体型を適用することで普通型となる。上述の例の通り、 ```ListK<A>```は１階の型コンストラクタだが、このAに対して、Int型を割り当てた場合、```ListK<Int>```となり、普通型となる。
- Arrowでは１階の型コンストラクタは```Kind<F, A>```というインタフェースで表現され、```F```はコンテンツをラップするコンテナの型を表し、```A```はコンテンツの型を表す。（２階の型コンストラクタは```(* -> *) -> *```で表現され、Arrowでは```Kind<Kind<F, A>, B>```で表す。３階以降の表現方法も同様。)
- ```Kind<F, A>```の```F```を表現するための代理クラスがあり、その代理クラス名はコンテナのクラス名に対して接頭辞「For」を付与したものである。（例：ForListK、ForOption)


具体的に、OptionクラスとForOptionクラスの関係性は以下のようになります。

```kotlin
class ForOption private constructor() { companion object {} }
typealias OptionOf<A> = arrow.Kind<ForOption, A>

@higherkind
sealed class Option<out A> : OptionOf<A> 
// => sealed class Option<out A>: Kind<ForOption, A>
```

上記の通り、```Option```クラスは```Kind<ForOption, A>```を実装するクラスとして定義されており、以下を満たすことが読み取れます。

- ```Option<out A>```はコンテンツの型として、```A```（ジェネリックパラメータ）をもつ。 
- ```Option<out A>```はコンテナの型（コンテンツをラップする役割を持つ型）として```ForOption```をもつ。(※2)
- ```Option<out A>```はパラメータAを持ち、カインドとして```* -> *```(「１階の型コンストラクタ」)で表現できる。
- ```Option<out A>```のAに対して、具体的な型- 例えばInt -を適用すると、```Option<Int>```となり、型コンストラクタではなく具体的な型（カインドは「*」）となる。

※2… ```Kind<ForOption, A>```を実装するのは```Option<A>```のみであるため、```ForOption```と```Option<A>```は密接な結びつきを持つ。そのため、後述の```Kind<ForOption, A>.fix()```を呼び出すことで、```Kind<ForOption, A>```から```Option```へ安全にダウンキャストができる。

## ```Kind<F, A>```の拡張関数について
```Kind<F, A>```の```F```に対して、Arrowで提供される全てのDatatypes(OptionやListK、Eitherなど）に適用できる、```fix```という関数が実装されています。
これにより、```Kind```クラスから```Option```や```Either```などのサブクラスにダウンキャストができるようになっています。

例えば、```Kind<F, A>```の```F```に```ForOption```が適用された```fix```関数は以下の通りです。

>inline fun \<A\> OptionOf\<A\>.fix(): Option\<A\> = this as Option\<A\>
> // => inline fun \<A\> Kind\<ForOption, A\>.fix(): Option\<A\> = this as Option\<A\>

Arrowライブラリの実装上、```Kind<ForOption, A>```を実装するのは```Option<A>```のみ（他のDatatype(ListK, Either, etcも同様）であるため、ダウンキャストが安全に行えるようになっています。
Leetcode #986: Interval List Intersections

```swift
func intervalIntersection(_ A: [[Int]], _ B: [[Int]]) -> [[Int]] {
    var intervals = [[Int]]()
    var i = 0
    var j = 0
    while i < A.count && j < B.count {
        if A[i][0] > B[j][1] {
            j += 1
        } else if A[i][1] < B[j][0] {
            i += 1
        } else {
            intervals.append([max(A[i][0], B[j][0]), min(A[i][1], B[j][1])])
            if A[i][1] == B[j][1] {
                i += 1
                j += 1
            } else if A[i][1] > B[j][1] {
                j += 1
            } else {
                i += 1
            }
        }
    }
    return intervals
}
```
ローカルにnpmレジストリを立てる

## 概要

みなさんは個人開発をする時、自分で作った共通で使えそうな便利なライブラリをどのように管理していますか？
簡単なコードなどでは公開せずに自分用のライブラリとして使いたいor使った方がいいような場合もあるかと思います。

今回はそう言った時に、自分のPCにnpmのレジストリを立て、そこに作ったライブラリをpublishする簡単な方法を紹介します。

(npmでのインストール手順もありますが、今回はdockerでの手順です。)

## 登場人物

### verdaccio

[verdaccio](https://github.com/verdaccio/verdaccio)はprivate npm registryです。自分だけで使えるnpmのregistryです。

### docker

[docker](https://www.docker.com/)は簡単にいうと仮想マシンの1つです。nginxやmysqlがインストールされた仮想環境が、簡単に起動できて簡単に削除できるようなものです。[docker hub](https://hub.docker.com/)にはいろんな環境が転がっています。

今回は[verdaccio/verdaccio](https://hub.docker.com/r/verdaccio/verdaccio/)を使って自分のPCにprivate npm registryを立て、自分のパッケージをそこにpublish/unpublishする方法を紹介します。

## (dockerのインストール)

[dockerのインストール](https://docs.docker.com/install/) はここを参考にしてください。

僕の `$ docker --version` は `Docker version 18.09.2, build 6247962` になりました。

## verdaccioの起動

`$ docker pull verdaccio/verdaccio` → verdaccioの最新のイメージをダウンロードします。
`$ docker run -it --rm --name verdaccio -p 4873:4873 verdaccio/verdaccio` → verdaccioをdockerで起動します。

Ctrl + Cでプロセスを終了できます。コンテナは `--rm` オプションによって自動的に削除されるのでdockerを汚しません。

## publishするパッケージの準備

簡単にverdaccioにpublishできることを確認するために、 `console.log('this is my package')` だけするパッケージを用意してpublishしてみましょう。

`$ mkdir verdaccio-sandbox && cd verdaccio-sandbox && npm init -y && echo "console.log('this is my package')" > index.js` などして、検証に使うnpmパッケージを作成します。

## registryの指定

`$ echo registry=http://localhost:4873 > .npmrc` 

`.npmrc` があるディレクトリで `npm` コマンドを使った場合、このファイルに書かれた設定を読み込んでくれるので、今後このディレクトリでは `--registry=http://localhost:4873` が省略できます。上のコマンドを使わない場合は、適宜このオプションを付け加えてください。

## verdaccioで使うユーザー作成

`$ npm adduser` で、先ほど起動したverdaccioのユーザーを作成します。ユーザー名、パスワード、メールアドレスなどを聞かれるので適宜入力してください。自分だけで使うのであれば適当で構いません。

## パッケージの公開

`$ npm publish` で、先ほど起動したverdaccioに今回のパッケージを公開します。

## パッケージの削除

`$ npm unpublish`

## ログアウト

`$ npm logout`

## 確認

別のパッケージから上記手順で `publish` したパッケージをインストールするには、 `.npmrc` か `--registry` を忘れないようにしてください。
ぼくのかんがえたさいきょうのWordpress@AWS環境

# はじめに
下記の観点でAWS環境にWordpressをたてました。

 - 安い
 - 簡単
 - 早い
 - メンテしやすい
 - そこそこのセキュリティ
 - そこそこのリクエストに耐えられる

4.5$/月で200万リクエストまで耐えられる(200万リクエスト以降は従量課金)Wordpressを約１時間くらいで作成できます。

どこが最強だよ！？
Xサーバの方が安いしメンテもしやすいじゃん
とか
GCP使えば永久に無料じゃん

などなどあるかと思いますが、
今回はAWSである事に意味を感じて下さい:rolling_eyes:

# 環境
こんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265300/a56402cb-dbb4-340d-8b11-9bf896914e8e.png)


各サービスの役割は下記の通り

 - LightSail：Wordpressサーバ(最小構成で3.5$/月)
 - Route53：ドメイン取得(~.comは12$/年)& DNS設定(無料)
 - CertificateManager：SSL証明書(ワイルドカード)を発行(無料)
 - CloudFront：CDNを構築(200万リクエストまで無料)

# 作成手順
1. [WordPress入りのLightSailを作成](https://qiita.com/Shi-nakaya/items/a882963cf14dcc64fcac)
2. [Route53にてドメインを取得](https://qiita.com/Shi-nakaya/items/edcd86a3a8811654573b)
3. [取得したドメインを元にSSL証明書を発行](https://qiita.com/Shi-nakaya/items/d35b5a0f7fb7a7689fce)
4. [CloudFront構築](https://qiita.com/Shi-nakaya/items/b00a04e07ca6e24887ca)
5. [DNSの設定](https://qiita.com/Shi-nakaya/items/30d2339c3570d012ca62)
6. [セキュリティ対策](https://qiita.com/Shi-nakaya/items/8812da74f5dca200cf45)

一つの記事にするとかなり長くなってしまうので
それぞれ別記事にて記載しています。

# 所感
低スペックのサーバでも
大量のリクエストにも耐えたれる事
そして安く運用できる事
これらを目標に環境を構築しました。

特にCloudFrontは200万リクエストまで無料で使用できます。
https://aws.amazon.com/jp/cloudfront/pricing/

また、Route53で設定したゾーンに対するリクエストは通常は従量課金制なのですが、
CloudFrontで配信した場合は無料となります。
https://aws.amazon.com/jp/route53/pricing/#Hosted_Zones_and_Records

その為、これを利用しない手はないなと思いました。

が、この貧乏性が足かせとなり、どハマりました。

CloudFrontを経由するとWordpressへのリクエストにフィルタがかかってしまう為、
理解してフィルタを外してセットアップしなけばなりません。
その設定を調べるのに多くの時間を使うことになりました。

本当はAWS WAFも使用して悪意のあるアクセスを制御したりしたいのですが、
そこそこお金がかかってしまうので(5$/月)... 

ドメイン取得に関してもかなり調べましたが、
料金的には他のサービスと変わりありませんでした。
むしろ少し安いくらいでした。
その為、Route53を使用しています。

とにかく作成できてよかったです。

まだ記事は何も書いてませんし、テーマも設定していません。
全てこれからです。

まずはまっさらなWordpress環境ができたのでこれから色々と検証していきたいと思います。
Zabbix APIでホスト指定してトリガー作成する。復旧条件式も。


Zabbix APIを用いて任意のホストに復旧条件式を含むトリガー作成したのですが、
情報が少なくハマったのでjsonサンプルを共有します。

感覚的にitem.createのようにhostidを指定することで任意のホストにトリガーを生成するのかと思っていましたが、そうでなかったので混乱しました。公式リファレンスだけだと難しいので、誰かの助けになると嬉しいです。

Zabbix APIの使い方は多くの方が記事にされているので、割愛いたします。

<b>・環境</b>
Zabbix Ver: 3.4


##さっそくサンプル

```json:sample.json
{
  "jsonrpc": "2.0",
  "method": "trigger.create",
  "params": {
    "description": "トリガーの名前",
    "expression": "{ホスト名:アイテム値.last(0)}<1000",
    "recovery_expression": "{ホスト名:アイテム値.last(0)}>1000"
    "priority": 5,
    "recovery_mode": 1
  },
  "id": 1,
  "auth": "xxxxxxxxx"
}
```

##各パラメータについて

・"jsonrpc"："2.0" 固定
・"method": "trigger.create" 固定
・"description": 任意のトリガー名をつける
・"expression": 障害の条件式。設定済のホスト名及びアイテム値を定義することで、該当ホストに紐付く形でトリガーが設定される。
・"recovery_expression": 復旧条件式。書式は"expression"と同様
・"priority": 深刻度
・"recovery_mode": 1にすると復旧条件式が設定できる。デフォルトは0

<b>これでいけると思います!</b>
Ansible2.8をCentOS7にインストールする

#目的
備忘録。
Ansible2.8.2をCentOS7にインストールします。
epel を利用することで簡単にインストールできます。

#環境
CentOS7 を minimal イメージでインストールし、直後に yum update 実施

```shell:CentOSのバージョン
# cat /etc/centos-release
CentOS Linux release 7.6.1810 (Core)

```

#手順

```shell
epel リポジトリを追加
# yum install epel-release

ansible をインストール
# yum install ansible

```

#確認
```shell
# ansible --version
ansible 2.8.2
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Jun 20 2019, 20:27:34) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
#
```

以上です。
ShellScriptに入門する(4・5・6日目)

今日もやっていきましょう

[ShellScriptに入門する(1日目)](https://qiita.com/kshiva1126/items/955e8f636adae57aaff5)
[ShellScriptに入門する(2日目)](https://qiita.com/kshiva1126/items/fff8bb8d11f4590cc5bb)
[ShellScriptに入門する(3日目)](https://qiita.com/kshiva1126/items/f303453d00ea1aaaad8a)
[ShellScriptに入門する(4・5・6日目)](https://qiita.com/kshiva1126/items/53f65ef205d5342f7023)

## はじめに
Laravelのdocker環境を対話形式で構築できるようなスクリプトをShellScriptでつくりました

## 指定できるもの
- DBの種類(MySQL/PostgreSQL)
- DBのバージョン
- DB名・user・password・DBのポート番号
- webサーバ(Apache/Nginx)
- webサーバのポート番号
- PHPのバージョン
- Laravelのバージョン

## 流れ
1. 対話形式で上記設定をdocker-compose.yml, Dockerfileや.envに反映させていく
2. docker-composeコマンドでコンテナを立ち上げる
3. コンテナ内でLaravelのプロジェクトを作成する
4. プロジェクト内の.envを書き換える(主にDB関係)

## 事前準備
こちらのスクリプトを動かすには以下のコマンドをインストールして使えるようにしておく必要があります

- docker
- docker-compose
- [jq](http://linuxcommandlibrary.com/man/jq.html)

## 作成したファイル
こちらに置いています
[gen_laravel_on_docker](https://github.com/kshiva1126/gen_laravel_on_docker)

## デモンストレーション
```
% chmod 755 ./gen_laravel_on_docker.sh; . ./gen_laravel_on_docker.sh
Please select MySQL or PostgreSQL mysql/postgres [ mysql ]
postgres
Please input PostgreSQL version [ 10 ]
10
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1153    0  1153    0     0    752      0 --:--:--  0:00:01 --:--:--   752
Please input DB name you want to set
psql-test
Please input DB user you want to set
postgres
Please input DB password you want to set
password
Please input DB port you want to set
5432
Please select Apache or Nginx apache/nginx [ apache ]
nginx
Please input PHP version [ 7.3 ]

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1032    0  1032    0     0    707      0 --:--:--  0:00:01 --:--:--   707
Please input WebServer port you want to set
8080

Creating network "gen_laravel_on_docker_default" with the default driver
Building db
Step 1/3 : FROM postgres:10
 ---> 092b8d6e3163
略...
Creating gen_laravel_on_docker_app_1 ... done
Creating gen_laravel_on_docker_db_1  ... done
Creating gen_laravel_on_docker_web_1 ... done


Please input Laravel version you want
5.8.*
Installing laravel/laravel (v5.8.17)
  - Installing laravel/laravel (v5.8.17): Downloading (100%)         
Created project in /work
略...
Package manifest generated successfully.
Application key set successfully.
Complete deploy Laravel on Docker!
Access to http://localhost:8080
```

使用シェルがbashの場合は下記のように最初に`from_zsh_to_bash.sh`を実行すればOK

```
$ chmod 755 from_zsh_to_bash.sh; . ./from_zsh_to_bash.sh
$ chmod 755 ./gen_laravel_on_docker.sh; . ./gen_laravel_on_docker.sh
以下同様...
```

## 改善できそうなこと
- 一旦環境構築が終われば*.shや*.libは必要なくなるので、処理の最後で削除したほうがいい？
- 便宜上DB(MySQL/PostgreSQL)とPHP(Apache用/Nginx用)のDockerfileはすべて用意しているため、使用しないDockerfileがでてくる  
使用しないDockerfileは削除したほうがよさそう

## さいごに
会社の開発環境構築自動化のための練習としてLaravel環境構築対話スクリプトを作成してみた
思ったより難しく時間がかかってしまったが、とりあえず最後まで終わらせられてかなり勉強になった

今日はここまで
明日はもしかしたら別のことやってるかも...
「関数型でデータサイエンス#2」で躓いた箇所


7/30 [fukuoka.ex#27：Elixir／Phoenixもくもく会](https://fukuokaex.connpass.com/event/139885/)に参加しました。

私は@piacerex さんの関数型でデータサイエンスを#1から実装していきました。
順調に進んでいたのですが、[関数型でデータサイエンス#2](https://qiita.com/piacerex/items/64c2127857599137e8a7)の正規化でエラーが出てしまいました。もくもく会の中では解決できなかったので、改めて調べてみました。

##エラー内容

<img width="237" alt="error.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385793/05a4b60e-6e1c-4eb0-74da-f1084ac383c2.png">


```
min = result |> Enum.map( &( &1[ "ApplicantIncome" ] ) ) |> Enum.min |> String.to_integer
```
Webページにアクセスしようとすると、画像のようなエラーになります。
ハイライトされている部分がエラーだと分かりますが、エラーの原因が分かりません。

## エラーの調査
まずはパイプラインを１つづつ試しながらエラー箇所を絞り込みました。

```
:erlang.binary_to_integer/1
>Called with 1 arguments
 1. nil
```
エラー箇所を特定して見ると|> String.to_integerに nil が渡っているのが原因のようです。

```
min = result |> Enum.map( &( &1[ "ApplicantIncome" ] ) )　|> Enum.min　
```

を表示してみると確かに何も表示されていませんでした。
Enum.min以前に、Enum.mapの値も取得できていませんでした。

## 解決
こうなると取得元のCSVファイルが怪しそうです。
CSVの列がどう格納されているのかを表示してみました。

<img width="436" alt="columns.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385793/a16abee6-5909-77a8-74f6-f62bf0143902.png">


各列に「 ApplicantIncome」のような空白が含まれています。
CSVファイルは次のようになっています。どうやらカンマの後ろの空白も列名に含まれるようです。

```
ID, Gender, Profession, ApplicantIncome, CoapplicantIncome, LoanAmount, LoanStartDatetime
```

CSVファイルの空白を詰めてみました。
<img width="455" alt="result.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385793/f136fce1-6a34-ed3f-f44b-b12a0a20d5ac.png">

無事に表示されました。
CSSで要素を中央寄せする方法

#はじめに
未来電子テクノロジーでインターンをしている＠reies1204です。
今回は自分が以前に要素の中央寄せについて学んだ色んな方法をどのように使い分けるのか、しっかり理解できていなかったので今回は中央寄せについて使い方も兼ねてまとめていこうと思います。
ただし、プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

#左右の中央寄せ
####テキストを中央寄せする場合
まずテキストを左右で中央寄せる場合は、**そのテキストが含まれる要素**、もしくは**その親要素**に`text-align:center;`を指定します。

####画像を中央寄せする場合
画像もテキストと同様に`text-align:center;`を使うことで中央に寄せることができます。ただし、画像の場合はimgタグではなく、**imgタグの親要素に対して**`text-align:center;`を指定する必要があります。
つまり、例えば

```html
<body>
 <div class="example">
  <p>
   <img src="##">
  </p>
 </div>
</body>
```
となった場合、ここではCSS にて**親要素のp要素に対して**`text-align:center;`を指定します。



####ブロック要素を中央寄せする場合
ブロック要素を中央寄せする場合、上記のテキストや画像を中央寄せするときと異なり`text-align:center;`を指定しても、**要素の中身が中央寄せされるだけで要素自体の位置は変わりません**。
これはCSS のルールとして**ブロック要素に対しては`text-align:center;`は効かない**という仕様があるからです。
そこで要素の外側に余白を指定する`margin`プロパティを使います。
先ほどの例からexampleクラスを中央寄せしてみると

```CSS
.example {
 margin:10px auto;
 width:100px;
}
```
といったようになります。
つまり、ここでは「指定した要素は幅100pxで上下に10pxの余白、左右は中央になるように自動で配置」ということになります。
ただし、これはあくまで要素の中での中央寄せなので、「中央に寄せたい要素はどの親要素の中での指定なのか」ということに注意が必要になります。

####インラインブロック要素を活用する方法も
ブロック要素をインラインブロック要素へと表示し直してから、親要素に対して`text-align:center;`を指定することで中央に寄せるという方法もあります。



#上下での中央寄せ
先ほどは左右での中央寄せについて`text-align:center;`や`margin`を使った方法をまとめましたが、次は上下での中央寄せについてまとめます。

####要素、ボックス内の中身を縦に中央寄せる方法
親要素で縦方向に中央寄せしたい場合には、行の高さ(line-height)を親要素の高さに合わせることでできます。
例えば、親要素の高さが`height:50px;`としていた場合、子要素の高さを`line-height:50px;`とすることで中央寄せができます。
ただし、これは中のテキストが一行のときしか使えないので注意が必要です。

#さいごに
今回は中央寄せについて、条件に応じた色々な方法をまとめてみました。
自分自身これらを中央寄せの方法としてしか覚えられていなかったので、今回それぞれどのような条件ごとに使えるのかまとめられて良かったと思います。
これからも学習続けます。

参考サイト：[CSSで中央寄せする9つの方法（縦・横にセンタリング)](https://saruwakakun.com/html-css/basic/centering)
jestで現在時刻を固定化する

追記  

[timer-mocks](https://jestjs.io/ja/docs/timer-mocks) を使ってください。  


- https://jestjs.io/ja/docs/timer-mocks
- https://jestjs.io/ja/docs/jest-object#jestsetsystemtimenow-number--date

```ts
afterEach(() => {
  jest.useRealTimers();
});

test('', () => {
  const fixed = new Date('2022-1-1T00:00:00');
  jest.useFakeTimers().setSystemTime(fixed.getTime());
  // ...
});
```

以下の情報は古いです。



----

# はじめに
時間に依存しているようなAPIの振る舞いを試験するとき、現在時刻を固定化して試験したいことがよくあると思います。
`Date.now()` と `new Date()` をモックすることで、現在時刻を固定化することができます！！


# やり方

`Date`の振る舞いを固定することで、`moment()` の現在時刻も固定化できます。

```javascript
const moment = require('moment')

describe('モックした現在時刻のテスト', () => {
  let now;
  let spiedDate;
  // setup
  beforeAll(() => {
    const OriginalDate = Date; // 退避
    now = new OriginalDate('2019/8/1 12:00:00');
    // Date.now() と new Date() のみmocking
    Date.now = jest.fn().mockReturnValue(now.valueOf());
    spiedDate = jest.spyOn(global, 'Date').mockImplementation((arg) => {
      if (arg === 0 || arg) {
        return new OriginalDate(arg);
      }
      return now;
    });
  });

  afterAll(() => {
    spiedDate.mockRestore();
  });

  test('現在時刻をYYYY/MM/DDの形式で表示できる', () => {
    const actual = moment().format('YYYY/MM/DD');
    expect(actual).toBe('2019/08/01');
  });

  test('Dateコンストラクタで現在時刻が固定化される', () => {
    const actual = new Date();
    expect(actual.valueOf()).toBe(now.valueOf());
  });

  test('Dateコンストラクタで時刻を指定できる', () => {
    const actual = new Date(0);
    expect(actual.valueOf()).toBe(0);
  });
})
```

# 説明

ここで固定したい日付を設定します。
後ほどコンストラクタの振る舞いを書き換えるため、`Date`オブジェクトを退避しています。

```javascript
const OriginalDate = Date; // 退避
now = new OriginalDate('2019/8/1 12:00:00');
```

[Date.now()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Date/now) を固定し、常に同じUnix時刻が返却されるようにしています。


```javascript
Date.now = jest.fn().mockReturnValue(now.valueOf());
```

[jest.spyOn](https://jestjs.io/docs/ja/jest-object#jestspyonobject-methodname) を利用して、コンストラクタで固定の値を返却するようにします。
`arg === 0` の判定は、Unix時間0の時も正しく動作させるためです。

```javascript
spiedDate = jest.spyOn(global, 'Date').mockImplementation((arg) => {
  if (arg === 0 || arg) {
    return new OriginalDate(arg);
  }
  return now;
});
```


`Date` オブジェクトを元に戻します。(`global.Date = OriginalDate` でも同じ効果)

```javascript
afterAll(() => {
  spiedDate.mockRestore();
});
```
Leetcode #1110: Delete Nodes And Return Forest

```swift
func delNodes(_ root: TreeNode?, _ to_delete: [Int]) -> [TreeNode?] {
    return helper(root, Set(to_delete), true, nil, true)
}

private func helper(_ node: TreeNode?, _ to_delete: Set<Int>, _ isRoot: Bool, _ root: TreeNode?, _ fromLeft: Bool) -> [TreeNode?] {
    if node == nil {
        return []
    }
    if to_delete.contains(node!.val) {
        if fromLeft {
            root?.left = nil
        } else {
            root?.right = nil
        }
        return helper(node?.left, to_delete, true, nil, true) + helper(node?.right, to_delete, true, nil, true)
    } else {
        return helper(node?.left, to_delete, false, node, true) + helper(node?.right, to_delete, false, node, false) + (isRoot ? [node] : [])
    }
}
```
scikit-learnの実装トレーニング3～ディープラーニングで探索～

#前回までにやったこと
機械学習で顧客情報から顧客が定期預金を申し込む確率を予測した。
ロジスティック回帰、ランダムフォレスト、サポートベクタマシンを使用した[前回](https://qiita.com/shiroino11111/items/610bdd0704cdc25db7c0)の最高スコアは
grid best score, 0.9296152371929293
Test set AUC: 0.90
であった。
[前々回](https://qiita.com/shiroino11111/items/eb1017fe053527862266)のロジスティック回帰モデルの結果の
grid best score, 0.9383648126404396
Test set AUC: 0.91
にわずかに劣った。

##今回やること
ディープラーニングのMLPClassifierを利用し、高い精度を目指す。
実装コードは[こちら](https://github.com/shiroino11111/predict_deposit.git)のbank3.py
#####パッケージのインポート(前回と少し違う)
```python
import numpy as np
import pandas as pd
from sklearn.model_selection import *
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neural_network import MLPClassifier
import warnings
import mglearn
# 実行上問題ない注意は非表示にする
warnings.filterwarnings('ignore') 
```
#####データの読み込み（前回と同じ）
```python
df = pd.read_csv("data/bank_01.csv")
#ワンホットエンコーディング
data_dummies = pd.get_dummies(df)

features = data_dummies.loc[:, 'age':'poutcome_success']
X = features.values
y = data_dummies['y_no'].values
#データ確認
print("X.shape: {}  y.shape: {}".format(X.shape, y.shape))
print(data_dummies.y_no.value_counts())
```
#####GridSearchCVを使って最適なalpha, 隠れ層数を探す
めちゃくちゃ時間が掛かったのでmax_iterの桁を下げるか、パラメータ数を下げることを推奨。１時間以上掛かった。

```python
pipe = Pipeline([('scaler', StandardScaler()), ('classifier', MLPClassifier(max_iter=200000))])
param_grid = {'classifier__alpha':[0.01, 0.1, 1, 10 ], 'classifier__hidden_layer_sizes': [[10], [100], [1000], [10000], [100000]]}
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
grid = GridSearchCV(pipe, param_grid=param_grid, cv=2, return_train_score=False,  scoring="roc_auc")
grid.fit(X_train, y_train)
print("Best parameters: ", grid.best_params_)
print("grid best score, ", grid.best_score_)
print("Test set accuracy: {:.2f}".format(grid.score(X_test, y_test)))

```
結果
Best parameters:  {'classifier__alpha': 10, 'classifier__hidden_layer_sizes': [10]}
grid best score,  0.9368240651853158
Test set accuracy: 0.91
[前々回](https://qiita.com/shiroino11111/items/eb1017fe053527862266)のロジスティック回帰モデルの結果に並んだ。

#####テストデータでヒートマップ確認
```python
xa = 'classifier__hidden_layer_sizes'
xx = param_grid[xa]
ya = 'classifier__alpha'
yy = param_grid[ya]
plt.figure(figsize=(5,8))
scores = np.array(grid.cv_results_['mean_test_score']).reshape(len(yy), -1)
mglearn.tools.heatmap(scores, xlabel=xa, xticklabels=xx, 
                      ylabel=ya, yticklabels=yy, cmap="viridis")
```
結果
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479337/6ff9a97c-2555-e367-b822-6cb1ea8529b0.png)


隠れ層は大きいほど高スコアが確認できる。
alphaはそんなに影響ない？
Leetcode #442: Find All Duplicates in an Array

```swift
func findDuplicates(_ nums: [Int]) -> [Int] {
    var nums = nums
    var answer = [Int]()
    for i in stride(from: 0, to: nums.count, by: 1) {
        let index = abs(nums[i]) - 1
        if nums[index] < 0 {
            answer.append(index + 1)
        } else {
            nums[index] = -nums[index]
        }
    }
    return answer
}
```
テスト11

```vb


Sub サンプル()

Call FileSearch("C:\Users\user\Desktop\中小企業診断士関係")

End Sub

Sub FileSearch(Path As String)

Dim FSO As Object
Folder As Variant
File As Variant

    Set FSO = CreateObject("Scripting.FileSystemObject")

    For Each Folder In FSO.GetFolder(Path).SubFolders
        Call FileSearch(Folder.Path)
    Next Folder

    For Each File In FSO.GetFolder(Path).Files
        Debug.Print File.Path
    Next File

End Sub


Sub Macro1()
'グループ化するためのコード

    Columns("D:F").Select
    Selection.Columns.Group
    Rows("6:12").Select
    Selection.Rows.Group
    
End Sub


Sub Macro4()
'グループ化したシートから可視セルを選択、別シートに貼付

    Range("A1:J17").Select
    Selection.SpecialCells(xlCellTypeVisible).Select
    Selection.Copy
    Sheets("Sheet8").Select
    Selection.Copy
'    Application.Run "テーブルスクレイピング.xlsm!値で貼付"
    
End Sub



```
Fusion360でpipを使って外部ライブラリをインスコする(macOS)

# Fusion360は独自のpython環境がある．

Fusion360の[スクリプト](http://help.autodesk.com/view/fusion360/ENU/?guid=GUID-1C665B4D-7BF7-4FDF-98B0-AA7EE12B5AC2)は割といろんなコマンドにアクセスできて便利．PythonもしくはC++で書けるのだが，Pythonを使うにあたってはNumpyなどを使いたいなどと思うことがある．しかし__Fusion360ではローカルのマシンとは別のPython環境が内部にあり，単に`pip install`しただけではFusionにモジュールが追加されない__．
本稿ではこれをどうにかする方法を紹介する．

なお今回はmacOSにおける解決方法を紹介．

## Fusion360のPython実行環境にたどり着く

macOSの場合，筆者の環境では

```/Users/jotaro/Library/Application Support/Autodesk/webdeploy/shared/PYTHON/3.5.3c/mac64_sp/Python.framework/Versions/3.5/```
にFusion python実行環境があった．ターミナルで`cd`を用いてここまでたどり着いてみよう．

```shell
cd /Users/[your username]/Library/Application\ Support/Autodesk/webdeploy/shared/PYTHON/3.5.3c/mac64_sp/Python.framework/Versions/3.5/
```

このフォルダ内の`bin/python`がFusion360がスクリプトをrunする際に用いるpython本体である．

## get-pip.pyによるpipのインストール

この状態で`site-packages`のあるディレクトリまで移動する．

```shell
cd lib/python3.5/site-packages/
```

ここにhttps://bootstrap.pypa.io/get-pip.py からインストールできる `get-pip.py`を保存．

__先に探し当てたFusion pythonの本体を使って__`get-pip.py`を実行する．

```shell
/Users/jotaro/Library/Application\ Support/Autodesk/webdeploy/shared/PYTHON/3.5.3c/mac64_sp/Python.framework/Versions/3.5/bin/python ./get-pip.py
```

## Fusionのpythonのpipを実行

普段の`python`を上で実行したFusion Pythonに置き換えて，pipを利用してモジュールをインストールできるはずである．

```shell
/Users/jotaro/Library/Application\ Support/Autodesk/webdeploy/shared/PYTHON/3.5.3c/mac64_sp/Python.framework/Versions/3.5/bin/python -m pip install numpy
```

```shell
Collecting numpy
  Downloading https://files.pythonhosted.org/packages/4a/2e/cf0a2fea6d97604a0e058e804b50d589c31b360b317be9f5c126b22a560e/numpy-1.17.0-cp35-cp35m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl (14.9MB)
     |████████████████████████████████| 15.0MB 26.0MB/s
Installing collected packages: numpy
Successfully installed numpy-1.17.0
```

これで，Fusion側で

```python
import adsk.core, adsk.fusion, traceback
import numpy as np
```

して問題なければ，Fusion側のpipを用いてnumpyがインストールできている．
【Unity(C#)】Scene上のサウンドをまとめて再生、停止する方法

##まとめて停止、再生
`FindObjectOfType`を利用して、
シーン上にある全ての`AudioSourceコンポーネント`を`Start`で集めてくる方法を使います。
なので、途中で生成された`AudioSourceコンポーネント`は範囲外です。

外部から呼び出すことは確定しており、2つ以上必要なコンポーネントではないので
**シングルトン**を用います。

##シングルトン
あんまり理解せずに使ってましたが、
この説明[^1]が個人的には一番しっくりきました。
>Unityでゲーム作ってるとどこからでも呼び出したいクラスが欲しくなります。
命名するとなんちゃらマネージャーみたいになるやつ。
AudioManagerとか、SettingManagerとか、ParticleManagerとか
どこからでも呼び出せると便利で、でも２つ以上あったら変なもの。
じゃーどうすんの？って調べてると大体シングルトンっていう考え方に行き着くと思う。
ようするにインスタンスを１個しか作らなければいいだけ。

あとシングルトンというのはデザインパターンのことらしいです。
~~C#の機能か何かだと思ってた。~~


##シングルトン実装
最強に使いやすい[^1]のがあるのでいつも使わせてもらってます。

```C#
using UnityEngine;

public class Singleton<T> : MonoBehaviour where T : MonoBehaviour {
    static T instance;

    public static T Instance
    {
        get
        {
            if(instance == null)
            {
                instance = (T)FindObjectOfType(typeof(T));

                if(instance == null)
                {
                    Debug.LogError( typeof(T) + " none");
                }
            }

            return instance;
        }
    }
}
```

```C#:適当にどっかにアタッチ
using UnityEngine;

public class SoundsOnOffController : Singleton<SoundsOnOffController>
{
    AudioSource[] audioSources;
    AudioSource[] tmpAudioSources;

    int count;

    void Start()
    {
        audioSources = FindObjectsOfType(typeof(AudioSource)) as AudioSource[];
        tmpAudioSources = new AudioSource[audioSources.Length + 1];
    }

    public void StopSounds()
    {
        foreach (AudioSource _as in audioSources)
        {
            if (_as.isPlaying == true)
            {
                tmpAudioSources[count] = _as;
                _as.Pause();
                count++;
            }
        }
    }

    public void StartSounds()
    {
        for (int i = 0; i < tmpAudioSources.Length; i++)
        {
            if (tmpAudioSources[i] != null)
            {
                tmpAudioSources[i].UnPause();
                tmpAudioSources[i] = null;
            }
        }
    }
}
```

##Pause、UnPause
今回は`Pause`と`UnPause`を使っています。
`Pause`でAudioを止めて、`UnPause`で止めた箇所から再生です。

大量にAudioがあるときの負荷なんかは調べてないので知りませんが5、6個なら問題なく動きました。

##呼び出し方
`SoundsOnOffController.Instance.StartSounds();`
このようにしてあげればどこからでもスクリプト経由で呼び出せます。


[^1]: [引用元、参考リンク](https://naichilab.blogspot.com/2013/11/unitymanager.html)
Leetcode #1108: Defanging an IP Address

```swift
func defangIPaddr(_ address: String) -> String {
    var str = Array(address)
    var answer = [Character]()
    for i in stride(from: 0, to: str.count, by: 1) {
        if str[i] == "." {
            answer.append(contentsOf: ["[",".","]"])
        } else {
            answer.append(str[i])
        }
    }
    return String(answer)
}
```
GRUB修復　LinuxとWindowsのデュアルブート 


Windows10とLinux_mintのデュアルブートで使用しています。
しかし、Microsoftの仕様により、Windows10が半年に一度大型アップデートを実施します。
デュアルブートしていることを忘れて、1903を適用してしまいめでたくGRUBが死にました。
修復メモとして、記録します。

①"ls"にてパーティションを確認
②"ls (hd0,gpt6)/" 等にて　"grub"が入っているパーティションを確認します。
③set prefix="(hd0,gpt6)/grub"
④root=(hd0,gpt6)
⑤insmod normal
⑦normal
=====Linuxが起動してくる=====
⑧起動後、以下のコマンドを実行し、再起動後起動するように設定
"sudo grub-install --force /dev/sda"  ※"/dev/sda"は、適切な場所にインストールしてくれる

これで復旧しました。

再起動等して、確認してください。
Noodlで色の変わるOn/Offボタンを作る

#概要
　NoodlでOn/Offボタンを作ってみました。その備忘録を残します。
↓のようにボタンを押すと色とテキストが変わります。

　<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Noodlで作ったボタンの色を状態で変えてみた。<a href="https://twitter.com/hashtag/Noodl?src=hash&amp;ref_src=twsrc%5Etfw">#Noodl</a> <a href="https://t.co/4Rju0MEz1i">pic.twitter.com/4Rju0MEz1i</a></p>&mdash; まえぷー@技術書典７サークル参加 (@kmaepu) <a href="https://twitter.com/kmaepu/status/1161600455274745856?ref_src=twsrc%5Etfw">August 14, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

全体のフローは次の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/8665f285-c649-28b5-3873-4d3f7063de18.png)

#作ってみる
##使用するノード
　次の４種類のノードを使用します。

・**Circle**
　ボタンの外見に使用します。
・**Text**
　ボタンに表示するテキストです。
・**States**
　ボタンのOn/OFF状態を設定します。
・**Color Blend**
　複数の色を用意し、"Blend Value"で与えられた値に応じて色を出力します。

##ボタンを押すと状態遷移
　Circleノードを押すと、Statesが変わるようにしています。Circleノードの"**Tap**"とStatesノードの"**Toggle**"を接続します。これで状態が遷移するようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/fa8c77bb-d73b-98dc-e92b-3d4249efff91.png)

Statesノードで扱う"States"と"Values"は次の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/5b237eb3-7422-ecca-4204-dc68199f8c34.png)

各状態のValueは次のように設定しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/1ebdd004-f46a-cc94-cdf8-a5df0a27a903.png)

##状態で色を変える
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/ded40c00-b286-ccf1-3918-5ea7b0cf7faf.png)

色のコントロールは"**Color Blend**"ノードで行います。
このノードは予め色を登録しておき、"Blend Value"で与えられた値によって、出力する色を変えます。
今回は次のように設定しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/37c9f7f6-6cdd-8800-d1ee-b92c81403b64.png)

Blend Valueは各色の割合を設定するようです。
　0　→　Color0
　1　→　Color1

0.5を設定すると、Color0とColor1の中間色が出力されるようです。
Color Blendノードの"Result"をCircleノードの"Color"に接続します。

以上でボタンの色を変えることができました！
chart.jsの使い方！chart.jsでおしゃれなグラフを表示する方法（入門編）                                                                                                            

**はじめに**
---
今回はchart.jsを用いて「動く！」「おしゃれ！」「かんたん！」なグラフを表示していきたいと思います。

⚠️htmlファイルとjsファイルをそれぞれ作ることを推奨しますが、初心者の方は躓く可能性があるため、独断でまとめてhtmlファイルに記述しちゃいます。

**chart.jsとは**
---
折れ線グラフ、棒グラフ、円グラフ、レーダーチャートなど、8種類のグラフが簡単に描けてしまうJavascriptのライブラリです。 HTML5のCanvasを使って描画され、表示の際の気持ちいいアニメーションの動きが特徴的です。 とても分かりやすいマークアップなので、誰でも簡単に編集ができるようになっています。

実際に表示すると↓のようになります。

![chartjs.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457895/9f8f95df-ff52-f848-e422-297546c45024.gif)

**ソースコード**
---
早速ソースコードに入ります。
[公式サイト](https://www.chartjs.org/samples/latest/)でもサンプルコードが公開されています。
公式サイト内でグラフを弄れるのでぜひ！

```html


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>chart</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.min.js"></script>
</head>
<body>

<canvas id="myChart"></canvas>
<script>
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
  type: 'line',
  data: {
    labels: ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
    datasets: [{

      label: 'label',
      data: [3, 18, 6, 10, 12, 7, 12],
      backgroundColor: "rgba(255,153,0,0.4)"
    }]
  }
});
</script>

</body>
</html>
```



**各グラフの描写方法**
---
棒グラフ：type:'line',
折れ線グラフ：type:'bar',
レーダーチャート：type:'radar',
散布図：type:'scatter',
円グラフ：type:'pie',
ドーナツチャート：type:'doughnut',
バブルチャート：type:'bubble',
鶏頭図：type:'polarArea',
に変更すれば描写できます。

**グラフの数値を変数によって動的に変化させたいとき**
---

```
data: [3, 18, 6, 10, 12, 7, 12],
　　　　　　　　　↓
data: [a, b, c, d, e, d, e],　
```

の数値の部分を任意の変数にするだけでok!


**まとめ**
---
今回はchart.jsで描写する８つのグラフについて紹介しました。

紹介したソースコードは非常にシンプルですが、こちらをベースに御自身で必要な要素を追加してみて下さい。