OmniAICreator/Qiita-1.07M huggingface dataset:
Raspberry Pi カメラ画像をS3へアッロード

##モチベーション
AWSへ繋ぐ目的で購入したラズパイをようやくAWSに繋ぐ。
まずは単純にカメラで静止画撮影してS3にあげる

##前提環境
- RaspberryPi3B+
- Raspbian 9.8
- Python 2.7.13/Python 3.5.3
- picamera 1.13

##追加環境
- boto3

##事前準備
[「クラウドへの複数ファイル一括アップロード」](https://qiita.com/atmaru/items/8187ea2d6eac4c03b49a)にて以下の準備を済ませています。
- AWS IAM ユーザーの作成→AWS_Admin
- AWS CLI インストールおよび設定(Configure)
- S3 Bucketの作成→atsmaru-bucket

##pythonにて写真撮影＋S3へのアップロード

以下のコードを実行させることで、日付+時刻.jpgの画像をpicameraから取得し、s3にuploadすることができるようになりました。

```takePicToS3.py
# coding: utf-8
import picamera
import boto3
import time
from datetime import datetime

def take_pic_from_picamera(filename):
    print("take_pic_from_picamera:"+filename)
    with picamera.PiCamera() as camera:
 #    camera.resolution = (1024, 768)
     camera.resolution = (500, 500)
     camera.start_preview()
     camera.led = False
     #camera warm-up time
     time.sleep(2)
     camera.capture(filename)
     print("done")
    
def upload_to_S3(filename):
    print("upload_to_S3:"+filename)
    bucket_name = "atsmaru-bucket"
    s3 = boto3.resource('s3')
    s3.Bucket(bucket_name).upload_file('/home/pi/'+filename, filename)
    print("done")

# main
timestr = datetime.now().strftime('%Y%m%d%H%M%S')
filename=timestr+'.jpg'
take_pic_from_picamera(filename)
upload_to_S3(filename)
```
Ansibleでファイルの中身を変数に入れる

# 1.はじめに
会社でAnsibleを使ってます。
Google先生に頼りながら切った貼ったを繰り返してるわけですが、自分が困ったところはきっと世の中でも困ってる人がたくさんいるだろうと思って書きます。
今回はAnsibleでファイルの中身を変数に入れるやり方を紹介します。

# 2.shellを使えばOK
```
shell: cat /tmp/hoge.txt
register: hoge
#変数に入れたいファイルのフルパス「/tmp/hoge.txt」
#実行後にファイルの中身が入った変数「hoge」
```
それだけ。確かにそりゃそうだけども！！！ってなりますよね。
もしかしたらAnsibleでちゃんとそういう機能はあるかもしれません。
英語はThis way...ぐらいしか読めないのでドキュメントもまともに読んでないです。

たぶん、変数を使う時はもしかしたら「hoge.stdout」と指定する必要があるかもしれません。
会社でやったことを記憶を頼りに思い出してるので、あやふやなんですがご了承下さい。
Go言語のinterface

Go言語の中ではinterfaceがあります。
JAVAのinterfaceと同じじゃないと想像するかもしれませんが、実際は全然違う感じです。

#定義
type インタフェース名 interface {
    メソッド１(パラメータ名１　パラメータ型１, ..., パラメータ名n　パラメータ型n) (戻リ値１　戻り値型１, ..., 戻リ値n　戻り値型n)
    メソッド2(パラメータ名１ パラメータ型１, ..., パラメータ名n パラメータ型n) (戻リ値１　戻り値型１, ..., 戻リ値n　戻り値型n)
}

例：

```go
type Printer interface {
	Print()
	ReceiveData(data string) (result bool)
}

type Data struct {
	printData string
}

func (data Data) Print() {
	fmt.Println(data)
}

func (data *Data) ReceiveData(printData string) (result bool) {
	data.printData = printData
	return true
}

func main() {
	var d Printer = &Data{}

	fmt.Println(d.ReceiveData("print data"))
	d.Print()
}
```

出力：
>true
>{print data}


#embeded interface
例：

```go
type Sender interface {
	send()
}

type Receiver interface {
	receive()
}

type MixMac interface {
	Sender
	Receiver
}

```


#Nil interface
実装されないinterfaceを呼び出すとruntimeエラーになる。

```go
type Car interface {
	run()
}

func main() {
	var car Car
	recover(car)
	car.run()
}

func recover(car Car) {
	fmt.Printf("(%v, %T)\n", car, car)
}

```

出力：
`(<nil>, <nil>)`
`panic: runtime error: invalid memory address or nil pointer dereference`
`[signal 0xc0000005 code=0x0 addr=0x0 pc=0x490062]`


#empty interface
メソッドがないインタフェースです。


```go
func main() {
	var car interface{}
	run(car)

	car = "toyota"
	run(car)

	car = 2000
	run(car)
}

func run(car interface{}) {
	fmt.Printf("(%v, %T)\n", car, car)
}

```

出力：

`(<nil>, <nil>)`
`(toyota, string)`
`(2000, int)`

以上
How to disable command output in jenkins pipeline build logs

## タイトルを訳すと
Jenkins pipelineのビルドログに、shellコマンドの出力を非表示にする方法

### set +x && set -x
```
sh(script: "set +x && echo test && set -x")
```

実行すると、大体こんな感じ

```
[Pipeline] sh
+ set +x
```
Raspberry PiにNASをマウントしセグメントが違うネットワークでNASを共有する

# Raspberry Piでイーサネットコンバータ&samba構築

DroboFS(NAS)が有線LANしか接続方法が無いため設置場所が限られていた問題をRaspberry Piを使って解決させました。

ルーター = [無線] = Raspberry Pi = [有線] = DroboFS(NAS)

でDroboFS ( NAS )にルーター側のPCから接続できるようになりましたという話の手順になります。



##　使用機器
- Raspberry Pi 3 Model B+
- DroboFS ( NAS )


## ネットワーク環境

### 192.168.1.x
- ルーター(gateway) 192.168.1.1
- PC (dhcpからip取得) 192.168.1.x
- Raspberry Pi wlan0 192.168.1.110(dhcpで固定)

### 192.168.2.x 
- Raspberry Pi eth0 192.168.2.1
- NAS ( DroboFS ) 192.168.2.100(NAS側でip固定)



## 1. 準備

・[Raspberry PiにOSインストールする](https://qiita.com/kanaisawa/items/4723f72a28084263ae1f)


## 2. Raspberry Pi を イーサネットコンバータ にする

・[Raspberry Pi 3 を イーサネットコンバータにする](https://qiita.com/fstyle/items/dee9271bb8e17a005b31)


## 3. NAS を マウント させる

・[Raspberry Pi 3 に NASをマウントさせる](https://qiita.com/fstyle/items/284508cfc33af54d826d)


## 4. マウントした領域を共有 ( samba )

・[Raspberry Pi 3 でファイル共有](https://qiita.com/fstyle/items/1670d260f58f77a43144)


## Raspberry Pi 関連
・[Raspberry Pi 3 を SSH接続できるようにする](https://qiita.com/fstyle/items/2e85cd0a85b848213a14)
・[Raspberry Pi 3 GUI から CUI に変更](https://qiita.com/fstyle/items/4bb497ef4194328040f4)

## 最後に

ここまで来るのに3日ほど時間を要しましたが構築してみて大変便利になりました。

テレビ周りをスッキリとさせたかったというのが一番の目的でRaspberry Piを使うことでNASがクローゼットの中で動作させることが可能になり、音も気にならなくなり、場所もとらなくなりで大満足です。

今回どうしても外せなかった条件

- ルーターとNASを有線で接続させない
- 電源が確保できる場所であればどこでも設置可能とする
- どこからでもアクセス可能なNASにする
- NASからもインターネットを可能とする

上記をすべて達成しています。

無線対応のNASを買えばよいのですがDroboFSがとても気に入っているので今回の方法を取らざるを得ない状態でした。
こだわりがない場合はRaspberry Piに外付けUSBのHDDをとりつけマウントさせてしまえばNAS自体を構築することも可能なので環境に応じて設定をお楽しみください。
C#/Python手遊び(lambda式とかのミニマムコード)

#この記事、何?
ちょっと前に初めて書いてみたlambda式とか。
旧世代言語との付き合いが長かったので最初、「？？？」って感じだったけど、ようやく見えてきた気がする。
で、PythonとC#と混ぜて書いていると書き方が混ざってよく間違う。
なので、両方で同じことをやってみるミニマムコード作って覚書を作ってみた。


#どういう人向け?
やっていることはかなり単純なことなので初心者向け。
つまり自分向け。。。

#方針
1文字レベルの細かなリテラルが分かればいいかな、と。
で、存在している関数を書く場合と、lambda式をその場で作る場合の2通りを。
まあ、動作確認しやすい四則演算で。
なので、{ 存在している関数, lambda式 } × { +, -, *, / } で8つの関数をlistに束ねてforeachでくるくるする感じで。


#出来上がり
コード書式の覚書でしかないのでいきなりコードで。

```csharp
//c#

using System;
using System.Collections.Generic;

public class Test
{
    public static void Main(string[] args)
    {
        var list = GetFunctionList();
        Export(list, 24, 4);
    }

    //関数定義
    public static List<Func<int, int, int>> GetFunctionList()
    {
        var list = new List<Func<int, int ,int>>();
        list.Add(GetAnsPlus);
        list.Add(GetAnsMinus);
        list.Add(GetAnsMultiple);
        list.Add(GetAnsDivide);
        //list.Add((int x, int y) => x + y);
        //list.Add((int x, int y) => x - y);
        //list.Add((int x, int y) => x * y);
        //list.Add((int x, int y) => x / y);
        list.Add((x, y) => x + y);
        list.Add((x, y) => x - y);
        list.Add((x, y) => x * y);
        list.Add((x, y) => x / y);
        return list;
    }

    //出力
    public static void Export(List<Func<int, int, int>> list, int x, int y)
    {
        foreach (var f in list)
        {
            Console.WriteLine(f(x, y));
        }
    }

    public static int GetAnsPlus(int x, int y) { return x + y; }
    public static int GetAnsMinus(int x, int y) { return x - y; }
    public static int GetAnsMultiple(int x, int y) { return x * y; }
    public static int GetAnsDivide(int x, int y) { return x / y; }

}
```


```
■ 出力
C:\projects\qiita\draft\29>29-01.exe
28
20
96
6
28
20
96
6

```


```python
#Python

def GetAnsPlus(x, y):
    return x + y
def GetAnsMinus(x, y):
    return x - y
def GetAnsMultiple(x, y):
    return x * y
def GetAnsDivide(x, y):
    return x / y

list = []
list.append(GetAnsPlus)
list.append(GetAnsMinus)
list.append(GetAnsMultiple)
list.append(GetAnsDivide)
list.append(lambda x, y: x + y)
list.append(lambda x, y: x - y)
list.append(lambda x, y: x * y)
list.append(lambda x, y: x / y)

for f in list:
    print(f(24, 4))

```

```
(base) C:\projects\qiita\draft\29>python 29-02.py
28
20
96
6.0
28
20
96
6.0

```


#感想
うん、まあ、満足。
これ、忘れたころに自分で見に来ることになりそう。
いや、よく、C#とPythonのコードルールをまぜこぜで書こうとしてエラーが出て手が止まったりしてたので。
Raspberry Pi 3 GUI から CUI に変更

Raspberry Pi 3 Model B+ ( ラズベリーパイ )  GUI / CUI の変更方法


```
$ sudo raspi-config
```
![img2-5.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/65db5f3b-4143-2e26-096a-f52bc8293519.jpeg)

「3 Boot Options」 を選択

![2220.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/beac0a74-a6d9-cb74-226e-756aa8e8b13c.jpeg)

「B1 Desktop / CLI」を選択して切り替える
Raspberry Pi 3 を SSH接続できるようにする

Raspberry Pi 3 Model B+ ( ラズベリーパイ ) を SSH接続可能な状態にする

# Raspberry Pi 側の SSH接続設定

```
$ sudo raspi-config
```
![img1.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/4b6439b5-f264-e896-f6c7-3fb3b2878b85.jpeg)
「5 Interfacing Options」を選択

![3334.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/5443c8d9-8c3c-307d-f55c-a70bd4bd4727.jpeg)
「P2 SSH」を選択

![222-6.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/6d2ee958-ef8b-61ca-ce8b-97731e94c3b2.jpeg)
「はい」を選択

# Windowsからの接続

- Windows PC側「Poderosa」では接続できなかったので「Tera Term」をインストールして接続

![4442.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/b7daeb6a-9953-bd0a-a338-0157abd84421.jpeg)

![111-8.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/83612173-d3a7-1c8b-ae12-2472c3792b67.jpeg)
【備忘録】Ubuntu 18.04 基本設定

Ubuntu 18.04ja インストール後、基本設定のあれこれを行いました。
備忘録としてメモしておきます。

### フォルダの表示名変更
デフォルトでは、「ドキュメント」「ダウンロード」のように日本語表示です。
端末上での操作性の観点から、英語表示に変更します。

```java:setting
env LANGAGE=C LC_MESSAGES=C xdg-user-dirs-gtk-update
```

「ドキュメント」「ダウンロード」が「Documents」「Downloads」のように変更されます。


### 端末のプロンプト表示の変更
端末左側のあれです。
私の好みで、[ユーザ@カレントディレクトリ名]も表示変更します。

```java:setting
 export PS1="[\u@ \w]\$ "
```
\u がユーザ名, \w がカレントディレクトリを表します。
その他, \t で時刻, \h でホスト名が表示できます。
bashrcにも書いておきましょう。


### 右側表示メニュー(Dock)の非表示化
左側にボヨンと出ているメニュー（アクティビティ押すと出てくる）を非表示にして、画面を広く使えるようにします。

```java:setting
gsettings set org.gnome.shell.extensions.dash-to-dock autohide false && gsettings set org.gnome.shell.extensions.dash-to-dock dock-fixed false && gsettings set org.gnome.shell.extensions.dash-to-dock intellihide false
```
端末で実行すれば、非表示に変更されます。



今日はここまで。
また何かあれば更新します。
php-master-changes 2019-03-08

今日はZPP の実装をテストしているに過ぎないテストの削除、ビルドシステムのリファクタリング、ドキュメントの更新があった！

# 2019-03-08
## nikic: More zpp error/variation test removals
- https://github.com/php/php-src/commit/2580a7ba092b4ed9f4a9860d911e2e17ec545ef5
- [7.4~]
- [昨日](https://qiita.com/sj-i/items/dea5d92e65b35f10b89f)に引き続き ZPP の実装をテストしているに過ぎないテストを削除

## petk: Add AS_HELP_STRING to *nix build configure options
- https://github.com/php/php-src/commit/9df6a1e4dd84a39bfaec70d7d008b61f7bbae347
- [7.4~]
- ビルドシステムで、[AS_HELP_STRING](https://www.gnu.org/software/autoconf/manual/autoconf.html#Pretty-Help-Strings) を *nix の configure オプションに追加
- カラム落ちがないよう頑張る奴らしい……

## petk: Clean *nix build system
- https://github.com/php/php-src/commit/f5fa9ddbd50e323091320f125324353153558bcf
- [7.4~]
- ビルドシステムで、*nix 用の不要な記述を削除

## KalleZ: Give Peter credit for his work on the Unix build system
- https://github.com/php/php-src/commit/aa33ab96963c1a2dd55f209ab284172f85fd3980
- [7.4~]
- petk の人をビルドシステム修正頑張ってる人としてクレジットに記載
- 実際がんばってる

## nikic: More zpp error/variation test removals
- https://github.com/php/php-src/commit/59dd1979ef8edc2586b551b0686f57ddfa159160
- [7.4~]
- ZPP の実装をテストしているに過ぎないテストをもっと削除
水上ドローン作りたい9、動作テスト

# モーター用電池ボックス
単3×3を2つ投入する必要が有ります。
船体の前後にに丁度いいスペースがありました。そこを利用します。※横のペットボトルは後述。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/359316/b0cca99e-205a-2e9c-1330-9c3c4b14e60a.png)
# 船体-甲板間のやりとり
  甲板に穴をあけてケーブルをやりとりします。穴ははんだゴテで簡単にあきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/359316/15314752-7d49-3a4a-428c-b8c58ee1390c.png)
  船体と甲板を合わせるとこうなります。モータードライバの収まりが悪いですね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/359316/bd856c8b-6674-a71d-e9e5-36639097dc6c.png)
　これで蓋を閉めると、こうなります。※スペースがギリギリで蓋がなかなか閉まりません。最後は無理矢理押し込みました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/359316/d75817a5-4173-8a69-f6a4-ebd3a0c51977.png)
# 動作確認
操船関連の目途がついたので、簡単に動作確認を行いました。こんな感じです。
PCからコマンドを送ってモーターを回しています。※UIが未整備なのでCUIです。
[モーターテスト Youtube](https://www.youtube.com/watch?v=cl-uH6g7Oek)
風呂に浮かべてみました。
[風呂テスト Youtube](https://www.youtube.com/watch?v=31CXgPe2Nkk)

ボートを遠隔PCからコントロールできる事が確認できました。残るコンポーネントは「カメラ」「インターネット通信用ドングル」の2つのみです。
[python] 深さ優先探索でディレクトリ名を再帰的に変更

# やりたいこと
　**あるディレクトリ配下に存在する全てのディレクトリを一括でリネームする**． 例えば、このようなディレクトリ構造から

```shell

.
├── a.txt
├── dir_1
└── dir_2
    ├── b.txt
    ├── dir_3
    └── dir_4
        ├── c.txt
        ├── dir_5
        └── dir_6
```

カレントディレクトリ配下のディレクトリを、以下のようなディレクトリ名に再帰的にリネームしたい．

```
.
├── a.txt
├── new_dir_1
└── new_dir_2
    ├── b.txt
    ├── new_dir_3
    └── new_dir_4
        ├── c.txt
        ├── new_dir_5
        └── new_dir_6
```
　　
# How?
 [深さ優先探索](https://ja.wikipedia.org/wiki/%E6%B7%B1%E3%81%95%E5%84%AA%E5%85%88%E6%8E%A2%E7%B4%A2)の要領でディレクトリを探索させることで、**最も深い階層のディレクトリから優先的にリネーム**することができる．

```python

from pathlib2 import Path

def rename_dirs(path):
    path = Path(path)
    dirs = [d for d in path.iterdir() if d.is_dir()]
    for d in dirs:
        rename_dirs(d)
        new_name = "new_" + d.name
        d.rename(d.parent / new_name)    
    
rename_dirs(".")
```

`rename_dirs()`は、引数のpath直下にあるサブディレクトリを列挙してから、それぞれのサブディレクトリに対しさらに直下のサブディレクトリを列挙する(再帰処理)．これを繰り返し、サブディレクトリをもたないディレクトリまでたどり着いたときに、そのディレクトリのリネームが行われる．また浅い階層(=最下層ではない)ディレクトリのリネームは、自分のサブディレクトリが全てリネームされた段階で逐次実行されることになる．
　

# Appendix

　参考までに、pathlibモジュールの`glob()`を使ってうまくいかなかった例を残しておきます． (`glob()`の引数`**`を指定すると、再帰的にディレクトリだけ取得できます．)


```python

from pathlib2 import Path

path = Path(".")
dirs = [d for d in path.glob("**") if not str(d)=="."] #カレントディレクトリをレネーム対象から除いておく 
for d in dirs:
    new_name = "new_" + str(d.name)
    d.rename(d.parent / new_name)
```
```:output
FileNotFoundError: [Errno 2] No such file or directory: './dir_2/dir_4' -> './dir_2/new_dir_4'
```
｢そんなファイルないよ｣と怒られます．リネームのループ中で、浅い階層にあるディレクトリのリネームを、それより深い階層にあるディレクトリのリネームより前に行ってしまったからです．`dir_2`が`new_dir_2`と変名されると、次のループで処理対象となる`dir_2/dir_4`はもう存在しません．(存在するのは`new_dir_2/dir_4`)
フォルダ内のCSVファイルを統合するマクロ　その3

今回は、その2で作成した
『同じフォルダ内にあるCSVファイルをコピー範囲の開始行をinputboxで指定してコピペして統合するマクロ』
に一番右のセルにCSVファイル名の【】内の文字を記入するコードを追加しました。

```VB
Sub tougou03()

'フォルダを選択
    Dim folderPath As Variant
    With Application.FileDialog(msoFileDialogFolderPicker)
        .Show
        folderPath = .SelectedItems(1)
    End With

'Dir関数でCSVファイル名を取得
    Dim buf As String
    buf = Dir(folderPath & "\" & "*.csv")
    Debug.Print buf        'ファイル名を確認

'貼り付け元の「請求統合.xlsx」ファイルを開いて最初のシートを指定
    Dim bath As Workbook
    Set bath = Workbooks.Open(folderPath & "\" & "請求統合.xlsx")
    Dim tougouWs As Worksheet
    Set tougouWs = bath.Worksheets(1)

'CSVファイルの転記位置が上から何行目かをインプットボックスで指定
'（「j」が空白を入力されたときにメッセージを出したいので、Long型ではなくString型を指定）
    Dim j As String
    j = InputBox("CSVファイルの転記の開始は何行目ですか？（半角英数で入力してください）")

    If j = "" Then
        MsgBox "空白が入力されました。最初からやり直してください"
        Exit Sub
    End If

'CSVファイルの一番右下のセルの位置
    Dim maxRows As Long
    maxRows = Cells(1, Columns.Count).End(xlToLeft).Column

'ループ開始・CSVファイルの名前が空白になったら（取得できなかったら）ループから外れる
    Do While buf <> ""

'「請求統合.xlsx」の最終行を取得
        With tougouWs
            Dim bathLastLine As Long
            bathLastLine = .Cells(Rows.Count, 1).End(xlUp).Row
        End With

'CSVファイルの最初のシートを取得
            Dim wb As Workbook
            Set wb = Workbooks.Open(folderPath & "\" & buf)
            Dim ws As Worksheet
            Set ws = wb.Worksheets(1)

'CSVファイルの最下行を取得
'最終行：lastLine
            Dim csvLastLine As Long
            csvLastLine = ws.Cells(Rows.Count, 1).End(xlUp).Row
            
'一番右のセルにCSVのファイル名を記入
            ws.Range(Cells(j, maxRows + 1), Cells(csvLastLine, maxRows + 1)).Value = buf
            
'範囲指定してコピー（クリップボード）
            ws.Range(Cells(j, 1), Cells(csvLastLine, maxRows + 1)).Copy

'「請求統合.xlsx」のA列の最終行の次のセルを指定し貼り付け
            With tougouWs
                .Activate
                .Cells(bathLastLine + 1, 1).Activate
            End With
            ActiveSheet.Paste

'CSVファイルを保存せずに閉じる
            wb.Application.CutCopyMode = False
            wb.Saved = True
            wb.Close

'次のCSVファイルを指定する
            buf = Dir()
    Loop

'一番右のセルのSCVのファイル名の【】内のみを残して置換しセルA1を選択する
    With tougouWs
        .Activate
        bathLastLine = .Cells(Rows.Count, 1).End(xlUp).Row
        With Range(Cells(1, maxRows + 1), Cells(bathLastLine, maxRows + 1))
            .Replace What:="【", Replacement:=""
            .Replace What:="】*", Replacement:=""
        End With
        Range("A1").Select
    End With

'「請求統合.xlsx」を保存して閉じる
    bath.Save
    bath.Close

End Sub
```

【】内の文字列を抜き出しには置換で不要部分を削りました。
最後にセルA1を選択してから保存して閉じるようにしました。

2つ目のマクロ作成も、これで一旦完了とします。
1つ目に比べると変数を使うことに慣れてきた気もします。

次回は
『フィルター機能などを使ってシートごとに必要な行を転記する』
マクロを作りたいと思います。
paizaでgo test

#概要

paizaでgo testやってみた。


#サンプルコード


```
import subprocess
import os

def go():
    p_file = 'calc.go'
    test_p = """
package main

func Add(l, r int) int {
    return l + r
}

"""
    with open(p_file, 'w') as f:
        f.write(test_p)
    c_file = 'calc_test.go'
    test_c = """
package main

import "testing"

func TestAdd(t *testing.T) {
    var result int
    result = Add(1, 2)
    if result != 3 {
        t.Errorf("add failed. expect:%d, actual:%d", 3, result)
    }
    t.Logf("result is %d", result)
}

"""
    with open(c_file, 'w') as f:
        f.write(test_c)
    os.system("ls")
    os.system("go test calc_test.go calc.go")

if __name__ == '__main__':
  go()
  

```

#成果物

https://paiza.io/projects/isJZNn3EQmso1JEmp9VzjQ


以上。
配列の要素を配列のindexとして使う

配列の要素を別の配列のindexとして使えることが分かったのでメモ。

## Usage
```
numbers = [0, 1, 3, 2, 4, 6, 1, 2, 4, 6]

array = []
p array #> []
```

配列numbers[0]の要素をindexにして、配列array[0]に要素を追加する

```
#numbers[0]の要素は0なので、array[0]となる
array[numbers[0]] = 10

p array[numbers[0]] #> 10
p array[0] #> 10
```

ハッシュもできる

```
subject = ["english", "math", "science"]
point ={}

point[subject[0]] = 98

p point #> {"english"=>98}
p point[subject[0]] #> 98
p point["english"] #> 98

```
WindowsのDELコマンドのエラーハンドリング


# 謎仕様
WindowsのDELコマンドはファイルを削除することができるが、
何かしらの理由により対象を削除できなかったときにエラーとなるのだが、
ERRORLEVELには値を設定してくれない。

https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/del
オフィシャルにはそんなこと一言も書いていないけど。

なので、以下のようなエラーハンドリングをBATで作成したとしてもエラールートにはいかない。

```
rem オプション -Q : 削除前に確認メッセージを表示しない
call del /Q C:\temp\sample\*.dat
if %ERRORLEVEL% NEQ 0 goto ERR

goto END

:ERR
echo ファイル削除：Error > del_file.log
exit 2

:END
echo ファイル削除：OK > del_file.log
exit 0
```

# ではどうするか？

## 案１
http://scripting.cocolog-nifty.com/blog/2008/03/errorlevel_95dd.html

エラー時にERRORLEVELに値を設定してくれない代わりに標準エラーメッセージは出力してくれる
であれば、それを捕まえて判定する

ただ、FINDを行う都合上、ERRORLEVELにはDELでのエラー時は0,正常終了時は1となるので、そのあとの判定も逆転させておく必要がある。

```
rem オプション -Q : 削除前に確認メッセージを表示しない
call del /Q C:\temp\sample\*.dat 2>&1 | FIND /V ""
if exist C:\temp\assist\sample\*.dat goto ERR
if %ERRORLEVEL% NEQ 1 goto ERR

goto END

:ERR
echo ファイル削除：Error > del_file.log
exit 2

:END
echo ファイル削除：OK > del_file.log
exit 0
```


## 案２
https://teratail.com/questions/62445

何かしらのエラーで削除されていないのだからファイルの有無チェックでERRORLEVEL判定の代わりにする。

こんな感じになるかと
同じパスを二回ずつ書かないといけないのがなんだかダサいが、修正する箇所は一行で済む。

```
rem オプション -Q : 削除前に確認メッセージを表示しない
call del /Q C:\temp\sample\*.dat
if exist C:\temp\sample\*.dat goto ERR

goto END

:ERR
echo ファイル削除：Error > del_file.log
exit 2

:END
echo ファイル削除：OK > del_file.log
exit 0
```

## 結論
どっちでもいいとは思うので、好みの方法でやればいいんだと思う。
【イベント】 Applaud Her WWC Tokyo + Rails Girls Tokyo

2019年3月9日に[Rails GirlsとWomen Who Code共同開催イベント](https://www.meetup.com/Women-Who-Code-Tokyo/events/258801947/)に参加してきました。

Rails Girlsはフィンランド生まれの国際コミュニティーです。
東京は2012年から始まったそうです。東京では割と初心者向けのイベントを定期的に開催しています（2019年現時点では独自イベントは11回開催している）。

Women who codeはTech業界への女性の進出を促すNPO団体です。定期的にプログラミング講座やハッカソン等のイベントを開催しています。2011年に発足され、現在5万人以上の女性が登録しており、20国以上で3000以上の女性技術者向けのイベントを開いています。

もっと知りたいかたへ：
* [Rails Girls Tokyo](http://railsgirls.jp/)
* [Women who code Tokyo](http://womenwhocode.tokyo/)
* [WWC Tokyoのオーガナイザーブログ記事](https://medium.com/@Himi/women-who-code-tokyo%E3%81%A8%E7%A7%81-c8fc2b635790)

今回のテーマとしては [#applaudeher](https://twitter.com/hashtag/applaudeher) でした。これはテクノロジーのキャリアに挑んだ女性たちのストーリーを共有し世の中の女性たちに勇気づけるためのムーブメントのようです（正確な定義は見つかっていなくて、テクノロジー以外にも使われているようです）。

Cookpad、万葉、メルカリなどの在籍エンジニアが自分の経験を語る10分セッションとネットワーキングタイムの構成でした。

クッキーとソフトドリンクが豊富でさすがCookpadという印象でした！

ここで気づきや学びを簡単に記録しておきます。

* 林田千瑛に会えた！
* Cookpadは日本だけではなく、60カ国以上に展開されている。
* Machine Learningを活躍してレシピの自動カテゴライズや写真の料理の自動判別と取り込み。
* Cookpadユーザの84%は女性ですが、エンジニアはほとんど男性でしたら共感しづらい。そのために女性エンジニアを増やそうとしている。
* Tech職(OLからフロントエンドエンジニアに、そしてRailsエンジニアへ) に挑むことによって、自身がののもてるようになった、自分の仕事に熱意がモテるようになった、という劇的な人生の変化が得られた方もいた。
* 開発チームに女性が4/5だったりするとより働きやすい環境になっていきます（突然子供が病気になり、出勤できないときなど）。
* 男性が多い職場には未だにハラスメントがおきて、この状態で改善することが難しく、ダイバーシティのある環境にすることが重要だと再確認ができた。
* 土曜日の14:00-17:00イベントはちょうどよいかも！
【初心者】図書館で借りた本を管理したい（返却編） 2

###前回からの築城作業　続き

以前作成した[【初心者】図書館で借りた本を管理したい（外堀編）](https://qiita.com/mpec/items/17ac082be3d9e4be038d)の続きで
図書館で借りた本を返却した際に、csvからその本を削除するというもの

色々検索したところ**pandas**と言うモジュールを使うと簡単にできそうだということが判明


```python
import pandas as pd

BOOKSHELF = 'Bookshelf.csv'

RETURN_BOOK = pd.read_csv(BOOKSHELF, encoding='utf-8', header=0)
# 貸出日、タイトル等は最初の行にあるのでheader=0は無くてもよし

print(RETURN_BOOK)
           貸出日   タイトル    作者          返却日
0  2019年03月07日    方丈記   鴨長明  2019年03月21日
1  2019年03月07日   無双の花   葉室麟  2019年03月21日
2  2019年03月09日  神技の系譜  甲野善紀  2019年03月23日
3  2019年03月09日     秘密  東野圭吾  2019年03月23日
```
csvを読み込んでprintで出力してみるとこのような感じで左にインデックスとして0～3の数字が出てくる
次にインデックス番号を指定して本を返却します


```python
RETURN_BOOK = RETURN_BOOK.drop(1)
# 左のインデックスの番号を引数としてdrop()に渡す

RETURN2_BOOK = RETURN_BOOK.drop([1, 2])
# 複数の引数を渡す場合には[]を使う

print(RETURN_BOOK)
           貸出日   タイトル    作者          返却日
0  2019年03月07日    方丈記   鴨長明  2019年03月21日
2  2019年03月09日  神技の系譜  甲野善紀  2019年03月23日
3  2019年03月09日     秘密  東野圭吾  2019年03月23日

print(RETURN2_BOOK)
           貸出日 タイトル    作者          返却日
0  2019年03月07日  方丈記   鴨長明  2019年03月21日
3  2019年03月09日   秘密  東野圭吾  2019年03月23日
```
指定したインデックス番号の本が消え、インデックス番号が飛び飛びになりました
**返却完了**

```python

RETURN_BOOK.to_csv(BOOKSHELF, encoding='utf-8', index=False)
# 最後に編集したものを書き出す、第1引数を同じにすれば上書き。別のにすれば新たに作成して保存
# index=Falseでインデックス番号を消して保存できる。
```
新たなファイルも問題なし、完成。

今回は本人のやる気の問題でここまで
次回はいろいろ工夫してみ。。。たい


 
 
#2019/03/12追記
```python
def return_book():
    return_book_list = pd.read_csv(BOOKSHELF, encoding='utf-16', header=0)
    print('返却した本はどれですか？番号を入力してください')
    print(return_book_list)
    while True:
        return_book_num = input('>>>')
        if return_book_num.isdecimal() == True:
            return_book_num = int(return_book_num)
            if return_book_num <= len(return_book_list) - 1:
                print(return_book_list[return_book_num : return_book_num + 1])
                print('上記の本を返却しました。')
                return_book_list = return_book_list.drop([return_book_num])
                return_book_list.to_csv(BOOKSHELF, encoding='utf-16', index=False)
                break
            else:
                print(termcolor.colored('その番号は正しくありません。', 'red'))
                continue

        else:
            print(termcolor.colored('番号を入力してください。', 'red'))
            continue
```
やる気が向いて返却の部分を作ってみた
なんかまだ削れる気がする
だがその記述方法を知らない



##参考にさせて頂きました
[pandasでcsv/tsvファイル読み込み（read_csv, read_table）](https://note.nkmk.me/python-pandas-read-csv-tsv/)
[pandas.DataFrameの行・列を指定して削除するdrop](https://note.nkmk.me/python-pandas-drop/)
[pandasでcsvファイルの書き出し・追記（to_csv）](https://note.nkmk.me/python-pandas-to-csv/)

ずぶの素人にはありがたい



##まとめ
新たな方法を見つけるのがなかなか楽しいと感じた
が、重ねていった場合最終的な整合性が？？？

また、お気づきの点がありましたら遠慮なくご指摘お願いいたします
Re：ゼロから始める物体認識 その1 導入と環境構築


#はじめに
最近Deep Learningという言葉をよく聞きます。
あるところでは魔法のように、またあるところでは地獄のように様々な人がいろいろな解釈で話をしていて非常に興味をそそられます。
しかし、現状「Deep Learning興味あるな」から「Deep Learningやってみよう」までにはかなり大きな壁があるように感じます。
大きな問題として必須とされる数学の知識量、環境構築、日本語での資料の少なさが挙げられると思います。
そこで今回は上記の3点を抑えた数学の深い知識が必要なく、環境構築から一つのシリーズで繋げた日本語のDeep Learningの記事を投稿しようと思いました。
こういった技術紹介等を書くのは初めてですので至らないところがあるかもしれませんが、ぜひDeep Learningに興味のある方はお付き合いいただけたらと思います。

#作るもの
タイトルにも書いた通り物体検出を作りたいと思います。
画像では人の顔を認識していますが人の顔でなくてもトランプやボール等様々な物の検出に使うことができます。
![isVC30-n.jpg](https://qiita-image-store.s3.amazonaws.com/0/362776/3a7ac6ec-c741-c987-66de-0508a5749c96.jpeg)




#開発環境
機械学習はLinuxで開発されている方が非常に多いですが今回はWindowsでやっていこうと思います(~~学校のLANがLinuxでは使えないゴミなため~~___初心者向けですからね!___)
下に使用言語やなんやかんや書いていますが導入方法も書くのでわからなくても安心してください。

- OS
 - Windows7

- 使用言語
 - Python3.6.5

- その他使用する外部ライブラリやプラットフォーム
 - VScode
 - TensorFlow-gpu 1.12.0
 - ~~cudnn 9.0~~
 - ~~CUDA 9.0~~
 
CUDAとcudnnはGPUで学習を進める際に必要ですがCPUでも構わないので今回は触れません。
ただ、速度にはかなりの差があるので時間を短縮したい方は入れて見るといいと思います。


# 環境構築
さあ皆さんお待ちかねの環境構築です。
今回の最大の鬼門と言っても過言ではないでしょう。
ここまで読んだあなたなら流石にWindows7(10でもおそらく大丈夫です)は自前で用意できていることでしょう。
もし用意できていない場合はwindows7搭載パソコンをネットで注文してください。これでwindowsの環境構築は完了です。

### Pythonの開発環境を構築する
今回、PythonのインストールにはAnacondaというものを使っていきます。
Anacondaはデータサイエンスや機械学習に必要なパッケージを同時にインストールしてくれる優れもので仮想環境の構築なども比較的容易に可能です。
DLするときにPythonのバージョンを聞かれるので3.6を選択しましょう。
Anacondaは[ここから](https://www.python.jp/install/anaconda/index.html)DLできます。
基本的にダウンロードしてきたセットアップウィザードのnextをどんどん押していくだけです。
ユーザーとしてインストールするかコンピュータ全体にインストールするか聞かれますがよくわからなければユーザーとして(Just Me)にしましょう。
![python-anaconda-install-windows-4.png](https://qiita-image-store.s3.amazonaws.com/0/362776/9d1de065-f5b1-7a2d-1a26-8edfa8167d88.png)
インストール先は特別な理由がない限りデフォルトがいいです。
インストールのオプションとして「Add Anaconda to my PATH environment variable」というチェックボックスが現れますがチェックを入れないことを推奨します。(元からチェックが入っていないので気にせずnextを押し続けていれば入ることはないです)
![python-anaconda-install-windows-6.png](https://qiita-image-store.s3.amazonaws.com/0/362776/04fdfb5e-de4f-3a16-f882-7742702f6c4b.png)

インストールが完了するとVScodeをインストールするか尋ねられます。
使うのでここからインストールしても大丈夫です。


### VScode
次にコードを書く環境です。
先程のAnacondaのセットアップでVSCodeをインストールした方はここは飛ばしても大丈夫です。

正直なんでもいいんですが僕はVScodeを推します。
~~っていうかVisualStudioとVScodeしか使ったことないんですけどね。~~

VScodeは[ここから](https://code.visualstudio.com/)DLします。
セットアップウィザードを起動したら画像の画面が出てくるまでどんどん次へを押して行って大丈夫です。
下の画面が出たら全てのチェックボックスにチェックを入れておきましょう。
![STEP005.jpg](https://qiita-image-store.s3.amazonaws.com/0/362776/ae1df79f-ed72-5385-7442-4263ca14b8ca.jpeg)
このあともどんどん次へを押していきます。
これでVScodeのインストールは完了です。

### VScodeの拡張
VScodeをインストールしたら拡張機能を追加していきましょう
画像の赤で囲っているボタンを押すと拡張機能が追加でき右に出てきた検索欄でほしい拡張を使いすることができます。
![vscode.PNG](https://qiita-image-store.s3.amazonaws.com/0/362776/e5139945-00ea-80ff-985b-776363ba9441.png)

- 今回導入することを推奨する拡張機能は次のとおりです
 - Python
 - Anaconda Extension Pack
 - Code Runner
 - MagicPython
 - Visual Studio Keymap

それぞれ出てきたものをインストールすれば大丈夫です。

### TensorFlowのインストール
Anacondaをインストールすると自動的にAnaconda Promptというものが付属されているのでそれを起動します。
起動するとコンソール画面が出ると思うのでそこにTensorFlowのインストールのコマンドを打ちます。
Pythonのパッケージは基本的にここからインストールをします。
インストールコマンドは`pip install tensorflow`です。

# おわりに
今回は環境構築編ということで必要な物のインストールの仕方を紹介していきました。
次回からは実際にPythonのコードを書いていこうと思います。
ぐるぐる数


O(N)です.昔はO(logN)にできるようちゃんと解析していたのですが申し訳ないです.`crystal build --release`で2分でした.`ruby --jit`はCase63あたりで力尽きました.

```rb
#!/usr/bin/ruby
#http://nabetani.sakura.ne.jp/hena/orde31rotnum/
#https://qiita.com/Nabetani/items/d139d5ef70aa23c2d038

# can run on both Ruby and Crystal.

def chk(n,b)
	n,r=n.divmod b
	while n>0
		n,r0=n.divmod b
		if r0!=r && (r0+1)%b!=r
			return false
		end
		r=r0
	end
	true
end

while s=gets
	b_,x_,y_=s.chomp.split(",")
	b=b_.to_i
	x=x_.to_i(b)
	y=y_.to_i(b)
	p (x..y).count{|i|chk(i,b)}
	STDOUT.flush
end
```

`gcc-8 -fopenmp -O3`では30秒で実行できました.

[追記] 30秒なのはこのMacBookの物理コア数が2コアだからです.大学のスパコンでは3秒でした.

```c
//http://nabetani.sakura.ne.jp/hena/orde31rotnum/
//https://qiita.com/Nabetani/items/d139d5ef70aa23c2d038

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

bool get(int *b,int *x,int *y){
	char s[999];
	if(!fgets(s,999,stdin))return false;
	*b=strtol(strtok(s,","),NULL,10);
	*x=strtol(strtok(NULL,","),NULL,*b);
	*y=strtol(strtok(NULL,","),NULL,*b);
	return true;
}

bool chk(int n,int b){
	div_t x,y;
	x=div(n,b);
	for(;x.quot;){
		y=div(x.quot,b);
		if(y.rem!=x.rem && (y.rem+1)%b!=x.rem)return false;
		x=y;
	}
	return true;
}

int main(){
	int b,x,y;
	for(;get(&b,&x,&y);){
		if(b==2){
			printf("%d\n",y-x+1);
		}else{
			int r=0;
			#pragma omp parallel for reduction(+:r)
			for(int i=x;i<=y;i++){
				r+=chk(i,b);
			}
			printf("%d\n",r);
		}
		fflush(stdout);
	}
}
```

std::futureを使った並列化は以下のようになります。ちゃんとnum_threads分の並列化をするようにしないと重くなってしまいます。

```cpp
//http://nabetani.sakura.ne.jp/hena/orde31rotnum/
//https://qiita.com/Nabetani/items/d139d5ef70aa23c2d038

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#include <vector>
#include <future>

bool get(int *b,int *x,int *y){
	char s[999];
	if(!fgets(s,999,stdin))return false;
	*b=strtol(strtok(s,","),NULL,10);
	*x=strtol(strtok(NULL,","),NULL,*b);
	*y=strtol(strtok(NULL,","),NULL,*b);
	return true;
}

bool chk(int n,int b){
	div_t x,y;
	x=div(n,b);
	for(;x.quot;){
		y=div(x.quot,b);
		if(y.rem!=x.rem && (y.rem+1)%b!=x.rem)return false;
		x=y;
	}
	return true;
}

int main(){
	int b,x,y;
	for(;get(&b,&x,&y);){
		if(b==2){
			printf("%d\n",y-x+1);
		}else{
			int num_threads=std::thread::hardware_concurrency();
			auto f=[&](int start)->int{
				int r=0;
				for(int j=x+start;j<=y;j+=num_threads){
					r+=chk(j,b);
				}
				return r;
			};
			std::vector<std::future<int>>task;
			for(int i=1;i<num_threads;i++)task.push_back(std::async(std::launch::async,f,i));
			int r=f(0);
			for(auto &t:task)r+=t.get();
			printf("%d\n",r);
		}
		fflush(stdout);
	}
}
```
Non-exhaustive enum/struct

Rust RFC 2008で規定されている`#[non_exhaustive]`属性について簡単に解説します

- RFC 2008: https://github.com/rust-lang/rfcs/blob/master/text/2008-non-exhaustive.md
- Rust Issue: https://github.com/rust-lang/rust/issues/44109
- Unstable book: https://doc.rust-lang.org/unstable-book/language-features/non-exhaustive.html

~~この内容は安定化されておらずnightlyでしか使えません~~ 1.40 (2019/12/20) で安定化されています

Motivation
-----
ライブラリを設計するとき、実装が進むにつれて新たにエラーを定義する必要が出てきます。Rustではエラーを扱うのに主にenumを使いますが、この要素は将来増える可能性があります。例えば`std::io::ErrorKind`を見てみましょう

```rust
pub enum ErrorKind {
    NotFound,
    PermissionDenied,
    ConnectionRefused,
    ConnectionReset,
    ConnectionAborted,
    NotConnected,
    AddrInUse,
    AddrNotAvailable,
    BrokenPipe,
    AlreadyExists,
    WouldBlock,
    InvalidInput,
    InvalidData,
    TimedOut,
    WriteZero,
    Interrupted,
    Other,
    UnexpectedEof,
    // some variants omitted
}
```

このエラーをハンドリングするために次のような`match`文を書いたとします

```rust
use std::io::ErrorKind::*;

match error_kind {
    NotFound => ...,
    PermissionDenied => ...,
    ConnectionRefused => ...,
    ConnectionReset => ...,
    ConnectionAborted => ...,
    NotConnected => ...,
    AddrInUse => ...,
    AddrNotAvailable => ...,
    BrokenPipe => ...,
    AlreadyExists => ...,
    WouldBlock => ...,
    InvalidInput => ...,
    InvalidData => ...,
    TimedOut => ...,
    WriteZero => ...,
    Interrupted => ...,
    Other => ...,
    UnexpectedEof => ...,
}
```

これは実装した段階では動きますが、将来`ErrorKind`に新たなエラーが追加されたときに正しくハンドリングできなくなります。しかし

```rust
match error_kind {
    // ...
    _ => ...,
}
```

のように`_`ブランチが用意されていれば将来にわたって正しく動作することが期待できます。

`non_exhaustive` attribute
----------------------------

現在ではこの問題に対処するために、例えば`diesel::error::Error`はライブラリレベルで次のような方法をとっています：

```rust
pub enum Error {
    InvalidCString(NulError),
    DatabaseError(String),
    NotFound,
    QueryBuilderError(Box<StdError+Send+Sync>),
    DeserializationError(Box<StdError+Send+Sync>),
    #[doc(hidden)]
    __Nonexhaustive,
}
```

このように隠された要素を追加することによって、`__Nonexhaustive`が見える範囲では網羅的なマッチが可能で、それより外では網羅的なマッチを禁止しています。

これを簡単に実現するのが`non_exhaustive`属性です

```rust
#[non_exhaustive]
pub enum Error {
    Message(String),
    Other,
}
```

のように定義することで、このenumが定義されたcrate内では網羅的なマッチが可能となり、外からは

```rust
use mycrate::Error;

match error {
    Message(ref s) => ...,
    Other => ...,
    _ => ...,
}
```

のようにアクセスする必要があります。

特に述べませんが、structのマッチにおいても同様の問題が発生するため、`non_exhaustive`属性はstructに対しても適用できます。
Pythonでオプション付きのコマンドを作成する(argparse)

## 概要
pythonでオプション付きのコマンドを作成する方法。
argparseというモジュールを使います。

## 関連記事
- [シェルスクリプトでオプション付きのコマンドを作成する](https://qiita.com/Esfahan/items/e88bb806c7ca1dc8b758)
- [Pythonでシェルコマンドを実行する](https://qiita.com/Esfahan/items/e33aa8daf39a2c883eb4#python%E3%81%A7%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B)

## pythonスクリプトを作成
sampleというファイル名で作成する。

```py:sample
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import argparse

'''
引数の定義
-a, -bは必須
-c, -dは任意
'''
def get_args():
    psr = argparse.ArgumentParser()
    psr.add_argument('-a', '--alpha', required=True, help='A explanation for arg called a')
    psr.add_argument('-b', '--bravo', required=True, help='A explanation for arg called b')
    psr.add_argument('-c', '--charlie', help='A explanation for arg called c')
    psr.add_argument('-d', '--delta', help='A explanation for arg called d')

    return psr.parse_args()

if __name__ == '__main__':
    args = get_args()

    print(args.alpha)
    print(args.bravo)
    print(args.charlie)
    print(args.delta)
```

## help
`--help`もしくは`-h`を指定する。

```shell-session
$ ./sample  --help
usage: sample [-h] -a ALPHA -b BRAVO [-c CHARLIE] [-d DELTA]

optional arguments:
  -h, --help            show this help message and exit
  -a ALPHA, --alpha ALPHA
                        A explanation for arg called a
  -b BRAVO, --bravo BRAVO
                        A explanation for arg called b
  -c CHARLIE, --charlie CHARLIE
                        A explanation for arg called c
  -d DELTA, --delta DELTA
                        A explanation for arg called d
```

必須オプションである`-a`, `-b`を指定しないとエラーとなる。

```shell-session
$ ./sample
usage: sample [-h] -a ALPHA -b BRAVO [-c CHARLIE] [-d DELTA]
sample: error: argument -a/--alpha is required
```

## 実行例
オプションを全て付与して実行する。

```shell-session
$ ./sample -a sample001 -b sample002 -c sample003 -d sample004
sample001
sample002
sample003
sample004
```

オプションは順不同。

```shell-session
$ ./sample -c sample003 -d sample004 -b sample002 -a sample001
sample001
sample002
sample003
sample004
```

必須オプションのみ指定。

```shell-session
$ ./sample -a sample001 -b sample002
sample001
sample002
None
None
```

`--alpha`は`-a`, `--bravo`は`-b`、`--charlie`は`-c`、`--delta`は`-d`と同義。

```shell-session
$ ./sample --alpha sample001 --bravo sample002 --charlie sample003 --delta sample004
sample001
sample002
sample003
sample004
```
AEExpression　メモ　トランジション

#トランジションエクスプレッション
シェイプレイヤーに長方形を作成

>ControlLayerでkeyのタイミングだけ打っておく。

>シェイプレイヤーにはいくつかのエクスプレッション制御を追加
・X Min
・X Max
・Y Min
・Y Max
・Delay Max
・Randomize Animation

#エクスプレッション

長方形パス　サイズ

```jsx
myNum = thisProperty.propertyIndex;
xmin = effect("X Min")("スライダー");
xmax = effect("X Max")("スライダー");
ymin = effect("Y Min")("スライダー");
ymax = effect("Y Max")("スライダー");
seedRandom(myNum,true);
x = Math.floor( random() * (xmax - xmin) ) + xmin;
y = Math.floor( random() * (ymax - ymin) ) + ymin;

[x,y]+content(thisProperty.propertyGroup(1).propertyIndex).size;
```

長方形パス位置

```jsx
rs = content(thisProperty.propertyGroup(1).propertyIndex).size; //Rect Size
myNum = thisProperty.propertyIndex; // My Index Num
cw = thisComp.width; // composition width
ch = thisComp.height; // composition height
xmin = -cw/2;
xmax = cw/2;
ymin = -ch/2;
ymax = ch;
seedRandom(myNum*effect("Randomize Animation")("スライダー"),true);
x = Math.floor( random() * (xmax - xmin) ) + xmin;
y = Math.floor( random() * (ymax - ymin) ) + ymin;

tf = random() >= 0.5;
if (tf == true){
inp = [x,y]+[content(thisProperty.propertyGroup(1).propertyIndex).position[0],rs[1]+ch];
enp  = [x,y]+content(thisProperty.propertyGroup(1).propertyIndex).position;
}else{
inp = -[x,y]-[content(thisProperty.propertyGroup(1).propertyIndex).position[0],rs[1]+ch];
enp  = -[x,y]-content(thisProperty.propertyGroup(1).propertyIndex).position;
}


//moving
delay = random() * (effect("Delay Max")("スライダー") - 0)+0 ;
target = thisComp.layer("Control Layer").effect("スライダー制御")("スライダー")
linear(target.valueAtTime(time-delay),target.key(1),target.key(2),inp,enp);
```

#最終調整
あとは長方形パスを複製して、サイズと位置が気に入らなければvalueで修正する

![bandicam 2019-03-09 17-51-03-705.jpg](https://qiita-image-store.s3.amazonaws.com/0/178061/93d3589a-f896-f807-e9f2-80b59d8180ee.jpeg)
truffle migrate が出来ずに Error: Returned values aren't valid, did it run Out of Gas? が返ってくる？

簡単なdemoであるpetShopを`truffle compile`して`truffle migrate`出来たのに
exit後に再度マイグレートするとエラー`Error: Returned values aren't valid, did it run Out of Gas?`になってしまう。

そもそもdockeにコンテナを作成してそこから`ganache`にアクセスしているとexitする度に再度マイグレートしないといけないと言われているのに`truffle migrate`出来ないとは何事ぞ。

調べると`truffle migrate --reset`で反映された。
どうもバグであるらしい。

https://github.com/ethereum/web3.js/issues/1916#issuecomment-427398031
シェルスクリプトでオプション付きのコマンドを作成する

## 概要
シェルスクリプトでオプション付きのコマンドを作成する方法。

## 関連記事
- [Pythonでオプション付きのコマンドを作成する(argparse)](https://qiita.com/Esfahan/items/72b3c34d744eaaea6c93)

## シェルスクリプトを作成
sampleという名前でファイルを作成する

```
$ vi sample
```

シェルスクリプトを作成

```bash:sample
#!/bin/bash
# helpを作成
function usage {
  cat <<EOM
Usage: $(basename "$0") [OPTION]...
  -h          Display help
  -a VALUE    A explanation for arg called a
  -b VALUE    A explanation for arg called b
  -c VALUE    A explanation for arg called c
  -d VALUE    A explanation for arg called d
EOM

  exit 2
}

# 引数別の処理定義
while getopts ":a:b:c:d:h" optKey; do
  case "$optKey" in
    a)
      echo "-a = ${OPTARG}"
      ;;
    b)
      echo "-b = ${OPTARG}"
      ;;
    c)
      echo "-c = ${OPTARG}"
      ;;
    d)
      echo "-d = ${OPTARG}"
      ;;
    '-h'|'--help'|* )
      usage
      ;;
  esac
done
```

実行権限を付与

```
$ chmod u+x sample
```

## 実行例

```shell-session
$ ./sample -a sample001
-a = sample001

$ ./sample -b sample002
-b = sample002

$ ./sample -c sample003
-c = sample003

$ ./sample -d sample004
-d = sample004

$ ./sample -a sample001 -b sample002 -c sample003 -d sample004
-a = sample001
-b = sample002
-c = sample003
-d = sample004

$ ./sample -d sample004 -a sample001 -c sample003
-d = sample004
-a = sample001
-c = sample003
```

`-h`もしくは、存在しないオプションを付与した場合は、helpが表示される。

```shell-session
$ ./sample -h
Usage: sample [OPTION]...
  -h          display help
  -a VALUE    a explanation for arg called a
  -b VALUE    a explanation for arg called b
  -c VALUE    a explanation for arg called c
  -d VALUE    a explanation for arg called d

$ ./sample -z sample999
Usage: sample [OPTION]...
  -h          display help
  -a VALUE    a explanation for arg called a
  -b VALUE    a explanation for arg called b
  -c VALUE    a explanation for arg called c
  -d VALUE    a explanation for arg called d
```


## パスワードプロンプト

```bash:sample.sh
#!/bin/bash
# 入力時に表示される
read -p "username: " USERNAME
echo $USERNAME

# 入力時に表示されない
read -sp "Password: " PASSWORD
echo 
# 入力した文字列を表示
echo $PASSWORD
```

実行

```bash
$ bash sample.sh
username: my_user
my_user # 入力した文字列
Password: ### 入力する ###
my_pasword # 入力した文字列
```
CarrierWave, RMagickを使ってRailsで画像を投稿できるようにする。

#環境
mac OS 10.14.3
Ruby 2.4.1
Ruby on Rails 5.2.2
#やりたいこと
Railsで画像を投稿したい！
#使用ライブラリ
CarrierWave
RMagick
#手順
### 1. Gemfile にgemを挿入し、インストール。
```:Gemfile
（省略）
gem 'carrierwave'
gem 'rmagick'
```
```
$ bundle install
```
### 2. config/locales/application.rb におまじないを書き込む。
```ruby:application.rb
module Workspace
  class Application < Rails::Application
.省略
.
.
#おまじない開始
    config.autoload_paths += Dir[Rails.root.join('app', 'uploaders')]
#おまじない終わり
  end
end
```
### 3. アップロードファイルを作成。(ファイル名は任意)

```
$ rails g uploader image
```
### 4. uploaders/image_uploader.rb に画像のサイズ等を指定するメソッドを書き込む。
```ruby:image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base

(省略)

# サムネイルを生成する設定
  version :thumb do
    process :resize_to_limit => [300, 300]
  end

#画像が回転してしまう問題を解消
   process :fix_rotate

  def fix_rotate
      manipulate! do |img|
          img = img.auto_orient
          img = yield(img) if block_given?
          img
      end
  end

#画像サイズの大きさを制限
  def size_range
    1..5.megabytes
  end

(省略)

end
```
[画像加工についてもっと詳しく知りたい方はこちら！](https://pg-happy.jp/carrierwave-rmagic-uploader.html)

### 5. ユーザーモデル(モデル名,カラム名は任意)を生成し、モデルを関連付ける。
```
$ rails g model User image:string
$ rails db:migrate
```
```ruby:user.rb
mount_uploader :image（⬅︎上記で生成したカラム名）, ImageUploader（⬅︎３で生成したアップローダーの名前Uploader）
```

###6. ルーティング、ビュー、コントローラの部分を作成。
```ruby:routes.rb
root to: "users#index"
get "/new", to: "users#new"
post "/create", to: "users#create"
```
```ruby:users_controller.rb
def index
  @users = User.all
end

def new
end

def create
  User.create(image:params["users"]["image"])
  redirect_to "/"
end
```
```html:new.html.erb
<%= form_tag("/create",:multipart => true) do %>
  <%= label_tag "form-image", "画像" %>
  <%= file_field :users, :image, id:"form-image" %>
  <%= submit_tag "新規作成"%>
<% end %>
```
```html:index.html.erb
<% @users.each do |u| %>
  <%= u.image %>
<% end %>
```

#完成！！(注意)
これでRailsで画像投稿ができるようになりました！！

ただし、デプロイ後はAWS S3のような画像ストレージサービスに登録しないと、画像が表示できなくなるので要注意です！

# 参照
[CarrierWaveとrmagickで画像アップロード機能を作る](https://pg-happy.jp/carrierwave-rmagic-uploader.html)
[Rails で画像のアップロード機能を実装する](https://numb86-tech.hatenablog.com/entry/2018/08/18/114948)
[railsでcarrierwaveを使って画像をアップロード、表示](https://qiita.com/Inp/items/cc447237e23bf10d159e)
[Carrierwaveでアップロードした画像が回転して表示されてしまう問題を解決する](https://paranishian.hateblo.jp/entry/2015/09/29/093139)
[carrierwaveを利用して画像をアップロードしたがDBに保存されない](https://teratail.com/questions/56248)
Go言語の異常処理

Goの中ではtry catchがないです。
異常処理には、defer,panic,recoverで制御します。

#defer
deferを実行した関数がリターンする直前に、指定した関数の呼び出しが行われるようにスケジューリングします
逆順で実行する流れです。

例：

```go

func main() {
	printNum()
}

func printNum() {
	for i := 0; i < 5; i++ {
		fmt.Println("数字：", i)
		defer fmt.Println("defer:", i)
	}
}
```

出力：
>数字： 0
数字： 1
数字： 2
数字： 3
数字： 4
defer: 4
defer: 3
defer: 2
defer: 1
defer: 0

#panic
panicを発生すると、その以降の処理は行わないです。
例：

```go

func main() {

	fmt.Println("Go begin")

	defer fmt.Println("defer処理")

	fmt.Println("ロジック処理 begin")
	printNum()
	fmt.Println("ロジック処理 end")

	fmt.Println("Go end")
}

func printNum() {

	for i := 0; i < 5; i++ {
		fmt.Println("数字：", i)
		if i == 2 {
			panic("三番目に異常が発生しました。")
		}
	}
}
```

出力：
>Go begin
ロジック処理 begin
数字： 0
数字： 1
数字： 2
defer処理
panic: 三番目に異常が発生しました。
goroutine 1 [running]:
main.printNum()

出力の通り、異常発生してもdefer部分が実行されます。


#recover
recoverを呼び出すと、巻き戻しを停止し、panicに渡された引数が返ります

例：

```go

func main() {

	fmt.Println("Go begin")

	defer func() {
		if err := recover(); err != nil {
			fmt.Println("defer エラー:", err)
			fmt.Println("defer エラーが発生したため、ロジック処理は終了")
		}
	}()

	fmt.Println("ロジック処理 begin")
	printNum()
	fmt.Println("ロジック処理 end")

	fmt.Println("Go end")
}

func printNum() {

	for i := 0; i < 5; i++ {
		fmt.Println("数字：", i)
		if i == 2 {
			panic("三番目に異常が発生しました。")
		}
	}
}
```

出力：
>Go begin
ロジック処理 begin
数字： 0
数字： 1
数字： 2
defer エラー: 三番目に異常が発生しました。
defer エラーが発生したため、ロジック処理は終了


以上
Windows10でWiiリモコンをbluetoothで追加しようとすると確認コードを求められた

Windows10でWiiリモコンをbluetoothで追加しようとすると、確認コードを聞かれることがありません。
でも、そんなものはありません。

そういったとき、おそらくはUWPでできた設定画面からbluetoothの設定を開いているのが原因です。

Windows7ライクなコンパネから追加してあげてください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245977/ba7053f9-fd76-8d57-6ae8-605a6c252426.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/245977/4ffd758e-3671-d180-4aa9-9b40fc50faf9.png)
rex0220 計算式プラグインとカレンダーPlus 連携


計算式プラグインとカレンダーPlus の連携対応例です。
カレンダーPlus の追加・変更・複製イベントで、計算式プラグインの計算処理を実行してレコードに反映させます。

# 関連

[ラジカルブリッジ様カレンダーPlus](https://radical-bridge.com/product/calendarPlus.html)

# 操作例

タイトル省略時に、「初期タイトル」を自動設定します。

![2019-03-09_17h32_41.gif](https://qiita-image-store.s3.amazonaws.com/0/100572/2bdda93a-ea79-cc3b-f9cf-18ce3657a3c2.gif)


# 計算式プラグイン設定

- 「循環参照を許可」
- タイトル：NVL(タイトル,"初期タイトル")
    - 「編集」をチェック


※ NVL関数は、空文字以外のパラメータがあれば、その値を返します。


<img width="993" alt="2019-03-09_17h26_12.png" src="https://qiita-image-store.s3.amazonaws.com/0/100572/600266fe-e77f-0d49-9505-4e49a1fcdd94.png">


# 注意事項

計算式プラグインとカレンダーPlus 連携に対応するのは、下記バージョンになります。

- 計算式プラグインは、 Ver.24 以降
- カレンダーPlus は、バージョン9 以降
xiaomi mi5でAndroidのアップデートで起きたときに「This Package is gemini for device: gemini」と怒られた

```
This Package is gemini for device: gemini
```
いや、mi5=geminiなのですが。
>>TWRPのバージョンが古かったのが原因でした。

#Ref
https://www.reddit.com/r/LineageOS/comments/825pfy/error_this_package_is_for_device_gemini/
macOS アップグレード時に覚えておく環境設定の個人メモ（追記中）

## OS X を久しぶりにアップグレード（Mavericksからmojave）したらすっかり忘れていた環境設定方法をメモしておく。必要に応じて追記予定。

### 1. macOS すっかり忘れていた隠しファイルの表示方法
#### キーボードショートカット「Command」キー＋「Shift」キー＋「 . 」（ピリオド）を入力すると、不可視ファイルや不可視フォルダが表示される。
【HTTPリクエスト】GETとPOSTの違いって何なの？

#1. はじめに
私は現在、業務未経験からエンジニアを目指して転職活動中です。先日面接させていただいた、とある会社で「HTTPにおけるGETとPOSTの違いを説明してください。」という質問にスムーズに答えられなかったので、GETとPOSTの違いについてまとめてみました。
ちなみにその時は、「POSTはデータベースを操作するリクエストで、GETはデータベースの操作を伴わないリクエストです」とお茶を濁し、面接担当者からは「半分正解だね」との苦し紛れの評価をいただいたのですが、改めて調べてみると、全然違ったので絶望しているところです。

#2. 結論
まず結論から書いてしまうと、GETとPOSTはどちらもフォームなどに入力したデータをWebサーバーへ送ることのメソッドだが、その送信方法が異なる。（つまり僕の回答はダメダメだった！！）

- **GET: URLの後ろにデータを付与して送る**
- **POST: HTTPリクエスト内のメッセージボディにデータを含めて送る**

つまり、GETメソッドでデータを送る際には、URLにデータが付与されているため、送ったデータがブラウザの閲覧履歴に残ってしまう。一方で、POSTメソッドを利用する際は、メッセージボディ内にデータが組み込まれるため、閲覧履歴は残らない。

#3. もう少し詳しく
結論だけ読めば、GETとPOSTの違いがわかるが、「HTTPリクエスト？、メッセージボディってなに…？」っていう僕のような人に向けてもう少し詳しく解説してみる。
##3-1. HTTPの基本動作
HTTPは、「クライアント（Webブラウザ）からの要求」と「サーバーからの応答」というやりとりを行い、Webサイトの閲覧などを行うことができる。この時の、「クライアントからの要求」を**HTTPリクエスト**、「サーバーからの応答」を**HTTPレスポンス**と呼ぶ。

##3-2. HTTPメッセージ（リクエスト）の構成
|開始行|
|:--:|
|メッセージヘッダー（ブラウザの種類やデータタイプなどを伝える）|
|空行（メッセージヘッダーの終わりを伝える|
|メッセージボディ（サーバーにデータを送るために使われる）|

##3-3. GETとPOSTのデータ送信方法
会員サイトへのログイン時を例に取るとユーザー名：Mr.hoge、パスワードをhoge123とした場合、GETとPOSTのデータ送信方法は以下の通り。

```
開始行｜ GET /login.html?name=Mr.hoge&pass=hoge123
```

```
開始行｜POST /login.html HTTP/◯◯（version)
メッセージボディ｜ name=Mr.hoge&hoge123
```
上記の通り、GETメソッドの場合、URLにユーザー名とパスワードが含まれ、それがそのままブラウザの閲覧履歴に残ってしまい、危険。パスワードや氏名、住所などの個人情報をサーバーに送る際は、POSTメソッドを使う。

#終わりに
先日の面接では、「オブジェクト指向について説明してください」という質問にもまったく対応できなかったので、次回はオブジェクト指向とはなんぞやについて自分なりにまとめてみようと思います。先日の面接はボロボロでしたが、この記事が、僕のような業務未経験のエンジニア志望の方に少しでも役立つと嬉しいです。
ここまで読んでいただきありがとうございます。間違い等ありましたら、ご指摘いただけると幸いです！
メモ：flutterで自動的に閉じるシンプルなoverlay dialogをだす

* シンプルでいいけど、animationでぬるっと出てきて自動的に閉じてくれるoverlayな表示を出すための実装。

# overlay dialog widgetの実装
* ぶっちゃけこちらの方が紹介しているoverlayのコードをほぼ使った。
    * [dart - Flutter custom animated dialog - Stack Overflow](https://stackoverflow.com/questions/52408610/flutter-custom-animated-dialog)
- 以下がwidgetのコード。

```:overlay_dialog.dart
import 'package:flutter/material.dart';

class OverlayDialog extends StatefulWidget {
  OverlayDialog({Key key, this.message}):super(key:key);

  final String message;

  @override
  State<StatefulWidget> createState() => OverlayDialogState();
}

class OverlayDialogState extends State<OverlayDialog>
    with SingleTickerProviderStateMixin {
  AnimationController controller;
  Animation<double> opacityAnimation;
  Animation<double> scaleAnimatoin;

  @override
  void initState() {
    super.initState();

    controller =
        AnimationController(vsync: this, duration: Duration(milliseconds: 450));
    opacityAnimation = Tween<double>(begin: 0.0, end: 0.4).animate(
        CurvedAnimation(parent: controller, curve: Curves.fastOutSlowIn));
    scaleAnimatoin =
        CurvedAnimation(parent: controller, curve: Curves.elasticInOut);

    controller.addListener(() {
      setState(() {});
    });

    controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      color: Colors.black.withOpacity(opacityAnimation.value),
      child: Center(
        child: ScaleTransition(
          scale: scaleAnimatoin,
          child: Container(
            decoration: ShapeDecoration(
                color: Colors.white,
                shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(15.0))),
            child: Padding(
              padding: const EdgeInsets.all(50.0),
              child: Text(widget.message),
            ),
          ),
        ),
      ),
    );
  }
}

```

# widgetのopen/closeの実装
- overlay dialog wigetを開き、１秒後に閉じるコード。今回はボタンをおした時にoverlay表示を出すので、onPressedのfunctionに入れてある。

```
  void _onPressed() {
    setState(() {
      var _overlayEntry = OverlayEntry(
        builder: (BuildContext context) {
          return OverlayDialog(message: "open!");
        },
      );
      Navigator.of(context).overlay.insert(_overlayEntry);
      Timer(Duration(seconds: 1), () => _overlayEntry.remove());
    });
  }

```
vscodeでndenv使おうとしたらバージョンが切り替わらなかった場合にやる事

macのターミナルからだと問題無いのに、vscodeのターミナルからだとndenvで入れたnodeを見てくれない。
~/.bash_profileに下記を追記する。

```
for D in `ls $HOME/.ndenv/shims`
do
  export PATH="$HOME/.ndenv/shims:$PATH"
done
```

そして

```
$ source ~/.bash_profile
```

下記vscodeのターミナルから実行してバージョンが表示されればOK。（nodeのバージョンはご自由に）

```
$ ndenv local v11.10.1
$ node -v
```

# 参考
https://dev.classmethod.jp/tool/anyenv-set-path-for-visual-studio-code/