OmniAICreator/Qiita-1.07M huggingface dataset:
今日から開発で使えるサクラエディタ機能

##インフラエンジニアで仕事してる時にサクラエディタにお世話になってたけど、開発でコード書いてる時も使えそうなのでメモ。（2019/2/22作成）


###～～目次～～
**・タブ揃えで使える、正規表現を使って特定の行にタブを入れる**

**・サクラエディタの入手方法**


###・タブ揃えで使える、正規表現を使って特定の行にタブを入れる

例えば、こんな風にコードを書いてしまって

  if(!empty($_POST)) {
  \$user = \$_POST['userName'];
  \$pass = \$_POST['passwordName'];

変数の\$のところに頭タブを忘れたとして。2行なら良いけど、これが何十行ってなると面倒でないですか？そこでサクラエディタ。

①サクラエディタを起動して、
<img width="582" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/321507/e6e29b31-2490-0e2a-9659-ea609c58a925.png">

②コード貼り付けて、
<img width="263" alt="キャプチャ1.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/321507/603709e0-19db-c764-b8ce-2a70792129cd.png">

③対象の行を選択して、
<img width="223" alt="キャプチャ2.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/321507/495f3d17-1eb2-20bd-2247-8de74f36c7d8.png">

④「Ctrl + r」キーを押して、置換機能を起動。（もしくはタブの「検索」→「置換」を選択）置換メニューが立ち上がります。
<img width="581" alt="キャプチャ3.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/321507/1d6ed81d-58b1-60ef-47a5-0f5a0cf3dc47.png">

⑤「置換前」に「^」、「置換後」に「\t」を入れる。あとは、真ん中の方にある「正規表現（E）」にチェックが入っていることを確認。
<img width="377" alt="キャプチャ4.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/321507/61abfbea-2180-a4d5-2bf1-c039404c7576.png">

⑥「すべて置換（A）」を選択。置換完了を確認。
<img width="554" alt="キャプチャ5.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/321507/ce574bd8-06e0-97ec-6712-b5645b5d81bd.png">

これで置換完了です。ちなみに入力した正規表現の意味は、
^　＝　行頭
\t　＝　タブ
です。
 やったことは、「行頭にタブを挿入」って意味です。「\t」の数増やせばその分だけタブ増やせるので何個忘れた時でも対応できます。



###・サクラエディタの入手方法
無料で調べればすぐ出てきます。
下記で落とせると思います。

https://sakura-editor.github.io/download.html

他にもgrep検索、矩形とか便利な機能があるので時間ある時にまた投稿しようと思います。
【開発環境】右も左もわからないAWS初心者のための導入の仕方からECSを使ってEC2にファイルをぶち込んでぶっ壊すまで。

##まずはAWSのアカウントを作成

https://aws.amazon.com/jp/

これは難なく完了。次AWS CLIのインストール。

とにかくよくわからないからページをスクロールして見つけたコマンドを実行。

```
aws ec2 describe-instances
```
当然のごとく動かない。のでもう少しページを調べてみます。

Mac および Linux
Python 2.6.5 以降が必要です。

##pip を使ってインストールします。

見逃してました。

```

curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py

sudo python get-pip.py

sudo pip install awscli --upgrade --ignore-installed six

aws configure

```

そしたらこんなんが順番に出てくる

```
AWS Access Key ID [None]: 
AWS Secret Access Key [None]: 
Default region name [None]: 
Default output format [None]: 
```

でIDとかなんやらを入れろってなってるけど、アクセスキー？シークレットアクセスキー？ってなったので、ぐぐってみる。そして見つけました。
[参考：AWSアクセスキーIDとシークレットアクセスキーを取得する方法](https://www.multcloud.com/jp/tutorials/s3-key.html)

どうやらログインして取得する必要があるようです。

#####各項目の意味合い

- AWS Access Key ID [None]: "アクセスキーID"をコピー
- AWS Secret Access Key [None]: "シークレットアクセスキー"をコピー
- Default region name [None]: "ap-northeast-1"を入力
-  (これがTokyoリージョンらしいので日本国内ならこれ)
- Default output format [None]: "text","JSON","table"のどれかを指定(とりあえずtextで指定しました。)

[参考：AWS CLIのセットアップ](https://qiita.com/n0bisuke/items/1ea245318283fa118f4a)

設定の確認

```
aws configure list
```

最新版のインストーラーをダウンロードし再インストールする。

```
sudo pip install -U awscli
```

[参考：AWS CLIのインストール](https://qiita.com/yuyj109/items/3163a84480da4c8f402c)

「AWS ECS」を使ってファイルをAWSにアップする

Dockerのダウンロードも忘れずに
[Dokerの公式サイト](https://www.docker.com/)
アカウント登録 → ダウンロード
※WiFi環境でやらないと時間がかかる。テザリングだと早くて１時間ぐらい

IMS　権限の設定
プログラムからのアクセスにチェックをしないとCLIでアクセスできない


```
aws ecr get-login --no-include-email --region us-east-2
```

を打つとコマンドラインに文字列がかえってくる

その文字を「amazonaws.com」までをコピーして、貼り付け→Enter
Login Succsesstedが返って来ればOK
pushできる準備が整う

下記の１から順番に実行

```
1. docker build -t php .

2. docker tag php:latest 510930968738.dkr.ecr.us-east-2.amazonaws.com/php:latest

3. docker push 510930968738.dkr.ecr.us-east-2.amazonaws.com/php:latest
```

全部実行したらAWSのリポジトリにファイルがアップロードされる

###クラスターとタスクの定義をします

ECSの機能を使ってEC2のサーバーを立ち上げる時に

#### クラスターの設定
EC2 Linax ネットワーキングをせんたく
※ネットワーキングのみだとルート権限のあるものを制御できない
→自分でEC2を管理しなくてもいい

※定義できないエラーが出たら先にタスクを作成する

#### タスクの作成

タスクを作成してからクラスターを定義したらできました。
ちなみにサーバーやクラスターの管理をしないでコンテナを実行できる仕組み「[ファーゲート](https://aws.amazon.com/jp/fargate/)」もある


EC2 インスタンスタイプはその時に応じて、今回の場合そんなに大きなものはいらないので「t2micro」でOK。

キーペアは重要
「新しいキーペアは EC2 コンソールで作成できます」から遷移して作成

タスクの定義をします。

ECSはEC2を自動的に立ち上げてコンテナを入れる


sshしたい場合は、接続を押して「例」にかいてあるところのコードを貼り付けて実行します。
けどエラーになる場合があるののでsshのポートの設定を「マイIP」に変更してください。

sshのportが空いてないのsshのポートの設定を「マイIP」にする

### sshできない!
ファーゲートで設定で行なった場合は中のログとか全部みれないのが欠点。
サーバーレスの開発を行なっている場合はgoodです。
ログを見たい場合は、自分でログをはくプログラムを書かないといけない。


### インスタンスの消し方
ESCから立ち上げたEC2は削除できない
ECSの考え方は指定したインスタンスは常に立ち上げるからインスタンスを消してもダメ
クラスターを消す必要がある
クラスターの操作画面から「クラスターの削除」を選択すると削除できます。

※「ECS CLI」　ECS専用のCLIもある

##まとめ
かなり簡単に全く同じ開発環境がいくつも作れて便利ではないかと感じました。
AWSの管理画面の操作がそれなりに複雑な気もするのではじめのうちは何度も作ってはぶっ壊すかもしれませんがこのような開発環境の構築の仕方もあるのだと勉強になりました。
ガード節を使って読みやすいコードを書こう

# ガード節とは

例えば以下のように階層の深い`if`条件分岐があったとします。

```php
function hoge($a, $b, $c) {
  if ($a === 'a') {
    if ($b === 'b') {
      if ($c === 'c') {
        return 'is c';
      } else {
        return 'not c';
      }
    } else {
      return 'not b';
    }
  } else {
    return 'not a';
  }
}
```

関数`hoge`が何を返すか、簡単には理解できないと思います。
この関数はガード節を使って、以下のように書くことができます。

```php
function hoge($a, $b, $c) {
  if ($a !== 'a') {
    return 'not a';
  }
  if ($b !== 'b') {
    return 'not b';
  }
  if ($c !== 'c') {
    return 'not c';
  }
  return 'is c';
}
```

条件を逆転させてreturnしているだけなのですが、かなり読みやすくなったのではないでしょうか。
実際のアプリケーションのコードはもっと複雑だと思いますが、エラー処理を早めにreturnするなどして、比較的簡単にリファクタリングできるので、皆さんもぜひやってみてください。
【PHP】変数の内容を出力する関数いろいろ

公式サイトには「変数操作　関数」として紹介されています。

> [変数操作 関数](http://php.net/manual/ja/ref.var.php)

# var_dump
変数に関する情報をダンプします。変数の型も分かるので、重宝してます。

出力した変数ごとに改行されるので、情報量は多いですが見やすいです。
一度に複数の引数を指定することも可能です。

> [php.net〜var_dump](http://php.net/manual/ja/function.var-dump.php)

```php
<?php
$test_str  = 'test';
$test_int  = 1;
$test_bool = true;

$test_array = array(
    'test' => array(1, '2', 'aaa', false, 'true')
);

var_dump($test_str);
// 出力結果：string(4) "test"

var_dump($test_int);
// 出力結果：int(1)

var_dump($test_bool);
// 出力結果：bool(true)

var_dump($test_array);
/*
出力結果
array(1) {
  ["test"]=>
  array(5) {
    [0]=>
    int(1)
    [1]=>
    string(1) "2"
    [2]=>
    string(3) "aaa"
    [3]=>
    bool(false)
    [4]=>
    string(4) "true"
  }
}
*/

/*
この書き方も使えます！
var_dump($test_str, $test_int, $test_bool, $test_array);
*/
```

# print_r
指定した変数に関する情報を解りやすく出力します。var_dumpより情報量は少ないですが、レイアウトが見やすいです。

自動的に改行されないので、連続して複数の変数を出力する場合は``echo "\n";``を使用した方が良いかもしれません。

一度に複数の変数を指定することはできません。

> [php.net〜print_r](http://php.net/manual/ja/function.print-r.php)


```php
<?php
$test_str  = 'test';
$test_int  = 1;
$test_bool = true;

$test_array = array(
    'test' => array(1, '2', 'aaa', false, 'true')
);

print_r($test_str);
echo "\n";
// 出力結果：test

print_r($test_int);
echo "\n";
// 出力結果：1

print_r($test_bool);
echo "\n";
// 出力結果：1

print_r($test_array);
echo "\n";
/*
出力結果
Array
(
    [test] => Array
        (
            [0] => 1
            [1] => 2
            [2] => aaa
            [3] => 
            [4] => true
        )

)
*/
```

# var_export
変数の文字列表現を出力、または返します。返される表現は有効なPHPコードです。（そのまま変数に代入することができます。）

あまり使いませんが・・・

こちらも自動的に改行されないので、連続して複数の変数を出力する場合は``echo "\n";``を使用した方が見やすいです。

一度に複数の変数を指定することはできません。


> [php.net〜var_export](http://php.net/manual/ja/function.var-export.php)

```php
<?php
$test_str  = 'test';
$test_int  = 1;
$test_bool = true;

$test_array = array(
    'test' => array(1, '2', 'aaa', false, 'true')
);

var_export($test_str);
echo "\n";
// 出力結果：'test'

var_export($test_int);
echo "\n";
// 出力結果：1

var_export($test_bool);
echo "\n";
// 出力結果：true

var_export($test_array);
/*
出力結果
array (
  'test' => 
  array (
    0 => 1,
    1 => '2',
    2 => 'aaa',
    3 => false,
    4 => 'true',
  ),
)
*/
```
[Laravel] エンドポイントが自動で変わるHeroku Redisに適応する

こちらの記事に書いてありますが、HerokuのRedisはたまにアップデートされた節にHostとポートが変わってしまうことがあります。
https://qiita.com/usagizmo/items/7c5a338e339ebffd7eba

アップデートされると、自動で環境変数`REDIS_URL`の値を書き換えますが、
Laravelは通常、HostやPostなどをわけて書くため、アップデートされるとある日突然Redisつながらなくなります。

そこで、Herokuが面倒見てくれる`REDIS_URL`に合わせて、Redisの接続方法を変更しましょう！

configの変更
---

まず、こちらがデフォルトのRedisのconfig

```php:config/database.php
    'redis' => [

        'client' => 'predis',

        'default' => [
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', 6379),
            'database' => env('REDIS_DB', 0),
        ],

        'cache' => [
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', 6379),
            'database' => env('REDIS_CACHE_DB', 1),
        ],

    ],
```

`REDIS_URL`をパースする方法に変更します

```php:config/database.php
    'redis' => [

        'client' => 'predis',

        'default' => [
            'host' => parse_url(env('REDIS_URL'), PHP_URL_HOST),
            'password' => parse_url(env('REDIS_URL'), PHP_URL_PASS),
            'port' => parse_url(env('REDIS_URL'), PHP_URL_PORT),
            'database' => env('REDIS_DB', 0),
        ],

        'cache' => [
            'host' => parse_url(env('REDIS_URL'), PHP_URL_HOST),
            'password' => parse_url(env('REDIS_URL'), PHP_URL_PASS),
            'port' => parse_url(env('REDIS_URL'), PHP_URL_PORT),
            'database' => env('REDIS_CACHE_DB', 1),
        ],

    ],
```

環境変数
---

HostやPasswordと分けてた環境変数を`REDIS_URL`にまとめます。
HerokuではRedisをアドオンすると自動で作られます。

ローカルでは以下のように設定します

```
REDIS_URL=redis://[HOST]:[PORT]
```

ユーザやパスワードの設定が必要ならこうなります

```
REDIS_URL=redis://[USER]:[PASSWORD]@[HOST]:[PORT]
```
vueでmomentを使うときにはまったこと..

#この記事では..
日付の操作をmoment.jsで行っています.ほかにもあるけど,最初に覚えてものだし使い続けてます.
ただ今回vueの開発中にいつも通り使っていたら,更新されない???ってことが起こったので,まとめておきます.

#事象
ただ日付を表示してボタンで次の日へとかをできるようにするだけのもの.
![image.png](https://qiita-image-store.s3.amazonaws.com/0/283053/e643b101-a325-27c9-ed16-d83bafe5c5be.png)

```vuejs:source
<template>
  <div>
    <div>Date: {{displayDate}}</div>
    <div><button @click="addDay" style="color:blue">1day</button></div>
  </div>
</template>
<script>
import moment from 'moment';
export default {
  name: 'Home',
  data() {
    return {
      date: moment(),
    };
  },
  methods: {
    addDay: function() {
      this.date.add(1, 'day');
    },
  },
  computed: {
    displayDate: function() {
      return this.date.format('YYYY/MM/DD');
    },
  },
};
</script>
```

この状態で1dayをクリックすると,変化がない???
そこでdevtoolで見ると,変化している.なぜ???
![image.png](https://qiita-image-store.s3.amazonaws.com/0/283053/bf019b42-6a50-e477-0980-0875b7463b96.png)

#解決策

##クローンしてあげる.

オブジェトへの新規追加などは更新されないっていうのは見たことあったけど..新規でないんだけどなぁ..と思い調べても同様な記事がありませんでした.momentを複製してあげると表示ができます.(無理やり感ありますが..)

```vuejs:source
<script>
  methods: {
    addDay: function() {
      //this.date.add(1, 'day');
      this.date = this.date.clone().add(1, 'day');
    },
  },
</script>
```

##forceUpdateしてあげる.
vueのforceUpdateでも更新することができました.
https://jp.vuejs.org/v2/api/#vm-forceUpdate
ただし,computedが聞かないので,html部分に{{date.format('YYYY/MM/DD')}}と書く必要がありました.

##まだまだ..勉強中..:bow_tone1:
私は今回はクローンしてあげることにしました.
何かほかのアイディアがあればぜひコメントいただけると嬉しいです.
さまざま分布のQQプロットを描画してみる

https://qiita.com/kenmatsu4/items/59605dc745707e8701e0
http://www.ie-kau.net/entry/2016/03/10/%E6%AD%A3%E8%A6%8F%E5%88%86%E5%B8%83%E3%81%8B%E3%81%A9%E3%81%86%E3%81%8B%E3%82%92%E8%A6%8B%E6%A5%B5%E3%82%81%E3%82%8B3%E3%81%A4%E3%81%AE%E3%82%B9%E3%83%86%E3%83%83%E3%83%97%EF%BC%88Python%EF%BC%89

上記のURLにも載っていますが、いくつか載せてみます。

```python
import numpy as np 
import scipy.stats as stats
import matplotlib.pyplot as plt

def qqplot(dist):
    plt.hist(dist, bins=30)
    plt.show()
    stats.probplot(dist, dist="norm", plot=plt)
    plt.show()
```

```python

# 正規分布
qqplot(np.random.randn(10000))
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/177689/7f7d5774-ce12-6ad6-00aa-9886c09eae1f.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/177689/79aaa875-dff9-682f-c310-70d3dc3a577b.png)

```python
# 一様分布
qqplot(np.random.rand(10000))
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/177689/12e3e8a6-7f80-c279-f233-cd44235ae916.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/177689/ea22ae23-97c4-f6f9-9cc9-cc19bd0fd3b8.png)

```python
# 混合ガウス分布1
dist = [np.random.normal(-3,1) if np.random.randint(2) else np.random.normal(3,1) for _ in range(10000)]
qqplot(dist)
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/177689/852daea8-1a81-1b41-e73b-9dffc5483a74.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/177689/2c75561c-3dbc-c104-0d41-37b6a9cbeaea.png)

```python
# 混合ガウス分布2
dist = [np.random.normal(-5,1) if np.random.randint(3) 
   else np.random.normal(3,5) for _ in range(10000)]
qqplot(dist)
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/177689/97603855-66d7-7dd3-76a3-5864ae7b04f1.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/177689/763eeae9-af22-a1dc-83f1-a7a57cf0690b.png)

```python
# Beta分布
qqplot(np.random.beta(0.5,0.5,10000))
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/177689/d2f5a029-7c7c-399e-bf6f-6616e2d75185.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/177689/38c2a160-167a-4433-76c6-4514d991c7c7.png)


```python
#t分布
qqplot(stats.t.rvs(5, size=100000))
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/177689/2415acdb-74ba-2151-4cb0-08017363ca41.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/177689/e59c971e-866d-730d-1f35-f448a9e52ccb.png)

```python
# 対数正規分布
qqplot(np.exp(np.random.normal(100,0.5,10000)))
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/177689/b4c6a8c1-99d5-71f4-3492-5ef469f7241c.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/177689/9baad132-9305-1efc-8a41-0f1c9cab5ab1.png)

裾の重いt分布のプロットが面白いですね。
IoTデバイスのスマートコントラクト登録・認証について考える

####リアルなデバイスの認証をスマートコントラクトでやる場合についてのシミュレーション（議論用）
思いついたことあったらコメントお願いします。

次の場合を想定する。

目的：無人ホテル（ルームシェア）を作る

条件：
・シーツ・布ものは各自持参。あるのは洗わなくて良い物だけ。
・API・P2Pを受け付けられる鍵がドアにかかっている
・各デバイス（テレビ・冷蔵庫・ボイラーコントロール等）は全てラズベリーパイで制御。
鍵認証で使えるようになる
・入ってくる人間は一切の現金を持たず、持っているのはスマホとEthereumのアカウントと10ETHだけ。

##問題１：入室＆デバイスアクティベート

実装：１つの部屋に１つNFTを割当

・NFTを持っていたら次のフローで解錠認証を許す
![PCS のコピー.jpg](https://qiita-image-store.s3.amazonaws.com/0/230572/cdd66bf8-acf3-4964-958e-0b50ffa05b93.jpeg)



・デバイスについても同様

・NFTは時間失効し、新規に発行され買い取られる（＝入室支払い）

##問題２:デバイスのビザンチン故障あるいは盗聴対策
最悪な状況：無人であるため、デバイスのラズパイの中を勝手にオーバーライドされて変なソフトを走らされる
→　コントラクトから監視する必要性

###実装１：
スマホのアプリで、スマホと繋いだラズパイの中身を可視化する機能を実装。中のソフトのバイナリからのハッシュ値がスマコンに登録されたハッシュと違ったらアラートを出す。（ソフト置き換え検知）
→入室後まず、ラズパイ全てをスマホにつないでチェック(めんどくさい)
→つなぐ際のセキュリティは？？？

→サブ実装として（部屋番号→デバイス名→バイナリハッシュ）のテーブルが必要
→登録していないデバイスへの通信制限＋電力供給のストップの必要

###実装２：　
実装１がめんどいのは各デバイスラズパイを束ねる中央デバイスがないから
→中央デバイスを設置、ここで１つのコントロールソフトウェアが全部のラズパイを監視
→この１つのソフトのバイナリハッシュだけスマホでチェックすれば、あとはコントロールソフトが勝手にスマコンのテーブルと下位ラズパイのソフトのバイナリハッシュを比較し、問題があればアラートを出す。
→さらに、登録していないデバイスの排除・アラートも自動で出来る

##問題３：たまに掃除しろ
→みんな頑張って
→たぶん、最後の奴を特定できるからKYCしてれば汚いやつ特定可能
c言語

C++ばかりでC言語がまともに書けないのはアレなので、
fopen
fopen関数はファイルを開きそのポインタを取得する関数です。
書式は
FILE *fopen(const char *filename,const char *mode);
モードには色々ある。rは読み込む専用
サンプルコード

```
#include <stdio.h>

int main(void)
{

	FILE *fp;
	char buf[50];

	fp = fopen("test.txt","r");

	fgets(buf,30,fp);

	puts(buf);

	fclose(fp);//fopenの戻り値として取得したファイルポインタを引数に渡してクローズしている。	
	return 0;
}
```
test.txtには
test,123,456という文字列が書き込まれているのでtestが表示される

char*filename,const char
エラー時はNULLが返ります。
fgets

char *fgets(char *s, int n, FILE *fp);

第一引数は文字配列のポインタ
第二引数は一行の最大文字数
第三引数はファイルポインタ

をそれぞれ指定する。
第二引数の最大文字数には末尾の\0も含まれるので、
実際に取得できる文字数は「最大文字数-1」になる。

サンプルコード

```
#include <stdio.h>

int main(void)
{

	FILE *fp;
	char buf[50];

	fp = fopen("test.txt","r");

	fgets(buf,30,fp);

	puts(buf);

	fclose(fp);
		
	return 0;
}
```
aiueoと入力するとaiueoと返ってくる

一年の各月の日数を表示するプログラム

```
#include<stdio.h>
#include<stdlib.h>
int main() {
	int seireki, nissu;
	char line[20];
	printf("西暦を入力:");
	fgets(line, sizeof(line), stdin);
	seireki = atoi(line);
	if (seireki % 4 == 0) {
		printf("西暦%d年はうるう年です\n", seireki); 
	}
	else {
		printf("西暦%d年はうるう年ではありません\n", seireki);
	}
	//キーボードから入力した西暦の文字列を整数に変換して変数seirekiに代入し画面に表示
	for (int tuki = 1; tuki <= 12; ++tuki) {
		nissu = get_days_of_month(tuki, seireki);
		printf("%2d月は%3d日あります。\n", tuki, nissu);
	}

	return 0;
}

int get_days_of_month(int month, int year) {
	int days[] = {
		0,31,28,31,30,31,30,31,31,30,31,30,31
	};
	if (year % 4 == 0)days[2]++;
	return days[month];
}
```

名前を入力して画面表示する

```
#include<stdio.h>
#include<string.h>
int main() {
	char name[30];
	while (1) {
		printf("あなたの名前は？");
		fgets(name, sizeof(name), stdin);
		name[strlen(name) - 1] = '\0';//改行文字を取り除く
		if (strlen(name) >= 1) {
			printf("あなたは%sさんです\n", name);
		}
		else {
			printf("恥ずかしがり屋さんね\n");
			break;
		}
	}

	return 0;
}
```
```
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<map>
#include<math.h>
#include<queue>
#include<deque>
#include<stack>
#include<cstdio>
#include<utility>
#include<set>
#include<list>
#include<cmath>
#include<stdio.h>
#include<string.h>
#include<cstdio>
#include<iomanip>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using piii = pair<pii, pii>;
const int INF = 1e9 + 7;
//名前を入力して場所とともに表示するプログラム
int main() {
	char basho[11];
	char sakusha[16], riyousha[16];
	strcpy_s(basho, "早稲田大学");
	strncpy_s(sakusha, "terunobu",sizeof(sakusha)-1);
	sakusha[sizeof(sakusha)-1] = '\n';
	printf("利用者の名前は？");
	fgets(riyousha, sizeof(riyousha), stdin);
	riyousha[strlen(riyousha) - 1] = '\0';
	printf("ここは%sです\n", basho);
	if (strcmp(riyousha, sakusha) == 0) {
		printf("あなたはこのプログラムを作った%sさんです\n", riyousha);
	}
	return 0;
}
```
nginx メンテナンスページを表示する

* nginxでメンテナンスページを表示する実験をしてみました (参考サイトをDockerで試してみました)
  * nginxの設定ファイルには触れずに、メンテナンスページの表示/非表示を切り替える
  * 指定したIPはメンテナンスページを表示しない
* Dockerは別途インストールしてください

# 単純にnginxを立ち上げる

```bash
$ docker pull nginx:latest
$ docker run --rm --name nginx-mainte -p 80:80 nginx:latest
```

* ブラウザでアクセス
  * `http://<hostname>`
  * Welcome to nginxページが表示される

# indexページを変更する

* nginxのコンテナに乗り込む

```bash
$ docker exec -it nginx-mainte /bin/bash
```

* ドキュメントルートの確認

```bash
$ cat /etc/nginx/conf.d/default.conf

・・・
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
・・・
```

* `index.html`を変更
  * `vi`無かったので無理くり・・

```bash
sed -i -e 's/nginx\!/nginx\!\!/g' /usr/share/nginx/html/index.html
```

* ブラウザでアクセス
  * `http://<hostname>`
  * nginx! ⇒ nginx!!

# メンテナンスページの作成/確認

* ホスト側で
  * Nginxコンテナの`index.html`を流用し、メンテナンスページを作成する

```bash
$ docker cp nginx-mainte:/usr/share/nginx/html/index.html maintenance.html
$ vim maintenance.html
htmlを適宜編集(パーミッションも)
```

* nginxコンテナのドキュメントルートにメンテナンスページを送り込みつつ起動

```bash
ctrl + c でコンテナ停止
$ docker run --rm --name nginx-mainte -p 80:80 -v `pwd`/maintenance.html:/usr/share/nginx/html/maintenance.html  nginx:latest
```

* ブラウザでアクセス
  * `http://<hostname>/maintenance.html`
  * メンテナンスページが表示される

# メンテナンスページの表示/非表示を切り替え設定

* ホスト側で
  * `mainte.conf`を作る
      * `/etc/nginx/conf.d/default.conf`を流用した(コメントアウトされている部分は削除)

```mainte.conf
geo $allow_ip_flag {
    default 0;
    x.x.x.x/24 1; # メンテナンス中もアクセス許可するIPを設定
}
server {
    listen       80;
    server_name  localhost;
    error_page 503 @maintenance;
    error_page   500 502 504  /50x.html;

    set $maintenance false;

     if ( -e /var/www/nginx/maintenance.txt ) {
        set $maintenance true;
    }

    if ( $allow_ip_flag ) {
        set $maintenance false;
    }

    if ( $maintenance = true ) {
        return 503;
    }

    location / {
         root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location @maintenance {
        internal;
        expires 0;
        root  /var/www/nginx;
        rewrite ^(.*)$ /maintenance.html break;
    }

    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
```

* `mainte.conf`をホスト側からnginxコンテナに送り込みつつ起動

```bash
ctrl + c でコンテナ停止
$ docker run --rm --name nginx-mainte -p 8080:80 -v `pwd`/maintenance.html:/var/www/nginx/maintenance.html -v `pwd`/mainte.conf:/etc/nginx/conf.d/default.conf nginx:latest
```

### メンテナンスページ ON

* nginxのコンテナに乗り込んで

```bash
$ touch /var/www/nginx/maintenance.txt
```

* ブラウザでアクセス
  * `http://<hostname>:8080`
  * 許可IP：Welcome to nginxページが表示される
  * 非許可IP：メンテナンスページが表示される

### メンテナンスページ OFF

* nginxのコンテナに乗り込んで

```bash
$ rm /var/www/nginx/maintenance.txt
```

# 参考

* [DockerHub Nginx](https://hub.docker.com/_/nginx/)
* [docker上のnginxのドキュメントルート](https://qiita.com/kkkkkkkkkk1005/items/817841c77538c356d25d)
* [Nginxでメンテナンスモード](http://blog.higty.xyz/post/nginx-maintenance-mode/)
Pythonで簡単な掲示板を作成する。（FlaskとSQLを使ったWebアプリ開発入門）#3

# pythonで作ったスレッド有りの掲示板をwebにアップロードする
今回は[前回の記事](https://qiita.com/tomson784/items/ed9542496ff46fd09d27)で作った掲示板をwebアプリとしてリリースするための方法について説明します。

# Heroku
Herokuではwebサービスを簡単にリリースでき、無料枠があるので今回はこの無料枠を使用します。
Herokuを使用するにはアカウントが必要なので、登録してください
[このリンク](https://jp.heroku.com/)からアクセスできます。

# Herokuをコマンドラインで操作
herokuでアプリをリリースするにはコマンドラインから操作を行う必要がありまマス。
そのためには Heroku client をインストールする必要があるのでインストールしてください。
[Heroku CLI の URL](https://devcenter.heroku.com/articles/heroku-cli)

# gitの操作
アプリのリリースの際はgitを使う必要があります。gitはコードのバージョンを管理するアプリです。それぞれのOSに合わせてインストールしてください。

# 準備

Herokuの無料枠を使うのでインストールするパッケージを最小限に抑えるために仮想環境を作ってから```requirements.txt```等の設定ファイルを作成します。仮想環境の作成には`venv`を使用しました。


```requirements.txt
Click==7.0
Flask==1.0.2
Flask-SQLAlchemy==2.3.2
gunicorn==19.9.0
itsdangerous==1.1.0
Jinja2==2.10
MarkupSafe==1.1.0
psycopg2==2.7.6.1
SQLAlchemy==1.2.15
Werkzeug==0.14.1
```

`Procfile`を以下のように設定

```
web: gunicorn app:app --log-file=- 
```



```runtime.txt
python-3.6.3
```


# Herokuアプリを作る
はじめにHerokuCLIでHerokuにログインしてください

```
heroku login
```
この時にHerokuでアカウント設定した際のE-mailアドレスとパスワードを要求されるので入力してください

次のコマンドでアプリ名を入力してアプリの作成をしてください

```
heroku create <アプリ名を入力>
```

Herokuでpythonを使用することを明示

```
heroku buildpacks:set heroku/python
```

するとこのようなエラーが発生

```
»   Error: Missing required flag:
»     -a, --app APP  app to run command against
»   See more help with --help
```

原因はわからなかったがアプリを一度削除して以下のコマンドを入力したらうまくいった。

```
heroku create <アプリ名を入力> --buildpack heroku/python
```

Herokuではsqlite3を扱うことが出来ないので、flaskのデータベース設定をsqlite3からpostgresqlに変更します。```db_uri```を以下のように変更してください。

```python:app.py
db_uri = os.environ.get('DATABASE_URL')
```

heroku側にも、どのデータベースを使用するのか明示する必要があるので以下のコマンドを入力してください。

```
heroku addons:add heroku-postgresql
```


gitを使ってアプリのソースコードをherokuにpushします。

```
git init
git add .
git commit -m "first commit"
```

```
git push heroku master
```

するとこのようなエラーで表示されました

```
fatal: 'heroku' does not appear to be a git repository
fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.
```

以下のコマンドを実行してから再びpushするとうまくいきました。（リポジトリを指定しろ、ということなんですかね）

```
heroku git:remote -a <アプリ名を入力>
```


pushだけではデータベースが作成されないのでheorkuアプリ側のpythonを起動してデータベースの作成をします。

```
heroku run python
>>> from app import db
>>> db.create_all()
```

次のコマンドを入力すると作製したアプリのURLにとびます

```
heroku open
```

以上で解説終わりです。
Kotlin+DangerをGithub Actionsで動かす

# 前提
danger-checkstyle_formatプラグインがgemにしかないのでRuby製のdangerを使用しました

# 結論

これでイケた

```
workflow "DangerPullRequest" {
  on = "pull_request"
  resolves = ["Danger"]
}

action "Detekt" {
  uses = "docker://adoptopenjdk/openjdk8:alpine"
  runs = "./gradlew"
  args = "detekt" ← ktlint or 併用でも適宜読み替えてください
}

action "Danger" {
  uses = "u-nation/GithubActions/danger@master"
  needs = "Detekt"
  secrets = ["GITHUB_TOKEN"]
}
```

# ハマりポイント
- `on = "push"` だとDangerが`Not a GitHubActions Pull Request - skipping danger run`エラーを出すので `on = "pull_request"` にするのを忘れない
- GithubActionsのでDangerに対応したのは[5.10.3](https://github.com/danger/danger/compare/v5.10.3...master)から、なのでバージョン指定をちゃんとする

```Dockerfile
FROM ruby:2.6

LABEL "com.github.actions.name"="Danger"
LABEL "com.github.actions.description"="Run Danger"
LABEL "com.github.actions.icon"="alert-triangle"
LABEL "com.github.actions.color"="yellow"

LABEL "maintainer"="u-nation <Endooooooo7@gmail.com>"

RUN apt-get update -qq && apt-get install -y build-essential p7zip unzip

RUN gem install danger -v '>= 5.10.3' ← これが大事
RUN gem install danger-checkstyle_format

ENTRYPOINT "danger"
CMD "--verbose"
```

### Danger対応してくれた [duck8823](https://twitter.com/duck8823)さんに感謝
https://github.com/danger/danger/pull/1054

# 他のCIサービスを使うよりいいところ
- Botアカウントを用意しなくて済む
![image.png](https://qiita-image-store.s3.amazonaws.com/0/58939/e11bb20e-6d44-f2a9-7107-a4e2bd9facfe.png)

- Gemfileもなくて済む(使ってもできたがなるべくファイル数は減らしたい)

# 参考
- http://blog.duck8823.com/entry/2018/12/20/011632
- http://blog.duck8823.com/entry/2018/12/24/131641
- http://blog.duck8823.com/entry/2018/12/31/053415
xlsx を シートで分割　(python3)

表示されているシートごとのファイルに xlsx を分割します。

## プログラム

```py:split_xlsx.py
#! /usr/bin/python
#
#	split_xlsx.py
#
#					Jan/24/2019
import	sys
from openpyxl import load_workbook
#
# ---------------------------------------------------------------
def sheet_pick_up_proc(wb,sheetnames,nn_sheet):
	sheet_target = sheetnames[nn_sheet]
	for sheet in sheetnames:
		if sheet != sheet_target:
			del wb[sheet]
		else:
			print(sheet_target)
#
	xlsx_out = "sheet_%d.xlsx" % nn_sheet
	wb.save(xlsx_out)
#
# ---------------------------------------------------------------
sys.stderr.write ("*** 開始 ***\n")
#
xlsx_file = sys.argv[1]
sys.stderr.write(xlsx_file + "\n")
#
wa = load_workbook (filename = xlsx_file)
#
sheetnames = wa.sheetnames
print(sheetnames)
#for sheet in sheetnames:
#	print(wa[sheet].sheet_state)
#
for icount in range(len(sheetnames)):
	sys.stderr.write("icount = %d\n" % icount)
	sheet = sheetnames[icount]
	wa = load_workbook(filename = xlsx_file)
	if wa[sheet].sheet_state == "visible":
		try:
			sheet_pick_up_proc(wa,sheetnames,icount)
		except Exception as ee:
			sys.stderr.write("*** error *** in sheet_pick_up_proc ***\n")
			sys.stderr.write(str(ee) + "\n")
#
sys.stderr.write ("*** 終了 ***\n")
# ---------------------------------------------------------------
```

## 実行方法

```bash
./split_xlsx.py in01.xlsx
```

次のようなファイルが作成されます。
>sheet_0.xlsx
>sheet_1.xlsx

## 確認したバージョン

```text
$ python
Python 3.12.3 (main, Apr 10 2024, 05:33:47) [GCC 13.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import openpyxl
>>> openpyxl.__version__
'3.1.2'
```
【PHP】call_user_func_array関数で多次元配列の階層を減らす

配列が深すぎて、階層を浅くしたいな〜というときに使えます。
``array_merge``を使うと長くなりますが、``call_user_func_array``を使用すれば一行で済みます。

私は職場で知りましたが、公式サイトの``User Contributed Notes``に載っています！

> [php.net〜call_user_func_array](http://php.net/manual/ja/function.call-user-func-array.php#34594)

# テスト用配列
配列``$members``は、maleとfemaleにグループ分けされています。
この配列からグループ分けを取り払い、配列の階層を１つ減らします。


```php
<?php
$members = array (
    'male' => array (
        0 => array(
            'id' => 1,
            'name' => 'Bob'
        ),
        1 => array(
            'id' => 2,
            'name' => 'John'
        ),
        2 => array(
            'id' => 3,
            'name' => 'Ben'
        )
    ),
    'female' => array (
        0 => array(
            'id' => 4,
            'name' => 'Kate'
        ),
        1 => array(
            'id' => 5,
            'name' => 'Jane'
        )
    )
);

var_dump($members);

/*
出力結果
array(2) {
  ["male"]=>
  array(3) {
    [0]=>
    array(2) {
      ["id"]=>
      int(1)
      ["name"]=>
      string(3) "Bob"
    }
    [1]=>
    array(2) {
      ["id"]=>
      int(2)
      ["name"]=>
      string(4) "John"
    }
    [2]=>
    array(2) {
      ["id"]=>
      int(3)
      ["name"]=>
      string(3) "Ben"
    }
  }
  ["female"]=>
  array(2) {
    [0]=>
    array(2) {
      ["id"]=>
      int(4)
      ["name"]=>
      string(4) "Kate"
    }
    [1]=>
    array(2) {
      ["id"]=>
      int(5)
      ["name"]=>
      string(4) "Jane"
    }
  }
}
*/
```

# 配列の階層を減らす
``call_user_func_array("array_merge", 配列)``だけで完結します。

```php
$merge_members = call_user_func_array("array_merge", $members); 
var_dump($merge_members);

/*
出力結果
array(5) {
  [0]=>
  array(2) {
    ["id"]=>
    int(1)
    ["name"]=>
    string(3) "Bob"
  }
  [1]=>
  array(2) {
    ["id"]=>
    int(2)
    ["name"]=>
    string(4) "John"
  }
  [2]=>
  array(2) {
    ["id"]=>
    int(3)
    ["name"]=>
    string(3) "Ben"
  }
  [3]=>
  array(2) {
    ["id"]=>
    int(4)
    ["name"]=>
    string(4) "Kate"
  }
  [4]=>
  array(2) {
    ["id"]=>
    int(5)
    ["name"]=>
    string(4) "Jane"
  }
}
*/
```
Wordmoveでinvalid byte sequence in UTF-8 (ArgumentError)が出た


例によってさくらのサーバーを相手にしている中で起こったことです。
Wordmoveユーザーなら恐らく一度は目にされているのではないでしょうか。

## 原因
ちょっと前まで毎度のこと[こちらの記事](https://qiita.com/hiro93n/items/7a23cac716db0a863203)の通りに対処していましたが、どうやらWordmoveのアップデートに伴い対処方法が変わったようです。

https://github.com/welaika/wordmove/wiki/movefile.yml-configurations-explained
>@since 3.0.0 database.charset option is no more supported. Pass the '--default-charecter-set' flag into database.mysqldump_options or to database.mysql_options instead, if you need to set the same option.

## 対処法
### Before

```Movefile.yml
database:
    name: "dbname"
    user: "dbuser"
    password: "dbpassword"
    host: "dbhost"
    port: 3306
    charset: "utf8"
```

### After

```Movefile.yml
database:
    name: "dbname"
    user: "dbuser"
    password: "dbpassword"
    host: "dbhost"
    port: 3306
    mysqldump_options: "--default-character-set=utf8"
```


##　自戒と教訓
公式のドキュメントをちゃんと読もう！
地味な物体検出ですみません。　ープロジェクトの立て直しー


以前に、[こちら](https://qiita.com/shinmura0/items/fa352f42bde5bff86948)で「ラズパイで将棋駒を物体検出する」プロジェクトを開始しました。

その後、**とんでもない間違い**をしていたことに気が付きました。
今回はプロジェクトを仕切り直して、再開したいと思います。

![game_syougi.png](https://qiita-image-store.s3.amazonaws.com/0/264781/4cd12095-2cf5-435f-e687-de137988b95c.png)


#物体検出方法の選定ミス
以前に、[こちら](https://qiita.com/shinmura0/items/f818bcbb92d5fff5279d)で将棋駒の検出をやりましたが、物体検出方法は適当に選んでいました。
その結果、検出精度がイマイチでした。

##YOLOv3-tiny

このとき使った検出器はYOLOv3-tinyでした。tinyモデルを使った理由はこのシステムを
ラズパイに搭載したかったからです。

ところが、このYOLOv3-tiny、調べてみるとスペックがかなり悪いものでした。
YOLOv3の論文には出てきませんが、[darknet](https://pjreddie.com/darknet/yolo/)のサイトに載っています。

||mAP50|mAP（推測値）|
|---|---|---|
|YOLOv3-tiny|33.1|19.9|

なお、サイトではmPAという表記になっていますが、論文と照らし合わせるとmAP50の
ことだと思われます。mAPについて、詳しく知りたい方は以下のリンクを参照してください。
https://note.mu/seishin55/n/n542b2b682721
https://qiita.com/panchokyutech/items/2c972ede2bc883597a87

mAP50をmAPに直接変換することはできませんが、他の手法を見てみると、mAPは高くても
mAP50の6割ほどしか出ていません。従って、上の表では推測値を記入しました。

なお、YOLOv3-tinyの推論速度は爆速です。速さは以下の記事で実感できるはずです。
https://qiita.com/PINTO/items/526d2f35d5271d353f20#-%E7%B5%90%E6%9E%9C

##MobileNET + SSDLite

そして、YOLOv3-tinyの対抗馬となるのが、MobileNET(v1/v2) + SSDLiteです。
こちらのスペックは[論文](https://arxiv.org/pdf/1801.04381.pdf)にありました。

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/264781/da727a6d-22f2-82ba-d46a-e8cf3440ba1d.png)

特筆すべきは、MobileNet v1 + SSDLiteは、フルモデルのYOLOv2に対し精度でも
モデルサイズでも、（恐らく）推論速度でも上回っているということです！
正に、「早い！安い！うまい！」の3拍子が揃っています。

ちなみに、「SSDLite」は通常のSSDに対し、深さ方向のフィルタについてサイズを1に
変更して計算コストを下げたモデルだそうです。

物体検出方法はSSD以外にもたくさんあります。気になる方は以下のサイトをご覧ください。
https://github.com/hoya012/deep_learning_object_detection

##どちらの検出方法にすべきか？

以上をまとめると、以下の表になります。

||精度(mAP)|ラズパイの動作速度|
|---|---|---|
|YOLOv3-tiny|19.9|爆速|
|YOLOv2|21.6|遅い|
|**MobileNet v1 + SSDLite**|**22.2**|**通常**|
|YOLOv3|33.0|非常に遅い|

どこまでも速さを追い求めるなら、YOLOv3-tinyでしょう。

しかし、今回はUSB型GPUを使って、計算速度を補完できるため、**「MobileNET v1 +**
 **SSDLite」を使います。**これにより、速度と精度が両立できるでしょう。

最終的に目指す姿は、以下の記事のようにサクサク動く感じです！
https://qiita.com/PINTO/items/fc1fcecce4d5600c20bb#-%E7%B5%90%E6%9E%9C

ちなみに、YOLOv3をラズパイで動かすのは至難の業のようです。
https://qiita.com/PINTO/items/c766ac9614052f4d6304


#使うモジュールの選定ミス
今回は、USB型GPUにMovidiusを使います。

Movidiusのモジュールは、従来NCSDKという悪名高きものが用意されていました。
このモジュールはv2まで更新されましたが、バグだらけで全然収集がつかない状態でした。

その後、OpenVINOが登場してIntelボードだけではなく、ラズパイでも動作できる
ようになり、NCSDKにとって代わり、だいぶ開発環境が改善されたと聞きます。

次回以降は、OpenVINOのインストールから進めたいと思います。

#まとめ

+ ラズパイで物体検出するなら、「MobileNET v1 +SSDLite」が無難。精度と速度が両立できます（まだやってないけど）。
+ Movidiusの開発はOpenVINOを使いましょう。
Webpackでjsファイル、cssファイル、画像ファイルをインラインにする方法

# なぜjsファイル、cssファイル、画像ファイルをインラインにするのですか？
### なぜ画像ファイルをインラインに？
画像ファイルをインラインにすれば、HTMLの描写と一緒に表示させることができるのです。
### なぜjsファイル、cssファイル、画像ファイルをインラインに？
Google DevelpersのPageSpeed Insightsをしてみると

<img width="878" alt="スクリーンショット 2019-01-24 17.20.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/188304/30c44735-a2b7-d6e0-17fe-32b062cb0c29.png">

>
ぺージの初回ペイントをリソースが阻害しています。クリティカルな JS や CSS はインラインで配信し、それ以外の JS やスタイルはすべて遅らせることをご検討ください。

が監査に入りますよね。

Webpaackはデフォルトだと、scriptタグでurlを読み込むようになってしまいます。より早く画面を描写するには、JSファイル、CSSファイルはインラインで読み込みたいですよね。

```html:webpackのデフォルト
<script src="/bundle.js"></script>
```
⬇️

```html:JSをインラインに
<script type="text/javascript">...</script>
```
jsファイル、cssファイル、画像ファイルをインラインにしたWebアプリのたぐまるでは、
モバイルのスコア、93、PCのスコア、100です！
<img width="960" alt="スクリーンショット 2019-01-24 19.57.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/188304/f31a8707-d72c-aee5-775e-61145a3a5a1f.png">
<img width="882" alt="スクリーンショット 2019-01-24 19.57.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/188304/139d5150-0654-b51c-f859-f018b1c82c05.png">

https://tagmaru.me
# jsファイル、cssファイルをインラインにする

## HtmlWebpackInlineSourcePluginを使いましょう
https://www.npmjs.com/package/html-webpack-inline-source-plugin
### HtmlWebpackInlineSourcePluginを導入

#### インストール

```bash

yarn add -D html-webpack-inline-source-plugin
```

### HtmlWebpackInlineSourcePluginの使い方

webpack.config.jsで

```js:webpack.config.js
const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin');
```
そして

```js:webpack.config.js
plugins: [
  new HtmlWebpackPlugin({
        inlineSource: '.(js|css)$' // embed all javascript and css inline
    }),
  new HtmlWebpackInlineSourcePlugin()
]  
```

`inlineSource`で、`.(js|css)$`とすれば、
cssとjsがインラインになります！！

# 画像ファイルをインラインにする

画像ファイルをインラインにすると、画面が描写されても、画像が表示されなくて、遅れて表示されますよね。
トップページの画像など遅延させたくない画像があるなら、インラインにしてみましょう。

## url-loaderを使いましょう
https://github.com/webpack-contrib/url-loader
base64 URIに変換して、imgタグに展開してくれます。
### url-loaderを導入
#### インストール

```bash
yarn add -D url-loader
```
#### url-loaderの使い方　

```html
<img src="data:image/png;base64,xxxxx..."></img>
```

webpack.config.jsで

```js:webpack.config.js
  module: {
    rules: [
      {
        test: /\.(jpg|png|svg|gif)$/,
        use: 'url-loader',
      },
    ],
  }
```

これでインラインになります！
url-loaderと他の画像のloaderを併用することもできます！

### まとめ
jsファイル、cssファイル、画像ファイルをインラインにするのはお手軽、簡単なのでやってみてください。
【React Native】知っておきたかったアプリ開発Tipsまとめ


この記事では、React Nativeでアプリを開発してきて得た知見（特に他の記事ではあまり書かれていないもの）を雑にまとめてみました。
##Tip1: react-native-mapsのインストールが辛い
https://github.com/react-native-community/react-native-maps
React Nativeで地図機能を実装したいときに使うライブラリ。
インストールにはとにかく手こずりました。
公式ドキュメントのInstallation Instructionsにそってやっても上手くいかず、いろんな記事を参考にしてXcodeをゴリゴリいじっても上手くいかずって感じでした。。。
最終的にはReact Nativeをバージョン0.56から0.55.4にダウングレードしたら動きました！
##Tip2: react-native-router-fluxのドキュメントがしょぼい
https://github.com/aksonov/react-native-router-flux
画面遷移・ルーティングを実現するライブラリ。
機能は充実しているが、ドキュメントが乏しくてどう実装すればいいのかよくわからないケースがありました。[react-navigation](https://github.com/react-navigation/react-navigation)の方がよかったかも？
##Tip3: TextInputの日本語変換ができない問題
これは多分公式のバグで、TextInputでonChangeTextを使うと日本語変換がバグります。
(RN0.55.4/0.56ではこのバグがありましたが、RN0.57以降では解決されたそうです。)
関連issue: https://github.com/facebook/react-native/issues/18403
以下の記事に従ってTextInputを自作したら上手くいきました:
http://watanabeyu.blogspot.com/2018/04/react-native0542textinputonchangetext.html
##Tip4: redux-beaconでGoogle Analyticsをカンタンに実装しよう
トラッキングツールはGoogle Analyticsを使いました。
https://rangle.gitbook.io/redux-beacon/index/react-native-google-analytics#setup
redux-beaconを使ってGA用のMiddleware（gaMiddleware）を作成します。
以下のようにstoreを作成すれば実装完了です：

```js:store.js
const store = createStore(
  reducer,
  applyMiddleware(gaMiddleware)
);
```
あとは先ほどのredux-beaconのドキュメントに従って、トラッキングしたいイベントを定義すれば、画面遷移や、どのactionがdispatchされたか、などをカンタンにトラッキングできます。
##Tip5: react-native-share-extension
他のアプリのShare Extension（例えばinstagramの「シェア」ボタン）から自分のアプリにデータを送ることを実現するライブラリ。
https://github.com/alinz/react-native-share-extension
これもXcodeをゴリゴリいじらないといけなく、相当辛かったです。。。
本体のアプリとShare Extensionは別々のアプリとして扱うので、Share Extension側からreduxのstoreにはアクセスできません。なので、Share Extensionと本体のアプリ間で何かしらのデータ（ユーザIDやアクセストークンなど）を共有したかったら、[react-native-swiss-knife](https://github.com/alinz/react-native-swiss-knife)を使うと良いです。その際、App Groupなるものを作る必要があります。
##Tip6: iOSとAndroidは同時に開発するべき
React Nativeの最も大きな特徴の一つとして、クロスプラットフォームが挙げられます。
しかし、僕たちはその特徴を活かしきれませんでした。理由としては、とりあえずiOSをリリースしてからAndroidに対応しようという考えの元、最後までAndroid側を放置していたからです。いくらクロスプラットフォームとはいえ、先述のMapやShare Extensionのようにネイティブの設定をそれぞれでしないといけない場合や、iOSのみ（Androidのみ）対応のコンポーネントなど多々あるので、もしAndroid版もリリースする予定があるなら、Android側も定期的にビルドしてちゃんと動くかどうか確認すべきです。
#最後に
友人2人と一緒にFoolipというグルメ情報管理アプリを作りました。
機能は：
・お気に入りの飲食店を保存して整理
・Instagram・食べログ・Retty・Retripから飲食店情報をカンタンに保存して一元管理
・新しいお店をレコメンド
です。
ぜひ使ってみてください！お問い合わせなどは僕の[Twitter](https://twitter.com/nkmt_acm)まで！
Foolip: https://apple.co/2A4vn4t
TypeError: makedirs() got an unexpected keyword argument 'exist_ok'


```
# coding: utf-8

# -*- coding: utf-8 -*-


import os
os.makedirs('test1',exist_ok=True)
```

フォルダの作成を上記のコードで実行すると
makedirs() got an unexpected keyword argument 'exist_ok'
というエラーが出た(Python2.7)

os.mkdirじゃないから'exist_ok'に対応してるはず

なんでだ

原因分かる人よろしければ教えてください
RESTについて

# 振り返り　Ruby on Railsチュートリアル（５日目）
前回はHerokuの概要と、簡単なデプロイについて書きました。
今回は、**REST(Representational State Transfer)**について書きます。
また、タイトルに「Ruby on Railsチュートリアル（○日目）」と付けるのをやめます。。。。

### RESTって？
Webサービスにおける設計概念（モデル）のことで、URIにHTTPメソッドでアクセスすることで、データの送受信を行う考え方です。
様々なフレームワークに適用されており、[Twitter](https://developer.twitter.com/en/docs)や[Github](https://developer.github.com/v3/)といったSNSのサービスの中にはAPIを公開しています。

RESTに従うシステムのことを、**RESTful**とよびます。

### REST設計の原則

##### ステートレスなクライアント/サーバプロトコル
ステートレス、つまり状態を持たないように作ってるということです。
例えば、サーバがクライアントとのセッション情報を保持しないようにすることが挙げられます。


ステートレスにすると、良いことは

- 冗長になるが、リクエストする情報で処理に必要な全ての情報になる。（わかりやすい）
- 拡張しやすい
- 処理が単純になる

（ここが参考になりました。[yohei-y:weblog - ステートレスとは何か](http://yohei-y.blogspot.com/2007/10/blog-post.html)）

##### すべての情報（リソース）に適用できる「よく定義された操作」のセット
HTTPで例えるなら、HTTPのリクエストを利用して管理をしているということです。
HTTPには以下のリクエストがあります

- GET　…　取得
- POST　…　追加
- PUT　　…　更新
- DELETE …　削除

##### リソースを一意に識別する「汎用的な構文」
URIによって、一意的なアドレスになるということです。
例えば、以下のURLにアクセスするだけで、そのユーザの情報が取れることです。

```
https://www.hogehoge.com/users/okky
```

なので、URLが名詞になることが多いです。

##### アプリケーションの情報と状態遷移の両方を扱うことができる「ハイパーメディアの使用」
HTMLやXMLにといったハイパーメディアに、別のハイパーメディアへの情報（リンク）を含められることです。
リンクを含めることで、簡単に他のページやリソースにアクセスできます。


### 終わりに
チュートリアルは２章まで終わりました。
次回はテストについて書こうと思います。


### 参考

・[Wikipedia - Representational State Transfer](https://ja.wikipedia.org/wiki/Representational_State_Transfer)
・[0からREST APIについて調べてみた](https://qiita.com/masato44gm/items/dffb8281536ad321fb08)
GoogleDomainsドメインネーム取得

# 目的
* GCPでいろいろやりたいのでついでにポケットマネーでGoogleDomainでドメインを取得してみる

# ドメイン名購入

* 検索窓で利用したい名前を検索

![image.png](https://qiita-image-store.s3.amazonaws.com/0/57350/40938ab8-4fea-e225-f1e2-dc6c69af5e31.png)

* 安い名前が良ければ右側のプルダウンでソートする
![image.png](https://qiita-image-store.s3.amazonaws.com/0/57350/5b9ec47a-115f-d220-0ca0-497ad1621285.png)

* 希望の名前をカートに入れるとカートが赤くなる
![image.png](https://qiita-image-store.s3.amazonaws.com/0/57350/ed321f57-6367-a4f3-f857-2bcd055afe42.png)

* 購入確認画面で「CHECK OUT」を選ぶ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/57350/b907b0af-9a32-9110-4422-a593f8805c7f.png)


* 「Email Communication」にチェックを入れ「SAVE CONTINUE」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/655d96fe-de85-d427-8acb-928da347e5f7.png)


![image.png](https://qiita-image-store.s3.amazonaws.com/0/57350/a85aefc7-a924-457d-c7ba-87c356d14d90.png)


* 個人情報確認
![image.png](https://qiita-image-store.s3.amazonaws.com/0/57350/578e2c20-da67-ae7b-ac42-a6d986571181.png)

* 購入詳細を確認し「BUY」で購入
![image.png](https://qiita-image-store.s3.amazonaws.com/0/57350/cb98d184-187b-5683-3e8f-59737e2bb14b.png)

* 以下の画面に遷移する

![image.png](https://qiita-image-store.s3.amazonaws.com/0/57350/33373d04-6a76-b99d-596c-ac6b212b1aff.png)


![image.png](https://qiita-image-store.s3.amazonaws.com/0/57350/c72476cd-389f-3eed-5883-ec84d1c50547.png)

* 以下のようなメールが届くので「VIEW ALL YOUR ORDER」を押し手続き完了

![image.png](https://qiita-image-store.s3.amazonaws.com/0/57350/f84c7f5c-a463-b430-b746-126518311268.png)


## 自動更新オフ

* 1年で解約したいため勝手に更新されると困るので自動更新をOFFにする

![image.png](https://qiita-image-store.s3.amazonaws.com/0/57350/af0e4c19-e456-a143-a853-4fca5ed2fb39.png)

* 「キャンセル」を押す

![image.png](https://qiita-image-store.s3.amazonaws.com/0/57350/f70b8d20-134f-4941-ea6d-36e9ea4d6ca1.png)

* これで自動更新はされないはず

![image.png](https://qiita-image-store.s3.amazonaws.com/0/57350/24127c8a-17d6-b782-cd0d-5ad48a49f4cb.png)


# 感想
* 操作が簡単で管理しやすい
* 日本語解説が親切
* 国内レジストラなどと比較してUIが洗練されていて扱いやすい
* Gsuiteなど他サービスへの利用が用意なので他と比べて利用価値が高い（Gmailの独自ドメイン化など）
* AWSのRoute53でドメインを取得するよりもさらにわかりやすい
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x83 in position 0: invalid start byte


```
import csv

file = open('/Users/mizuguchitaishi/Documents/data (24).csv')
reader = csv.reader(file)
data = list(reader)
```

csvファイルの読み込みを上記のコードで実行すると
'utf-8' codec can't decode byte 0x83 in position 0: invalid start byte
というエラーが出た(Python3.7(qap37))

Python2.7だとエラーが出ない

原因わかる人いたら教えてくれるとうれしいです
お願いします
Devise使用時のApplicationController.renderer.renderで発生するDevise could not find the `Warden::Proxy` instance on your request environment

# はじめに
Warden::Proxyまわりのエラーを調べてたら、日本語の記事ではRSpecでの記事しか見つからなかったので投稿。
また、この記事は以下のサイトを参考にしております。ちなみに、こちらのサイトではDeviseだけでなく、Clearanceについても言及されています。
[Using Rails 5 new renderer with Clearance and Devise](https://www.stefanwienert.de/blog/2016/04/05/using-rails-5-new-renderer-with-authentication-gems-like-clearance-or-devise/)

#ActionView::Template::Errorエラー
ApplicationController.renderer.renderを呼び出した際に下記のエラーが発生。

>ActionView::Template::Error (Devise could not find the `Warden::Proxy` instance on your request environment.Make sure that your application is loading Devise and Warden as expected and that the `Warden::Manager` middleware is present in your middleware stack.
If you are seeing this on one of your tests, ensure that your tests are either executing the Rails middleware stack or that your tests are using the `Devise::Test::ControllerHelpers` module to inject the `request.env['warden']` object for you.):

##原因
Rails5のActionController::Rendererを使用して独自のプロキシを定義せずに通常のコントローラーとは別フローで、テンプレートをレンダリングするようです。
そのため、Deviseでの認証に必要なコントローラー環境全体とミドルウェアにアクセスできず、エラーが発生します。

>Rendering partials with the new Rails 5 ActionController::Renderer provides a nice shortcut to render templates outside the normal controller flow without defining own proxy classes. This is useful for a variety of use cases, like pushing partials down a MessageBus pipe to frontend or mobile, or PDF generation with WicketPDF. 
But to access authentication stuff, like Clearance/Devise (current_user) or CanCan (current_ability) is not obvious, as the whole controller environment and middlewares are missing.
[Using Rails 5 new renderer with Clearance and Devise](https://www.stefanwienert.de/blog/2016/04/05/using-rails-5-new-renderer-with-authentication-gems-like-clearance-or-devise/)

##対策
ApplicationControllerに、renderer.renderの代替メソッドを用意します。

```ruby:app/controllers/application_controller.rb
def self.render_with_signed_in_user(user, *args)
   ActionController::Renderer::RACK_KEY_TRANSLATION['warden'] ||= 'warden'
   proxy = Warden::Proxy.new({}, Warden::Manager.new({})).tap{|i| i.set_user(user, scope: :user) }
   renderer = self.renderer.new('warden' => proxy)
   renderer.render(*args)
 end
```

呼び出す際は、ApplicationController.renderer.render(変更前)の代わりにApplicationController.render_with_signed_in_user(変更後)を呼び出します。

```ruby
# 変更前
ApplicationController.renderer.render('messages/message', locals: { post: @post })
# 変更後
ApplicationController.render_with_signed_in_user(user, 'posts/post', locals: { post: @post })
```

##参考サイト
今回の記事に載せた対策について
[Using Rails 5 new renderer with Clearance and Devise](https://www.stefanwienert.de/blog/2016/04/05/using-rails-5-new-renderer-with-authentication-gems-like-clearance-or-devise/)

Renderについて
[Render views outside of action](https://evilmartians.com/chronicles/new-feature-in-rails-5-render-views-outside-of-actions)
VSCodeでPythonをvenvで仮想化環境として使えるようにする

#別バージョンのPythonをVSCodeで使えるようにする

プロジェクトでPython3.7を使っていましたが、別のプロジェクトでPython3.5を使う必要があるので、仮想化で対応してみました。ついでにVSCodeで連携してみました。

### 参考
[Windows10のVSCodeでvenvを利用するときの注意点](https://qiita.com/Avocado/items/3e71870815d6c54c1eea)
[venv: Python 仮想環境管理](https://qiita.com/fiftystorm36/items/b2fd47cf32c7694adc2e)


## 条件
対象はPython3.3以降
Windows10
Python3.7が入っている状態（パスも設定されている）

## 1. Python3.5のインストール
pythonの公式サイトからインストール
　https://www.python.org/downloads/windows/
現状C:\Python\Python37が入ってるので、C:\Python\Python35にインストール

## 2. PowerShellのポリシーを変更する
参考の[Windows10のVSCodeでvenvを利用するときの注意点](https://qiita.com/Avocado/items/3e71870815d6c54c1eea)を参考にPowerShellのポリシーを変更します。
特に不都合もないと思ったので、管理者権限で実行してポリシーを変更しました。

## 3. Visual Stadio CodeにPowerShellの拡張機能を入れる
VSCodeを起動して以下の拡張機能をインストールして再起動します。
再起動するとVSCodeの左側のメニューアイコンにPowerShellのアイコンが表示されます。

```
名前: PowerShell
Id: ms-vscode.powershell
説明: Develop PowerShell scripts in Visual Studio Code!
バージョン: 1.11.0
発行者: Microsoft
VS Marketplace のリンク: https://marketplace.visualstudio.com/items?itemName=ms-vscode.powershell
```

## 4. Python3.5で仮想環境を作る
VSCodeのPowershellアイコンをクリックしてPowerShellを起動します。
確認のためにインストールしたPython35フォルダへアクセスし、そのフォルダ上で`./python --version`を実行する。

```
PS C:\Python\Python35> .\python --version
Python 3.5.3
```
venvコマンドで仮想環境を作成します。今回はC:\work\virtualworkにvenvという名前で作成します。
※フルパスでPython3.5のpython.exeを指定して実行します。

```
PS C:\Python\Python35> cd ..\..\work\virtualwork
PS C:\work\virtualwork> C:\Python\Python35\python.exe -m venv venv
```

仮想環境を起動してPythonのバージョンを確認します。

```
PS C:\work\virtualwork> .\venv\Scripts\activate
(venv) PS C:\work\virtualwork>
(venv) PS C:\work\virtualwork> python --version
Python 3.5.3
```

後は仮想化した状態でpipを初期化して、好きなパッケージをインストールして、
環境を利用してください。
仮想環境を閉じるときは`deactivate`で閉じます。

```
(venv) PS C:\work\virtualwork> deactivate
PS C:\work\virtualwork>
```

仮想化を閉じると元の3.7に戻ります。

```
PS C:\work\virtualwork> python --version
Python 3.7.0
```

## まとめ

何とかVSCodeと仮想環境を使えるように奮闘してましたが、PowerShellの拡張機能がVSCodeにあったのでそれを使ったら一気に解決しちゃいました。
PowerShellがVSCode上で利用できるので開発効率もかなり上がると思います。
Androidのthemeで指定できるcolors属性一覧

Androidのthemeでは、色々な色を指定できます。必要に応じて `editTextStyle` のようにWidgetごとのstyleやthemeを指定することもありますが、どのようなcolors属性を指定できるのかをざっと知っておくといざという時に便利です。

大まかに [Android Platform](https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/res/res/values/attrs.xml)、[AppCompat](https://github.com/aosp-mirror/platform_frameworks_support/blob/master/v7/appcompat/res/values/attrs.xml)、[Material Components](https://github.com/material-components/material-components-android/blob/master/lib/java/com/google/android/material/theme/res/values/attrs.xml)あたりを網羅できればいいと思うのですが、定義が多すぎて整理しづらかったのでcolor関連の属性だけ集めてMarkdownのテーブルにするスクリプトを書きました。
https://github.com/konifar/android-theme-attrs-to-markdown-table

`android_framework` のみに◯がついているものは、属性の指定時に `android:` namespaceが必要です。全体でどんな属性があるのか、MaterialComponentsのみ指定できる属性にはどんなものがあるのか、といったことは把握できると思います。それぞれの属性の説明については、各attrs.xmlのコメントに記載されています。

----

attr name | android_framework | appcompat | material_components
:-- | :--: | :--: | :--:
actionMenuTextColor | ◯ | ◯ | ー
colorAccent | ◯ | ◯ | ◯
colorActivatedHighlight | ◯ | ー | ー
colorBackground | ◯ | ー | ー
colorBackgroundCacheHint | ◯ | ー | ー
colorBackgroundFloating | ◯ | ◯ | ◯
colorButtonNormal | ◯ | ◯ | ー
colorControlActivated | ◯ | ◯ | ー
colorControlHighlight | ◯ | ◯ | ー
colorControlNormal | ◯ | ◯ | ー
colorEdgeEffect | ◯ | ー | ー
colorError | ◯ | ◯ | ◯
colorFocusedHighlight | ◯ | ー | ー
colorForeground | ◯ | ー | ー
colorForegroundInverse | ◯ | ー | ー
colorLongPressedHighlight | ◯ | ー | ー
colorMultiSelectHighlight | ◯ | ー | ー
colorOnBackground | ー | ー | ◯
colorOnError | ー | ー | ◯
colorOnPrimary | ー | ー | ◯
colorOnSecondary | ー | ー | ◯
colorOnSurface | ー | ー | ◯
colorPressedHighlight | ◯ | ー | ー
colorPrimary | ◯ | ◯ | ◯
colorPrimaryDark | ◯ | ◯ | ◯
colorPrimaryVariant | ー | ー | ◯
colorProgressBackgroundNormal | ◯ | ー | ー
colorSecondary | ◯ | ー | ◯
colorSecondaryVariant | ー | ー | ◯
colorSurface | ー | ー | ◯
colorSwitchThumbNormal | ◯ | ◯ | ー
editTextColor | ◯ | ◯ | ー
fastScrollTextColor | ◯ | ー | ー
floatingToolbarDividerColor | ◯ | ー | ー
floatingToolbarForegroundColor | ◯ | ー | ー
panelColorBackground | ◯ | ー | ー
panelColorForeground | ◯ | ー | ー
textColorAlertDialogListItem | ◯ | ◯ | ー
textColorHighlightInverse | ◯ | ー | ー
textColorHintInverse | ◯ | ー | ー
textColorLinkInverse | ◯ | ー | ー
textColorPrimary | ◯ | ー | ー
textColorPrimaryActivated | ◯ | ー | ー
textColorPrimaryDisableOnly | ◯ | ー | ー
textColorPrimaryInverse | ◯ | ー | ー
textColorPrimaryInverseDisableOnly | ◯ | ー | ー
textColorPrimaryInverseNoDisable | ◯ | ー | ー
textColorPrimaryNoDisable | ◯ | ー | ー
textColorSearchUrl | ◯ | ◯ | ー
textColorSecondary | ◯ | ー | ー
textColorSecondaryActivated | ◯ | ー | ー
textColorSecondaryInverse | ◯ | ー | ー
textColorSecondaryInverseNoDisable | ◯ | ー | ー
textColorSecondaryNoDisable | ◯ | ー | ー
textColorTertiary | ◯ | ー | ー
textColorTertiaryInverse | ◯ | ー | ー
textUnderlineColor | ◯ | ー | ー
tooltipBackgroundColor | ◯ | ー | ー
tooltipForegroundColor | ◯ | ◯ | ー

以上。