OmniAICreator/Qiita-1.07M huggingface dataset:
JSONExport

# JSONExportの使い方

### REST API の JSON Mapping Modelを作成する
ここでは `POST /api/users/login` を例とする。

#### Request

 * Jsonを添付する
 * `Root class name` に `/` 区切りで `PascalCase` にしたpathを設定する。 例：UsersLogin
 * `Classes prefix` に pathを省略した3文字 + method名 + Request を設定する。例：ULIPostRequest
 * `Swift - Struct` で `Save` する
 * `public` 演算子を付与する。例：全て(struct, var, init, func)
 * `publicイニシャライザ` を追加する。引数は、必須項目は非オプショナル、オプション項目はオプショナル型で宣言する

#### Response

 * Jsonを添付する
 * `Root class name` に `/` 区切りで `PascalCase` にしたpathを設定する。 例：UsersLogin
 * `Classes prefix` に pathを省略した3文字 + method名 + Response を設定する。例：ULIPostResponse
 * `Swift - Struct` で `Save` する
 * `public` 演算子を付与する。例：全て(struct, var, init, func)
 * `AnyObject` 型になっている変数を `String or Int etc.` にする。value が nullの場合、AnyObjectに置き換わるため
 *  nullが入らない変数は、 `暗黙的アンラップ型` から `非オプショナル型` に変更する
 *  nullが入りうる変数は、 `暗黙的アンラップ型` から `オプショナル型` に変更する

#### トラブルシューティング

 * JSON内のKeyで被っていて、構造に差異があるある場合、別名クラスにする必要がある。例：ULIPostResponseData.swift と ULIPostResponseRoleData.swift
htmlの基礎

ドットインストールのhtmlの基礎講座を受講したので、学んだことをアウトプットします。
実際のところ、理解が追いついていないので、細かい知識は後からインプットし直します。

##htmlでできること
ホームページを作る時に必要な技術。
構造的な文章が書けるようになる。


##タグと属性
タグは文章を意味付けするのに使われる。<タグ>文章</タグ>みたいな感じで使われる。
属性はタグに情報を加えるのに使われる。<タグ　属性名＝値>=文章</タグ>といった風に使う。また、属性は一つだけでなく二つや三つ付けることもできる。

##色々なタグや属性がある
htmlの最初は、
<!DOCTYPE html>（HTMLでコード書くよ）
<html lang="ja">（日本語で書くよ）
といったようにする。
他にも文字コードをutf8にするといったような指令も出す。

さっき書いたタグや属性には色々種類がある。meta,link,styleタグやid,class,style属性とか。

##セクション
header
footer
nav:ナビゲーションのタグ
article:メインのコンテンツ。独立している。
aside:副次的なコンテンツ
section:それ以外の情報の塊
h1~h6:セクションごとの見出し

##セクションより細かいグルーピング
p:段落
hr:水平線
pre:改行や字下げを保持
blockquote:引用
div:スタイリング

##リスト
ol:順番があるリスト
ul:箇条書きのリスト
li:list item
dl:definition list
dt:definition term
dd:definition description


##最後に
講座を受講して思ったことは、実際にコード通りに動いたら気持ち良いなということです。現段階では、マネしてるだけですが・・・
これからも頑張っていきます。
ColorUtils を使って Android で色差を簡単に求める

Android で簡単に色差を求めたいけど、単純に RGB 色空間上でのユークリッド距離だと人間の感覚と合わないからなあ、、と思って調べると、 ColorUtils というクラスで簡単に Lab 色空間上の距離を求めることができました。
Lab 色空間は人間の視覚特性に合うように考えられた色空間で、その距離を取ることで人間の感覚に近い色の距離を求めることができます。

もう少し具体的な話は[ブログ](https://kawmra.hatenablog.com/entry/2018/08/06/030310)に投稿しましたので、よろしければご覧ください。

# ColorUtils

ColorUtils クラスは support-v4 ライブラリに含まれている色に関する便利な機能を提供するクラスで、 色差を求めるための `distanceEuclidean()` というメソッドがあります。
このメソッドは２つの Lab 色空間で表された色を引数に受け取り、それらのユークリッド距離を求めて返します。

ColorUtils には色空間を変換するメソッドも多数用意されており、 `ColorUtils.RGBtoLAB()` や `ColorUtils.colorToLAB()` メソッドを使用することで RGB 色空間を Lab 色空間に変換することができます。

これらを組み合わせることで、簡単に色差を求める事ができました。

# 色差を求める

２つの色から色差 (Lab 色空間上でのユークリッド距離) を求めるには次のようにします:

```kotlin
val labArray1 = DoubleArray(3).also {
  ColorUtils.RGBtoLAB(r1, g1, b1, it)
}
val labArray2 = DoubleArray(3).also {
  ColorUtils.RGBtoLAB(r2, g2, b2, it)
}
val distance = ColorUtils.distanceEuclidean(la1, labArray2)
```

または、 `0xFF0088FF` などの `@ColorInt Int` を用いて

```kotlin
val labArray1 = DoubleArray(3).also {
  ColorUtils.colorToLAB(colorInt1, it)
}
val labArray2 = DoubleArray(3).also {
  ColorUtils.colorToLAB(colorInt2, it)
}
val distance = ColorUtils.distanceEuclidean(la1, labArray2)
```
前処理関係の備忘録(to_numeric)


## 1. 文字列を含んだ行(object)を強制的に数値(float64)のみの行に変換する。
csvから数字を読み込んだはずなのに、型がfloat64でなくobjectとなってしまう場合、
数字以外に文字列が含まれてしまっている。
膨大なファイルだと探すのが面倒だが、pandasにはto_numericという関数がある。
これを使うと文字列をNaNに変えてくれることを、今更知った。

使い方

```python
df['column0']=pd.to_numeric(df['column0'],error='coerce')
```

例：

```python
# sample dataとしてirisを用意。
from sklearn.datasets import  load_iris
import pandas as pd
df=pd.DataFrame(data.data)

#data=load_iris()
#df.iloc[1,0]='asdfasfasdf'
#df.info()
#<class 'pandas.core.frame.DataFrame'>
#RangeIndex: 150 entries, 0 to 149
#Data columns (total 4 columns):
#0    150 non-null object   <--- object!!!
#1    150 non-null float64
#2    150 non-null float64
#3    150 non-null float64
#dtypes: float64(3), object(1)
#memory usage: 4.8+ KB



# 文字をNaNに変換し、行をfloat64型に変換する。
df[0]=pd.to_numeric(df[0],errors='coerce') 

df.info()

#<class 'pandas.core.frame.DataFrame'>
#RangeIndex: 150 entries, 0 to 149
#Data columns (total 4 columns):
#0    149 non-null float64    <--- object が float64　になった。
#1    150 non-null float64
#2    150 non-null float64
#3    150 non-null float64
#dtypes: float64(4)
#memory usage: 4.8 KB

# Nanの処理
df.dropna(inplace=True) # NaNの扱いは.fillna()や.dropna()
```

参考：　dataCamp
pandasの1重と２重括弧の違い

# pandasの２重括弧について

DataFrameから特定のcolumnをdf['column']取り出すと、typeがSeriesになってしまい、扱いにくい場合がある。実は２重カッコを使うと、DataFrameとして取れるので、こっちの方が便利。

```python
# df1 is Series
df1=df['column0']   # Series

# df2 is DataFrame
df2=df[['column0']] # DataFrame 

```
Androidお天気アプリ

https://play.google.com/store/apps/details?id=com.websarva.wings.android.asyncsample

テストでアプリを作成しました。
もしよろしければダウンロードと、そのアプリに対するコメントをお願いします。

初投稿でまだまだしっかりとしたアプリとは言えませんがよろしくお願いします！！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/240422/fbb2daf8-6b2d-27c1-740b-553a2440551c.png)
Linuxのディレクトリ移動について

#はじめに
Linuxサーバーにsshして作業をするときは、頻繁にディレクトリを移動することになるかと思いますが、最近新しい移動コマンドを覚えましたので以下に記載します。

##cdコマンドの基本

基本的には、以下の通り`cd`コマンドの引数に移動したいディレクトリを指定します。
`pwd`コマンドは現在位置するディレクトリを表示するコマンドです。

```shell
[shota@hostname ~]$ pwd
/home/hoshis
[shota@hostname ~]$ cd /var/tmp/
[shota@hostname tmp]$ pwd
/var/tmp
```

上記の通り、基本的には移動するディレクトリを指定すれば良いのですが
何回も移動するときに毎回ディレクトリを指定するのは少し煩雑です。

##popd、pushd
こちらが、はじめにで触れていたコマンドの`popd`、`pushd`です。

①先ずは、`pushd`

```shell
[shota@hostname ~]$ pwd
/home/shota
[shota@hostname ~]$ pushd /var/tmp/
/var/tmp ~
[shota@hostname tmp]$ pwd
/var/tmp
[shota@hostname tmp]$ pushd /usr/bin/
/usr/bin /var/tmp ~
[shota@hostname bin]$ pwd
/usr/bin
```

使い方は`cd`コマンドと同様に移動したいディレクトリを引数に指定するとそのディレクトリに移動できます。

②次は、`popd`

```shell
[shota@hostname bin]$ pwd
/usr/bin
[shota@hostname bin]$ popd
/var/tmp ~
[shota@hostname tmp]$ pwd
/var/tmp
```

popdで前回移動したディレクトリに、戻ることができます。上手く使えば、毎回ディレクトリを指定する手間が省けるため便利です。

