OmniAICreator/Qiita-1.07M huggingface dataset:
Azure Cognitive Face API エラー「Rate limit is exceeded. Try again later.」

そのままの意味ですが、次のエラーが出ることがあります。

```
status_code: 429
code: RateLimitExceeded
message: Rate limit is exceeded. Try again later.
```

現時点でFace APIの無料Tierだと、２０回 / 分を超えるとこのエラーになります。
３秒に１回ですね。きっつー。

その場合はsleep()で処理待ちするか、有料版を検討しましょう。
特定のディレクトリにある画像ファイルをDBに一括アップロードする


##やりたいこと
画像データをファイルで管理していたが、ELBの構成の関係でDBに上げる必要が出た為、バイナリデータで一括アップロードをしたい。

実はこれは作ってもらったソースである事は内緒である。

頻繁ではないけど、何かと使うことがある機会があるソースかもしれなくて、役に立てればいいなぁと思ったので公開します。

###条件

- バイナリデータである事
- IDと紐付いていること

###ディレクトリ構造
/public/uploads/items/以下はIDの中に連番で画像が格納されていた。

``` 
/public/uploads/items/{ID}/jpeg/1.jpg
/public/uploads/items/{ID}/jpeg/2.jpg
```

###テーブル構造


``` sql
CREATE TABLE `images` (
  `image_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `id` int(5) unsigned NOT NULL,
  `image` longblob NOT NULL,
  `image_name` varchar(255) NOT NULL DEFAULT '',
  `image_alt` varchar(100) DEFAULT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`image_id`),
) ENGINE=InnoDB AUTO_INCREMENT=466 DEFAULT CHARSET=utf8;
``` 

## 完成ソース
実際に使用したソースは以下の通り

``` import-images.php

function filterOutCurrentDirectory($fileNames) {
    return array_filter($fileNames, function ($dirName) {
        return !in_array($dirName, ['.', '..', '.DS_Store'], true);
    });
}


$dirs = scandir('../public/uploads/items');

$facilityIdList = filterOutCurrentDirectory($dirs);

$imageFileNames = array_map(function ($id) {
    $names = scandir(sprintf('../public/uploads/items/%d/jpeg', $id));

    $filteredFileNames = filterOutCurrentDirectory($names);

    return [
      'id' => $id,
      'file_names' => $filteredFileNames
    ];
}, $facilityIdList);

$imageFullPathList = array_reduce($imageFileNames, function ($acc, $id) {
    $id = $id['id'];

    $pathList = array_map(function ($path) use ($facilityId) {
        return sprintf('../public/uploads/items/%d/jpeg/%s', $id, $path);
    }, $item['file_names']);

    return array_merge($acc, $pathList);
}, []);

print_r($imageFullPathList);

foreach ($imageFullPathList as $fullPath) {
    $user = "user";
    $pass = "admin";

    $pdo  = new PDO("mysql:host=127.0.0.1;dbname=database;charset=utf8", $user, $pass);

    $sql  = "INSERT INTO images( id, image, image_name) VALUES (:id, :image, :image_name);";
    $stmt = $pdo->prepare($sql);
    $stmt->bindValue(":id", explode('/', $fullPath)[4], PDO::PARAM_STR);
    $stmt->bindValue(":image", 'data:image/jpeg;base64,' . base64_encode(file_get_contents($fullPath)), PDO::PARAM_STR);
    //     $stmt->bindValue(":image_name", (new Hashids())->encode(basename($fullPath)), PDO::PARAM_STR);
    $stmt->bindValue(":image_name", basename($fullPath), PDO::PARAM_STR);

    $stmt->execute();
}

