OmniAICreator/Qiita-1.07M huggingface dataset:
LUA4-U3-AGTをmacOS High Sierra、Mojave, Catalinaで使う話

* 追記：Mojave, Catalinaでも同様のようです

# LUA4-U3-AGT
* BUFFALOのUSB有線LANアダプタ
    * http://buffalo.jp/product/wired-lan/lan-adapter/lua4-u3-agt/
    * 仕様には10.11までしか対応が書いてない

なんとなくいままで使っていたEL CapitanをHigh SierraにしたらLinkせず全く繋がらなくなってしまったので色々対処。
BUFFALOのサイトでは10.12までのドライバしかないようだ。
http://buffalo.jp/download/driver/lan/lua4-u3-agt-mac.html
この有線LANアダプタはチップにAsixのAX88179を使っていて、割りと汎用的に使われてるからドライバーあるかなと探す。
チップメーカーのサイトをみるとやはりありそう。
http://www.asix.com.tw/products.php?op=pItemdetail&PItemID=131;71;112
更新日をみると割と最近だったので期待。

さっそく、「Apple Mac OS X 10.6 and above Drivers Installer」 からドライバをダウンロードしているてみる。が、認識しない。。。
`pkgutil --pkgs` でみるとちゃんとインストールされているようだ。。。

いろいろ調べていたら、この記事にたどり着く
https://lorenzo.mile.si/2017/10/ax88179-usb-ethernet-and-macos-10-13-high-sierra/

なんと、KEXT（Kernel Extension）のセキュリティが強化されていて、ユーザ操作で許可しないといけないらしい。署名がないものはデフォルトでは不許可になっているようだ。
https://developer.apple.com/library/content/technotes/tn2459/_index.html#//apple_ref/doc/uid/DTS40017658

なので、許可するようにする。
システム環境設定 -> セキュリティとプライバシー の下の方
許可するものは「WEI LU SU」（わかりづらい）。許可した後は再起動。
つながるようになったので、この記事を書いている。
ActiveStorageでS3へファイルをアップロードする

単純にS3へのファイルアップロードした際のメモ。




###準備編

`Rails 5.2.0.alpha`を使用する。

下記ページの`Setting up ActiveStorage for Rails`の項目に従ってGemfileの書き換えやDBのマイグレーション、active_storageのプロジェクトへのインストールを行う。
http://blog.jasonkim.ca/blog/2017/11/13/Using-ActiveStorage-Today/


####`storage.yml`
`bin/rails active_storage:install`を実行すると、`config`以下に`storage.yml`
ファイルが生成されるのでそこに必要事項を記入する。
今回はamazon以下に自分が管理しているS3のバケット情報を記入。

```yaml
amazon:
  service: S3
  access_key_id: XXXXXXXXXXXXXXXXXX
  secret_access_key: XXXXXXXXXXXXXXXXXX
  region: ap-northeast-1
  bucket: your.bucket.name
```

###アップロード

下記の用なコードで単純なアップロードが可能。

`ActiveStorage::Blob.create_after_upload!(io: StringIO.new('qwerty'), filename: 'test_file')`

上記コードでファイル内容が`qwerty`となるファイルをアップロードしている。
S3のバケット上でのファイル名は`znzAavPtDwXdqzYoP4eAPWgy`のような`standard secure-token format`となる。
FrameworkでSwiftとObjective-C混ぜるのはやばい


何言ってんだおめー。SwiftとObjective-CなんかBridging Headerかimport "-Swift.h"で余裕だろwww

って思ってた時期私にもありました。

#とりあえずおさらい

通常アプリを開発する場合、Objective-CのファイルにSwiftのファイルをインポートする時、"プロジェクト名-Swift.h"をインポートします。
SwiftのファイルにObjective-Cのファイルをインポートする場合は、Bridging Headerを作成し、使用したいObjective-Cのヘッダーをインポートすることで使用することができます。

#フレームワークで使ったら死ぬ
「Swift Objective-C import」とかでググったら上記の情報がいっぱい出てくるし、そのままでいけると思うじゃないですか？

ですが、Frameworkで使用した場合、コンパイルエラーが発生しビルドが通らなくなります。