##おまけ
`cd`コマンドは引数を指定しないで実行するとユーザーのホームディレクトリへ移動します。

```shell
[shota@hostname tmp]$ pwd
/var/tmp
[shota@hostname tmp]$ cd
[shota@hostname ~]$ pwd
/home/shota
```

また、`cd -`といったように"-"（ハイフン）を引数にすると、以前いたディレクトリに移動できます。
※@tenmyoさん、補足いただきありがとうございます。

```shell
[shota@hostname tmp]$ pwd
/var/tmp
[shota@hostname tmp]$ cd
[shota@hostname ~]$ pwd
/home/shota
[shota@hostname ~]$ cd -
/var/tmp
[shota@hostname tmp]$ pwd
/var/tmp
```
TIC-80 初心者講座: config コマンドで設定を変更してみよう

TIC-80 は、無料でオープンソースな架空のレトロゲーム機です。Windows,Mac,Linux,Android,ラズパイなどで動作します。詳細は [まとめページ](https://qiita.com/yamachan360/items/3544a96f0dbea31224be) から。

# 設定メニューはどこ？

TIC-80 を起動して戸惑うのは、アプリケーション自体の設定メニューが見あたらないないことです。

[Wiki](https://github.com/nesbox/TIC-80/wiki#console) のコマンド一覧を見ると、以下のコマンドがあることがわかります。

* `config [save | default]` - Show config.tic file editor, use save param to save current configuration, use default to edit default cart template

【訳】config.tic ファイルエディタを開きます。現在の設定を保存するには save パラメーターを指定し、全てを初期値に戻すには default パラメーターを指定してください。

# 設定を変更してみる

TIC-80 を起動していると、右上にたまに赤字で SYNC と表示されます。この表示を設定で OFF にしてみましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/193519/89fe74f2-28ee-f761-9a42-74551890a127.png)

まずは `config` コマンドを実行します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/193519/69112a62-9d24-6ba4-9263-49fe976e44db.png)

カートリッジ用のフォルダに .local というフォルダがあり、そこから `config 0.60.3.tic` というカートリッジファイルが読み込まれていることがわかります。以下のファイルですね。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/193519/6195e52b-4421-94ec-afd6-c6e145698b6c.png)

さて、この状態で **F1 キー** を押して、Code Editorを開きます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/193519/0ad674c4-3e8e-caf9-1b5a-846eee73b058.png)

と、設定ファイルらしきもの (実際には単にLUAのプログラム) が開きます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/193519/fa04a7b4-4b38-ad48-1e65-f7aa054949d2.png)

下のほうに `USE_VSYNC` の値を設定している行がありますので、ここを true から false に変更します。変更したら、**ESC キー** でコンソールに戻りましょう。

さて、保存するため `config save` コマンドを…

![image.png](https://qiita-image-store.s3.amazonaws.com/0/193519/185f6985-a4a0-6029-4582-336e2c12e184.png)

実行してもエラーになりますね。ここは代わりに `save` コマンドで設定 (実態はカートリッジ) を保存しておけば大丈夫なようです。

TIC-80 を再起動すると、保存した設定が反映されて、右上に赤い SYNC が表示されなくなっています。

# フォントで遊んでみる

この設定ですが、実は面白い機能があります。TIC-80 で使用されている標準フォントを、自分好みに修正することができるのです。

`config` コマンドで設定用のカートリッジを呼び出したあと、**F2 キー** で Sprite Editor を開いてください。右上にある `FG` をクリックしてフォアグラウンド(前景)用のスプライト設定を開きます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/193519/142574d1-dfab-6db4-f7fd-bdfdbcfc1dd0.png)

ここで表示されている文字の画像のうち、上半分の128文字が、TIC-80 で使用される標準フォントとして取り込まれます。

テストのため、大なり記号文字(＞)をちょっと修正してみましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/193519/5b902a28-3a99-701e-a607-9e734b93d50c.png)

コンソールに戻った時点で既に反映されていると思いますが、せっかくですので `save` コマンドで修正をファイルに保存します。そして TIC-80 を再起動しても、自身が設定したフォントが引き続き使用されていることを確認してみてください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/193519/38d32e96-b4df-acdd-ba9e-ecc4a7d7c5e5.png)

## ちょっとした注意点

フォントの変更は面白い機能ですが、あくまで自身の実行環境における **ローカルな設定** であることに注意が必要です。ここで変更したフォントを自分のゲームで利用した場合、他の人の環境で実行されてもその文字は出ない、ということです。

これを逆手にとって、標準では空白の領域がけっこうありますので、自分なりの記号を定義して遊んでも面白いかもしれませんね。他人には表示できない文字でコメント欄や、表示文字列に秘密のメモを残しておく？みたいなことが可能かもしれませんw

# 設定を標準に戻す

さて、いろいろ遊んだので、念のため設定を初期値に戻しておきましょう。とりあえず楽で安全なのは、TIC-80 をいったん終了して、設定ファイルを直接削除することです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/193519/6195e52b-4421-94ec-afd6-c6e145698b6c.png)

削除後、TIC-80 を起動すれば、初期化された設定ファイルが再作成されます。

# TIC-80 に興味をもったら