```
else if とは何か

社内で、人のプルリクを眺めていたら、新人と2年目との、不思議なやりとりがあった。

元々、こんなコードがあった。

```c:もともと
if (isHoge()) {
    foo = something_value;
} else {
    foo = another_value;
}
```

別の方法でもfooを指定できるように改造することになったため、新人は以下のようなコードを書いた。

```c:新人くんのコード
if (isGuruguru()) {
    foo = guruguru_value;
} else {
    if (isHoge()) {
        foo = something_value;
    } else {
        foo = another_value;
    }
}
```

そこに、2年目くんから「元々の処理を変更しない方がいい。ネストを深くしない方がいい」という物言いがついて、コードはこのように変更された。

```c:修正後コード
if (isHoge())) {
    foo = something_value;
} else {
    foo = another_value;
}
if (isGuruguru()) {
    foo = guruguru_value;
}
```

これはものすごくよくない。
今回のやりとりを知らずに、このソースを見た人は、`isGuruguru`の部分だけを追いたかったとしても、関係ないところ読まされる上に「なんか、fooを2回代入してるけど、これ意味あんのかなぁ?」という疑問を抱きながら生きることになる。そういった人生を他人に送らせるべきではない。

最初に新人が書いたコードだが、gitのdiffで見ると、とてつもなく複雑な変更を加えているように見える。

```diff:gitのdiff
-if (isHoge()) {
-    foo = something_value;
+if (isGuruguru()) {
+    foo = guruguru_value;
 } else {
-    foo = another_value;
+    if (isHoge()) {
+        foo = something_value;
+    } else {
+        foo = another_value;
+    }
 }
```

けれど、よくよく見ると、これは新たにif else構文を1個付け加えて、元あったコードをelse節にぶちこんでるだけだ。
これは `git diff -w` のように、`-w` オプションを付けてdiffを取ると分かりやすい。

```diff:wオプションを付けてdiff
+if (isGuruguru()) {
+    foo = guruguru_value;
+} else {
     if (isHoge()) {
         foo = something_value;
     } else {
         foo = another_value;
     }
+}
```

ところで、C言語の規格書には`else if`構文はない、という話を聞いたことがあるだろうか。
http://kikakurui.com/x3/X3010-2003-01.html より、規格を引用する。

>6.8.4 選択文 
構文規則
　　　　　選択文：
  　　　　　　　　if　(　式　)　　文
 　　 　　　　　　if　(　式　)　　文　　else　　文
 　　 　　　　　　switch　　(　式　)　　文
意味規則  選択文は，制御式の値に応じて幾つかの文の中から一つを選択する。
選択文はブロックとする。そのブロックの有効範囲は，それを囲むブロックの有効範囲の真部分集合とする。各副文もブロックとする。そのブロックの有効範囲は，選択文の有効範囲の真部分集合とする。
6.8.4.1 if 文 
制約  if 文の制御式は，スカラ型をもたなければならない。
意味規則  両形式とも，式の値が 0 と比較して等しくない場合，最初の副文を実行する。else 形式の場合，式の値が 0 と比較して等しいならば，2 番目の副文を実行する。ラベルを通して最初の副文に制御が到達した場合，2 番目の副文は実行しない。
　elseは，構文規則で許される if のうち，その else の前で最も近い位置にある if と結び付く。
6.8.4.2 switch 文
...


見て分かる通り、`else if`という構文はない。では、C言語で`else if`を書くとコンパイルエラーになるのか。いいや、ならない。
C言語においては`else if`とは、`if (式) 文 else 文` の、二つ目の「文」に、別の`if`文を持ってきているものとみなされる。
文は `{}`で囲うことができるので、例えば

```:else-if
if (式) 文
else if (式) 文
else 文
```

は、こう書くこともできる。

```:else-ifはこういう意味
if (式) 文
else {
    if (式) 文
    else 文
}
```

つまり、この2つの書き方は等価なのだ。

これはあくまでC言語の話で、例えばPythonなどでは、

```:Python_書けない例
if 式:
    文
else: if 式:
    文
```

のような書き方はできず `elif` といったキーワードが必要になるが、`else`の中に`if`文だけを書くのと、`if...elif...else`構文を使うのが等価であることには変わらない。

```:elseのネストで書く
if 式:
    文
else:
    if 式:
        文
    else:
        文
```

```:elifを使った、上と等価なコード
if 式:
    文
elif 式:
    文
else:
    文
```

`elif`を使った方が断然見やすい。

ところで、話を元に戻そう。
新人が書いたコードを見てほしい。

```c:再掲・新人くんのコード
if (isGuruguru()) {
    foo = guruguru_value;
} else {
    if (isHoge()) {
        foo = something_value;
    } else {
        foo = another_value;
    }
}
```

あ、`else` の中に `if`文が入ってる！
なので、これはこのように書ける。

```c:else-ifで書き直した
if (isGuruguru()) {
    foo = guruguru_value;
} else if (isHoge()) {
    foo = something_value;
} else {
    foo = another_value;
}
```
新たにファイルシステムを追加(増設)する

## <INS>ファイルシステムのリストを閲覧

```Bash
$ df -h
Filesystem                     Size  Used Avail Use% Mounted on
udev                           7.9G     0  7.9G   0% /dev
tmpfs                          1.6G  8.7M  1.6G   1% /run
/dev/mapper/ubuntu14--vg-root   16G   15G  116M 100% /
tmpfs                          7.9G     0  7.9G   0% /dev/shm
tmpfs                          5.0M     0  5.0M   0% /run/lock
tmpfs                          7.9G     0  7.9G   0% /sys/fs/cgroup
/dev/sda1                      236M  147M   77M  66% /boot
cgmfs                          100K     0  100K   0% /run/cgmanager/fs
tmpfs                          1.6G     0  1.6G   0% /run/user/1002
```

ここに新たなファイルシステムを追加マウントする。

## <INS>ブロックデバイスのリストを閲覧

```Bash
$ lsblk
NAME                    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sdb                       8:16   0   16G  0 disk
sr0                      11:0    1 1024M  0 rom
fd0                       2:0    1    4K  0 disk
sda                       8:0    0   32G  0 disk
├─sda2                    8:2    0    1K  0 part
├─sda5                    8:5    0 31.8G  0 part
│ ├─ubuntu14--vg-swap_1 253:1    0   16G  0 lvm  [SWAP]
│ └─ubuntu14--vg-root   253:0    0 15.8G  0 lvm  /
└─sda1                    8:1    0  243M  0 part /boot
```

ここにあるsdbというブロックデバイスをマウントすることを目標とする。

## <INS>ファイルシステム作成

lsblkの結果にsdbが存在するということは/dev/sdbが存在するということ。
この/dev/sdbにはまだファイルシステムが定義されていないため、ファイルシステムを作成する。

```Bash
$ sudo mkfs.ext4 /dev/sdb
mke2fs 1.42.13 (17-May-2015)
Creating filesystem with 4194304 4k blocks and 1048576 inodes
Filesystem UUID: e16b1a92-3bba-4560-b931-08aa7564b142
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
        4096000

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
```

## <INS>マウント

```Bash
$ sudo mkdir -p /mnt/sdb
$ sudo mount /dev/sdb /mnt/sdb
```

## <INS>中身を見てみる

```Bash
$ ls /mnt/sdb
lost+found
```

このlost+foundというディレクトリは、fsckというファイルの整合性をチェックするコマンドで作成され、ファイル同士の対応関係が崩れてしまったファイルが保存されている。

今回はこの中身は空であるため、削除する。

```Bash
$ sudo rm -rf /mnt/sdb/lost+found
```
自分メモ　AWSその２ IAM編（１）

# この記事の対象者
AWSでIAMユーザを割り当てられて手順通り管理したり、
初心者用の本読んだりしたけど、イマイチ理解できていない人が
いきなりAWSのアカウントを作成して、四苦八苦しながら
検証や勉強の環境を作っているライブ配信を見たい人
＊ただし更新はリアルタイムではないので注意
＊Markdownも慣れていないので読みにくいと思うけど我慢できる人

# その1でやったこと
アカウントを作っていきなり戸惑ったこと。
最初にやること（IAMでサインインリンクを作成）

# その２の内容
ルートユーザーではない管理用IAMユーザーを作成

# 今更ですがそもそもIAMユーザーって何？
あなたのAWSクラウド領域の管理コンソールにサインインできるユーザーのこと。
決して、「EC2サーバーにログインするためのユーザー」とか、「WorkSpacesにログインするためのユーザー」ではないので注意です。

# 管理者用IAMユーザーを作成
IAMメニューに行きます。
わかりにくいのは「ロール」「ポリシー」ですね。
（IDプロバイダはこの際無視）

## ユーザーを作る前にまずやること
パスワードポリシー、つまり、「パスワードは何文字以上」だとか、複雑性だとか、そういうやつです。
通常はそれほど気にしなくてよいですが、気にする方は先に設定しましょう。

## グループとユーザー
これは見たまんまです。Windowsに詳しい人であれば、セキュリティグループとユーザーだと思ってもらえれば十分です。

## ロール
実は、まだよくわかっていません。例えば、EC2で作成したDBサーバのバックアップをS3に取得する際に、DBサーバのインスタンスに対してS3にアクセスできるロールを割り当てる、とかそういう感じです。

## ポリシー
ポリシーは詳しくなっておいたほうがいいです。
IAMに対するアクセス権限のことで、ロールやグループに割り当てます。
例えば「S3フルアクセス」というポリシーがあって、これをグループに割り当てれば、
そのグループに所属するユーザーは、S3を管理する権限が与えられていることになります。
ロールに割り当てれば、そのロールが割り当てられているEC2インスタンスが、S3にアクセスできるようになります。
（ここは概念の話なので、実際の挙動とは違鵜と思います。ふーんそんなものか、と思ってください）

しかし、困ったことに、デフォルトのポリシーだけで、無数にあります。
しかも、１つのポリシーの中に、「何ができるのか」が複数設定されていたりします。

それでは面倒なので、自作ポリシーを作るとよいです。
GUIでも簡易なものはできますが、jsonで記述する方法があるので、各自調べてみてください。

現在、必要としているのは、
・ルートユーザーの代理IAMユーザー
・EC2のインスタンスの作成と削除、起動と停止ができるIAMユーザー
・EC2のインスタンスの起動と停止ができて、Cloud9が使えるIAMユーザー
の３つですが、まず一番上の、ルートユーザーの代理ユーザーを作りたいので、
それ用のポリシーを作成することにします。ほかの２つは、実際に必要になった時点で作ります。


さて代理IAMユーザ用ポリシー、と思ったのですが、これは最初から用意されていますね。
「AdministratorAccess」というポリシーがあることを確認できればOKです。

# グループ
新しいグループを作成で、適当な名前を付けて、ポリシーのアタッチ画面へ。
たぶん一番上に「AdministratorAccess」ポリシーがあるので、それにチェックをいれて完成。
ちなみに、ここの名前の横にAWSアイコンがあるポリシーが、デフォルトで存在するポリシーです。
難しくないですね。

# ユーザー
ユーザーを追加をクリック。
アクセスの種類は「AWS マネジメントコンソールへのアクセス」を選びましょう。
パスワードはここで作成したほうがわかりやすいので、「カスタムパスワード」を選びましょう。
リセット云々はご自由に。
次に進むと、グループを選択とかでてくるので、先ほど作成した管理者用グループを選んで、完了です。

# IAMユーザーでログインしてみる
IAMユーザーが作成されたことが確認できたら、IAMユーザーサインインリンクを確認してから、ルートユーザーから一度サインアウトし、
サインインリンクから作成したIAMユーザーでログインしてみましょう。


今回はここまでー。
git 空フォルダを探して再帰的に.gitkeepを作るバッチを作った

# 空フォルダを探して再帰的に.gitkeepを作るバッチを作った

## gitは空のディレクトリはcommitできない
通例として.gitkeepをおいておく

VBSのバッチなのでwindowsならとくにインストールせずに使えます

``` gitkeep追加.vbs
' 作業ディレクトリはドラッグ・アンド・ドロップ
Dim dir
If WScript.Arguments.Count > 0 Then
	dir = WScript.Arguments.Item(0)
End If
If dir = "" Then
	msg = "パスがないです。ドラッグ・アンド・ドロップしてください"
Else
	' 一時バッファ用辞書
	Dim fs,tempDic
	Set tempDic = CreateObject("Scripting.Dictionary")
	Set fs = CreateObject("scripting.Filesystemobject")
	Call ChildPathget(dir)
	For Each key In tempDic
		Call Makegitkeep(tempDic.Item(key))
	Next
	Set fs = Nothing
	Set tempDic = Nothing
	msg = "完了"
End If

msgbox msg

'//==================================================================================
'// 関数  ：空フォルダのパスを辞書にいれる
'//==================================================================================
Private Sub ChildPathget(pdir)
	Dim subF,SubFolder
	Set SubFolder = fs.GetFolder(pdir).SubFolders
	Set wFiles = fs.GetFolder(pdir).Files
	If SubFolder.Count > 0 Then
		For Each subF In SubFolder
			' 子供がいる時は再帰
			Call ChildPathget(subF.Path)
		Next
	Else
		' 子供が居なくてファイルもない時は自分
		If wFiles.Count = 0 Then
			Call tempDic.Add(tempDic.Count,pdir)
		End If
	End If
	Set SubFolder = Nothing
	Set wFiles =Nothing
End Sub

'//==================================================================================
'// 関数  ：gitkeep作成
'//==================================================================================
Private Sub Makegitkeep(wdir)
	Set obj = CreateObject("Scripting.FileSystemObject")
	Set mgit = obj.openTextFile(wdir &"/.gitkeep",8,True)
	Set obj = Nothing
	Set mgit = Nothing
End Sub
```
必要は発明の母
Zbrush Memo

■SculptrisPro　
[Stroke>SculptrisPro ]
→ブラシサイズに応じて、メッシュを細分化する。
Subdivisionでは機能しない。
PolyMesh3Dで機能する。
https://mononoco.com/creative-design/zbrush/sculptris-settings

■Polygroup it
[Zplugin>polygroup it]
→ポリペイントによるポリグループ分けの機能。
http://3dnchu.com/archives/danny-mac-zbrush-polygroupit-60s-tutor/
raspberry pi でwebcam

#概要
raspberry pi でwebcamやってみた。

#環境
raspberry pi 1 b
raspbian jessie 8.0
elecom ucam-dlk130

#仕掛け
jsdoのjavascriptでsettimeoutで10秒間隔でimgを読み取る。
node-redの、Execでpythonを動かして、jpegを読み取って送る。
pythonは、opencvで、カメラをキャプチャする。

#jsdo

```
function tick() {
    img = document.getElementById('koko');
    var now = new Date(); 
    img.src = "http://192.168.11.8:1880/test?" + now.getTime(); 
    setTimeout("tick()", 10000);
}
tick();

```

#node-red

headerで、contents-typeをセットする。

![node.jpg](https://qiita-image-store.s3.amazonaws.com/0/18104/1091f463-aaae-7a70-cb4d-0cdf1a2b53f1.jpeg)

#python

```
import cv2

cap = cv2.VideoCapture(0)
ret, frame = cap.read()
cv2.imwrite('test.jpg', frame)
cap.release()
print open("test.jpg", "rb").read()
```

以上。
【Android】adb pushでPC上のフォルダを指定してAndroidにファイルを転送する方法

#概要

adbコマンドの中にpushというコマンドがあり、PCからAndroidにファイルを転送するときに使います。

```sh
adb push PC上のファイルのパス　Android上のフォルダパス
```

参考
https://developer.android.com/studio/command-line/adb?hl=ja
https://qiita.com/t2low/items/cb37cec5f864c4748e14

ファイルって説明されてあったので、てっきりフォルダはできないのかな？バッチファイル作って再帰的に呼び出さないといけないのかな？と思っていたのですが、調べてみたらstackoverflowですでに同じ質問があったので実際に試したらできたのでやり方をまとめます。

参考
https://stackoverflow.com/questions/13145872/android-recursive-copy-with-adb-push

#実装
結論から言うと、フォルダパスを指定したあとに「.」を書くだけです。

```sh
adb push PC上のフォルダパス/. Android上のフォルダパス
```

日頃からコマンドをあまり叩かないのもあって、「.」はカレントフォルダの役割を持つのを知らなかったので勉強になりました。
wxPythonを使ってみる (6) 

こんにちは．これからwxPythonを使ってみる(6)について始めたいと思います．
対象や動作環境などのはじめに必要な情報は[wxPythonを使ってみる(1)](https://qiita.com/Kenta-Han/items/5ac4f38d518e3262905f) と同じになります．
また，今回の内容は前の5回の続きとなります．是非読んで見てください．

## 特徴
前回までは，BoxSizerについて説明しまいした．
今回から，GridSizerについて学びましょう．

GridSizerは，コンテナー領域を指定の行数，列数を分割し，順番にウィジェットを配置していくマス目状のレイアウトです．

<img width="402" alt="スクリーンショット 2018-07-04 11.57.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/179248/f2a016ab-8ac0-1d83-03a9-fba1655ee0f7.png">

コンストラクタ関数には行数と列数を渡します．1行目からアイテムを配置していき，1行目への配置が終わったら2行目へ．
window_display12.py は上の図のプログラムとなります．

```python3:window_display12.py
import wx

class CustomFrame(wx.Frame):
		def __init__(self,title):
			wx.Frame.__init__(self,None,-1,title,size=(400,400))
			
			panel = wx.Panel(self)
			
			layout = wx.GridSizer(2,2,0,0)
			layout.Add(wx.Button(panel,wx.ID_ANY,'B01'))
			layout.Add(wx.Button(panel,wx.ID_ANY,'B02'))
			layout.Add(wx.Button(panel,wx.ID_ANY,'B03'))
			layout.Add(wx.Button(panel,wx.ID_ANY,'B04'))
			
			panel.SetSizer(layout)
			
			self.Show()
			
app = wx.App(False)
CustomFrame('GridSizer')
app.MainLoop()
```
ここで注意すべきどこは，`layout = wx.GridSizer(2,2,0,0)`となります．`wx.GridSizer`コンストラクタ関数の引数は4つが必要です．
`wx.GridSizer(行数を指定,列数を指定,縦の余白を指定,横の余白を指定)`

このプログラムを書いたとき，`wx.GridSizer(2,2)`のように行数と列数のみを指定して書きましたが，下のようなエラーが吐き出されました．

```
layout = wx.GridSizer(2,2)
TypeError: GridSizer(): arguments did not match any overloaded call:
overload 1: not enough arguments
overload 2: argument 2 has unexpected type 'int'
overload 3: not enough arguments
overload 4: not enough arguments
```

このエラーを検索してみると
https://stackoverflow.com/questions/37502112/typeerror-gridsizer-arguments-did-not-match-any-overloaded-call
のサイトがあります．回答は下のように書かれています．

> As you are running Python 3.4 I presume you are using wxPython Phoenix. According to the documentation of wx.GridSizer two int do not match any of the allowed signatures. Use e.g. three integers instead.

これをみて引数を3つにすると，エラーがなおりました．
また，`wx.GridSizer(行数を指定,列数を指定,縦の余白を指定,横の余白を指定)`の縦の余白を指定したくないときは，`wx.GridSizer(2,2,hgap=2)`で書けば，行列数と横の余白を指定することができます．

今回のwxPythonを使ってみる(6)は以上で終わります．
読んでいただいてありがとうございます．

### 「wxpythonを使ってみる」目次
* [wxPythonを使ってみる(1)](https://qiita.com/Kenta-Han/items/5ac4f38d518e3262905f)
* [wxPythonを使ってみる(2)](https://qiita.com/Kenta-Han/items/dfd9764aedd64f9f92be)
* [wxPythonを使ってみる(3)](https://qiita.com/Kenta-Han/items/a7a58ad3cf5ae1f67625)
* [wxPythonを使ってみる(4)](https://qiita.com/Kenta-Han/items/89d11908d49c34976071)
* [wxPythonを使ってみる(5)](https://qiita.com/Kenta-Han/items/9b8025b7accae5fa770d)
アロー関数式のひとつのノート

```javascript
function Yige(x){
    this.instance={
        init:function(x){
            this.x=x;
        }
    };
    this.instance.init(x);
    return this;
}

console.log(new Yige(2).instance.x);
```

その`init`関数はアロー関数式になると、コンソールにはundefinedが出る。一応ノートを作っておこう。

> アロー関数式 は、function 式より短い構文で、this, arguments, super, new.target を束縛しません。アロー関数式は、メソッドでない関数に最適で、コンストラクタとして使うことはできません。
[モブプログラミング]Master-Detail App を実装する

<p>勉強会初の試みとして、モブプログラミングに挑戦します。事前に用意した内容を公開します。</p>

<p>進め方</p>

<ul>
<li>大まかな仕様があるので、それを参考にして皆で製作する。
        <ul>
        <li>スムーズにするため、サンプル・プロジェクトを用意する。</li>
        <li>プロジェクトは共有した方がいいが大変なので、各自ローカルの環境でとする。</li>
        </ul>
</li>
<li>役割は、一人がドライバ、その他がナビゲータ。</li>
<li>ドライバーは時間を決めて、順番に交代して担当する。時間は例えば5分。</li>
<li>ドライバーは操作しているMacの画面を投影して、皆で見ながら進める。</li>
<li>大まかな仕様とサンプルと異なる実装方法の意見があると思うが、それを皆で共有して議論したいので、異なる意見は大いに歓迎。</li>
</ul>

<p>作るもの</p>

<ul>
<li>iOSのMaster-Detail App。
        <ul>
        <li>ほぼ、新規プロジェクトで生成される雛形のまま。</li>
        </ul>
</li>
<li>モデルのクラスを用意する。
        <ul>
        <li>サンプルのモデルのクラス名は、Document。</li>
        <li>シングルトンでなく、AppDelegateのメンバー変数で保持。</li>
        </ul>
</li>
</ul>

![モブ.jpg](https://qiita-image-store.s3.amazonaws.com/0/12540/25138566-b680-e52b-8d55-3a591493fd95.jpeg)

ソースコード
たたき台となるExampleを共有ディスクで公開しています。<br />
<a href="https://drive.google.com/open?id=12_lOqG7qlTUa8NwEvTqeajFF7rXyRtH9">Exampleプロジェクト</a><br />

【関連情報】
<a href="https://cocoa-kanto.connpass.com/event/91202/">BUKURO.swift 2018-07</a><br />
<a href="https://cocoa-kanto.connpass.com/">Cocoa.swift</a><br />
<a href="https://www.facebook.com/groups/cocoa.kanto/">Cocoa勉強会 関東</a><br />
<a href="http://www.bitz.co.jp/weblog/">Cocoa練習帳</a><br />
<a href="https://qiita.com/m_yukio">Qiita</a><br />
getho.io使って見た

## 概要
infuraと同じ、自分でnodeを立てずにethereum networkにアクセスするためのサービス。
cryptokyoというチームが開発している。日本製。今はAlpha版で、ropstenにしか繋がらない。
[getho.io | The Simplest Way To Get a Ethereum Full Node.](https://getho.io/)

## 試して見た

- 登録したらapi_key的なものを表示してくれた。
- それを使って、json-rpcでeth_getBalanceのリクエストを送った

request
(「自分のホストネーム」と「自分のアドレス」を書き換える）

    curl -X POST https://自分のホストネーム/jsonrpc -H 'Content-Type:application/json' --data '{"jsonrpc":"2.0","method":"eth_getBalance","params":["自分のアドレス", "latest"],"id":1}'

response

    {"jsonrpc":"2.0","id":1,"result":"0xa90679c0113d5900"}

resultはweiの16進数表示なので、10進数にしてetherに直したら、正しい値であることが確認できた。
（0xa90679c0113d5900[wei] -> 12179556108100000000[wei] -> 12.1795561081[ether]）

## 感想

とりあえずinfuraと同じことができそう。
今すぐinfuraから乗り換えようとは思わないが（infuraの方が全てのネットワークに繋がれるし、ドキュメントや使い方の記事も充実している）、またupdateがあったら触ってみたい。
選択肢が増えるのはいいことだと思う。
JavaでList同士の比較をする


```:java
hogeList.equals(fugaList);
```

で、可能です。
`List#equals` は順序保証含めて等値性判定する（厳密）ので、
Listにする前にSQLでOrber Byとかしておいたほうが良いです。


重複要素を省いてもいいのであれば` HashSet` に変換後に` equals` する手段もあります。
[VCCW3] vagrant upに失敗してしまう。

VCCW3系でwordpress環境を作成しようとしたところ
失敗したので備忘録。

## 環境
Vagrant 1.9.3
Vartual Box 5.1.18

## 現象

```
$ vagrant up

The box 'vccw-team/xenial64' could not be found or
could not be accessed in the remote catalog. If this is a private
box on HashiCorp's Atlas, please verify you're logged in via
`vagrant login`. Also, please double-check the name. The expanded
URL and error message are shown below:

URL: ["https://atlas.hashicorp.com/vccw-team/xenial64"]
Error: The requested URL returned error: 404 Not Found
```

## 解決方法
vagrantを最新バーション(現在は2.1.2)にアップデートすることで解決しました。

### ちなみに
vagrant up中にansibleでwordmoveのインストールが
rubyのバージョンの関係で失敗していたので、
vagrant sshしてwordmoveのバージョンを指定して、直接インストールしました。

```
$ vagrant ssh

$ gem install wordmove -v "2.0.0"
```
さよならアナコンダ（How to uninstall Anaconda）

##環境
Python 3.6.5 |Anaconda, Inc.

##問題
Anacondaいらなくなったので消したい。

##手順

### anaconda-cleanをインストール

```bash
$ conda install anaconda-clean
Solving environment: done # 時間かかる

## Package Plan ##

  environment location: /root/anaconda3

  added / updated specs: 
    - anaconda-clean


The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    anaconda-clean-1.1.0       |           py36_0           5 KB
    conda-4.5.8                |           py36_0         1.0 MB
    ------------------------------------------------------------
                                           Total:         1.0 MB

The following NEW packages will be INSTALLED:

    anaconda-clean: 1.1.0-py36_0

The following packages will be UPDATED:

    conda:          4.5.4-py36_0 --> 4.5.8-py36_0

Proceed ([y]/n)? y # yを入力
```

```bash
Downloading and Extracting Packages
anaconda-clean-1.1.0 |    5 KB | ################################ | 100% 
conda-4.5.8          |  1.0 MB | ################################ | 100% 
Preparing transaction: done
Verifying transaction: done
Executing transaction: done

```

### anaconda-cleanを実行

```bash
$ anaconda-clean
Delete .conda? (y/n): y # yを入力
Backup directory: /root/.anaconda_backup/2018-07-13T095546
Delete .ipython? (y/n): y # yを入力
Delete .jupyter? (y/n): y # yを入力
Delete .theano? (y/n): y # yを入力

```

```bash
$ python --version
Python 3.6.4 |Anaconda custom (64-bit)| (default, Jan 16 2018, 18:10:19) 
```
### Anacondaのディレクトリを削除

```bash
$ cd PATH_TO_ANACONDA # あなたのアナコンダパス
$ rm -rf anaconda3 # 時間かかる3Gくらいある？
```

```bash
$ python
-bash: /root/anaconda3/bin/python: そのようなファイルやディレクトリはありません
```

### Anacondaのパスを削除

```bash
$ vim ~/.bashrc #.bash_profileかもしれない
```

```bash
# added by Anaconda3 installer
export PATH="/root/anaconda3/bin:$PATH" # <-この行を削除

```

### 設定再読み込み

```bash
$ source ~/.bash_rc
```


```bash
$ python --version
Python 2.7.5 (default, Nov  6 2016, 00:28:07) 
```
Unreal Engine 4メモ：C++でスケルタルメッシュを表示させる

スケルタルメッシュを簡単に表示するためには、普通のAActorにUSkeletalMeshComponentを付けてロードして来たUSkeletalMeshをセットするだけで大丈夫です。

位置や向きや大きさはUSkeletalMeshComponentを追加したアクタ依存です。

```c++:LoadSkeletalMeshSample.cpp
// スケルタルメッシュであることは「SkeletalMesh」で表す
FString path = TEXT("SkeletalMesh'/Game/Model/ModelName.ModelName'");

FStreamableManager loader;
loader.RequestAsyncLoad(FStringAssetReference(path), FStreamableDelegate::CreateUObject(this, &ATestClass::CompleteLoad));
```


作ったアクタにUSkeletalMeshComponentを追加しておけば下記のコードで反映されます。

```c++:SetupSkeletalMeshComponentSample.cpp
USkeletalMesh* skeletalMesh;
USkeletalMeshComponent* skeletalMeshComponent->SetSkeletalMesh(skeletalMesh);
```
Ada言語を学ぶ

#Ada言語を学ぶ

##どこで勉強したらええんやろ？
いざ書いてみようと思ってネットの海を探してみるも
あまり情報見つけられなくて悲しい:confounded:

##貴重な情報源
###日本語で良さそうなところ
- [WikipediaにおけるAdaの定義](https://ja.wikipedia.org/wiki/Ada)
- [Ada 基礎文法最速マスター](http://d.hatena.ne.jp/carver/20100227/p1)
- [Ada入門](https://dotinstall.com/lessons/basic_ada)
- [Ada日本コミュニティ](https://ada.jp/)
- [Ada日本コミュニティにおけるAda言語入門](https://ada.jp/?cat=5)
- [Ada日本コミュニティにおけるSPARK言語入門](https://ada.jp/?cat=6)
- [SPARKのユーザーガイド](https://www.adacore.com/papers/spark-2014-users-guide-japanese)

###一番良さそうなのはここ
- [Ada Programming](https://en.wikibooks.org/wiki/Ada_Programming)

### 英語で最新な資料
- [AdaとSPARKを学べるインタラクティブなホームページ](https://learn.adacore.com/)

##ふぁーすといんぷれっしょん
見た感じPL/SQLっぽくて、違和感なく書けそうな気がしてきた。

[A#](http://sourceforge.net/projects/asharp/)(.NET実装)なんてのもあるのね:relaxed:
UserDefaultsの保存場所

##使用シュミレータのIdentifierを調べる

まずはxcodeを開き、メニュバーのWindow→Devices and Simulatorsを開く。

![スクリーンショット 2018-07-13 10.00.50.png](https://qiita-image-store.s3.amazonaws.com/0/185455/a8c7fc61-9d0b-5abe-e6f9-96c44cd57ce5.png)

開いた画面の上部にIdentifier:###########があるためメモ、コピーのいずれかをしておく。
SS上ではC3CDE390-D7FA-########のやつです。

![スクリーンショット 2018-07-13 10.02.45.png](https://qiita-image-store.s3.amazonaws.com/0/185455/861ba2d1-39f8-a26d-a979-cd218a32005b.png)

##ターミナルより.plist探し

~~~
$cd ~/Library/Developer/CoreSimulator/Devices/
~~~

移動後 `$ls`で見ると端末の拡張子がたくさんある。
先ほど調べたIdentifierと同様なものに移動

~~~
$cd C3CDE390-D7FA-########
~~~

.plistの検索を行う。

~~~
find ./ -name "ここですよ".plist
~~~

![スクリーンショット 2018-07-13 10.16.24.png](https://qiita-image-store.s3.amazonaws.com/0/185455/790a11c3-f384-1b7e-1710-c1f08161e1df.png)

アプリ名.plistまでのpathが表示される。

##Finderにて見つけた.plistを開く

移動/フォルダへ移動を選択

![スクリーンショット 2018-07-13 10.23.47.png](https://qiita-image-store.s3.amazonaws.com/0/185455/457340fb-66ce-8e84-3d26-0f28903a906a.png)

`~/Library` と入力し移動

![スクリーンショット 2018-07-13 10.24.49.png](https://qiita-image-store.s3.amazonaws.com/0/185455/cf63e97b-6aa9-40fd-5a0e-0576d10083cf.png)

あとは先ほど`find ./ -name "ここですよ"`で表示されたpath通りに目的地まで移動し、開くのみ

これでUserDefaultsの中身がわかりますね！
Raspberry Pi ZeroにUSB経由でSSH接続する

# Raspberry Pi Zero WH

GPIOが生えててLinuxが動く手頃なマイコンボードが必要だったので、Raspberry Pi Zero WHを買ってみました。
ちなみに、Raspberry Pi Zeroシリーズの各モデルの違いはだいたい以下のようなかんじです。

- Raspberry Pi Zero … 普通のやつ。Wi-Fi & Bluetoothなし。
- Raspberry Pi Zero W … Wi-Fi & Bluetoothあり。
- Raspberry Pi Zero WH … Wにピンヘッダが生えたやつ。

この記事の内容は、たぶん上記のどれでもできると思います。

# 下準備

microSDカードにRaspbianのイメージを書き込みます。
これは記事が山ほどあると思うので飛ばします。

# boot以下のファイルを編集

## 空の `ssh` ファイルを作成

最初からSSH機能を有効にするために `boot` 以下に `ssh` という名前の空ファイルを作ります。
macOSであれば、 `/Volumes/boot` にマウントされてるはずなので、コマンドでやるとしたら以下のようなかんじです。

```shell
$ cd /Volumes/boot
$ touch ssh
```

## `config.txt` を編集

`boot` 以下に `config.txt` というファイルがあるはずなので適当なテキストエディタで編集します。
以下の一行を追加すればOKです。

```
dtoverlay=dwc2
```

## `cmdline.txt` を編集

このファイルはWindowsのレジストリみたいに、ちょっとミスがあるだけで起動しなくなる繊細なやつらしいです。
`rootwait` と `quiet` の間にスペース区切りで以下の文字列を追加してください。`=` とか `,` の前後に余計なスペースとか入れてはダメです。

```
modules-load=dwc2,g_ether
```

以下の記述例のようになればOKみたいです。

https://pastebin.com/WygSaptQ

# 起動して接続

ここまで来たらmicroSDカードをPCから取り外してRaspberry Pi Zeroに挿入し、microUSB - USBケーブルでRaspberry Pi Zeroの内側（PWRじゃなくてUSBって書かれている方）とPCを接続します。
少し待つとRaspbianが起動して、以下のようにSSH接続できるようになります。

```shell
$ ssh pi@raspberrypi.local
```

初期パスワードは例によって `raspberry` です。


# 参考

- https://www.raspi.jp/2016/07/pizero-usb-otg/
- https://www.raspberrypi.org/blog/programming-pi-zero-usb/
- https://blog.gbaman.info/?p=791
AMIの更新通知をトリガーにlambdaからBatchをキックする(Serverless Frameworkも使うぜよ)

AWSはAMIが更新された場合の連絡チャネルを[準備してくれているようです](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ECS-AMI-SubscribeTopic.html)。
更新連絡をトリガーとして、lambdaからBatchをキックして、[先回](https://qiita.com/sista05/items/71798cad6afd71cd44a7)のAMIのコンピューティング環境自動更新を動かす試みです。

設定にあたり、Serverless Frameworkなるものを初めて使用したのですが素敵でした。
以下が、使用したserverless.ymlです。

```yaml:serverless.yml
service: latest-ami-replace
provider:
  name: aws
  stage: ${opt:stage, self:custom.defaultStage}
  region: ${opt:region, self:custom.defaultRegion}
  runtime: python2.7
  iamRoleStatements:
      - Effect: Allow
        Action:
          - batch:SubmitJob
          - logs:CreateLogStream
          - logs:CreateLogGroup
          - logs:PutLogEvents
        Resource: "*"
custom:
  defaultStage: dev
  defaultRegion: ap-northeast-1
  environment:
    dev:
      JOB_DEFINITION: 'ami-replace:1'
      JOB_NAME:  'ami-replace'
      JOB_QUEUE: 'arn:aws:batch:ap-northeast-1:999999999999:job-queue/ami-replace'

functions:
  handler:
    handler: ami-replace.lambda_handler
    environment: ${self:custom.environment.${self:provider.stage}}
    timeout: 60

resources:
  Resources:

    SNSSubscription:
      Type: AWS::SNS::Subscription
      Properties:
          Endpoint: arn:aws:lambda:ap-northeast-1:999999999999:function:asd_latest_ami_replace
          Protocol: lambda
          TopicArn: arn:aws:sns:ap-northeast-1:177427601217:ecs-optimized-amazon-ami-update
```


lambda関数は以下です。Batchをcallしているだけの内容です。
上記ではami-replaceとしていますが、環境変数として任意に設定してください。

```python:ami-replace.py
import boto3,os
 
def lambda_handler(event, context):
    client = boto3.client('batch')
 
    JOB_NAME = os.getenv("JOB_NAME")
    JOB_QUEUE = os.getenv("JOB_QUEUE")
    JOB_DEFINITION = os.getenv("JOB_DEFINITION")
 
    response = client.submit_job(
        jobName = JOB_NAME,
        jobQueue = JOB_QUEUE,
        jobDefinition = JOB_DEFINITION
        )
        
    print(response)
    return 0
```



上記のServerless Frameworkで登録した環境を削除すると、CloudFormationが以下のエラーを放ちます。
自分のリソースではないものは削除できない模様ですが、AWSが自ら公開しているリソースなのでなんとかして頂きたいところです。

```
Stack:arn:aws:cloudformation:ap-northeast-1:999999999999:stack/latest-ami-replace-dev/acc286e0-8406-11e8-9519-50a6866998ae is in DELETE_FAILED state and can not be updated.
```

今回のトピックのキモは、Serverless(CloudFormation)による操作では 外部topic登録できれど削除はできずというところくらいですね。ありがとうございました。
MSX POSITサンプル

画面左上の座標はBASICのLOCATEは(0,0)だがPOSITは(1,1)のようだ。

```posit.c
/*
z88dk / WebMSX
zcc +msx -lndos -create-app posit.c
bload"cas:",r
*/

#include <stdio.h>

int cls()
{
#asm
        xor     a
        call    $00c3           ; CLS
#endasm
}

int posit(int xy)
{
#asm
        call    $00c6           ; POSIT
#endasm
}

int posit2(char x, char y)
{
#asm
        ld      ix, 0
        add     ix, sp
        ld      l, (ix+2)       ; y
        ld      h, (ix+4)       ; x
        call    $00c6           ; POSIT
#endasm
}

#define locate(x,y) posit((((x)+1)<<8)|((y)+1))

void main()
{
        cls();
        locate(1, 0);
        puts("locate");
        posit(0x0403);
        puts("posit");
        posit2(6, 5);
        puts("posit2");
}
```

![WMSX Screen.png](https://qiita-image-store.s3.amazonaws.com/0/257554/0e69cc37-8272-3ecf-2a21-3f8d86a22caf.png)
【react-navigation】DrawerNavigatorだとparamsが渡されない

## 何が起きたか
react-navigationにて
DrawerNavigatorを使用した場合、現状（v2.5.5）だとパラメータが渡されない。

以下の場合、DrawerNavigatorであるMainの`Home`にparamsを設定しても、View内でparamsが消えてしまう。

```route.jsx
const Main = createDrawerNavigator({
  Home: {
    screen: HomeScreen,
  },
  MyPage: {
    screen: MyPageScreen,
  },
}, {
  initialRouteName: 'Home'
});

export const Root = createStackNavigator({
  Main: {
    screen: Main,
  },
}, {
  initialRouteName: 'Main',
});
```

この状態で、navigate()でページ遷移したときに

```jsx
NavigationActions.navigate({
    'MyPage',
    params: {
      title: 'タイトル', 
      uri: '/uri',
    },
  })
```

paramsの値を`MyPageScreen`のView内で出力しても`undefined`となる。

## 原因
結構前（１年以上前）から発生しているようす。関連するissueが立ちまくっている
>https://github.com/react-navigation/react-navigation/issues/3250
>https://github.com/react-navigation/react-navigation/issues/143

## 対応方法
DrawerNavigatorをRootNavigatorにするとparamsが渡されない。
なので、ワンクッションNavigatorをかまして、DrawerNavigator以外でparamsを扱うViewを定義する

この[コメント](https://github.com/react-navigation/react-navigation/issues/3250#issuecomment-356543292)を参考に。

```jsx:Page2にparamsを渡したい場合
const Main = createDrawerNavigator({
  Home: {
    screen: HomeScreen,
  },
  // MyPageを移動する
}, {
  initialRouteName: 'Home'
});

const RootMain = createStackNavigator({
  Drawer: {
    screen: Main,
  },
  // MyPageを追加
  MyPage: { 
    screen: MyPageScreen,
  },
}, {
  initialRouteName: 'Drawer',
});


export const Root = createStackNavigator({
  Main: {
    screen: RootMain,
  },
}, {
  initialRouteName: 'Main',
});
```

こうすると

```
NavigationActions.navigate({
    'MyPage',
    params: {
      title: 'タイトル', 
      uri: '/uri',
    },
  })
```

`MyPageScreen`のView内に`params.title`や`params.uri`が渡され、使えるようになる


あまりキレイな形ではないが、これでやりたいことは実現できる。
FCM Topic Messaging の挙動

# 概要
FCMでは`topic`宛にメッセージを送ることで、`topic`に登録した端末に一斉にpush通知を送ることができます。`topic`に端末を登録する際、端末の`fcm registration token`(以下`TOKEN`)を使用しますが、これはアプリを再インストールした場合等に更新されます。`TOKEN`が更新された場合topic上でどう扱われるか気になったので、試してみました。

# 結論
TOKENが更新された場合、更新前に登録していたtopicからは通知が来なくなることがわかりました。ですが、`topic`い登録していた古いトークはどうなるんでしょうね？古いトークンを使って明示的にunsbscribeすることはできないようなのですが、更新されたら勝手にunsbscribeにしてくれているんですかね。。

# 実験
## topicへ端末を登録
```
$ curl -XPOST --header "Authorization: key=${SERVER_KEY}" \
    --header "Content-type: application/json" \
    --header "Content-Length: 0" \
    "https://iid.googleapis.com/iid/v1/${TOKEN}/rel/topics/test"
```
## 登録状況の確認
```
$ curl --header "Authorization: key=${SERVER_KEY}" \
    "https://iid.googleapis.com/iid/info/${TOKEN}?details=true" | jq
{
  "applicationVersion": "1",
  "connectDate": "2018-07-12",
  "attestStatus": "NOT_ROOTED",
  "application": "com.example",
  "scope": "*",
  "authorizedEntity": "111111111111",
  "rel": {
    "topics": {
      "test": {
        "addDate": "2018-07-12"
      }
    }
  },
  "appSigner": "xxxxxxx",
  "platform": "ANDROID"
}
```
## メッセージの送信
```
$ curl --header "Authorization: key=${SERVER_KEY}" \
    --header Content-Type:"application/json" \
    https://fcm.googleapis.com/fcm/send \
    -d "{
      \"to\" : \"/topics/test\", 
      \"data\" : {
        \"message\": \"hello\"
      }
    }"
```
受信できました。
## アンインストール＆再インストール＆登録状況の確認
```
$ curl --header "Authorization: key=${SERVER_KEY}" \
    "https://iid.googleapis.com/iid/info/${TOKEN}?details=true" | jq
{
  "error": "No information found about this instance id."
}

$ curl --header "Authorization: key=${SERVER_KEY}" \
    "https://iid.googleapis.com/iid/info/${NEW_TOKEN}?details=true" | jq
{
  "applicationVersion": "1",
  "connectDate": "2018-07-12",
  "attestStatus": "NOT_ROOTED",
  "application": "harutacompany.sample.message",
  "scope": "*",
  "authorizedEntity": "366365399328",
  "appSigner": "c40ce9d10d3d1ac89519090ae031de3f1f50af42",
  "platform": "ANDROID"
}
```
## メッセージの送信
```
$ curl --header "Authorization: key=${SERVER_KEY}" \
    --header Content-Type:"application/json" \
    https://fcm.googleapis.com/fcm/send \
    -d "{
      \"to\" : \"/topics/test\", 
      \"data\" : {
        \"message\": \"hello\"
      }
    }"
```
受信できませんでした。
first_nameとfirstnameだとどちらがいいのか（Ruby）

- DBのUserテーブルにカラムを作るにあたり、どちらがいいのかを調べた結果をまとめておきます。
- ほぼ[こちらのページ](https://www.reddit.com/r/rails/comments/36wkx3/first_name_firstname_or_firstname_which_do_you/)をまとめた感じです。

## 結論
- Rubyなら`first_name`の方がいいよ！

## 根拠
### その１：　Ruby-Style-Guideで使われてる。
- https://github.com/rubocop-hq/ruby-style-guide#naming
- こちらのページでは`first_name`で使われてる。
- スタイルガイドに書かれているくらいだから、こっちの方が「Rubyの理想の形」に近いに違いない。

### その２：　`titleize`メソッドを使った時にそれっぽくなる。
```rb
'first_name'.titleize
# => First Name

'firstname'.titleize
# => Firstname
```

- 「そもそも`titleize`メソッドなんて使わないよ」とか言われるとそれまでだけど・・・。
- 意識として、入力欄のラベルに`titleize`を使った時に、「どっちがすっきりとしてみえるか」が選ぶヒントになるかもしれない。

## まとめ
- `first_name`を使った方がいいよ！！
rails sが立ち上がらない・・・

##サーバー起動
rails serverでサーバーを立ち上げようとしたところ、

```
=> Booting Puma
=> Rails 5.1.6 application starting in development 
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.9.1 (ruby 2.4.1-p111), codename: Private Caller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://localhost:8080
Exiting
/usr/local/rvm/gems/ruby-2.4.1/gems/puma-3.9.1/lib/puma/binder.rb:269:in `initialize': Address already in use - bind(2) for "127.0.0.1" port 8080 (Errno::EADDRINUSE)
from /usr/local/rvm/gems/ruby-2.4.1/gems/puma-3.9.1/lib/puma/binder.rb:269:in `new'
from /usr/local/rvm/gems/ruby-2.4.1/gems/puma-3.9.1/lib/puma/binder.rb:269:in `add_tcp_listener'
.
.
省略
.
.
from bin/rails:3:in `<main>'
```

のように表示され、立ち上がらない。なんで？？

##プロセスの確認
このコマンドで動いているプロセスを確認する。
(今回はポート番号8080)

```
lsof -i -P | grep 8080
```
すると・・・

```
ruby    15882 ec2-user   11u  IPv4  24076      0t0  TCP localhost:8080 (LISTEN)
```
うんうん、
どうやら15882のプロセスが動いていて邪魔をしているってさ！
##プロセスの停止
プロセスIDがわかったので停止！！

```
kill -9 15882
```
ちなみに-9は強制終了させるよという意味らしいです。
他にも何通りかあるらしいので、気になる方は調べてみてください。

再度rails serverでサーバーを立ち上げたら、動きました！


以上となります。
間違いなどありましたら、ご指摘いただけると幸いです！
悩めるアラフィフＩＴ初心者の今後の行く末

最近、ブログ代わりにここに書いている。
もちろん、これを見られても、何の参考にならないことはわかっている

とりあえず、サイトとしては、ＱＩＩＴＡやＴＥＲＡＴＡＩＬに投稿していると
それなりに、ＩＴエンジニアになった気になるから不思議だ。。。


さてプログラミングのテクニカルな記述で、
よくマークダウンを使うと、書きやすいと思うのであるが、
正直言えば、「目ざわりである」・・・


最近、本屋で買ったプログラム書物の大半が、
マークダウンで書かれているのが、バレバレの本がある。

正直に言えば、うっとうしい。
（簡単に書物を出版されていることが、見え見えなので）


なので、私はプレーンテキストで書く。
（読みにくいとか、これで書いていれば思わないし）



さてさて、今後のプログラミングスキルを何でやっていくのか？
これが、やはり当面の課題である。


ＰＹＴＨＯＮ
　ジュピターノートや、ＳＰＹＤＥＲなどのエディタでポチポチと
　プログラムを動かしながら、仕上げていくのに、なんとなく使えるとこまできた
　マスプロットでグラフを書いたり、パンダにデータを読み込んだり。。。
　これはこれで、使えるレベルまでやってきた気がする。

　しかしながら、デスクトップアプリを作ろうとしたり、
　ＷＥＢフレームワークを使ったアプリを作ろうとすると、
　やはり、それなりに敷居が高くなってくる

　あとテキストレベルの情報処理については、やはり使い慣れたＥＸＣＥＬ＋ＶＢＡが軽い！
（なにせ、実行ファイルを作っても、やはり会社では配布できないことが最大のネックである）

やはりＰＹＴＨＯＮはＬＩＮＵＸや、ＭＡＣといったデフォで動作環境があるＰＣにはかなわない
（そういう意味では、windows10 に切り替われば、ＬＩＮＵＸが動かせる（あくまでwindows linux であるが）

　で、当面は家の中で、ラズパイ工作や、ＡＩ関連の雑誌を見ながら、
時流をおっかけて、とりあえずソースを解読できるレベルを維持することはやっておく
（実際に、手を動かすことは、最近はあんまりしない）
会社で、実行できない言語は、やはり実用性にかけるという結論に落ち着いた。


次に、手掛ける言語として悩んでいるのは、
アプリケーションをブラウザでやるか？
それとも無料のビジュアルスタジオでやるか？
のどちらかである。


ＶＢＡからの移行であれば、ＶＢ．ＮＥＴに移行して、そこからＣ＋＋という流れは確かにある。
しかしながら、やや時代に逆行しているような気がする（だって、たいていは速度を無視すれば、それなりにＶＢＡで出来てしまうから）
ただ、実行アプリで配布したら、かっこいい！気がする（さすが、ソースまで触らせないので、完全に自分にクローズ）
でも、これって完全に、自慰行為な気がする
だって、時代は完全にオープンソースであって、いまさら隠しても仕方ないし、
第一、みんなのためにならない！


といいながら、ＶＢＡは永遠に脱出できず（これもプログラマとしては、悲しいところである）


そこから出した結論としては、
やはりＷＥＢベースでやっていくことも経験としては必要
流れとしては、ＨＴＭＬ＋ＪＡＶＡＳＣＲＩＰＴなどで、ＷＥＢの経験値を上げることかなと
（そういえば、ＰＨＰ、ＲＵＢＹなんてのもあるねえ。。。いっそのこと無くなってしまえばいい）


他に調べたところ、エレクトロンなどというものもある。
これはジャバスクリプトを使えと言っているようなものである。。。


でも、最近はＧＯＯＧＬＥなどが開発した言語などもあるし
しかしクラウドベースの仕事は、仕事では厳禁なので、
その場合は、オープンソースの方がまだ救いはある


いずれにしろ、ＪＡＶＡ経験もなければ、Ｃ＃プログラムもできないなんて
やはりプログラマとしては、少々失格な気がする。

この年になると、ほんとに選択肢が多いと悩むんですなあ。
ＰＹＴＨＯＮが仕事でバリバリ使える環境なら、悩まないで済むような気もするし
ほんまに何とかならないものなのかなあ。。。

と考えつつ、最近はＶＢＡに舞い戻っているのが現状


ＶＢ．ＮＥＴでエクセルまがいのことができる環境を探したけど
結局、有料のスプレッドシートが必要だったりするし、
それなら、エクセルでやっている方が、だいぶんましである。


# 追記

GitHubでのVBAの利用に関する以下のデメリットを追加します。

1. VBAのソースコードはバイナリ形式で保存されるため、直接的に比較やマージを行うことが難しい。GitHubのバージョン管理機能をフルに活用することができにくい。
2. VBAプロジェクトには、ソースコードだけでなく、フォームやモジュール、リソースファイルなどの要素が組み込まれることがある。これらの要素をGitHubで管理することは難しい。
3. VBAは主に個別のOfficeアプリケーションに密接に結びついており、依存性が高い。そのため、VBAプロジェクトを別の環境で再構築する際には困難が伴う場合がある。
4. VBAは主にマイクロソフトの製品に対して実行されるため、他のプラットフォームやアプリケーションに移植することが困難である。これは、オープンソースやクロスプラットフォームのツールや言語に比べて制約があると言える。

これらのデメリットにより、VBAのソースコードのバージョン管理や共同開発の面においては、GitHubが提供する機能を十分に活用することが難しくなることがあります。ただし、VBAを他の言語やツールに移植し、そのソースコードをGitHubで管理することは可能です。
Web Workerのメモ

Web Workerを少し勉強したので、そのメモ。

## Web Workerって？
WebWorkerは並列処理を実現する機能。

## 使い方

ワーカー（サブスレッド）で実行したい処理を別コードで用意する。
メインスレッド側でWorkerオブジェクトをインスタンス化。

##とりあえず書いてみる
echo-back-server的なワーカーを作ってみる。
ワーカーはメインスレッドからメッセージを受け取り、返答を返す。
echo-back-serverと言ったが、メッセージのオウム返しではなく、ACKという文字列を返すようにする。

```javascript:worker.js

self.addEventListener('message', function(e){
  let resp = 'say hello!';
  if (e.data.msg == 'hello'){
    resp = 'ACK';
  }
  postMessage(resp);
});
```

上で書いたワーカーを実験するためにメインスレッド側のコード。

```html:index.html

<!DOCTYPE html>
<html>
  <head>
    <title>webworker test</title>
     <script src="./workerclient.js"></script>
  </head>
  <body>
    <form>
      msg: <input id="msg", value="hello">
      <input id="btn", type="button", value="send"/>
      <span id="msgbox"></span>
    </form>
  </body>
</html>
```

```workerclient.js

document.addEventListener('DOMContentLoaded', function(){

  document.getElementById('btn').addEventListener('click', function(){
    let worker = new Worker('worker.js');

    worker.postMessage({
      msg: document.getElementById('msg').value
    });

    worker.addEventListener('message', function(e){
      document.getElementById('msgbox').textContent = e.data;
    }, false);

    worker.addEventListener('eroor', function(e){
      document.getElementById('msgbox').textContent = e.data;
    }, false);

  },false);

},false);


```
注文で理解するDDDのエンティティ・オブジェクト場合分け

#基本パターン
- 不変オブジェクトでない
    - 同一性を持つ
        - 親エンティティを持たない
            - 生存期間がトランザクションより短い -> 普通のオブジェクト
            - 生存期間がトランザクションより長い -> エンティティ
                - 値オブジェクトで構成される - 普通のエンティティ
                - 他のエンティティや普通のオブジェクトや集合(list, map)で構成される - ルートエンティティ
        - 親エンティティを持つ
         - 生存期間が親エンティティと同じか短い -> エンティティの一部
         - 生存期間が親エンティティより長い -> エンティティへの関連
    - 同一性を持たない -> 普通のオブジェクトだが値オブジェクトに変更可能
- 不変オブジェクトであるー値オブジェクト
    - エンティティへの参照を持つ -> エンティティへの注釈かエンティティの一部
    - 持たない
        - そもそも構造を持たない -> スカラー値。Intとか文字列とかenumとか
        - 内部構造は有る -> data class とか case class で表される値オブジェクト
        - エンティティと同じ内部構造 -> エンティティのコピー（スナップショット）

#色々な同一性の例
###私がラーメン屋に入り「ラーメン！ラーメン！」と叫ぶとします。
- ラーメンが二つ出てきた -> 2回のラーメンがそれぞれ別の同一性を持つ二つのエンティティと解釈した
- ラーメンが一つ出てきた -> 2回のラーメンが別の注文ではない(別の同一性を持たない)と解釈した
- ラーメン一つ？と聞かれた -> 2回のラーメンがそれぞれ別の同一性を持つと解釈したが一つの注文を二回発声しただけかもしれないので確認した

注文は注文を受け付ける前から料理を出した後まで存在するのでトランザクションより長い＝エンティティです。

###私がラーメンとラーメンの食券を出すとします
- ラーメンが二つ出てきた -> 二つの食券がそれぞれ別の同一性を持つと解釈した
- ラーメン二つ？と聞かれた -> 二つの食券がそれぞれ別の同一性を持つと解釈したが一つの注文を間違えて二回しただけかもしれないので確認した

※物理的存在は特に理由がなければ同一性を持ちますので二つの食券が一つの注文と解釈されることは有りません。黙ってラーメン一つだけ出てくるということはないでしょう

###私が大盛りラーメンの食券を出すとします
- この食券に書かれているだろう「ラーメン」の文字列はラーメンと呼ばれる何かを指す値オブジェクト
- この食券に書かれているだろう「大盛り」の文字列は盛り属性を指定する値オブジェクト

###私がラーメンの食券を出すとします
- ラーメン売り切れたからチャーシュー麺でいいよね？と食券が書き換えられた -> 食券のラーメン値オブジェクトがチャーシュー麺値オブジェクトに置き換えられた

###私がラーメンと大盛りの食券を出すとします
- 大盛りラーメンがでてきた -> 大盛りは「大盛り属性」値オブジェクトなので物理的存在にはならない。物理的存在になるラーメンの属性を大盛りにした
- ラーメンとラーメンでない何かがでてきた -> このラーメン屋では大盛りは属性ではなく「大盛りと呼ばれる何かの料理？」であり物理的存在になりえるのでそれを出した

###私がラーメンと味玉の食券を出すとします
- 味玉を載せたラーメンが出てきた -> ラーメンがルートエンティティであり味玉はその一部とした

味玉を食べずに味玉載せラーメンを完食することは可能でしょうか？味玉は味玉載せラーメンの一部となります。

###私がラーメンと大盛りと餃子の食券を出すとします
- 餃子をのせた大盛りのラーメンが出てきた -> ラーメンがルートエンティティと解釈した
- 大盛りラーメンと別の皿に餃子が出てきた -> 注文がルートエンティティでありラーメン（大盛り）と餃子がそれに含まれると解釈した


###私がラーメンと大盛りの食券を出すとします
- 「大盛りラーメンのお客さまー？」という私を探す声が聞こえた -> 提供先エンティティ（私）を見失ったので値オブジェクトでのマッチングで絞り込みを行った。
- 食券に席の番号を書き込んだ -> 提供先エンティティを見失わないように座っている席エンティティのIDを追加した
- 食券に「いつも大盛りラーメンの人」と書き込んだ -> 提供先エンティティを見失わないようにIDを追加した
- 食券に何かを書き込み半分にちぎって返してきた -> 食券と半券に注文のIDとなる何かを追加した（提供先エンティティを見失ってもIDでの突合せが可能）

なお、私や席は物理的に存在し同一性を持ちトランザクション以前も以後も存在するのでエンティティです。

###水はセルフサービスだった
- 水はトランザクションに含まれず生存期間は私の任意なのでエンティティとして扱う必要はない＝普通のオブジェクト。また、水に同一性は不要なので一杯の水と言う値オブジェクトとして扱ってもそう困らない。

###私が大盛りラーメンの写真を撮るとします
- これは大盛ラーメンのスナップショット

###私が大盛りラーメンを日記に書いたとします
- これも大盛ラーメンのスナップショット

###私が独りで大盛りラーメン食べたと日記に書いたとします
- 独りは大盛りラーメンの一部でもなければ属性でもない＝ラーメンの注釈（ラーメンへの関連）

###私がラーメン屋ではなくセルフうどん屋にいったとします
- 自分で盆に載せる＝自分のトランザクション内で同一性が保てれば十分＝同一性は私がローカルで保持するのでグローバルな同一性は不要＝盆やうどんはエンティティではない

#終わりに
注文を間違えるとお互いにつらいので同一性はしっかり保持しましょう。
勘違いしがちですが同一性とはなにもしなくとも有るというものではなく注文を間違えないように（IDを発行するなど）同一性を保つ工夫をするものです。
RaspberryPI にSSHログインしている最中、いまアクセスしているラズパイのモデルを知る

# 序
安いからといって複数モデルのラズパイを買い足していくと、
「いまアクセスしてるこれ、どれだっけ?」となることがあります(俺だけかも)。
そんなときのためのワンライナー[^1]。

[^1]: [neofetch](https://www.google.co.jp/search?q=neofetch&oq=neofetch) を使ってもいいんですが、出力が冗長すぎることと、ArchLinux や Fedora の aarch64 版だと Modelの項目が 'rpi' としか出てこないんですよ。ちなみに neofetch は 巨大 bash スクリプトで、特定ファイルの存在を判定してモデル名を決定しているのですが、ラズパイ向け aarch64 版にとっては存在確認するファイルの順番が変で、詳細なモデル名が書いてあるファイルよりもよりも 'rpi' 文字列が書かれているファイルのほうが先に見つかってしまうので、こちらのほうが優先されて出力されます。それゆえ私はラズパイに neofetch をインストール後、model 文字列判定部分を改造して利用しています.

# 確認したモデルとディストリビューション(2020/06/08再確認)

## モデル

- 2B(V1.1)
- 3B
- 3B+
- 4

(初代と Zero 系, CM は持っていないもので・・・すみません。)

## ディストリビューション
- Raspberry PI OS (buster)
- Raspberry PI OS 64bit beta (buster)

ファームウェアに依存するものなので、インストールできて、稼働させることができたならば、多分他のディストリでも大丈夫でしょう。

# 解決策

```shell-session
[hoge@fuga ~]$ cat `find /sys/firmware/devicetree -name model`
```
## 出力結果

- 4B

```shell-session
[hoge@fuga ~]$ cat `find /sys/firmware/devicetree -name model`
Raspberry Pi 4 Model B Rev 1.2%   
[hoge@fuga ~]$
```

- 3B+

```shell-session
[hoge@fuga ~]$ cat `find /sys/firmware/devicetree -name model`
Raspberry Pi 3 Model B Plus Rev 1.3% 
[hoge@fuga ~]$
```

- 3B無印

```shell-session
[hoge@fuga ~]$ cat `find /sys/firmware/devicetree -name model`
Raspberry Pi 3 Model B Rev 1.2% 
[hoge@fuga ~]$
```

- 2B(V1.1)

```shell-session
[hoge@fuga ~]$ cat `find /sys/firmware/devicetree -name model`
Raspberry Pi 2 Model B Rev 1.1%                                                                                                                                                           
[hoge@fuga ~]$
```

この値を bash の case 文などの判定文字列として利用すれば、
モデルに応じた処理ができますね＼(^o^)／

(ただし、今後、出たばかりのモデルでは、Raspbian 以外のディストリで変な結果を吐き出す可能性もあるので注意)

以上
imagemagickで画像のリサイズ

imagemagickで画像のリサイズを行う時、

## 1ファイルずつ

```sh:1ファイルずつ
# 縦横比を維持したままリサイズ。指定サイズ内に収まるように縮める
convert -resize 1366x768 input.png output.png

# 縦横比を無視して強制リサイズ
convert -resize 1366x768! input.png output.png
```

## 複数画像

````sh:複数画像を一斉にリサイズ
# 縦横比を維持したままリサイズ。指定サイズ内に収まるように縮める
mogrify -resize 1366x768 *.png

# 縦横比を無視して強制リサイズ
mogrify -resize 1366x768! *.png
```

## .psdをpng化

```sh:合成レイヤーのみ
convert input.psd[0] output.png
```

## 圧縮

リサイズをした後、ファイルサイズが大きいため、以下オンラインサービスで縮小すると良い。
https://imagecompressor.com/ja/
【C#】ゲッター・インデクサはラムダ式にすると読み書きしやすかった

ラムダ式と言えばメソッド定義で使うことが多いです。

```c#:LINQでラムダ式で匿名メソッド
int[] numbers = { 1, 7, 0, 4, 3, 7, 9, 2, 5, 8 };
int count = numbers.Count(n => n > 4);
Console.WriteLine($"4を超える数は{count}つです。"); // 4を超える数は5つです。
```

```c#:ラムダ式でインスタンスメソッド定義
class Greeter {
  public void Greeting() =>
    Console.WriteLine("Hello world!");
}

var greeter = new Greeter();
greeter.Greeting();  // Hello world!
```

ラムダ式は読みやすく書きやすいので好きです。
調べていたらゲッターやインデクサでも使うことができることを知りました。

## ゲッターをラムダ式で定義する

```c#
class Product {
  public double Price { get; set; }
  // ↓ ラムダ式で読み取り専用プロパティを定義
  public double IncludeTaxPrice => Price * 1.08;
}

var daifuku = new Product { Price = 100 };
Console.WriteLine($"税込価格は{daifuku.IncludeTaxPrice}です");
  // 税込価格は108です
```

ラムダ式によるメソッド定義によく似ていますが、
プロパティ名の後に`()`がありません。

- 副作用を起こす処理
- 重い処理
 
はゲッターでなくメソッドにするとよいと思います。

従来の書き方では`{{}}`で囲む必要があり、`get`や`return`などのノイズが多いです。

```c#
public double IncludeTaxPrice { get { return Price * 1.08; } }
```

また、`return`の代わりに`get`の本体をラムダ式にすることもできます。

```c#
IncludeTaxPrice { get => Price * 1.08; }
```

## インデクサをラムダ式で定義する

インデクサでもラムダ式が使えます。
ゲッターと同様に読み取り専用の場合、特に読みやすくなります。

```c#:本棚クラス
class Bookshelf {
  readonly IList<Book> books = new List<Book>();

  // ↓ 読み取り専用のインデクサがスッキリかける
  public Book this[int index] => books[index];

  public void Add(Book book) => books.Add(book);
}

class Book {
  public string Title { get; }
  public Book(string title) => Title = title;
}
```

```c#
var bookshelf = new Bookshelf();
bookshelf.Add(new Book(title:"幼年期の終り"));
bookshelf.Add(new Book(title:"1984年"));
bookshelf.Add(new Book(title:"アンドロイドは電気羊の夢を見るか"));

// インデクサ経由で Book オブジェクトを取り出す
var book = myshelf[1];
Console.WriteLine(book.Title); // 1984年
```

## 余談

コンストラクタもラムダ式で定義することができます。

```c#
class Logger {
    readonly TextWriter writer;
    // コンストラクタでプライベートフィールドを初期化する
    public Logger(TextWriter writer) => this.writer = writer;
    public void WriteLog(string text) => writer.WriteLine(text);
}
```

```c#
var consoleLogger = new Logger(writer: Console.Out);
consoleLogger.WriteLog("コンソールに出力");

using (var writer = new StreamWriter("log.txt")) {
    var fileLogger = new Logger(writer);
    fileLogger.WriteLog("ファイル書き込み");
}
```

ただ、コンストラクタはゲッターやメソッドと見間違ったり、
設計中に引数が増減する機会も多く書き直す手間を考えると個人的にブロックで書く派です。
`return` もないので`{}`と`=>`の違いくらいしかないです。

プロパティもラムダ式で書けますが、自動実装プロパティのほうが簡単でしょうか。

```c#
class Circle {
    public double Radius { get; set; }
    /*
     * ラムダ式で書くとこれだけ必要...
     * double radis;
     * public double Radius { get => radis;　set => radis = value; }
     */
    public double Area() => Radius * Radius * Math.PI;
}
```
bluetoothの研究　その4

#概要
bluetoothを理解したかった。
pythonでrfcommサーバしてみた。

環境
android nexus7
raspberry pi 1 b
raspbian jessie 8.0
bluetooth dongle cambridge silicon radio

#設定

sudo nano /etc/systemd/system/dbus-org.bluez.service

```
ExecStart=/usr/lib/bluetooth/bluetoothd --compat
ExecStartPost=/usr/bin/sdptool add SP
```

#インストール

sudo aptitude install python-bluez

#pythonでrfcommサーバー

```
import bluetooth

server_sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
port = 1
server_sock.bind(("", port))
server_sock.listen(1)
client_sock, address = server_sock.accept()
print "Accepted connection from ", address
data = client_sock.recv(1024)
print "received [%s]" % data
client_sock.close()
server_sock.close()
```

以上。
bluetoothの研究　その3

#概要
bluetoothを理解したかった。
ラズパイとandroidをペアリングしてみる。

#環境
android nexus7
raspberry pi 1 b
raspbian jessie 8.0
bluetooth dongle cambridge silicon radio

#手順1　android
設定を開く。bluetoothを開く。周辺のすべてのbluetoothデバイスに表示にする。

#手順2　raspberry
bluetoothctlを実行。
scan onして、androidを見つける。
pair アドレスする。

#手順3　android
許可する。

以上。
超ざっくりと理解する無名関数（匿名関数）


## これは名前付き関数
```
function hello (name) {
 
       var msg = "hello" + name;
       return msg;
}

 var greet = hello("Taro") ;

console.log(greet);
//出力結果 "hello Taro"
 
```
こちらの関数には「hello」という<b>名前</b>が付いています。

## これが無名関数
```
var hello = function(name) { 

            var msg = "hello " + name;

            return msg;
        };

        var greet = hello("Tom");

        console.log(greet);
```
関数を関数名と同じ変数に代入することで、関数を無名にできるのです。

イメージは以下のような感じでしょうか？

![スクリーンショット 2018-07-13 7.19.31.png](https://qiita-image-store.s3.amazonaws.com/0/214529/1922184e-5d03-447b-9254-591c97f75775.png)
[※ちなみに同じ名前の変数じゃなくても問題ないです。](https://wa3.i-3-i.info/word15754.html)



## 参考
https://dotinstall.com/lessons/basic_javascript_v2/26713