OmniAICreator/Qiita-1.07M huggingface dataset:
jsdoでtensorflow.js その6

#概要

jsdoでtensorflow.jsやってみた。
ウェイトとバイアスを注入してみた。

#写真

![image.png](https://qiita-image-store.s3.amazonaws.com/0/18104/1c54d60b-6914-8431-3537-4fecbcbd3635.png)


#サンプルコード

```
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
function draw(data, n) {
	var hc = n * 100 + 100;
    ctx.strokeStyle = "#f00";
    ctx.lineWidth = 1;
	ctx.moveTo(0, hc);
    for (var i = 1; i < 20; i++) 
    {
        ctx.lineTo(i * 10, hc - data[i] * 30);
    }
	ctx.stroke();
}
const buffer = tf.buffer([20, 1]);
const buffer2 = tf.buffer([20, 1]);
const tx = [];
const ty = [];
for (var i = 0; i < 20; i++) 
{
    var x = i / 3.0;    
    var y = Math.sin(x);
    tx.push(x);
    ty.push(y);
    buffer.set(x, i, 0);
    buffer2.set(y, i, 0);
}
draw(ty, 0);
const train_x = buffer.toTensor();
const train_y = buffer2.toTensor();
var arr0 = [1.1656082, -2.0180476, -6.9387307, 3.3653135, -1.7032033, -2.8969588, 0.0565524, -9.5316219, -5.7146306, -2.8060255, -0.3085915, -6.3642092];
var arr1 = [[0.6203325, -1.027319, 1.8841791, -3.2817535, 1.2214272, 0.9679314, 1.4196726, 7.171823, 1.3714954, 3.7268815, 0.0598045, 1.1944624],];
var arr2 = [-0.2928229];
var arr3 = [[-1.2655445], [-1.0401167], [0.2071615], [-0.4695872], [-2.6633599], [-0.5835096], [1.2490041], [1.2825323], [-1.5088843], [0.6767025], [0.0224434], [1.6849496]];
const w1 = tf.variable(tf.tensor(arr1));
const b1 = tf.variable(tf.tensor(arr0));
const w2 = tf.variable(tf.tensor(arr3));
const b2 = tf.variable(tf.tensor(arr2));
function func(x) {
    const h = tf.tanh(x.matMul(w1).add(b1));
    return tf.tanh(h.matMul(w2).add(b2));
}
const preds = func(train_x).dataSync();
draw(preds, 1);
var out1 = document.getElementById('src');
out1.value += b1 + '\n';
out1.value += w1 + '\n';
out1.value += b2 + '\n';
out1.value += w2 + '\n';



```

#成果物

http://jsdo.it/ohisama1/CIcn

以上。
iOSアプリのプライバシーポリシーをFirebase Hostingでデプロイ

この記事の内容は、お題の通りです。
2018年10月3日から全てのアプリに[**プライバシーポリシー**](https://itunespartner.apple.com/jp/apps/news/100002362)が必要になりました。
Hostingが可能なサービスはいくつか知っていたのですが、開発中のアプリがFirebaseを使用していたのでFirebaseを利用します。
※Firebaseにプロジェクトが登録してある前提で書いてます。
※言葉使いや間違いなどありましたら、指摘、伝えてもらえると嬉しいです。

---
###まずはプライバシーポリシーを用意。
以下のサービスを利用しました。
[App Privacy Policy Generator](https://app-privacy-policy-generator.firebaseapp.com/)

・アプリの名前
・どんなアプリか
・会社か個人か
・どんなデータを採集するのか
・プライバシーポリシーに含めるサードパーティ
・プラットフォーム

を入力すると、よしなにプライバシーポリシーを作成してくれます。
出来上がったhtmlをダウンロード。

---
###FirebaseのコンソールからHostingを選択
<img width="1440" alt="スクリーンショット_2018-10-20_7_09_16.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/255984/e71760b1-64bb-ced1-3306-149d9aede504.jpeg">

使ってみるを選択で導かれるままにコマンドを入力
<img width="1440" alt="スクリーンショット_2018-10-20_7_09_41.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/255984/db6defa3-e5fe-d35c-b3fa-cec47aad3256.jpeg">
<img width="1440" alt="スクリーンショット_2018-10-20_7_09_44.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/255984/6ed1251a-8e65-f562-cd89-e0d4a80d3477.jpeg">

ルートディレクトリでfirebase initするとデプロイするファイルを置くディレクトリが作成され、いくつか質問に答えます。
記憶が曖昧なんですが

・Firebaseのどのサービス使うの？　→　Hosthig
・ディレクトリの名前は？　→　yes/noと勘違いしてyというディレクトリ完成
・index.htmlを読み込む？　→　yes

だったと思います。
で、プライバシーポリシーのhtmlファイルを作ったディレクトリに配置してデプロイするんですが、Functionsなど他のサービス使ってたらfirebase deployだとまるごとになって遅いのでfirebase deploy --only [ディレクトリ名]と入力しました。

---
urlを下の画像の箇所に入力して完了かと思います。
<img width="1440" alt="スクリーンショット_2018-10-20_7_43_18.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/255984/1aacc253-e05b-4c4e-3d57-dda37324ef48.jpeg">

---
###終わってみて
プライバシーポリシーが個人の無料アプリにも必須になったのが10月3日からでしたし、プライバシーポリシーの作成も初めてでしたがすんなり行きました。
結構適当に作ったつもりでしたがリジェクト内容にプライバシーポリシーが入ってない事をみても、他の記事でも言われている様にあればOKみたいな適当な感じなんですかね。。
google-home-notifier でエラーが起きるようになった

[google-home-notifier](https://github.com/noelportugal/google-home-notifier)は、Google Home にテキストを読み上げさせるNode.jsパッケージだ。

普通に使っていたが、ある日を堺に、以下のようなエラーが起きるようになってしまった。

```
Error: get key failed from google
```

原因は、 issue と pull request がすでにある。詳しくはそちらに。わずかな変更だが、現時点ではまだマージされておらず、なかなかマージされないかもしれない。

issue
https://github.com/noelportugal/google-home-notifier/issues/46
pull request
https://github.com/noelportugal/google-home-notifier/pull/47/files

原因は、Google翻訳のAPI仕様が変わったからだ。 google-home-notifier が使う google-tts-api パッケージ側で追従する対応がなされた。

暫定的に、すぐに使いたい人は、google-home-notifierをクローンしてきて google-tts-api のバージョンを書き換えれば良い。

> Before
>
  "dependencies": {
      :
    "google-tts-api": "0.0.2",
      :
  }
> After
>
  "dependencies": {
      :
    "google-tts-api": "0.0.3",
      :
  }

---

そもそも、google-home-notifierやgoogle-tts-apiは、Google翻訳のWebサイトをスクレイピングしてAPIだけ利用するというもので、あまり良いやり方では無い。少なくとも非公式だ。もし使う場合は、突然使えなくなる覚悟が必要だろう・・・。

シンプルな読み上げ機能を、もう少しクリーンな方法で実装するならば、GCPの [Cloud Text-to-Speech](https://cloud.google.com/text-to-speech/) や、 AWSの [Amazon Polly](https://aws.amazon.com/jp/polly/) がある。
コンストラクタを経由しないオブジェクトの生成


以下の場合には、コンストラクタが使われないで、オブジェクトが生成される
 ・cloneする時
 ・deserializeする時

このプログラムを実行して、「コンストラクタ」が一度しか表示されないことを確認する


```Tips0013.java
package jp.avaj.lib.algo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import jp.avaj.lib.test.L;

class Tips0013 {
  public static void main(String[] args) throws CloneNotSupportedException, FileNotFoundException, IOException, ClassNotFoundException {
    //
    Data data = new Data();
    //
    L.p("cloneを実行する");
    Data copyData = (Data)data.clone();
    //
    L.p("Serializeを実行する");
    String filename = "./Tips0013.txt";
    ObjectOutputStream oos = null;
    try {
      oos = new ObjectOutputStream(new FileOutputStream(filename));
      oos.writeObject(data);
    }
    finally {
      oos.close();
    }
    L.p("desirializeを実行する");
    ObjectInputStream ois = null;
    try {
      ois = new ObjectInputStream(new FileInputStream(filename));
      Data newData = (Data)ois.readObject();
    }
    finally {
      ois.close();
    }
    // ワークファイルを削除しておく
    File workFile = new File(filename);
    workFile.delete();
    L.p("処理終了");
  }

  private static class Data implements Cloneable,Serializable {
    private String v;
    public Data() {
      v = "aaaa";
      L.p("コンストラクタ");
    }
    public Object clone() throws CloneNotSupportedException {
      return super.clone();
    }
  }
}
```

結果は次のとおり。

```tips0014.txt
コンストラクタ
cloneを実行する
Serializeを実行する
desirializeを実行する
処理終了
```
jsdoでtensorflow.js その5

#概要

jsdoでtensorflow.jsやってみた。
backendを、呼び出してみた。

#写真

![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/Q/V/V/QVVM.jpg?t=1539988164)

#テストコード

```
var zeroTensor = K.getScalar(0.0);
zeroTensor.print();
var one = K.getScalar(1.0);
one.print();
```

#サンプルコード

```
var K = tf.backend;
var isObject = function(value) {
    if ((Object.prototype.toString.call(value) === '[object Object]') && (!Array.isArray(value)) && (value !== null) && (typeof value !== 'undefined'))
    {
        return true;
    }
    return false;
};
var objToString = function(obj) {
    var items = JSON.stringify(obj).split(',');
    items = items.map(function(element, index, array) {
        return element.replace(/(.+:)(.*)/, function(string, capture1, capture2) {
            return capture1.replace(/\"/g, '') + capture2;
        }).replace(/:/g, ': ');
    });
    return items.join(', ');
};
var consoleExt = {};
consoleExt.originalConsoleLog = console.log;
consoleExt.result = '';
consoleExt.delimiter = ';';
consoleExt.logOutput = true;
consoleExt.log = function(message) {
    if (consoleExt.logOutput) 
    {
        alert(message);
    }
    if (isObject(message)) 
    {
        consoleExt.result += objToString(message) + consoleExt.delimiter;
    } 
    else    
    {
        consoleExt.result += message + consoleExt.delimiter;
    }
};
consoleExt.hook = function() {
    if (consoleExt.originalConsoleLog === console.log)
    {
        console.log = consoleExt.log;
    }
};
consoleExt.unhook = function() {
    if (consoleExt.originalConsoleLog !== console.log) 
    {
        console.log = consoleExt.originalConsoleLog;
    }
};
consoleExt.hook();
consoleExt.result = '';
consoleExt.logOutput = true;

var out = document.getElementById("out");
var src = document.getElementById("src"); 
out.innerHTML = '';
function run() {
    try
    {
        eval(src.value);
    }
    catch(e)
    {
        var b = document.createElement('b');
        b.appendChild(document.createTextNode(e));
        b.style.color = '#F00';
        out.appendChild(b);
    }
}

```

#成果物

http://jsdo.it/ohisama1/QVVM

以上。
文章の中から重要な文を抽出する．

###基本的なプロセス
1，tfidfで文章の重要な単語をあぶり出します．
2，その単語が出現している文のなかでより多く出現した文を重要な文とします．
最も出現した文というのは複数あるかもしれません．そこだけ注意してください．

その前段階として文章を文に区切ったりしますが，適宜コードを眺めてご理解ください．

###利用した小説
著作権は私にあるので，ご使用は自由に．
これをコピーしてtxtファイルにしてcolabに渡してやります．
https://syosetu.com/usernoveldatamanage/top/ncode/748763/noveldataid/7054824/

コード
https://nbviewer.jupyter.org/gist/Ooshita/1eaf18bacf8b71a35379ce1078c66d13

###推定された文
![スクリーンショット 2018-10-20 5.39.44.png](https://qiita-image-store.s3.amazonaws.com/0/33329/34162c8b-3451-6ddb-027e-3c04678cbe42.png)
イメージ図（人力で作りました．）

###最後に
この手法は結局，文章に共起性が無いと利用できないのと，ある程度の大きさの文章が必要になります．
また果たしてこれが重要と言えるのかと疑問がありますが，それは共起性という観点でみるとそう言えると思います．

また，短文の文章である，Tweetの何処が一番重要なのかというような判定はできません．

そのような短文の文章の何処が重要かを確率的に出す手法を現在研究中です．
できたらarXivかなんかにあげます．（あげたい）
Javaを利用したスクレイピング実践①

##Javaを利用したスクレイピング①

参考/サイト
ITのおもちゃ箱 さま　(https://ittoybox.com/archives/385)
するめとめがね さま　(http://tm8r.hateblo.jp/entry/2013/11/26/125937)
Terry③ さま　（https://qiita.com/Terry3/items/0c1829130111967773bf）
takahiroSakamoto さま　（https://qiita.com/takahiroSakamoto/items/c2b269c07e15a04f5861）

####バックボーン
未経験者
java文法習いたて。
備忘録的な形での運用なので、真似したからと言って上手に行くわけじゃないので。
むしろ皆様から教えを請いたい。


####Scraping準備
スクレイピングにはjsoupというのを利用すればいいらしいとは聞いていたので、利用するための準備。
なお私はEclipsのphotonを利用している。

以下サイトよりjarファイルをダウンロード
(https://jsoup.org/download)

パッケージ"Scraping"を作成し、直下に"lib"ファイルを作成。
"lib"ファイル内に先ほどのjarファイルをコピー。
![1.PNG](https://qiita-image-store.s3.amazonaws.com/0/304664/136d6013-9d7b-0185-46f7-9959c6dedc9b.png)

そしてクラスパスを通す。
このあたりは『ITのおもちゃ箱』さまに画像付きで説明があります。
非常にありがたい。

####Scraping記述。
まずは導入したjsoupのインポートから

```
import java.io.IOException;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
```

jsoup文はtry-catch文で囲む必要があるらしいので、IOExceptionも同時にインポートしました。

さてスクレイピングの対象ですが、まだよくわからない部分も多いのでまずは『Yahoo!Japan』様のトップページをスクレイピングしてみましょう。

```
	public static void main(String[] args) {
		
		//try-catch文が必要
		try {
			
			//Document A = Jsoup.connect("url").get(); urlにスクレイピング対象
			Document doc = Jsoup.connect("https://www.yahoo.co.jp/").get();
			
			//Elements B = A.select("タグ"); この形でソースに含まれるタグで指定された範囲を書き出す。
			Elements elm = doc.select("title");
			
			//拡張for文
			for(Element elms : elm) {
				String title = elms.text();
				System.out.println(title);　//結果　Yahoo!JAPAN
			}
		
			//例外処理
		}catch(IOException e) {
			e.printStackTrace();
		}
	}
}
```
jsoupにはconnectメソッドとselectメソッドがあるらしく、それぞれurlの指定とタグの指定ができるとのこと。
urlのタグを指定することで、javascriptなど使われていないものは簡単にスクレイピングすることができる。

なるほど、なんとなくわかったぞ、と他のサイトで実験。

どうせなら表形式で違いが分かりやすいものをと、日本考古学協会さまの2018年度講義一覧というページをスクレイピングしてみる。
対象ページ（http://archaeology.jp/learning/university/2018kougiichiran/#）

コードはほとんど変わらないけど


	public static void main(String[] args) {

		//try-catch文が必要
		try {

			//Document A = Jsoup.connect("url").get(); urlにスクレイピング対象
			Document doc = Jsoup.connect("http://archaeology.jp/learning/university/2018kougiichiran/#").get();

			//Elements B = A.select("タグ"); この形でソースに含まれるタグで指定された範囲を書き出す。
			Elements elm = doc.select("tbody");

			//拡張for文
			for(Element elms : elm) {
				String title = elms.text();
				System.out.println(title);
			}

			//例外処理
		}catch(IOException e) {
			e.printStackTrace();
		}
	}


この場合はコンソールに出力される結果は

<コンソール>
●國學院大學北海道短期大学部 ＜国文学科＞ 考古学A・B【夏季集中】 兼任講師 青木敬 ●札幌学院大学 考古学A(前期) 特任講師 大塚宜明 考古学B(後期) 非常勤講師 越田賢一郎 考古学研究法(後期) 特任講師 大塚宜明 考古学実習 教授 臼杵勲 特任講師 大塚宜明 文化財概論（後期） 教授 臼杵勲 北方の歴史・文化 非常勤講師 澤井　玄 北海道史研究Ｂ（後期） 教授 臼杵勲 ・・・・

と横にずらっと並んだ形。

これだと見にくいので、

			//Elements B = A.select("タグ"); この形でソースに含まれるタグで指定された範囲を書き出す。
			Elements elm = doc.select("tbody tr");
("tbody tr")と行を分けているタグを追加してみると

<コンソール>
●國學院大學北海道短期大学部
＜国文学科＞
考古学A・B【夏季集中】 兼任講師 青木敬
●札幌学院大学
考古学A(前期) 特任講師 大塚宜明
考古学B(後期) 非常勤講師 越田賢一郎
考古学研究法(後期) 特任講師 大塚宜明
考古学実習 教授 臼杵勲
...

とほぼホームページ通りに書き出すことができるようだ。


いったんはここで実践①終了。
最終目標は競馬情報などをスクレイピングできるようになること。
基本的にjavascriptが邪魔をするので、どう読み取るかがポイントになりそう。
RStanのインストール時に C++14 standard requested but CXX14 is not defined と怒られた時の対処

#はじめに
友人がRStanの環境作りにはまり、それを解決する日本語の記事が見当たらなかったのでここに残しておきます。

#環境
OS:Windows8
R:3.5.1
RStdio:1.1
Rtools:3.4 (g++:4.9.3)
RStan:2.17.3

#インストール手順
基本的には以下のURLに従って進めます。
[RStan Getting Started (Japanese)](https://github.com/stan-dev/rstan/wiki/RStan-Getting-Started-(Japanese))
しかし、RStanのインストールまで済ませてモデルのフィッティングを行う以下のコードを実行すると

```R:console
fit <- stan(file = '8schools.stan', data = schools_dat,
            iter = 1000, chains = 4)
```
次のエラーが出て終了しました。

```
Error in compileCode(f, code, language = language, verbose = verbose) :
Compilation ERROR, function(s)/method(s) not created! Error in .shlib_internal(commandArgs(TRUE)) :
C++14 standard requested but CXX14 is not defined
```
#原因
RToolsによってインストールされるg++のバージョンが4.9.3だったのですが、RからC++14を要求されているらしく、4.9.3のバージョンでは実行時にオプションをつけないとc++14を利用できないことが原因でした。
#対処
結果的には、以下のURLに従って ~/.R/Makevars ファイルを生成することで無事にエラーを解消することができました。
[Installing RStan on Windows](https://github.com/stan-dev/rstan/wiki/Installing-RStan-on-Windows#configuration)
このページ内の以下のコードをコンソールで実行することによって解決できました。

```R:console
dotR <- file.path(Sys.getenv("HOME"), ".R")
if (!file.exists(dotR)) 
  dir.create(dotR)
M <- file.path(dotR, "Makevars")
if (!file.exists(M)) 
  file.create(M)
cat("\nCXX14FLAGS=-O3 -Wno-unused-variable -Wno-unused-function",
    "CXX14 = g++ -std=c++1y",
    file = M, sep = "\n", append = TRUE)
```

このコードでは、~/.R/に以下のMakevarsファイルを生成します。

```:Makevars

CXX14FLAGS=-O3 -Wno-unused-variable -Wno-unused-function
CXX14 = g++ -std=c++1y

```
Rのコードの実行時にMakevarsにC++のコンパイルコマンドを読みにくるようです。
今回引っかかったのはC++14の利用だったので、最適化オプションであるCXXFLAGSは無くてもいいかもしれません（まああったほうがいいとは思います）。

#もう一つ引っかかったこと
実は上のコンソールコマンドを実行する時に`Sys.getenv("HOME")`でホームディレクトリが正しく取得できなかったのですが、これはユーザー名を日本語にしていたためパスに日本語が含まれていたことが原因でした。変えるのにレジストリいじる必要があってとてもめんどくさかったのでwindowsは悪(過激派)(ごめんなさい)
なぜかRustで言語処理100本ノック ～第2章 後編～

[前編はこちら](https://qiita.com/kbone/items/2d947090fb152ef9d0fb)

# 第2章: UNIXコマンドの基礎
## 16. ファイルをN分割する
> 自然数Nをコマンドライン引数などの手段で受け取り，入力のファイルを行単位でN分割せよ．同様の処理をsplitコマンドで実現せよ．

`split -l $N hightemp.txt`相当なのですが、このコマンドだとファイルが自動生成されるのに対して、今回は`Vec<String>`で返すようにしました(実質等価なので許してください)。スライスを用いれば`join`が使えるんですね。

```rust
pub fn split_file(path: &Path, n: usize) -> Result<Vec<String>> {
    let file = File::open(path)?;
    let br = BufReader::new(file);
    let lines = br.lines().collect::<Result<Vec<_>>>();
    lines.and_then(|lines| Ok(lines.chunks(n).map(|chunk| chunk.join("\n")).collect()))
}
```
## 17. １列目の文字列の異なり
> 1列目の文字列の種類（異なる文字列の集合）を求めよ．確認にはsort, uniqコマンドを用いよ．

`cat col1.txt | sort | uniq`これと同じ結果になれば良いわけですね。`unwrap`しないように書いたら結構な長さになってしまいました。

```rust
pub fn get_column_differences(path: &Path, n: usize) -> Result<HashSet<String>> {
    let file = File::open(path)?;
    let br = BufReader::new(file);
    let mut result = HashSet::new();
    br.lines().map(|line|
        line.and_then(|line|
            line.split_whitespace().map(|word| word.to_string()).nth(n)
            .ok_or(Error::new(ErrorKind::NotFound, format!("the column {} is not found.", n)))))
    .for_each(|line| match line {
        Ok(line) => { result.insert(line.to_string()); },
        Err(e) => eprintln!("{}", e)
    });
    Ok(result)
}
```

## 18. 各行を3コラム目の数値の降順にソート
> 各行を3コラム目の数値の逆順で整列せよ（注意: 各行の内容は変更せずに並び替えよ）．確認にはsortコマンドを用いよ（この問題はコマンドで実行した時の結果と合わなくてもよい）．

ファイル内容を見ると実は反転させるだけで結果が一致してしまうのですが、それはそれとして。こまんどのばあいとことなることがあるのは、安定ソートかどうかで結果が少し変わってしまうからですね。一応、相当するコマンドは`sort hightemp.txt --key=3`です。

```rust
pub fn sort_by_column(path: &Path, n: usize) -> Result<Vec<String>> {
    let file = File::open(path)?;
    let br = BufReader::new(file);
    let lines = br.lines().collect::<Result<Vec<_>>>();
    lines.and_then(|mut lines| {
        lines.sort_by(|a, b| a.split_whitespace().nth(n).cmp(&b.split_whitespace().nth(n)));
        Ok(lines)
    })
}
```

## 19. 各行の1コラム目の文字列の出現頻度を求め，出現頻度の高い順に並べる
> 各行の1列目の文字列の出現頻度を求め，その高い順に並べて表示せよ．確認にはcut, uniq, sortコマンドを用いよ．

`cut --field=1 hightemp.txt | sort | uniq -c | sort -r`相当なのですが、今回`HashMap`を使った影響で同数だと順序不定になるようです。

```rust
pub fn sort_by_frequency(path: &Path) -> Result<Vec<String>> {
    let file = File::open(path)?;
    let br = BufReader::new(file);
    let lines = br.lines().collect::<Result<Vec<_>>>();
    let mut counter: HashMap<String, usize> = HashMap::new();
    lines.and_then(|lines|
        Ok(lines.into_iter().for_each(|line| {
            let key = line.split_whitespace().next().unwrap_or("");
            if counter.contains_key(key) {
                *counter.get_mut(key).unwrap() += 1
            } else {
                counter.insert(key.to_string(), 1);
            }
    }))).and_then(|_| {
        let mut tmp = counter.into_iter().collect::<Vec<_>>();
        tmp.sort_by(|a, b| b.1.cmp(&a.1));
        Ok(tmp.into_iter().map(|(k, _)| k).collect())
    })
}
```
`HashMap`の更新ってもう少しスッキリ書けないものかと思ってしまいました。

# 第2章の感想
UNIXコマンドの中でもファイル関係を扱う影響で、またできる限り`unwrap`しないようにした結果、`Result`及び`Option`の扱い方が自然とわかってきました。この章をやっただけでも十分な収穫な気がします。
CentOS 7.x でのIPマスカレード設定

## 概要

CentOS 7.x でのNAPT（IPマスカレード）設定の備忘録。

### 対象読者

- グローバルIPを持たないホストBから、外部へ通信できるホストAを踏み台に疎通を行いたい。
- 例）Webサーバーとのみ疎通可能なDBサーバーで *yum install* したい時など。

<pre>
[ホストB] 例) DBサーバー
   | eth0 192.168.1.101
   |
   | eth0 192.168.1.1
[ホストA] 例) Webサーバー
   | eth1 x.x.x.x
   |
[example.com]
</pre>

---

### 事前の確認

ホストBではping, yum等が失敗するはず。

```shell
# ping google.com
  失敗
# yum install mariadb-server
  失敗
```

ホストAでは下記の様なデフォルト設定のままであることを確認。

```shell
# firewall-cmd --get-active-zones
public
  interfaces: eht0 eth1
#  firewall-cmd --direct --get-all-rules
ipv4 filter INPUT 0 -p tcp -m multiport --dports ssh -m set --match-set fail2ban-sshd src -j REJECT --reject-with icmp-port-unreachable
```

### 設定

ホストAでは *firewall-cmd* での変更のみ。

```shell
// eth0 の firewalld zone を external に変更
# firewall-cmd --zone=external --change-interface=eth0
success
// externalゾーン に IPマスカレード設定
# firewall-cmd --zone=external --add-masquerade --permanent
success
// 変更の反映
# firewall-cmd --reload
success

// 変更後の確認
# firewall-cmd --get-active-zones
external
  interfaces: eht0
public
  interfaces: eth1
# firewall-cmd --list-all --permanent --zone=external
external
  ... 略
  masquerade: yes
  ... 略
#  firewall-cmd --direct --get-all-rules
ipv4 nat POSTROUTING 0 -o eth0 -j MASQUERADE
ipv4 filter FORWARD 0 -i tun0 -o eth0 -j ACCEPT
ipv4 filter FORWARD 0 -i eth0 -o tun0 -m state --state RELATED,ESTABLISHED -j ACCEPT
ipv4 filter INPUT 0 -p tcp -m multiport --dports ssh -m set --match-set fail2ban-sshd src -j REJECT --reject-with icmp-port-unreachable
```

ホストBでやることはGateway変更のみ。

```shell
// GatewayをホストAのeth0に変更。
# vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
... 略
GATEWAY=192.168.1.1
... 略

// ネットワーク再起動して変更を反映
# systemctl restart network

// 疎通確認して完了
# ping google.com
  成功
# yum install mariadb-server
  成功
```
【Swift】No such module 'ライブラリ名'と出てしまった時の対処法

# なぜか
podで導入したコンポーネントのビルドが失敗しているケースが多いです。
そのため、podをビルドするといいです。

#やり方
1. ワークスペースツールバーにあるSchemeメニューから、Scheme menu > Manage Schemes > check Pods > Closeとする。

2. Scheme menuからpodsを選択する。

3. podsをbuildする。

以上の操作を行った後もう一度プロジェクトをbuildしてみましょう！！
Swiftのenum型の要素をindexで指定してStringで取得

# やりたかったこと
- Iconのリストを表示したかった。
- imageViewの表示にファイル名が必要なので、Assetsのファイル名をenumにしておいて、そのままStringでとりたかった

```swift

cell.imageView.image = UIImage(named: "ここにファイル名をEnumから入れたい ")
```

# 解決
Swift4.2 CaseIterableを使う + Stringを継承させる




CaseIterableで Icon.allCasesが使え、配列でEnumの要素を返してくれます。

```
(lldb) po Icon.allCases
▿ 3 elements
  - 0 : CheckBoxProject.Icon.apple
  - 1 : CheckBoxProject.Icon.game
  - 2 : CheckBoxProject.Icon.teeth
```

このままだと文字列にならないので、Stringを継承させ、rawValueで文字列に変換します。

結果以下のコードにしました。

```swift

enum Icon: String, CaseIterable {
    case apple
    case game
    case teeth
}
```

```swift

cell.imageView.image = UIImage(named: Icon.allCases[indexPath.row].rawValue)
```
Docker Desktop (Mac) で Disk圧迫を一発解決


## 概要
Dockerコンテナの build を 繰り返し行っていると

```
user@macbook:/$df
Filesystem     1K-blocks      Used Available Use% Mounted on
/dev/disk1s1   118181844 107307736   6025692  95% /
```

Diskの空き容量が減少してしまいました。

いらないイメージを `docker rmi` で消したり
まとめて削除するには、以下のようなコマンドが有効です。
[こちら](https://qiita.com/junsumida/items/e3baf53294a6245a8cf6)を参考にしました

```
docker images | grep none | awk '{print $3}' | xargs docker rmi
```


が、Diskの空き容量はそれほど小さくなりません。
どうやらキャッシュファイル等が蓄積されているようです。

## 簡単に一括クリーニングする。

* GUIで簡単に image や docker環境のクリーニング一発できます！
* ただし docker image がすべて消えるので注意が必要です。

### メニューバーから Performanceを選択

![スクリーンショット 2018-10-20 1.57.10.png](https://qiita-image-store.s3.amazonaws.com/0/21391/7e0ea2b4-0b78-d0ef-457b-63036affe6f5.png)

### Reset タブを選択し Reset disk image をクリック！

![スクリーンショット 2018-10-20 1.57.30.png](https://qiita-image-store.s3.amazonaws.com/0/21391/6cce24a5-389e-b811-992e-4417c2b02253.png)


### スッキリ！

```
user@macbook:/$df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/disk1s1    113G   71G   38G  65% /
```
業務系システムのエンジニアが今風のポートフォリオサイトを作ってみた

# なぜ作ったのか
少し業務的にも暇になってきたので新しいことを始めようと思ってポートフォリオを作ってみた。
これまで、データーベースやJavaのフレームワーク(SpringやPlay)とかは参考書とかを買って、勉強してきたが、HTML5やCSS3はあんまり、がっつり本を買って勉強したことがなかったので、この際にしっかりと学ぼうと...

# 作ったポートフォリオ
![porto.PNG](https://qiita-image-store.s3.amazonaws.com/0/304662/5cdd4733-6e97-0fd3-7770-75cf2949bbd2.png)

 [作ったサイトはこちらです。](http://www.koumotoj.com)

# どうやって作ったのか
まず、jQueryありきで作りました。
「jQueryプラグイン」とかで調べて、ポートフォリオに使えそうなjQueryのプラグインを調べました。
その中から、[pagePiling.js](https://alvarotrigo.com/pagePiling/)というプラグインがいい感じだったので使ってみました。
pagePiling.jsのサンプルからよさげなものを選んで、中身のcssとhtmを適当に書き換えました。
それに加えて、レスポンシブにしたかったので[Bootstrap4](https://getbootstrap.com/)を用いてレスポンシブ対応を行いまいした。
投稿フォームはサーバーサイドを作るのがめんどくさかったので、Google Formを利用して、フォームに投稿されると、Google スプレッドシートに内容が書き込まれて、メールが送信されるようにした。
最後に、さくらインターネットのVPSとドメインを用意して(これはあらかじめ用意していた)、サーバにNignxを入れLets Encryptで証明書を取得して終わり。

# かかった時間

だいたい4時間くらい
[Python] paizaプログラミング練習問題 長テーブルのうなぎ屋 (paizaランク B 相当)

paizaの練習問題をPython3でプログラミングします。

#問題
長テーブルのうなぎ屋 (paizaランク B 相当)
https://paiza.jp/learning/long-table

#ポイント
- 円卓なので、最後の席まで座ったら1番目の席に戻ること
- グループ全員が連続して座れること

#解答
```python:unagi.py
# coding: UTF-8 

# ①入力処理：値取得、テーブル座席の配列準備
nm_array = input().split(" ")
seat_num = int(nm_array[0])
group_num = int(nm_array[1])
# print("シート数：", seat_num)
# print("グループ数；", group_num)

# 空席を0にする
seat = [0] * seat_num

count = 0
# ②グループ毎に空席確認
# グループ分のループ
for i in range(group_num):
    group_array = input().split(" ")
    group_person_num = int(group_array[0])
    sit_point = int(group_array[1])

    # インデックスのため-1する
    sit_point -= 1
    # print("グループの人数：", group_person_num)
    # print("着席開始位置：", sit_point)

    # グループ人数分のループ、空席確認
    empty_flg = True;
    for j in range(sit_point, sit_point+group_person_num):
        # 円卓処理
        if j >= seat_num:
            search_point = j - seat_num
        else:
            search_point = j
        # 空席確認
        if(seat[search_point] > 0):
            empty_flg = False
            break

    # ③席が空いていたら座る処理
    if empty_flg == True:
        # グループの人数分のループ、着席処理
        for j in range(sit_point,sit_point+group_person_num):
            # 円卓処理
            if j >= seat_num:
                search_point = j - seat_num
            else:
                search_point = j
            # print(search_point)
            # 着席処理
            seat[search_point] = 1
        # 座った人の人数を合算
        count += group_person_num
        
# 出力処理：座った人の人数を出力
print(count)
```

2018/10/21　追記
コメントをいただいたので、シンプルな別解を追記しました。

```python:unagi2.py
def sit(n, m):
    """長テーブルのうなぎ屋の関数
    
    Arguments:
        n {int} -- シート数
        m {int} -- グループ数
    """
    # 空席をTrueとする
    sitable = [True] * n
    # グループ分のループ
    for _ in range(m):  
        people, seat = map(int, input().split())
        # 着席位置
        seats = range(seat, seat + people)
        # 空席確認（全員が座れるか確認）
        if all(sitable[seat % n] for seat in seats):
            # 座れた人数を報告
            yield people
            # 着席処理
            for seat in seats:
                sitable[seat % n] = False

# 出力処理：グループ毎に座れた人数を合計して出力
print(sum(sit(*map(int, input().split()))))
```

- `for _ in range(m)`の`_`（アンダースコア）は変数名を置き換えただけで、変数を使っていないことを表す。

- `yield`を実行すると、値を返却しつつ、現在の処理を中断したまま保持する。

- `all(sitable[seat % n] for seat in seats)`の`all`関数は引数内で指定した条件が全て満たされている場合、Trueを返す。

- `sit(*map(int, input().split()))`の`*`（アスタリスク）はリストはタプルや分解して渡し、`sum`関数で合計する。


#感想
アルゴリズム以前にPythonでリストの初期化方法を知りませんでした。
円卓処理のif文（座席数を超えたら最初に戻る）や、ループ処理の開始と終了（グループの1人目からグループの人数分）をどうすればいいかで悩みました。
うなぎ屋ではなく、回転寿司屋だと思って途中まで解いていました。

#関連
[[ネタばれ] 長テーブルのうなぎ屋 (paizaランク B 相当)](https://qiita.com/asahina_dev/items/e477b0b9d33a75659a29)
[アルゴリズム問題　paiza練習問題　長テーブルのうなぎ屋]
(https://qiita.com/krppppp/items/a75205c9dcb4165ca2b4)
Python(Python3)でTkinterを使って何かやってみたい(1)

# まず初めに
プログラミングと言えば、
**アプリケーション(GUI)作ってみたい！**
なんてことを最初は考えるかと思います。

でもまず何から始めたらいいんだろう？みたいな感じで
Pythonを始めました。
そんな方が一定数いるのではないかと信じたい・・・。

で、みんなはJupyterだのPyCharmだの言う統合開発環境(IDE)を使ってますが、
私は使いこなせないので**Anaconda**(Pythonを使う上で便利なものの宝庫)に付いてきた
**Spyder**を使って書いていきます！

# Tkinterとは？
アプリを作る時、まず必要となるのは
・画面
・ボタン
・テキストボックス
などなどの表示だと思いますが、そのために使うのが**Tkinter**であり、
他にも**kivy(スマホアプリが作れる)**や**PyQt**等いっぱいあります。

今回は簡単そうなTkinterを採用します！余裕だな！(フラグ)

# モジュールについて
さっきはTkinterについて触れましたが、そういう
"用途に対しての便利グッズ集"
みたいなのを**モジュール**と言います。(勝手なイメージですが)

個人的には洋服ダンスみたいなイメージですね。
"この洋服ダンスを使う！"　と宣言してから、　"この服を着る！"
というように、順を追って書いていくのがプログラミングなんですね～。

別に裸でも出来ることはありますが、
外に出て活動するには服はきちんと着ないといけませんよね？
プログラミングも同じく、しっかりとしたソースコードを書きたい時は
いろんなモジュールを適切に使っていくべきなのではないかと思います。

# 最後に
今回は自分語りを9割くらいしました。
拙く偏った知識ばかりですが、これから少しずつ成長していきます！多分！

何か間違いやアドバイス等々ありましたらコメント頂けると嬉しいです！
PHPで3単語以上の文字列検索した時のメモ

# なにしたの
PHPでTwitterのツイートを取得して特定ハッシュタグのツイートだけ取得したいと思った時
preg_matchで検索するべきかstrposでするべきか迷ったから処理速度調べてみた。

**動的に正規表現を作ったケースでないため固定の文言でのみの結果となります**
**動的な場合も追って追加します**

# 結果
**こんにちは、これは#テストケースです。これから#時間を#報告します。**
から#テストケース、#時間、#時間の順で100万回文字列検索をかけた結果

| method | time |
|:-----------|------------:|
| strpos | 24.532892942429 |
| preg_match | 25.085613012314 |

**こんにちは、これは#テストケースです。これから#時間を#報告します。**
**こんにちは、これは#テストケースです。これから#時間を#申請します。**
を交互に文字列検索をかけて50万件ヒットさせた結果

| method | time |
|:-----------|------------:|
| strpos | 12.542304039001 |
| preg_match | 12.694728136063 |


#テストコード
```php:check.php
<?php

    $text1 = 'こんにちは、これは#テストケースです。これから#時間を#報告します。';
    $text2 = 'こんにちは、これは#テストケースです。これから#時間を#申請します。';
    $flg = true;

    $start_time = microtime(true);
    for ($i =0; $i < 1000000; $i++) {
        if ($flg) {
            $text = $text1;
        } else {
            $text = $text2;
        }
        $flg = !$flg;

        if (strpos($text, '#テストケース') !== false) {
            if (strpos($text, '#報告') !== false) {
                if (strpos($text, '#時間') !== false) {
                    echo($i.'回目'.PHP_EOL);
                }
            }
        }
    }
    $end_time = microtime(true) - $start_time;
    // 24.532892942429
    // 12.542304039001

    $reg = '/^(?=.*#テストケース)(?=.*#報告)(?=.*#時間).*$/';
    $start_time = microtime(true);
    for ($i =0; $i < 1000000; $i++) {
        if ($flg) {
            $text = $text1;
        } else {
            $text = $text2;
        }
        $flg = !$flg;
        if (preg_match($reg, $text)) {
            echo($i.'回目'.PHP_EOL);
        }
    }
    $end_time = microtime(true) - $start_time;
    //25.085613012314
    //12.694728136063

    echo($end_time);
```

# まとめ
正規表現よりstrposのが単純なものは早いのかもしれないけれど
複数の文字列検索する場合はそこまで大きな差が見られなかった。

膨大なループで検索する場合を除いてそこまで神経質になる必要もないのかもしれない。

テストケースが間違ってたりすることもあるので
その際はコメントなり編集リクエストで教えてもらえると助かります。

同じように迷った人がいれば。
【Unity】モデルにアニメーション（Wolf）

環境メモ
⭐️Mac OS Mojave バージョン10.14
⭐️Xcode version 10.0(10A255)
⭐️Unity 2018.2.11f1
⭐️iPhone7 IOS11.4.1

実際に動かした動画はこちら↓↓
https://twitter.com/nonnonkapibara/status/1054508344956731392

<img width="375" alt="IMG_0016.png" src="https://qiita-image-store.s3.amazonaws.com/0/93155/b7f771c8-78bb-6d46-b641-00f36aee05e4.png">
ArduinoでIPアドレス取得時に4オクテット記法へ変換するTips

こんにちわ。

小ネタです。

Arduinoで`.localIP()とかのIPアドレス拾うやつ、お馴染みの`xxx.xxx.xxx.xxx`へ変換するのはちょっと小細工が必要だったのでメモって置きます。

```c++
// 例: 192.168.0.13 の場合
(String)WiFi.localIP();

// そのままStringにcastすると...
// => "218147008"

// "218147008"を2進にすると...
// 00001101 00000000 10101000 11000000

// 8bitずつ10進にすると...
//       13        0      168      192

// お分かり頂けただろうか...

// つまりこうじゃ!
String ipToString(uint32_t ip){
    String result = "";

    result += String((ip & 0xFF), 10);
    result += ".";
    result += String((ip & 0xFF00) >> 8, 10);
    result += ".";
    result += String((ip & 0xFF0000) >> 16, 10);
    result += ".";
    result += String((ip & 0xFF000000) >> 24, 10);

    return result;
}

Serial.println(ipToString(WiFi.localIP()));
// => "192.168.0.13"

// パワープレイは正義。めでたしめでたし。
```
kotlinで24時以降の時刻文字列をいい感じに扱う



UIから"HH:mm"形式の文字列を受け取り、処理日の日付を足してDate型にする、という処理を書きました。

例：10月20日に処理を実行する場合

|受け取る文字列|返すDateの日時|
|-----------------|------------------|
| "10:00"|2018/10/20 10:00:00|
| "20:00"|2018/10/20 20:00:00|
| "30:00"|2018/10/21 06:00:00|
| "40:00"|2018/10/21 16:00:00|

やっかいだったのが、24時以降の日付を受け取った場合は1日後の日付とする必要があったことです。

以下、実装してみたメソッドです。
（翌々日以降の日時が来ることはない仕様でしたが、実装上は99時まで対応してます。）


```kotlin
    /**
     * "HH:mm"形式の文字列を、当日の日付を付与したDate型で返却する.
     * 24時以降が指定された場合、対応する翌日以降の日付を返却する.
     * @param "HH:mm"形式の文字列.
     * @return Date型、形式が不正ならnull
     */
    fun String.toTodayDate(): Date? {
        // 形式が不正ならnull返却
        val split = this.split(':')
        if (split.size != 2) return null
        val hour = split[0].toIntOrNull() ?: return null
        val minute = split[1].toIntOrNull() ?: return null

        val c = Calendar.getInstance()
        // 指定された時・分をset
        // 24を超えても正規化される
        c.set(Calendar.HOUR_OF_DAY, hour)
        c.set(Calendar.MINUTE, minute)
        //秒以下は0を指定
        c.set(Calendar.SECOND, 0)
        c.set(Calendar.MILLISECOND, 0)

        return c.time
    }
```

Stringの拡張関数として実装しています。
24時以降の文字列の処理の方法がわからずに微妙にハマったのですが、
Calendarのset()は範囲外の数値でもいい感じにしてくれるとのことで、すんなりこれで実装できました。
c.set()が続くのが冗長ですが、これはそういうもんなんですかね。

---

もっとスマートな書き方があれば、ご教授いただければ助かります。
また、Kotlin初心者なので、文法面・体裁面の指摘もお待ちしてます。
プロジェクトにライブラリをブチ込む前に、必ず問いかける2つの事

## あたりまえ

ライブラリを入れるというのは闇雲に行うべきではなく、
入れようとしているものが本当にこれなのかを考えなければなりません。
![project_comedy_l.gif](https://qiita-image-store.s3.amazonaws.com/0/128115/5dc5e013-0c73-cb48-a924-75e913e7cf99.gif)

## 問おう。

### 1つ目
「今、自分は何を解決したいですか？」

### 2つ目
「その(ライブラリ|フレームワーク)は、何を解決するために存在していますか？」

## それだけ？


2つだけ問いかける。ほんとこれだけ。これだけなのに、
ブチ込むライブラリと自分が本当に解決したいこととのミスマッチを防ぎ、
プロジェクトが重厚になるのを遅らせる事ができます。

自分でコード書けば済んだり、もっと小さな単一の問題を解決するライブラリで済んだり。


## あとがき

単発のクローラーを作るためだけのためになぜかDjango(フルスタックWebフレームワーク)を
入れようとしている人がいて、ちょっとそれはズレてるよ…となったので。
短くてコードもない記事ですが、起こしました。
AndroidでAPKを作成しようとしたら発生した依存関係のエラー

#事象
開発時は問題なくビルドできたのだけど、APKを作成しようとしたら以下のようなエラーがでてしまい困った。
```"Program type already present: com.google.gson.ExclusionStrategy"```

#理由
*そのプログラムはすでにある：gson*
gsonは使っている。好きな方だし、build.gradle にも記載している。これが重複しているのが問題らしい。開発時は問題ないのになんでだろう？

#探査
下記コマンドを実行し、使用ライブラリの依存関係をみる。
```./gradlew :app:dependencies```
gsonで検索すると、retrofit, glide, chuck… 様々なライブラリで使われている。みんなも好きなんだな。
さまざまなバージョンが指定されてしまっており、このあたりが問題になっているのではないかと推測してみる。

#対処
とりあえず不要なライブラリの整理をしてビルドしてみたがだめだった。
次にretrofitやほかのライブラリ内でつかわれているgsonをexcludeしてみた

```gradle:build.gradle
implementation('com.squareup.retrofit2:converter-gson:2.4.0') {
        exclude group: 'com.google.code.gson', module: 'gson'
}
```
それでもだめだった…

#解決
なかばやけ気味にgson本体のimplementationも削除してみたらビルドできた。
念の為動作も確認してみたが問題はなさそう。まだだれかが依存しているのだろうか…。

とりあえず解決したし、いそいでいたこともあり今回はこれ以上は深掘りはしなかった。しかし依存関係を解消してくれるはずであるgradleに依存関係で転がされてしまった。機械め… という気持ちになりつつまだAIに仕事を奪われるような時代は遠いなとうっすら適当に思った。

以上でございます。
AWS を使って社内PCのソフトウェア管理（SAM)

AWSは、クラウドサービスばっかり面倒みてくれるものと思っていましたが、なんと社内のPCのソフトウェア管理まで可能です。レジストリも見てくれるので、頑張ればプロダクトキーぐらいまでとれそうです。

オンプレミスのwindows(ようするに単なる社内PC)に、SSM をインストールすれば、下記のような情報をAWSのコンソールからみることができます。

![crop.png](https://qiita-image-store.s3.amazonaws.com/0/48387/4346f675-98bf-436a-44a0-a5eeb6f06e2f.png)
自分の Qiita 記事を自動英訳して Qiita/gist/Twitter へ投稿する Python スクリプトを作成してみた

# transQiita（作ったもの）
transQiita は、Qiita API v2 、googletrans を利用したコマンドラインアプリケーションです。**コマンドラインから実行することでインタラクティブ（または非インタラクティブ）に、Qiita 上の記事を自動で英訳し、 Qiita へ投稿することができます**。
また、Qiita の GitHub 連携と Twitter 連携を利用して、gist/Twitter への同時投稿ができます（オプション）。

**GitHub リポジトリ：** [tm-tech/transQiita](https://github.com/tm-tech/transQiita)

## さっそくデモ！
![transQiita-demo.gif](https://qiita-image-store.s3.amazonaws.com/0/218139/60dc2dd6-9962-f1cd-732d-ea23a48db9b9.gif)

**元記事：**
https://qiita.com/speaktech/items/fa9dd70024865bff90f0
　　↓
**スクリプトで自動投稿された英訳記事：**
https://qiita.com/speaktech/items/99d1530950987019e7d4

## 必要なもの
- [googletrans](https://pypi.org/project/googletrans/)（9/20時点で動作不良を起こすバグが発生しているようですが、[こちらの記事](https://qiita.com/maboy/items/9a1336ece11db4630858)で解決策が提示されています）
- Qiita のアクセストークン(環境変数 QIITA_ACCESS_TOKEN として登録、またはオプションで直接指定)
    
```
e.g.
$ pip install googletrans
$ export QIITA_ACCESS_TOKEN='YOUR QIITA ACCESS TOKEN'
```

## コマンドラインでの実行例

```
$ python transQiita.py  [-h] [--gist] [--tweet] [--private] [--auto] [--token TOKEN]
```

## オプション引数

```
-h, --help     ヘルプ
--gist         GitHub 連携していれば、gist へコードブロック部を投稿
--tweet        Twitter 連携していれば、投稿を Tweet
--private      記事を限定共有投稿
--auto         インタラクティブな実行をせず、自動実行（スケジュール実行時に利用）
--token TOKEN  環境変数を利用しない場合、Qiita のアクセストークンを指定
```

## 制限事項
1. **コードブロック部を翻訳処理するとインデントが崩れるため、コードブロック部は翻訳しません。**
2. **翻訳処理をすると記号と文字の間にスペースが挿入されるため、「 ** 」や「 ~~ 」等のマークダウン装飾が機能しません。**

# 参考にさせていただいた記事
- [Qiita API v2 を使って自身の全投稿をエクスポートする Python スクリプトを書いた](https://qiita.com/sta/items/5074df5fcb81d890897b)
- [pythonでGoogle翻訳が使えるモジュール](https://qiita.com/maboy/items/9a1336ece11db4630858)
- [Pythonでコマンドラインアプリケーションを作るときの雛形](https://qiita.com/Alice1017/items/0464a38ab335ac3b9336)

# あとがき
- **データベースを使わず更新処理ができるように、英訳版記事に印として「元記事のIDを含むバナー」を付けています**。
元記事が更新された際には、元記事IDのバナーを持つ英訳記事を見つけて更新するようにしています。
データベースで元記事と英訳記事の関係性を管理してもよいのですが、それだけのためにデータベースを準備すると汎用性がなくなると考えたため、多少冗長なコードになろうとデータベースレスな設計を目指しました。
（定期的なバッチ処理で使用することを想定していたため、多少処理が重くなろうと構いませんでした）

- **マークダウンが崩壊する致命的な制限事項**については、正規表現で修正しようと試みましたが、「※」が「*」に翻訳されたりとイレギュラーな装飾記号の出現があるため、挫折しました。（解決策を思案中）

- 最後に余談ですが
**インフラ屋さんの私にとって、初めての Python 投稿となります。デバッグ不足なところが多々あると思いますので、不具合がございましたらご報告いただけますと幸いです！**（小声）
削除系Dockerコマンド一覧

## 全て

未使用なコンテナ・イメージ・ボリュームを削除

```shell
$ docker system prune
```

## コンテナ

停止コンテナ全削除

```shell
$ docker container prune
```

コンテナ全削除

```shell
$ docker rm `docker ps -a -q`
```


## イメージ

タグ無しイメージ全削除

```shell
$ docker rmi `docker images -f "dangling=true" -q`
```

イメージ全削除

```shell
$ docker rmi `docker images -q`
```

Dockerのイメージ削除時のエラー「Error response from daemon: Conflict, cannot delete image」対策

```shell
$ docker rmi `docker images | sed -ne '2,$p' -e 's/  */ /g' | awk '{print $1":"$2}'`
```

イメージファイルを削除

Docker for Mac を停止し、イメージファイルを削除します。起動時にイメージファイルがなくても再生成してくれます。

```shell
$ rm ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/Docker.qcow2
```

## ボリューム

未使用ボリューム全削除

```shell
$ docker volume prune
```

ボリューム全削除

```shell
$ docker volume rm $(docker volume ls -qf dangling=true)
```
Google Colab で Julia を使ってみた

# 元ネタ

https://discourse.julialang.org/t/julia-on-google-colab-free-gpu-accelerated-shareable-notebooks/15319
本記事の内容はこちらにすべて書かれてます。
以下はそれをやってみた系の備忘録となります。

# 手順

上記のリンク先では `GPU` を使うとのことですが、今回は普通に `CPU` でサクッと試してみます。
`GPU` を使う場合は、インストールに15~20分くらいかかるらしいですし、自分がやったときは Error でしくじりました。

## 1. Google Colabをひらく

https://colab.research.google.com

`Python3` で新しいノートブックを作成してください

## 2. 以下のコードをセルにコピペして実行(Ctrl+Enter)

```
!curl -sSL "https://julialang-s3.julialang.org/bin/linux/x64/1.0/julia-1.0.0-linux-x86_64.tar.gz" -o julia.tar.gz
!tar -xzf julia.tar.gz -C /usr --strip-components 1
!rm -rf julia.tar.gz*
!julia -e 'using Pkg; pkg"add IJulia"'
```

[上記リンク先](https://discourse.julialang.org/t/julia-on-google-colab-free-gpu-accelerated-shareable-notebooks/15319)で紹介されてたコードで `CUDA` に関係なさげなところを削っただけです。
やっていることは、`Julia` をダウンロードして解凍してるだけですね。
ついでに `IJulia` パッケージもダウンロードしてます。

## 3. 以下のJSONを .ipynb ファイルでローカルに保存

```
{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "julia_test.ipynb",
      "version": "0.3.2",
      "provenance": []
    },
    "kernelspec": {
      "name": "julia-1.0",
      "display_name": "Julia 1.0"
    }
  },
  "cells": [
    {
      "metadata": {
        "id": "u8woq-Zbu_SK",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "for i in 1:3\n",
        "  println(\"Juliaが動いた。Colabで動いた\")\n",
        "end"
      ],
      "execution_count": 0,
      "outputs": []
    }
  ]
}
```

上記の `JSON` を保存する際に注意してほしいのは、拡張子を `.ipynb` とすることです。

`"kernelspec"` に注目してください。 
`Colab` のエンジニアが `Julia` も実行できるようにしてたんですね。完全にGoogle社員しか知らない裏ワザです。

この `JSON` も、[上記リンク先](https://discourse.julialang.org/t/julia-on-google-colab-free-gpu-accelerated-shareable-notebooks/15319)とほぼ同じなのですが、` "accelerator"` を指定してません。
` "accelerator"` は、 `GPU` / `TPU` を指定する際に使われるのですが、今回は `CPU` で動かすのでつけなくておｋということです。
`GPU` で動かしたい！という方は[上記リンク先](https://discourse.julialang.org/t/julia-on-google-colab-free-gpu-accelerated-shareable-notebooks/15319)を読んでみてください。

## 4. 保存した ipynb ファイルを Colab にアップロード

2 で実行した `Colab` 上で `[ファイル] -> [ノートブックをアップロード] `
そいで、3で保存した `ipynb` ファイルをアップロードします。
すると、こんな感じのセルが表示されるのではないでしょうか。

```
for i in 1:3
  println("Juliaが動いた。Colabで動いた")
end
```
これは紛れもなく `Julia` の文法ですね。

## 5 実行(Ctrl+Enter)

ちゃんと3回、 `Juliaが動いた。Colabで動いた` が表示されましたでしょうか。

```
Juliaが動いた。Colabで動いた
Juliaが動いた。Colabで動いた
Juliaが動いた。Colabで動いた
```

# これから

本記事は以上となります。

`Julia` のパッケージを追加する場合は、2 のところで書いたコードに、こんな感じで追加していくのでおｋです。

```
!julia -e 'using Pkg; pkg"add IJulia; add Dataframes; add TextPlots;"'
```

enjoy!
Expressでもアップロードしたファイルを操作したい！

# はじめに

Node.jsでちょろちょろ〜っと、機能を実装したりすることがあるんですが……
フロント・サーバ両方まとめて対応していたんですが、サーバ側でファイルアップロードの処理を書かないといけなくなてしまって。
Expressでのアップロードファイルの操作の方法をだいぶド忘れしていたので、備忘録も兼ねて。

# 単純にアップロード

```normal_upload.js
const express = require('express');
const multer = require('multer');

const app = express();
const upload = multer({ dest: 'uploads/' });

app.use(express.urlencoded({ extended: false }));
app.post('/upload', upload, async (req, res) => {
  // await お好みのファイルの操作
  // req.fileにファイルの情報

  res.status(200).send('done file control.').end();
});

app.listen(process.env.PORT || 8080);
```

/uploadにpostで投げれば、これでひとまずアップロードできるようになりました！

## 問題点

これだと、このjsファイルの階層にuploadディレクトリが作成され、ファイルが配置され続けてしまいます:frowning2:
削除はどうするんだとか、容量はどうするんだとか、そもそも書き込めないサーバだったらどうしようとか、ロードバランサーの下に複数台のサーバがある場合とかとか。

# メモリ上にファイルを読み込んでアップロード

```memory_upload.js
const express = require('express');
const multer = require('multer');

const app = express();
const upload = multer({ storage: multer.memoryStorage() }).single('file');

app.use(express.urlencoded({ extended: false }));

app.post('/upload', upload, async (req, res) => {
  // await お好みのファイルの操作
  // req.fileにファイルの情報

  res.status(200).send('done upload.').end();
});

app.listen(process.env.PORT || 8080);
```

multer.memoryStorage() で、ファイルの情報をメモリに読み込むようにしてみました。
ファイルのbuffer情報もあるので、前述の問題点はクリアした上で一通りの操作は前と変わらずできるはず？

## 問題点

巨大なファイルを送られると死ぬ。
こればっかりは仕方ないんだけれども、実際に死なれると困るので……そういう訳にもいかない感じです。

素直にS3やGCSの署名付きURLを使って直接アップロードできる仕組みを作るのが一番だなぁ
Rails-tutorial初心者


# 2章 toy_app
**↓bitbucketにpushするときに毎回でるのかな？**

```
[vagrant@localhost toy_app]$ git push -u origin --all
To git@bitbucket.org:[username]/toy_app.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'git@bitbucket.org:[username]/toy_app.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again.  See the 'Note about
fast-forwards' section of 'git push --help' for details.

```

<つまづきポイント>
bitbucketでpushできなくて、30分苦戦したけどなんとかクリア。あとで理解できたらいいな。
[git pushがrejectされたときの解決方法URLまとめ](https://qiita.com/kaw/items/767deb773223fe013ada)


#### gitについて
以下のコマンドあたりを調べて押させえよう。
`$ git init`
`$ git add`
`$ git remote`
`$ git push`
`$ git commit`
`$ git pull`
`$ git checkout`
`$ git fetch`
`$ git rebase`
`$ git merge`




 

２章で再度リモートリポジトリでpushできなくて、苦戦中
再度、appつくりなおし。

`pull = fetch + merge origin/master`の理解が必要

master と origin/master
参考<https://qiita.com/osamu1203/items/cb94ef9da02e1ec3e921>

<img width="1046" alt="スクリーンショット 2018-10-19 19.26.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/213554/81986bc4-a2b3-efbe-5877-dedd3bb862d0.png">


[non-fast-forwardについて](https://linux.keicode.com/prog/git-resolve-non-fast-forward-push-problem.php)




2.2.1完了 2018/10/19
rails generate でUsersを作成した。



### 2.2.2

#### rubyについての予備知識
`@hogehoge`はインスタンス変数（クラスの中で扱う変数のことです。）
通常の変数は（ローカル変数）の宣言は、特に宣言なく
`hogehoge = 1`とかでいけます。

`def`はメソッドの定義のときに利用します。

```
def hogehoge
  puts "hogehogehogehoge"
end
```
といった感じ。

`resorce:users`
→: シンボル（文字列の皮を被った数値）



#### 図で整理しました。


<img width="932" alt="スクリーンショット 2018-10-19 21.24.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/213554/28da80a4-c4c3-4084-4939-3df405016178.png">



### 2.3~

has_many:micropost
belongs_to:user

validates: XXXXX,prsence:true
とか



一旦は2章で完了しました。
Angularフォーム作法について

Angular6でこんな絞り込みメニューを作成した。
![スクリーンショット 2018-10-19 23.04.18.png](https://qiita-image-store.s3.amazonaws.com/0/272635/32199104-d0c0-5236-3238-886237d61b00.png)

jqueryだと簡単なフォームだけど、Angularだと2つの項目で絞り込む時、迷ったのでメモ


test.ts

    export class CompetitionsComponent implements OnInit {
      competitions: Competition[] = [];
      selectedStatus = new BehaviorSubject(CompetitionStatus.Editing);
      status = CompetitionStatus.Editing;
      plan = PlanStatus.al;

      statusList: Array<{ value: number; name: string }> = [
        {
          value: CompetitionStatus.Editing,
          name: getCompetitionStatusName(CompetitionStatus.Editing)
        },
        {
          value: CompetitionStatus.Waiting,
          name: getCompetitionStatusName(CompetitionStatus.Waiting)
        },
        {
          value: CompetitionStatus.Cancel,
          name: getCompetitionStatusName(CompetitionStatus.Cancel)
        }
      ];

      planList: Array<{ value: number; name: string }> = [
        {
          value: PlanStatus.al,
          name: getPlanName(PlanStatus.al)
        },
        {
          value: PlanStatus.standard,
          name: getPlanName(PlanStatus.standard)
        },
        {
          value: PlanStatus.free,
          name: getPlanName(PlanStatus.free)
        }
      ];

      onChangeStatus(status:number) {
        this.status = status;
      }

      onChangePlan(plan:number) {
        this.plan = plan;
      }
      // getListでAPIを呼んでます
      onSubmit() {
        this.selectedStatus
        .pipe(mergeMap(_status 
          => this.competitionService.getList(this.status, this.plan)))　
        .subscribe(
          competitions => {
            this.competitions = competitions;
          },
          err => {
            this.alert.danger('情報の取得に失敗');
          }
        );
      }
    }


test.html

    <div class="form-group">
      <div class="block">
        <label for="status">ステータス</label>
        <select class="form-control" id="status" required  [ngModel]="status" (change)="onChangeStatus($event.target.value)">
          <option *ngFor="let status of statusList" [value]=status.value>{{ status.name }}</option>
        </select>
      </div>
      <div class="block">
        <label for="plan">プラン</label>
        <select class="form-control" id="plan" required [ngModel]="plan" (change)="onChangePlan($event.target.value)">
          <option *ngFor="let plan of planList" [value]=plan.value>{{ plan.name }}    </option>
        </select>
      </div>
      <div class="block">
        <button type="submit" class="btn btn-success" (click)="onSubmit()">検索    
     </button>
      </div>
    </div>

test.scss

    @import url('https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css');

    .form-group{
      padding: 10px 20px;
    }

    .form-control{
      width: 200px; 
      margin-right:10px;
    }
    .btn{
      margin-top: 23px;
    }
    .block{
      float: left;
    }

Angular6だとngModelとか色々フォーム周りの所作をする際に
書き方があるようですがなかなか慣れないす。。

他にももっと綺麗にする方法あるんだろうけど。アドバイス求む。
シンプルな計算グラフの保持クラス

# CalculationRecorder

[ソースはこちら](https://github.com/uyuutosa/calculation_recorder)です。

以下のようにしてクラスを定義します。

```python
import calculation_recorder as cr

func = cr.CalculationRecorder()
```

以下のように適当な値をどんどん足してみます。

```python
func = func + 1
func = func + 2
func = func + 3
func = func + 4
func = func + 5
func = func + 6
func = func + 7
func = func + 8
func = func + 9
func = func + 10
```

`func`にはこれまでの計算過程が含まれています。
適当な値を順伝播させてみましょう。

```python
func.forward(0)
55
```
となります。単純な$0+1+2+3+4+5+6+7+8+9+10=55$です。

次に、逆伝播させてみます。55を逆伝播させると0になりそうです。

```python
func.backward(55)
0
```

0でした。

## 用途

画像処理の各種座標変換に使っています。
DLの前処理のクラスに忍ばせておくと、座標変換後の$(x,y)$は座標変換前の座標系でいうとどのあたりなのかなどを悩まなくてよくなります。

例えば、画像を半分に圧縮した上で{$(x,y)|100\leq x<200,100 \leq y<200$}として、更に4倍に引き伸ばしたときの画像の$(x,y)=(20,20)$はもとの画像でいうとどこか。ということを考えます。一つ一つ考えてコードを書いていけばよいですが、このクラスを使うと以下のように簡単にかけます。

```python
from numpy import array
func = cr.CalculationRecorder()
func = func / 2
func = func - 100
func = func * 4

func.backward(20)
```

x,yは独立なので、numpy.arrayで処理できれば楽ですが、対応していません。
AWS Lambdaのタイムゾーンを変更する(コード内での変更は反映されない)

## Lambdaのタイムゾーン

AWS Lambdaでは **東京(ap-northeast-1)リージョンであっても** タイムゾ－ンはUTCになります。

```py:タイムゾーンと時間を表示する例
import datetime
import os


def lambda_handler(event, context):
    now_dt = datetime.datetime.now()
    
    print("TZ: {}".format(os.environ['TZ']))
    print("now: {}".format(now_dt))
    print("now_timestamp: {}".format(now_dt.timestamp()))

    return 'Hello from Lambda'
```

> TZ: :UTC
> now: 2018-10-19 14:13:02.141871
> now_timestamp: 1539958382.141871

## タイムゾーンの変更方法

Lambda関数の設定にある「環境変数」で変更することができます。

キーに `TZ` 、値に `Asia/Tokyo` と入力します。

![lambda-tz.png](https://qiita-image-store.s3.amazonaws.com/0/216963/d32f1963-20cd-7cd7-4737-8d1d139a0611.png)
同じスクリプトを実行すると次のようにタイムゾーンの変更が反映されています。

> TZ: Asia/Tokyo
> now: 2018-10-19 23:13:46.994964
> now_timestamp: 1539958426.994964


## コード内で `TZ` 環境変数を変えても変更は反映されない

「環境変数」ということで Pythonの `os.environ` を書き換えてみましたが、タイムゾーンの変更が反映されませんでした。

Lambda関数の「環境変数」の設定を忘れた時の対策として別な方法を考えたほうが良いでしょう。

```py:コード内でタイムゾーンの変更が反映されない
import datetime
import os


def lambda_handler(event, context):
    default_tz = 'Asia/Tokyo'
    if os.getenv('TZ', '') != default_tz:
        os.environ['TZ'] = default_tz
    now_dt = datetime.datetime.now()
    
    print("TZ: {}".format(os.environ['TZ']))
    print("now: {}".format(now_dt))
    print("now_timestamp: {}".format(now_dt.timestamp()))

    return 'Hello from Lambda'
```

実行結果を見ると TZだけが "Asia/Tokyo" になっています。

> TZ: Asia/Tokyo
> now: 2018-10-19 14:15:45.675777
> now_timestamp: 1539958545.675777

## 参考

AWS Lambdaのタイムゾーン変更 - Qiita
https://qiita.com/nullian/items/39ecf1f6d0194b72e8e6

Python で環境変数の取得と追加 | TM Life
http://tmlife.net/programming/python/python-environ.html

16.1. os — 雑多なオペレーティングシステムインタフェース — Python 3.6.4 ドキュメント
https://docs.python.jp/3/library/os.html#os.putenv