[無料でオープンソースな架空のレトロゲーム機「TIC-80」に関するまとめ](https://qiita.com/yamachan360/items/3544a96f0dbea31224be) ページを参考にしてみてください。

ではでは。
GitHubのコメントを一括で開閉できるブックマークレット

# コメントを全部開くのが大変
- レビューが進むにつれていつの間にかコメントが閉じていて、開かないと中身が分からない時などありますよね。全てを見たい時にコメントが多いと全部開くのが大変です。（こんな時↓

　　![スクリーンショット 2018-08-06 0.09.32.png](https://qiita-image-store.s3.amazonaws.com/0/106805/5e8392ee-b4cb-45a3-6cb2-77dc01705f19.png)

# そんな時は
- ブラウザのブックマークに以下のスクリプトを登録して、ボタンを押すと一気に開閉を行うことができます。

　　![スクリーンショット 2018-08-06 0.01.49.png](https://qiita-image-store.s3.amazonaws.com/0/106805/977c5326-4239-9b02-2f57-a9727dba067a.png)

```javascript

javascript:
var outdated = Array.from(document.getElementsByClassName('outdated-comment'));	
var details = Array.from(document.getElementsByClassName('Details-element'));
var concated = outdated.concat(details);
if (document.querySelectorAll('details[open]').length>0) {	
	concated.forEach(l => l.removeAttribute('open'));
} else {	
	concated.forEach(l => l.setAttribute('open', ''));
}
```
- `Conversation` と `Files change` のページのどちらでも使うことができます。
- というか、公式がこの機能を用意してくれればいいのに...

# 参考
- 以前はこちら↓を参考にしたのを使っていたけど、GithubのDOMの構成が変わって機能しなくなってしまったので新しく作り直しました。

Qiita [GitHubのプルリクでoutdated diffへのコメントが閉じてるのを全部開く](https://qiita.com/shingo-nakanishi/items/129188bd3885d22d9477)
動的型付けと静的型付け

#**静的型付け**
変数を宣言する時、その変数のデータ型が実行前に決まるのが静的型付け。
データ型とはデータの種類を表すもの。String(文字列)やBoolean(真偽値)とか
CやJava、Goとかがそうらしい

C言語だとこんなかんじ

```test.c
#include <stdio.h>

int main(void) {
  int value; //int型(整数)でvalueという変数を宣言
  return 0;
}
```
#**動的型付け**
静的型付けに対して、変数宣言時に型を示す必要がない。
プログラムの実行時に変数に入るデータの型が動的に変わる。
P言語やRubyは動的型付け

Rubyだと

```test.rb
value = "hogehoge"
```
parted の Warning: The resulting partition is not properly aligned for best performance に対処する

最近のHDDは容量が大きく、GPT的なパーティションを作成する必要があります。そんなとき Linux では parted を使うわけですが、`partd /dev/sdx mklabel gpt` したあと `partd /dev/sdx mkpart ...` したときに次のような警告が表示されることがあります。

```
# parted /dev/sdh mkpart primary ext4 <開始> <終了>
Warning: The resulting partition is not properly aligned for best performance.
Ignore/Cancel?
```

ググると、いくつかの解決方法が出てきます

* /sys 配下の情報をもとに開始、終了位置を計算する
* 開始に `1` を、終了に `-1` を指定する
* -a optimal を使う
* etc.

環境によって異なる可能性はありますが、少なくとも私の環境では上記の方法では解決しませんでした。
解決するには、 `-a optimal` をつけた上で、かつ、開始終了ともに `%` 表記で指定すればOKです。

```
# parted -a optimal /dev/sdh mkpart primary ext4 0% 100%
```

mklabel から通して書くと、

* 現状のラベル、パーティションを確認

```
# parted /dev/sdh print
Error: /dev/sdh: unrecognised disk label
Model: ASMT 2105 (scsi)
Disk /dev/sdh: 6001GB
Sector size (logical/physical): 512B/4096B
Partition Table: unknown
Disk Flags:
```
* GPTラベルを付与

```
# parted /dev/sdh mklabel gpt
Information: You may need to update /etc/fstab.

```
* ラベルがついたことを確認

```
# parted /dev/sdh print
Model: ASMT 2105 (scsi)
Disk /dev/sdh: 6001GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:

Number  Start  End  Size  File system  Name  Flags

```
* パーティション作成。 `-a optimal` オプションをつけ、開始終了は `%` 表記にする。

```
# parted -a optimal /dev/sdh mkpart primary ext4 0% 100%
Information: You may need to update /etc/fstab.

```
* パーティションを確認

```
# parted /dev/sdh print
Model: ASMT 2105 (scsi)
Disk /dev/sdh: 6001GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:

Number  Start   End     Size    File system  Name     Flags
 1      33.6MB  6001GB  6001GB               primary

```
Laravel 5 ErrorException (E_ERROR) Class 'HTML' not found はタイプミス

Laravel5 で view を書いていたらエラーがでました。

#　HTML Class が無いとエラー

```
ErrorException (E_ERROR)
Class 'HTML' not found (View: /var/www/laravel/resources/views/pugiemonn/index.blade.php)
```

![寿司ゆき:confused](https://d1zd1v0cxnbx2w.cloudfront.net/images/sets/sushiyuki/56.png) 
# よく見ると
よく見て気づいたのですが、**HTML**という表記が間違っていました。

```diff:index.blade.php
- {!! HTML::link('/pugiemonn/, $creator, ['id' => 'pugiemonn']) !!}
+ {!! Html::link('/pugiemonn/, $creator, ['id' => 'pugiemonn']) !!}
```
Html でした。頭文字だけ大文字でした。きづかなかった(☝ ՞ਊ ՞)
HTMLの基本

#はじめに
progateにて、HTMLの勉強を始めたのでメモ帳のように使って行きたいと思います。
タグを視覚化するためにこちらの記事を参照
<a href = "https://qiita.com/motoakim/items/71add1daf55ea05bf4c5">HTML文章を視覚化し、そのまま文章として表示する</a>

#タグ一覧
##&lt;h1&gt;&lt;/h1&gt;
見出し
&lt;h1&gt;&lt;/h1&gt;〜&lt;h6&gt;&lt;/h6&gt;
まであり&lt;h1&gt;&lt;/h1&gt;が一番が大きい
##&lt;p&gt;&lt;/p&gt;
段落
言葉通り段落用のタグ
##&lt;a&gt;&lt;/a&gt;
リンクを埋め込むタグ
画面に出したい文字をタグで挟み、リンク先は
&lt;a href = &quot;hoge&quot;&gt;ここに画面に出す文字"&lt;/a&gt;
のhogeの部分に書く
##&lt;img&gt;
画像を埋め込むタグ
&lt;img src = &quot;hoge&quot;&gt;
のように書く
(hogeの位置に画像のリンクを書く)
##&lt;li&gt;&lt;/li&gt;
リストを作るときに使用。
&lt;ul&gt;&lt;/ul&gt; や&lt;ol&gt;&lt;/ol&gt;
など親要素によって文頭が変わる
例:
&lt;ul&gt;
  &lt;li&gt;hoge1&lt;/li&gt;
  &lt;li&gt;hoge2&lt;/li&gt;
&lt;/ul&gt; 
&lt;ol&gt;
  &lt;li&gt;hoge3&lt;/li&gt;
  &lt;li&gt;hoge4&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;&lt;/ul&gt;で挟むと文頭に黒点が付き
&lt;ol&gt;&lt;/ol&gt;で挟むと数字が着く
##&lt;!DOCTYPE html&gt;
HTMLのバージョンの宣言
htmlファイルの先頭に書くもの(？)
勉強していて「違うな」と思ったら訂正します。
##&lt;head&gt;&lt;/head&gt;
①文字コードの指定
②ページのタイトル
③CSSの読み込み
(CSSについては別の記事で書くかもです)
を行うタグ
例①：&lt;meta charset=&quot;utf-8&quot;&gt;
文字コードを指定してあげることで文字化けを防ぐ
utf-8がHTML5で推奨されている
例②：&lt;title&gt;hoge&lt;/title&gt;
hogeがブラウザのタブに出る
例③：&lt;link rel=&quot;hogehogehoge&quot; href=&quot;hogehoge.css&quot;&gt;
##&lt;div&gt;&lt;/div&gt;
要素のグループ化に使用
これに関してはCSSも一緒に説明しないとわかりづらい。。。
##まとめ

書いていくうちにCSSについても書いていかないとわかりづらいことに気づいたので
この記事に追記していくか別で書くかしようと思います。
DurableFunctionsを試してみる

# 今回の目的
DurableFunctionsの利用方法を理解する。

- [DurableFunctionsの概要](https://docs.microsoft.com/ja-jp/azure/azure-functions/durable-functions-overview) に記載されている"パターン #1: 関数チェーン"の動くサンプルを作ってみる。

## 検証の前提 
隙間時間を利用して技術検証等を行うためマシンに依存せずに作業ができるようにブラウザオンリーで実施可能な内容としている。
（ブラウザオンリーでの開発に固執中 - 8月下旬に入手予定のSurface Goで空いた時間を有効利用できたら…と夢想中）

## 題材
AWS Lambdaの設定画面上だけで実装を続け、長大になってしまったLine Botの処理(Node.js)を分割しDurableFunctionsを利用して順次処理させるようにする。
AWS LambdaからAzure Functionsへの移行は[完了済み](https://qiita.com/KasaharaJumpei/items/3dad47ad7fa98f88e7d6)。

- DurableFunctionsを利用すると、処理を非同期で依頼した後に、処理のステータスを問い合わせることもできるが、今回は行なわない。

# 個人的な結論（感想）
理解を深めていけば、使いどころが色々とありそう。
[DurableFunctionsの概要](https://docs.microsoft.com/ja-jp/azure/azure-functions/durable-functions-overview) に記載されている各パターンについて理解し、使いどころを見出していきたい。

# 注意点
現時点（2018/08/05）では下記制限がある。

- ブラウザ上からの開発では言語はC#しか選択できない。 
- Function App作成時にランタイム バージョンでbetaを選択する必要がある。

# 試した手順
下記手順でLine Botから呼び出せるモノを作成。

1. Function App作成
 -  ランタイム バージョンで"beta"を選択。
 -  その他はデフォルト値を選択。
<br/><br/>
1. 関数を作成
 - 「Durable Functions HTTP starter」「Durable Functions orchestrator」「Durable Functions activity」をそれぞれ生成する。
 - 生成した「Durable Functions HTTP starter」の編集画面にて"関数のURLの取得"を選択し処理を呼び出すためのURLを確認する。        
![functionurl.png](https://qiita-image-store.s3.amazonaws.com/0/157737/8d3a23f2-80ce-9655-115d-13b3697e1de4.png)
<br/><br/>
 - Curl等で上記URLを呼び出すことで「Durable Functions activity」が呼び出せることを確認。
![functionurlsub.png](https://qiita-image-store.s3.amazonaws.com/0/157737/aff602df-7c46-a2c6-2d28-3a7d5249e72f.png)

		functionName部分には「Durable Functions orchestrator」の名称（例：HelloSequence）を指定。
<br/>
1. Line Botから作成した関数を呼び出す。
 - パラメータはPostパラメータとして渡すことが可能。
 - 「Durable Functions HTTP starter」Runメソッドのパラメータ"HttpRequestMessage req"から取得可能。  

上記までできれば、後は元の処理をC#化しながら複数の「Durable Functions activity」として分割していく。

参考とさせていただいた記事：[LineSimulatorを利用してDurable FunctionsでロングランなLineBotをローカル環境交えて作ってみる](http://blog.kokoni.jp/2017/12/11/durable-functionsでロングランなlinebotをローカル環境交えて作っ/)
この記事を参考とすれば、処理を非同期で依頼した後に、処理のステータスを問い合わせることが可能。
php-master-changes 2018-08-05

# 2018-08-05

少ない日はよゆう

## petk: Remove outdated comment with PEAR xmlrpc dependency
- https://github.com/php/php-src/commit/99020cc085063819ab6cecb5a4594b90d0ec6e7f
- PEAR のインストールに xmlrpc 拡張が必要という今では嘘になった記述をビルドスクリプトから削除

## cmb69: Fix #76706: mbstring.http_output_conv_mimetypes is ignored
- https://github.com/php/php-src/commit/70ecb6e50b983419f6a2d5e028f9779354047ec1
- ext/mbstring が mbregex サポートなしでビルドされた際、mbstring.http_output_conv_mimetypes が基本的に無視される問題の修正

## cmb69: Add missing skip conditions
- https://github.com/php/php-src/commit/a003af5b62f802da5e1e0563741284cb5e622957
- mbregex サポートなしで ext/mbstring がビルドされた際、一部テストをスキップするよう修正

## carusogabriel: Make test run on non debug builds
- https://github.com/php/php-src/commit/37245e63ca30fb334411132aedba8eeffcb2ef33
- テストが非デバッグビルドでも動くよう修正
- 非デバッグビルドでも動くべきコードではあるけれど、敢えてスキップ外すようなものかなあ、というなんとなくの疑問はあったりする
ターミナルからTimeMachineのバックアップを削除して使用可能領域を増やす

※ 当たり前ですが自己責任でやってください。筆者はエラーに何度か遭遇しました。直ったけど。トラブルシューティング参照。
実行した環境はTimeCapsuleに保存したTimeMachineです。

# 基本的なやり方
念のためTimeMachineの自動バックアップをオフにしておく。[^5]
![image.png](https://qiita-image-store.s3.amazonaws.com/0/94/cceeb211-b0c7-f0fe-c1bd-e47dc9c8f4ff.png)

`tmutil listbackups`でバックアップを確認する

```
$ tmutil listbackups
/Volumes/Time Machine バックアップ/Backups.backupdb/takc923 の MacBook Pro/2017-11-03-001721
/Volumes/Time Machine バックアップ/Backups.backupdb/takc923 の MacBook Pro/2017-11-10-013213
/Volumes/Time Machine バックアップ/Backups.backupdb/takc923 の MacBook Pro/2017-11-17-012823
/Volumes/Time Machine バックアップ/Backups.backupdb/takc923 の MacBook Pro/2017-11-24-011152
略
```

`sudo tmutil delete`で削除する[^1]。私の環境だと40分くらいかかった。

```
$ sudo tmutil delete '/Volumes/Time Machine ハ<3099>ックアッフ<309a>/Backups.backupdb/takc923 の MacBook Pro/2017-08-27-024822'
Password:
Deleting: /Volumes/Time Machine バックアップ/Backups.backupdb/takc923 の MacBook Pro/2017-08-27-024822
Deleted (4.4G): /Volumes/Time Machine バックアップ/Backups.backupdb/takc923 の MacBook Pro/2017-08-27-024822
```

これだけだとsparsebundleファイルのサイズが小さくならないので、これを小さくする。
その操作の前に、データが壊れないようにバックアップボリュームをデタッチする。

```
$ hdiutil detach /Volumes/Time\ Machine\ バックアップ
"disk2" unmounted.
"disk2" ejected.
```

sparsebundleファイルを小さくする[^2]。私の環境だと1時間くらいかかった。

```
$ hdiutil compact /Volumes/takc923/takc923\ の\ MacBook\ Pro.sparsebundle
圧縮を開始中…
空き領域を再び利用可能にしています…
...................................................................................................................................................................................
圧縮の仕上げ中…
空き領域1.1 TBのうち13.5 GBを再び利用可能にしました。
```

# １コマンドで複数消す
こんなコマンドで一番古いバックアップを3つ消せる。

```
$ tmutil listbackups | head -3 | sed 's/ /\\ /g' | sudo xargs tmutil delete
```

注意点は、パス名に半角スペースが混じっていて、それが文字列の切れ目だと認識されてしまうので間の`sed 's/ /\\ /g'`が必要。[^3]

# TimeMachineのサイズを制限する
若干タイトルからずれるけど、あとちゃんと動作の確認してないけど、TimeMachineのサイズを制限できるらしい。
以下のコマンドで制限できる。最後の引数が制限したいサイズ（bytes）[^6]。実行した後再起動したら反映されるらしい。

```
$ sudo defaults write /Library/Preferences/com.apple.TimeMachine MaxSize 858993459200
```

# トラブルシューティング
こんなエラーが出て肝を冷やした。

```
$ hdiutil compact /Volumes/takc923/takc923\ の\ MacBook\ Pro.sparsebundle
圧縮を開始中…
空き領域を再び利用可能にしています…
hdiutil: compact failed - 内部エラーです
```

手動で一回TimeMachineのスナップショット取ったら直った。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/94/bd80e6f0-5557-1e0a-ef76-62488a8a053d.png)

こんなエラーも出た。

```
$ hdiutil compact /Volumes/takc923/takc923\ の\ MacBook\ Pro.sparsebundle
hdiutil: compact failed - 機能が実装されていません
```

再起動したら↑の「内部エラーです」になって、スナップショット取ったら直った。

# 参考
* https://discussions.apple.com/message/32431186#message32431186

[^1]: あと"バックアップ"が"ハ<3099>ックアッフ<309a>"になってるのはMacがディレクトリ名を「バ」を「ハ」＋「濁点のunicode」、「パ」を「ハ」＋「半濁点のunicode」で作ったからっぽい。それでコピペしたらこうなった。参考: https://www.unicode.org/charts/PDF/U3040.pdf
[^2]: 一応出力も一緒に書いてるけど、実際にこの順序でコマンド叩いたわけじゃないので減った使用領域が消したバックアップのサイズを一致してない。
[^3]: パス名にスペース入れるのまじで勘弁してほしい
[^5]: 意味があるか知らない
[^6]: 858993459200==800GiB
緯度経度から2地点間の距離 (km) を計算する JavaScript

2地点の緯度経度を指定して距離を km で返す JavaScript 関数

参照 → https://qiita.com/naotarou/items/628952e68fef059c6b1a

```js
const R = Math.PI / 180;

function distance(lat1, lng1, lat2, lng2) {
  lat1 *= R;
  lng1 *= R;
  lat2 *= R;
  lng2 *= R;
  return 6371 * Math.acos(Math.cos(lat1) * Math.cos(lat2) * Math.cos(lng2 - lng1) + Math.sin(lat1) * Math.sin(lat2));
}
```

地球を（回転楕円体でなく）~~直径~~ __半径__ 6,371km の球体としたときの計算らしい。
[Google Maps](http://yamao.lolipop.jp/map/2017/g-m.htm) も同じ計算らしい。

試してみる：

```js
distance(35.666863,139.74954,35.663729,139.744047); // => 0.6063721931946154
distance(43.064313,141.347255,35.663729,139.744047); // => 834.321307653742
```

https://gist.github.com/kawanet/15c5a260ca3b98bd080bb87cdae57230 にも置いておいた。

---
2021/05/26 更新　直径→半径でした💦　`Math.PI / 180` の除算定数を１回に集約。
MSX Z80で120倍

```mul120.asm
; z88dk / WebMSX
; z80asm -b -l mul120.asm
; appmake +msx -b mul120.bin --org=0xd000

        org     $d000
start:
        push    hl
        pop     ix
        ld      a, (ix+2)

        ld      h, a            ; 256倍
        add     a, a
        add     a, a
        add     a, a
        ld      e, a            ; 8倍
        ld      d, 0
        xor     a
        srl     h               ; 256/2=128倍
        rra
        ld      l, a
        sbc     hl, de          ; 128-8=120倍

        ld      (ix+2), l
        ld      (ix+3), h
        ret
```

```mul120.bas
10 clear 100,&hcfff
20 defint a-z
30 def usr=&hd000
40 input "y(0~24)";y
50 print usr(y)
60 goto 40
```

![WMSX Screen (2).png](https://qiita-image-store.s3.amazonaws.com/0/257554/c3c75a5c-27a2-aab1-9d49-6eed660a5efc.png)
大事なファイルを消してしまったけどextundeleteを使って危ないところで助かった話


この記事は、2014年の覚書をもとに書いています。

# やっちまった
家のサーバの調子がいまいち。立ち上げた時にへんな具合になるので、とりあえず日記等々いろいろなものをバックアップしておこうと思って、tarで固めようとした。で、tarの前にいらないものを消していたら、最重要な日記データを消しちゃった。

## とりあえず、落ち着こう。
ここで焦ってはいけない。とりあえず、落ち着こう。深呼吸をしよう。
そこでおもむろに、何もHDDに書き出さないようにして、Google先生に質問。質問の項目は
**「CentOS rm 復元」**
たくさんページが出てくるが、自分がわかりそうなページを見つけたら出てきたページに素直に従う。

まずファイルシステムを確認。

```
# df -T
```
これで、ext4 を使用していることを確認。

続いてファイルを削除した時間を確認。

```
# export HISTTIMEFORMAT="%F %T "
# history
```

これでコマンド実行時の時間を取得。

続いて復元させるパーティションを読み取り専用に。

```
# mount -o remount,ro /dev/mapper/vg_www-lv_home
```

それから本命の extundelete をダウンロードしてインストールするんだけどその前に

```
# yum -y install e2fsprogs-devel
```

で、extundeleteをダウンロードする。

```
# cd /usr/local/src

# wget http://downloads.sourceforge.net/project/extundelete/extundelete/0.2.0/extundelete-0.2.0.tar.bz2"

# tar xfj extundelete-0.2.0.tar.bz2
# cd extundelete-0.2.0
# ./configure --prefix=/tmp/a && make && make install
```

これで無事に /tmp/a 以下に bin/extundelete ファイルが作成されている。

あとは時間を指定して実行する。先ほど時間を確認したところ３０分くらいまえだったので削除されてから一時間以内のファイルのみ復元させる。

変なところに復活のディレクトリ作られても困るので、一旦/rootへ移動。

```
# cd /root
```

満を持して復活のコマンド実行。

```
# /tmp/a/bin/extundelete --restore-all --after $(date +%s -d '1 hour ago') /dev/mapper/vg_www-lv_home
```

これで RECOVERED_FILES ってディレクトリに復元されている。
確認すると、大切な日記データも復元していた。よかったー。
jupyter notebookからBigQueryを使う

# 試した環境
localのdockerでjupyterを起動

```
$ cat docker-compose.yml
version: "3"
services:
  jupyter:
    image: jupyter/datascience-notebook
    ports:
      - "8888:8888"
    volumes:
      - jupyter_data:/opt/conda
      - jovyan_data:/home/jovyan
    container_name: jupyter
volumes:
  jupyter_data:
  jovyan_data:
```

# 必要なパッケージのインストール
jupyter notebookだとブラウザ上からターミナルを呼び出してpip installができる。
<img width="1255" alt="001.png" src="https://qiita-image-store.s3.amazonaws.com/0/231123/b8d6fb77-cd59-19c3-171d-af70dc838d0a.png">

```
pip install pandas-gbq -U
pip install --upgrade google-api-python-client
pip install --upgrade oauth2client
```

<img width="1272" alt="002.png" src="https://qiita-image-store.s3.amazonaws.com/0/231123/b60ad09a-4dce-77f0-3d54-08f49ad3b575.png">

# BigQueryとの接続
事前にBigQueryにデータセットとテーブルを作成しておく。
※今回は気象庁から横浜市の気温データを取り込んで使用。

```
# BigQuery接続テスト(standardSQL)
import pandas as pd
query = 'SELECT * FROM dataset.table_name'
data_frame = pd.read_gbq(query, 'project_id', dialect='standard')
```

<img width="1244" alt="005.png" src="https://qiita-image-store.s3.amazonaws.com/0/231123/ebaae3e3-e2ad-37e5-5e9f-2723b117a0e8.png">

pd.read_gbqを実行した時にURLが表示されるので、そこからgoogle　accountの認証を行う。
認証後に表示されるコードを登録することでデータが取得できる。

<img width="1230" alt="007.png" src="https://qiita-image-store.s3.amazonaws.com/0/231123/f5273cf9-9559-ec81-ed91-01190186bf04.png">
Solidity ローカル環境でtruffle migrateが進まない・うまくいかない場合の対処法



ローカル環境でTruffleを使って色々実装してみたもののマイグレーションが止まったままうまく進まない時のチェックリストです。私は３番目の対応でうまくいきました。

##目次##
・1.gethはローカルで起動しているかを確認
・2.それでも止まっている場合、コンソールを確認
・3.まだダメな場合、別建てでトランザクションを発行してみる
・4.マイグレーションファイルをそのまま修正してませんか？

#1.gethはローカルで起動しているか？#

ソースコードのデプロイにもトランザクションは発生します。
truffle migrateの場合、複数にわたるトランザクションが実装される場合もあります。
gethが起動されているか確認し、されていない場合は任意のディレクトリで開発環境として起動しましょう。

```terminal
$ geth --dev --datadir .
```

#2.それでも止まっている場合、コンソール等で確認#


gethを起動したディレクトリからgethのコンソールを起動します。consoleでもいいですが、attachサブコマンドを用いるのもオススメです。
gethを入れたディレクトリから起動してください。


```terminal
$ geth attach geth.ipc
```


その後、マイニングが止まっていたらマイニングを開始


```terminal
$ miner.start()
```


マイニングステータスは下記で確認できます。
trueならOKです。


```terminal
$ eth.mining
```


#3.まだダメな場合、別建てでトランザクションを発行します#

コンソールでアドレスをもう一個発行して少量のテスト用イーサリアムを送付してみましょう。

例:（なお、`(web3.toWei(任意のETH額, "ether")}))`で指定するとWei建で計算しなくて良いので便利）

```terminal
eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(0.01, "ether")})
```
マイグレーションの対象が複数にわたる場合は、完了するまで任意の回数送付処理を試してみること。

#4.マイグレーションファイルをそのまま修正してませんか？#

例えば、下記のようにやっぱりトークンの発行量を10,000,000から変更したいなという場合。

このファイルを書き換えるのではなく新しいマイグレーションファイルを作成したほうがいいです。ただし**影響範囲には注意しましょう。**

`~/hoge/migrations/X_contract_deploy.js`

```X_contract_deploy.js
var hoge = artifacts.require("./hoge.sol");

module.exports = function(deployer) {
    let initialSupply = 10000000;
    deployer.deploy(hoge, initialSupply);
};
```
基本的に番号を一つ増やして、わかりやすい名前にするといいです。
`~/hoge/migrations/X+1_Modify_Supply.js`

```X+1_ModifySupply_file.js
var hoge = artifacts.require("./hoge.sol");

module.exports = function(deployer) {
    let initialSupply = 800000;
    deployer.deploy(hoge, initialSupply);
};
```

↑ X_ですでにトークンを投げ合っていた時、X+1_でmigrationると、Xでの内容は無効になります。
MacでRaspberry Pi 3 Model B+用起動ディスク作成(RASPBIAN STRETCH LITE)

## 目的

購入したRaspberry Pi 3 Model B+(RSコンポーネンツ版)用の起動ディスクを作成する

## 実施環境

* macOS High Sierra
* microSD 32GB class2

## 手順

### 事前準備

作業用ディレクトリを作成する

```
$ mkdir ~/RaspbianWork
```

### OSイメージの取得

OSイメージ[RASPBIAN STRETCH LITE](https://www.raspberrypi.org/downloads/raspbian/)をダウンロードする

```
$ curl -L -o ~/RaspbianWork/raspbian-stretch-lite.zip https://downloads.raspberrypi.org/raspbian_lite_latest
```

ダウンロードしたOSイメージを解凍する

```
$ unzip ~/RaspbianWork/raspbian-stretch-lite.zip -d ~/RaspbianWork/
$ ls -1 ~/RaspbianWork/ | grep img
2018-06-27-raspbian-stretch-lite.img
```

### SDカードの準備

Macに接続してある対象SDカードのフォーマットを確認する

```
$ diskutil list

~ 中略 ~

/dev/disk2 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *31.9 GB    disk2
   1:                  Apple_HFS                         31.9 GB    disk2s1
```

フォーマットがFAT32でない場合、SDカードをフォーマットする

```
$ sudo diskutil eraseDisk FAT32 "NO NAME" MBRFormat /dev/disk2
```

フォーマットがFAT32である事を確認する

```
$ diskutil list

~ 中略 ~

/dev/disk2 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *31.9 GB    disk2
   1:                 DOS_FAT_32 NO NAME                 31.9 GB    disk2s1
```

### OSイメージの焼き込み

SDカードのマウント状態を確認

```
$ df
Filesystem    512-blocks      Used Available Capacity iused               ifree %iused  Mounted on

~ 中略 ~

/dev/disk2s1    62303488      3136  62300352     1%       0                   0  100%   /Volumes/NO NAME
```

マウントしたまま書き込むとエラーになるため、SDカードをアンマウントする

```
$ sudo diskutil umount /Volumes/NO\ NAME/
Volume NO NAME on disk2s1 unmounted
```

SDカードに解凍したOSイメージを書き込む

```
$ sudo dd bs=1m if=~/RaspbianWork/2018-06-27-raspbian-stretch-lite.img of=/dev/rdisk2 conv=sync
1776+0 records in
1776+0 records out
1862270976 bytes transferred in 306.518476 secs (6075559 bytes/sec)
```

書き込まれたSDカードのボリュームラベルはbootになっている

```
$ df | grep /dev/disk2
/dev/disk2s1       87078     44384     42694    51%       0                   0  100%   /Volumes/boot
```

書き込んだSDカードをアンマウントし、Raspberry PiにSDカードをセットする

```
$ sudo diskutil umount /Volumes/boot
```

## 参考

* [INSTALLING OPERATING SYSTEM IMAGES ON MAC OS](https://www.raspberrypi.org/documentation/installation/installing-images/mac.md)
* [MACでOSイメージを焼く](https://qiita.com/mogetarou/items/b193be4974f9b0282cc6)
作業効率を上げるためにキーボードの変換キーと無変換キーを設定してみた

# 「変換」キーと「無変換」キー
「スペース」の両隣にある「変換」「無変換」キー。スペースキーが短くなっただけで普段全然使用していない。色々な使い方があるらしいのだが、全くと言っていいほど使っていない。普段使っていないので、スペースキーを押すつもりが、押し間違えた時の動作が予測できない。この2つのキーはいらないので、スペースキーをもっと長くしたやつをどこかで売り出してほしいと思っていた。

ところが、Macユーザと話をしていたら、どうやらMacではこのキーを使って日本語on/offを実現しているらしい、ということがわかった。「半角/全角」キーを使ってホームポジションから手が離れてしまわないようにキーボード配列が設計されているらしい。

**いいじゃないか、さすがデザインに優れているMac！これが機能美というやつか**

と一瞬だけ思ったが、僕はそれだけでMacを買うほど、キーボードに執着しているわけではない。

確かに言われてみれば、日本語と半角アルファベットを切り替える「半角/全角」キーはとても遠い。「半角/全角」を押したつもりが、1を押したり、Tabキーを押したり、Escキーを押したりすることがあるので、「変換」「無変換」キーを使えるようになると作業効率が上がるかもしれない。

ということで、早速LinuxMintでやってみた。

## やり方
やり方は簡単。

- Menu-設定-Fcitx設定で入力メソッドの設定を開く
- 「全体の設定」タブをクリック
- 「入力メソッドのオンオフ」はそのままで、「拡張オプションの表示」をチェック
- 拡張オプションの「入力メソッドをオンに」で「変換」キーを押して登録
- 「入力メソッドをオフに」で「無変換」キーを押して登録

これで「変換」キーを押すと日本語入力できるようになり、「無変換」キーを押すとアルファベット入力できるようになる。

少し慣れるまで時間がかかるかもしれないけど頑張ってみよう。
ちなみに、同じ設定は(設定方法は違うけど）WindowsのIMEでもできるのでWindowsにも設定してみよう。
ゆかりんの歌詞をKHCoderで可視化してみる

# 概要
声優、アーティストとして活躍中の田村ゆかりさん（ゆかりん）の歌詞を可視化してみます
主にPythonとKHCoderの使い方確認

## データ取得
「歌ネット」
https://www.uta-net.com/
からデータを取得します。

先人(Aidemy Tech Blog)がBeautifulSoupを利用して歌詞取得しているスクリプトを公開しているのでほぼそのまま流用させていただく

326曲もありますね。
キャラソンも含まれてるようなので除外しようかとも思いましたが
ざっくり可視化のためそのまま

## 可視化
### 共起ネットワーク
KHCoderで可視化しました。
いきなり結果ですが以下の通りです。

![共起ネットワーク.png](https://qiita-image-store.s3.amazonaws.com/0/278271/3ce81ff1-2bc3-6472-d7a1-e801f81516b7.png)

ほとんど前処理いれていないけど、なんかいい感じ
いくつかの曲も想起されつつ、ポジティブな言葉も多くてニヤニヤしちゃいます
「ねぇ」がいいですね

### Word2Vec
Aidemy Tech Blogのとおり、ゆかりんにも「恋」とは何か聞いてみました(word2vec)
ベストテンは以下の通り

0    ゴコロ    0.9935595989227295
1    気分    0.9933409690856934
2    メール    0.9930744171142578
3    つかまえる    0.9926524758338928
4    切る    0.9924467206001282
5    ふう    0.9921718835830688
6    一瞬    0.991794764995575
7    ほる    0.9917645454406738
8    がんばる    0.9917554259300232
9    持つ    0.9917395710945129

「ゴコロ」は「恋ゴコロ」として必ず一緒に出てくるからNo.1になっていますね
「ふう」、「ほる」あたりはちょっとよくわからないのでもうちょっと前処理が必要そう

1部の歌詞(20曲分)だけ抽出して「恋」とは何か聞いてみたのが以下のとおり
こっちのほうが詩的な感じ

0    聞く    0.9997913837432861
1    あせる    0.9997637867927551
2    生まれる    0.9997403621673584
3    起こす    0.9997315406799316
4    きり    0.999724268913269
5    気持ち    0.9996978044509888
6    こぼれる    0.9996976256370544
7    あふれる    0.999697208404541
8    かける    0.9996947050094604
9    涙    0.9996943473815918


## 参考サイト

・西野カナに「恋」とは何か聞いてみた
http://blog.aidemy.net/entry/2018/06/15/174827
・KHCoder
http://khcoder.net/
・『社会調査のための計量テキスト分析』 樋口耕一著
http://khcoder.net/book.html
PhpStormからDockerを使ってカバレッジを取得する

# はじめに

テストケースの確認用にカバレッジを見ておきたい事もある。

## CLI Interpreterの追加

![2018-08-05_22h14_53.png](https://qiita-image-store.s3.amazonaws.com/0/165884/496dde03-4699-a9e4-323a-32948fe98bf5.png)

## phpunit.xmlの用意

テスト対象ファイルのwhitelistを設定していないとカバレッジ取得時にエラーとなるので下記のような設定ファイルを用意する。

```xml:phpunit.xml
<?xml version="1.0" encoding="UTF-8" ?>
<phpunit>
    <filter>
        <whitelist>
            <directory>./App</directory>
        </whitelist>
    </filter>
</phpunit>
```

## テスト設定の追加

![2018-08-05_22h29_39.png](https://qiita-image-store.s3.amazonaws.com/0/165884/0e08669c-c09f-f74b-784a-e6b5162c7544.png)

## テスト実行

エディタでテストケースを開いて右クリックから下記を選択

<img src="https://qiita-image-store.s3.amazonaws.com/0/165884/0bd79dc2-232d-c7a3-48fe-9d0b5bbe5f8a.png" width=50%>

## カバレッジ確認

<img src="https://qiita-image-store.s3.amazonaws.com/0/165884/644f7893-0ff2-5d7c-7e55-eb06ff0e2980.png" width=50%>


<img src="https://qiita-image-store.s3.amazonaws.com/0/165884/6537c1eb-ea41-35f6-42c9-c1e0b51ce84f.png" width=80%>
macでApache2.4のローカルファイルに対するアクセスにハマった問題解決法

基本的に以下の記事をもとに解決を試みたのだが、自分の場合さらにもう一箇所変更が必要でハマったので備忘録として残しておく

[Apache2.4で、アクセス制限の記述方法が変更されていた](https://qiita.com/nwsoyogi/items/c8eb1fedef3c00c5fbac)

``` /etc/apache2/httpd.conf
# Deny access to the entirety of your server's filesystem. You must
# explicitly permit access to web content directories in other
# <Directory> blocks below.
#
<Directory />
    AllowOverride none
    Require all granted
    # ↑に書き換え
    # Require all denied
</Directory>
```
上記はDirectoryの指定を / で指定している部分を直接変更したのでファイルシステム上全てに影響してしまうが、もっと局所的な指定でもOK。
####ハマった原因
ユーザ名とホームディレクトリの名前が同一でないことかも？（過去に色々いじって別になってる）
【エクセル的に】アンケートの単純集計的なもの

忘備録

800くらい？のサンプル数のアンケート集計をする機会があった。下記を応用してこれをpandasで集計した。

+ Series.value_counts()だけだと、だれも選択しなかった選択肢は出力されない。
+ 選択肢にはあるが、回答されなかった選択肢の計数結果は0としてデータフレームに出力されるように小細工した。

＜大まかな流れ＞
選択肢のシリーズを作る
↓
value.counts()でカウント結果のシリーズを作る
↓
選択肢のシリーズに、カウント結果のシリーズをmap()する。ここでのmapは、シリーズXのvalueのうち、シリーズYのindexに一致するものをシリーズYのvalueで置換する。
関数をリストなどにmapするのではない。
↓
このシリーズと選択肢のシリーズをconcat

```python
import pandas as pd
#サンプル
data = {"Q1": [1, 1, 3, 3,1],
        "Q2":[1,2,2,2,1],
        "Q3":["m", "f", "f", "m","f"]}
df = pd.DataFrame(data,columns=["Q1","Q2","Q3"])
print(df)
   Q1  Q2 Q3
0   1   1  m
1   1   2  f
2   3   2  f
3   3   2  m
4   1   1  f
```
このQ1をカウントする。Q1の選択肢は1,2,3であるが、2の回答者がいなかったとする。value_counts()だけだと2のカウント結果0が出てこないので、小細工した。

```python
#①選択肢のシリーズを作る
sr_label = pd.Series(range(1,4))
print(sr_label)

0    1
1    2
2    3
dtype: int64


#②Q1カウント結果のシリーズを作る（未選択だった回答は無視される）
sr_count = df.iloc[:,0].value_counts()
print(sr_count)

1    3
3    2
Name: Q1, dtype: int64

#③ ①選択肢のシリーズに、②カウント結果のシリーズをmap。
#つまり、①のvalueのうち、②のindexと一致するものは、②のvalueに置換される。
#該当なしの回答2はNaNとなるので、0に置換。float→intにしておく。
sr_result = sr_label.map(sr_count).fillna(0).astype(int)
print(sr_result)

0    3
1    0
2    2
dtype: int64

#④　①の選択肢のシリーズと③のmap後のカウント結果シリーズを結合
df_result = pd.concat([sr_label, sr_result],axis=1)
df_result = df_result.rename(columns = {0:"選択肢",1:"回答数"})
print(df_result)

  選択肢  回答数
0    1    3
1    2    0
2    3    2
```
もっと簡単なやり方があればご教示お願いいたします。
シェル小物：IP,ポート番号集計

# tcpdumpしてIPとポート番号を集計する
tcpdumpのPCAP形式のキャプチャデータから、あるサーバがどのクライアントIPとどんなportで通信しているかを集計するためのシェルスクリプト

ちなみに、tcpdumpでポート番号を数値で表示するときには、”-dd"オプションを使う

```
$ ls
shelltest.sh  test1.txt  test2.txt  test3.txt
```
test1.txt、test2.txt、test3.txtはtcpdumpで取得したPCAPデータをリダイレクトしたファイル。

```
$ cat test1.txt 
123.123.123.123.telnet 234.234.234.34555
123.123.123.123.domain 234.234.345.34655
```
ってな感じ。

最初のIP.PORTがサーバ側、後ろのIP.PORTがクライアント側の、こんなファイルtest1.txt,test2.txt,test3.txt　があったとする。

以下のシェルを使うと、サーバに通信しているクライアントのIPアドレスとport番号一覧ができる。

```shelltest.sh 
#!/bin/sh

#ファイルを１つずつ読み込み

for file in `\find . -name '*.txt'`; do
    cat $file |tr "." " " | awk '{if ( $5 ~/^[a-z]+$/) print $1,$2,$3,$4,$5,$6,$7,$8,$9; else if ( $5 ~/^[0-9]+$/) print $6,$7,$8,$9,$10,$1,$2,$3,$4}' | sort | uniq >> ./testZ
done

#ファイルの結果を集計
cat testZ | sort | uniq > testZZ
exit 0
```

これは、そこそこ使われたな。
【個人開発】git pushを取り消して、branchを変更しもう一度 git push する方法

# 今回起きた問題
- 以下の流れで作業してしまった
    - masterブランチで作業
    - ステージング
    - git commit
    - GitHubにpush
 
# どうしたかったのか？
本来であればbranchを新たに作って作業し、そのブランチをGitHubにpushしたかったのだが、ついうっかりしてしまい上記の手順で、master branchをpushしてしまったのである。

# 解決した方法
**注意【このやり方はチームでの開発ではお勧めできません】**
まずは以下の方法で、最新のコミットを取り消し、プロジェクトをコミット前の状態に戻します。
```--soft```は「変更した内容は残る」、```HEAD^```は「一つ前のコミット」です。 
実行するとプロジェクトがコミット前の状態に戻り、変更した内容は残ります。

```
$ git reset --soft HEAD^
```

次にコミット前の状態に戻ったプロジェクトをGitHubにpushして、前のpushを取り消します。
[ -f ]を付けずにpushすると、pushする内容が古いのでエラーが出ます。
[ -f ]を付けることで強制的にpushさせています

```
$ git push -f origin master
```
ここまででGitHubは前の状態に戻っているはずです。

---

#### ここからはbranchを変更してpushするまでを解説します。

まずはプロジェクトの変更した内容とステージングエリアを一時撤退させます。

```
$ git stash
```

そして、branchを移動、もしくは新たに作成します。今回は新たに作成しました。

```
$ git branch -b 新ブランチ名
```

新たに作成し移動したbranchで以下コマンドを実行することで、直前に一時撤退した内容をこのbranchで元に戻します。これで、新しいブランチにmasterで変更した内容を持ってこれました。

```
$ git stash pop
```

最後に新しいブランチでpushして目的は完了した。

```
$ git add -A
$ git commit
$ git push origin 新ブランチ名
```
---
**gitもコマンドが色々あるのだと実感しました。まだまだ覚えることがたくさんのようです。日々精進**
シェル小物：時間の比較

# 今の時間とCSVを比較するシェルスクリプト
IPアドレス、時間１、時間２　という感じのcsvファイルになっている。
今の時間が、時間１と時間２の間に入っていたら、IPアドレスをファイルに書き出すというだけのちょっとしたシェルスクリプト。作ったけど、結局使われませんでした。

```test.csv
192.168.1.10,201710030830,201710031700
192.168.1.11,201710030830,201710032300
192.168.1.12,201710032250,201710032330
```
こんな感じのcsvファイルがあったとする。
今の時間が、CSVの2項目と3項目の間だったら、IPアドレスを書き出す。
というシェル。

```hoge.sh
## ファイルを1行ずつ読み込み
TESTFILE=./test.csv
NOWTIME=`date "+%Y%m%d%H%M"`

mv ./ip.csv ./ip_$NOWTIME.csv
touch ip.csv

while read line; do

IPADD=`echo $line | tr "," " " | awk '{print $1}'`
KAISHI=`echo $line | tr "," " " | awk '{print $2}'`
OWARI=`echo $line | tr "," " " | awk '{print $3}'`

if [ $KAISHI -le $NOWTIME ] && [ $NOWTIME -le $OWARI ]; then
       echo -e "$IPADD" >> ip.csv
fi

done < $TESTFILE
```

もったいないので記録だけ残しておこう。
8/5

#　HTML
##　概要
- ホームページ
- HTML　を使うことで構造できな文書+CSS 見た目

## 範囲
- HTML５

## 仕様
- W3Cで確認ができる

## タグ
- <タグ>文章</タグ>
- <タグ　属性名=値 属性名=値>文章</タグ>
- <p class="message">Hello</p>
OpenAI roboschool をMac High Sierraにインストール

Open AI のロボットシミュレーション環境、RoboSchoolを、Mac High Sierra にインストールします。

# 環境

* Mac High Sierra
* Anaconda で、Python3 の環境がインストールされているとします。[参考](https://qiita.com/t2y/items/2a3eb58103e85d8064b6)

# 必要なものをインストール

```bash
$ brew install cmake tinyxml assimp ffmpeg
$ brew install boost-python3
$ conda install qt
$ ln -s /usr/local/lib/libboost_python37.a /usr/local/lib/libboost_python3.a
$ ln -s /usr/local/lib/libboost_python37.dylib /usr/local/lib/libboost_python3.dylib
$ export PKG_CONFIG_PATH=$(dirname $(dirname $(which python)))/lib/pkgconfig
$ pip install future 'gym[atari]' 'gym[box2d]' 'gym[classic_control]'

```

# roboschool のソースを取得

```bash
$ git clone https://github.com/openai/roboschool.git
$ cd roboschool
$ ROBOSCHOOL_PATH=`pwd`
```

# bullet3 をインストール

bullet3 は物理演算エンジンです。

```bash
$ git clone https://github.com/olegklimov/bullet3 -b roboschool_self_collision
$ mkdir bullet3/build
$ cd bullet3/build
$ cmake -DBUILD_SHARED_LIBS=ON -DUSE_DOUBLE_PRECISION=1 -DCMAKE_INSTALL_PREFIX:PATH=$ROBOSCHOOL_PATH/roboschool/cpp-household/bullet_local_install -DBUILD_CPU_DEMOS=OFF -DBUILD_BULLET2_DEMOS=OFF -DBUILD_EXTRAS=OFF  -DBUILD_UNIT_TESTS=OFF -DBUILD_CLSOCKET=OFF -DBUILD_ENET=OFF -DBUILD_OPENGL3_DEMOS=OFF ..
$ make -j4
$ make install
$ cd ../..
```

上記の、make install では、$ROBOSCHOOL_PATH にインストールされます

# roboschoolをインストール

以下の通り、roboschool/cpp-household/render-simple.cppを修正。

```diff
diff --git a/roboschool/cpp-household/render-simple.cpp b/roboschool/cpp-household/render-simple.cpp
index 1a3002c..10325d5 100644
--- a/roboschool/cpp-household/render-simple.cpp
+++ b/roboschool/cpp-household/render-simple.cpp
@@ -4,8 +4,8 @@
 #include <QtOpenGL/QGLFramebufferObject>

 #ifdef __APPLE__
-#include <gl3.h>
-#include <gl3ext.h>
+#include <OpenGL/gl3.h>
+#include <OpenGL/gl3ext.h>
 #endif

 // OpenGL compatibility:
```

```
$ pip install -e $ROBOSCHOOL_PATH
```

## エラーが出た場合

```
    ./render-simple.h:6:10: fatal error: 'QtWidgets/QOpenGLWidget' file not found
```

などと出る場合は、以下のようにします。
python-3.7 の部分はバージョン番号に合わせてください。

```
$ brew install pkg-config
$ pkg-config --cflags Qt5Widgets Qt5OpenGL assimp python-3.7
```

# サンプルを動かしてみる

tensorflowが必要なので、condaでインストールします。

```
$ conda install tensorflow
$ python $ROBOSCHOOL_PATH/agent_zoo/demo_race2.py
```

以下のように表示されます

![スクリーンショット 2018-08-05 22.27.35.png](https://qiita-image-store.s3.amazonaws.com/0/38555/fb1204e2-f97b-8b8f-87c1-9cbe0ecdc8d8.png)

# セグメンテーションフォルトが起こる場合

デモを実行するとセグメンテーションフォルトが起こる場合があります。

```
$ python $ROBOSCHOOL_PATH/agent_zoo/demo_race2.py
Segmentation fault: 11
```

これは、Pythonのバージョンによって起こるようです。

@kenrota に教えてもらったのですが、以下のような挙動となります。ただ、環境によっては動いたりするのでよく分かっていません。

3.6.8: x
3.6.6: x
3.6.5: x
3.6.0: o
3.5.5: x
3.5.2: o
Cordaとは?

#目的
Cordaとは何かを理解する。
技術的な内容というよりは、概念レベルで理解する。

#内容
##Cordaとは?
分散台帳技術Distributed Ledger Technology(DLT)プラットフォーム。[R3](https://www.r3.com/ "R3")社が主体となって開発している。
R3が主催するコンソーシアムには世界中の金融機関やTech企業が参加している。(日本からはメガバンなど)
CordaにはOpenSource版とEnterprise版がある。



##開発言語
CordaのスマートコントラクトはJavaやKotlinなどJVM言語で記述する。Corda自体はKotlinで書かれている。
ちなみにHyperledger FabricはGoかJavaかNode.jsで、EthereumはSolidityという言語でスマートコントラクトを開発する。

##分類
BlockchainはPublicとPrivateの2つに分類可能で、CordaはPrivateに分類される。

+ Public Blockchain
<br>誰でも参加可能なBlockchain。BitcoinやEthereumなど。
+ Private Blockchain
<br>参加者が制限される、企業や団体向けに設計されたBlockchain。CordaやHyperledgerなど。

##第3波のBlockchain
[ホームページ](https://www.corda.net/discover/blockchain.html "ホームページ")では、自身を"第3波のBlockchain"と位置付けている。

* 第1波-Bitcoin
<br>分散台帳を実現
* 第2波-Ethereum
<br>スマートコントラクトを実現
* 第3波-Corda
<br>プライバシーやトランザクションなどの問題を解決し、ビジネス利用できるBlockchainを目指す

##Cordaの全体図

Cordaの台帳には当事者間の取引のみが記録されるため、参加者ごとに台帳の中身が異なる。Bitcoinのように参加者が全く同じ台帳を持っている訳ではない。参加者ごとの台帳を持つことで、不特定多数の人が全ての取引を閲覧できないようにしてプライバシーを確保している。

[Corda](https://docs.corda.net/key-concepts-ledger.html "Corda")
<img width="762" alt="スクリーンショット 2018-08-05 21.37.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/231906/42e0dea5-1358-3309-7d9f-d211c4b1720c.png">
<br>


トランザクションはImmutability(不変性)が確保されているため、トランザクションそれ自体を変更したり削除することはできない。トランザクションを新しく作成する場合は、Bitcoinと同じように前のトランザクションのハッシュを新たなトランザクションに含める。(最初のトランザクションは例外)

<img width="664" alt="スクリーンショット 2018-08-06 14.17.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/231906/6bf3ecb9-08a4-f862-b903-6e4089dbac02.png">

Cordaではノータリーというサービスがあり、トランザクションのハッシュが既に別のトランザクションに含まれていないか検証することで、2重支払いを防ぐ。

#まとめ
BitcoinやEthereumとは方向性がまた違い、ビジネス利用を目的としているのがCorda。
金融だけでなく、他分野での利用も可能で今後が楽しみ。

#参考文献
Github
https://github.com/corda/corda
公式HP(英)
https://www.corda.net/
公式Document(英)~日本語字幕の動画あり
https://docs.corda.net/index.html
medium(英)
https://medium.com/corda
[python] pythonのキュー（queue）


Pythonでは、キューとして
`collections.deque`（以下、 **deque**）と `queue.Queue` （以下、 **Queue**） がある。


# 両者の違い

## deque

`deque` は **D**ouble- **E**nded **Que**ueの略称で、
名前通り、 **両サイドからデータ**を入れたり取り出したりすることができるちょっと特殊なキューです。

図で表現しますと、

![Kobito.edvWuD.png](https://qiita-image-store.s3.amazonaws.com/0/170309/c6bb8a1c-82ad-2970-74ff-7a0e7ce44454.png "Kobito.edvWuD.png")

> 上図は pythontic.comさんから借りてきた

* 英語の表現がわかりやすいです

> A deque is a double-ended queue on which elements can be added or removed from either side - that is on left end or right end, head or tail.


## Queue


こちらは一般に認識されている **FIFOキュー** となります。

![Kobito.b12TkZ.png](https://qiita-image-store.s3.amazonaws.com/0/170309/2ab5e904-0d22-4095-5909-06ebf710f36a.png "Kobito.b12TkZ.png")

上図にあるように、片サイドからデータを入れたり、もう片サイドからデータを取り出したりすることになります。


`queue.Queue` と同じクラスに `LifoQueue` と `PriorityQueue`も定義されいています。


### queue.LifoQueue(maxsize=0)

`LifoQueue` は名前通り、`queue`のLIFO版です。
データ構造的には `stack`ですね。

![Kobito.QqVcNS.png](https://qiita-image-store.s3.amazonaws.com/0/170309/7361534a-7d0f-afe2-4bae-ba6335f56077.png "Kobito.QqVcNS.png")


### queue.PriorityQueue(maxsize=0)

`queue.PriorityQueue` は優先度付きキューです。
また今度説明します。

# 使い分け

* マルチスレッド（複数プロデューサ-複数コンシューマ(multi-producer, multi-consumer)）とかの場合は、スレッドセーフ設計（マルチスレッド対応）の `queue.Queue` を使用する。

* シングルスレッドの場合は `collections.deque` を使用。理由は、スレッドセーフ設計の`queue.Queue`より早いため。
Ubuntu 16.04にAvogadro1.2.0をインストールする

# はじめに
分子モデリングライブラリのAvogadroをUbuntuにインストールするのに苦労したので、メモを残しておきます。
バージョンは以下の通り:
Ubuntu 16.04
Avogadro 1.2.0
python 3.6.1

# 事前インストールが必要なもの
ドキュメントにはこう書いてあります。

-- CMake 2.8.9 or later (2.8.11 recommended)
-- Qt 4.6.0 or later (4.8.5 recommended)
-- OpenBabel 2.3.x or later (development version from 
http://github.org/openbabel/openbabel is recommended)
-- Eigen 2.0.x or later (3.x also supported)

CMakeはインストール済みでしたが、他の要件が満たされていませんでした。

## Qt
GUIアプリケーションの補助ツールらしいです。
[公式ドキュメント](http://doc.qt.io/archives/qt-4.8/install-x11.html)に従って進めます。

(1) https://download.qt.io/archive/qt/4.8/4.8.5/ でqt-everywhere-opensource-src-4.8.5.tar.gz　をダウンロード

(2) 展開してインストール
makeの後に-j4オプションをつけると、4コアでコンパイルを行います。
中にはコンパイルに時間のかかるソフトもあるので、使うと便利です。

```
$ tar zxf qt-everywhere-opensource-src-4.8.5.tar.gz
$ cd /tmp/qt-everywhere-opensource-src-4.8.5
$ ./configure
$ make -j4
$ sudo make install
```

(3) 環境変数の設定

`~/.profile`に以下を追加します。

```.profile
PATH=/usr/local/Trolltech/Qt-4.8.5/bin:$PATH
export PATH
```

~/.loginに以下を追加します。

```.login
setenv PATH /usr/local/Trolltech/Qt-4.8.5/bin:$PATH
```
環境変数を変更したあとは再ログインが必要です。
最後に、私の環境ではqt5-defaultが入っていて4.8.5が読み込まれなかったので、

```
$ sudo apt install qt4-default
```

をしました。
これでQtは完了です。

## OpenBabel
化合物ファイルのフォーマットを変換するツールです。
https://sourceforge.net/projects/openbabel/files/ からファイルをダウンロードします。
あとはこれだけです。

```
$ tar zxf openbabel-2.4.1.tar.gz
$ cd openbabel-2.4.1
$ mkdir build 
$ cd build
$ cmake ../
$ make -j4
$ sudo make install
```

## Eigen
行列演算のツールです。
http://eigen.tuxfamily.org/index.php?title=Main_Page　
から3.2.10をダウンロードします。公式ドキュメントには"3.x also supported"とありましたが、3.2より新しいファイルだとAvogadroのコンパイルがうまくいきませんでした。
先ほどと同じ手続きです。

```
$ tar zxf eigen-eigen-b9cd8366d4e8.tar.gz
$ cd eigen-eigen-b9cd8366d4e8/
4 mkdir build 
$ cd build
$ cmake ../
$ make -j4
$ sudo make install
```

# Avogadroインストール
(1) https://sourceforge.net/projects/avogadro/files/latest/download
から1.2.0をダウンロード

(2)展開

```
$ tar zxf Avogadro-1.2.0.tar.gz
```

(3) python2の一部修正(なくても大丈夫？)
avogadro-1.2.0/cmake/modulesのFindNumpy.cmakeとFindSIP.cmakeがpython2なので、SyntaxErroを避けるためにprintに()をつけておきましょう。

(4) インストール

```
$ mkdir build
$ cd build
$ cmake ../
$ make -j4
$ sudo make install
```

GUIが起動できたら成功です。
Pod内 コンテナ間で SysV IPC 共有メモリを試してみた



次の図の様に、ポッドのコンテナ間で、共有メモリの読み書きができることを確認した。結果は、ポッド内で、異なるコンテナ間で、System-V 共有メモリを利用して、データの受け渡しができることが確認できた。


![スクリーンショット 2018-08-05 21.42.43.png](https://qiita-image-store.s3.amazonaws.com/0/42829/2a0dc47c-956a-6e20-7cf8-9dc4faceded1.png "スクリーンショット 2018-08-05 21.42.43.png")


## サイドカーポッドのYAML

System-V 共有メモリへ書き込む writerコンテナと、読み取り readerコンテナを作成して、次のYAMLで、一つのポッドとして起動する。

~~~
apiVersion: v1
kind: Pod
metadata:
  name: sidecar
spec:
  containers:
  - name: writer
    image: maho/sidecar-ipc:w.4
    volumeMounts:
    - mountPath: /mnt
      name: shared-vol
  - name: reader
    image: maho/sidecar-ipc:r.4
    volumeMounts:
    - mountPath: /mnt
      name: shared-vol
  volumes:
  - name: shared-vol
    emptyDir: {}
~~~



## 結果

コンテナは、異なっていても、二つのコンテナ間で共有メモリを利用して、データの受け渡しができることが確認できた。

~~~
(1) 共有メモリに書き込む前に、読み取り、結果な空の応答
imac:sidecar-ipc maho$ kubectl exec -it sidecar -c reader /reader.py

(2) 共有メモリに書き込み
imac:sidecar-ipc maho$ kubectl exec -it sidecar -c writer /writer.py

(3) 共有メモリから読み取り、書き込んだ内容が表示された
imac:sidecar-ipc maho$ kubectl exec -it sidecar -c reader /reader.py
takara aho maho !

~~~


---

## コンテナのファイル
この検証で利用したコンテナをビルドするためのファイルです。

### Writerコンテナ

~~~Dockerfile
FROM python:2
RUN pip install posix_ipc
COPY ./writer.py /writer.py
CMD [ "tail", "-f", "/dev/null" ]
~~~

~~~writer.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from time import sleep    
import mmap
import posix_ipc as ipc

s = ipc.SharedMemory('/shm', flags=ipc.O_CREAT, size=20, read_only=False)
mm = mmap.mmap(s.fd, s.size)
mm.seek(0)
mm.write(b'takara')
mm.write(b' aho maho')
mm.write(b' !\n')
s.close_fd()
~~~


### Readerコンテナ

~~~Dockerfile
FROM python:2
RUN pip install posix_ipc
COPY ./reader.py /reader.py
CMD [ "tail", "-f", "/dev/null" ]
~~~


~~~reader.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import mmap
from time import sleep    
import posix_ipc as ipc

s = ipc.SharedMemory('/shm', flags=ipc.O_CREAT, size=20, read_only=False)
mm = mmap.mmap(s.fd, s.size)
mm.seek(0)
print mm.read(20)
print "\n"
~~~


# 参考資料
[1] http://note.crohaco.net/2017/python-posix-ipc-systemv-ipc/
[2] https://www.mirantis.co.jp/blog/multi-container-pods-and-container-communication-in-kubernetes/
[3] https://github.com/kubernetes/kubernetes/issues/28272