OmniAICreator/Qiita-1.07M huggingface dataset:
LaravelのExistsバリデーションでなぜデータベースエラーが発生しないのか？

# 疑問
FormRequestクラスを継承した自前のクラスで、以下のようなルールを定義した。

~~~ php
    public function rules()
    {
        return [
            'id' => [
                'required',
                "integer",
                "between:1,2147483647",
                'exists:users,id',
        ];
    }
~~~

このidに対して、2147483648を入力しても、データベースエラーにはならない。
また、文字列 "abcd" などを入力しても、やはりデータベースエラーにはならない。
existsより手前に設定されている検証がNGの場合に、exists検証が実行されていないようだ。
なぜ？

そういえば、requiredが失敗するとそれ以降のバリデーションが実行されていないのも理由がよくわからない。

https://readouble.com/laravel/5.5/ja/validation.html
ドキュメント中に、「暗黙の拡張」という項目があって、ここが関係していそうなのだが、ドキュメントを読んだだけでは要領を得ない感じ。

# 実験
そこで、自作のバリデーションルール(my_rule_exists_in_users)を作って、existsの代わりに適用してみた。
※このmy_rule_exists_in_usersは、usersテーブルのid列に、入力値が存在しているかの確認を行う処理を実装。

~~~ php
    public function rules()
    {
        return [
            'id' => [
                'required',
                "integer",
                "between:1,2147483647",
                //これを自作してみた
                'my_rule_exists_in_users',
        ];
    }
~~~

この場合、2147483648や"abcd"を入力すると、integer型に対して不適切な入力値であるためデータベースエラーが発生する。

なんでexistsはうまいこと動いているの？

# 解決編
Illuminate\Validation\Validator::validateAttribute() および、
Illuminate\Validation\Validator::isValidatable() 
の実装を見ると、なせこのような動きになっているのかがわかった。

~~~ php:Illuminate\Validation\Validator.php(一部抜粋)
    /**
     * Determine if the attribute is validatable.
     *
     * @param  object|string  $rule
     * @param  string  $attribute
     * @param  mixed   $value
     * @return bool
     */
    protected function isValidatable($rule, $attribute, $value)
    {
        return $this->presentOrRuleIsImplicit($rule, $attribute, $value) &&
               $this->passesOptionalCheck($attribute) &&
               $this->isNotNullIfMarkedAsNullable($rule, $attribute) &&
               $this->hasNotFailedPreviousRuleIfPresenceRule($rule, $attribute);
    }

    /**
     * Determine if it's a necessary presence validation.
     *
     * This is to avoid possible database type comparison errors.
     *
     * @param  string  $rule
     * @param  string  $attribute
     * @return bool
     */
    protected function hasNotFailedPreviousRuleIfPresenceRule($rule, $attribute)
    {
        return in_array($rule, ['Unique', 'Exists']) ? ! $this->messages->has($attribute) : true;
    }

~~~ 

各バリデーションは、実際に検証を行う前に isValidatable() を呼んでいて、このメソッドがfalseを返すと検証自体をスキップする仕様になっているようだ。
検証ルールにrequired、nullableなどを追加している場合の動きも、この辺で実装されているっぽい。
exists の動作に直接関わっているのは↑の hasNotFailedPreviousRuleIfPresenceRule() で、ここに答えが書いてあった。

# 結論
自作のバリデーションルールに、existsルールのような「それより手前のバリデーションがNGの場合に検証自体をスキップする」よう振る舞ってほしい場合は、Validatorクラスを継承した自分用のValidatorクラスを定義して、hasNotFailedPreviousRuleIfPresenceRule()をオーバーライドすればよい、ということになりそう。

この['Unique', 'Exists'] を外から書き換えられるようにしておいてほしい感じではある。
インライン要素・ブロック要素を擬人化して理解する

[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしているerika_zです。

HTMLとCSSの学習には、progateを利用しています。
HTML＆CSS中級編まででprogateだけでは理解しがたいことがいくつかありました。
そこで今回は、理解に苦しんだインライン要素・ブロック要素についてまとめます。

#はじめに

プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

#そもそも何が分類されているか

要素が分類されています。
それぞれ人間の性格が違うのと同じように、要素もそれぞれ違う働きをします。
そこで、単純化するため要素は同じ働きをする者同士でひとまとめにされ、グループ化されています。
そのグループ名がインライン要素・ブロック要素です。

#インライン要素
・グループのメンバー
a , em , img , input , span, strong, textareaなど

・グループの特徴
自分の体の大きさ分しか、横幅を取りません。一列横に座る場合、隣に座っても大丈夫です。
そのため、前後の要素はインライン要素の横に配置されます。


#ブロック要素

・グループのメンバー
center, div, form, h1~h6, ol, ul, pなど


・グループの特徴
いくら体が小さくても、一列を占領します。ほかの要素は隣に座ることはできません。
そのため、ブロック要素の次に来る要素は下に配置されます。

#まとめ

インライン要素・ブロック要素を擬人化してご紹介しました。

学習をはじめてすぐは、HTMLとCSSの仕組み完全に理解していないため、小さなことでも理解することが困難なことがあります。
どうしても理解できないときは、人物にたとえてみると理解できるかもしれません。
React.js 学習メモ　第6回

最近Reactの勉強を始めたので、ノート代わりにまとめていきます。
主に自分の学習の流れを振り返りで残す形なので色々、省いてます。
Webエンジニアの諸先輩方からアドバイスやご指摘を頂けたらありがたいです！

#Reducerメモ
>reducerはactionとstateから、新しいstateを作成して返すメソッドです。ポイントは、引数のstateを更新することはせず、新しいstateのオブジェクトを作成して返します。
reducerのメソッドは副作用を起こさないpureな関数でなければならず、Aというstateに対して毎回必ずBというstateを返すような関数でなければなりません。

>actionからstoreへアクセスする事で状態を変化
Reducerはアプリケーションが大きくなるにつれて実装が肥大化してしまうので、Reducer内に子Reducerを作成し、stateのプロパティごとに子Reducerで処理するようにします。

####Reduxの3原則 
>1. Single source of truth
アプリケーション内でStoreは1つのみとし、Stateは単独のオブジェクトとしてStoreに保持される。
2. State is read-only
Stateを直接変更することはできず、actionをStoreへdispatchすることでしかStateは変更できない。
3. Mutations are written as pure functions
Stateを変更する関数(Reducer)はpureな関数にする。

#pureな関数
renderメソッドは「ピュア」である必要がある。これは、「コンポーネントの状態を操作しない」「DOMの操作（読み書き）をしない」「ブラウザの操作をしない」ということ。

####Component と PureComponentの使い分け 
(1) 原則
render関数を発火させる回数を減らせば減らせるほど、
Reactの性能を発揮することができる。

(2) 結論
propsと stateが常に変化していれば、PureComponentを使わず、Componentを使うべし。
>（理由：shouldComponentUpdate内のshallowEqualも時間かかる）
propsと stateがあまり変わらなければ、PureComponentを使うべし。
propsと stateが変わらなければ、どちらでもOK.
React自体VirtualDOM機構で差分しかrenderされず性能を保証してくれるため、初心者は気にせずComponentを使用。Bottle Neckになったら、最適化すれば良い。

ちなみに上記では1つのdivコンポーネントを返しているが、コンポーネントの中にコンポーネントを含めることも可能。ただし、ルート要素（上記の場合div）は1つしか返せない。

つまり、以下の様な返し方はNG。

```jsx
// NG例
return (
  <div className="commentBox">
    Hello, world! I am a 1st CommentBox.
  </div>
  <div className="commentBox">
    Hi, world! I am a 2nd CommentBox.
  </div>
);
```

#振り返り
pureな関数を書けるように一旦、「コンポーネントの状態を操作しない」「DOMの操作（読み書き）をしない」「ブラウザの操作をしない」ということを意識してコードリーディングなどを行なっていきます。
Python スレッドの停止と再開の簡易サンプル

# はじめに

pythonで処理を並列に行いたいと思いました
しかし、マルチスレッドに関する知識がありませんでした。
そこでとりあえず動くレベルで良いので勉強してみました。
ざっくりとしたものですが、記事に残してみようと思います。

Python 3.7.3で動作確認しました。

# 要件

1. マルチスレッドで処理を並行で行いたい。
2. スレッドの処理を頻繁に停止・再開をしたい

# 実装

## メンバにスレッドを持つタイプ

```python:python
import threading
import time

class Test1():
  def __init__(self):
    self.started = threading.Event()
    self.alive = True
    self.thread = threading.Thread(target=self.func)
    self.thread.start()

  def __del__(self):
    self.kill()

  def begin(self):
    print("begin")
    self.started.set()

  def end(self):
    self.started.clear()
    print("\nend")

  def kill(self):
    self.started.set()
    self.alive = False
    self.thread.join()

  def func(self):
    i = 0
    self.started.wait()
    while self.alive:
      i += 1
      print("{}\r".format(i), end="")
      self.started.wait()

test = Test1()
test.begin()
time.sleep(2)
test.end()
test.begin()
time.sleep(2)
test.end()
test.begin()
time.sleep(2)
test.end()
test.kill()
```

## threading.Threadを継承するタイプ

```python
class Test2(threading.Thread):
  def __init__(self):
    super().__init__()
    self.started = threading.Event()
    self.alive = True
    self.start()

  def __del__(self):
    self.kill()

  def begin(self):
    print("begin")
    self.started.set()

  def end(self):
    self.started.clear()
    print("\nend")

  def kill(self):
    self.started.set()
    self.alive = False
    self.join()

  def run(self):
    i = 0
    self.started.wait()
    while self.alive:
      i += 1
      print("{}\r".format(i), end="")
      self.started.wait()

test = Test2()
test.begin()
time.sleep(2)
test.end()
test.begin()
time.sleep(2)
test.end()
test.begin()
time.sleep(2)
test.end()
test.kill()
```

# 最後に

ざっくりとした記事と書いた割には、大分トリッキーな気もしますが
Laravel組み込みのBootstrapでbtn-info,text-infoが効かない(違う色になる)ときにやった暫定対処

# 結論：デフォのBootstrapを使わない
Laravelには組み込みでBootstrap4.0が入っている。
純粋にグリッドシステムだけ使うとかであればそのままデフォのjsとcssを使えばいい。
ちなみに

```php:test.blade.php
<html>
<hrad>

// 中略
<script src="{{ asset('js/app.js') }}" defer></script> //これと
<link href="{{ asset('css/app.css') }}" rel="stylesheet"> //これ

// 中略
</head>
<body>
....// 略
```

を書けば、デフォのBootstrapの導入は終わり。  
(make:auth で生成されるloginページもこれが使われている)  
ただ、デフォの組み込みのBootstrapで作ってて、タイトルの事象が起きて困った。
開発者コンソールからカラーの設定を見ると、btn-infoとtext-infoの設定が  

```css:app.css
color:#6cb2eb!important
```

になっている。これ、なんか色が違うのでは・・・  ？
と思って、app.cssの編集することも考えたのですが、影響範囲がわからないし、よくわからないものは手を加え無いほうが無難  

ということで、普通にhead内にBootstrapの導入の記述をしました。  
※JSとCSSのCDNをコピってheadに貼り付けるだけ
[Bootstrap公式4.3.1:導入](https://getbootstrap.com/docs/4.3/getting-started/introduction/)

デフォのBootstrapの読み込みはしないように忘れずに削除するか
コメントアウトをしておく

```
// <script src="{{ asset('js/app.js') }}" defer></script>
// <link href="{{ asset('css/app.css') }}" rel="stylesheet">  この2行はいらないのでコメントアウトする。
```

たぶん、これが一番手っ取り早いです。
sassの書き換えとかでverを上げるいろいろな記事が上がっているけど、
よくわからないものには（以下略）
WireMockでスタブサーバーを立ち上げる

WireMockのスタブサーバーとは、HTTP通信が発生するAPIにおいて、送信先のポートをモック化し、期待する返却値を返すようにするものです。

- 環境
    - Java1.8
    - SpringBoot2系
    - WireMock 2系

##１個たてる場合

```java

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class FunctionalTest {

  @ClassRule
  public static WireMockRule wireMockRule =
    new WireMockRule(wireMockConfig().port(8081)
      .usingFilesUnderDirectory("src/functionalTest/resources/"));

  @Test
  public void 正常系() {
    stubFor(get(urlEqualTo("/hoge"))
      .willReturn(aResponse()
        .withStatus(200)
        .withBodyFile("hoge.json")))

    //テスト内容...

  }
}
```

```hoge.json
{
  "text": "hogehoge"
}
```

簡単に解説すると、/hogeにアクセスしたときに200ステータスとhogehogeを返却するスタブサーバーが8081番ポートで立ち上がります。
注意点としてはhoge.jsonを配置する場所です。
src/functionalTest/resources/**__files**/hoge.json  
です。この__filesをわすれて一時間ハマりました。

## 複数個たてる場合

先にコードを載せておきます。

```java

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class FunctionalTest {

  @Rule
  public WireMockRule wireMockRuleHoge =
    new WireMockRule(wireMockConfig().port(8081)
      .usingFilesUnderDirectory("src/functionalTest/resources/"));

  @Rule
  public WireMockRule wireMockRuleFuga =
    new WireMockRule(wireMockConfig().port(8082)
      .usingFilesUnderDirectory("src/functionalTest/resources/"));

  @Test
  public void 正常系() {

    wireMockRuleHoge.stubFor(get(urlEqualTo("/hoge"))
      .willReturn(aResponse()
        .withStatus(200)
        .withBodyFile("hoge.json")
      )
    );

    Resource requestResource = resourceLoader.getResource(ResourceLoader.CLASSPATH_URL_PREFIX + "/fuga.json");
    String request = FileUtils.readFileToString(requestResourcePerformance.getFile(), UTF_8);  
    wireMockRuleFuga.stubFor(post(urlEqualTo("/fuga"))
      .withRequestBody(equalToJson())
      .willReturn(ok())
    );

    //テスト内容...

  }
}
```
なんとなくわかると思いますが、/fugaにpostでfugafugaを送ると200番ステータスのみを返却するスタブが追加できました。  
利点としては各ルールに対してverifyなどが用意されているので、どのスタブのどんなPOSTリクエストが何回呼ばれたかなどをテストすることができます。
日付と値のユーザログをpandasで正規化

# 日付と値のユーザログをpandasで正規化
以下のようなDBに保存されたユーザログを
行をユーザIDと列日付に直したのでメモ

| user_id       |       value  |    date    |
|-----------------:|------------------:|:------------------:|
| 1             |             12 |       2018-01-01        |
| 1           |            100 |       2018-01-02       |
| 1             |              20 |        2018-01-03        |
| 2               |                10 |         2018-01-01         |
| 2             |             12 |       2018-01-02       |
| 2          |           22 |      2018-01-03       |
| :            |             : |       :       |
| 1000          |           120 |      2018-01-03       |


当初はforでゴリゴリするしかないのかぁと思ったが、
pandasでループを使ったら負けだと思っているので、
調べていたら、pivot_tableあるじゃんとなったのであっさり解決

```python
import pandas as pd

# CSV読み込み
csv_df = pd.read_csv('hoge.csv')

# 重複を削除
data = data.drop_duplicates(subset=['date', 'user_id'], keep=False)

# 並び替え(確認のため)
data.sort_values(['user_id', 'date'], inplace=True)

# pivot_table実行
# indexが行に指定したいカラム, columnsが列に指定したいカラム, valuesが集計したい対象 
result_df = pd.pivot_table(data, index='user_id', columns='date', values='value')
# 欠損は0で穴埋め
result_df = result_df.fillna(0.0)

# 適当に確認して、CSVに出力
print(result_df.head())
print(result_df.tail())
result_df.to_csv('value_by_user_and_date.csv')
```
※本来であれば、日付が全て揃っているか確認する必要があるかも
Raspberry Pi にDockerとDocker-composeを入れる

#Raspberry Piについて
使用したラズパイは3B+です。(3Bでも動きました)
初期OSはRaspbian Stretch with desktop(Kernel version:4.14)
なお、Raspberry Pi 1xとzero(w)はCPUが異なるので現時点では最新版は動作しません。
バージョンを下げれば動くので、その方法も記載しました。

```
$ uname -a
Linux raspberrypi 4.19.42-v7+ #1219 SMP Tue May 14 21:20:58 BST 2019 armv7l GNU/Linux

$ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 9.8 (stretch)
Release:        9.8
Codename:       stretch
```

#Dockerのインストール
[公式blog](https://www.raspberrypi.org/blog/docker-comes-to-raspberry-pi/)に記載の方法で入ります。
sudo使わなくて済むようにdockerグループにユーザーを追加します。(再ログイン後に反映される)
自動起動の設定も必要かも。

```
$ curl -sSL https://get.docker.com | sh
$ sudo usermod -aG docker pi
$ sudo systemctl enable docker

$ docker --version
Docker version 18.09.0, build 4d60db4
```

### Raspberry Pi 1x and zero(w)
Raspi1xとzero(w)の場合、バージョンは表示されますが動作していません。CPUが古いのが原因とのこと。
詳細は、[docker-ce segmentation fault on Raspbian (v18.09.03) #38175](https://github.com/moby/moby/issues/38175)

```
$ docker ps
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

$ sudo systemctl status docker.service
    (抜粋)
    docker.service - Docker Application Container Engine
    Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
    Active: failed (Result: core-dump)
```

以下のようにしてdocker-ceをダウングレードします。

```
$ sudo apt install docker-ce=18.06.3~ce~3-0~raspbian
$ sudo apt autoremove
$ sudo systemctl enable docker && sudo systemctl start docker
```

動作確認

```
$ docker --version
Docker version 18.06.2-ce, build 6d37f41

$ sudo systemctl status docker.service
    (抜粋)
    docker.service - Docker Application Container Engine
    Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
    Active: active (running)
````
docker-composeも動きませんが、そっちはわからないです・・・。

# Docker-composeのインストール
公式サイトにはRaspberryPi用のバイナリが置いていないため、ソースコードからビルドするしかないです。
少し前まで情報がなくて大変でしたが、Dockerfileで出来るようになっていました。
手順を書いてあるサイトは多いですが、エラーが出たりするので、情報をマージしたものです。
ブランチを変更しないと、最新にはDockerfile.armhfが入っていません。

ネットで調べると出てくる、Dockerfileをコピーして作る方法だと、Dockerfile内の
`RUNTIME_DEBIAN_VERSION=stretch-20190326-slim`でエラーになります。<br>`RUNTIME_DEBIAN_VERSION=stretch-slim`に修正するとbuildはできますが、その先でエラーになります。

```
$ git clone https://github.com/docker/compose.git
$ cd compose
$ git checkout bump-1.23.2
$ sed -i -e 's:^VENV=/code/.tox/py36:VENV=/code/.venv; python3 -m venv $VENV:' script/build/linux-entrypoint
$ sed -i -e '/requirements-build.txt/ i $VENV/bin/pip install -q -r requirements.txt' script/build/linux-entrypoint
$ docker build -t docker-compose:armhf -f Dockerfile.armhf .
```
ビルドに30分～1時間程度かかります。

```
$ docker run --rm --entrypoint="script/build/linux-entrypoint" -v $(pwd)/dist:/code/dist -v $(pwd)/.git:/code/.git "docker-compose:armhf"
```
これでdocker-composeのバイナリができるので、移動して完了です。

```
$ sudo cp dist/docker-compose-Linux-armv7l /usr/local/bin/docker-compose
$ sudo chown root:root /usr/local/bin/docker-compose
$ sudo chmod 0755 /usr/local/bin/docker-compose

$ docker-compose --version
docker-compose version 1.23.2, build 1110ad01
```
ビルドに使ったdockerイメージは削除してかまいません。
Windows10でOffice 365 Business のOneDriveも使えるようにする

## Office 365の法人アカウント ≠ Microsoftアカウント

　Microsoft Officeアプリケーションを使うため[お名前.com](https://www.onamae-office.com/lp/04/?utm_source=yahoo&utm_medium=yss&utm_campaign=office&utm_content=1702)のOffice 365 for Businessを利用している。ノートPCは個人のMicrosoftアカウントを利用し、1TBあるBusinessのOneDriveは使っていなかった。

　仕事用にデスクトップPCを購入したので、「法人アカウント」で共通化することした。アカウントを切り替えるために、一旦、ローカルアカウントでのサインインに切り替え、再度Microsoftアカウントに切り替える。

　ところが、Microsoftアカウントの入力画面でOffice 365のアカウントを入力しても、それはMicrosoftアカウントではないと言う。

**Office 365 のアカウント**は**Microsoftアカウント**ではないということを知った。(^^;)

　しょうがないので、個人のMicrosoftアカウントに戻した。

## OneDriveは追加できる

OneDriveのアカウントを切り替えられないものかとおもい、OneDriveの設定を開いてみた。
![Microsoft OneDrive1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112480/5d8527c4-f551-83db-4465-fed91f689dd0.png)
**アカウントを追加**ボタンがあるではないか！
押してみると
![Microsoft OneDrive2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112480/3ea80d31-4074-faf8-f1fc-59c61a69a93c.png)
Office 365のアカウントでサインインしてみる。

OneDriveが追加された。
![Microsoft OneDrive3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112480/7cb89e5c-9762-7fb3-f41d-f8b49bd27e33.png)
タスクバー上のOneDriveアイコンが２つに
青いアイコンが法人アカウントの方だ。
![Microsoft OneDrive4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112480/92b8fa37-024c-1de4-6adb-1c6f7ed7d0be.png)
エクスプローラーのOneDriveも二つになった。
こちらはどちらも青いアイコンなんだが…
調べたいキーワードを含むニュースを配信するSlackbotを作った話

こんばんは〜
今日はAtcoderじゃなくて、slackbotを作った話です:point_up:
指定したキーワードを含む最新のgoogleニュース5件を返してくれるようにしました。
入力は「news　（キーワード）」※newsの後にスペースが必要
初期設定は[こちら](https://qiita.com/croissant1028/items/8d6334b76576762df349)を参考にさせて頂きました。


```python
# coding: utf-8
from slackbot.bot import respond_to
import feedparser
import json
import pprint
import urllib
import re

@respond_to('news\s(.*)')　#入力はnews xxxx
def news_reply(message, keyword): #inputの2つ目を調べる際のkeywordとする
    # RSSのスクレイピング
    s = keyword
    # URLエンコーディング
    s_quote = urllib.parse.quote(s)
    url = "https://news.google.com/news/rss/search/section/q/" + s_quote + "/" + s_quote + "?ned=jp&amp;hl=ja&amp;gl=JP"

    d = feedparser.parse(url)
    news = list()

    for i, entry in enumerate(d.entries, 1):

        p = entry.published_parsed
        sortkey = "%04d%02d%02d%02d%02d%02d" % (p.tm_year, p.tm_mon, p.tm_mday, p.tm_hour, p.tm_min, p.tm_sec)

        tmp = {
            "no": i,
            "title": entry.title,
            "link": entry.link,
            "published": entry.published,
            "sortkey": sortkey  #日付でソート
        }

        news.append(tmp)

    news = sorted(news, key=lambda x: x['sortkey'])
    #最新のニュース5件のタイトルとリンクを表示
    for i in range(1,6): 
        text = news[-i]["title"] + '\n' + news[-i]["link"]
        message.reply(text)
```

見た目はこんな感じ。
<img width="382" alt="スクリーンショット 2019-06-21 23.26.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433971/9a333d4b-2a65-5467-e7f9-e5aa8a6d85ef.png">

結論:
slackbotは簡単に作れる。
~~普通にググれば良い~~ :ramen:
Pythonのライブラリを調べてみました

#はじめに

[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしているにのみやです。

Haccerrankをしている時に知らないライブラリが出てきたのでそれについて調べました。
pythonを勉強して一週間ほどなので、間違いも多いと思います。
間違いがあれば、ぜひ教えてください。


#random
このライブラリはその名の通り、数字をランダムに抽出するものです。
抽出の仕方はたくさんありますが、その中でも特に僕が今使えそうな簡単なものをご紹介します。

##決められた範囲から、数字を抽出する（float型）
```
random.uniform(a,b)
これをつかうと、a <= x <= bのxの値がランダムで出ます。
aとbは整数でも、小数点以下を忘れずに書きましょう。
```
　
サンプル

```python

x = random.uniform(1.0,3.0)
print(x)
```
実行すると

```

1.2034892992721113
```
##決められた範囲から、数字を抽出する（int型）
```
randam.randint(a,b)
これを使うと、a <= n <= bの自然数ｎがランダムに抽出されます。
```
サンプル

```
n = random.randint(1,5)
print(n)
```
実行すると

```
2
```
#おわりに
Pythonの勉強を始めたばかりで、まだまだ知らないライブラリがたくさんあります。
気になったものは調べて、またまとめてみたいと思います。
知っておくとよいおすすめのライブラリがありましたらぜひ教えてください。
標準入力から読み込むコード

AtCoder や paiza といった、入力をもとに仕様に合った出力を出す系のプログラミングサイトだと、入出力のスニペットが必要だと思って用意しているものたち。

# Bash

こっちの方が断然書きやすい！
けど、AtCoder では思ったように動くけど、paiza では Beta ということもあってあまりうまく動かない…。

```bash
#!/bin/bash
read num
i=0
while [ ${i} -lt ${num} ]; do
    read a
    echo ${a}
done
```

# PHP

普段は Web やバッチだから、コンソールアプリなど扱うこともなく、「標準入力から読み込むってどうやるん」というレベルでした。

```php
<?php
$num = trim(fgets(STDIN));
for ($i = 0; $i < $num; $i++) {
    $a = trim(fgets(STDIN));
    echo $a . PHP_EOL;
}
```
babelがnode_modulesを通してくれないときの対応

# 始めに
よくIE対応で一部のモジュールだけbabelを通すということをやると思います。

例えばSwiperのモジュールでbabelを通すとかです。
https://qiita.com/mah_lab/items/5bcd0edc0a68f882a2a7

```webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules\/(?!(dom7|swiper)\/).*/,
        loader: 'babel-loader'
      }
    ]
  }
};
```

この書き方はおそらくbabel6系までは動くのだと思いますが、babel7に上げたらなぜかnode_modulesにあるパッケージにbabelが通らなくなりました。色々調べて解決できたので、記事にしました。

# babel7系でnode_modulesにbabelを通す方法
結論から言うと、僕の場合はbabelの設定ファイルを`.babelrc`から`babel.config.js`に変えたら動くようになりました。
どうやらbabel7系からデフォルトでnode_modulesは除外するようになったようで、webpack側で設定してもbabelの方で除外されてしまったようです。ちゃんとかくなら`babelrcRoots`というオプションに追加する必要がありますが、その設定は`.babelrc`では書けないようで、`babel.config.js`側だとできるようです。
なので明示的に書くなら`babel.config.js`にした後に、`babelrcRoots`を指定すると良さそうですが、僕の場合は別に書かなくてもnode_modulesのコードをトランスパイルしてくれました（もちろんwebpack側でexcludeしていたらやりませんが）。

https://babeljs.io/docs/en/v7-migration-api#config-changes

# 終わりに
今までbabel7にしても普通に動いていたのでこの仕様には全く気づきませんでした。しかも厄介なことにいくら調べてもなかなか情報がでてこないのでかなり苦労しました。
もし他にも同じ問題を抱えている人がいましたら参考してもらえると幸いです。
React Nativeでスプラッシュスクリーンを表示する方法

# はじめに

React Nativeでアプリを開発しているものです。
自分が忘れないよう、また調べるのはめんどくさいので、React Nativeでスプラッシュスクリーンの表示の仕方について整理してみました。

# 1. 必要なパッケージのインストール
React Nativeでスプラッシュスクリーンを表示・非表示するには、下記のパッケージを
インストールする必要があります。
[パッケージの詳細はこちら](https://github.com/crazycodeboy/react-native-splash-screen)

```console
$npm i react-native-splash-screen --save
$react-native link react-native-splash-screen
```

# 2.iOSについて
### 2.1 ネィティブコードの修正
まず、`cd`コマンドで下記のディレクトリへ移動します。
そして、その配下にある`AppDelegate.m`ファイルを開きます。

```console
$cd プロジェクト名/ios/プロジェクト名/
```

起動時にスプラッシュ画像を表示するには、ネイティブのソースを修正する必要があるため、`AppDelegate.m`ファイルにソースを追加します。

```AppDelegate.m

#import "AppDelegate.h"

#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import "RNSplashScreen.h"  //追記！

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // ...other code

    [RNSplashScreen show];  // 追記！
    return YES;
}

@end
```

### 2.2 Xcodeで設定ファイルの設定方法
表示するスプラッシュスクリーンの設定についての説明になります。
大きく分けて、３パターンあります。
(1) Images.xcasssetsのLaunchImageで設定する方法 
(2) LaunchScreen.xibまたはLaunchScreen.storyboardで設定する方法
(3) SplashViewControllerで設定する方法

（１）についての設定方法については、こちらの記事がわかりやすく解説してあります。
自分もこちらを参考にしました。
https://qiita.com/TD3P/items/fabfdf7e39551ee89e59

(2),(3)についてはこちらを参考にしました。
https://qiita.com/k-boy/items/7de88a834bf01a6e858f

# 3.Androidについて
### 3.1 ネィティブコードの修正

まず、以下のファイルを作成します。
`android/app/src/main/res/layout/launch_screen.xml`

作成したらファイルに下記のコードを追加します。

```launch_screen.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/launch_screen">
</LinearLayout>
```
次に`android/app/src/main/res/`配下に下記のフォルダを作成します。

- drawable-xhdpi
- drawable-xxhdpi
 
作成したら、このフォルダの中にスプラッシュ画像を入れます。
画像の名前は`launch_screen.png`にしてください。

#4. アプリ起動後、スプラッシュ画像を非表示にする

アプリ起動後に、スプラッシュ画像を非表示したいので、一番最初に呼ばれる`App.js`でコンポーネントをマウントできたらスプラッシュを消すように処理を加えます。

```App.js
import React, {Component} from 'react';
import { View, Text } from 'react-native';
import SplashScreen from 'react-native-splash-screen';

export default class App extends Component{
  //コンポーネントがマウントされた時に実行されるメソッド
  componentDidMount() {
    SplashScreen.hide();  //スプラッシュスクリーンを非表示にする
  }

  render() {
    return (
      <View>
        <Text>Hello World</Text>
      </View>
    );
  }
}

```

ここまでできたら、`react-native run`コマンドまたは、.xcodeprojからビルドして確認すると、スプラッシュ画像が最初に表示されるようになります。

もし、表示されない場合は、一度アプリをアンインストールするか、シミュレータの場合、[Heardware]->[Erase All Content and Setting..]を実行してから再度ビルドするとうまく行くはずです。
Macのデュアルディスプレイ時のアプリ切り替えはMission Controlが良い

## Macのデュアルディスプレイ時のアプリ切り替えはMission Controlが良い
Macのアプリケーション切り替えには何を使用していますか？
command + Tabのシュートカットキーを使用している方が多いかと思います。

しかし、最近デュアルディスプレイで作業するようになってMission Controlの良さに気がつきました。
Mission Controlはトラックパッドを３本指で上にドラッグすることで使用できます。

Mission Controlの特徴はそれぞれのディスプレイに開いているアプリの一覧が表示されるところです。
アプリの選択をクリックで行わなければならない点は不便ですが、デュアルディスプレイ環境においてはとても便利です。

ぜひ試してみてはいかがでしょうか。

## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
[Vue]boostrap-vueで用意したモーダル画面で、開くとともにオートフォーカスするサンプル

# 今回のコード
```vuejs:HTML側
<b-modal
    v-model="state.is_confirm_modal_open"
    title="モーダル画面"
    @shown="focusMyElement"
><input type="text" id="focusThis"></b-modal>
<button @click="open">スイッチ</button>
```

```javascript:JS側
let vm = new Vue({
  el: '#app',
  data:{
    return{
      state:{
        is_confirm_modal_open: false,
      }	
    }
  },
  methods: {
    open(){
      this.state.is_confirm_modal_open = true,
    },
    focusMyElement(){
      document.getElementById('focusThis').focus();
    },
});
```
ブラウザに「スイッチ」と書かれたボタンが表示される。
それを押すと、モーダル画面が出現し、画面内には入力欄が用意されている。
開いた時点で、その入力欄がフォーカスされている状態になっている。
# 解説
## モーダル画面表示まで
画面で「スイッチ」ボタンを押すと、

```vuejs:スイッチ
<button @click="open">スイッチ</button>
```
↑ここの@click(v-on:click)により、「openメソッド」が起動する。

```javascript:openメソッド
open(){
  this.state.is_confirm_modal_open = true,
},
```
↑JS側のここに「openメソッド」があって、「this.state.is_confirm_modal_open」をtrueに切り替える。

```javascript:dataの中
  data:{
    return{
      state:{
        is_confirm_modal_open: false,
      }	
    }
  },
```
↑「this.state.is_confirm_modal_open」は、JS側のdata内で初期値「false」で定義されている。
これがtrueに変えられることで、

```javascript:b-modalの中
<b-modal
    v-model="state.is_confirm_modal_open"
```
HTML側のb-model内の`v-model="state.is_confirm_modal_open"`がtrueとなり、
モーダルが表示される。
## inputタグへのフォーカス
モーダルが表示された際、

```vuejs:b-modalの中
@shown="focusMyElement"
```
により、「focusMyElementメソッド」が発火する。
（ちなみに、この@shownは@showとは違うディレクティブになるので注意）
このメソッドは、

```javascript:focusMyElementメソッド
focusMyElement(){
      document.getElementById('focusThis').focus();
},
```
このようになっていて、id="focusThis"の付いている要素にフォーカスされる、といった仕組み。
「find_or_create_by」と「create_or_find_by」 の違い #Railsのコードを読んでみた

# これ何

`create_or_find_by` と `find_or_create_by` の違いってなんだろうって深夜に思ったのでまとめました。

# まとめ

簡単にまとめると、createが先に実行されるかfindが先に実行されるかです。

## create_or_find_by
transactionに失敗したらfind_byする。

```ruby
def create_or_find_by(attributes, &block)
  transaction(requires_new: true) { create(attributes, &block) }
rescue ActiveRecord::RecordNotUnique
  find_by!(attributes)
end
```

[Railsのコード](https://github.com/rails/rails/blob/b1c917ee2fdaa452aeb52904db0d254d85285380/activerecord/lib/active_record/relation.rb#L209-L214)


## 違いについて
find_or_create_by でできないカラムもcreate_or_find_byではできてしまう可能性があります。

例えば、Userモデルがあったとします。`create_or_find_by` ではcreateが先に実行されるため2つ同じようなデータが作られます。
find_or_create_byでは、findが先に実行されるため、検索結果が返され、同じデータは2つ作られることはありません。

```ruby
User.create_or_find_by({name: 'geru')
User.create_or_find_by({name: 'geru')
User.count
# => 2
```

```ruby
User.find_or_create_by({name: 'geru')
User.find_or_create_by({name: 'geru')
User.count
# => 1
```

## 関連
### find_or_initialize_byとfind_or_create_byの違い
- [find_or_initialize_byとfind_or_create_byの違いとは？](https://qiita.com/sagaeminami/items/0a21738d018f475d63ae)
- [[Rails]find_or_create_byとfind_or_initialize_by](https://blog.hello-world.jp.net/ruby/1526/)
Google Cloud PlatformのAppEngineでPythonのHello Worldにたどり着く

# はじめに
GCPを初めて触る方がとにかくAppEngineを利用してPythonのHello Worldのチュートリアルまでたどり着くための手順を書きます。

#前提
Googleのアカウントを作成してGCPのトップページまでたどり着いていること


#手順




![スクリーンショット 2019-06-21 21.39.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439918/3db183da-d275-da08-07fb-a6493b05da0d.png)

- GCPで何かをするにはとにかくプロジェクトを作成する必要がありますのでプロジェクトを作成していきます。

- 「プロジェクトの選択」をクリックします。


![スクリーンショット 2019-06-21 21.39.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439918/4624f0b0-6a3a-3f3f-9fdf-cccbb56b8c86.png)

- プロジェクトの選択画面が表示されるので「新しいプロジェクト」をクリックします。


![スクリーンショット 2019-06-21 21.39.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439918/625a52fe-ccfe-e73b-5494-3958f8e7767f.png)

- プロジェクト名は自動で適当につけてくれるのでそのまま「作成」をクリックします。

![スクリーンショット 2019-06-21 21.40.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439918/fb12bb33-84b9-63f9-8804-9a2f94d3efba.png)

- プロジェクトの作成が完了するまで若干時間がかかるので完成するのを待つとダッシュボードが表示されます。ダッシュボードが表示されたらメニューから「App Engine」を選択します。

![スクリーンショット 2019-06-21 21.41.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439918/581bd020-82bb-cb4e-4672-efd0036ccbb0.png)

- ようこそが表示されるので「アプリケーションを作成」をクリックします。
- App Engineを作成する手順の途中でクレジットカード情報の入力を催促されます。クレジット番号はロボットでないことを確認するためだけで、勝手には請求しないと書いているので信じて素直に入力します。ですが、私は怖いので不要なプロジェクトは消しています。


![スクリーンショット 2019-06-21 21.41.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439918/90114626-9563-0935-42fb-9de8d6ede778.png)

- リージョンはどこでも良いのですが今回は日本のリージョンを選択しました。リージョンによって料金が微妙に異なることやリージョンまでの距離などを考えて選択すると良いようです。
- 「アプリを作成」をクリックします。

![スクリーンショット 2019-06-21 21.41.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439918/ba039c3b-fa96-426b-a6ec-a05a6f3463e7.png)

- Languageで「Python」を選択します。
- Environmentで「標準」を選択します。「標準」と「フレキシブル」の違いはいろいろあるようですが、無料枠に入っているのは「標準」なので選択しています。
- 「次へ」をクリックします。

![スクリーンショット 2019-06-21 21.41.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439918/7e8250ec-bf07-7831-cb4a-7e49a6706d11.png)

- 作成完了まで少し時間がかかるので待ちます。

![スクリーンショット 2019-06-21 21.43.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439918/7405202d-54ed-2f67-6dc8-283b544d5746.png)

- 完了してからメニューの「App Engine」を改めて選択すると「Hello World」が表示されるので「チュートリアルを始める」をクリックします。

![スクリーンショット 2019-06-21 21.43.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439918/f3f29624-d6b3-3ada-fd51-60b9a6717ec6.png)

- 言語がいくつか表示されるので「Python」をクリックします。

![スクリーンショット 2019-06-21 21.45.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439918/cd6c190e-6540-749d-67a6-3883ee475331.png)

- あとはチュートリアルが開始されてHello Worldまで導いてくれます。

![スクリーンショット 2019-06-21 22.31.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439918/01a2624c-4786-fc67-1009-2a10a98199ae.png)

- チュートリアルの最後まで行くとこうなります。
MAMP（MacOS）でPHPを表示する方法





ド初心者がPHPを始める際にぶつかるのが
どうしよ？HTMLみたいにGoogle Chrome使えへんやん！となるので




学習用メモとして、MAMPの設定方法をまとめておく。







まず、MAMPのインストール
英語版で日本語はない。。。

https://www.mamp.info/en/mamp/

このURLからMAC版をインストール

流石にインストール方法は割愛させて頂く。




次に解凍まで出来たら、エディターからこのファイルを開く
<img width="350" alt="MAMP1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443250/8ced360f-92b6-68a7-dcf2-0a0de55b1f35.png">

それがこれ
<img width="350" alt="MAMP2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443250/23452bf5-dd13-5065-e500-6a5af9f31a21.png">


とりあえず、お目当てのMAMP開く

<img width="350" alt="MAMP3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443250/07174c3c-51d5-7f24-a5b3-6a7b3026aab8.png">


多分この状態のはず
<img width="350" alt="MAMP4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443250/670738bc-e92a-aa48-33b2-150fa246980f.png">

ここまでで、めんどくさくなったので次回
C++からPythonをコールしてopencv Matを渡す

とりあえずC++からPythonの関数をCALLしてcv:Matを渡して戻り値を取るってのをした。
boost　pythonとかうまく行かなかなったので直に書いた。
やり方はとしてまずpythonの部分はこんな感じ

```python:py_test3.py
import cv2

def test4(mat):
	gray = cv2.cvtColor(mat, cv2.COLOR_BGR2GRAY)
	bgr = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
	return bgr
```
とりあえず入力をグレーにして次に３チャンネルにしてみた。
でこれをC++から呼ぶにはこうする

```cpp
#include "Python.h"
#include <opencv2/opencv.hpp>
#include <numpy/arrayobject.h>



int demo5(){
    Py_Initialize();
    import_array();
    //カレントディレクトリを探す範囲にいれる-------------------------
    PyObject *sys = PyImport_ImportModule("sys");
    PyObject *path = PyObject_GetAttrString(sys, "path");
    PyList_Append(path,PyUnicode_DecodeFSDefault("."));
    //---------------------------------------------------------------
    //探すファイルを指定-------------------------------------------
    PyObject *pName = PyUnicode_DecodeFSDefault("py_test3");
    PyObject *pModule = PyImport_Import(pName);
    Py_DECREF(pName);
    //---------------------------------------------------------------

    PyObject *pFunc = PyObject_GetAttrString(pModule, "test4");

    cv::Mat matdata=cv::imread("/home/kokawa2003/Pictures/daat3.png");
    int ch=matdata.channels();
    npy_intp dimensions[3] = {matdata.rows, matdata.cols, ch};
    int d=matdata.dims + 1;
    PyObject *pdemo2=PyArray_SimpleNewFromData(d,&dimensions[0], NPY_UINT8, matdata.data);

    //Tupleの作成    -----------------------------------------------
    PyObject *pArgs = PyTuple_New(1);//Tupleを新しく作成する
    PyTuple_SetItem(pArgs,0,pdemo2);//Tupleの0の位置にpdemo2を設定
    //---------------------------------------------------------------
    //RUN
    PyArrayObject *presult = (PyArrayObject *)PyObject_CallObject(pFunc, pArgs);


    int res1=PyArray_NDIM(presult);
    long rows = PyArray_SHAPE(presult)[0];
    long cols = PyArray_SHAPE(presult)[1];
    long res2 = PyArray_SHAPE(presult)[2];
    assert (res1 == 3 && res2 == 3);
    void *frame_data = PyArray_DATA(presult);


    cv::Mat cv_frame(rows, cols, CV_8UC3, frame_data);
    cv::imshow("win",cv_frame);

    Py_Finalize();
    return 0;
}
```
要点はtupleにすることぐらいか？
import_array();をコールしないとPyArray_SimpleNewFromDataが落ちる。（１日悩んだ）
あとpy_test3.pyは実行ファイルと同じところにおく。
リンクはqtならproに
CONFIG += link_pkgconfig
PKGCONFIG += python3
PKGCONFIG += opencv
CONFIG += no_keywords
を追記（言いたいのはpkgconfigでリンクしろってこと）
忘れないうちに書いた。
.html.erbのコメントアウトの仕方

みなさんは、コメントアウトしたいなという時、どのようにしていますか？
コメントアウトの仕方自体、何個かあるので、人によって様々だと思います。

html.erbで、コメントアウトしているのを見ると、<!--   -->を使っている人が多い印象を受けます。
以下の画像のように、ちゃんとコメントアウトはできます。
<img width="916" alt="スクリーンショット 2019-06-21 22.21.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436942/4c3a2e27-e1c3-5eb5-4be5-e8928dd74b66.png">

しかし、これだと、ブラウザでページのソースコードを表示すると、このコメントアウトも出てきてしまいます。

じゃあ、どうしたらいいのか、、、

**Rubyのコメントアウトを使いましょう！　**
１、<%#   コメントアウト　%>
2、<%= begin %>コメントアウト<%＝ end %>
３、<% if　false %>コメントアウト<% end %>

いろいろあると思うのですが、よく使われているのは、この３つかなと思います。

参照
https://ja.stackoverflow.com/questions/43321/html-erb%E3%81%A7%E3%81%AE%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%E3%82%A2%E3%82%A6%E3%83%88%E3%81%AE%E6%96%B9%E6%B3%95
GitHubのPull requests フロー

- githubにてプレリクエスをあげようとして、つまづいたのでおさらいします。

1. 変更前にブランチを作成　
2. github desktopにて変更をコミット！
3. ローカルリポジトリにpull
4. リモートリポジトリにpush
5. githubにてブランチをpull request
6. 変更許可が出ればmasterマージする
7. ブランチは削除
8. リモートリポジトリにて変更された、masterブランチをgithub desktopにてpull
9. リモートリポジトリの変更がローカルリポジトリに同期される！

ざっとこんな手順です。
※間違えてブランチを作成せずに変更をPushしてしまい、正しくpull requestできませんでした。
その際、一度変更部分を消してpushし変更前の状態に戻してから、ブランチを作成し直して、pull requestを行いました。　二度手間。。。気をつけます。

P.S.
## LGTM - "Looks Good To Me”
これは「Looks Good To Me」、つまり「自分的にはOKだよ」という意味です。 開発したシステムやコードのレビューをお願いされたり、資料のサマリを確認を行った際、特別問題がなかった場合に使います。
AtCoder Beginner Contest  096 C grid repainting

ABC　C問題
[grid repainting](https://atcoder.jp/contests/abc096/tasks/abc096_c)


```python
raw_input = input().split()[2:]
W = len(raw_input[0])
H = len(raw_input)
added_input = [row + '.' for row in raw_input] + ['.' * len(raw_input[0])]
for y in range(H):
    for x in range(W):
        if added_input[y][x] == '#' and added_input[y+1][x] \
        == added_input[y-1][x] == added_input[y][x+1] == added_input[y][x-1] == '.':
            print('NO')
            break
else:
    print('YES')
```


全てのマスに関して、そのマスが黒かつ上下左右のマスが全て白、というマスが1個でもあったら NO
1個もなかったらYES。
for~elseはあまり使わないから忘れてた。
HTMLのLABEL要素を.focus()でフォーカスしたかった

`tabindex="0"`を設定した`<label>`を`.focus()`してもフォーカスされない。調べてもクリティカルな回答がない…。から試行錯誤で至ったコードを晒します。

# 状況

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="html,result" data-user="horyu" data-slug-hash="Wqpryq" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Toggle-Button">
  <span>See the Pen <a href="https://codepen.io/horyu/pen/Wqpryq/">
  Toggle-Button</a> by horyu (<a href="https://codepen.io/horyu">@horyu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

見て読んでお分かりのように、こんな感じでトグルボタン用の`<label>`がありました。隣の`<button>`に `label.focus()` が仕組んであります。`document.activeElement ===`の後ろの`<span>`に現在フォーカスされているエレメントが表示されるようになっています。さて、ボタンをクリックしてみましょう。

・・・

**できるじゃん！！！！**となった方、そのブラウザは良いですね。私が常用する**[Waterfox](https://www.waterfox.net/)**では出来ませんでした。

# 実装
Waterfox 56.2.11 (64 ビット)でlabelをフォーカスさせる例が以下となります。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="horyu" data-slug-hash="ydMJYK" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Toggle-Button Focus">
  <span>See the Pen <a href="https://codepen.io/horyu/pen/ydMJYK/">
  Toggle-Button Focus</a> by horyu (<a href="https://codepen.io/horyu">@horyu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

フォーカスの実装は以下のようになりました。

```javascript
// 参考：
// https://stackoverflow.com/questions/2388164/set-focus-on-div-contenteditable-element#answer-16863913
const setFocus = (label) => {
  label.setAttribute('contentEditable', true);
  const range = document.createRange();
  range.setStart(label, 0);
  range.setEnd(label, 0);
  const sel = window.getSelection();
  sel.removeAllRanges();
  sel.addRange(range);
  label.setAttribute('contentEditable', false);
};
```

概説としてはこんな感じになります。

1. `label`に`contentEditable`属性を`true`にし、テキストを選択可能にする
2. `label`のみを含む`Range`オブジェクトを作る
3. ユーザーの選択範囲`Selection`オブジェクトの中身を作りたてのRange`オブジェクトだけにする
4. `label`の`contentEditable`属性を`false`にする
PCIスロットがあるマザーボード

#レガシーポートが必要なことがまだある
実験で使用する機器にはまだまだ古い規格のものが残っていて、その中で困るのがPCIボードで通信するようなもの。最近のパソコンだとPCI Expressならばたくさん載っているが、PCIが載っているものはほとんどないので、古いパソコンをいつまでも使い続けることになる。

#PCIスロットを持つマザーボードの探し方
色々とネットを調べていて、kakaku.comが比較的調べやすいことがわかった。マザーボードのメーカーのページを調べても、そもそも検索の選択肢にPCIがないことがほとんどで、PCIかと思ったらPCI-Eのことがほとんど。その点、kakaku.comならばちゃんとレガシーのPCIスロットがあるかないかを検索できる。
https://kakaku.com/specsearch/0540/
現時点（2019/6）で価格が付いているものだと以下の3つが比較的新しい。
https://kakaku.com/item/K0001044807/
https://kakaku.com/item/K0001044810/
https://kakaku.com/item/K0001044795/
いずれも2018/4発売とあるので、もう1年以上PCIスロットを持つマザーボードは作られていないことになるが、完全になくなったわけではなさそう。コメントを見るとそれなりに需要もあるみたい。全部ATXで、さすがにMicroATXのものはもうなさそう。パソコンを輸送して使うことが多いのでできれば小さい方が嬉しいんだけど、もう今探すのは難しいみたい。

#BTOサイト
自作PCは面倒なのでパソコンはBTOで買いたい。上記のマザーボードを使っているサイトは検索するだけでは見つからないので、頑張って一つずつBTOサイトの仕様を確認するしか見つける方法はなさそう。現時点でPCIスロットを持つパソコンを販売しているのはここしかなかった。
https://www.frontier-direct.jp

#産業用パソコン
あとは、「産業用PC」「レガシーポート」あたりで検索すると、同じようにPCI機器がまだあって更新できずにいる人はいるので、金さえ出せば手に入る。でも、CPUやメモリなどのスペックと価格が全く見合わないのでかなり買うのは躊躇する。

#そろそろPCIは完全に無くなるかもね
そろそろ無くなる可能性が高いので、1台くらいそこそこ最新のCPUが載っているパソコンを持っておかないと、数年後に困ることになりそう。どこかの時点で、もうPCIを使っているものは全て使うのをやめて新しい規格に移行すべきなんだろうけど、機器更新するならば多少高くてもレガシーポートを持っているパソコンを買うだけで済むならば安い、という状況はまだ続きそう。
distrolessで作るRust軽量コンテナ

https://github.com/GoogleContainerTools/distroless/tree/master/cc

をみてもRustとかD言語みたいなのに使えますよとしか書いてないし、記事がどこにもありません。果たしてどうしたものか。
  
  
　とりあえずhttps://techno-tanoc.github.io/posts/rust-multistage-build/ の記事を参考にさせてもらって

```
# select build image
FROM rust:1.34 as build

# create a new empty shell project
RUN USER=root cargo new --bin appname
WORKDIR /appname
# copy over your manifests
COPY ./Cargo.lock ./Cargo.lock
COPY ./Cargo.toml ./Cargo.toml

RUN \
    echo "fn main() {}" > src/main.rs && \
    cargo build --release


# this build step will cache your dependencies
RUN cargo build --release
RUN rm src/*.rs

# copy your source tree
COPY ./src ./src

# build for release
RUN rm ./target/release/deps/appname*
RUN cargo build --release

# our final base
FROM rust:1.34

# copy the build artifact from the build stage
COPY --from=build /appname/target/release/appname .

# set the startup command to run your binary
CMD ["./appname"]
```


のFROM rust:1.34をFROM gcr.io/distroless/ccに書き換えるだけ！

```
# select build image
FROM rust:1.34 as build

# create a new empty shell project
RUN USER=root cargo new --bin appname
WORKDIR /appname
# copy over your manifests
COPY ./Cargo.lock ./Cargo.lock
COPY ./Cargo.toml ./Cargo.toml

RUN \
    echo "fn main() {}" > src/main.rs && \
    cargo build --release


# this build step will cache your dependencies
RUN cargo build --release
RUN rm src/*.rs

# copy your source tree
COPY ./src ./src

# build for release
RUN rm ./target/release/deps/appname*
RUN cargo build --release

# our final base
FROM gcr.io/distroless/cc

# copy the build artifact from the build stage
COPY --from=build /appname/target/release/appname .

# set the startup command to run your binary
CMD ["./appname"]
```

イメージが3GBから22mbに減った！神！
簡易的なジョブの設計とplantumlのシーケンス図

DBの設計とかその辺がかなり大雑把ですが、基本的なジョブの設計をシーケンス図に起こしてみました。

自分のメモ用でもありますが、参考になれば幸いです。

### 画像
![job sequence.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107536/10214806-1dc6-4fe9-23b8-7de74f6e71f9.png)

### コード
```plantuml
@startuml "job sequence"
title "簡易版ジョブ設計"
Actor "ユーザー" as U

participant "ロードバランサー" as LB

box "サーバー1号機" #LightGreen
	participant "1号機アプリ" as 1A 
    database "1号機DB" as 1DB
    Actor "1号機ワーカー" as 1W
end box


box "サーバー2号機" #LightBlue
    participant "2号機アプリ" as 2A
    database "2号機DB" as 2DB
    Actor "2号機ワーカー" as 2W
end box

U -> LB: 非同期処理リクエスト
LB -> 1A: 非同期処理リクエスト

alt 同一のジョブは登録されていない
	1A -> 1DB: ジョブレコード登録
	1A -> LB: 201
	LB -> U: 201
else 同一のジョブが登録されている
    alt ジョブステータスがsuccessもしくはfailedで完了している
	    1A -> 1DB: ジョブレコード登録
		1A -> LB: 201
		LB -> U: 201
	else ジョブステータスがwaitingもしくはrunningで未完了
	    1A -> LB: 重複なので400系で返す
		LB -> U: 重複なので400系で返す
	end
end

loop ジョブレコード登録確認ポーリング
    1W --> 1DB: ジョブレコード取得
	alt ジョブが登録されている
	    1DB --> 1W: ジョブレコード
	    1W --> 1W: ジョブ実行
	end
end

loop ジョブレコード登録確認ポーリング
    2W --> 2DB: ジョブレコード取得
	alt ジョブが登録されている
	    2DB --> 2W: ジョブレコード
	    2W --> 2W: ジョブ実行
	end
end
@enduml
```
AWS CloudFrontの配信元のファイル(S3)が更新されたら自動的にキャッシュをクリアする仕組みを作る

# こまった事
こんな感じのアプリ構成で
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265300/52a2a434-21a8-41eb-a8ae-aa600acdf01c.png)
CloudFront経由でS3に格納したコンテンツを配信する場合、
CloudFrontのCloudFrontエッジロケーション(キャッシュサーバー)からコンテンツをクライアントに配信する為、
クライアントに中々、最新のコンテンツが行き渡らない事象がしばしば発生します。

# CloudFrontにキャッシュを残さないようにすれば？
設定次第でそれもできますが、
それだとCloudFrontの意味ないです。
それと毎回、配信元のS3にアクセスしに行く事になるのでS3のアクセス数が増加してしまいます。(お金がかかってしまう)

# 解決方法
CloudFrontの配信元のファイル(S3)が更新されたら自動的にCloudFrontのキャッシュをクリア(Invalidation)してあげる仕組みを作ります。

配信するファイルにもクライアントにキャッシュさせないようにメタ情報を付与します。
方法はこちらの記事を参考に
https://qiita.com/anchoor/items/2dc6ab8347c940ea4648

# その仕組みどんな風に作るの？
配信元のファイル(S3)の更新をトリガーとして実行するLambdaFunctionを作成します。
そのLambdaFunction内でCloudFrontのキャッシュをクリア(Invalidation)してあげます。

# このように作るのだ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265300/acb4cd00-3e01-11f4-89df-e7bb5efaf051.png)
S3のオブジェクトの更新をトリガーとして発火する
LambdaFunctionを作成します。

※詳細は、こちらの記事で記載しています。
[AWS S3のオブジェクトの更新をトリガーとして発火する LambdaFunctionを作成する](https://qiita.com/Shi-nakaya/items/cc842447f44ec16e6d10)

# LambdaFunctionの中身
今回はGoで書きました。
AWSのAPI(AWS SDK for Go)にCloudFrontののキャッシュをクリア(Invalidation)するAPIがあるので
そいつをキックしてあげるだけです。
https://docs.aws.amazon.com/sdk-for-go/api/service/cloudfront/#CloudFront.CreateInvalidation

※詳細は、こちらの記事で記載しています。
[AWS S3バケット名からCloufFrontのキャッシュをクリア(CreateInvalidation)するAPIをコールする](https://qiita.com/Shi-nakaya/items/32f8d049a0262e29efe3)
# 実装に苦労した点
ロール周りや、パーミッションの問題で実際に動作させるまで時間がかかりました。
これはエラーメッセージが丁寧に出力されるので一つ一つ対応していけば問題ないのですが、

S3オブジェクトの更新トリガーについはそうもいきませんでした。
私はS3バケットの中全てのオブジェクトを更新チェック対象としている為、
オブジェクト更新したら更新した数のオブジェクトの数分、発火してしまいます。

つまり、対象のS3バケットの中身20個のファイルを格納、更新したら20回発火します。

# 苦労した点の対応
Goの実装内でAPI(CloudFront.CreateInvalidation)実行時に一意なIDを指定します。
そのIDには現在年月日時分秒を指定していましたが、
それを現在年月日時分を指定する事で1分に一回しかCreateInvalidationを実行しないようにしました。イベント発火の最初の1回のみ実行され、後の発火は全てIDが重複している為、エラーとなりますので1分に1回しか実行されません。

よって、S3バケットの中身20個のファイルを格納、更新したら20回発火しますが、1回だけ正常にCreateInvalidationを実行し、19回はエラーとなります。

# 所感
これでクライアントは常にCloudFrontエッジロケーション(キャッシュサーバー)を見に行き、見にいく先のCloudFrontエッジロケーション(キャッシュサーバー)は最新のコンテンツが行き渡っています。

CloudFront標準の機能で用意してくれててもいいような気がする機能でした。

この機能を実装した直後にこんな記事が...
「【朗報】Amazon CloudFrontのキャッシュ削除(Invalidation)が速くなりました【5秒で90%】」
https://dev.classmethod.jp/cloud/aws/cloudfront-fast-invalidation/

※構成図はこちらの記事を参考にして作成しました。
https://qiita.com/nave-m/items/68425f476b254a1a47b0
TemplateDoesNotExist atとなった時の対応

#はじめに

Djangoを使って、WEBアプリを作っていた時に遭遇する
![スクリーンショット 2019-06-21 18.50.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343721/010cbd38-baac-704f-2297-3d449dca3112.png)

このエラー、そう
TemplateDoesNotExist at ***
今回はその対処法を書いておく

##ソース
```blog/urls.py
from django.conf.urls import url

from . import views

app_name = 'blog'
urlpatterns = [
    url(r'^$', views.index,name='index'),
]
```

```blog/views.py
from django.shortcuts import render

# Create your views here.
def index(request):
    return render(request, 'blog/index.html')
```

していることは何の難しいことはない。
ただ、~/blogにアクセスした時にindex.htmlを表示してね。って書いただけだ。

ここで

```
$python manage.py runserver
```

して
http://127.0.0.1:8000/blog
にアクセスすると上で紹介した画像のように
エラー画面が表示されTemplateDoesNotExist at blogとなってしまうのだ。

ちなみにフォルダ構成はこんな感じ

<img width="1133" alt="スクリーンショット 2019-06-21 21.05.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343721/7f48f2cd-ab03-ff38-694f-e7ee527ebce4.png">


##原因
mysite/setting.pyでモデルを有効にしてなかった。


```mysite/setting.py

INSTALLED_APPS = [
    'polls.apps.PollsConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
     # この部分が抜けていた
    'blog.apps.BlogConfig',
]
```

追加して、

```
$python manage.py runserver
```

して、
http://127.0.0.1:8000/blog
にアクセスしてみると

<img width="1223" alt="スクリーンショット 2019-06-21 20.59.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343721/1862e383-2004-2a89-3789-c50d71ac0819.png">

表示できたー！！

よかったよかった😌


#最後に

解決してみると呆気に取られるほど簡単ですが、一度深みにはまってしまうと
なかなか、抜け出せないですよね。

この記事がそういった方の他受け助けになれば、幸いです。
Lubuntuでxrdpを使う

#前書きと参考リンク
表記の通り。LinuxのGUIをリモートで使いたい。使用環境はホストがLinuxでLubuntuを使っている。クライアントは色々。MacOSXだった、Linuxだったり、Windowsだったり。
以前だとVNCを使うのが便利だったんだけど、どうも18.04あたりになってubuntu標準のVNC環境がlubuntuだと使えなくなった。どこかに情報があったはず、と調べてみたら、自分で書いてあった。
https://qiita.com/niikura/items/8ea4a45f178ff5587ae3
その後しばらく使用することもなかったので放置していたのだが、最近また必要になって調べてみたところ、Windowsのリモートデスクトップで接続するのがよいらしい。
https://lubtech.geo.jp/2018-08-02/?p=7507
ポイントは「RDP 用 LXDE 導入」と書いてあるところで、これをやらないと接続した時に真っ黒な画面が表示される。

#RDPとVNCは挙動が結構違う
VNCの場合は基本的にホストの画面を共有するので、ホストのマシンで作業している人がいるのにリモートでも何かやろうとするとコントロール権の取り合いが発生する。実験では離れたところから現場で何の作業をしているかわかるのでむしろ便利だったのだが、RDPで接続した場合は新しいセッションが動くので、画面の共有ができない。
ちなみにWindowsのRDPの場合は作業できるのは排他的で、リモートからRDPで接続するとホストの方は操作できなくなる。これはこれでわかりやすいので良い。
排他的でも共有でもなく独立に作業できてしまうのは、共有のアカウントで実験をする場合は困る。やっぱりVNCの方がいいなぁ、と思いながら、どうするかはしばらく考えることにする。

#追記
どうもRDPの設定でVNCをバックエンド？に使うとできるらしい。
https://askubuntu.com/questions/235905/use-xrdp-to-connect-to-desktop-session
https://forums.ubuntulinux.jp/viewtopic.php?id=13257

ここでまたLubuntuではvinoが使えない問題が出てくる。困ったな。
[TypeScript 3.5] 型が指定されていない場合の型推論の仕様変更について

今まで空のオブジェクト`{}`として推論されていたのですが、TypeScript3.5から導入された`unknown`が推論に使用されるようになりました。
タイプ定義が無いライブラリ等を使用している場合、今まで通ってたコンパイルが結構通らなくなる可能性が高いです。
私もかなりの数のエラーが発生しました。

## `unknown`型について

`{}`と`unknown`は似ておりますが、以下の違いがあります。

- `{}`は文字列でインデックス参照ができます(例: `k["foo"]`)が、`unknown`はできません
- `{}`は`null`や`undefined`ではないとみなされるが、`unknown`は`null`や`undefined`の可能性があります
- `{}`はオブジェクトに代入可能ですが、`unknown`はできません

## 対策

例として、型定義がないライブラリのフック関数等を定義する場合を考えます。


```ts
// 今まで型が未定義の場合は以下のように`{}`と推論されていた
// type HookType = (args: {}) => void;
// 3.5からは`unknown`型と推論される
type HookType = (args: unknown) => void;

const hook: HookType = args => {
  // error: Object is of type 'unknown'.
  console.log(args.hoge);
};
```

対策としてはまず、無理やりキャストする方法があります。

```ts
const hook: HookType = args => {
  const castedArgs = args as { hoge: any };
  // ok
  console.log(typedArgs.hoge)
}
```

ただ、無理やりキャストするよりも`User-Defined Type Guards`を使いましょう。
https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards

返り値の型に`引数名 is 型`のように指定することでタイプガードを定義することができます。
これを使って条件式を書くことで、型の推論を限定する(narrow)ことができます。

```ts
const hasHogeProperty(args: any): args is { hoge: any } => {
  if (!data) return false;
  if (data.hoge) {
    return true;
  }

  return false;
}

const hook: HookType = args => {
  if (hasHogeProperty(args)) {
    // ok
    console.log(args.hoge)
  }
}
```