#じゃあどないすればええんや・・・？
こういう時のための[公式リファレンス](https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html#//apple_ref/doc/uid/TP40014216-CH10-XID_82)を読んでみると答えが書いてありました。

#フレームワーク上でSwiftにObjective-Cをインポートする

1. TargetのBuild Setting からDefine Moduleの設定をYesにします。

1. Umbrella headerファイルにSwift側で使用したいObjective-Cファイルのヘッダーをimportします。

```objectivec:FrameworkName.h

#import <FrameworkName/yourFirstFile.h>
#import <FrameworkName/yourSecondFile.h>
#import <FrameworkName/yourThirdFile.h>

```

Umbrella headerはCocoaTouchFrameworkのプロジェクトを作成した際に初期状態で生成されている「フレームワーク名.h」ファイルのことです。

以上の手順を行うと、SwiftのファイルでObjective-Cのファイルにアクセスできます。

#フレームワーク上でObjective-CにSwiftをインポートする

1. TargetのBuild Setting からDefine Moduleの設定をYesにします。

1. Objective-Cからアクセスしたいクラスや変数などに@objcをつけます

1. Objective-C側で使用したいSwiftのアクセス修飾子をpublicまたはopenにします。

1. SwiftのファイルにアクセスしたいObjective-Cの.mファイルに「-Swift.h」をimportします。

```objectivec:yourfile.m

#import <ProductName/ProductModuleName-Swift.h>

```

以上の手順で、Objective-CからSwiftへのアクセスが可能になります。

#正直イケてない件
ここまで読んで違和感を感じないでしょうか？

**Objective-CをUmbrellaHeaderでimportしたり、SwiftをPublicとかOpenにすれば、外部からアクセスされるくね・・・？**

そこなんですよ。イケてないのは。
言語を越えてアクセスするために無駄にファイルを公開しなきゃいけないので、内部のみで使用しているファイルがSwiftとObjective-C混在だった場合とかにすごい困ります。スーパー公開祭りが発生します。

これに関しては、誰かいい方法知らないですか？って聞きたいですね。

#まとめ

- Build SettingでDefine ModuleをYesに設定しようね

- この表に従ってimportしようね

|			  | Swiftに		 | Objective-Cに |
|:-----------|:-----------|:------------|
| **Swiftをインポート**  | インポート不要 |	#import \<ProductName/ProductModuleName-Swift.h> |  
| **Objective-Cをインポート** | Umbrella Headerにインポート  | #import "Header.h"|

- SwiftはpublicかopenじゃないとObjective-Cにimportされないから気をつけてね

- ここまで書いておいてなんだけど、 **どっちか片方で作った方がいい**
Python fileinput と argparse の両立

たとえば、Perl で以下のように書くととても便利です。

```
while(<>){
	print $_;
}
```

何が便利かというと、以下２種類からの入力を受け付けられます。

- 標準入力からの読み込み
- 引数に指定したファイルの読み込み


Python で同じことは **fileinput** を使うとできるようです。

```
#!/usr/bin/env python
import fileinput

for line in fileinput.input():
	print(line, end="")
```

ここで、**fileinput** を **argparse** と単純に組み合わせてみます。

```
#!/usr/bin/env python

import argparse
import fileinput

parser = argparse.ArgumentParser(prog="cata.py", description="fileinput & argparse")
parser.add_argument('-i', '--info', action='store_true', help='Print information')
args = parser.parse_args()

for line in fileinput.input():
	print(line, end="")
```

するとこんなエラーが（泣）

```
$ ./catf_ng.py  file?.txt
usage: cata.py [-h] [-i]
cata.py: error: unrecognized arguments: file0.txt file1.txt file2.txt
```

**解決方法**が下記のサイトにありました:grinning:
https://gist.github.com/martinth/ed991fb8cdcac3dfadf7

上記サイトには最終的な記述例が無かったのと、同様の内容が日本語サイトでヒットしなかったで、この記事にてメモを残したいと思います。

```
#!/usr/bin/env python

import argparse
import fileinput

parser = argparse.ArgumentParser(prog="cata.py", description="fileinput & argparse")
parser.add_argument('files', metavar='FILE', nargs='*', help='files to read, if empty, stdin is used')
parser.add_argument('-i', '--info', action='store_true', help='Print information')
args = parser.parse_args()

for line in fileinput.input(files=args.files):
	print(line, end="")
```

最後におまけで、上記**add_argument()**で追加したオプション（'-i', '--info'）で機能を追加してみました。

```
#!/usr/bin/env python

import argparse
import fileinput

parser = argparse.ArgumentParser(prog="cati.py", description="cat with file infomation")
parser.add_argument('files', metavar='FILE', nargs='*', help='files to read, if empty, stdin is used')
parser.add_argument('-i', '--info', action='store_true', help='Print filename and line no')
args = parser.parse_args()

for line in fileinput.input(files=args.files):
	if(args.info):
		if(fileinput.isfirstline()):
			print("*** {}".format(fileinput.filename()))
		print("{:6}\t".format(fileinput.filelineno()), end="")
	print(line, end="")
```


上記スクリプトはオプション無しだと cat だけします。
たとえば、以下３つのファイルを用意します。

```file0.txt
I am Nozomi.
Are you Nozomi.
Yes, I am.

```


```file1.txt
This is my bag.
That is your pen.
Is that a pen?
Yes, it is.
No, it is not.
It is a pencil.

```

```file2.txt
He is my friend.
She is not from America.
Do you study English?
I like soccer.

```

"--info"または "-i" をつけて実行すると以下のように出力します。


```
$ ./cati.py --info file?.txt
*** file0.txt
     1	I am Nozomi.
     2	Are you Nozomi.
     3	Yes, I am.
     4	
*** file1.txt
     1	This is my bag.
     2	That is your pen.
     3	Is that a pen?
     4	Yes, it is.
     5	No, it is not.
     6	It is a pencil.
     7	
*** file2.txt
     1	He is my friend.
     2	She is not from America.
     3	Do you study English?
     4	I like soccer.
     5	
```
組合せ最適化で数コロを解く

Advent Calendar 18日目の記事 [組合せ最適化で四角に切れを解く](https://qiita.com/SaitoTsutomu/items/7c37ab147c390a1de0a9)
Advent Calendar 20日目の記事 [組合せ最適化でビルディングを解く](https://qiita.com/SaitoTsutomu/items/251de8ae14a142ccfb3d)

## これなに

**数コロ**を、Pythonで[組合せ最適化](https://qiita.com/SaitoTsutomu/items/bfbf4c185ed7004b5721)モデルを作って解きます。
解く楽しみは、モデル化を工夫することになります。

自分でも試してみたい人は、下記を参考にしてください。

- [数独を通して組合せ最適化を学ぼう](https://qiita.com/SaitoTsutomu/items/bd09190d8a02432b3f16)

## 問題
* 全てのマスを１から４の数字か空白にします。
* 数字は、そのマスの隣接マスに数字が入るマスの数になります。
* 同じ数字を連続してはいけません。
* すべての数字を連結すること。

下記は、左が問題で、右が答えです。

![](https://raw.githubusercontent.com/SaitoTsutomu/opt4puzzle/master/pic/suukoro.png)

### 入力パラメータ

`data`にヒントが入っているとします。

```py3:python
import numpy as np
from itertools import chain, product
from pulp import LpProblem, lpSum, lpDot, value
from ortoolpy import addvars, addbinvars
data = """\
..1...1
.1.3.32
.......
.2.4.4.
.......
31.1.3.
1...1..""".splitlines()
nw, nh = len(data[0]), len(data)
```

## Pythonで解く

数理モデルを作成し、解きましょう。

### 変数
* v：0:white, 1-4:number (1)
* r：数字 (2)

### 制約
* 数字があればその数字 (3)
* 数字は1つ (4)
* rをvで表現 (5)
* 数字は周りの数字の数に等しいこと (6)
* 同じ数字は連続しないこと (7)
* 全ての数字がつながること (8)

```py3:python
m = LpProblem()
v = np.array(addbinvars(nh, nw, 5)) # 0:white, 1-4:number (1)
u = np.zeros((nh+2, nw+2), dtype=object)
u[1:-1,1:-1] = v[:,:,1:].sum(2)
w = u[1:-1,2:]+u[1:-1,:-2]+u[2:,1:-1]+u[:-2,1:-1]
r = np.array(addvars(nh, nw)) # (2)
for i, j in product(range(nh), range(nw)):
    if data[i][j].isdigit():
        m += v[i,j,int(data[i][j])] == 1 # (3)
    m += lpSum(v[i,j]) == 1 # (4)
    m += lpDot(range(5), v[i,j]) == r[i,j] # (5)
    m += w[i,j] >= r[i,j] # (6)
    m += w[i,j] <= r[i,j] + 4*v[i,j,0] # (6)
for k in range(1, 5):
    for e in chain((v[1:,:,k]+v[:-1,:,k]).flat, (v[:,1:,k]+v[:,:-1,k]).flat):
        m += e <= 1 # (7)
while True:
    m.solve()
    s = np.vectorize(value)(r).astype(int)
    break
    if unionfind.isconnected(s==0):
        break
    m += lpSum(v[r==0]) >= 1 # (8)
```

### 結果の表示

```py3:python
t = s.astype(str)
t[s==0] = '.'
print('\n'.join(' '.join(s) for s in t))
>>>
1 . 1 2 . . 1
3 1 . 3 2 3 2
2 . . 2 . 2 .
3 2 3 4 2 4 1
2 . 2 3 . 2 .
3 1 . 1 . 3 1
1 . . . 1 2 .
```

解けていることが確認できます。

以上
初めてのプリント基板(PCB)発注 eagleからelectrow覚書

Arduinoやブレッドボードで試作した後は、自分で基板を作ると小さくできたり、耐久性が上がったり、かっこよかったりする。もちろん量産だってできる。中国のelectrow社に発注するとプリント基板が1000円せずに作れる（5枚）とのことで発注。

まだ到着していないのでなにかプラスしてあったら後で書く(2017/11/26)

# 基板の基礎知識
[株式会社ユニクラフト](https://unicraft-jp.com/pcbe/gerber.shtml)ここの画像が簡潔で分かりやすかった。ガーバーデータって何？レジストってなに？って人はちらっと見ておくとよい。

#基本的な流れ
[ツール・ラボ](https://tool-lab.com/2014/07/mac-eagle-101-26/)ここが最高に丁寧で分かりやすかった。ぼここをみればOK

## 補足
###electrow 発注用ファイルの場所
デザインルールファイルとCAMファイルのリンクが変わっている。現在は[ここ](https://www.elecrow.com/5pcs-2-layer-pcb.html)の下部3. Wiki & External linksにある。
###ガーバーデータの確認、windowsの場合
[はるまきパタパタ](http://harumaki-flipflop.hatenablog.com/entry/2017/02/16/221634)を見た


# Tips的なあれ
## eagleのレイヤはなんとなく見ておくといい
[Eagleで使用するレイヤ](https://www.technoveins.co.jp/develop/eagle/layer.htm)見ておくとあとであれ？ってなったときに助かる。
## 導線を露出させたい時
今回は指をのせるとスイッチオンにしたかったので一部導線を露出させたかった。また、後ほどはんだを盛って増強したい時など。T_stopに描いた図形の場所はマスクされ、レジストが乗らなくなるので、T_stopレイヤを利用する。
##ロゴ・画像を入れたい時
[シルクで画像を入れる(EAGLE)](http://www.s-m-l.org/silk_logo.html)基本ここの通り。このサイトでは一度200番のレイヤーにインポートしてからレイヤを変えているけど、一色であればインポートの指定時に「choose start layer for 1st selected color」で21番(T_place)を指定するとレイヤ移動をさせなくていいので楽。

# メモ
3Vボタン電池CR2032の[秋月で買える表面実装ホルダー](http://akizukidenshi.com/catalog/g/gP-11348/)のeagleパーツは[このライブラリ](https://github.com/jan1s/hw-eaglelibs/blob/master/battery-holder.lbr)に入っている。
組合せ最適化で四角に切れを解く

Advent Calendar 17日目の記事 [組合せ最適化でナンバーリンクを解く](https://qiita.com/SaitoTsutomu/items/a1a2df0e142c7ab10ff5)
Advent Calendar 19日目の記事 [組合せ最適化で数コロを解く](https://qiita.com/SaitoTsutomu/items/3b61cf7232cfac25bff3)


## これなに

**四角に切れ**を、Pythonで[組合せ最適化](https://qiita.com/SaitoTsutomu/items/bfbf4c185ed7004b5721)モデルを作って解きます。
解く楽しみは、モデル化を工夫することになります。

自分でも試してみたい人は、下記を参考にしてください。

- [数独を通して組合せ最適化を学ぼう](https://qiita.com/SaitoTsutomu/items/bd09190d8a02432b3f16)

## 問題
* 盤面を数字を1つずつ含む長方形に分割します。
* 数字は1マスの面積を1とした長方形の面積になるようにします。

下記は、左が問題で、右が答えです。

![](https://raw.githubusercontent.com/SaitoTsutomu/opt4puzzle/master/pic/square.png)

### 入力パラメータ

`data`にヒントが入っているとします。

```py3:python
import numpy as np
from itertools import product
from pulp import LpProblem, lpSum, value
from ortoolpy import addvars, addbinvars
data = """\
3..3..
......
6.4...
...2.6
......
..6..6""".splitlines()
nw, nh = len(data[0]), len(data)
tgt = [(i, j, int(data[i][j])) for i in range(nh)
       for j in range(nw) if data[i][j].isdigit()]
nm = len(tgt)
```

## Pythonで解く

数理モデルを作成し、解きましょう。

### 変数
* v：各位置が各部屋かどうか (1)
* vl：候補のどれか (2)

### 制約
* vは1つの部屋のみ (3)
* vlは１つの候補のみ (4)
* vlの1つを選んだら、その位置のその部屋は1 (5)

```py3:python
m = LpProblem()
v = np.array(addvars(nh, nw, nm)) # (1)
for i, j in product(range(nh), range(nw)):
    m += lpSum(v[i,j]) == 1 # (3)
def make(h, pi, pj, na):
    lst = []
    for i in range(1, na + 1):
        j = na // i
        if i * j >= na:
            for y in range(i):
                if 0 <= pi-y <= nh-i:
                    ly = range(pi-y, pi-y+i)
                    for x in range(j):
                        if 0 <= pj-x <= nw-j:
                            lx = range(pj-x, pj-x+j)
                            lst.append([v[dy,dx,h] for dy in ly for dx in lx])
    return lst
for h, (i, j, k) in enumerate(tgt):
    lst = make(h, i, j, k)
    vl = addbinvars(len(lst))  # (2)
    m += lpSum(vl) == 1 # (4)
    for l, ll in enumerate(lst):
        for t in ll:
            m += vl[l] <= t # (5)
m.solve()
```

### 結果の表示

```py3:python
print(np.vectorize(value)(v.dot(range(nm))).astype(int)+1)
>>>
[[1 1 1 2 2 2]
 [3 3 4 4 6 6]
 [3 3 4 4 6 6]
 [3 3 5 5 6 6]
 [7 7 7 8 8 8]
 [7 7 7 8 8 8]]
```

解けていることが確認できます。

以上
ReactNative入門④ ~Stateに触れる~


# State
propsの他にもコンポーネントのデータを管理するものがあり、`state`といいます。
propsとstateの違いは、簡単にまとめると以下のようになります。詳しくはReactのstateの公式ドキュメントや記事を読むと良いでしょう。

||props|state|
|----|------|------|
|設定元|親コンポーネント|自身|
|変更|しない|する|

stateは`constructor`で初期化し、stateの値を変更したいときは、`setState`で変更します。

## コードを確認する
では、今回のソースコードを確認しましょう。

```js
import React, { Component } from 'react';
import { AppRegistry, Text, View } from 'react-native';


class Blink extends Component {
  constructor(props) {
    super(props);
    this.state = { showText: true }

    setInterval(() => {
      this.setState(previousState => {
        return { showText: !previousState.showText };
      });
    }, 1000);
  }

  render() {
    let display = this.state.showText ? this.props.text: '';
    return (
      <Text>{display}</Text>
    );
  }
}

export default class BlinkApp extends Component {
  render() {
    return (
      <View>
        <Blink text='I love to blink' />
        <Blink text='Yes blinking is so great' />
        <Blink text='Why did they ever take this out of HTML' />
        <Blink text='Look at me look at me look at me' />
      </View>
    );
  }
}

AppRegistry.registerComponent('AwesomeProject', () => BlinkApp);
```

## 解説
StateとPropsの使い分けに注目です。
画面に表示するテキストは、変わらないので親コンポーネントであるBlinkAppがBlinkコンポーネントにpropsとして定義しています。
反対に、テキストの表示・非表示は交互に **変化** していくので`state`のshowTextとして定義します。
そして、showTextをsetIntervalを使って1秒毎にtrue, falseを切り替え、テキストの表示・非表示を切り替えています。
すると、このようにテキストが表示・非表示されるようになります。

![b33b42846a01723084ec5a7026c61d6a.gif](https://qiita-image-store.s3.amazonaws.com/0/45577/a24ee73b-81f8-9821-443d-9b08439f0fac.gif "b33b42846a01723084ec5a7026c61d6a.gif")
[Git] 直前のコミットのコミッターの名前とメールアドレスを取得する

CIで自動コミット処理をしたい場合に、直前のコミットの名前とメールアドレスを再利用したいケースがあったためやり方をメモ

# 対応方法
`git log -1 --pretty=format:'XX'` を利用すれば色々と情報を取得できる。

```bash:直前のコミットのコミッターの名前を取得
$ git log -1 --pretty=format:'%an'
Taro Tanaka
```

```bash:直前のコミットのコミッターのメールアドレスを取得
$ git log -1 --pretty=format:'%ae'
tanaka.taro@example.com
```

その他のフォーマット指定に関しては以下などを参照

[Git - pretty-formats Documentation](https://git-scm.com/docs/pretty-formats)
[git logのフォーマットを指定する - Qiita](https://qiita.com/harukasan/items/9149542584385e8dea75)

# 参考
[Script to get last commit author name in git - Stack Overflow](https://stackoverflow.com/questions/41548698/script-to-get-last-commit-author-name-in-git)
組合せ最適化でウォールロジックを解く

Advent Calendar 13日目の記事 [組合せ最適化でペイントエリアを解く](https://qiita.com/SaitoTsutomu/items/5815c64ec23b8c88eee0)
Advent Calendar 15日目の記事 [組合せ最適化でののぐらむを解く](https://qiita.com/SaitoTsutomu/items/7e01f4bc3acb540b4c81)

## これなに

**ウォールロジック**を、Pythonで[組合せ最適化](https://qiita.com/SaitoTsutomu/items/bfbf4c185ed7004b5721)モデルを作って解きます。
解く楽しみは、モデル化を工夫することになります。

自分でも試してみたい人は、下記を参考にしてください。

- [数独を通して組合せ最適化を学ぼう](https://qiita.com/SaitoTsutomu/items/bd09190d8a02432b3f16)

## 問題

- 数字が記入されているマスからその数字の数だけ縦と横に線を引きます
- 1つのマスには1本の線しか引くことができません
- 数字が記入されているマスには線を引くことができません

下記は、左が問題で、右が答えです。

![](https://raw.githubusercontent.com/SaitoTsutomu/opt4puzzle/master/pic/wall.png)

`data`にヒントの数が入っているとします。

```py3:python
import pandas as pd
from itertools import product
from pulp import LpProblem, lpSum, lpDot, value
from ortoolpy import addvars, addbinvars
data = """\
4..1..
.4..2.
..2..2
1..1..
.1..1.
..3..2""".split()
```

## 変数表

下記のような変数表を作成します。各行の変数は0または1をとります。
変数の値が1ならば、該当行 該当列のマスが黒になります。
「向」は{0:左, 1:上, 2:右, 3:下}です。`VDir`はその方向かどうか、`VLen`は矢印の長さです。

<table><tr><th></th><th>行</th><th>列</th><th>向</th><th>VDir</th><th>VLen</th></tr>
<tr><th>0</th><td>0</td><td>0</td><td>0</td><td>v000001</td><td>v000145</td></tr>
<tr><th>1</th><td>0</td><td>0</td><td>1</td><td>v000002</td><td>v000146</td></tr>
<tr><th>...</th><td>...</td><td>...</td><td>...</td><td>...</td><td>...</td></tr>
</table>

```py3:python
ni, nj = len(data), len(data[0])
mx = max(ni, nj)
a = pd.DataFrame([(i,j,k) for i,j,k in product(range(ni),
    range(nj),range(4))], columns=list('行列向'))
a['VDir'] = addbinvars(len(a))
a['VLen'] = addvars(len(a))
a[:2]
```


## 数理モデルを作り解く

変数表ができたので、ウォールロジックの解になるように、制約条件を追加し数理モデルを作成し、解きましょう。

- 数字があれば、方向別長さの和に等しく、かつその位置に矢印がないこと (1)
- 数字がなければ矢印は1方向のみ (2)
- 数字がなければ矢印の方向に長さを1足すこと (3)

```py3:python
drc = [(-1, 0, 0), (0, -1, 1), (0, 1, 2), (1, 0, 3)]
m = LpProblem()
for i,j in product(range(ni), range(nj)):
    b = a[(a.行==i)&(a.列==j)]
    if data[i][j].isdigit():
        m += lpSum(a[(a.行==i+y)&(a.列==j+x)&(a.向==k)].VLen
                   for y,x,k in drc) == int(data[i][j]) # (1)
        m += lpSum(b.VLen) == 0 # (1)
        continue
    m += lpSum(b.VDir) == 1 # (2)
    for y,x,k in drc:
        r = b[b.向==k].iloc[0]
        m += r.VLen <= mx * r.VDir # (3)
        m += r.VLen <= r.VDir + lpSum(
            a[(a.行==i+y)&(a.列==j+x)&(a.向==k)].VLen) # (3)
m.solve()
```

### 結果の表示

```py3:python
a['Val'] = a.VDir.apply(value)
print('\n'.join(''.join(' '+(data[i][j] if data[i][j].isdigit()
    else '↑←→↓'[int(value(lpDot([0,1,2,3],a[(a.行==i)&(a.列==j)].Val)))])
    for j in range(ni)) for i in range(nj)))
>>>
 4 → → 1 → ↑
 ↓ 4 → → 2 ↑
 ↓ ↓ 2 → ↓ 2
 1 ↓ ↓ 1 ↓ ↑
 ↓ 1 → ↓ 1 ↑
 ← ← 3 → ↓ 2
```

解けていることが確認できます。

以上
fast.aiの最初の最初のAWS設定につまずかないために

（はじめに）
文系大学生が独学でデータサイエンティストを目指していく過程で、勉強のアウトプット、モチベーションアップ用、誰かのためになるような情報を発信していこうと思います。日頃、Qiitaさまにはよく助けられているので。Qiita初公開です。

（本題はここから）
どうやらfast.aiがKaggleで50位に入れる方法を教えてくれるらしいという記事([fast.ai の Practical Deep Learning for Coders, Part1 を受けた](http://futurismo.biz/archives/6440))を読み、fast.aiを始めてみましたが、プログラミング歴3ヶ月の私は最初の環境構築で1週間くらいかかってしまったので、自分と同じ目に合わないようにということで今回記事を書いていきます。しかも英語しかないという。

※この記事は[Lesson0の動画](https://www.youtube.com/watch?v=8rjRfW4JM2I)を見た前提で書きます。わからない部分は動画でご確認ください。

# fast.aiの動画やWikiは見なくていい　AWS設定の仕方
1週間悩み続けた自分みたいな人が減ればとおもい。

## 0.AWSにアカウント登録
注意してほしいのはregionをOregonにすることです。
　　https://aws.amazon.com/jp/

ここでまず、電話認証に何度も失敗して、PINコードを打ってもエラーで、お問い合わせに電話番号を掲載して日本Amazonカスタマーサービスさんから電話をいただいて、やっとアカウント作成完了。（US・札幌・東京・仙台から10回ほど電話がいっせいにかかってきます。これ、改善したほうがよさそうですAmazonさん）

## 1.githubからcloneする。
以下のリンクになります。
[github.com/fastai/course/](https://github.com/fastai/courses)

```none:
git clone clone https://github.com/fastai/courses
```

## 2.ダウンロードしたcourseを開き、移動、setupの中にあるp2_setup.shをコマンドで開く

```none:
cd course/setup

bash p2_setup.sh
```

実行結果はこんなふうになりました。

```none:
$ bash setup_p2.sh
True
Waiting for instance start...

All done. Find all you need to connect in the fast-ai-commands.txt file and to remove the stack call fast-ai-remove.sh
Connect to your instance: ssh -i /Users/username/.ssh/aws-key-fast-ai.pem ubuntu@ec2-ho-gei-ho-ge.us-west-2.compute.amazonaws.com
```

## 3.実行結果の最後の`.ssh/aws-key-fast-ai.pem ubuntu@ec2-ho-gei-ho-ge.us-west-2.compute.amazonaws.com`を実行
もちろん`ubuntu@ec2-ho-gei-ho-ge.us-west-2.compute.amazonaws.com`のhogeの部分は自分の実行結果に変えてください。
```
$ .ssh/aws-key-fast-ai.pem ubuntu@ec2-ho-gei-ho-ge.us-west-2.compute.amazonaws.com
```
で、これが出てくる
```
Are you sure you want to continue connecting (yes/no)? yes
```
yesを選択。

ここで、完了。なんて簡単なことに1週間もかかっていたなんて…

## 4.　そのあと：動画どおりにする
```
ubuntu@ip-10-0-0-10:~$ nvidia-smi
nvidia-smi: command not found
ubuntu@ip-10-0-0-10:~$ sudo rm .bash_history
ubuntu@ip-10-0-0-10:~$ jupyter notebook
```

`nvidia-smi`はnot foundでした。理由がわかりませんが、問題ないので進みます。（あとで問題でる気がするがダウンロードしてないだけだと）詳しい方コメントくださいm(_ _)m

※地域については、この記事は、[Lesson0の動画](https://www.youtube.com/watch?v=8rjRfW4JM2I)で解説されていますが、オレゴン(us-west-2)にします。本当は日本でやりたいがsettingが変わってややこしくなることを防ぎます。離れているためか、通信速度が遅いですが、我慢します。

※参考程度に、AWSの概要　AWSってなんだよって人のために。
　一言で言うと、Amazonが出してる、クラウドです。
　　https://qiita.com/hiroshik1985/items/6433d5de97ac55fedfde

以上です。
fast.aiさんも設定を簡単にしたようです。おかげさまで、DLと関係のないところで試行錯誤を繰り返していた時間を取り戻す勢いでがんばります。

fast.aiのWeekごとのアウトプットも今後していく予定です。
超絶簡単 TweetDeckをしゃべるクライアントに変える! (コード量: 254バイト)

![図1.png](https://qiita-image-store.s3.amazonaws.com/0/91558/c19490c7-f1cd-5ca1-9e02-81fc2899cb93.png)

# 作ったものの動画
以下のYouTubeの動画をご覧ください。
[![TweetDeckを喋れるようにした - YouTube](http://img.youtube.com/vi/7FebVeht3Ys/0.jpg)](http://www.youtube.com/watch?v=7FebVeht3Ys)

# 使い方
ブックマーク(ブックマークレット)を作成します。
以下の図のように、URLに以下の内容を入力します。
あとは、TweetDeckを開いて作成したブックマークをクリックするだけ。
(Chromeでのみ動作確認しています。)

```js:URLの内容
javascript:(new MutationObserver(function(r){t=r[0].addedNodes[0].innerText.split("\n");if(!t[0].endsWith("Retweeted"))speechSynthesis.speak(new SpeechSynthesisUtterance(t.slice(3,-5).join("\n")))})).observe($(".chirp-container").get(0),{childList:true})
```


![image.png](https://qiita-image-store.s3.amazonaws.com/0/91558/38b734ad-563f-81ce-22c0-d55f73158ee3.png)


# 中身
まず[SpeechSynthesis](https://developer.mozilla.org/ja/docs/Web/API/SpeechSynthesis)を使ってしゃべらせるテスト。

```js
function speakText(text) {
  speechSynthesis.speak(
    new SpeechSynthesisUtterance(text)
  );
}

speakText("ﾌﾞﾘﾌﾞﾘﾌﾞﾘﾌﾞﾘｭﾘｭﾘｭﾘｭﾘｭﾘｭ！！！！！！ﾌﾞﾂﾁﾁﾌﾞﾌﾞﾌﾞﾁﾁﾁﾁﾌﾞﾘﾘｲﾘﾌﾞﾌﾞﾌﾞﾌﾞｩｩｩｩｯｯｯ！！！！！！！");
```

これだけのコード量でしゃべってくれるのすごい。


次に[TweetDeck](https://tweetdeck.twitter.com/)のメインのタイムラインが変更(誰かがつぶやい)たら、検知する。[MutationObserver](https://developer.mozilla.org/ja/docs/Web/API/MutationObserver)を使うと簡単にできます。

```js
var observer = new MutationObserver(function(mutationRecords, _observer) {
  var record = mutationRecords[0];
  var element = record.addedNodes[0];
  var text = element.innerText;
  var first_text = text.split("\n")[0];

  if (!first_text.endsWith("Retweeted")) {
    var tweet = text.split("\n").slice(3, -5).join("\n");
    console.log(tweet);
  }
});

var targetElement = $(".chirp-container").get(0);

observer.observe(targetElement, {
  childList: true
});
```

これらをつなぎ合わせる。

```js
function speakText(text) {
  speechSynthesis.speak(
    new SpeechSynthesisUtterance(text)
  );
}

var observer = new MutationObserver(function(mutationRecords, _observer) {
  var record = mutationRecords[0];
  var element = record.addedNodes[0];
  var text = element.innerText;
  var first_text = text.split("\n")[0];

  if (!first_text.endsWith("Retweeted")) {
    var tweet = text.split("\n").slice(3, -5).join("\n");
    console.log(tweet);
    speakText(tweet);
  }
});

var targetElement = $(".chirp-container").get(0);

observer.observe(targetElement, {
  childList: true
});
```

短くすると以下のようになる。

```js
(new MutationObserver(function(r){t=r[0].addedNodes[0].innerText.split("\n");if(!t[0].endsWith("Retweeted"))speechSynthesis.speak(new SpeechSynthesisUtterance(t.slice(3,-5).join("\n")))})).observe($(".chirp-container").get(0),{childList:true})
```

# 参考にしたサイト
[ブラウザのみで音声認識とテキスト読み上げを実現する Web Speech API | CYOKODOG](http://www.cyokodog.net/blog/web-speechi-api/)
[動的に生成されるDOMの操作にsetTimeoutなんぞ使うな](https://qiita.com/MysticDoll/items/7b2654b7a8b58d773286)
[SpeechSynthesis - Web API インターフェイス | MDN](https://developer.mozilla.org/ja/docs/Web/API/SpeechSynthesis)
[MutationObserver - Web API インターフェイス | MDN](https://developer.mozilla.org/ja/docs/Web/API/MutationObserver)

# まとめ
テキスト読み上げすごい。MutationObserver簡単。

# 宣伝
フォローお願いします！ :guitar: [@redshoga](https://twitter.com/redshoga)
[Git] 特定のローカルブランチをまとめて削除

Gitは最近は基本的にGUIツールのSourceTreeを使っているが、ブランチをまとめて削除するのが面倒なためコマンドでなんとかする。

# 対応方法
基本的には `git branch` で取得したブランチをgrepで絞り込んで、`xargs git branch -d` を使えば良い

```bash:基本1
$ git branch | grep branchname | xargs git branch -d
$ git branch | grep -E regex | xargs git branch -d
```

`git branch -d branchname1 branchname2` と並べて実行できるのでコマンド置換を使っても良い

```bash:基本2
$ git branch -d `git branch | grep branchname`
$ git branch -d $(git branch | grep branchname)
```

個人的にはxargsのほうが対象の絞込を確認してから、後ろにつなげればそのまま実行できるので、前者のやりかたのほうが安全な気がする。

# 参考
[Can you delete multiple branches in one command with Git? - Stack Overflow](https://stackoverflow.com/questions/3670355/can-you-delete-multiple-branches-in-one-command-with-git)
[Swift] AlamofireでSemaphoreを使って同期通信する

_whileで終わるまでループってまじかよ　―「先人」の嘆き_

## 忙しい人向け
これで解決:star:

``` 
let semaphore = DispatchSemaphore(value: 0)
let queue     = DispatchQueue.global(qos: .utility)
Alamofire.request("https://qiita.com").response(queue: queue)　{ response in
    ???
    semaphore.signal()
}
semaphore.wait()
```
## Alamofireを同期通信しようとするとデッドロックが起きる
[Alamofireでデータ受信が終わるまで待機する方法 - Qiita](https://qiita.com/kazuhirox/items/9ecb25bc238ad2d47ff0)
[Alamofire(非同期通信)をsemaphoreで同期的に処理できなかった](http://www.toosaa.net/entry/2016/10/20/102617)
などにあるように、セマフォでAlamofireの通信終了を待とうとするとデッドロックが発生します。

``` デッドロックが発生するコード
let semaphore = DispatchSemaphore(value: 0)
Alamofire.request("https://qiita.com").response{ response in
    ???
    semaphore.signal()
}
semaphore.wait()
```
これは、`response`の`completionHandler`（{}の部分）が`DispatchQueue.main`で実行されるため、同じく`DispatchQueue.main`で`semaphore.wait()`を行うと`completionHandler`の実行までも止まってしまいデッドロックが発生してしまう、という寸法です。

## 解決策
`completionHandler`を`DispatchQueue.main`以外で実行させれば良いので、 **`response`の引数に実行させたい`queue`を指定してやれば良い**です。

### 余談
_逆にAlamofireの処理は`DispatchQueue.main`のままにしておき`DispatchQueue.global()`で`semaphore.wait()`を呼ぶことでも解決できますが、面倒な上に何やってるか把握しづらいのでやめたほうがいいと思います。_


## 参考ページ
[Alamofireでデータ受信が終わるまで待機する方法 - Qiita](https://qiita.com/kazuhirox/items/9ecb25bc238ad2d47ff0)
[Alamofire(非同期通信)をsemaphoreで同期的に処理できなかった](http://www.toosaa.net/entry/2016/10/20/102617)
[GCD のディスパッチセマフォを活用する (Objective-C〜Swift 3 対応)](https://blog.ymyzk.com/2015/08/gcd-grand-central-dispatch-semaphore/)
組合せ最適化でペイントエリアを解く

Advent Calendar 12日目の記事 [組合せ最適化で推理パズルを解く](https://qiita.com/SaitoTsutomu/items/c5fe27b8727f5147e783)
Advent Calendar 14日目の記事 [組合せ最適化でウォールロジックを解く](https://qiita.com/SaitoTsutomu/items/24742740571bc122e2b8)

## これなに

**ペイントエリア**を、Pythonで[組合せ最適化](https://qiita.com/SaitoTsutomu/items/bfbf4c185ed7004b5721)モデルを作って解きます。
解く楽しみは、モデル化を工夫することになります。

自分でも試してみたい人は、下記を参考にしてください。

- [数独を通して組合せ最適化を学ぼう](https://qiita.com/SaitoTsutomu/items/bd09190d8a02432b3f16)

## 問題

- 盤面上にある、太線で区切られた部分（タイル）のいくつかを黒くぬります。
- 盤面の数字は、その数字の入っているマスにタテヨコに隣り合うマスのうち、黒マスになるマスの数を表します。
- 数字のマスが黒マスになることもあります。
- どのタイルも、すべてのマスをぬるかすべてのマスをぬらずにおくかのどちらとし、タイルの一部のマスだけをぬってはいけません。
- すべての黒マスはつながること。
- 黒白マスとも、２×２以上はだめ。

下記は、左が問題で、右が答えです。

![](https://raw.githubusercontent.com/SaitoTsutomu/opt4puzzle/master/pic/paint.png)

`data`にタイルのグループが、`nums`にヒントの「行、列、個数」が入っているとします。

```py3:python
import pandas as pd, matplotlib.pyplot as plt
from pulp import LpProblem, lpSum, value
from ortoolpy import addbinvars, unionfind
data = """\
AABBC
DEFBC
DGFHH
DGIJH
KKLJH""".splitlines()
nums = [[0,1,3], [3,2,2], [4,1,1]]
```

## 変数表

下記のような変数表を作成します。各行の変数は0または1をとります。
変数の値が1ならば、該当行 該当列のマスが黒になります。
「字」は`data`の値です。

<table><tr><th></th><th>行</th><th>列</th><th>字</th><th>Var</th></tr>
<tr><th>0</th><td>0</td><td>0</td><td>A</td><td>v000001</td></tr>
<tr><th>1</th><td>0</td><td>1</td><td>A</td><td>v000002</td></tr>
<tr><th>...</th><td>...</td><td>...</td><td>...</td><td>...</td></tr>
</table>

```py3:python
ni, nj = len(data), len(data[0])
a = pd.DataFrame([(i,j,data[i][j]) for i in range(ni)
    for j in range(nj)], columns=list('行列字'))
a['Var'] = addbinvars(len(a))
a[:2]
```


## 数理モデルを作り解く

変数表ができたので、ペイントエリアの解になるように、制約条件を追加し数理モデルを作成し、解きましょう。

- 2×2の白および2×2の黒がないこと。
    - `query`で2x2を取り出して、黒の数を1,2,3とします。
- タイル内は同じこと。
    - タイル内の隣り合う変数を等しくします。
- 数字は周りの黒の数と等しいこと。
    - 上下左右は、差分の絶対値の和が1のものです。
- 全ての黒がつながること。
    - 繋がっていなかったら、その解の全白のマスに少なくとも1つ黒を置いて解きなおします。

```py3:python
m = LpProblem()
for i in range(ni-1):
    for j in range(nj-1):
        e = lpSum(a.query(f'{i}<=行<={i+1}&{j}<=列<={j+1}').Var)
        m += e >= 1 # 2×2の白がない
        m += e <= 3 # 2×2の黒がない
for _,v in a.groupby('字'):
    for vi, vj in zip(v.Var, v.Var[1:]):
        m += vi == vj # タイル内は同じ
for i, j, k in nums: # 数字は周りの黒の数と等しい
    m += lpSum(a.query(f'abs(行-{i})+abs(列-{j})==1').Var) == k
while True:
    m.solve()
    r = a.Var.apply(value)
    if unionfind.isconnected(r.values.reshape(ni,nj)):
        break # 全ての黒がつながる
    m += lpSum(a[r==0].Var) >= 1
```

### 結果の表示

```py3:python
plt.imshow((1-r).values.reshape(ni,nj), cmap='gray', interpolation='none')
plt.show()
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/13955/79a2315a-43f7-b23d-881c-95065bb63111.png)

解けていることが確認できます。

以上
nコマンドでnodejsのバージョンを指定する方法

nodeのバージョンがサポートされてなくて困ったので。

###最新の安定版を入れる場合。

```
n stable
```

###バージョンを指定する場合(例えばv7.1.0)

```
n 7.1.0
```

これで動いた…。
組合せ最適化でスターバトルを解く

Advent Calendar 10日目の記事 [組合せ最適化でクリークを解く](https://qiita.com/SaitoTsutomu/items/d6897d8ec72fdfe7370e)
Advent Calendar 12日目の記事 [組合せ最適化で推理パズルを解く](https://qiita.com/SaitoTsutomu/items/c5fe27b8727f5147e783)

## これなに

**スターバトル**を、Pythonで[組合せ最適化](https://qiita.com/SaitoTsutomu/items/bfbf4c185ed7004b5721)モデルを作って解きます。
解く楽しみは、モデル化を工夫することになります。

自分でも試してみたい人は、下記を参考にしてください。

- [数独を通して組合せ最適化を学ぼう](https://qiita.com/SaitoTsutomu/items/bd09190d8a02432b3f16)

## 問題

- 各行、各列、各エリアに★をちょうど1つ置く。
- ★の周り(8か所)に★は置けない。

左が問題で、右が答えです。

![](https://raw.githubusercontent.com/SaitoTsutomu/opt4puzzle/master/pic/starbattle.png)

Pythonでは、`data`（エリアのグループ）を使うことにします。

```py3:python
import pandas as pd, matplotlib.pyplot as plt
from pulp import LpProblem, lpSum, value
from ortoolpy import addbinvars
data = """\
AABBB
AABCC
ADDDC
DDECC
EEEEC""".splitlines()
```

## 変数表

下記のような変数表を作成します。各行の変数は0または1をとります。
変数の値が1ならば、該当行 該当列のマスが★になります。

<table><tr><th></th><th>行</th><th>列</th><th>字</th><th>Var</th></tr>
<tr><th>0</th><td>0</td><td>0</td><td>A</td><td>v000001</td></tr>
<tr><th>1</th><td>0</td><td>1</td><td>A</td><td>v000002</td></tr>
<tr><th>...</th><td>...</td><td>...</td><td>...</td><td>...</td></tr>
</table>

```py3:python
nn = len(data)
a = pd.DataFrame([(i,j,data[i][j]) for i in range(nn)
    for j in range(nn)], columns=list('行列字'))
a['Var'] = addbinvars(len(a))
a[:2]
```


## 数理モデルを作り解く

変数表ができたので、スターバトルの解になるように、制約条件を追加し数理モデルを作成し、解きましょう。

- 各行、各列、各エリアに★をちょうど1つ置く。
    - `['行','列','字']`ごとに、`groupby`して、和を1にします。
- ★の周り(8か所)に★は置けない。
    - 2x2マスの中に、★を1つ以下にすればOKです。

```py3:python
m = LpProblem()
for cl in ['行','列','字']:
    for _,v in a.groupby(cl):
        m += lpSum(v.Var) == 1
for i in range(nn-1):
    for j in range(nn-1):
        q = f'{i}<=行<={i+1}&{j}<=列<={j+1}'
        m += lpSum(a.query(q).Var) <= 1
m.solve()
```

### 結果の表示

```py3:python
a['Val'] = a.Var.apply(value)
plt.imshow((a.Val<0.5).values.reshape(nn,nn), cmap='gray', interpolation='none')
plt.show()
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/13955/6174d55e-e07b-9847-c062-b10bd9a5c5af.png)

別解ですが、制約条件は、満たしているようです。

以上
【Playcanvas】Image Elementの当たり判定がうまくいかない問題【2Dゲーム】

Image ElementにCollisionをつけてtriiger enterで当たり判定の処理を実装した際に、うまく当たり判定がいかなかったので再現手順を記述したいと思います。

[サンプルプロジェクト](https://playcanvas.com/project/513574/overview/shootingtest)

## 実装手順

1.Player,Enemy,Bulletの画像を32*32ドットで用意する。
2.Playcanvasのroot配下に2D Screenを設置する。
3.2D ScreenにPlayer,Enemy,BulletになるImage Elementを追加する。
4.Image Elementに画像をアタッチする。
5.EnemyのImage ElementにCollisonとRigidbodyをアタッチする。

![20171126enemysetting.PNG](https://qiita-image-store.s3.amazonaws.com/0/76537/7350d900-3d51-1d6d-8c58-eb9d4d0fe4eb.png)

6.BulletのImage ElemetにCollisonをアタッチする。

![20171126bulletsetting.PNG](https://qiita-image-store.s3.amazonaws.com/0/76537/765e346e-7837-cf06-155d-3bafd6931309.png)

7.Bullet,PlayerにScriptをアタッチし、スペースキーでPlayerからBulletを発射するようにする。

PlayerからBulletが発射されEnemyに当たると止まる処理を記述しているのですが、かなり手前で判定が行われるようです。

![20171126game.PNG](https://qiita-image-store.s3.amazonaws.com/0/76537/a549e783-8c78-52ca-4f27-45b0f1bae890.png)

この原因がわからないので教えて詳しい人！
タイピングを利用したソースコードリーディングの方法

###タイピングを利用したソースコードリーディング
昔は、北斗の拳のタイピングソフトでタイピングを覚えました。最近、ソースコードを読んでて思うことが、結構ソースコードだけ読んでいくのが精神的に辛いなということなんですよね。
ソースコードを読むことを習慣にしようとするんですが、なかなか続かないということなんですよね。
２ちゃんねるに「最初は眺めている感じでいい、毎日読むこと」と書いてあっても、なかなか続かない。
ということで、いろいろ探していると、typing.ioというサイトを見つけたんですが、このサイトが、詳細は省きますが、微妙に使えないんですよね。しばらくメンテナンスがされていないようです。
ということで、代替のものを探したんですよね。以下のものを見つけました。

https://github.com/shadowfacts/type

これは以下のウェブサイトにアクセスして、

https://type.shadowfacts.net

「owner/repo」と書いてあるところに、まずは、

https://github.com/shadowfacts/type　

このサイトのソースコードだったら、

shadowfacts/type

と入力するんですよね。
それから、「path/to/file.js」というボックスが出てくるので、ファイルパス、例えば

js/type.js

みたいなものを入力するわけです。
そしたらソースコードを写経開始です。タイピングしていけば、どんどんシンタックスハイライトで塗りつぶされていきます。
個人的にやってみて思ったことが、どんどん塗りつぶされていくので、なんだか達成感があるのと、なんか、ソースコードを理解するのがたやすくなった感じがします。
これが果たして、ソースコードをそのまま読んでいくより学習効果が上がるのか、それはちょっとわかりません。プログラミングの学習効果の測定は容易じゃないです。
でも、ソースコードをタイピングしていくことは全然苦行じゃないので、なんか他のことに疲れたら、気分転換にやってみてもいいのではないでしょうか？


<img width="1440" alt="スクリーンショット 2017-11-25 15.31.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/53172/bc2f6f15-4a55-e349-4bc3-a45d788b686e.png">
AngularでMarkdownをHTMLとして表示するカスタムpipeを作成する

AngularでMarkdownをHTMLとして表示するpipeを作成してみます。
markedパーサーは定番っぽいmarkedを使いました。

# 前提

今回使用した環境は次の通りです。

```bash
$ ng -v
...
Angular CLI: 1.5.4
Node: 9.2.0
OS: darwin x64
Angular: 5.0.3
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

@angular/cli: 1.5.4
@angular/flex-layout: 2.0.0-beta.10-4905443
@angular-devkit/build-optimizer: 0.0.33
@angular-devkit/core: 0.0.21
@angular-devkit/schematics: 0.0.37
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.8.4
@schematics/angular: 0.1.7
typescript: 2.4.2
webpack: 3.8.1
```


# 手順

## pipeの作成

markdをインストール
(今回使ったバージョンは1.2.0)

```bash
$ npm i markd --save
```

angluar-cliでパイプを作成します。

```bash
$ ng generate pipe mdToHtml
```

前の手順で作成された`md-to-html.pipe.ts`を編集していきます。

```typescript:md-to-html.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
import * as marked from 'marked'; // markedをインポート

@Pipe({
  name: 'mdToHtml'
})
export class MdToHtmlPipe implements PipeTransform {

  // 追加
  mdToHtml(md: string): any {
    return marked(md);
  }

  transform(value: any): any {
    // pipeに流れてきた文字列をmarkedに渡す
    return this.mdToHtml(value);
  }
}
```
pipeの実装は上記のみです。

# 使い方

実際にテンプレートからパイプを使ってみます。
angluar-cliでpipeを作成した場合、デフォルトでapp.module.tsにインポート&declarationsへの定義が終わっているので、使用したいコンポーネントのテンプレートから呼び出すだけです。

```html
<div [innerHTML]="md | mdToHtml"></div>
```

`innerHTML `というプロパティに変換後のHTMLをバインドして表示しています。

## 例

簡単なMarkdownエディタみたいなものです。
(左側のテキストエリア入力したMarkdownが右側でHTMLに変換されて表示される)

```html:app.component.html
<div fxLayout="row">
  <div fxFlex="50%">
    <textarea [(ngModel)]="md" cols="30" rows="50" style="width: 100%"></textarea>
  </div>
  <div fxFlex="50%">
    <div [innerHTML]="md | mdToHtml" style="padding: 10px"></div>
  </div>
</div>
```

app.moduleに、FormsModuleとFlexLayoutModuleをインポートし、
コンポーネントのクラス側では、入力した内容を格納するmdという変数を定義しているだけです。

![スクリーンショット 2017-11-26 18.31.35.png](https://qiita-image-store.s3.amazonaws.com/0/79414/110fc134-91ea-9b2e-3864-6a9e33782ccd.png)



angular-cliではpipeをテンプレートを作成するコマンドも用意されているので、今回のようなライブラリをパイプに組み込む使い方も簡単に行えました。

# 参考

https://angular.io/guide/pipes
Node.js でメールの受信

Node.js で imap サーバーからメールを受信する方法です。
ライブラリーは、inbox を使います。

```bash
sudo npm install inbox
```

```js:imap_get.js
#! /usr/bin/node
// ---------------------------------------------------------------
//	imap_get.js
//
//					Nov/26/2017
//
// ---------------------------------------------------------------
var inbox = require("inbox")

const server = "imap.mail.yahoo.co.jp"
const user = "xxxxxx"
const password = "yyyyyy"
 
var client = inbox.createConnection(false, server, {
    secureConnection: true,
    auth:{
        user: user,
        pass: password
    }
})
 
client.connect()
 
// ---------------------------------------------------------------
client.on("connect", function()
{
	console.log ("*** connected ***")
	client.openMailbox("INBOX", function(error, info)
	{
	if(error) throw error;
 
	client.listMessages(-10, function(err, messages)
		{
		messages.forEach(function(message)
			{
			const uid = message.UID
			console.log(uid)
			console.log("Name: " + message.from.name)
			console.log("Address: " + message.from.address)
			console.log("Title: " + message.title)

//			client.createMessageStream(uid).pipe(process.stdout, {end: false})
			});

		client.close()
		})
	})
})

// ---------------------------------------------------------------
client.on('close', function (){
    console.log('*** disconnected! ***');
})

// ---------------------------------------------------------------
```

次の環境で動作を確認しました。

```text
$ uname -a
Linux iwata 5.4.0-42-generic #46-Ubuntu SMP Fri Jul 10 00:24:02 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

$ node --version
v14.8.0
```
ReactNative入門③ ~Propsに触れる~

## Props
Componentを場面に適した状態で使用するには、Propsを使用します。
場面に適した状態とは、ボタンのコンポーネントを作成時には「作成」と表示されたボタン、更新時には「更新」と表示されたボタンを描画することです。
この、コンポーネントをカスタマイズするパラメータを`props`と呼びます。


## コードで確認する
先にソースコードを見てみましょう。

```js
import React, { Component } from 'react';
import { AppRegistry, Text, View } from 'react-native';

class Greeting extends Component {
  render() {
    return (
      <Text>Hello {this.props.name}!</Text>
    );
  }
}

export default class LotsOfGreetings extends Component {
  render() {
  return (
      <View style={{alignItems: 'center'}}>
        <Greeting name='Rexxar' />
        <Greeting name='Jaina' />
        <Greeting name='Valeera' />
      </View>
    );
  }
}

AppRegistry.registerComponent('AwesomeProject', () => LotsOfGreetings);
```

## 解説
今回のコードでは、Greetingというコンポーネントを作成し、LotsOfGreetingsというコンポーネントの中で呼び出しています。

注目は、Greetingコンポーネントを呼び出している16~18行目です。
`name=名前`となっています。この部分で、Greetingコンポーネントにpropsを定義しています。
propsの定義は、`props名=propsの値`という形になります。
そして、Greetingコンポーネント側では、`this.name`と記述することで、propsにアクセスしています。
これがpropsの定義方法と値の取得方法になります。
シミュレータを確認すると、以下のように同じコンポーネントを使っていても、表示される名前が異なります。（ステータスバーに重なっているので、見づらいですが、、、）
このようにpropsを使うことで、同じコンポーネントを使っても、表示などを変更することが可能になります。

![iPhone_6_-_iOS_11_0.png](https://qiita-image-store.s3.amazonaws.com/0/45577/67d7b67f-0102-86a5-cf2f-bc2677357b7f.png "iPhone_6_-_iOS_11_0.png")
さくらのクラウド > phpMyAdminのインストール



# 環境
さくらのクラウド
OS：CentOS 7.2

# 参考
[「location ~ \[^/\]\\\.php\(/\|$\)」の前あたりに、以下のコードを追加します。](https://chronoir.net/use-phpmyadmin-on-nginx-with-kusanagi/)

## suになる


## カレントディレクトリをKUSANAGIのまで持っていく！

`# cd /home/kusanagi/`


## phpMyAdminをwget！

最新ファイルは以下で確認する。
[phpMyAdmin](https://www.phpmyadmin.net/)

ダウンロードのリンク先を取得して以下コマンド

```
# wget https://files.phpmyadmin.net/phpMyAdmin/4.7.5/phpMyAdmin-4.7.5-all-languages.zip
```

## unzip

`unzip phpMyAdmin-4.7.5-all-languages.zip`


## rename

`# mv phpMyAdmin-4.7.5-all-languages phpMyAdmin`


## カレントディレクトリを移動
プロファイルに応じたconfファイルの変更

```
# cd /etc/nginx/conf.d
$ vi [PROFILE]_http.conf
```


「location ~ [^/]\.php(/|$)」の前あたりに、以下を追加

> phpMyAdmin用のlocationディレクティブを作成し、先ほどインストールしたphpMyAdminのディレクトリをaliasに指定します。その中に、PHPファイル用のlocationディレクティブを作成し、phpMyAdminのディレクトリをfastcgi_paramのSCRIPT_FILENAMEに指定します。


```
# http://[ホスト名]/phpMyAdmin/ 内のファイルに対する処理を行います。
location ^~ /phpMyAdmin/ {
	# aliasには、インストールしたphpMyAdminのディレクトリを指定します。
	alias /home/kusanagi/phpMyAdmin/;
	try_files $uri $uri/ /index.php;
	# 接続できるIPアドレスを制限します。
	allow 127.0.0.1;
	# 自分のPCのネットワーからアクセスできるように、IPアドレスを指定します。
	allow 125.56.1.254;

	deny all;

	# http://[ホスト名]/phpMyAdmin/ 内のphpファイルに対する処理を行います。
	location ~ /phpMyAdmin(.+\.php)$ {
		fastcgi_pass    127.0.0.1:9000;
		fastcgi_index   index.php;
		# fastcgi_paramのSCRIPT_FILENAMEには、インストールしたphpMyAdminのディレクトリを指定します。
		fastcgi_param   SCRIPT_FILENAME  /home/kusanagi/phpMyAdmin$1;
		include         fastcgi_params;
		fastcgi_buffers 256 128k;
		fastcgi_buffer_size 128k;
		#fastcgi_intercept_errors on;
		#fastcgi_read_timeout 120s;
	}
}
```

## restart
kusanagi nginx


## Access to phpMyAdmin

https://xxxx.com/phpMyAdmin/
さくらのクラウド > Redmineのインストール


# 環境
さくらのクラウド
OS：CentOS 7.2 (kusanagi)
kusanagi


kusanagiのプロビジョニングでRailsの環境が簡単に作成できるようです。（2017.11.2発表）

[KUSANAGI バージョンアップ情報 8.1.0](https://kusanagi.tokyo/archives/4152/)
[超高速CMS仮想マシン「KUSANAGI」がRuby on Railsに対応 ](https://webtan.impress.co.jp/u/2017/11/02/27330)

[KUSANAGIコマンド – rails](https://kusanagi.tokyo/document/command/#ruby-on-rails)


## という訳で、以下の情報は古くなりました。（2017/11/27）

# Redmin
[Redmine 3\.4をCentOS 7\.3にインストールする手順 \| Redmine\.JP Blog](http://blog.redmine.jp/articles/3_4/install/centos/)



## Redmine専用ユーザーを作成
```
# useradd redmine
# passwd redmine
```





kusanagi環境にてphp、mysql、rubyは導入済み

## yum.conf
/etc/yum.confの最下部に以下を追加
`group_package_types=optional`


## 開発ツール(Cコンパイラ等)のインストール
必要なパッケージのインストール。前述のyum.confの設定をしないとパッケージのインストールが成功しない。
yum -y groupinstall "Development Tools"


## RubyとPassengerのビルドに必要なヘッダファイルなどのインストール
`yum -y install openssl-devel readline-devel zlib-devel curl-devel libyaml-devel libffi-devel`


## ImageMagick
yum -y install ImageMagick ImageMagick-devel ipa-pgothic-fonts



## redmineの取得
カレントフォルダを以下に移動したのちsvnコマンドで取得する。
/home/kusanagi/redmine/


`# svn checkout http://svn.redmine.org/redmine/branches/3.4-stable redmine`


/home/kusanagi/redmine/redmine3.4
に配置した。


## rbenvインストール
```
git clone https://github.com/sstephenson/rbenv.git /usr/local/rbenv
echo 'export RBENV_ROOT="/usr/local/rbenv"' >> /etc/profile
echo 'export PATH="${RBENV_ROOT}/bin:${PATH}"' >> /etc/profile
echo 'eval "$(rbenv init -)"' >> /etc/profile

```
バージョンの確認

`rbenv --version`





## ruby-buildインストール
`git clone https://github.com/sstephenson/ruby-build.git /usr/local/rbenv/plugins/ruby-build`


## rubyインストール
rbenvでインストールできるRubyのバージョン一覧確認
`rbenv install -l`


Rubyのバージョンを指定してインストール
```
rbenv install -v 2.4.2
rbenv rehash
```


使用するRubyのバージョンを指定
`rbenv global 2.4.2`

バージョンを確認する
`ruby -v`



## Railsインストール
```
gem update --system
gem install --no-ri --no-rdoc rails
gem install bundler
rbenv rehash
```

バージョンを確認する
`rails -v`

エラーが出る場合
`Could not find xxx in any of the sources`
などのエラーが出る場合、

`bundle update`
をやってみる。 


## gemパッケージのインストール

Rubyのパッケージ管理ツール「bundler」を使用してRedmineが依存するgemパッケージをインストールします。
Redmineのインストールディレクトリで以下のコマンドを実行してください。

`bundle install --without development test --path vendor/bundle`


## bundleのインストール
`gem install bundler`





## Redmineの初期設定と初期データ登録

### セッション改ざん防止用秘密鍵の作成

`bundle exec rake generate_secret_token`

エラーが出る
```
Could not find nokogiri-1.7.2 in any of the sources
```

`yum -y install libxml2 libxslt libxml2-devel libxslt-devel`

gem install nokogiri -v '1.7.2'






### データベースのテーブル作成

config/database.yml で指定したデータベースにテーブルを作成します。

`RAILS_ENV=production bundle exec rake db:migrate`





## Unicornのインストール

RedmineをインストールしたディレクトリにGemfile.localというファイルを作成し
gem “unicorn”と追記します。

bundle updateコマンドを実行し、unicornをインストールします。

`bundle update`
CentOS > SMB


Samba

# install


```
# yum -y install samba
```


```
mkdir /home/samba

chmod 777 /home/samba
cp /etc/hosts /home/samba
nano /etc/samba/smb.conf


useradd username
passwd username
pdbedit -a username

chown username /home/$user/samba
```


## smb.confの編集
`vi /etc/samba/smb.conf`


```

[global]
	workgroup = WORKGROUP
	catia:mappings = 0x22:0xa8,0x2a:0xa4,0x2f:0xf8,0x3a:0xf7,0x3c:0xab,0x3e:0xbb,0x3f:    0xbf,0x5c:0xff,0x7c:0xa6
	vfs objects = catia
	dos charset = CP932
	unix charset = UTF-8
	hosts allow = xxx.xxx.xxx.xxx.
	read only = no
	mangled names = no


[homes]

　	# /home/ユーザー名/sambaをホームディレクトリにする
	path = %H/samba

	# Windows側から見た時に付加されるコメント
	comment = %U's Home directory

	# Windowsの共有一覧にホームディレクトリを表示するか
	browseable = No

	# 読み出しのみ可能か
	read only = No

	# 書き込みを許可する
	writable = Yes

	# ファイルにはこのアクセス権（644）が付与される
	create mode = 0644

	# ディレクトリにはこのアクセス権（775）が付与される
	directory mode = 0775
```



## smbの起動と再起動
初回はstart, 以後はrestart

```
systemctl start smb
systemctl start nmb
```

以後はrestart

```
systemctl restart smb
systemctl restart nmb
```

## Samba自動起動設定

```
# systemctl enable smb
# systemctl enable nmb
```
GCPを使ってデプロイから独自ドメイン設定まで行う

## はじめに
ドメインを取得しようとしていたところ、beta版ながらGoogle Domainsが日本で利用可能になっていたので使ってみました。
今回はhello worldアプリをGAE上にデプロイし、ドメインを取得してマッピングするところまで行います。

基本的には公式ドキュメントを参考にしているため、しっかりと理解したい方はそちらをみたほうが良いでしょう。
最近仕事で使っていることもあり、言語はGoを選択しました。

デプロイする前にプロジェクトの作成とCloud SDKをインストール必要があるので、以下を参考にしてください。

**プロジェクト作成**
https://console.cloud.google.com/projectselector/appengine/create?lang=go&st=true&hl=ja&_ga=2.158786106.-1060890979.1502261753

**SDKをインストール**
https://cloud.google.com/appengine/docs/standard/go/download?hl=ja

## GAEにデプロイ
**helloworldディレクトリをクローンする**

```bash
$ git clone -b part1-helloworld https://github.com/GoogleCloudPlatform/appengine-guestbook-go.git helloworld
$ cd helloworld
```

**ローカルで動かしてみる**
app.yaml ファイルが置かれている場所で以下のコマンドを実行します。

```bash
$ dev_appserver.py app.yaml
```

以下にアクセスし確認しましょう。
http://localhost:8080

**デプロイ**
app.yamlが置かれている場所で以下のデプロイコマンドを実行します。

```bash
$ gcloud app deploy
$ gcloud app browse
```

以上でデプロイは完了です。

他のプロジェクトが設定されている際は以下のコマンドで変更することができます。

```bash
$ gcloud projects list // プロジェクト一覧
$ gcloud config list // 設定されているプロジェクト
$ gcloud config set project <project name> // プロジェクトの設定
```

gcloudコマンドの詳細は以下を確認してください。
https://cloud.google.com/sdk/gcloud/reference/


## ドメイン取得
Google Domainsでドメインを取得します。
価格は年間1400円と決して安いとは言えず、jpもありません。(2017年11月現在)
お名前.comで調べたところ同じドメインが910円だったので500円近く価格差があります。

[Google Domains](https://domains.google/#/)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/25424/e58ab9fc-8623-3195-c3e8-92d25e0d5fcf.png)

お好きなドメインを検索し、カートアイコンを選択してください。
whoisに情報を公開したくない際はMake my info privateを選択しましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/25424/1f7898fd-11f3-15e0-dc3e-d7d57bf7c45b.png)

カード情報の登録やメールアドレスの認証を済ませれば取得完了です。


## ドメインをアプリにマッピングする

```bash
$ gcloud domains verify xxx.com　// webmaster centralを通して、ドメインの所有者であることを認証します。
$ gcloud domains list-user-verified　// 認証済みのドメインを確認
$ gcloud beta app domain-mappings create xxx.com　// 先ほど作成したアプリにドメインをマッピング
```

以下からDNS設定ページを開き、DNSをクリックしてください。
https://domains.google.com/registrar?hl=ja#chp=d

![image.png](https://qiita-image-store.s3.amazonaws.com/0/25424/985086a3-3c96-1ab6-a806-31fa56d96247.png)

カスタムリソースレコードからAレコードを登録します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/25424/e035fcc0-0929-5853-10d8-71cf05a5af67.png)

アクセスして表示されれば完了です。(反映されるのに少し時間がかかります。)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/25424/ffb15210-ea19-1caa-c33d-1e85f7be4d08.png)


## 参考
https://cloud.google.com/appengine/docs/standard/go/quickstart?hl=ja
https://cloud.google.com/appengine/docs/standard/go/mapping-custom-domains?hl=ja
https://cloudplatform-jp.googleblog.com/2017/07/App-Engine-users-now-you-can-configure-custom-domains-from-the-API-or-CLI.html
Prophetを使って時系列解析してみた


#Prophetとは
- Facebookが開発したオープンソースの時系列解析パッケージ
- PythonとRのいずれでも利用可能
- 「トレンド」「季節効果」「イベント」の3つで時系列を解析

#開発環境
- CentOS 7.2
- Jupyter 4.3.0
- Python 3.6.3 :: Anaconda, Inc.

#ライブラリをインストールしよう

　まずはライブラリをインストールします。
　scopyやpandasといった他のライブラリについては、Anacondaインストール時に入っているので省略します。

```py
pip install pystan
pip install fbprophet
```

#データを読み込もう

　今回は定番のデータセットを用意せず、総務省が公開している総人口数を1921～2015年分を用意して、csv形式に整形して今後の人口変動を予測してみました。

```py
dateparse = lambda dates: pd.datetime.strptime(dates, '%Y-%m')
df=pd.read_csv("total_population.csv",names=("ds","y"),date_parser=dateparse)
df.tail()
```

![prophet001.png](https://qiita-image-store.s3.amazonaws.com/0/213134/98cbb548-f1ff-9b88-7c93-fbe28246fa07.png)

#モデルを構築してプロットしよう

　csvファイルが読み込めたことが上記で確認できました。
　それでは、ここからが本題。モデルを用意して、用意したデータに合うようフィットさせます。ここで、1年に1個のデータでありデータ数も少ないことから季節効果は考慮しないようFalseにしました。

```py
from fbprophet import Prophet
m = Prophet(yearly_seasonality=False)
m.fit(df)
```

　では2015年1月から200ヶ月先の人口変動を予測したいと思います。
　まずは日付だけの空のデータを用意します。

```py
future = m.make_future_dataframe(periods=200,freq='m')
future.tail()
```

![prophet002.png](https://qiita-image-store.s3.amazonaws.com/0/213134/379b9785-eda7-fdac-b4f5-c4192a21ccea.png)


　2031年8月末までの予測になりますね。
　では、データの予測を行いたいと思います。

```py
forecast = m.predict(future)
forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail()
```
![prophet003.png](https://qiita-image-store.s3.amazonaws.com/0/213134/cceb3503-60b4-0abb-9f1a-87386234271f.png)

　空の部分に予測データが入ってきました。
　それでは、このデータをプロットしてみましょう。

```py
m.plot(forecast)
```

![prophet004.png](https://qiita-image-store.s3.amazonaws.com/0/213134/2d159525-e448-cf72-4c97-ca8cae60e902.png)

　今後の人口は微増のようですね。
　ただ先に進めば$y_{lower}$のように減少傾向につながることが見られます。他の説明変数も関わってきそうなので、VARなどの多変量時系列解析で評価する必要がありそうです。

　今回はここまで。
2次配列を転置したい


Pythonで2次配列の転置行列 (x軸、y軸を入れ替える) の作り方。
毎回調べなおしてるので、めもめも。

```py
>>> matrix = [
...   [ 11, 12, 13 ],
...   [ 21, 22, 23 ]
... ]

>>> for l in matrix:
...   print l
... 
[11, 12, 13]
[21, 22, 23]

>>> transposed = list(zip(*matrix))

>>> for l in transposed:
...   print l
... 
(11, 21)
(12, 22)
(13, 23)
```

## Python 2.x系

Python 2.x系だと↓だけで期待した結果になります。

```py
>>> zip(*matrix)
[(11, 21), (12, 22), (13, 23)]
```

なんでこうなるかというと Python 2.x系 と 3.x系 は ``zip()`` functionの動きが異なるのが原因です。

* [2.x系の zip()](https://docs.python.org/2.7/library/functions.html#zip) は **tuple の list** を返します。
* [3.x系の zip()](https://docs.python.org/3.3/library/functions.html#zip) は **tuple を返す generator** を返します。

## tupleじゃなくてlistで

tuple のままだと都合が悪い時は ``map()`` を使います。

```py
>>> map(list, zip(*matrix))
[[11, 21], [12, 22], [13, 23]]
```