OmniAICreator/Qiita-1.07M huggingface dataset:
F#で別プロセスの標準出力をもれなくとる



![IMG_2219.jpeg](https://qiita-image-store.s3.amazonaws.com/0/149269/be1b155a-cfe6-b3b5-3be1-1d8c1612e0b2.jpeg)

```
標準出力をとったときの
喜びのポーズ
```







# Summary

別プロセスの標準出力を取得する

## Motivation

`dotnet-RX` というか `fsharp control reactive` でなぜか`throttle`だけはじかれるので、なんとなくもどきを作ってみた


## like this

`sendRecieve`のところ

```fsharp

type Interaction (fp:string, args:string, wd:string) =

  let cq = new ConcurrentQueue<DataReceivedEventArgs>()

  // 子プロセスの起動パラメータを作成する
  let procStartInfo =
    ProcessStartInfo(
      FileName     = fp ,
      Arguments    = args ,
      WorkingDirectory   = wd ,
      RedirectStandardInput  = true , // 子プロセスの標準入力をリダイレクトする
      RedirectStandardOutput = true , // 子プロセスの標準出力をリダイレクトする
      RedirectStandardError  = true , // 子プロセスの標準エラーをリダイレクトする
      UseShellExecute    = false  // シェルを使用せず子プロセスを起動する(リダイレクトするために必要)
    )

  // 子プロセスをインスタンス化
  let ps = new Process(StartInfo = procStartInfo)

  do ps.OutputDataReceived
    |> Event.add ( fun (args :DataReceivedEventArgs) ->
    cq.Enqueue(args) |> ignore
    )

  // 子プロセスを起動する
  do ps.Start() |> ignore
  // 子プロセスがアイドル状態になるまで無期限に待機
  do ps.WaitForInputIdle() |>ignore
  // Start the asynchronous read of the ps output stream.
  // 標準出力の非同期読み込みを開始する
  do ps.BeginOutputReadLine()

  // リダイレクトした子プロセスの標準入力にテキストを書き込む
  member this.Send(message:string) =
    ps.StandardInput.WriteLine(message)

  member this.Quit() =
    ps.Kill()

  member this.sendRecieve (message:string) : string=

    let initialTime = System.TimeSpan.FromMilliseconds(10000.)
    let checkTime = 300

    cq.Clear |> ignore
    ps.StandardInput.WriteLine(message)

    // 標準出力の初期出力はなんとなく遅いので
    // 多めに待ってあげる
    let sw = new System.Diagnostics.Stopwatch();
    sw.Start();
    while cq.IsEmpty do
      if sw.Elapsed > initialTime then
        raise (System.ArgumentException("===== foo =====") )
      ()

    // cq.Countが300ms以内に変化がなければ
    // 全て出力されたとみなして値を返す
    let rec foo () =
      let mutable currentCount = cq.Count
      Thread.Sleep checkTime |> ignore
      if currentCount = cq.Count then
        snd ( cq.TryDequeue() ) |> fun x -> x.Data
      else
        foo ()

    foo ()
```

使い方サンプル

```fsharp
let mono  = "/usr/local/Cellar/mono/5.18.0.268/bin/mono"
let args  = "./bin/deopletefs.exe"
let workdir = "./"
let replyer = Interaction(mono,args,workdir)

let initialize_deopleteExe () =
  let json = """{ "Row" : -9999 ,"Col": 1, "Line": "", "FilePath" : "./dummy.fsx", "Source" : "", "Init":"true"}"""
  let resultString = """{"word":"finish initialize!","info":[[""]]}"""
  check (decode64( replyer.sendRecieve(json)  )) resultString
initialize_deopleteExe ()
```

改善点多々あり、、、ですよね・・・。。

はぇ〜さん( @haxe）によると `ConcurrentQueue` を入力待ちに使うの、すじわる〜らしい。。。ひっ。
DockerでWASMを試してみる

# install

[公式サイト](https://webassembly.org/getting-started/developers-guide/)のインストール方法だと、環境依存度が高すぎるので、Dockerを使おう。

```bash
docker pull trzeci/emscripten
```

# coding

Hello Worldを書く。

```c:hello/hello.c
#include <stdio.h>
int main(int argc, char ** argv) {
  printf("Hello, world!\n");
}
```
出典：[公式サイト](https://webassembly.org/getting-started/developers-guide/)

# compile

コンパイルしよう。

```bash
docker run \
  --rm \
  -v $(pwd)/hello:/src \
  -u emscripten \
  trzeci/emscripten \
  emcc hello.c -s WASM=1 -o index.html
```

こんな感じに`*.html,*.js,*.wasm`ファイルができる。

```text
└── hello
    ├── hello.c
    ├── index.html
    ├── index.js
    └── index.wasm
```

# run

ウェブサイトとして実行する。

```bash
docker run \
  --rm \
  -v $(pwd)/hello:/src \
  -u emscripten \
  -p 8080:8080 \
  --network=host \
  trzeci/emscripten \
  emrun --no_browser --port 8080 .
```

以下のサイトにアクセスする。

http://localhost:8080

Hello Worldが表示された。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/114392/d2454c85-c289-689a-3789-224d2a548171.png)

# Reference

- https://webassembly.org/getting-started/developers-guide/
- https://hub.docker.com/r/trzeci/emscripten
netdataでサーバの監視

サーバーの稼働状況を見やすくしたかったので、centos7にnetdataというものを入れてみた。

# netdataインストール
これだけで入るから楽

```
bash <(curl -Ss https://my-netdata.io/kickstart.sh)
```

# netdata起動
デフォルトが19999portを使うのでそこを開放

```
firewall-cmd --zone=public --add-port=19999/tcp --permanent && firewall-cmd --reload
```

これでブラウザから確認できるはず

```
http://[server-IP or Server-Name]:19999
```


# gpuの監視用プラグイン
gpuも見たかったので、以下のようにプラグインを入れた

```
cd /tmp/
# ダウンロード
git clone https://github.com/Splo0sh/netdata_nv_plugin --depth 1
cp netdata_nv_plugin/nv.chart.py /usr/libexec/netdata/python.d/
cp netdata_nv_plugin/python_modules/pynvml.py /usr/libexec/netdata/python.d/python_modules/
cp netdata_nv_plugin/nv.conf /etc/netdata/python.d/
# 再起動
systemctl restart netdata
```

# Custom
デフォでは`/usr/share/netdata/web/index.html`を参照しているみたいだけど適当に新しいhtmlファイルを作ってそこを見に行けば、自分で表示を変えられたので結構カスタマイズしやすいかなと思った。
複数のサーバー状況を一箇所で確認することもできた。
Google Code Jam 2019 Qualification

#Google Code Jam 2019 Qualification
Google Code JamとはGoogleが主催するプログラミングコンテストです。先日、予選が開催されました。
https://codingcompetitions.withgoogle.com/codejam/round/0000000000051705

##Question1 Foregone Solution
問題文
整数Nが与えられます。A+B=Nを満たす整数A,Bのうち、4を含まないものの1例を示してください。

解答例
nを2で割る。nが奇数ならリストに格納した後のaに+1する。
割った値a,bを1桁ずつに分解し、4が含まれていたらその桁の値をaは+1,bは-1とする。

```python:Foregone_Solution.py
t = int(input())
n = []
a = []
b = []

for i in range(t):
  n.append(int(input()))

for i in range(t):    
  if n[i]%2 == 0: #If n is even number
    d = 0
    x = int(n[i]/2)
    y = x
    num = []
    while x != 0: #nを各桁に分割し、リストに格納する
      num.append(int(x%10))
      x /= 10
    for j in range(len(num)): #もし桁が4であればその桁を+1する
      if 4 == num[j]:
        d += 10**j
    a.append(y+d)
    b.append(y-d)
  else: #If n is odd number add 1 to 'a' last
    d = 0
    x = int(n[i]/2)
    y = x
    num = []
    while x != 0:
      num.append(int(x%10))
      x /= 10
    for j in range(len(num)):
      if 4 == num[j]:
        d += 10**j
    a.append(y+d+1)
    b.append(y-d)
for i in range(t):
  print('Case #{0}: {1} {2}'.format(i+1, a[i], b[i]))
```
input:
4
2345
4444
888
9876

output:
Case # 1 : 1173   1172
Case # 2 : 2222   2222
Case # 3 : 555   333
Case # 4 : 5938   3938

##Question2 You Can Go Your Own Way
Nが与えられます。N*Nマス上を移動するYouとLydiaがいます。Lydiaが進む方向(SまたはE)が与えられます。Lydiaと同じマスからマスへの移動をすることなしに、Youがスタートの北西からゴールの南東のブロックまで進む1例を示してください。

解答例
・YouとLydiaが同じマスにいたらLydiaが進まない方角に進む。(LydiaがEならYouはSに進む)

・YouとLydiaが異なるマスにいたらYouはゴールの南東へ近づく方向へ進む。SとEのうち、現在いる位置からゴールまで遠い方の方角へ進む。
分かりづらいので具体例↓
n=5のとき S=4, E=4となればよい。
異なるマスにいるときにS=1, E=3であるときSに進む。

```python:YouCan_Go_Your_Own_Way.py
t = int(input())
n = []
p = []
q = []
ans = [[] for i in range(t)]
for i in range(t):
  n.append(int(input()))
  p.append(input())
  
for i in range(t):
  q.append(list(p[i]))

ans = [[] for i in range(t)]
for i in range(t):
  ms = 0 #Youの座標を(ms, me) Lydiaの座標を(os, oe)であらわす 
  me = 0
  os = 0
  oe = 0
  for j in range(n[i]+n[i]-2): #(ms, me) = (n*2-2, n*2-2)を満たすまで繰り返す
    if ms == os and me == ms:
      if q[i][j] == 'S':
        ans[i].append('E')
        me += 1
      else:
        ans[i].append('S')
        ms += 1
    else:
      if ms > me:
        ans[i].append('E')
        me += 1
      else:
        ans[i].append('S')
        ms += 1

    if q[i][j] == 'S':
      os += 1
    else:
      oe += 1
     
anss = []
for i in range(t):
  s = ''
  for j in range(len(ans[i])):
    s += ans[i][j]
  anss.append(s)
for i in range(t):
  print('Case #{0}: {1}'.format(i+1, anss[i]))
```

input:
4
2
SE
5
EESSSESE
8
SESESESESESESE
10
EEESSSESESESSESEES

output:
Case # 0 : ES
Case # 1 : SESEESES
Case # 2 : ESESESESESESES
Case # 3 : SESESESESESEESESSE

Question3,4は解答していません。問題文の解釈がおおまかなので、間違っていたらコメント欄にて報告してください。
F#でお気軽すぐるテスト




![IMG_2138.jpeg](https://qiita-image-store.s3.amazonaws.com/0/149269/f69b1b77-f49f-f83f-3281-f324f5a0c823.jpeg)

```
へんにね
合わせすぎても
たぶん
つらいだけさ
```




# Summary

おてがるテスト

## Motivation

愛用してる [perssimon.script](https://github.com/persimmon-projects/Persimmon.Script) が `travis` で動作しなくなってるため、急遽書いた

## like this

```fsharp
// かんたんチェッカー
let check  x y  =
  stdout.WriteLine " ----------------------------------- "
  if x = y then
    "OK" |> printfn "%A"
    x |> printfn "%A"
    y |> printfn "%A"
  else
    "NG" |> printfn "%A"
    x |> printfn "%A"
    y |> printfn "%A"
    raise (System.ArgumentException("===== NG =====") )

// --------------------------------------------------------
//                          使い方
// --------------------------------------------------------

// OK
check 1 1
check "foo" "foo"
check [1..10] [1..10]

// NG -> エラーを発生させる
check 1 2
```
結果

```fsharp

[Loading /Users/callmekohei/foo.fsx]
 ----------------------------------- 
"OK"
1
1
 ----------------------------------- 
"OK"
"foo"
"foo"
 ----------------------------------- 
"OK"
[1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
[1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
 ----------------------------------- 
"NG"
1
2
System.ArgumentException: ===== NG =====
  at FSI_0008.Foo.check[0] (a x, a y) [0x00108] in <062d34e0fb6f431f9681f515345f5230>:0 
  at <StartupCode$FSI_0008>.$FSI_0008_Foo$fsx.main@ () [0x00062] in <062d34e0fb6f431f9681f515345f5230>:0 
  at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&)
  at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0003b] in <547b0ab402754bd3aef2dcb174312979>:0 
Stopped due to error

*** time : 0.12656 s ***
```

まぁこれでいいのだ
WeChat用Bot開発テストアカウント設定

WeChatのBot開発のについてのメモ。
1. テストアカウント作成
まず[こちら](https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login)からテスト用のアカウントを作る。「登录」(登録)をクリックするとQRコードが表示されるので、お手持ちのWeChatのQRコードリーダーでスキャン。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/216609/d28ed0de-4321-39ed-0631-a83b69c36989.png)
2. Webhook URLの設定
アカウント作成するとこのような画面になるので、URLのところにWebhook URL、Tokenのところは任意の文字列を入れる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/216609/d0a14dc2-9b16-5399-206e-d5fee8672e92.png)
この状態で緑色の「提交」(送信)ボタンを押してもエラーになる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/216609/5c615b4c-ff5a-bc20-0b41-4d388f86736b.png)
3. Webhook URLのValidation
webhook URLに設定したファイルに以下を記述するとValidationが通ってエラーが表示されなくなる。

```webhook.php
<?php
echo $_GET['echostr'];
```

4.開発開始
あとはwebhookの方にプログラムを書いていく。
5. 参考
[Callback message API Document(英語)](https://open.wechat.com/cgi-bin/newreadtemplate?t=overseas_open/docs/oa/sending-messages/callback-msgs#sending-messages_callback-msgs)

| 中国語 | 意味| 
|:--|:--|
|微信|WeChat|
|公众|Open *日本の漢字だと"公衆"|
|平台|Platform|
|接口|Interface, API|
|测试|テスト|
|帐号|アカウント|
SQL Anywhere での UPDATE OR INSERT ってどうやるんだっけ？

# SQL Anywhere での UPDATE OR INSERT

お仕事で SQLAnywhere ばかりいじってるのですが、少々マイナーな文法が多いのでメモを残しておきます。今回はINSERTしたいんだけど、UPDATEになるのも混じっている場合、というやつです。マスタの更新をまとめてする場合に、追加もあれば更新もある。元ネタのテキストデータはあるんだけど、いちいち分けて更新するの面倒くさい（つべこべ言わずにやれよ）という場合に使えるネタですね。

## Firebird では　UPDATE OR INSERT

Firebirdでは、バージョン2.1から UPDATE OR INSERT文が使用できます。MERGE文も使えるので、元ネタがテーブルにあるならMERGE文、そうでないならUPDATE OR INSERT文を使います。MATCHING句でカラムを指定しなければ主キーで判定されます。シンプルかつ必要十分な構文ですね。

```SQL:
UPDATE OR INSERT INTO
   {tablename | viewname} [(<columns>)]
   VALUES (<values>)
   [MATCHING (<columns>)]
   [RETURNING <values> [INTO <variables>]]

<columns>      ::=  colname  [, colname  ...]
<values>       ::=  value    [, value    ...]
<variables>    ::=  :varname [, :varname ...]
```

```SQL
MERGE INTO {tablename | viewname} [[AS] alias]
   USING {tablename | viewname | (select_stmt)} [[AS] alias]
   ON condition
   WHEN MATCHED THEN UPDATE SET colname = value [, colname = value ...]
   WHEN NOT MATCHED THEN INSERT [(<columns>)] VALUES (<values>)

<columns>  ::=  colname [, colname ...]
<values>   ::=  value   [, value   ...]

Note: It is allowed to provide only one of the WHEN clauses
```

## SQLAnywhere では　INSERT ... ON EXISTING UPDATE VALUES ...

SQLAnywhere で同じことをするにはどうするんだろうということで調べると、MySQLに似た文法で出来るようです。VALUES句の前に ON EXISTING UPDATE を挿入します。

```SQL:
INSERT [ INTO ] [ owner.]table-name [ ( column-name, ... ) ]
[ ON EXISTING { 
   ERROR 
   | SKIP 
   | UPDATE [ DEFAULTS { ON | OFF } ] 
   } ]
{ DEFAULT VALUES 
   | VALUES row-value-constructor }
[ OPTION( query-hint [, ... ] ) ]
```

DEFAULTS句をONにすると、UPDATE時に指定されていないカラムをデフォルト値で初期化してくれるとか嬉しいオプションもあります。更新しないでSKIPしろよとかERRORにしろよなども指定できる万能性は素晴らしいですね。

## MySQL では ON DUPULICATE KEY UPDATE

MySQLの場合は、SQLAnywhereと似てますね。INSERT ... VALUES ... ON DUPUILCATE KEY UPDATE と文の後ろにつくところが違います。また、UPDATEだった場合の更新値を後ろに全部書かないといけないのが面倒ですね。　

```SQL:
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    [PARTITION (partition_name,...)] 
    [(col_name,...)]
    {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
    [ ON DUPLICATE KEY UPDATE
      col_name=expr
        [, col_name=expr] ... ]
```

## まとめ

やっぱりFirebirdはシンプルでいいですね。なんでも出来そうなSQLAnywhereも素晴らしい。MySQLが面倒なのが意外でした。
XFSファイルシステムでrmしたファイルについて

#経緯
SSDのディスクを3台使用し、LVMを組んでいた。その内、1台をノートパソコンで使うために、LVMから削除を行う。
しかし、XFSでフォーマットしていたため、resizeが出来ないwww

#LVMを構築しなおす
xfs_dumpコマンドを使用しダンプを取る。その後、LVMを構築しなおしxfsrestoreコマンドでリストアを行う。
これでリストアしたと勝手に思い込み、xfs_dumpで作成したファイルをrmコマンドで削除。

...リストアされていなかったwww

色々と調べたけど、XFSフォーマットはファイルの復元が出来ないようだ。
これからは、ちゃんとxfsrestoreで復元されているのを確認した後に、rmコマンドを使用しよう。

自宅サーバの仮想イメージが入ったディレクトリだから、まだ良かったけど、仕事でやったら始末書もんだ。
また一つ、いい経験になった。
オフラインリアルタイムどう書く E32 の実装例( python )

問題の名前 : きれいな四角
問題 : http://nabetani.sakura.ne.jp/hena/orde32rects/
実装リンク集 : https://qiita.com/Nabetani/items/bd16f3fa1d9e4d0d60ae

で。

会場で提示だけしたアイディアを Python3 で実装した。

こんな感じ。

```python:Python3
import cv2
import sys
import json
import numpy as np
from copy import deepcopy

WH=36

def newRect(s):
  s36 = "0123456789abcdefghijklmnopqrstuvwxyz"
  x, y, r, b = [s36.index(x) for x in s ]
  return (x+1, y+1, r+1, b+1)

def findRect(field0, x, y):
  field = deepcopy(field0)
  h, w = field.shape[:2]
  mask0 = np.zeros((h + 2, w + 2, 1), dtype=np.uint8)
  _, _, mask, box = cv2.floodFill(
      field, mask0, seedPoint=(x, y), newVal=1)
  filled = mask[1:(h+1),1:(w+1)]
  if box[2] * box[3] == cv2.countNonZero(filled):
    return box, filled
  return None, filled

def buildField(src):
  field = np.zeros((WH+1, WH+1, 3), np.uint8)
  col=1
  for r in [ newRect(s) for s in src.split("/") ]:
    field[r[0]:r[2], r[1]:r[3]]+=np.array([col&255,col//256,0], np.uint8)
    col <<= 1
  return field

def collectSizes(field):
  checked = np.zeros((WH+1, WH+1, 1), np.uint8)
  sizes=[]
  for y in range(1,WH):
    for x in range(1,WH):
      if 0 != checked[y,x][0]:
        continue
      r, ch = findRect( field, x, y )
      checked += ch
      if r:
        sizes.append(r[2]*r[3])
  return sizes

def solve(src):
  field = buildField(src)
  sizes = collectSizes(field)
  return ",".join([str(s) for s in sorted(sizes)])

with open(sys.argv[1], "r") as file:
  data = json.load(file)
  for case in data["test_data"]:
    actual = solve( case["src"] )
    ok = actual == case["expected"]
    print( ("ok" if ok else "**NG**"), case["src"], actual, case["expected"] )
```

入力は JSON で、コマンドライン引数で与える。

戦略としては。

1. 地図を作る
2. 地図を塗る
3. 塗った範囲が四角ければ、それはきれいな四角なので、サイズを計算してリストに追加する
4. 出来上がったリストを整形して返せば OK

というもの。

地図はセルの集まりになっている。
セルの色は、そのセルを含んでいる矩形のリストを意味している。
具体的には、n番目の矩形の内側ならn番目のビットが立っている2進数……にしたかったんだけど、OpenCV の制約で 8bit-color にしなければならず、そこはちょっとごちゃごちゃしている。

地図ができたら、`cv2::floodFill` で地図を塗る。
都合のいいことに `cv2::floodFill` は

* 塗った範囲の外接矩形
* 塗った範囲を 1 とする白黒画像

を返してくれる。
前者の面積と後者の非ゼロの点の数が一致していれば四角く塗ったことになるので、それがきれいな四角である。

一度塗られたことがある領域は調べなくて良いので、それを `checked` に覚えてもらって適宜スキップする。

OpenCV がなくても、floodFill さえ実装すれば同じ戦略で解くことができる。

今回は OpenCV を使っている関係で、画素値に 24bit しか使えない。矩形の数が 24 を超えたらなんか考える必要があるけど、今回は 9個が最大なのでこれで大丈夫。
VirtualboxとVagrantを使ってRuby on Railsの開発環境を整える

#目標
・仮想環境の理解と開発環境構築
・win・macどちらでも構築ができる
・現場に出た時に一番に行う＆躓くであろう環境構築の対策

#仮想環境とは
わかりやすくすると、PCの中にもう一つPCが入っている状態です。
普段使用しているPCの設定に影響を与えることなく別のPCを用意できるため開発環境でいろいろと試すことができます。別のPCなので、仮想環境を操作するためには「ssh(遠隔操作)」という通信接続手段が必要になります。

#VirtuakboxとVagrant
Virtualboxで仮想環境を作り、Vagrantで操作していきます。

野球に例えるとVirtualboxは野球場、Vagrantは野球場を作るために指示を出す人(マネージャー)のような感じです。

#仮想環境構築
VagrantはVirtualbox上で動いているのでまずは、「Virtualbox」をインストールする。
https://www.virtualbox.org/wiki/Downloads
https://www.oracle.com/virtualization/virtualbox/

ダウンロードしたファイルを実行して指示通りに進めるとインストール完了になります。

次にVagrantをインストールします。
https://www.vagrantup.com/downloads.html

※winの場合はここで一度PCを再起動

MacのOSがHidh SierraまたはMojaveの場合、以下の設定が必要です。
①　環境変数
②　セキュリティとプライバシー
③　システム・ソフトウェアの読み込み許可
④　変更カギをクリック

winの場合、次に仮想環境に接続するために「SSHクライアント」というアプリケーションが必要になります。
SSHクライアントにはいろいろありますが、今回はMobaXtermを使います。
https://mobaxterm.mobatek.net/

インストールが完了したら、Vagrantを立ち上げる準備を行います。
まず、最初にvagrant-vbguestというプラグインをインストールします。ターミナルまたはコマンドプロンプトで下記のコードを入力

```
$ vagrant plugin install vagrant-vbguest
```

次にVagrantの初期設定をするためにVagrantfileを利用します。VagrantfileはVagrantの初期設定が書かれているファイルです。

Virtualboxにboxファイルを登録する
http://www.vagrantbox.es/
https://app.vagrantup.com/boxes/search

自分はubuntu-trusty-32を選択しました。

```$ vagrant init box名```
でVagrantfileを生成
Vagrantfileをdesktop/work/vagrantに配置しました。
```$ cd vagrant```

Mac
ユーザー名:vagrant ユーザー名$

Win
C:\Users\ユーザー名\Desktop\work\vagrant
となっていれば大丈夫です。

Vagrantを起動
```$ vagrant up```
初回起動時はとても時間がかかります。（スペックにもよるが、1～3時間）
コンソール上で汽車のマークが出ていれば成功です！

Macではすべてターミナル、
WinではコマンドプロンプトとSSHクライアントを使ってきました。
```$ cd ~/vagrant
   $ cd vagrant up (vagrant起動)
   $ cd vagrant halt (vagrant終了)
```

これで開発環境の立ち上げまで行うことができました。

#SSHクライアント
起動時にログインを求められます。以下を入力。
ホスト名 :127.0.0.1
port :2222

次にログインするためのユーザー名を入力し、秘密鍵をクリックします。
ユーザー名 :vagrant

vagrant/machines/default/virtualboxに秘密鍵(private_key)が表示され、ファイルの種類を「all」にした状態でクリックします。
これで秘密鍵を設定し、ログインすることができるようになりました。

Macの場合
```$ vagrant ssh```

```vagrant@vagrant-ubuntu-trusty ~$```
となれば接続完了です！

現在の状態は、仮想環境にある自分のPCとは別のPCなので、ファイルやデータを共有で利用できる作業場所に移動する必要があります。
共有フォルダとは仮想環境と自分のPCの双方から見ることができるものです。

自分のPCにおける共有フォルダの場所はVagrantfileが置いてある場所です。

仮想環境における共有フォルダの場所は/vagrantです。

仮想環境での共有フォルダへの移動
```$ cd /vagrant```
cdの後に半角スペースを忘れずに！

以上で終了になります。
早速、Railsアプリを生成してみます。
```$ rails new アプリケーション名```
これでひな形が作成されます。

仮想環境からログアウト
```$ exit```

仮想環境のシャットダウン
```$ vagrant halt```

#参考
・https://qiita.com/ozawan/items/160728f7c6b10c73b97e
・https://qiita.com/TakashiOshikawa/items/d2fb48d59e9e316af9a2
・https://qiita.com/kanpou0108/items/315b53ac31e2811c2ba1
iMovie でシネマスコープ (2.35:1) 動画を簡単に作成する方法

iMovie で映画のような横長のシネマスコープ (2.35:1) 動画を簡単に作成する方法です。上下に黒帯を追加してレターボックス状態にします。

## 1. 以下の画像を右クリックして「画像を保存」

![1980x1080.png](https://qiita-image-store.s3.amazonaws.com/0/155587/33ddbcae-9a49-059c-5f19-01c25acc8469.png)

## 2. iMovie の下半分のタイムラインで、すでにある動画の上に画像をドラッグ&ドロップ

※ すでにタイムライン上にオーバーレイ（動画を2つ重ねている状態）がある場合は、1回書き出してから、その動画を新規プロジェクトに読み込んで手順に従ってください。

![imovie.gif](https://qiita-image-store.s3.amazonaws.com/0/155587/a81a0711-00a7-87c8-8c8d-e3d10ee8850c.gif)

## 3. 動画の長さに合わせて黒帯の画像の長さを調節

## 4. 右上の「クロップ」ボタンを押して「フィット」を選択

デフォルトでは Ken Burns が選択されており、画像が動いてしまうため、フィットを選択します。

<img width="630" alt="SS_2019-04-07_at_17_13_34.png" src="https://qiita-image-store.s3.amazonaws.com/0/155587/529cf693-b001-2e71-5524-4de3e5d165f8.png">

<img width="634" alt="SS_2019-04-07_at_17_13_44.png" src="https://qiita-image-store.s3.amazonaws.com/0/155587/8d17a9e2-2595-5526-9d6c-e9e8f00d7128.png">

完了です！

動画の上下に黒帯が表示されるのが嫌な方は、「Mac 動画 トリミング」などでググってみてください。画面録画 (Shift+Command+5) でもできないことはないと思います。ターミナルが使えるならおすすめは ffmpeg です。


# 参考
https://whoismatt.com/cinemascopetutorial/
Laravel入門 -Laradock導入-

# はじめに

## Laradockについて

PHPを開発するのに必要なアプリが全部セットになったDocker環境。
今回はMySQL + PHP-FPM + NGINX + Laravelでいきますが、データベースにPostgreSQLを選んだり、WebサーバにApacheを選んだりかなり自由度は高いです。

## ディレクトリ構成

```
.
├── laradock-dakoku ←Laradockのコード (docker-composeコマンドはここで実行)
└── src ←Laravelのコード (コンテナに入らずエディタで編集できる)
```

# コンテナを動かすための初期設定

```bash
PROJECT=(プロジェクト名)
mkdir $PROJECT
cd !$
# イメージを他プロジェクトと共用しないよう名前を変える
git clone https://github.com/Laradock/laradock.git laradock-$PROJECT
cd laradock-$PROJECT
cp env-example .env
```

```:.env
DB_HOST=mysql
APP_CODE_PATH_HOST=../src
# MySQL8の認証方式caching_sha2_passwordにPHPのMySQLライブラリが対応していないため
MYSQL_VERSION=5.7.25
```

# コンテナを動かす

```bash
docker-compose up -d nginx mysql workspace
```

# Laravelをインストール

```bash
docker-compose exec workspace bash
# バージョンは好きなものを指定する。ここでは5.2系
composer create-project laravel/laravel . "5.2.*"
```

# DB migrate実行

```:.env
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=default
DB_USERNAME=default
DB_PASSWORD=secret
```

```bash
php artisan migrate
```

# NGINX設定

```bash
cp nginx/sites/laravel.conf.example nginx/sites/laravel.conf
```

```:nginx/sites/laravel.conf
root /var/www/src/public;
```

```bash
docker-compose stop nginx
docker-compose up -d nginx
```

# Webブラウザでアクセス

https://localhost/

# Q&A

Q1. artisanコマンドはどうやって実行すればいい？
A1. laradockのディレクトリで`docker-compose exec workspace bash`

Q2. NGINXのログはどこ？
A2. laradock配下の`logs/nginx`

Q3. MySQLのデータはどこ？
A3. laradockの.envファイル、DATA_PATH_HOSTに定義されている場所 (デフォルトは~/.laradock/data)。
交通流シミュレータ SUMO をWindowsに導入する

#概要
SUMO（Simulation of Urban MObility）はドイツ航空宇宙センター（DLR）が開発しているオープンソースの交通流シミュレータで，高度交通システム（ITS）の研究でもよく使われています．道路上に信号等を設置し，一定の法規に従った交通流を再現できます．
本稿では，交通流シミュレータSUMOを初めて触る人に向けて，Windowsにインストールする方法を説明します．

#環境
- Windows10 Home/Pro 64bit
- SUMO version 1.1.0

#インストール
1. [公式ページ](https://www.dlr.de/ts/en/desktopdefault.aspx/tabid-9883/16931_read-41000/)のDownloads部分の "SUMO x.x.x for Windows" を選択し，インストーラをダウンロードする
2. インストーラを実行する

※このとき，Set SUMO_HOME and adapt PATH... にチェックを入れ，PATHを通すのに注意する．
<img width="386" alt="sumo_install.png" src="https://qiita-image-store.s3.amazonaws.com/0/366359/d5aacb82-f5a6-2975-c02d-05fdb00bf42e.png">

インストールが終了したら，コマンドプロンプトを立ち上げ，インストールが成功しPATHが通っていることを確認する．

```
$sumo
バージョンが表示されればOK

$netconvert
バージョンが表示されればOK
```

また，GUI版のSUMOは，下記コマンドもしくは "インストールフォルダ\eclipse\Sumo\bin\" の中にある sumo-gui.exeを実行すれば起動します．

```
$sumo-gui
```

#デモシミュレーションを実行してみる
"インストールフォルダ\eclipse\Sumo\doc\tutorial\quickstart\data" の中にある quickstart.sumocfgをクリックし，GUI版SUMOを起動します．

ツールバーでよく使用するボタンは以下の2つ
- Delay (ms): シミュレーションの再生速度．1000にすると1倍速．今回は50msくらいにしときます．
- 再生ボタン: 右からシミュレーション開始・停止・ステップ実行のボタンになります．

![sumo_toolbar.png](https://qiita-image-store.s3.amazonaws.com/0/366359/9b8133c5-e6e0-df9e-b794-7654e564bbf1.png)

実行ボタンを押すと，黄色い矢印で表された車両が仮想の道路上を走行するのが観察できると思います．

![sumo_ex.png](https://qiita-image-store.s3.amazonaws.com/0/366359/ad3ba32d-1a9a-604c-55e2-abe753f3e44e.png)


#関連記事
- [交通流シミュレータ SUMO でグリッド地図を生成し，GUIで読み込む](https://qiita.com/jagimo/items/fa598bd4902456e8c7f5)
: 交通流シミュレータでグリッドなどモデルにもとづいた地図の生成方法を解説
- [交通流シミュレータ SUMO で日本国内のOpenStreetMap地図を読み込む際の設定と注意点](https://qiita.com/jagimo/items/5581ac3cc02356911c85)
: 交通流シミュレータでOpenStreetMapの実際の地図を読み込んで利用する方法と注意点を解説
- [東名高速 大和トンネルの渋滞を再現する【交通流シミュレータSUMO】](https://qiita.com/jagimo/items/a09f8e08de6e947cca3f)
: 【SUMO応用編】交通流シミュレータで非ランダムなデマンド（トリップ）を発生させ，渋滞のシミュレーションを行う方法を紹介
ABC - 045- A&B&C

#AtCoder ABC 045 B&C
[AtCoder - 045](https://atcoder.jp/contests/abc045)

#A問題

```java
	private void solveA() {
		int numA = nextInt();
		int numB = nextInt();
		int numH = nextInt();

		out.println((numA + numB) * numH / 2);
	}
```

#B問題

 - ループの中で、A,B,Cそれぞれの枚数が今何枚かをカウントしておく

```java
	private void solveB() {
		char[] a = next().toCharArray();
		char[] b = next().toCharArray();
		char[] c = next().toCharArray();

		int cntA = 0;
		int cntB = 0;
		int cntC = 0;
		char num = 'a';
		while (true) {

			switch (num) {
			case 'a':
				if (cntA < a.length) {
					num = a[cntA];
					cntA++;
				} else {
					out.println("A");
					return;
				}
				break;
			case 'b':
				if (cntB < b.length) {
					num = b[cntB];
					cntB++;
				} else {
					out.println("B");
					return;
				}
				break;
			case 'c':
				if (cntC < c.length) {
					num = c[cntC];
					cntC++;
				} else {
					out.println("C");
					return;
				}
				break;
			}
		}

	}
```

#C問題

 - 以下のような感じで10個の数値の間に　$+$　を入れていく

```
数列:
1234567891
-> 1 + 23456789
-> 1 + 2 + 3456789
-> 1 + 2 + 3 + 456789
-> 1 + 2 + 3 + 4 + 56789
  ・
  ・
-> 1234 + 56789
  ・
  ・
-> 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9
```

 - $+$ が数式の間に挿入されるパターンは $2^n$ になる
    - $n$ は最小0：最大9

 - このパターンの作成は、マスクを作る時のやり方を使うと楽
    - 000000000 -> 000000001 -> 000000010 -> 000000011 -> ・・・ -> 111111111
    - 0は何もしない
    - 1は $+$ として扱う

####マスクの作成部分だけ抜き出し

 - 0-maxまで、2進数に変換して配列に入れる

```java
		for (int i = 0; i < max; i++) {
			int[] plusMinus = new int[maskMax - 1];
			int wkBit = i;
			for (int j = 0; j < maskMax - 1; j++) {
				plusMinus[j] = wkBit % 2;
				wkBit /= 2;
			}
		}
```

####C問題：解答本体

```java
	private long chkC(String[] number) {
		long res = 0;
		/*
		 * +-は最大9個
		 * 000000000から、111111111までの配列を作成。2の剰余を入れていけば2進数に変換できる。
		 * 最大は 2^9
		 * 最小は 2^0
		 *
		 */
		int maskMax = number.length - 1;

		/*
		 * マスクの最大値を設定
		 * ex:1024 -> 1111111111
		 */
		int max = (int) Math.pow(2, maskMax);
		for (int i = 0; i < max; i++) {
			/*
			 * bitを生成
			 * 1は+/0は何もしない
			 * 例：数値が123の場合
			 * 00
			 * 01
			 * 10
			 * 11
			 * の4パターン生成される
			 * 00の場合は数値をそのまま利用
			 */
			int[] plusMinus = new int[maskMax];
			int wkBit = i;
			for (int j = 0; j < maskMax; j++) {
				plusMinus[j] = wkBit % 2;
				wkBit /= 2;
			}
			StringBuilder builder = new StringBuilder();
			/*
			 * 数値を文字列に入れた後、bitが1なら+(扱いの@)を足す
			 * +を足さないのはあとの処理で正規表現扱いになるのを避けるため
			 */
			for (int j = 0; j < number.length; j++) {
				builder.append(number[j]);
				if (j < plusMinus.length && plusMinus[j] == 1) {
					builder.append("@");
				}
			}
			/*
			 * @で区切って数値に変換
			 */
			String[] numS = builder.toString().split("@");
			//足す
			for (String long1 : numS) {
				res += Long.parseLong(long1);
			}
		}

		return res;
	}
```
C流、C++流の入出力メモ(printf, sprintf, fprintf)

## はじめに 
 C言語、C++言語での入出力方法（標準・ファイル）について忘れないためにメモを残す。
 サンプルコードをいくつか載せますが、決してスマートなコードではありません。あくまで比較しやすいように書いています。それと、メモなので説明は少ないです。

## 環境
- Cygwin (ver. 3.05)
- gcc (ver. 7.4.0)

## printf VS cout

```c++:printf.cpp
#include <iostream>

using namespace std;

int main(){
    int n(10);

    // C
    printf("C\n");
    printf("%d\n", n);

    //C++
    cout << "C++" << endl;
    cout << n << endl;

    return 0;

}
```


出力結果

```console
C
10
C++
10
```

## sprintf VS stringstream

　`ostringstream`じゃなくて、`stringstream`でもいいけど、
今回は、`istringstream`の機能は使わないため、`ostringstream`を採用。

```c++:sprintf.cpp
#include <iostream>
#include <sstream> // for ostringstream

using namespace std;

int main(){
    int n(10);

    // C
    char str[10];
    printf("C\n");
    sprintf(str, "str = %d", n);
    printf("%s\n", str);

    //C++
    ostringstream oss;
    oss << "str = " << n;
    cout << "C++" << endl;
    cout << oss.str() << endl;

    return 0;

}
```

出力結果

```console

C
str = 10
C++
str = 10
```


## fscanf & fprintf VS ifstream & ofstream
　入力ファイルとして以下を用意。3行目には、行頭に2スペース挿入。

``` data:sample.dat
aaa bbb
123 456 679
  12 22
```

続いて、CとC++の比較用コード

```c++:fprintf.cpp
#include <iostream>
#include <fstream>

using namespace std;

int main(){

    // C
    char str1[10], str2[10];
    FILE *ifile, *ofile;
    int int1, int2, int3, int4, int5;
    ifile = fopen("sample.dat", "r");
    ofile = fopen("sample.dat.out.C", "w");
    fscanf(ifile, "%s %s", str1, str2);
    fscanf(ifile, "%d %d %d", &int1, &int2, &int3);
    fscanf(ifile, "%d %d", &int4, &int5);

    fprintf(ofile, "1: %s %s\n", str1, str2);
    fprintf(ofile, "2: %d %d %d\n", int1, int2, int3);
    fprintf(ofile, "3: %d %d\n", int4, int5);

    fclose(ifile);
    fclose(ofile);

    //C++
    ifstream ifs;
    ofstream ofs;

    char st1[10], st2[10];
    int in1, in2, in3, in4, in5;

    ifs.open("sample.dat");
    ofs.open("sample.dat.out.Cplus");

    ifs >> st1 >> st2;
    ifs >> in1 >> in2 >> in3;
    ifs >> in4 >> in5;

    ofs << "1: " << st1 << " " << st2 << endl;
    ofs << "2: " << in1 << " " << in2 << " " << in3 << endl;
    ofs << "3: " << in4 << " " << in5 << endl;

    ifs.close();
    ofs.close();

    return 0;

}
```

出力結果

```text:sample.dat.out.[C|Cplus]
1: aaa bbb
2: 123 456 679
3: 12 22
```

空白はうまいこと扱ってくれる。C++の方では、charではなくstringを使った方が安全だけど、対照実験のためcharを使用。

## 所感
　結構C++のコードでも、while + getline + sscanfで変数への代入をやっているものを見かけるけど、個人的にはifstreamから直接代入する方が楽かなーと思いました。
　私は行によってコラム数が変わるようなデータを扱うこともあるので、後者の方法を良く使うことになりそう。
逆にループ回数の情報を、ファイルのヘッダーや外部の情報から得ることができない場合は、前者を使うことになるのかな。

## その他
- 何か間違いがあれば、ご指摘いただけると幸いです。
LinuxMintに.NET Core SDK 2.2とVisual Studio Codeをインストールする

# はじめに
初投稿です。
はじめまして、本名じゃないときは大体はるかぜと名乗ってます。
今までずっとWindows、VisualStudio（C#、WindowsFormsがメイン）、SqlServerとMicrosoftべったり業務アプリ開発の仕事をしてきましたが.NETCoreがだいぶ使えるようになってきたみたいなのでこれを機に仕事とは関係なくLinuxとVisualStudioCodeを触ってみたいと思い、空き時間にやったことを日記のように書いていきたいと思っています。
とりえあえずの目標として.NETCoreでWebAPIを作れるようにするところまでやる予定です。
参考にしてくださる方がいると嬉しいですが、時間があるときにゆっくりやっていくので遅いですがご了承ください。
LinuxもWeb系もVSCodeもほぼ初心者なのでとりあえず動く方法を手探りでやってます。
（これが本当に正しい方法なのかわかりませんが動けばOKというレベルでやってます）

#### 環境
Linux Mint 19.1（ubuntu系なら違いはないはず）
.NET Core 2.2
Visual Studio Code 1.33

## .NET Core SDK 2.2のインストール
ubuntu18.04ベースなので[公式](https://dotnet.microsoft.com/download/linux-package-manager/ubuntu18-04/sdk-current)のubuntu18.04へのインストール方法に従って以下のコマンドを実行

```shell-session
~$ wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb
~$ sudo dpkg -i packages-microsoft-prod.deb
~$ sudo add-apt-repository universe
~$ sudo apt-get install apt-transport-https
~$ sudo apt-get update
~$ sudo apt-get install dotnet-sdk-2.2
```

特に問題なく終わったのでバージョンを確認

```shell-session
~$ dotnet --list-sdks
2.2.202 [/usr/share/dotnet/sdk]
```

バージョン2.2.202がインストールされたようです。

## VSCodeのインストール

[公式](https://code.visualstudio.com/)でダウンロードしてもいいんですがリポジトリを追加してインストールしました。

```shell-session
~$ sudo add-apt-repository "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main"
~$ sudo apt-get update
~$ sudo apt-get install code
```

これも特に問題なく終了。
![Visual Studio Code_001.png](https://qiita-image-store.s3.amazonaws.com/0/277868/d92847d4-46b2-24e9-2fdc-4ec8862576a4.png)
バージョンも最新のものになっているようです。

## VSCodeに必要な拡張機能を追加
とりあえず以下のものを入れました。
（後々増えたらここに追記します）

 - Japanese Language Pack for Visual Studio Code（日本語化）
 - C#
 - NuGet Package Manager（Nugetパッケージの検索、追加）

## Hello World
これでC#の開発をする準備はできているはずなのでHello Worldを実行してみます。

1. 適当な場所にフォルダを作成してVSCodeで開く（今回はhelloworldというフォルダを作りました）
2. `Ctrl+Shift+^`でターミナルを開く
3. `dotnet new console`でコンソールアプリケーションのプロジェクトを作成

これで`dotnet run`で実行できるのは確認しましたがなにやらOmniSharpがエラーを吐いているようなので確認してみます。

```console
Microsoft.Build.Exceptions.InvalidProjectFileException:
The SDK 'Microsoft.NET.Sdk' specified could not be found.
/home/(ユーザー名)/vscode/helloworld/helloworld.csproj
```

ここで2時間くらいハマりましたがどうやら環境変数のMSBuildSDKsPathにインストールした.NET CoreのバージョンのSdksフォルダを設定してやればいいようです。

```config:.bashrc
export MSBuildSDKsPath="/usr/share/dotnet/sdk/2.2.202/Sdks/"
```

.bashrcに上記の記述を追加して`source .bashrc`で再読込してやったら無事エラーはなくなって「デバッグの開始」での実行もできるようになりました。
draw.io で技術資料の図を作成し、使い回すまでの流れ

毎回忘れるのでメモがてら :raised_hand:

# 図を新規作成する流れ
### 新規作成
<img width="406" alt="1.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/110482/edefca4e-1606-eb31-6426-aee347a1284d.jpeg">

### テンプレートを選択する

<img width="683" alt="2.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/110482/bff26dd9-de67-8ec8-75eb-1e3caf13313b.jpeg">

### 必要であれば他のshapeを追加する
<img width="815" alt="3.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/110482/45592c47-2eff-c4e3-7420-73cd215a30f0.jpeg">

<img width="701" alt="4.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/110482/5b9ceca0-ba5e-7517-2a0a-348715fc6da1.jpeg">

### アウトライン、レイヤーパネルを追加する
パネルアイコンからOutline,Layers選択する
<img width="676" alt="5.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/110482/8b7a4d85-55c6-3095-350c-a98d5cb60ffa.jpeg">

### スクラッチパッドを追加する
メニュー [View] -> ScrachPad を 選択する
<img width="564" alt="6.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/110482/f7d44772-8f7e-3345-750d-c2d15dfe93e8.jpeg">

### スクラッチパッドにアイコンや画像などをimportする
<img width="509" alt="7.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/110482/cca2e5ef-a113-e6a4-5cf4-8f71f7d0bd39.jpeg">
<img width="703" alt="9.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/110482/412dac9c-a19f-1c89-e3d5-4ad5ba1622bf.jpeg">

技術スタックのアイコンや画像の配布先URLをまとめておくと良いでしょう
https://qiita.com/tkit/items/932316c5f5f7b162b61e


### 図を作り込む
がんばりましょう

### drawio ファイルとして保存する
メニュー [File] -> save as ...で保存先を選択する

### スクラッチパッドを永続化する
ライブラリとして書き出さないと、cokkieとともに消えるらしいです。

https://desk.draw.io/support/solutions/articles/16000042367
> Note that the scratchpad is stored in the local storage of the browser, which means it's contents are deleted if cookies are cleared. The scratchpad is automatically saved between each change.

<img width="703" alt="10.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/110482/c06cf6a5-a8f8-acd1-024f-83d12872caa0.jpeg">

# 以前作成した図を読み込む

### draw.io を開く際に Open Exi....を押下する
<img width="414" alt="12.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/110482/8a149c06-40db-1406-aa52-61d4ecfa06a4.jpeg">

### スクラッチパッドを読み込む
メニュー [File] -> Open Library from でスクラッチパッドファイルを選択する
<img width="524" alt="13.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/110482/43d2c144-d930-b530-5932-dfbb4e8f3811.jpeg">

以上が新規作成から、図を使い回すまでの流れです。
Docker on CentOS7で特定コンテナの容量制限を柔軟に行ってみた

Dockerで容量制限を柔軟に変更することができます。

ベースサイズよりも大きい容量に設定することができます。
ですので、例えば0.1Gをbase sizeとしてそれを拡大すれば、事実上自由に大きさを調整できるというわけです。



![image.png](https://qiita-image-store.s3.amazonaws.com/0/245977/4e50e67c-2ce8-4b69-a874-6cc7b0217618.png)


##Dockerインストール
https://qiita.com/inakadegaebal/items/be9fecce813cebec5986

##Storage Driverが overlayfs + xfs であるか確認
```
[root@localhost ~]# docker info
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 0
Server Version: 18.09.4
Storage Driver: overlay2
 Backing Filesystem: xfs
 Supports d_type: true
(略)

```

##サイズを指定してみて実行（成功）
```
[root@localhost ~]# docker run --storage-opt size=50g -t -i ubuntu /bin/bash
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
898c46f3b1a1: Pull complete 
63366dfa0a50: Pull complete 
041d4cd74a92: Pull complete 
6e1bee0f8701: Pull complete 
Digest: sha256:017eef0b616011647b269b5c65826e2e2ebddbe5d1f8c1e56b3599fb14fabec8
Status: Downloaded newer image for ubuntu:latest
root@d4b78fb73127:/# df -h
Filesystem      Size  Used Avail Use% Mounted on
overlay          47G  1.5G   46G   4% /
tmpfs            64M     0   64M   0% /dev
tmpfs           910M     0  910M   0% /sys/fs/cgroup
/dev/sda3        47G  1.5G   46G   4% /etc/hosts
shm              64M     0   64M   0% /dev/shm
tmpfs           910M     0  910M   0% /proc/asound
tmpfs           910M     0  910M   0% /proc/acpi
tmpfs           910M     0  910M   0% /proc/scsi
tmpfs           910M     0  910M   0% /sys/firmware
root@d4b78fb73127:/# 

```

##場合によっては
```
sudo vi /etc/default/grub
```

GRUB_CMDLINE_LINUX= に「 rootflags=uquota,gquota,pquota　」を追記してください。

```bash:BIOSの場合
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
sudo reboot
```

で適用できた

#See Also
https://qiita.com/haniokasai/items/2b7a1889e4930b7682c9
補数表現とは

参考サイト:
http://proengineer.internous.co.jp/content/columnfeature/6254
http://ur0.biz/SDfX
http://kccn.konan-u.ac.jp/information/cs/cyber03/cy3_hub.htm
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1363723923

#「補数(complement)」とは
ある基数法において、<font color="red">ある自然数 a に足したとき桁が1つ上がる（桁が1つ増える）数のうち最も小さい数</font>をいう。

#基数の補数
基数と補数を足した場合に<font color="red">桁上がりが発生する</font>数のうち<font color="red">最小</font>の数のこと。
##実際に10進数で、基数の補数を求めてみる
>・「６」の補数は「４」　　　　　（１０¹＝１０）
・「１７１」の補数は「８２９」　（１０³＝１０００）


#減基数の補数
基数と補数を足した場合に<font color="red">桁上がりが発生しない</font>数のうち<font color="red">最大</font>の数のこと。
##実際に10進数で、減基数の補数を求めてみる
>・「６」の補数は「３」　　　　　（１０¹－１＝９）
・「１７１」の補数は「８２８」　（１０³－１＝９９９）

#補数表現を使うメリット
補数を使うことによってもたらされる最も大きなメリットは、<font color ="red">マイナス記号を使わずに負の数を表現することができる</font>という点です。

例えば、次のような計算をしたいとします。
>1195 <font color="red">-</font> <font color="blue">171</font> = 1024

ここで、<font color="blue">171</font>を引く代わりに、<font color="blue">171</font>を基数とした時の補数<font color="green">9829</font>を足してみます。
>1195 <font color="red">+</font> <font color="green">9829</font> = 11024

この結果から最上位の桁にある「１」を取り除くことで、答えである「１０２４」を得ることができました。

##マイナス記号を使わずに負の数を表現することができることのメリット
下の表をご覧ください。
![hosu.png](https://qiita-image-store.s3.amazonaws.com/0/368574/c27c88b6-9c83-bd20-b408-6932c1782c1a.png)
この通り、２の補数を使用した場合、絶対値や１の補数を使用した場合よりも、<font color="red">負数を１種類多く表現できる</font>ことが分かります。
つまり、<font color="red">使用するビット数を節約することができる</font>のです。

また、四則演算を電子回路がやってくるのが当たり前なら良いですが、そうでない場合もあると思います。
そんな時、補数を利用すれば加算回路さえあれば<font color="red">減算回路を作成しなくて済む</font>ため、経済的メリットが得られます。
CentOS7でSelenium＋Pythonを動かすまで

Webアプリケーションテストツール **Selenium** 実行環境作成までの手順をまとめる。

# 前提環境
```shell_session
# cat /etc/redhat-release 
CentOS Linux release 7.4.1708 (Core)
```

# ブラウザのインストール
## Chromeの場合
- Google Chrome用のyumリポジトリを作成

```ini:/etc/yum.repos.d/google.chrome.repo
[google-chrome]
name=google-chrome
baseurl=http://dl.google.com/linux/chrome/rpm/stable/$basearch
enabled=1
gpgcheck=1
gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub
```

- アップデート

```
yum update
```

- 本体と日本語フォントをインストール

```shell_session
# yum -y install google-chrome-stable

# google-chrome --version
Google Chrome 73.0.3683.86

# yum -y install ipa-gothic-fonts ipa-mincho-fonts ipa-pgothic-fonts ipa-pmincho-fonts
```

- GUIがないヘッドレスモードでHTMLを取得し、動作確認

```
google-chrome --headless --no-sandbox --dump-dom https://www.google.com/
```

## Firefoxの場合

```
yum -y install firefox
```

# Selenium導入

`yum list installed | grep python` や `pip -V` で、Pythonパッケージ管理システム **pip** があるか確認する。
無ければ導入。

```
yum -y install python-pip
pip install --upgrade pip
```

pipから**Selenium**導入

```
pip install selenium
```

# Webドライバ
## ChromeDriverの場合

```
# pip install chromedriver-binary
# pip show chromedriver-binary
Version: 74.0.3729.6.0

# chromedriver-path
/usr/lib/python2.7/site-packages/chromedriver_binary
```

>```
session not created: This version of ChromeDriver only supports Chrome version 74
```
とか

>```
session not created: Chrome version must be between 70 and 73
```

のエラーが出た場合、**Chrome** のバージョンと **ChromeDriver** のバージョンが対応していないということ。
`pip uninstall chromedriver-binary` した上で、
http://chromedriver.chromium.org/downloads から対象バージョンを探して手動インストールしよう。

```
cd /usr/local/bin
wget https://chromedriver.storage.googleapis.com/73.0.3683.68/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
chmod 755 chromedriver
rm chromedriver_linux64.zip 
```

## GeckoDriver(Firefox)の場合

```
cd /usr/local/bin
wget https://github.com/mozilla/geckodriver/releases/download/v0.24.0/geckodriver-v0.24.0-linux64.tar.gz
```

実行時に `selenium.common.exceptions.WebDriverException: Message: Unable to find a matching set of capabilities` が出るときは、FirefoxとGeckoDriverのバージョンが合っていないときだから、双方のバージョンを最新にしてみよう。

# 動作確認

```py:Python
from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
driver = webdriver.Chrome(options=options)

driver.get('https://www.google.com/')
```

**Firefox**の場合は、

```py
from selenium.webdriver.firefox.options import Options

options = Options()
options.add_argument('-headless')
driver = webdriver.Firefox(options=options)
```

と書き替えればOK。
dockerでpquotaを有効にする

dockerでディスク使用量を制限するためにはgrubでproject quotaを有効にする必要があります。

>
Quotas are support on btrfs, overlay2+xfs, and and devicemapper. 

　と言われた場合に。

##grubの編集
```
vi /etc/default/grub
```
どこかに
```
GRUB_CMDLINE_LINUX_DEFAULT="rootflags=uquota,pquota" 
```

を追加

##grub更新
んで( https://qiita.com/moukuto/items/c78f29f9bd1221baffca )より引用

>
・BIOSマシン

```
grub2-mkconfig -o /boot/grub2/grub.cfg
```

・UEFIマシン

```
grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg
```

##再起動


##確認
>
GRUB_CMDLINE_LINUXの変更が適用されているかは、以下コマンドで確認可能

```
cat /proc/cmdline
```

```
[root@localhost ~]# cat /proc/cmdline
BOOT_IMAGE=/vmlinu(中略）uiet rootflags=uquota,pquota
```

#Ref
https://forums.docker.com/t/storage-quota-per-container-overlay2-backed-by-xfs/37653
https://qiita.com/moukuto/items/c78f29f9bd1221baffca
.gitignoreを使ってGitの管理対象外ファイルを指定

# .gitignoreとは？
Gitの管理対象外とするファイルを指定するための設定ファイルのこと。

拡張子以降の記載しかないので、端末の設定によっては表示されてない点に注意が必要です。


# 設定方法

.gitignoreファイルからみた除外対象ファイルのパスを記載して指定する。
.gitignoreファイル内の空行や#で始まる行は無視される。

なお、.gitignoreファイルの影響範囲は、そのファイルが置かれているディレクトリ以下の全ての階層。
.gitignoreファイルは複数のディレクトリに置くことができるが、深い階層のファイルに書かれた指定の方が優先度が高い。（後から読み込まれるかららしい。）

### 除外のための記載方法（パターン）
- `*.a` 
.aファイルを全て無視

- `!lib.a` 
.aファイルを全て無視する記述がある場合でも、lib.aファイルは無視しない。

- `/TODO` 
ルートディレクトリに置かれたTODOファイルを無視

- `build/`
build/ディレクトリ以下の全てのファイルを無視

- `doc/*.txt` 
doc/ディレクトリ配下の.txtファイルを無視（doc/server/ディレクトリ配下の.txtファイルは無視しない）





### .gitignoreの作成タイミング

初回の.gitignore編集は"git add ."の前に実施しておくべき。





# （参考文献）
 - git

https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E5%9F%BA%E6%9C%AC-%E5%A4%89%E6%9B%B4%E5%86%85%E5%AE%B9%E3%81%AE%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%81%B8%E3%81%AE%E8%A8%98%E9%8C%B2#%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E7%84%A1%E8%A6%96


# 宿題事項
この記事を書くに当たり、一旦保留事項とした案件リスト。今後の学習対象とするので乞うご期待。

 - gitignoreで管理対象外とすべきファイルには、どのようなものがあるんや？とりあえずコレ書いとけみたいなのがある、はず？
 - gitignoreは`gibo`や`gitignore.io`で自動生成できる？
 - 管理対象外としたいファイルを既にadd してしまった時にやること。つまり.gitignoreファイルの設置が遅れた時にやること。があるのか？
Railsで日本語化および国際化機能をためす

##エラーメッセージの日本語化
デフォルトだと英語になっているので、日本語に変更する。

```rb:config/application.rb
（中略）
config.generators.system_tests = nil
config.time_zone = "Tokyo"
# ↓これを追加
config.i18n.default_locale = :ja
```
config配下のファイルは自動更新されないので、変更後は**必ずサーバーを再起動する**。

次にgemパッケージ「rails-i18n」を追加する。

```rb:Gemfile
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.1.0', require: false
gem 'email_validator', '~> 1.6'
# 以下を追加
gem 'rails-i18n', '~> 5.1'
```
```
bundle install
```
これでエラー時に表示される、「can't be blank」部分は日本語化できる。
しかし、モデルの情報については英語のままになるので、それについても対応が必要。

```yml:config/locales/ja.yml
ja:
  activerecord:
    models:
      member: 会員情報
    attributes:
      member:
        number: 背番号
        name: ユーザー名
        full_name: 氏名
        sex: 性別
        sex_1: 男
        sex_2: 女
        birthday: 誕生日
        email: メールアドレス
        administrator: 管理者
```
これでモデル情報についても日本語化される。

##Railsの国際化機能の使い方
ロケールテキストを読みだすには、I18nクラスのtranslateメソッド(t)を使う。
また、日付や時刻を現在のロケールに従った、文字列に変換するには、localizeメソッド(l)を使う。
viewやcontrollerで使う場合は、I18nを省略して書くことができる。
ロケールの設定がjaならja:の下のテキストが使われる。

```yml:config/locales/ja.yml
ja:
  messages:
    hello: "%{name}さん、こんにちは"
  date:
    formats:
      default: "%Y/%m/%d"
      long: "%Y年%m月%d日(%a)"
      short: "%m/%d"
  time:
    am: 午前
    formats:
      default: "%Y/%m/%d %H:%M:%S"
      long: "%Y年%m月%d日(%a) %H時%M分%S秒"
      short: "%y/%m/%d %H:%M"
    pm: 午後
```
```
a = I18n.t("messages.hello", name: "プーさん")

s = I18n.l(Time.current)
```
指定した国際化フォーマットを使った例

```erb:sample.erb
<%= t("messages.hello", name: "プーさん") %>
<%= l(Time.current, format: :long) %>
```
【基本情報技術者試験対策】最短経路の問題の解き方

参考サイト:
https://www.fe-siken.com/kakomon/30_haru/q2.html

#問題
![keiro.png](https://qiita-image-store.s3.amazonaws.com/0/368574/3bc91d67-cec2-6444-ec6e-2af0d6ed2131.png)

#解き方
次の３ステップで解ける
>1.点Pから点Rに至る経路数を求める
2.点Rから点Qに至る経路数を求める
3. 1 × 2

##1.点Pから点Rに至る経路数を求める
4回行われる移動のうち上2回の位置が決まると自動的に右2回の位置も決定することから、組合せの公式を用いて次のように求められる。
>4C2＝(4×3)／2＝6(通り)

##2.点Rから点Qに至る経路数を求める
4回行われる移動のうち上3回の位置が決まると自動的に右2回の位置も決定することから、組合せの公式を用いて次のように求められる。
>5C3＝(5×4×3)／(3×2)＝10(通り)

###余談
右への移動をベースに考えた時でも、求めらえる答えは同じ。
>5C2＝(5×4)／2＝10(通り)

##3. 1 × 2
> 6 × 10 = 60(通り)
Highcharts色々テクニック集

## PDFだけ出力させないようにする
exportingでPDFだけのけものにする

```javascript
        exporting: {
          buttons: {
            contextButton: {
              menuItems: ['printChart', 'separator', 'downloadPNG', 'downloadJPEG', 'downloadSVG']
            }
          },
        },
```
https://api.highcharts.com/highcharts/exporting.buttons.contextButton.menuItems


## ボタンを押して動的に全グラフ削除
グラフを動的に制御したい時に重宝。全グラフを削除して新しいグラフを入れる場合とかに使う。
while でseriesの中身がなくなるまでremoveする。

```javascript
$('#button').click(function () {
    while (chart.series.length) {
        chart.series[0].remove();
    }
    for (var i=1;i<new_data.length;i++) {
    	chart.addSeries(new_data[i])
    }
});
```
[全文はこちらから](http://jsfiddle.net/tentatsu/sbnjme41/)
[Rails] hidden_field_tagでparamsにクエリを渡したい時の書き方

クエリに`{ xxxx: vvvv }`を設定したいとき、つまり
`params[:xxxx] = vvvv`となるようなクエリを
hidden_field_tagを使って設定したいときは

`<%= hidden_field_tag(:xxxx, vvvv) %>`

とすればよい。


`<% hidden_field_tag(:xxxx, vvvv) %>`のように
`=`を外してしまうと<b>URLにクエリが表示されなくなる</b>ので注意。。

<br>

この手のことが、調べてもなかなか書いてなかったので。

おわり
/etc/groupの`user_list`が更新されるタイミング

# TL;DR
/etc/groupの`user_list`はあるユーザのSupplementary groupが変更されるときに更新される。
`useradd`や`usermod`だと`-G, --groups`オプションを指定しない限り更新されない。

# 気になった経緯
「group01をPrimary groupにもつユーザを複数作る」という要件に対してAnsibleで作成したときと手動で作成したときで`/etc/group`の内容が違う、という問い合わせが発端。

手動で作成した時のコマンド群は以下の通り。

```bash
groupadd -g 2000 group01
useradd -u 2000 -g 2000 user01
useradd -u 2001 -g 2000 user02
useradd -u 2002 -g 2000 user03
```

（varsの取り方などがやや特殊な使い方をしているため細部は異なるが）実行したplaybookの要点を整理すると以下の通り。

```play_user.yml
- hosts: all
  tasks:
    - name: "Add group01"
      group:
        name: group01
        gid : 2000

    - name: "Add users in group01"
      user:
        name: "{{ item.name }}"
        uid : "{{ item.uid }}"
        group : group01
        groups: group01
      with_items:
        - { name: user01, uid: 2000 }
        - { name: user02, uid: 2001 }
        - { name: user03, uid: 2002 }
```

上記をそれぞれ実行したとき`/etc/group`の内容が異なってくる。

```bash:手動で作成した場合の/etc/group
group01:x:2000:
```

```bash:play_user.ymlで作成した場合の/etc/group
group01:x:2000:user01,user02,user03
```

結論としては手動で`-G, --groups`を指定していないのにAnsibleで`groups`パラメータを有効にしているのが原因。
`id`コマンド実行時の結果は変わらないので実害はないはずだが、個人的には/etc/groupだけ見れば「あるグループに所属しているユーザ一覧」を出せると思っていたのでPrimary groupとして所属しているユーザが/etc/groupに反映されていないのは少し気持ち悪い。
`man group`でも`user_list`についてPrimary/Supplementaryに関する言及は特になかったので厳密な取り扱いはしないのかな。

```
The /etc/group file is a text file that defines the groups on the system. There is one entry per line, with the following format:
    group_name:password:GID:user_list

The fields are as follows:
    group_name  the name of the group.
    password    the (encrypted) group password.  If this field is empty, no password is needed.
    GID         the numeric group ID.
    user_list   a list of the usernames that are members of this group, separated by commas.
```

結局、権限に関する処理を実行する際に「ユーザ→グループ」の参照ができれば「グループ→ユーザ」はあんまり需要がないのだろうな、と。
「あるグループに所属するユーザ全員に対する処理」はユーザ一覧総ナメして所属の有無確認すれば実現できるしなぁ。

# 蛇足

* [useradd.c](https://github.com/shadow-maint/shadow/blob/70a412fd3479bc172c9993717556585d486a9206/src/useradd.c#L1126-L1128)では/etc/groupを更新する処理に入るのは`--G, --groups`が指定されたときのみ。
* [user module](https://github.com/ansible/ansible/blob/stable-2.4/lib/ansible/modules/system/user.py#L486-L524)では`group`と`groups`でコマンドへの反映処理はきっちり分けている。
2進数の、1の補数 と 2の補数

参考サイト:
http://proengineer.internous.co.jp/content/columnfeature/6254

#はじめに
理屈は抜きにして、どうすれば２進数の１の補数と２の補数を求めることができるのかだけ書くよ。
補数って何？補数を使うとどんないいことがあるの？って方は、<a href="https://qiita.com/philip_runner/items/14a16ae4e4f5874bcc25">こちら</a>をご参照ください。

#２進数の、１の補数の求め方
１の補数にする前の数を７桁の２進数「１００１１０１」とします。
２進数の１の補数は、<font color ="red">元の数の０と１を反転</font>すればよい。
つまり……
>元数：１００１１０１
補数：０１１００１０

これでいいのだ。

#２進数の、２の補数の求め方
先程と同じく、元の数を７桁の２進数「１００１１０１」とします。
２進数の１の補数は、<font color="red">１の補数に１を加算</font>すればよい。
つまり……
>元数：１００１１０１
補数：０１１００１<font color=blue>１</font>

これでいいのだ。
Three.jsとシェーダー　〜カスタム変数〜

前回で組み込み変数がサクッと使えることがわかったのですが、自分で追加するカスタム変数に関しては結構様々面倒なことがあるらしいので、ドキュメントを追っていきたいと思います。

## 宣言
カスタム変数は当然組み込み変数と違って宣言する必要があるみたいです。
attributeは使用するとき、つまりは頂点シェーダー内で宣言すれば良いみたいです。またvaryingも使用するときに宣言すればよいです。これは実際上２つのシェーダーで使用するので両方のシェーダーで宣言することになります。

uniformは特殊で、uniformを宣言するプロパティが存在し、また使用するときにも宣言する必要が出てくるみたいです。なので、例えばカスタム変数を宣言、使用するときの例はこんな感じに。

```.js

var material = new THREE.ShaderMaterial( {

uniforms: {
    time: { value: 1.0 }, //unformはここでも宣言
},

vertexShader:[
    "precision mediump float;",
    "attribute vec4 attr_hoge;", //アトリビュートは使うときに宣言
    "varying vec4 var_fuga;",   //varyingも使うときに宣言
    "void main() {",,
    "}"
  ].join( "\n" ),

fragmentShader:[
    "precision mediump float;",
    "uniform float time;",　//uniformを使うときの宣言
    "varying vec4 var_fuga;",　//varyingも使うときに宣言
] .join( "\n" )

} );

```

ここでカスタム変数に関して注意しなくてはいけないてんとして**WebGLは一次元配列しか扱えないので一次元配列として宣言、使用する必要があります。**
PostgreSQL｜could not connect to server: No such file or directory

こんにちは[@yukifreeworld12](https://twitter.com/yukifreeworld12)です。

#PostgreSQLでハマる
軽くエラーにハマったので今後の為にもメモメモ。
参考になったサイト(https://techracho.bpsinc.jp/hachi8833/2017_12_21/48661)
##問題
`$ bin/rails db:create`と打つと
>could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/tmp/.s.PGSQL.5432"?

と返され起動できない。
##やったこと
`$ $ brew services restart postgresql`
>==> Successfully started `postgresql` (label: homebrew.mxcl.postgresql)

上手くいったみたいなのでここで
`$ bin/rails db:create`
>Created database 'scaffold_app_development'
Created database 'scaffold_app_test'

データベースが作成され上手くいきました。