OmniAICreator/Qiita-1.07M huggingface dataset:
Form 表單樣式設計與輸入驗證 By 彭彭

![WS000030.JPG](https://qiita-image-store.s3.amazonaws.com/0/280122/bde6b271-4617-a713-f804-d81b2d6cd5ac.jpeg)![WS000031.JPG](https://qiita-image-store.s3.amazonaws.com/0/280122/7c226da1-1a56-f53e-0b3f-56e0c1dc667d.jpeg)

```ruby
<style type="text/css">
		form{
			line-height:2em;
		}
		form>input,form>select{
			padding:5px 10px;border:1px solid #888;border-radius:5px;
		}
		form>.ok{
			color:#008800;
		}
		form>input:valid+.ok{
			display:inline;
		}
		form>input:invalid+.ok{
			display:none;
		}
    </style>
```

```ruby
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1">
	<title>Form 表單樣式設計與輸入 驗證</title>
	<style type="text/css">

    </style>
</head>
<body>
	<h3>zhu ce zhang hao<h3>
	<form onsubmit="alert('sent')">
		zhanghao:
			<input type="text" required placeholder="4~12 文字" pattern ="[0-9a-zAZ]{4,12}"/>
			<span class="ok">ok</span><br />
			
		password:
			<input type="password" required pattern="[0-9a-zA-Z]{8,16}"/>
			<span class="ok">ok</span><br />
			
		email:
			<input type="email" required />
			<span class="ok">ok</span><br />
			
		tel:
			<input type="text" pattern="[0-9]{8,16}" /><br />
			
		性別：
			男：<input type="radio" name="gender" value="male" required/>
			女：<input type="radio" name="gender" value="male" required/><br />
		誕生日:
			<select>
			<option value="">
			<option value="">1990</option>
			<option value="">2000</option>
			</select><br /><br />
			<input type="submit" value="send" />
	</form>
	
</body>
</html>

```
Win16でhello, world

Neko Project 21/W
- MS-DOS 6.2
- Windows 3.1
- Visual C++ 1.5

```hello.c
#include <windows.h>

int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
	MessageBox(NULL, "hello", "hello, world", MB_OK);
	return 0;
}
```

```hello.def
NAME		HELLO
DESCRIPTION	'HELLO'

EXETYPE		WINDOWS

CODE		PRELOAD MOVEABLE DISCARDABLE
DATA		PRELOAD MOVEABLE MULTIPLE

STUB		'WINSTUB.EXE'

HEAPSIZE	1024
STACKSIZE	5120
```

```mk.bat
cl /c /G2As /Fl hello.c
link /NOD /NOE hello.obj, hello.exe, NUL, libw slibcew, hello.def
```

![hello.png](https://qiita-image-store.s3.amazonaws.com/0/257554/353d8f9f-d94d-a0c9-3448-57cdd70d340d.png)
手っ取り早くPromiseでループ処理を書きたいとき

```javascript
function hoge() {
    // 非同期処理
}

for (var i = 0; i < 10; i++) {
    hoge(i); // 待ってくれない・・・
}
```
Promiseを使ってループ処理を書く場合は[bluebird](http://bluebirdjs.com/docs/getting-started.html)などを使うことが多いが、
今回は外部ライブラリを使わずにループ処理を書く方法を紹介する。

## Promise Loop

for文やwhile文に対応する。

| param       |name        |description               |
|:------------|:-----------|:-------------------------|
| param1      |callbackFn  |                          |
| param2      |conditionFn |return false to end loop  |
| param3      |incrementFn |                          |

```javascript:promiseLoop.js
Promise.loop = function (callback, condition = () => true, increment = () => { }) {

    function onErr(resp) {
        errResp = resp;
        success = false;
        return false;
    }

    var errResp;
    var success = true;

    return (function loop() {
        return Promise.resolve(condition())
            .then((resp) => resp === false ? false : callback(), onErr)
            .then((resp) => resp === false ? false : increment(), onErr)
            .then((resp) => resp === false ? false : loop(), onErr);
    })().then(function () {

        if (success) {
            return;
        } else {
            throw errResp;
        }

    });

};
```

### サンプル
```javascript:sample1.js
var i = 0;
var max = 10;

Promise.loop(function () {
    return new Promise(function (resolve) {
        console.log(i);
        setTimeout(resolve, 1000);
    });
}, () => i < max, () => i++);
```

### 結果
```bash:console
0
1
2
3
~
99
```

## Promise Each

Array.prototype.forEach()に対応する。

| param       |name                             |description               |
|:------------|:--------------------------------|:-------------------------|
| param1      |array                            |                          |
| param2      |callbackFn(value, index, array)  |return false to end loop  |

```javascript:promiseEach.js
Promise.each = function (array, callback) {

    var i = 0;
    var length = array.length;

    return Promise.loop(() => callback(array[i], i, array), () => i < length, () => i++);

};
```

### サンプル
```javascript:sample2.js
var array = ["a", "b", "c", "d"];

Promise.each(array, function (n, i) {
    return new Promise(function (resolve) {
        console.log(n);
        setTimeout(resolve, 1000);
    });
});
```
### 結果
```bash:console
a
b
c
d
```
【I18n::InvalidLocaleData】can not load translations fromの対処法【Rails】

##エラー内容

`can not load translations from`

locateファイルが読み込めていないと、ロードできませんでしたというエラーがでる。

##結論

sprigを一度ストップさせてみる

```ruby
spring stop
```

そして**サーバーを一度再起動**すると解決できました。

参考: https://stackoverflow.com/questions/25300598/rails-if-validation-fail-shows-error-i18ninvalidlocaledata-can-not-load-t
(raid再構築) こんなこともあろうかと思って何となく raid にしといたらディスクが死んだ  --- Don't panic

# 概要

`mdadm` で raid-5 (ディスク3つ) のアレイを運用していたが、ディスクが壊れたり壊れそうになったりして再構築を経験したので、その手順の備忘メモ。ポイントは

  - 死にかけているディスクの交換
  - 完全に死んでしまったディスクの交換

で手順が違うこと。(特に後者はなかなか情報がなくて困ったのでこれが役に立てば幸いです。)
以下、アレイ `/dev/md0` が `/home` にマウントされているとして、 アレイを構成するディスクのうち `/dev/sdc1` を交換する対象とします。

# 状況確認

以下のコマンドあたりで状況を把握しましょう。

```shell-session
# cat /proc/mdstat
# mdadm --detail /dev/md0
# mdadm --examine /dev/sdc1 
```

# まだ生きているディスクの交換

  - step 0: 念のためアンマウント

```shell-session
# umount /home
```

  - step 1: ダメなディスクにこいつダメですの烙印押印

```shell-session
# mdadm --manage /dev/md0 --fail /dev/sdc1
```
どうぜ外しちゃうんだから不要な気もしますが、いちおうこうしておくのが正しい手順らしいです。

  - step 2: ダメなディスクをアレイから除去

```shell-session
# mdadm --manage /dev/md0 --remove /dev/sdc1
```
これで `/dev/md0` はdegraded modeになるので冗長構成ではなくなります。危ない状態なので一刻も早く本来の構成に戻してあげましょう。まずは　`poweroff` して `/dev/sdc` のディスクを交換します。ぼくの場合、同一容量の別メーカのディスクにしましたが問題ありませんでした。聞くところによると大きい方なら容量が違ってても交換可能とのことです。（試したことはありません。）

  - step 3: 新しいディスクの初期化

新しいディスクを取り付けて起動し、シングルユーザモードでログインします。やはり怖いので念のため `umount /home` しておきます。そしたら`gdisk` などで `/dev/sdc1` パーティションを作成します。パーティションIDは 0xfd00 (linux RAID)にしました。

  - step 4: RAIDに新しいディスクを追加

```shell-session
# mdadm --manage /dev/md0 --add /dev/sdc1
```
はいこれで終了です。`cat /proc/mdstat` 等で確認すると再構築が始まっているのが確認できます。その気になればすぐにマウントして使い始めてもいいのでしょうが、時間に余裕があるなら再構築が完了するまで待ってから再起動しましょう。

# 完全に死んでしまったディスクの交換

どちらかというとこちらの方がよくあるケースなんじゃないかと思いますが、突然 `/dev/sdc` を認識しなくなってしまったような場合です。

  - step 1: `/dev/md0` をディアクティベート

```shell-session
# mdadm --stop /dev/md0
```

  - step 2: 何とかdegrated として認識

```shell-session
# mdadm --assemble --scan
```
これで認識してくれたら一安心。あとは `poweroff` して前節の step 3 から手順を踏めば ok です。たぶん。
CodenvyでJava開発: Hello World!実行

##目的
CodenvyでJava開発環境を設定し、Hello World!を実行する。

##前提条件
Codenvyのアカウント持っている。
アカウント作成はこちらから https://codenvy.io/site/create-account

##内容
- Codenvyワークスペース作成
- Javaプロジェクト作成 
- Javaプロジェクト実行

##Codenvyワークスペース作成
1. Codenvyへログイン後、Workspaces画面から「Add Workspace」をクリック
![WS000000.JPG](https://qiita-image-store.s3.amazonaws.com/0/281032/e10af9ca-df4b-d4a2-3d64-e07d117c06aa.jpeg)

2. NAME、TEAM、SELECT STACKを入力し、「CREATE」をクリック
![WS000001.JPG](https://qiita-image-store.s3.amazonaws.com/0/281032/34b22a07-eb31-2efa-f214-29bde6896fcc.jpeg)

3. 画面がかわり、「Workshpace is running」が表示されると作成完了
![WS000002.JPG](https://qiita-image-store.s3.amazonaws.com/0/281032/444c441f-1baf-d70d-2ac8-1cc42e2fb818.jpeg)

##Javaプロジェクト作成
1. Projects Explorerから「Create Project」をクリック
![WS000003.JPG](https://qiita-image-store.s3.amazonaws.com/0/281032/a5df8c5d-d078-6fc9-946f-ad6e93b8c4c6.jpeg)

2. Nameを入力し「Next」をクリック
![WS000004.JPG](https://qiita-image-store.s3.amazonaws.com/0/281032/b8ef0b91-8381-fff1-8a18-44e997a1808f.jpeg)

3. From Acchetypeをチェックし、[maven-archetype-quickstart:RELEASE]を選択し[Create]クリック
![WS000005.JPG](https://qiita-image-store.s3.amazonaws.com/0/281032/4d4a2c62-4232-452c-d605-d48e439dd2a8.jpeg)

4. Project Explorerが下記画面のようになっていれば作成完了
![WS000006.JPG](https://qiita-image-store.s3.amazonaws.com/0/281032/2d978596-18d8-ed2c-05c7-a59ca2e46dbc.jpeg)

##Javaプロジェクト実行
1. Commands ExplorerからRUNを追加
![WS000009.JPG](https://qiita-image-store.s3.amazonaws.com/0/281032/20260d61-061a-20c7-61df-8504e1f6918d.jpeg)

2. Javaを選択
![WS000010.JPG](https://qiita-image-store.s3.amazonaws.com/0/281032/4f1e4033-cff5-ddf9-1a9b-924bab264063.jpeg)

3. NameとCommand Lineなかのコマンドを修正する
![WS000011.JPG](https://qiita-image-store.s3.amazonaws.com/0/281032/bbfb4db3-b2f1-4ea7-a77b-10195b2c7c41.jpeg)

4. RUNクリックすると、実行結果が表示される
![WS000012.JPG](https://qiita-image-store.s3.amazonaws.com/0/281032/945343bd-74f3-72d9-98d0-671b0f4611f7.jpeg)
BitBucketのPipelineでfirebaseに自動デプロイ

## firebaseトークン取得
プロジェクト配下に移動して以下コマンド

```
project$ firebase login:ci
```

ログインすればトークンが発行される

## 環境設定
画面右の歯車アイコンからトークンを登録

<img width="701" alt="無題.png" src="https://qiita-image-store.s3.amazonaws.com/0/145645/7b5ed700-2e2d-9819-aef8-28ac7085c024.png">

Name  FIREBASE_TOKEN
Value {発行したトークン}

## bitbucket-pipelines.ymlの編集
```bitbucket-pipelines.yml
image: node:6.9.4

pipelines:
  default:
    - step:
        caches:
          - node
        script: 
          - export FIREBASE_TOKEN=$FIREBASE_TOKEN
          - npm install -g firebase-tools
          - cd ./client // 任意：デプロイしたいモジュールがある場所に移動
          - npm install
          - firebase deploy --only hosting --token ${FIREBASE_TOKEN}

```

以上でfireabaseのHostingだけがデプロイされる
結構時間かかる
電子書籍メモ

Kinoppy（macOS）
===============

購入したコンテンツの保管場所
--------------------------

`~/Library/Containers/jp.co.kinokuniya.kinoppy/Data/Library/Application Support/jp.co.kinokuniya.kinoppy/.Contents/`

- 拡張子 `kbe`
  - 圧縮ファイルで、解凍するとDRMのかかった `.book` ファイルや、PDFファイルになる。

VarsityWave（macOS）
===================

購入したコンテンツの保管場所
--------------------------

`~/Library/VW-eBook-AC/`

- フォルダ `0_content_ids` 内のファイルがコンテンツに相当すると思われるが、拡張子なし。
- フォルダ `Native` にログが保存されている。
Unityでテキストで変なことする時の謎Tips

### RenderTexture すると文字が細く荒れる

境界のアルファが切り捨てられるせい。
RenderTexture側でどうにかしようとしたがどうしようもなかったので、
もとのTextの境界のアルファを、切り捨てられる前提で調整する。
具体的にはアウトラインを同色でいい感じにつける。
見た目が太くて潰れてね？ぐらいで、RenderTexture後の見栄えはほどよくなる。

### TextMeshProで細い文字が黒く潰れることがある

大きめのサイズでSDFを生成して、FontSize指定が、1.5未満（1とかに指定してると顕著）だと、特定の文字列パターンで特定の文字が潰れることがある。（"ゲージ"って書いた時の"ー"とか）

どうも大きいサイズでSDFを生成して、小さく表示する時に起きるっぽい。

RectRransform側のscaleで縮小（うわ糞対処...）とかしてやっても無駄。
SDF生成時のサイズを見直すか、そもそもの文字のサイズを上げるしかない。
Rubyデバッグで使うメソッド達

# 概要
Rubyでのソースコードリーディング時に
これだけは最初に押さえておきたい！というメソッドをまとめました。

実装をしたり、ソースコードリーディングを行う際に、pryデバッグなどを行うのですが、
基本的なことを確認するときに使うRubyのメソッドがあるので、その紹介。

# 自身のClassを確認する
## class
レシーバのクラスを調べて、出力してくれるメソッド。
意図してない箇所で、NoMethodErrorが出て、レシーバに何のクラスが入ってるのか確認したいときに使う。

# 自身にMix-inされているModuleや継承されているClassを調べる
## ancestors

Moduleのインスタンスメソッドとして定義されています。

あるクラスやオブジェクトがどのようなクラス・Moduleをincludeしているのか?は結構気になります。
`ancestors`を実行してあげると、継承ツリーの順番で返ってくるので、
include, extendされている位置関係が自身が意図した状態であるのか確認出来ます。

ActiveRecordを継承していたりすると、結構量があるので、ピンポイントで確認したい場合、
`HogeClass.ancestors.include?(確認したいクラス名)`をしてあげると、良いかと思われます。

参考
https://ref.xaio.jp/ruby/classes/module/ancestors

# 自身が使用できるメソッドを調べる
## methods
使用できる全てのmethodを出力

すごい量が出てくるので、
`Hoge.methods.grep(/部分検索文字列/)`で探したりしてます。

このメソッドは、インスタンスメソッドなのかを調べたくなってくる時がある。

- インスタンスか
- 特異かは調べられるようにしておこう :muscle: 

## instance_methods

使用できる全てのインスタンスメソッドを出力
スーパークラスやMix-inしてるModuleのインスタンスメソッドも含まれる。

`hoge.instance_methods(false)`のように引数にfalseを渡すと、
レシーバで定義されているインスタンスメソッドのみを出力する。

参考
https://ref.xaio.jp/ruby/classes/module/instance_methods

## singleton_methods

レシーバが使用できる全ての特異メソッドを出力
スーパークラスやMix-inしてるModuleの特異メソッドも含まれる。

`hoge.singleton_methods(false)`のように引数にfalseを渡すと、
そのオブジェクトで定義されているメソッドのみを出力する。

参考
https://ref.xaio.jp/ruby/classes/object/singleton_methods

# 自身が保持している変数を調べる
- インスタンス変数
- クラス変数
- 定数は調べられるようにしておこう :cat: 

methodsのように、全ての変数を返すというものはないっぽい

## instance_variables

保持しているインスタンス変数を出力

参考
https://ref.xaio.jp/ruby/classes/object/instance_variables

## class_variables

保持しているクラス変数を出力

参考
https://ref.xaio.jp/ruby/classes/module/class_variables

## constants

保持している定数を出力

`hoge.constants(false)`のように
falseをつければ、そのオブジェクトで定義されている定数のみを出力する。

参考
https://ref.xaio.jp/ruby/classes/module/constants

# まとめ

pry自体の機能を使ったいい方法もあるので、それも別途記事にする
Pandasについて

Pandasを使ってみましょう。

```py
import pandas as pd
```


ファイルを開く

```py
df_white = pd.read_csv("./winequality-white.csv", sep=";")
df_red = pd.read_csv("./winequality-red.csv", sep=";")
df_white
df_red
```

それぞれのデータフレームにtypeという列名で列を追加せよ
type列は白ワインは0、赤ワインは1を埋めよ

```py
df_white["type"] = 0
df_red["type"] = 1

df_white
df_red.head()
```

df_whiteとdf_redを行を追加する形でdfと言う名前の１つのデータフレームにせよ また、１つに結合した際にインデックスはリセットせよ

```py
df = df_white.append(df_red).reset_index(drop=True)
df
```

欠損値がないかの確認

```py
df.isnull()
```

特徴量側での欠損値の確認

```py
df.isnull().any()
```

qualityごとのレコード数を確認せよ

```py
df.groupby("quality").count()
```

```py
tmp_set = set(df["quality"])
tmp_dict = {}
for s in tmp_set:
    cnt = sum(df["quality"] == s)
    tmp_dict[s] = cnt
print(tmp_dict)
```

```
df["quality"] == 3
```

qualityとtypeごとのレコード数を確認せよ

```py
df.groupby(["quality", "type"]).count()
```

matplotlibのhistを用い、typeごとのpHの分布をヒストグラムを描き確認せよ 

```py
%matplotlib inline
import matplotlib.pyplot as plt
plt.hist([df_white["density"], df_red["density"]], label=["white", "red"])
#plt.hist(df_white["pH"], label="white", rwidth=0.4)
#plt.hist(df_red["pH"], label="red", rwidth=0.4)
plt.legend()
plt.show()
```

typeごと、pHを0.1単位ごとにレコード数がいくつあるか確認せよ

```py
import numpy as np
df["round_pH"] =  np.round(df["pH"], 1)
#df["round_pH"] =  df["pH"].apply(lambda x: round(x, 1))
df.groupby(["type", "round_pH"]).count()
```

本日はここまで！
Magic Pod で Carthage binary is not found Error

# 概要

- Magic Pod (Desktop v0.19.2) を使ってみようかなと思ったらいきなり動かなくて困ったのを解決
- Magic Pod は Carthage のインストール場所が固定の場所じゃないと認識できないっぽい
 -  `carthage` にpathが通っていてもダメ
- homebrew のインストール先（brew --prefix）をデフォルトの /usr/local から変えているとダメなので、 `brew install carthage` じゃなくて Carthage の Installer を使えば解決

## 追記（2018/08/31）

TRIDENTの伊藤さんから人伝に「GUIでPATH追加できるよー」と情報いただきました。
Magic Pod Desktop のウィンドウの下の方にある「Environment variables」に `PATH=hogehoge:$PATH` とか書くと追加できるのかな？

# Magic Pod とは

https://magic-pod.com/

- TRIDENT Inc. の Android/iOS テスト自動化ツール（appiumベース）
- AIでテスト作成を支援してくれる
- 実機/シミュレータ対応
- NTTレゾナントのクラウド実機検証サービス [Remote TestKit](https://appkitbox.com/testkit/) とも連携可能

## Install and Setup

公式サイト参照
https://www.trident-qa.com/magic-pod-help/

# Error

Magic Pod Desktop を起動して
Magic Pod Desktop > Tool > iOS Environment Check

```
Error: Unable to launch WebDriverAgent because of xcodebuild failure: "Carthage binary is not found. Install using `brew install carthage` if it is not installed and make sure the root folder, where carthage binary is installed, is present in PATH environment variable. The current PATH value: '/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/Applications/Magic Pod Desktop.app/Contents/Resources/app/node_modules/ios-deploy/build/Release'".
```

## Carthage binary is not found?

```
$ brew install carthage
$ which carthage
/Users/username/homebrew/bin/carthage
```

あるじゃん？

## ダメだった対処法1

carthage のシンボリックリンクを
`/Applications/Magic Pod Desktop.app/Contents/Resources/app/node_modules/ios-deploy/build/Release`
にコピー

## ダメだった対処法2

appiumを独立にインストールしてみる

```
$ npm install -g appium
$ npm install -g appium-doctor
$ appium-doctor --ios
...略...
info AppiumDoctor Everything looks good, bye!
```

ってなるけどMagic Podの方は解決せず（まぁそうだよね。。）

\#試さなかったけど自分で立ち上げた [appium server のアドレスを Magic Pod に設定ファイルで渡して使う](https://www.trident-qa.com/magic-pod-batch-test-run/#sec2_1) のもできるようなので、そうすればうまくいくのかもしれない

## 今回の対処

結局 `echo $PATH` の結果とエラーテキストの The current PATH value が一致していない。
このPATHに追加する方法はちょっと分からずだったので、 Carthage のインストール場所を変更することに。

```
$ brew uninstall carthage
```

[Installing Carthage (Github)](https://github.com/Carthage/Carthage#installing-carthage)

を参考に、 `Carthage.pkg` をDLして実行

```
$ which carthage
/usr/local/bin/carthage
```

再度 iOS Environment Check 実行

```
Check succeeded!
```

# 感想

まぁ homebrew の prefix を変更してる人とかあんまりいないんでしょうね。。
Carthage を installer で別ディスクに入れてる人とかはいるかもしれない。
動いてよかったよかった。
Babel 7へのマイグレーション方法まとめ

[Babel 7](https://babeljs.io/blog/2018/08/27/7.0.0)がリリースされましたね。

記事「[最新版で学ぶwebpack 4入門 \- Babel 7でES2018環境の構築](https://ics.media/entry/16028)」では、webpack 4とBabel 7の連携について、最新版の情報にすべて書き直しました。サンプルもすべてBabel 7対応しています。

マイグレーションするなかで気づいた点を紹介しようと思います。

## Babel 7の主な新機能

- TypeScriptをサポート
- babel.config.jsが新設. envで制御可能に。
    - .babelrc や package.json を置き換えるものではない
- globでプリセット指定が可能なoverrideが追加
- polyfillを必要分だけ自動的に導入(実験機能)


## 導入して気づいた、Babel 6→7の破壊的変更まとめ

- `babel-core`から`@babel/core`に名前が変更
- プリセットの設定名も変更
    - `babel-preset-env`が`@babel/preset-env`に変更された
    - `babel-preset-react`が`@babel/preset-react`に変更された
- `@babel/preset-env`で、モジュールがデフォルトでES Modules対応する
    - いままでは`import`文が忌まわしき`require()`メソッドに変換されるのを防ぐため、明示的に`{module: true}`を設定していたが、明示的に指定しなくてOK
- ポリフィルの扱いも変更
    - なんか自動的にプリフィルを当ててくれるらしい（要検証）

古い記事の手順だと最新版を導入できないので注意。

## 公式からアップグレードツールが便利

とりあえず、グローバルに入れる。

```bash
sudo npm i -g babel-upgrade
```

Babel 6のプロジェクトでドンと入力。

```bash 
babel-upgrade --write --install
```

これで、package.jsonや.babelrcのほとんどはアップグレードできる。

ただし、webpack.config.jsonまでは管理してくれないので、自前で修正する必要あり。

## Babelのテーマ曲

[babel/SONG\.md at master · babel/babel](https://github.com/babel/babel/blob/master/SONG.md)
に歌詞が公開されている。YouTubeでは歌声付きで視聴できる。

<iframe width="560" height="315" src="https://www.youtube.com/embed/40abpedBKK8?rel=0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
ドルアーガ風ダンジョンジェネレーター

## 結論

ドルアーガの塔のマップ生成アルゴリズムはすごくかっこいいです。

## はじめに

ドルアーガの塔のマップ生成アルゴリズムがすごくかっこいいので、javascriptで再現してみました。

+ [druaga-like-dungeon-generator](https://github.com/MasatoMakino/druaga-like-dungeon-generator)
+ [Demoページ](https://makino-design-staging.s3.amazonaws.com/dungeongenerator/index.html)

![](https://www.evernote.com/l/AAmtWUy7o5ZCFZYGdb2pEVP9wa7gERV5T_cB/image.jpg)

ページ下部のコントローラーで

* 乱数シード
* フロアサイズ（縦横）

を変更すると再現可能なフロアマップが生成されます。

本記事はドルアーガの塔のフロアマップ生成アルゴリズムについての解説となります。
マップ生成アルゴリズムは詳細な解説記事があります。

[古くて新しい自動迷路生成アルゴリズム](http://d.hatena.ne.jp/yaneurao/20130125)

本記事はこの解説をベースに再現と解説を行っています。

## 前提条件

ドルアーガの塔のフロアマップは、以下の前提条件を元に生成されています。

* 床、柱、壁のマップデータはROM上に保持しない。これらはフロア数を擬似乱数のシード値とし生成する。
* マトック（壁破壊アイテム）を使用しなくとも、必ずすべてのフロアを踏める。閉じた空間は存在しない。
* 広い部屋は存在しない。すべての床が通路になる。

実機では、**フロアマップはなんと8ビットの整数値から生成されています。**
各フロアの階数をシード値とするとフロアが生成されます。60階（最終フロア）のみ255をシードとして使用しています。同じフロアサイズとシード値を与えれば、必ず同じマップが生成されます。
生成されたフロア上にキャラクターを配置するとダンジョンが完成します。

広い部屋を許さないのは、当時はハードウェアの性能的にフロアの広さが制限されていたためです。
長い通路を作り出さないと、ユーザーがあっという間にフロアを横断できてしまいます。

### 擬似乱数

マップ生成アルゴリズムにはシード付き擬似乱数が必要となります。

[シード付き擬似乱数 Xorshift](https://crocro.com/write/js_sample/?act=vw_itm&itm=xorshift)

今回はこの記事を参考にXorshiftアルゴリズムで乱数を生成しています。

## マップ生成アルゴリズム

ここからは、実際にどのような手順でマップが生成されているかの解説となります。

### 基本的な方針

ドルアーガの塔のフロアマップは、3つの要素から構成されています。

1. 外壁 ■️
2. 床
3. 柱 ●

外壁はフロア全体を囲んでいます。
床はキャラクターが自由に行き来できるマップです。
柱は等間隔に並び、ここから壁が生えています。

ドルアーガの塔のマップ生成アルゴリズムは、[棒倒し法](http://algoful.com/Archive/Algorithm/MazeBar)をベースにしています。
しかし、棒倒し法は単純な直線ルートが生成されやすいという問題があります。
そのため、以下のようにアレンジされています。

1. 左上から右下へ順に柱をピックアップする
2. まだ壁が生成されていない柱から、棒倒しを行い壁を伸ばす
3. 壁の先にある柱へ移動
4. 移動した先の柱で手順2の棒倒しを繰り返す。壁を伸ばす方向は後戻りしない3方向から選ぶ
4. 外壁、もしくはすでに壁が伸びている柱にたどり着いたら終了

この処理を以下では基本手順と呼びます。

この基本手順をひたすら繰り返すことで、柱から壁が伸びてマップが生成されます。
柱からスタートし、外壁に到達すると壁の生成が終了するため、フロアを縦横に分断してしまう壁は生成されません。
他の壁に合流して手順が終了した場合も、必ず外壁に届いて壁の生成が止まることになります。


### 閉じた空間の回避

基本手順に従い壁を作り続けると

1. 生成中のルートにぶつかる
2. 生成中のルートに四方を取り囲まれる

の2つの場合に閉じた空間が発生します。
この2つの問題を解決する必要があります。

#### 生成中のルートにぶつかる

基本手順にしたがって壁を伸ばし続けた場合、生成中のルートに壁がぶつかると閉じた空間ができます。
数字の6のような形を想像してください。

```console
● ← ●
↓
● ← ●
↓   ↑
● → ●
```

上記のような場合、生成中のルートにぶつかって円ができています。
この問題を回避するため、壁を伸ばす先が生成中のルート上でないかを確認します。
ぶつかっている場合は最後の一手の壁生成を取り消して再抽選を行います。

#### 生成中のルートに四方を取り囲まれる

生成中のルートにぶつかる問題を解決しましたが、次のような場合の問題は回避できません。
渦巻きの形を想像してください。

```console
● ← ● ← ●
↓
●   ● ← ●
↓       ↑
● → ● → ●
```

この場合、現在生成中のルートに四方を囲まれてしまっています。
最後の一手をいくら再抽選しても生成中のルートにぶつかることを回避できません。

このようなループが発生した場合は、生成中のルートの壁をすべて破棄して最初から再抽選を行います。
これで壁生成のアルゴリズムができました。

## ソースとDemoページについて

GitHubに置いているソースは、マップ生成アルゴリズムがどのような挙動をしているかの確認用です。
javascriptのトランスパイルを行っても、基本的にはDemoページとまったく同じものが出力されます。

トランスパイルの手順は以下の通りです。

* GitHubからソースをクローンするかダウンロードする。
* `npm install`する。
* `npm run publish`する。
* distフォルダーにページ一式が出力され、ローカルサーバーが立ち上がる。

Demoページのデフォルトのマップサイズはドルアーガの塔のサイズを基準にしています。
フォームで入力するフロアサイズは柱の本数です。

マップ生成アルゴリズムはフロアサイズに影響されません。
サイズを拡大しても問題なく動作します。
レイアウトが破綻するためhtmlのinput側でフロアのWidthを40までに制限していますが、それ以上のサイズでも動作します。
（dungeonGenerator.jsのgenerate関数に1以上のサイズを与えれば動きます。）

文字列で出力を行っている関係上、スマホで表示するとレイアウトが崩れます。
マップチップを用意してcanvasに出力するとビジュアルの再現もできるはずです。

以上、ありがとうございました。かっこいいです。
元MSの中島聡さんに、アラサー未経験からのエンジニア転職を相談

#はじめに
この投稿は、ソフトウェアエンジニア中島聡さんの有料メルマガ『週間Life is beautiful』のFAQコーナーでエンジニアのキャリア相談をした際に、回答頂いた内容で「いいな」と思ったものを紹介するものです。メルマガの内容を転載することは、中島さんご本人からメルマガを通して承諾済みです。

#対象読者
未経験からITエンジニアへのキャリアチェンジを考えている人

#中島聡さんとは？
日本で有名なソフトウェアエンジニアといえば、Rubyのまつもとゆきひろさん、元ライブドアのCTO（ｱﾙﾌｧﾌﾞﾛｶﾞｰ）の小飼弾さん。辺りの名前が挙がると思いますが、僕が10年近く追いかけているのは、MS本社でWindows95やIEの設計をした中島聡さんです。IT業界では知る人ぞ知る存在でしたが、マイクロソフト時代に身につけたロケットスタートの仕事術（著者曰く、”界王拳”）を紹介したビジネス書「あなたの仕事はなぜ終わらないのか？」が10万部越えのベストセラーとなり、今ではIT業界以外の人たちからも認知されています。

#中島さんを知ったきっかけ
2011年に中島さんが出版された『エンジニアとしての生き方』は当時22歳の自分にとって衝撃でした。「こんな世界を覗いてみたい」それ以来、中島さんの有料メルマガ(週刊Life is Beautiful)を長年にわたって購読し、最近ではほぼ毎週、質問を送っています。2018年夏に「アラサー未経験からフリーランスエンジニアになる方法」について質問、回答を頂きました。未経験からフリーランスエンジニアへの道のりを模索していて、同じような悩みを持っている方の参考になればと思ったので共有します。

#筆者の質問
私は今30歳です。IT系の専門学校を卒業後日本の中小のSlerで5年働きましたが、そのほとんどが社内SEをしていたので開発経験がありません。しかもその後東南アジアでITと関係のない仕事に就いていましたから、実質0からプログラミング言語を学ぶことになります。プログラミング学習に関して、今はネット上の学習環境が整っているので学習自体はそれほど心配していませんが、問題はフリーランスとして活動できるようになるまでのプロセスです。

転職サイトやエージェントを通じて、未経験からフリーランスになる道のりを相談すると、"未経験者可の企業に勤務してプログラマーとしての数年実務経験を積むこと"が条件に上がります。正直、今から開発の現場に入って2～3年費やすよりは自学自習でプログラミングをバリバリ勉強して成果物を待って売り込んだり、ブログ(→派生して書籍)で発信した方が将来性に繋がりそうな気がしています。エンジニアとしてのキャリアプランについて中島さんのご意見をお聞かせ頂けると幸いです。場所にとらわれない働き方、は今後も若い世代を中心に注目されるでしょうし、それを比較的実現しやすい職種がソフトウェアエンジニアだと思っています。


#中島さんの回答
>フリーランスとして認められるには、大きく分けて2つのアプローチがあります。一つは、実際のプロジェクトで実績を上げて、また一緒に働きたいと思ってくれる人を一人づつ増やすこと。でもこれは、最初の取っ掛かりが難しいのです、必ずしも誰でも使える方法ではありません。2つ目は、オープンソースプロジェクトやブログでネット上の自分のプレゼンスを徐々に高めていく方法。Stackoverflow や Qiita も活用して自分の宣伝をしている人も大勢います。コードは嘘をつかないので、ここで良い仕事をすれば、それを履歴書代わりに活用することが可能になります


#追記：2018/12/01 「アラサー未経験からのエンジニア転職②」

他のメルマガ購読者の方からとても良い質問がありましたので、転載します。「ポテンシャル採用が難しい年齢からWeb業界に転職するにはどうすればいいのか」

#質問②
>初めて質問させていただきます。30代におけるエンジニアへの転向方法を教えていただきたいです。
現在経営コンサルタントをしておりまして、企業におけるAI活用（分析モデル作成と検証）や、RPA導入を支援した経験があります。その中で、導入支援ではなく、自分で技術を作り出したいという思いを強く持ちました。
もう30代ではありますが、自分がやるんだという強い思いがあれば絶対できると考えています。とは言え、年齢の影響かエンジニアのポテンシャル採用のようなポジションは中々見つからない現状です。
自分でアプリを作り出すとか、あるいは大学で研究するといった方法が良いのでしょうか。アドバイスいただければ幸いです。

#中島さんの回答
>３０歳を過ぎたからと言って、エンジニアへの転向が無理などと言うことはないので、そこは心配しないでください。プログラミングをするのに必須な数学さえしっかりと抑えておけば、やる気次第でいくらでも伸びることが出来ます。
ポテンシャル採用のようなものがないのは事実ですが、まずはソフトウェアを主たるビジネスをする企業に、なんらかの形で潜り込み、そこで環境を活用して勉強し、転籍するというのは悪くない戦略だと思います。
実際、Microsoft 時代にも、テスターや、カスタマー・サポート・スタッフとしてまずは Microsoft の社員になり、そこから勉強してソフトウェア・エンジニアになった人たちが何人もいました。

#追記：2019/01/18 「ﾌｨｰﾄﾞﾊﾞｯｸ：他職種でのWeb企業入社について」
先日、日本のそこそこ有名なWEB企業と面接し、質問②の回答を参考にして
「実務未経験だが、Webエンジニア志望。まず他の職種を経験してその後Web開発に転向したい」という旨を伝えました。結果通らなかったのですが、その際に「（意図的に）そういったキャリアを積んだ人の事例がほとんどなく、ミスマッチ」というフィードバックを受けました。入社したい企業がある場合、「他職種から転向した事例はあるか？」「なかった場合そういった人材を受け入れることについてどう思うのか？」を事前ヒアリングしておくといいかもしれません。

# 追記：2019/2/12 「4月からフリーランスになります」
先日、フロントエンド(Next.js)の受託開発案件に参画することが決まりました。4月から念願のフリーランスエンジニアです。きっかけはTwitterを経由して知り合った方からの紹介です。最初は正社員で実務経験を1年積んでからと思っていましたが、フォローしてくれる方と知り合いました。Twitterで学習内容を発信したり、オフ会を主催していたのが目に留まったようです。

以上です。今後もエンジニアのキャリアについて参考になる内容があれば、追加していきます。
Smalltalk(Pharo) である桁ごとにコンマ区切りにする

　ふと思い立ってある桁（以下の場合は3桁）ごとにコンマ区切りにするコードを書いてみました。
　もっとスマートにやるというか、そのものズバリの何かがあるような気がするのですが…。

　（追記）コメントにある通り `Integer >> printSeparatedBy: every: signed: base: on: ` がそのものズバリのようです。やっぱり、ありそうなものはあるものですね。

```smalltalk
|n stream|
n := 1.
stream := WriteStream with: ''.
1000000 asString reverse do: [:s | stream << s.
	(n = 3) ifTrue: [
		stream << ','.
		n := 1.
		]
	ifFalse: [
		n := n + 1
		].
	].

Transcript show: stream contents reverse; cr.
```
Numpyについて

# Numpy

まずはNumpyについて学んでいきましょう。

```
import numpy as np 
list_3 = [1, 2, 3, 4, 5, 6, 7, 8, 9]

array_c = np.array(list_3).reshape(3,3)

print(array_c)
```

出力結果では3行3列の３次元の数が返ってきます。このようにNumpyは様々な配列を返すことが出来ます。

.flatten()で戻します。

```
array_d = array_c.flatten()
print(array_d)
```

10の数は2行5列に変換

```
array_f = np.arange(10).reshape(2,5)
print(array_f)
```

単位行列

```
E_1 = np.identity(3)
E_2 = np.eye(6)

print(E_1)
print(E_2)
```

転置行列

```
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

arr_t1 = np.transpose(arr)
arr_t2 = arr.T

print(arr)
print(arr_t1)
print(arr_t2)
```

axisで繰り返す方向を指定

```
list_2 = np.arange(6).reshape(2,3)
array_1 = list_2.repeat(2, axis=0)
```

乱数を取得

```
random_array = np.random.rand(100)

print(random_array)
```

乱数を固定

```
np.random.seed(10)
A1 = np.random.randn(10)
```

機械学習でよく使用する内積の取り方

```
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
print(A)
print(B)

AB = np.dot(A, B)

print(AB)
```

外積

```
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

S = np.cross(a, b)

print(S)
```

演算(参考)

```
A = np.arange(1, 10).reshape(3,3)
B = np.arange(1, 4).repeat(3).reshape(3,3)
C = A + B 
print(C)
print(B)
```
np.eye(3)は１となる。

```
A = np.arange(1,10).reshape(3,3)
B = np.eye(3)* np.arange(1,4)
AB = np.dot(A, B)

print(AB)
```

３つの配列を書き表して、演算

```
A = np.array([-1, 1, 5, -1]).reshape(2,2)
B = np.array([4, -1, 5, -2]).reshape(2,2)
C = np.array([1, 1, 5, 1]).reshape(2,2)

ABC = np.dot(A, B).dot(C)
print(ABC)
```

.Tで転置を取ることができる。

```
A = np.arange(1,10).reshape(3,3)
B = np.arange(2,11).reshape(3,3)
print(A)
print(B)
AB = np.dot(A, B).T
print(AB)
```

```
A = np.arange(1,10).reshape(3,3).T
B = np.arange(2,11).reshape(3,3).T
print(A)
print(B)
AB = np.dot(A, B)
print(AB)
```

今日はここまで！
【PHP】外部ファイルを読み込む際のrequire、require_once、include、include_onceの使い分け

PHPで外部ファイルを読み込む場合、require、require_once、include、include_onceなどで読み込めますが、それぞれどういう違いがあるのか備忘録的に書いていこうと思います。

## require

> require は include とほぼ同じですが、失敗した場合に E_COMPILE_ERROR レベルの致命的なエラーも発生するという点が異なります。 つまり、スクリプトの処理がそこで止まってしまうということです。一方 include の場合は、警告 (E_WARNING) を発するもののスクリプトの処理は続行します。 

[参照元：PHP: require - Manual](https://php.net/manual/ja/function.require.php)
requireは指定されたファイルが読み込めない場合、Fatal Error(致命的なエラー)となり処理が停止されます。

## require_once

> require_once 文は require とほぼ同じ意味ですが、 ファイルがすでに読み込まれているかどうかを PHP がチェックするという点が異なります。 すでに読み込まれている場合はそのファイルを読み込みません。  

[参照元：PHP: require_once - Manual](https://secure.php.net/manual/ja/function.require-once.php)
require_onceはrequireと似ていますが、ファイルがすでに読み込まれている場合は再読み込みはしません。   

## include

> include は、ファイルを見つけられない場合に warning を発行します。一方 require の場合は、同じ場合に fatal error を発行する点が異なります。  

[参照元：PHP: include - Manual](https://php.net/manual/ja/function.include.php)
includeは指定されたファイルが読み込めない場合、Warning(警告)となりますがその先の処理はそのまま行われます。

## include_once

> include_once 命令は、スクリプトの実行時に指定 したファイルを読み込み評価します。この動作は、 include 命令と似ていますが、ファイルからのコー ドが既に読み込まれている場合は、再度読み込まれないという重要な違い があります。また、include_once は TRUE を返します。その名が示す通り、ファイルは一度しか読み込まれません。

[参照元：PHP: include_once - Manual](https://php.net/manual/ja/function.include-once.php)
include_onceはincludeと似ていますが、ファイルがすでに読み込まれている場合は再読み込みはしません。   

## requireとrequire_onceを実際に書いて比べてみる

require.phpとrequire_once.phpというファイルを作成してそれぞれ読み込んでみます。

```php:require.php
<?php
$test_require_str = 'hoge';
```

```php:require_once.php
<?php
$test_require_once_str = 'hoge';
```
作成したファイルを読み込む

```php
<?php
require 'require.php';
echo $test_require_str.PHP_EOL; // 出力結果はhoge

require_once 'require_once.php';
echo $test_require_once_str.PHP_EOL; // 出力結果はhoge

// 変数の値をそれぞれ変更してみる
$test_require_str = 'hoge_change';
$test_require_once_str = 'hoge_change';

// requireでの読み込みなので、通常通り読み込まれ変数の値が再度変更される
require 'require.php';
echo $test_require_str.PHP_EOL; // 出力結果はhoge

// require_onceでの読み込みなので、2回目は読み込まれず変数の値は変更されない
require_once 'require_once.php';
echo $test_require_once_str.PHP_EOL; // 出力結果はhoge_change
```

## requireとincludeを実際に書いて比べてみる

今度は、require.phpとinclude.phpというファイルを作成し、読み込み時にタイポしてしまった場合のテストをしてみたいと思います。

```php:require.php
<?php
// 今回は読み込みテストなので、中身は空にしてあります。
```

```php:include.php
<?php
// 今回は読み込みテストなので、中身は空にしてあります。
```

require.phpの読み込みに失敗した場合

```php
<?php
// require.phpのeを書き忘れて読み込み失敗した場合
require 'requir.php'; // この時点でエラーになり、処理が停止される
include 'include.php';

// 処理が停止されているので、当然出力されない
echo 'ファイルの読み込みをしました。';
```
include.phpの読み込みに失敗した場合

```php
<?php
require 'require.php';
// include.phpのeを書き忘れて読み込み失敗した場合
include 'includ.php';

// Warningにはなりますが、処理は停止されないので出力される
echo 'ファイルの読み込みをしました。';
```

## まとめ

以上、PHPで外部ファイルを読み込む際の構文について書いてみました。

### ポイント

- ファイルが読み込めない場合に処理を停止する場合は**require**を使用する。
- 一度しか読み込まなくていいものは **_once** をつける。

上記二つのポイントを抑えて、使い分けしていければいいと思います。
Androidで言語ごとにdrawableリソースを変更したい

こんにちは。私です。
アプリ開発中に私がスペイン語の画像やアイコンに差し替えるよう依頼頂いたが
うまくできずあたふたした記録です。


##この記事の対象者について
言語の切り替えについては他を当たってくださいごめんなさい。
ここでは

- 元々別の言語で表示されている。
- 切り替えまでは実装済みだが画像/アイコンを変更することができない。

という少数派の方への記事となっております。ご了承ください。

##drawableファイル
ドローアブル リソース：
>ドローアブル リソースとは、一般的に画面上に描画するグラフィックのことであり、getDrawable(int) などの API で取得できるものや、android:drawable や android:icon などの属性で別の XML リソースに適用するものがあります。ドローアブルには複数のタイプがあります。

ほう。
元々あった、英語用の画像やアイコンは**drawable-hdpi**に配置されています。
ここと同じ階層に**drawable-es-hdpi**を作成し、その中にスペイン語の画像やアイコンを配置して行きます。

それだけで綺麗にスペイン語の画像が表示されていることが確認できました！

##おまけ
今回はスペイン語だったため、「es」でしたが、ここのルールは

*「The language is defined by a two-letter ISO 639-1 language code, optionally followed by a two letter ISO 3166-1-alpha-2 region code (preceded by lowercase "r").」
(言語は2文字のISO 639-1言語コードで定義され、オプションで2文字のISO 3166-1-alpha-2地域コード（小文字の "r"で始まる）が続きます。)*
とあります。
ISO 639-1の言語コードは[こちら(wikipedia)](https://ja.wikipedia.org/wiki/ISO_639-1%E3%82%B3%E3%83%BC%E3%83%89%E4%B8%80%E8%A6%A7)から検索してください。

参考にさせて頂いたサイトは[Android アプリケーション開発](https://so-zou.jp/mobile-app/tech/android/resource/)さんの**代替リソース**の項目


##私ができなかった理由
単純に命名規則を理解できておらず、**drawable-hdpi-es**と作成していたため表示されておりませんでした…。

今回参考にさせて頂いたサイトは
[androidで言語毎にdrawableリソースを切り換えたい場合](http://sugi770.hateblo.jp/entry/2014/02/04/104400)です！
ファイル名での順番で表示されないとは落とし穴でした…。。

##締めの挨拶
この記事がどなたかの役に立ちましたら幸いです！
では皆さま、良いWorld Wide なAndoroid生活を！
Mac で Julia #8 Dates

前回に引き続きJuliaについてです。

[ドキュメント](https://docs.julialang.org/)に沿って試していきます。

よく使うのを試します。

### はじめに


```julia
julia> using Date
ERROR: ArgumentError: Package Date not found in current path:
- Run `Pkg.add("Date")` to install the Date package.

Stacktrace:
 [1] require(::Module, ::Symbol) at ./loading.jl:817

julia> using Dates
```

DateじゃなくてDatesなんですね。

```julia
julia> Dates.DateTime(2013)
2013-01-01T00:00:00

julia> DateTime(2013)
2013-01-01T00:00:00

julia> DateTime(2013,7)
2013-07-01T00:00:00

julia> DateTime(2013,7,1,12,30,59)
2013-07-01T12:30:59

julia> DateTime(2013,7,1,12,30,59,10)
2013-07-01T12:30:59.01

julia> DateTime(2013,7,1,12,30,59,10,1)
ERROR: MethodError: no method matching DateTime(::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64)
```

ミリ秒まで指定できました。

```julia
julia> Dates.DateTime(2020,2,29)
2020-02-29T00:00:00

julia> Dates.DateTime(2019,2,29)
ERROR: ArgumentError: Day: 29 out of range (1:28)
```

うるう年も大丈夫です。

### DateFormat

```julia
julia> df = Dates.DateFormat("y-m-d")
dateformat"y-m-d"

julia> Date("2015-12-31",df)
2015-12-31

julia> Date("2015",df)
2015-01-01

julia> Date("2015-12-31 12:30",df)
ERROR: ArgumentError: Found extra characters at the end of date time string
```

Dates型に変換するフォーマット指定です。足りないのは大丈夫でしたが余分なのはダメなようです。

```julia
julia> df = Dates.DateFormat("y/m/d H:M:S.s")
dateformat"y/m/d H:M:S.s"

julia> Dates.DateTime("2015/12/31 12:00:10.1",df)
2015-12-31T12:00:10.1
```

ミリ秒まで指定するにはこんな感じですかね。

### now()

```julia
julia> Dates.now()
2018-08-28T12:30:59.999
```

現時刻を表示できます。タイムゾーンはでないのかな？

```julia
julia> Dates.now(Dates.UTC)
2018-08-28T03:30:59.999
```

UTCのときはこうですね。Dates.JSTはエラーになりました。
基本LocalDateTimeなんですかね？

### Dates.Time 

```julia
julia> Dates.Time(12,30,10,50,50,50)
12:30:10.05005005
```

ナノ秒まで指定できました。

### unix2datetime 、datetime2unix

```julia
julia> Dates.unix2datetime(0)
1970-01-01T00:00:00

julia> Dates.unix2datetime(1234567890)
2009-02-13T23:31:30
```

UNIX時間を変換します。

```julia
julia> Dates.datetime2unix(DateTime("2009-02-13T23:31:30"))
1.23456789e9
```

逆はdatetime2unixですね。

### Durations/Comparisons

```julia
julia> d = (Dates.Date("2018-08-28") - Dates.Date("2020-01-01"))
-491 days

julia> typeof(d)
Day
```

引き算です。

```julia
julia> d1 = Dates.Date("2018-08-28")
2018-08-28

julia> d2 = Dates.Date("2020-01-01")
2020-01-01

julia> d1 == d2
false

julia> d1 != d2
true

julia> d1 > d2
false

julia> d1 < d2
true
```

普通ですねー

今日はこの辺で。
SES の設定方法

まずは Domain を登録します。

![c1.png](https://qiita-image-store.s3.amazonaws.com/0/45822/9946ddf4-29a7-ceb9-06a6-7d0e3de8a922.png)

この先は道なりにすすめて、Route 53 つかっているの `Use Route 53` をクリックします。

<img width="724" alt="スクリーンショット 2018-08-28 15.35.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/45822/fe007e0e-c894-bd17-b5cf-0aca3ab96680.png">


Status が verification になっていますので、放置します。
![c3.png](https://qiita-image-store.s3.amazonaws.com/0/45822/06e9f2db-d75e-14e5-d11e-fb87c69e5cdd.png)


つづいて、SMTP Settings から `Create My SMTP Credentials` します。
![c4.png](https://qiita-image-store.s3.amazonaws.com/0/45822/0fb52d41-e396-9aef-bbbe-2ec750c8e29e.png)

ユーザーを作成すると、ユーザー名とパスワードが取得できます。
![c5.png](https://qiita-image-store.s3.amazonaws.com/0/45822/3bd7f2c7-3a9e-9633-eda0-836fd5945ce0.png)


この状態で以下のようなスクリプトを実行すると、まだエラーでした。

```ruby
Mail.defaults do
  delivery_method :smtp,
                  address: 'email-smtp.us-east-1.amazonaws.com',
                  port: 587,
                  user_name: '{user_name}',
                  password: '{password}'
end
Mail.new do
  from 'info@{domain}'
  to '{適当メール}'
  subject 'test'
end.deliver!
```

```
Net::SMTPFatalError: 554 Message rejected: Email address is not verified. The following identities failed the check in region US-EAST-1: {適当メール}
from /Users/mochizuki/.rbenv/versions/2.3.3/lib/ruby/2.3.0/net/smtp.rb:965:in `check_response'
```

このあとは、サポートセンターから「サービス制限の緩和」を依頼するという流れです。

以上です。
GoのHTTPルータ BON

https://github.com/nissy/bon

以前、[Go製のHTTPルータを作って](https://qiita.com/ngc224/items/c43463378b876d365493)、特に使う機会がなくそのまま放置みたいな感じだったんですが、実戦投入する機会があったので、その際の感想を書きたいと思います。

- バグが出た
やはり実際使ってみると大きいバクから小さいバグまで結構出ました。

- 速度
速度がネックになることはあまりなかった

- 機能
思いもつかなかった、あんな機能やこんな機能ほしいというのが出てきて嬉しかった。

自作のツールが採用されるって嬉しいですね。
これからもブラッシュアップしてより良くしていこうと思います。
IntelliJ IDEAからディレクトリやファイルをEmacs（およびMagit）で開くことができるようにする

# はじめに

普段、プログラミングのIDEとして [IntelliJ IDEA](https://www.jetbrains.com/idea/) を使っていますが、**IDEA** から **Emacs** でファイルを開いたり、[Magit](https://github.com/magit/magit)（Emacs上で動くGitクライアント）でGit操作したりしたくなることがあります。

ただ、**IDEA** で開いていディレクトリやファイルを **Emacs** で開き直すのは面倒なので、**IDEA** から直接起動できるように設定します。

この設定をすると、↓のような感じで **Project** ツールウィンドウで開きたいディレクトリやファイルを右クリックして、*External Tools* から **Emacs** （および **Magit**）を起動できるようになります。

<img width="689" alt="usage.png" src="https://qiita-image-store.s3.amazonaws.com/0/94618/3f2eff19-362a-6f42-e6d1-3ab044beb8df.png">

# 前提

* Emacsがインストール済みであることが前提です。
  * 自分は **macOS** に [emacs-plusのCocoa版](https://github.com/d12frosted/homebrew-emacs-plus) をインストールしています。（参考 [Macへのspacemacsインストールメモ](https://qiita.com/crossroad0201/items/ca419e4dc2646667e669#emacs-plus%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)）

# 設定

* IDEAを起動し、*Preferences > Tools > External Tools* から、外部ツールの起動設定を追加するだけです。  
特にプラグインのインストールは必要ありません。
* この設定では、常に新しい **Emacs** プロセスが起動します。

## 選択したファイルをEmacsで開く設定

|設定項目|設定値|説明|
|----|----|----|
|Name|`Emacs`|任意の名前を付けます|
|Program|`/usr/local/bin/emacs`|emacsコマンドへのパスを指定します。|
|Arguments|`$FilePath$`|emacs起動時の引数として選択されたファイルへのパスを渡します。|
|Working directory|`$ProjectFileDir$`|たぶんどこでもいいです。|
|Open console for tool output|OFF|Emacs起動時に、IDEAのコンソールが開くと邪魔なのでOFFにしておきます。|

<img width="1017" alt="emacs.png" src="https://qiita-image-store.s3.amazonaws.com/0/94618/8287e5f1-0bb0-99ae-cb85-0e2ae3b3dfa0.png">


## 選択中のモジュールをMagitで開く設定

* Emacsにパッケージ [Magit](https://github.com/magit/magit) が追加済みであることが前提です。

|設定項目|設定値|説明|
|----|----|----|
|Name|`Magit`|任意の名前を付けます|
|Program|`/usr/local/bin/emacs`|emacsコマンドへのパスを指定します。|
|Arguments|`--chdir $ContentRoot$ -f magit-status`|Emacs起動時に、`--chdir $ContentRoot$`で選択されたファイルを含むモジュールのルートに移動し、`-f magit-statsu`で **Magit** を初期表示します。|
|Working directory|`$ProjectFileDir$`|たぶんどこでもいいです。|
|Open console for tool output|OFF|Emacs起動時に、IDEAのコンソールが開くと邪魔なのでOFFにしておきます。|

<img width="1045" alt="magit.png" src="https://qiita-image-store.s3.amazonaws.com/0/94618/a0985bd7-986c-84cc-c35a-4d54eaefb131.png">

----

以上です。
Nuxt.jsでNetlifyのForms使ってみた

Nuxt.jsとaxiosを使ってNetlifyのFormsでajax送信をしてみました。


## 全体像
コードの全体像は下記な感じです

```html:templateタグ
<div>
  <form v-if="isSubmit === false" @submit.prevent="onSubmit">
    <input type="text" v-model="name" name="name" >
    <input type="email" v-model="email" name="email">
    <textarea v-model="content" name="content"></textarea>
    
    <button type="submit">送信</button>
  </form>

  <div v-if="isSubmit === true">
    <p>サンクス</p>
  </div>

  <form name="contact" netlify netlify-honeypot="bot-field" hidden>
    <input type="text" name="name" />
    <input type="email" name="email" />
    <textarea name="content"></textarea>
  </form>
</div>
```

```javascript:scriptタグ
import axios from 'axios'

export default {
  data() {
    return {
      name: '',
      email: '',
      content: '',
      isSubmit: false
    }
  },
  methods: {
    onSubmit() {
      const params = new URLSearchParams()

      params.append('form-name', 'contact') // Forms使うのに必要
      
      params.append('name', this.name)
      params.append('email', this.email)
      params.append('content', this.content)

      axios
        .post('/', params)
        .then(() => {
          this.isSubmit = true
        })
    }
  }
}
```

要点だけ見ていきます。

## templateタグ

```html
<form name="contact" netlify netlify-honeypot="bot-field" hidden>
  <input type="text" name="name" />
  <input type="email" name="email" />
  <textarea name="content"></textarea>
</form>
```
Netlifyに認識してもらうために`netlify` `hidden`属性をもたせたフォームを作成します。
※SPAの場合は静的に記述する必要があります。

`netlify-honeypot`はreCAPTCHAを使用しないオプションです
postする時に`g-recaptcha-response`を含める方法もあるようなのですが、うまく行かなかったので教えていただけると嬉しいです。

## scriptタグ

```javascript
const params = new URLSearchParams()

params.append('form-name', 'contact') // Forms使うのに必要
      
params.append('name', this.name)
params.append('email', this.email)
params.append('content', this.content)

axios
  .post('/', params)
  .then((response) => {
    this.isSubmit = true
  })
```

実際にデータを詰めてpostする箇所は`form-name`を含めてあげる必要があるくらいで特に変わったところはありません。

こんな感じでajaxでFormsを使うことが出来ました。

##参考
https://www.netlify.com/docs/form-handling/#ajax-form-submissions
https://qiita.com/tatane616/items/f646e84fe4cdd9eac0de
Pythonでプログラミングを始めよう!　〜for文の使い方〜

#for文とは
今回は、for文の使い方を説明していきたいと思います。
for文とはプログラムの中でループ処理を行うために使う文です。
使用頻度が高いので使い方をしっかりと理解しておく必要があります。

#基本的なfor文の構文
for文の基本的な構文はこのようになります。  

```python

for 変数 in イテラブルオブジェクト:
    処理
```

Pythonでは他の言語でforeachと呼ばれる書き方が、
標準の書き方になります。

イテラブルオブジェクトとは具体的には、下記などがあります。

| 型            　　　　|内容               |
|:-----------------|:------------------|
|文字列              |'HelloWorld' 　　|
|リスト            |[1,2,3]   |
|辞書            |{'key1':'Hello', 'key2':'World'}   |
|タプル            |('Hello', 'World')   |
|セット            |{'Hello', 'World'}   |


リスト、辞書、タプル、セット詳細については[こちら](https://docs.python.jp/3/tutorial/datastructures.html)を参照ください。


サンプルコード①
文字列を１文字づつprintで表示してみよう！

```python
for x in 'HelloWorld':
    print(x)
```

#range関数を使用したfor文
for文で指定した回数ループしたいといった場合に,range関数を使います。

具体的な使い方は下記のとおりです。

```python
for x in range(5):
    print(x)
```

この場合、出力結果は0〜４の数字が表示されると思います。
もし０から出力されるのが嫌だとゆうことであれば、下記のようにして実行してみてください。

```python
x=1

for i in range(x, x+5):
    print(i)
```

#break-continue文を使ってみよう！
for文のなかで、ある条件の場合にループ処理を中止したいときには、break文を使います。
また、ある条件を満たしたら、それ以降の処理は行いたくないときには、continue文を使います。

具体的な使い方は下記のように実行してください。

```python
for x in 'abcdefg':
    if x == 'c':
        continue
    elif x == 'f':
        break
    print(x)
```

上記は、xが'c'の場合にcontinue, xが'f'の場合にbreakする、条件一致しない場合はxを表示する処理になります。

#enumerate関数を使ってみよう！
for文を回すと要素が一つずつ取り出されると思いますが、
同時に要素の番号も取得したいと行った場合にenumerate関数を使います。

具体的な使い方は下記のとおりです。

```python
for i, x in enumerate('abcdefg'):
    print("要素番号は{} ,要素は{}".format(i,x))
```

enumerate関数で要素番号を任意の数値から始めるには,
第２引数に任意の数値を渡します。

```python
for i, x in enumerate('abcdefg', 1):
    print("要素番号は{} ,要素は{}".format(i,x))
```

#zip関数を使ってみよう！
複数のイテラブルオブジェクトの要素を同時に取得したいなどの場合には、
zip関数を使いましょう！

具体的な使い方は下記のとおりです。

```python
for x, y in zip('Hello', 'World'):
    print(x, y)
```

#まとめ
今回はfor文の使用方法について説明させて頂きました。
if文につづきfor文についても、プログラミングのなかでは非常によく使いますので
しっかりと覚えてくださいね！

if文の記事は[こちら](https://qiita.com/fotome-developer/items/9a2b1e38c704d6b8afd5)

次回は配列、辞書についてに説明していきたいとおもいます！
CakePHP3でsaveで'atomic' => falseでrelation先までまとめて保存する際の返り値に注意

# CakePHP3でsaveで'atomic' => falseでrelation先までまとめて保存する際の返り値に注意

## なにこれ
無駄に長いタイトルでございますが、かなり状況が限定的なので。。。

CakePHP3でrelation先もまとめて保存するときってこんな感じで保存ができますよね

```php
$membersTable = TableRegistry::get('Members');
$data = [
    'name' => 'name',
    'hasone' => [
        'name' => 'name'
    ],
    'belongsto' => [
        'name' => 'name'
    ],
    'hasmany' => [
        [
            'name' => 'name'
        ]
    ],
];
$memberEntity = $membersTable->newEntity($data);
$result = $membersTable->save($memberEntity);

```

## saveに失敗したとき
saveに失敗したときは`$result`って`false`ですよね？  
普通に考えて・・・

しかし`false`が**返ってこないパターン**がありました。

- ベースのテーブルは保存に問題ないデータ
- relation先のデータはバリデーションを通過するデータ
- buildRuleで保存に失敗するデータ
- saveメソッドの`atomic`オプションが`false`

という条件が満たされたとき、$resultは`entity`が返ってき、さらに`$result->getErrors()`にはエラーメッセージが記載されているという状態になっていました。

コアは、、、追うのめんどくさかったのでもう追ってません。。。バグな気もするけど。。。

とりあえず最新のcakeで実験しても起きたので現状は発生すると考えて間違いないでしょう。

## 対応策
```php
$memberEntity = $membersTable->newEntity($data);
$result = $membersTable->save($memberEntity, ['atomic' => false]);
if (!$result || $result->getErrors()) {
    // save失敗
}
// 成功
```
みたいな感じで書けばいいんじゃね？
Linuxでポート番号からプロセスを調べてkillする


#Linuxでポート番号からプロセスを調べてkillする

####ポート番号から使用しているプロセスを表示する

    lsof -i:3000

####PID（プロセスID）を指定してプロセスを強制終了する

    kill -9 【PIDの数字】
>⬆︎-g（ジー）ではなく−９（数字の9）
FCM移行概要まとめ(とサーバ側対応)

全体把握のため調査した時のまとめ

## 前提
GCMのサーバおよびクライアントAPIを2019年4月11日付けで廃止するので、それまでに後継サービスのFCMに移行すること
http://www.atmarkit.co.jp/ait/articles/1804/13/news051.html
https://developers.google.com/cloud-messaging/gcm

## アップグレードに必要なこと(移行の流れ)
1. Firebase管理コンソール上からGCMプロジェクトをインポート(アプリ側)
2. FCM対応済みアプリをリリース(アプリ側)
3. サーバ側のエンドポイントをGCMからFCMに変更(サーバ側)

## 1. Firebase管理コンソール上からGCMプロジェクトをインポート(アプリ側)
- この手続きを行うと、アプリ側でFCM受信ができるようになる
- GCMも受信は可能(ゆえにインポートのタイミングと完全同時にサーバー側の設定も変えなければいけないわけではない)
- ただ、仮にインポート直後にGCMが受信できなくなったとしてもその作業を戻すことは~~できない~~できる

## 2. FCM対応済みアプリをリリース(アプリ側)
- 各々のアプリのプッシュの影響箇所を対応・リリース

## 3. サーバ側のエンドポイントをGCMからFCMに変更(サーバ側)
- 1.2.の対応後、特に問題なければサーバー側をリリース
- 1.で発行されたAPIキーを設定
- FCM受信の確認


#おまけ
以下は、自分はサーバー側の対応を行う感じだったのでその部分だけ具体的な内容を記載
pushサーバはphpのframeworkでライブラリはcomposerで管理

結論としてはエンドポイントが定義されていたのはライブラリ内のファイルで、FCM対応バージョンに上げて差し替える感じだった。

##サーバー側で対応した作業
php-gcmのライブラリをcomposerで更新すれば良い(その中で定義しているエンドポイントがFCMに向いている)
(名前はphp-gcmのまま)
具体的には以下のGCMのURLがFCMのURLに変わる

| GCM endpoint | FCM endpoint |
|:-:|:-:|
| gcm-http.googleapis.com/gcm/ | fcm.googleapis.com/fcm/ |
| gcm-xmpp.googleapis.com | fcm-xmpp.googleapis.com |

https://github.com/lkorth/php-gcm/commit/732d13ce427a8fc2feb4eac858c7e677d94e4033#diff-3384245c6f082c9d9369e4f183d2b8f1
https://developers.google.com/cloud-messaging/android/android-migrate-fcm

##気になった点
ライブラリのFCM対応のバージョンはdev-masterのみだった。
[Android] Material Button 使うとき、IllegalArgumentException予防。



```text
Caused by: java.lang.IllegalArgumentException: 
This component requires that you specify a valid TextAppearance attribute. 
Update your app theme to inherit from Theme.MaterialComponents (or a descendant).
```

style で　activity のThemeを変えましょう


```xml

<style name="Theme.Custom" parent="Theme.MaterialComponents.NoActionBar">
</style>
```
Tumblr テーマカスタマイズで infinite scroll がうまく動かないときメモ

テーマを拾ってきていじっていたら発生した問題ですが、調べると同様に困ってる人多そうだったのでメモしておきます。

`http://static.tumblr.com/wgijwsy/u2vm2hxv6/jquery.infinitescroll.min.js`

## 解法1
**HTML 内の infinitescroll スクリプトを更新する。**
調べてできてきたものではこれが多かったです。



## 解法2

css で解決する。
ページスクロールがトリガーになってるのかなと思い自分が試したらうまくったのはこれです。

```css
body {
  margin: 0;
  padding: 0;
  height: 120vh;
}
```

動きました https://anozon10.tumblr.com/tagged/yome
インライン外部表を試す（Oracle Database 18c）

Oracle Database 18c の新機能であるインライン外部表機能を試してみました。

# 外部表オブジェクト
外部表（EXTERNAL TABLE）オブジェクトは、表領域に格納された通常のテーブルとは異なり、データベースの外部に保存されたファイル等をテーブルと同様のSELECT文で検索できるようにするオブジェクトです。通常はCSVファイル等を直接テーブルとして参照したい場合に使います。

これまでのバージョンの外部表はあらかじめ CREATE TABLE 文を使って作成する必要がありました。このため参照するファイル名やディレクトリ・オブジェクト名は固定されていました。

```
SQL> CREATE TABLE extern1 
   (
      c1 NUMBER, c2 
      VARCHAR2(10)
   ) 
   ORGANIZATION EXTERNAL 
   (
     TYPE ORACLE_LOADER     
     DEFAULT DIRECTORY dir1
     ACCESS PARAMETERS 
     (
       RECORDS DELIMITED BY NEWLINE
       FIELDS TERMINATED BY '|'     
     )
     LOCATION ('data1-1.csv')
   )
   REJECT LIMIT UNLIMITED;

表が作成されました。

SQL> SELECT * FROM extern1;

        C1 C2
---------- ----------
       100 data1
       200 data2

```

# インライン外部表の作成
Oracle Database 18c では、あらかじめテーブルを作成せずに SELECT 文内に直接外部表のインターフェースを記述することができるようになりました。[こちら] (https://docs.oracle.com/cd/E96517_01/newft/new-features.html#GUID-7D707C76-4F3D-4AAE-B186-047217A36FB5) が新機能ガイドの記載です。
このためファイル名やディレクトリ名の指定を動的に記述することができます。下記は上記例と同じ処理を単一の文で実行しています。

```
SQL> SELECT * FROM EXTERNAL 
    (   
      (
        c1 NUMBER,
        c2 VARCHAR2(10)
      )     
      TYPE ORACLE_LOADER     
      DEFAULT DIRECTORY dir1
      ACCESS PARAMETERS 
      (
        RECORDS DELIMITED BY NEWLINE
        FIELDS TERMINATED BY '|'
      )     
      LOCATION ('data1-1.csv') 
      REJECT LIMIT UNLIMITED
    ) extern1;

        C1 C2
---------- ----------
       100 data1
       200 data2

```

# 制約
インライン外部表ではパーティション化を行うことができません。
Visual Studio Team ServiceのGitにSSHで繋がらない

## 超短期用忘備録

Visual Studio Team ServiceにSSH越しのGitで繋がらなくなった。
多分、またなんか工事してるんだろう。

すぐ直ると思うので、とりあえずの対処の仕方。

→ **ということで、直ったようなのでこの文章は意味がなくなりました。**

## DefaultCollectionを抜く

VSTSでSSHタブを選んでcloneするとこんな感じのエラーになる。

```shell
$ git clone yakumo@vs-ssh.visualstudio.com:v3/yakumo/DefaultCollection/Live2DSharp/Live2DSharp
Cloning into 'Live2DSharp'...
Enter passphrase for key '/home/xxx/.ssh/id_rsa': 
remote:
remote: Your Git command did not succeed.
remote: Details:
remote: 	Expected _full or _optimized, not 'Live2DSharp'.
remote:
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```

つれねぇ。

URLをちょっと変えて、 **DefaultCollection** の部分を抜くと、成功する。

```shell
$ git clone yakumo@vs-ssh.visualstudio.com:v3/yakumo/Live2DSharp/Live2DSharp
Cloning into 'Live2DSharp'...
Enter passphrase for key '/home/xxx/.ssh/id_rsa': 
remote: 
remote:                    vSTs   
remote:                  vSTSVSTSv
remote:                vSTSVSTSVST
remote: VSTS         vSTSVSTSVSTSV
remote: VSTSVS     vSTSVSTSV STSVS
remote: VSTSVSTSvsTSVSTSVS   TSVST
remote: VS  tSVSTSVSTSv      STSVS
remote: VS   tSVSTSVST       SVSTS
remote: VS tSVSTSVSTSVSts    VSTSV
remote: VSTSVST    SVSTSVSTs VSTSV
remote: VSTSv        STSVSTSVSTSVS
remote:                VSTSVSTSVST
remote:                  VSTSVSTs
remote:                    VSTs    (TM)
remote: 
remote:  Microsoft (R) Visual Studio (R) Team Services
remote: 
remote: Found 124 objects to send. (104 ms)
Receiving objects: 100% (124/124), 309.73 KiB | 357.00 KiB/s, done.
Resolving deltas: 100% (22/22), done.
```

### ちなみに

上記のリポジトリは存在しないのでよろしくお願いします。
IBMCloudでvirtualserver（仮想環境）を構築してみた

# 備忘録
IBMCloudでvirtualserver（仮想環境）を構築してみたので、備忘録の為に記載。

## 環境
mac 10.13 High Sierra


## 公開鍵・秘密鍵を作成する
`ssh-keygen -t rsa`
`cat ~/.ssh/`に公開鍵が格納される。  
※コマンド + シフト + カンマ「.」で隠しフォルダ表示 

### configファイル作成

```config
 Host server_name
 User root
 HostName 169.***.***
 Port 22
 IdentityFile ~/.ssh/**_id_rsa #秘密鍵のファイル
 ServerAliveInterval 60
```

## 手順   
①IBMCloud インフラストラクチャーより*virtualserver*インスタンス作成
②公開鍵をIBMCloudにアップロード（GUIより）
③rootでssh接続（何故か作成したユーザーでは初回ログインできない）`ssh server_name`
④パスワードを聞かれるので、入力（GUIに記載）


## 以上
少し手間がかかったので、記載しています。　
ちなみに料金体系を問い合わせると、電源OFFにしても料金はかかるそう。。。　
数カ月後には電源OFFでも料金がかからないようにすると言っていたが。（※2018/08/28現在）
「じゃあ必要な場合のみ運用したい場合は」と聞くと、サーバーイメージを保存しておき、それをマウントして再構築して下さいとのこと。
Chainer v4 PILからNumpy NumpyからPILの変換


モジュールインポート

```python
from PIL import Image
import numpy as np
```

PIL→Numpy

```python

img = Image.open("aaa.png")
numpyArray = np.asarray(img).astype("f").transpose(2, 0, 1) / 128 - 1.0
```

Numpy→PIL

```python
array = np.asarray(((numpyArray + 1) * 128).astype("i").transpose(1, 2, 0))
img = Image.fromarray(np.uint8(array))
img.show()
```

特にfromarrayでuint8にするのをよく忘れるので書き留めます。
誰かの役に立つことを祈ります。

まだ始めたばかりなので間違っていたらご指摘お願いします。
Google Apps Scriptデプロイ時に発生したclaspの「Push failed. Errors」

clasp push時に以下エラーが出たのでメモ。

```
$ clasp push
Push failed. Errors:
The service is currently unavailable.
```

サーバー側の問題っぽい。
しばらく時間置いて再度試してみたら何事もなくpushできた。