OmniAICreator/Qiita-1.07M huggingface dataset:
How to build an On-Demand delivery app that perfectly caters to the customers’ needs?

You love it or hate it, but the internet is eating the world. The dawn of mobile technology integration in the diverse industry verticals has brought a dramatic shift in the world’s economy and spoiled us. You must accept the latter impact of going mobile is not an overstatement at all.

The mobile addiction is growing with the delivery of the products or services anytime, anywhere at the fingertips through on-demand delivery apps.TheUber, DoorDash, GrubHub, Postmates, and Airbnb are the pioneers that have reinvented the traditional business models with doorstep service delivery. Now, with the increasing popularity of on-demand services, new businesses are joining the race.

The myriad of the business spheres is incorporating the on-demand business model to improve business growth, efficiency, and productivity, and pick up the pace with the changing trends. Are you one of them? Congrats! You are hopping onto the app bandwagon that’s guaranteed turn success to your business.

The stats validating the same:

The on-demand economy will grow to $57 billion by the end of 2018.
The revenue from the on-demand sector is expected to reach a whopping of $335 billion by 2025.
On-demand companies serve just 7%, that’s $758 billion of the US market, which means, still there is a lot of room for the new entrepreneurs.
The spending on on-demand mobile apps has increased from $48 Billion in 2016 to $75.7 billion in 2017 which amounts to nearly 58% growth.
It concludes that undeniably the future of the on-demand economy is bright and the businesses that take up this opportunity will shine. But, everything is not so rosy.

There are many challenges that stand in the way of building an on-demand app. Sometimes, the app is not built rightly,  the customer’s needs are not fulfilled, and UI/UX or performance issues exist, which must be resolved smartly in order to become the next UberEats or Postmates. Here, a couple of tips are shared that enable struggling on-demand app service providers to work like a pro and gain a competitive edge:
Know more from here..https://www.prismetric.com/how-to-build-an-on-demand-delivery-app-that-perfectly-caters-to-the-customers-needs/
Pycharm でリモートのUbuntu18.04に接続してTensorFlowを実行

# openssh-serverをインストール
[ubuntu18.04LTS SSH接続 ](https://usado.jp/spdsk/2018/05/23/post-3715/)を参考に Ubuntu 18.04 に openssh-server をインストールします。

# Pycharm の設定
基本的には、[SSH経由でのリモートインタープリタの設定](https://pleiades.io/help/pycharm/configuring-remote-interpreters-via-ssh.html)を参考に設定します。

***PIPENV_VENV_IN_PROJECT = true***と設定してある場合には、
python interpreter path には、使用したいPython環境のディレクトリ/.venv/bin/pythonを指定します。

```bash:例
/home/$USERNAME/Documents/tensorflow/.venv/bin/python
```

しかし、これらの設定だけでは、

```console
ImportError: libcublsa.so.9.0: cannot open shared object file: No such file or directory
```
というエラーが発生してリモートでのpythonの実行が出来ません。
これは Pycharm がリモートのPATHを上手く認識できていないのが原因らしいので、Pycharm にUbuntu のCUDAやcuDNNのPATHを設定します。

1. Edit configurations ボタンをクリック。
![qiita.jpg](https://qiita-image-store.s3.amazonaws.com/0/226891/41e852e3-f105-b541-3da6-29da7fcf3951.jpeg)

2. Environment variables の右端のアイコンをクリック。

3. Ubuntuで設定してあるPATHを入力。

```bash
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib64:/usr/local/cuda/extras/CUPTI/lib64
CUDA_HOME=/usr/local/cuda
PATH=$PATH:/usr/local/cuda/bin
```

これで、リモートでTensorFlowを実行できるようになりました。
めでたしめでたし。

# 参考
[PyCharm won't correctly import tensorflow](https://github.com/tensorflow/tensorflow/issues/9530)
[TensorFlow问题：pycharm远程调试报错ImportError:libcusolver.so.9.0: cannot open shared object file](https://blog.csdn.net/manduner/article/details/82349788)
react-navigation3系で画面遷移の実装をしていたが、今までのやり方は使えなそう。

## これは

react-nativeやreact-navigationなどのバージョン更新が激しく、今まで使えていた方法での画面遷移ができなそうです。

そこで、react-navigation 3.x系の使い方を書いておきます。

日本語の文献がなさすぎて辛いので、誰かのためになれば幸いです。

## バージョン

```package.json

"dependencies": {
    "expo": "^31.0.2",
    "install": "^0.12.2",
    "npm": "^6.4.1",
    "react": "16.5.0",
    "react-dom": "^16.6.3",
    "react-native": "^0.57.7",
    "react-navigation": "^3.0.1"
  },
```
## 今までと今後のStackNavigatorの使い方

### 今までの書き方

```App.js

import StackNavigator from 'react-navigation'

const app = StackNavigator(
//いろいろ
);

export default app;
```

### 今後

containerで囲んでくれというエラーがたくさん出るので、[React Navigation公式document](https://reactnavigation.org/docs/en/stack-navigator.html)を参照した。

```App.js

import { createStackNavigator, createAppContainer } from 'react-navigation';

const app = createStackNavigator({
//いろいろ
});

export default createAppContainer（app）;
```

どうやら、createAppContainerで囲まないと画面遷移の実装ができなくなったようです。

## 最後に

日本ではRNの利用例が少ないので、皆さんとコミュニティを大きくしていきたいです！

参考になったらいいねを押してください！
デスクトップPWAを動かせるようにする。

# tl;dr
+ 普通、スマートフォンのみで使える PWA をPCブラウザでも使えるようにする。
+ そのために、プログラムなど自体ではなく、ブラウザの設定を変更する。

## 検証に使用したブラウザ
+ Google Chrome: 70.0.3538.110 (Official Build) （64 ビット）
+ Google Chrome: 71.0.3578.62 (Official Build) beta （64 ビット）
+ Google Chrome: 72.0.3622.0 (Official Build) dev （64 ビット）
+ Google Chrome: 72.0.3624.0 (Official Build) canary （64 ビット）

# やってみましょう。
## Step 1.
アドレス欄に `chrome://flags` と入力。

![pn616-u2sf4.gif](https://qiita-image-store.s3.amazonaws.com/0/193558/6a106ad7-1415-917c-6241-428d784e87da.gif)

> <font color="red">WARNING: EXPERIMENTAL FEATURES AHEAD!</font> By enabling these features, you could lose browser data or compromise your security or privacy. Enabled features apply to all users of this browser.
>> これらの機能を有効にすると、ブラウザのデータが失われたり、セキュリティやプライバシーを危険にさらす可能性が。 有効な機能は、このブラウザのすべてのユーザーに適用されます。

と、あるように、あまり変にいじくるとおかしくなってしまうことがあるようです。
~~自己責任で。（←←←丸投げすんな。）~~

## Step 2.
:mag: `Search Flags` の欄に、 `PWA` と入力。
すると、いくつか設定が出てきます。

その中から、次のような設定を変更してください。
+ **Desktop PWAs**
+ **Desktop PWAs Link Capturing**
+ **Desktop PWAs Custom Tab UI**

![xgzzz-uuojy.gif](https://qiita-image-store.s3.amazonaws.com/0/193558/23cc64d2-2fcb-e08b-8828-34ada62e5ecc.gif)

また、:mag: `Search Flags` の欄に、 `App Banners` と入力。
次の設定を変更してください。

+ **App Banners**

すべて終わったら、右下の<font color="#3367D6">**RELAUNCH NOW**</font>をクリック！！
再起動して、設定が適用されます。

---

以上で設定終了です。
PWA対応のサイトを開いてみましょう。

[A selection of Progressive Web Apps](https://pwa.rocks/)

[Twitter (Mobile)](https://mobile.twitter.com)

<details>
<summary>Twitter Mobile での表示結果</summary><div>

![スクリーンショット (49)_.png](https://qiita-image-store.s3.amazonaws.com/0/193558/4e17c5a1-fc96-9898-41e8-c9ea07e34dbb.png)

![スクリーンショット (50)_.png](https://qiita-image-store.s3.amazonaws.com/0/193558/535177fa-f955-c7f6-0bdd-51ce7ec64c8d.png)

![スクリーンショット (51)_.png](https://qiita-image-store.s3.amazonaws.com/0/193558/4572fb3e-a83f-44ad-e989-1131ddb7acb9.png)

![スクリーンショット (52)_.png](https://qiita-image-store.s3.amazonaws.com/0/193558/a612731b-4983-17f2-7e55-6137606146ae.png)

</div></details>

---

# 終わりに
今記事では、デスクトップPWAの利用のための設定を紹介しました。

webアプリケーションの開発がスムーズになるでしょうし、
デスクトップでもPWAの利用が大いに期待されます。

みなさんバンバン使っていきましょう!!!
PlayOnLinuxの「インストールメニュー」で止まるバグの根本的な解決法

#はじめに
このバグの対処についてはいくつかの解決法が既に示されています．
1. [エラーが起きる行をコメントアウト-http://singletonton.blogspot.com/2017/10/playonlinux.html](http://singletonton.blogspot.com/2017/10/playonlinux.html)
2. [旧バージョンの使用-http://ginnoza.wpblog.jp/avoid-stop-of-playonlinux](http://ginnoza.wpblog.jp/avoid-stop-of-playonlinux/)
3. [localeの変更-https://qiita.com/shun819/items/d6fa19747d31e125bc61](https://qiita.com/shun819/items/d6fa19747d31e125bc61)
しかし，2,3の解決法ではアプリの快適な利用の妨げになる可能性がある(英弱)し，1の解決法は一部の機能を変更して無理やり解決している感じがしたので，できるだけ根本的な解決方法を模索した次第です．

#環境
PlayOnLinux 4.2.12
Ubuntu 18.04

#発生していた問題
PlayOnLinuxでインストールボタンを押しても読み込み中のまま進まない
端末から開くと

```
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
    self.run()
  File "mainwindow.py", line 111, in run
    self.real_check()
  File "mainwindow.py", line 78, in real_check
    self.sendToStatusBar(_('Refreshing {0}').format(os.environ["APPLICATION_TITLE"]), True)
KeyError: '0 '
```
というメッセージが出力されていました．

#原因特定までの過程
アンダースコアが関数のように扱われていたので，`print(_)`を挟んでみたところ，
`<bound method GNUTranslations.gettext of <gettext.GNUTranslations instance at 0x7f91475fc200>>`
という出力が得られました．[gettextモジュール](https://docs.python.org/ja/3/library/gettext.html#the-gnutranslations-class)は翻訳関係のモジュールであるようなので，言語関係の設定を行っていそうな /usr/share/playonlinux/python/lib/lng.py を調べると

```python:lng.py
class iLang(object):
    def __init__(self):
        if(os.environ["DEBIAN_PACKAGE"] == "TRUE"):
            languages = os.listdir('/usr/share/locale')
        else:
            languages = os.listdir(Variables.playonlinux_env+'/lang/locale')

        langid = wx.LANGUAGE_DEFAULT
        if(os.environ["DEBIAN_PACKAGE"] == "TRUE"):
            localedir = "/usr/share/locale"
        else:
            localedir = os.path.join(Variables.playonlinux_env, "lang/locale")

        domain = "pol"
        mylocale = wx.Locale(langid)
        mylocale.AddCatalogLookupPathPrefix(localedir)
        mylocale.AddCatalog(domain)

        mytranslation = gettext.translation(domain, localedir, [mylocale.GetCanonicalName()], fallback = True)
        mytranslation.install()
```
この記述から， ~~/usr/share/locale/ja/pol.mo~~ (**2023/5/2更新 :/usr/share/locale/ja/LC_MESSAGES/pol.moにパスが変わっていました**)を使って翻訳を行っていることが特定できました．
moファイルは言語の翻訳情報が書かれているバイナリファイルで，英語の原文と日本語の翻訳後の文がkeyとvalueのセットになっているようです（この辺とても曖昧です）．
moファイルはバイナリなので，これを編集可能なpoファイルというものに戻し([.mo ファイルを .po ファイルに戻す方法-Qiita](https://qiita.com/katzueno/items/8a760acb64c73e73131a)を参照)，ファイル中の`msgstr "{0 }をリフレッシュ中"`の不要な空白を削除し`msgstr "{0}をリフレッシュ中"`と書き直して元のmoファイルに上書きすれば無事にバグが治りました．
以下簡単に結論を書きます．

#原因
polの日本語向けlocaleファイルpol.moの記述ミス

#対処
記述ミスの箇所の修正( {0 } -> {0} )

#最後に
根本的なとは言っても応急措置(アップデートが来たら上書きされる)なので，本当はwrapperのような形で書きたかったです．
[MySQL]homebrewでインストールしたMySQLが起動できなくなった話

#　はじめに
- [mysqlのsocketエラーでrailsアプリが起動できない](https://qiita.com/fujitora/items/d341c52706d1954cae28)
- [mysqlが起動できない](https://qiita.com/hondy12345/items/d32ed749fb49e9da7de6)
- [mysql起動で「The server quit without updating PID file」](https://qiita.com/mogetarou/items/e34ca51d3756d55d7800)

辺りを試してみてもMySQLが起動できなくなったので備忘録的に。
ちなみに発生したエラーメッセージは次の通り。

```
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
  ... /tmp/mysql.sock がない時に発生した

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (38)
  ... /tmp/mysql.sock を作った後に発生した

ERROR! The server quit without updating PID file (/usr/local/var/mysql/xxxxx.pid).
  ... mysql.server start した時に発生した
```


|項目|バージョン|
|---|---|
|Mac|macOS Mojave 10.14.1|
|Homebrew|1.8.4|
|MySQL|mysql  Ver 14.14 Distrib 5.7.24, for osx10.14 (x86_64) using  EditLine wrapper|

# 試したこと

## 確認に使ったコマンド

```bash:console
# MySQLのパスが通っているか
which mysql
# => /usr/local/opt/mysql@5.7/bin/mysql

# MySQLサービスが起動しているか
mysql.server status
# => SUCCESS! MySQL running (xxxx)

# プロセスが稼働しているか
ps aux|grep mysql
```

## 結論

`/usr/local/var/mysql` をディレクトリごと消去して再インストールしたらうまくいきました。

```bash:console
sudo rm -rf /usr/local/var/mysql
brew uninstall mysql@5.7
brew install mysql@5.7
brew services start mysql@5.7   
mysql.server start                                                              
mysql -uroot                    
```

## ダメだったこと

### アンインストール&再インストール

```bash:console
brew uninstall mysql@5.7
brew install mysql@5.7
```

### パーミッション・所有権変更

```bash:console
sudo chmod -R 777 /usr/local/var/mysql
sodo chown _mysql:_mysql /usr/local/var/mysql
```

### `/tmp/mysql.sock` を作成・権限変更

```bash:console
sudo touch /tmp/mysql.sock
sudo chmod -R 777 /tmp/mysql.sock
sodo chown _mysql:_mysql /tmp/mysql.sock
```

### MySQL関係のディレクトリを全消去

[**こちら**](https://qiita.com/furafura_nau/items/7d8f5370899df125d459#local%E9%85%8D%E4%B8%8B%E3%81%AEmysql%E5%85%A8%E3%81%A6%E5%89%8A%E9%99%A4%E3%81%97%E3%81%A6mysql%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB) を参考に関連ディレクトリを削除。
Hiveのパーティションを10分単位で切るときのFlume設定

Flumeのバージョンは1.8.0を想定。
公式リファレンスにも例が載っているが、sinkの設定で日付の丸めに関わるパラメータを設定する。
https://flume.apache.org/FlumeUserGuide.html

### HDFS Sinkの場合 (external tableの作成時)
hdfs.round, hdfs.roundValue, hdfs.roundUnitの3つを設定する。以下、エージェントa1における設定例。

```
a1.sinks.k1.hdfs.round = true
a1.sinks.k1.hdfs.roundValue = 10
a1.sinks.k1.hdfs.roundUnit = minute
```
hdfs.round (デフォルトfalse) をtrueにすることで日付の丸め （round downするとあるので日本語的には切り捨てが正しいか) を有効化する。
hdfs.roundValueを10にすることでtimestampの切り捨て値を10にする。
hdfs.rountUnitをminuteにすることでtimestampの切り捨て単位を分にする。

これで、10分単位で切ったパーティションのフォルダに転送を設定できる。

```
a1.sinks.k1.hdfs.path = /flume/events/%y-%m-%d/%H%M
```

### Hive Sinkの場合
round, roundValue, roundUnitを設定する。以下、エージェントa1における設定例。

```
a1.sinks.k1.round = true
a1.sinks.k1.roundValue = 10
a1.sinks.k1.roundUnit = minute
```
それぞれ、HDFSの場合と同様である。
パーティションは以下のように記述する。

```
a1.sinks.k1.hive.partition = asia,%{country},%y-%m-%d-%H-%M
```
数量化法の基礎　岩坪秀一先生　オーム社

```{r}

#数量化三類からマルコフ連鎖へ

#要確認

mat=t(matrix(c(1,1,1,1,0,1,1,1,0,1,1,1),ncol=4))

PXY=mat/sum(mat)

PX=diag(apply(mat,1,sum),length(apply(mat,1,sum)))/sum(mat)

PY=diag(apply(mat,2,sum),length(apply(mat,2,sum)))/sum(mat)

PYX=t(PXY)

sqrt_PY=((PY)^(-1/2));sqrt_PY[sqrt_PY==Inf]=0

A_star=sqrt_PY%*%PYX%*%solve(PX)%*%PXY%*%sqrt_PY

lambda=eigen(A_star)$values

eigen_vectors=eigen(A_star)$vectors

z2=eigen_vectors[,2];z3=eigen_vectors[,3]


y2=sqrt_PY%*%z2;y3=sqrt_PY%*%z3

x2=solve(PX)%*%PXY%*%sqrt_PY%*%z2/sqrt(lambda[2])

x3=solve(PX)%*%PXY%*%sqrt_PY%*%z3/sqrt(lambda[3])

A=solve(PY)%*%PYX%*%solve(PX)%*%PXY

#定常確率の確認

times=100

trans=A

for(j in 1:times){

trans=trans%*%A

}

stationary_prob=PY%*%rep(1,ncol(PY))

#カイ二乗検定(2変数の独立性)

floor((sum(diag(solve(PY)%*%PYX%*%solve(PX)%*%PXY))-1)*10^4)/(10^4)==floor((lambda[2]+lambda[3])*(10^4))/10^4

N2=length(lambda)

kai2=length(lambda)*(sum(diag(solve(PY)%*%PYX%*%solve(PX)%*%PXY))-1)

qchisq(1-0.05/2,length(lambda))



```
```{r}

#エントロピーを最大にする遷移確率を無効グラフから生成する

A=matrix(sample(c(0,1),6*6,replace = T),ncol=6)

lambda0=max(Re(eigen(A)$values))

eigen_vectors=Re(eigen(A)$vectors[,1])

P=array(0,dim=c(nrow(A),ncol(A)))

for(i in 1:nrow(P)){
for(j in 1:ncol(P)){  
  
P[i,j]=(1/lambda0)*A[i,j]*eigen_vectors[j]/eigen_vectors[i] 
   
}
}

entropy=(-P*log(P))

entropy=sum(entropy[is.nan(entropy)==F])


times=1000

stationary=P

for(j in 1:times){
  
stationary=stationary%*%P  
  
}

```
[AWS]API GatewayでAPIにリソースを挿入する

AWSを活用したサーバーレスアプリケーションを勉強中に困ったことを書いていきます。

## こんな人向け

APIGatewayに沢山リソースとメソッド作成した！  
と、思ったら頭の方に階層が足りないことが発覚(´･ω･`)  

## やりたいこと

### Before

    /
      POST
        /resource_1
          GET
        /resource_2
          POST
                         その他もろもろ...

### After

    /
      /{param1}    // 追加
        POST
          /level_11
            GET
          /level_12
            POST
                         その他もろもろ...

## できそうな方法を考えてみる

- コンテキストメニューで挿入的なメニューがあるんじゃないか？  
  → ありません＼(^o^)／

- 作れる場所に作ってから、ドラッグ＆ドロップすれば...！  
  → できません＼(^o^)／

ということで、
[AWS Loft Tokyo](https://aws.amazon.com/jp/start-ups/loft/tokyo/) のAsk An Exportというサービスを利用させていただきました。

AWSのアカウントを持っていれば、無料で利用できるコ・ワーキングスペース、Ask An ExportでAWSの質問が可能です。

本当はもっと高度な相談をするためのものなんだろうな...と引け目も感じつつ、
聞くは一時の恥、聞かぬは一生の恥と勇気を出して質問してみましょう。

Q. 上記のようなことをする方法がありますか？  
A. あー、、、簡単にはできませんねぇ。

ということで、代替の方法を教えていただきました。

1. APIをSwaggerでエクスポートします。
1. Swaggerを編集します。
1. 編集したSwaggerをインポートします。

ふむ、確かに。。。  
ということでとりあえず出来たのですが、実はこの後に **落とし穴** があります。
各メソッドからLambdaを呼び出す設定が消えるので設定し直しです＼(^o^)／

## 所感

API設計をちゃんとやってから作りましょう！と言ってしまえばおしまいですが、
APIにリソースを追加したり、整理したりすると、こういうこともよくあると思いますので、
挿入する階層まで全部作り直し！よりはマシな方法として覚えておきたいです。
Tweepy で Twitter に画像付きのツイートをする

sample.png という画像付きの投稿をします。

```py:send_picture.py
#! /usr/bin/python
#
#	send_picture.py
#
#						Nov/28/2018
# ------------------------------------------------------------------
import sys
import tweepy
from key_tweepy import key_tweepy_proc

sys.stderr.write("*** 開始 ***\n")


api = key_tweepy_proc()

message = ""
message += "投稿のテスト\n"
message += "２０１８年１１月２８日　午後７時５０分\n"
#
#
#api.update_status(message)
api.update_with_media(filename='./sample.png',status=message)
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

key_tweepy.py はこちらと同じです。
[Tweepy で Twitter の単語を検索する](https://qiita.com/ekzemplaro/items/92bf8f680b7667f028d5)
Tweepy で Twitter にツイートする

```py:send_tweet.py
#! /usr/bin/python
#
#	send_tweet.py
#
#						Nov/28/2018
# ------------------------------------------------------------------
import	sys
import	tweepy
from key_tweepy import key_tweepy_proc

sys.stderr.write("*** 開始 ***\n")

api = key_tweepy_proc()

message = ""
message += "投稿のテスト\n"
message += "２０１８年１１月２８日　午後７時４５分\n"
#
api.update_status(message)
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

key_tweepy.py はこちらと同じです。
[Tweepy で Twitter の単語を検索する](https://qiita.com/ekzemplaro/items/92bf8f680b7667f028d5)
justInCase にエンジニアとして参加してからやったこと

2017 年 3 月より [justInCase](https://justincase.jp/) にエンジニアとしてお手伝いさせてもらっています。

![justincase-dev.png](https://qiita-image-store.s3.amazonaws.com/0/17936/72df46be-94ac-2f8d-8b33-3ea175971094.png)

その当時から justInCase 最初の保険商品としてモバイルアプリで完結するスマホ保険を提供するというのは決まっていました。

保険商品は当局の許可がないとリリースできません。 CEO の畑さんと CTO 小泉さんは、当局への折衝や営業なども含めて、すべての業務をこなしている状況でした（その状況自体は今も大きく変わっていないような気はしますが）。

そんな中、開発をより促進すべく、私ともうひとりアプリエンジニアがほぼ同時期にお手伝いとして参加することになったわけです。

## 当時の状況

- Swift でコーディングされた動くアプリはあった（デモアプリ的な位置づけ）
- AppStore 申請も試されていた
- BitBucket (git) を使ってコードのバージョン管理はされていた
- 基本 master ブランチ一本
- CEO / CTO がコーディングして、変更状況や内容は Slack 上で情報共有されていた
- BitBucket で将来的にやりたいことは簡易ながら数点チケット化はされていた

BitBucket を使ってアプリ開発の管理するという形にはなっていましたが、まだ試行錯誤な状態でした。

## ガイドラインの作成

justInCase に参加して私が最初にやったのは……

![jic-first-slack-message.png](https://qiita-image-store.s3.amazonaws.com/0/17936/55a853d4-1375-49d2-4c39-61dbd49de068.png)

1. コードならびにアプリ動作の確認
2. ガイドライン (開発工程・コーディング) の作成・提案
3. ガイドラインに沿って実践

私が参加した段階で CEO / CTO もまだ開発を行っていく前提でしたし、私とほぼ同時期に参加するもう一人のエンジニアもいらっしゃいました。つまり、私を含めて少なくとも 4 人ほどの開発人員がいる状態でした。また、それぞれ別々の場所で業務をこなしていて、開発要員全員がリモートでの開発という環境でもありました。

少人数の開発でうまく回っている、とりあえず開発が前進している、状態では、ガイドラインそのものはあまり必要でないというか、意識されないものです。

ただ、今回は今後のコミュケーションを円滑に進めるためにもたたき台となれるドキュメントはあった方がよいと判断しました。

## 開発工程

![jic-dev-flow.001.png](https://qiita-image-store.s3.amazonaws.com/0/17936/494f9cdf-bbfe-e863-ae5b-97eca4c1b5d5.png)

開発の手順を明確にしました。つまり、

1. チケットの発行・割り当て
2. feature ブランチの生成
3. 実装作業・feature ブランチへコミット
4. develop ブランチへの pull-request を作成
5. コードレビュー
6. pull-request のマージ・チケットの resolve

という手順に沿って開発しましょう、というのを文書化しました。

## 文書化と実践

文書にすると

- フィードバックを受けやすく、それを元に改善できる
- 後から参加する人に説明しやすい・共有できる

という大きな利点があります。一方

- メンテコストがかかる

という欠点もあります。メンテされない文書は害にもなりえるので、いつ更新したのかが分かる形で文書を残した方がいいでしょう。

ただ文書化しただけではダメで、それを私が実践してみせるということもすぐに実行しています。自ら実践してみて改善点が見えたり、言葉足らずの部分を発見します、そうして、それをまた文書に反映していきます。

## エンジニア募集中

そんな感じでフルリモートで開発のお手伝いを始めてもうすぐ二年になろうとしていますが、まだまだやることいっぱいです。

justInCase では一緒にアプリ・サービスを作り上げていただけるエンジニアを絶賛募集中です。

- [国内初P2P保険を創る！ブロックチェーンエンジニア募集！](https://www.wantedly.com/projects/257441)
- [フィンテック最期の砦:IT保険会社のインフラをサーバーレスで作る！](https://www.wantedly.com/projects/251109)
- [保険APIで保険フィンテック先駆けを作るサーバーサイドエンジニア！](https://www.wantedly.com/projects/251106)
- [フロントエンジニアfor保険テック保険会社！](https://www.wantedly.com/projects/169590)

よろしくお願いします。
AVRマイコンの整数型の実行速度について検証してみた

Arduino StudioのC++では整数型は`byte`、`int`、`long`の3種類 ( `unsigned`とか抜くと多分この3種類 ) が扱えるが、大きい型で計算したときにパフォーマンスにどのくらい影響があるのかというのを調べた。
# 調べた理由
* Arduinoで音声関連のリアルタイム処理をしたかったが、その前にどこまで計算量の多さに気をつける必要があるのかを調べたかった。 ( 実験の結果によっては可能な限りbyte型を使うようにする必要もある。 ) 
* ~~Google力が足りなかった~~
# 前提条件
 やろうと思っている音声関連処理はArduino Uno R3を利用する。Arduino UnoはATmega328というマイコンで、

* クロック周波数は16MHzである → 24KHzの音声を処理する場合1標本につき使用できるのは約666クロック分 ( 少ない、節約する必要があるかもしれない ) 
* メインメモリ ( データ格納 ) はSRAMである → メモリアクセスの遅延はほとんど影響しない?
* RISC型CPUであり、機械語の1命令が1クロックで実行できる → 機械語の量が処理時間とほぼ比例する

# 実験
以上のことから、処理時間を調べるためには実機で動作させるよりも生成された機械語の量を見るほうが確実であると考えた。そのため、それぞれ違う型で整数型の足し算` a = a + b ` のみを行うC言語のコードを書き、コンパイル後の機械語の詳細を調べた。
### 対照実験
```
void setup() {
  volatile byte a = 2;
  volatile byte b = 3;
}
void loop() {
}
```

上の例は`byte`型の場合の対照実験である。`int`型の対照実験のときは`byte`が`int`になったりする。
普通に変数を2つ定義しただけだと恐らく、最適化の過程で`a`と`b`はなかったことにされるので`volatile`をつけて最適化を防止する。

[こちらのページ](http://olfash.hateblo.jp/entry/arduino_helloworld)を参考に、
`avr-objdump -m avr -D -z testspec.ino.standard.hex` 
で逆アセンブルをした。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/152352/f58acc9b-188a-a305-1f44-3e83b39349a1.png)


今回は対照実験なのでこのコードの詳細を調べたりはしない(ので全文は載せません)。

### byte型の場合

```
void setup() {
  volatile byte a = 2;
  volatile byte b = 3;
  a += b;
}
void loop() {
}
```

このコードを逆アセンブルし、先程の対照実験のコードと比較した。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/152352/2a0ccbc5-288f-f455-fde5-083991ebc57f.png)

上の部分は、`jmp`のジャンプ先の番地が変わっているが、`jmp`のプログラムの番地が変わることに関してはコード量が増えて後半のコードが後ろに押し出されただけなので正直どうでもいい。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/152352/aa2bc606-b5e9-f92a-1f19-a8fb7f625d0e.png)

ここでもjmpなどのプログラムの番地がずれているために差ができている。しかし、それ以外にも、右側のコードには以下の4行のコードが追加されている。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/152352/71020b0d-8898-3d1b-7af5-d41435759932.png)

機械語未経験者なので詳しいことは分からないが、

1. ( レジスタY+1 ) 番地のメモリからレジスタ25に1バイトロード
2. ( レジスタY+2 ) 番地のメモリからレジスタ24に1バイトロード
3. レジスタ24にレジスタ25の値を加算する
4. レジスタ24の値を ( レジスタY+2 ) 番地のメモリに書き込む

という処理をしているらしい。機械語ではよくあるa=a+bの処理である。
[ここ](http://www.cs.shinshu-u.ac.jp/~haeiwa/m-com/instruction.html)を参考にクロック数を計算してみたところこの部分で7クロック必要であることがわかった。

### int型の場合
```
void setup() {
  volatile int a = 2;
  volatile int b = 3;
  a += b;
}
void loop() {
}
```
Arduino StudioのC++では`int`は2バイト型である。


対照実験のコードや`jmp`の飛び先が違うだけの差分は省略する。

差分の中でも、計算に用いるコードは実質以下の通り。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/152352/68305cd4-8cf6-5de5-0681-b63f142de432.png)

Arduinoはリトルエンディアンなので、2バイトの変数の場合は上位8ビットが後ろ側に来る。
このコードで言うと、
 ( Y+1 ) 番地には変数bの下位8ビットが、
 ( Y+2 ) 番地には変数bの上位8ビットが、
 ( Y+3 ) 番地には変数aの下位8ビットが、
 ( Y+4 ) 番地には変数aの上位8ビットが、それぞれ格納されているらしい。
また、ここでは加算命令が2回行われている。最初のadd命令で下位8ビット同士を足し算し、次にadc命令で、先程の計算の繰り上がりを考慮しながら上位8ビット同士を足し算している。

どうやら、AVRマイコンは8bitの値しか計算に使用できず、16ビットの値を計算するには2回に分けて行う必要があるらしい。この部分の命令の実行には合計14クロック必要である。`int`型の場合、`byte`型に比べて型の大きさが2倍になったぶん計算にかかる時間も2倍になっている。

### long型の場合
もうほとんど結果は見えているけど。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/152352/81839b2c-f7e5-ef04-566f-05d1892e49e1.png)

`byte`型のときに比べて4倍、`int`型のときに比べて2倍の量である、加算命令4回になっている。実行には合計28クロックかかる。

#結論
 AVRでは、`byte`型が使えるときは実行速度のために`byte`型を積極的に使うべき。
Tweepy で Twitter の単語を検索する

次のページを参考にしました。
[Python 今更ながらTweepyを使って、Twitterを操作する](https://qiita.com/gurensouen/items/484e3198bcafa69f5c8b)

```py:search_word.py
#! /usr/bin/python
#
#	search_word.py
#
#						Apr/26/2019
# ------------------------------------------------------------------
import  sys
import  tweepy
from key_tweepy import key_tweepy_proc

# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")

api = key_tweepy_proc()

word = ["グリム童話"]
set_count = 10
results = api.search(q=word, count=set_count)

for result in results:
	username = result.user._json['screen_name']
	user_id = result.id
	print("ユーザーID："+str(user_id))
	user = result.user.name
	print("ユーザー名："+user)
	tweet = result.text
	print("ユーザーのコメント："+tweet)
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

```py:key_tweepy.py
#
#	key_tweepy.py
#
#					   Apr/26/2019
# ------------------------------------------------------------------
import  tweepy
import os
from dotenv import load_dotenv

# ------------------------------------------------------------------
def key_tweepy_proc():
	dotenv_path = '.env'
	load_dotenv(dotenv_path)
	consumer_key = os.environ.get("CONSUMER_KEY")
	consumer_secret = os.environ.get("CONSUMER_SECRET")
	access_token = os.environ.get("ACCESS_TOKEN")
	access_token_secret = os.environ.get("ACCESS_TOKEN_SECRET")
#
	auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
	auth.set_access_token(access_token, access_token_secret)

	api = tweepy.API(auth)

	return api
#
# ------------------------------------------------------------------
```

```text:.env
CONSUMER_KEY = '******'
CONSUMER_SECRET = '******'
ACCESS_TOKEN = '******'
ACCESS_TOKEN_SECRET = '******'
```
IT未経験者がサーバーOSの違いを調べたお話

#はじめに
入社して2ヶ月足らずのIT未経験者の私が、研修中に学んだサーバーOSの違いについて、私なりにまとめた議事録的な扱いになります。
【目的】さまざまな文献を元に本当に必要な情報だけを抽出したページとなります。
※調べた内容について、齟齬がありましたら指摘のほどお願い致します。※

####簡単な自己紹介
前職は4年弱花屋の営業をしてました。
ITを活用して活躍をしたいと思い、転職を決意。
ITってなんぞやというところから下剋上をするため、IT業界へチャレンジ。
日夜PCと格闘する日々を行っています。
好きな言葉は「情熱」です。

#想定読者
-IT未経験者(うぇるかむかもーん)
-OS入門者

#そもそもOSってなんぞ？
<img alt="network_dennou_sekai_man.png" src="https://qiita-image-store.s3.amazonaws.com/0/316274/a9093a7d-e036-f43c-33e9-2a34b07bd0af.png" width=50%>
~~コンピュータネットワークを可視化した仮想空間（電脳世界・サイバースペース）にダイブした男性のイラストです。~~

**Operating System**の略で、コンピューターを動作させるための基本的なソフト。
Windows,Mac,Linux,Unixなどがありますね。
その中でもLinux系やUnix系などは、オープンソースが多くコストもかからず、有志の方々によって日々進化をしております。
また、自分自身でカスタマイズができるのが特徴なので、バシバシトライアンドエラーを重ねて作り上げていくのも魅力です。
[こんなんじゃわからないんだよなぁって人はこちらを見てください。]
(https://wa3.i-3-i.info/word179.html)

#OSの種類を紹介するぜ！
OSの種類もかなりあるので、今回は絞って以下の3つで比較をしていきたいと思います。
概要から特徴までざっくりとカキカキしていきますよぉ～いくいくっ

1. [Cent OS](https://www.centos.org/)<br>
Red Hat Enterprise Linuxを踏襲したフリーのLinux ディストリビューション。
RHELのベースを互換してきているので、**安定性がピカイチ。**
Linuxをこれから勉強したい人やWindowsユーザーも比較的取り入れやすくオススメ。
また、会社単位でも利用するケースが多い。<br>
きらら系で例えると、可愛さの安定している[スロウスタートの十倉栄依子ちゃん](https://slow-start.com/character/?chara=eiko)ですね！<br>
2. [BSD](https://www.freebsd.org/ja/)<br>一言で**正統派Unix。**(王道を征く～Unix系ですかねぇ)C言語をベースとしたサーバーOSで歴史も古くから存在している。
セキュリティの観点でも強固ではありますが、習熟した方が使うのがベター。
また、研究で使う分には無償だが、商用となると有料になるのが難点。
きらら系で例えると、攻略が簡単そうにみえてすごく難しい[スロウスタートの十倉栄依子ちゃん](https://slow-start.com/character/?chara=eiko)ですね！




3. [Ubuntu](https://www.ubuntulinux.jp/)
ウブンチュやウブンツって呼び方がバラバラのOSちゃん。~~〇〇ちゅって呼び方が可愛い(小並感)~~
GUIよりのCUIが特徴のLinux。ユーザーフレンドリーをモットーに
GUIなので初心者の方も取り入れやすいのが特徴。
簡単に使うことができるので、**世界での利用数がNo1!**
Ubuntuを使ったアプリケーションでいうと、FirefoxやThunderbird,Dropboxなど馴染みがある人が多い印象。
きらら系で例えると、きらら系初心者でも馴染めて入ることができる[ご注文はうさぎですか？の香風智乃ちゃん(チノちゃん)](https://matome.naver.jp/odai/2147246635392284701)ですね！ヤバスギでしょwww


#軍配
###適材適所に尽きる
使いたい人がどういう用途(目的)で使いたいかによります。~~(投げやり)~~
これから勉強をしていきたい人や初心者向け→　Cent OS
会社のネットワークエンジニアの高みを目指す人は→　BSD
個人レベルで楽しみたい人　　　　　　　　→　Ubuntu
みたいな感じでいいかと思います。

自己学習などのレベルでいけば、Cent OSやUbuntuが無料なので、敷居も低く取り掛かりやすいです。

ポイント別だとこんな感じかなと思います。(個人の見解なのでご了承をお願いします。)

|　OS|コスト|セキュリティ|はじめやすさ|
|:---|:----| ----|------|
|Cent OS|　◎|　 　○|　　  ◎|
|BSD|　△|　　   ◎|　　  ☓|
|Ubuntu|　◎|　　   △|　　  ◎|


#おわりに
ふわっとした感じの結論でクロージングになってしまいましたが、ビギナーの方には無駄がないシンプルな文献だったんじゃないでしょうか。(自画自賛)
私自身、研修中はCent OSを使いながら実践してきましたが、Cent OSの使いやすさにびっくりしました。初めて触る方にも優しい仕様なので、苦なくできるのはいいですね！

現在、さまざまな企業が仮想環境下で仕事をしているようです。PCの設定も必要なくなるので、すぐ業務に取りかかれるのがメリットみたいです。~~(業務中のログも取れるようなので、管理者は便利ですね！)~~
仮想環境のメリットやデメリットを知りたい人は[こちらも参考にしてはいかがでしょうか。]
(https://boxil.jp/mag/a1301/)

次回は、画像をマシマシに載せていきますので、1発目は多めに見て頂けますと幸いでございます。
Golang - new vs make

# new
1. returns its address(pointer)
2. does not initialize the memory

# make
1. creates slices, maps, and channels only
2. returns an initialized (not zeroed) value
3. does not return its address(pointer)

https://stackoverflow.com/questions/9320862/why-would-i-make-or-new
https://medium.com/d-d-mag/golang-%E7%AD%86%E8%A8%98-make-%E8%88%87-new-%E7%9A%84%E5%B7%AE%E5%88%A5-68b05c7ce016
https://golang.org/doc/effective_go.html#allocation_make
https://golang.org/doc/effective_go.html#allocation_new
オンプレGitLabのGravatarを無効にする

## 経緯
オンプレのGitLabがなぜかインターネットアクセスしようとするのが気になったので調べてみました(社内の認証プロキシに引っかかるから…)。
GitLabのアヴァター(利用者のアイコン)にはデフォルトではGravatarというグローバルなアヴァターが採用されていて、このアヴァターを取りにインターネットにアクセスしようとするみたいです。
無効にする方法はググったらすぐ見つかった…んですが情報が古くなってしまっていたので、うまくいった方法をメモしておきます。

## GitLabのバージョン
GitLab CE 11.4.0 (2018/10/22 リリース)

## GitLabの設定
設定ファイルをいじらないといけなかったのが、GUIで簡単に設定できるように変更されたみたいです。

### 古い方法(失敗)
下記の設定変更後、"sudo gitlab-ctl reconfigure"
> ```rb:/etc/gitlab/gitlab.rb
> gitlab_rails['gravatar_enabled'] = false
> ```

### 新しい方法
Admin Area＞Settings＞General＞Account and limit＞Gravatar enabledのチェックを外す
> ![GitLab_Gravatar_enabled.png](https://qiita-image-store.s3.amazonaws.com/0/320581/c0331c5b-fa96-e1c8-c01d-eae8a5b1e7a2.png)

## 効果
GitLabのアヴァターがGravatarからオンプレに切り替わり、アヴァター取得のためのインターネットアクセスがなくなります。
JUnit 4からJUnit 5に移行する

JUnit 5の機能を利用するために、既存のJUnit 4プロジェクトの移行を試しました。

#### 移行手順

##### (1) 依存関係を追加する

以下の3つの依存関係を追加する。

* junit-jupiter-engine
* junit-platform-launcher
* junit-vintage-engine（JUnit 3・JUnit 4のテストを実行する場合のみ必要）

pom.xml記述例（2018年11月28日時点の最新版）

```xml
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.3.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.platform</groupId>
    <artifactId>junit-platform-launcher</artifactId>
    <version>1.3.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.vintage</groupId>
    <artifactId>junit-vintage-engine</artifactId>
    <version>5.3.2</version>
    <scope>test</scope>
</dependency>
```

##### (2) テストメソッドを更新する

junit-vintage-engineを使えばJUnit 5でJUnit 3・JUnit 4テストを実行できるが、単純なアノテーションの置換で変換できるものは更新してしまうこともできる。

| JUnit 4 (org.junit.*) | JUnit 5 (org.junit.jupiter.api.*) |
| --------------------- | --------------------------------- |
| Test                  | Test ※                            |
| Ignore                | Disabled                          |
| Before                | BeforeEach                        |
| After                 | AfterEach                         |
| BeforeClass           | BeforeAll                         |
| AfterClass            | AfterAll                          |

※ アノテーションの属性は互換性がないことに注意

#### EclipseでJUnit 5実行する

Eclipse 4.7.3 (Oxygen) 以上であればJUnit 5を実行できる。実行するにはテストしたいクラス（メソッド）を右クリック → 実行 → JUnitテスト を選択すればよい。

※ Eclipseはプロジェクトの依存関係から実行するJUnitのバージョンを自動的に選択する。（JUnit 4の古い実行構成が残っている場合はこれを削除してから実行すること。）

#### 参考

* https://qiita.com/naotawool/items/a8d77ff9d468fedab2c9
Cloud PubSubの ack(Acknowlede)がわからなかったのでまとめた

Cloud PubSubのAcknoledgeがよくわからなかったのでまとめ。基本pullのsubscriptionであることを前提としています。すべて公式docに載っている内容です。

# Cloud PubSubとは?
イケてるマネージドキューサービス
https://cloud.google.com/pubsub/docs/overview

# Pubsubのack(Acknowlede)とは?

- サブスクライバーがpubsubに送る確認応答のこと
- pubsubはacknowledeを受け取ると、message storageからメッセージを削除する
  - [Pub/Sub の概念とメッセージ フロー](https://cloud.google.com/pubsub/docs/overview#concepts)
  - [データプレーン - メッセージの一生](https://cloud.google.com/pubsub/architecture#data_plane_-_the_life_of_a_message)
  - [at-least-once配信](https://cloud.google.com/pubsub/docs/subscriber#at-least-once-)
- ackDeadliceSecondsで設定された期限前にackされない場合は、subscriberに再送信される(デフォルト10秒/最大10分)
  - ackは関係ないけどPubSubのメッセージ保持期間はmessageRetentionDurationで設定された期間(デフォルト/最大値は7日で最小は10分)
  - [サブスクリプションの設定](https://cloud.google.com/pubsub/docs/subscriber#create)

# Acknowledeの確認方法

```shell

% gcloud alpha pubsub subscriptions describe sub_name                                                                                                                                                  (
ackDeadlineSeconds: 10
expirationPolicy:
  ttl: 2678400s
messageRetentionDuration: 604800s
name: projects/xxx/subscriptions/sub_name
pushConfig: {}
topic: projects/xxx/topics/topic_name
```

- `ackDeadliceSeconds`: subscriberがackするまでのdeadline
  - 値が10だった10秒以内にackされない場合は再送信される
- `expirationPolicy`: subscriptionのexpiration設定。
  - 値が31日だった場合、subscriptionがactive(subscriberが処理に成功する)にならない場合はsubscriptionは削除される(default31日/最小1日)
- `messageRetentionDuration`: publish後にmessage storageに保持する期間
  - この値が7日だった場合、7日間ackされないmessageは削除される。(デフォルト最大7日/最小10分) 
  - `retainAckedMessages`がtrueの場合はこの値はack後seek可能な期間となる
- [subscription create options] (https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.subscriptions/create)


# AckDeadlineSecondsを変更したい場合

`gcloud alpha pubsub subscriptions update subscription_name --ack-deadline=11`
- [gcloud alpha pubsub subscriptions update](https://cloud.google.com/sdk/gcloud/reference/alpha/pubsub/subscriptions/update)
LogstashのApache用grokフィルタ %{COMBINEDAPACHELOG} 


Logstash から Elasticsearch にログを送って Kibana で表示したけどアクセス数が変？

#### よく見る Apache アクセスログ用 grokフィルタ：
```
filter {
    grok {
        match => { "message" => "%{COMBINEDAPACHELOG}" }
```

https://github.com/hpcugent/logstash-patterns/blob/master/files/grok-patterns　
によると、

`%{COMBINEDAPACHELOG}` の内容は、読んだまんま combined ログフォーマットで、　


`%{COMMONAPACHELOG} %{QS:referrer} %{QS:agent}`

と同等。ログの最後にリファラとAgentがついてない行は無視されてしまうぽい。

`%{COMMONAPACHELOG}` の方の内容はこれ：

`%{IPORHOST:clientip} %{HTTPDUSER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes}|-)`

ログの例：
`123.45.78.9 - - [14/Nov/2018:00:00:04 +0900] "GET / HTTP/1.1" 200 18696`

%{} の順番とログを見比べてみよう
オリジナルのログ出力にしてあるならその通りに組み立てればOK

### Grok debugger

https://grokdebug.herokuapp.com/

上の箱にログを貼り付けて下に grok パターンを書くと、何が返るかを表示してくれる。
`%{COMMONAPACHELOG}` の例：
![スクリーンショット 2018-11-28 18.38.21.png](https://qiita-image-store.s3.amazonaws.com/0/45576/2f18c968-3969-944b-ec93-02401f9f8aab.png)

リファラとagentがないと、`%{COMBINEDAPACHELOG}` ではエラー：
![スクリーンショット 2018-11-28 18.38.45.png](https://qiita-image-store.s3.amazonaws.com/0/45576/89db8a83-382a-9eac-f347-a8c268d6a827.png)

リファラがある行はOK：
![スクリーンショット 2018-11-28 18.40.52.png](https://qiita-image-store.s3.amazonaws.com/0/45576/6ac9e042-8799-e8c3-46a1-ca66c3722d6d.png)

複数条件はうまく読んでくれない...？
![スクリーンショット 2018-11-28 18.44.41.png](https://qiita-image-store.s3.amazonaws.com/0/45576/10e03736-32d6-2920-65d8-665aa3cbbfef.png)
AWS IoT

**■AWSのIoTにはどんなサービスがあるのか**

クラウド側

|サービス名 |詳細 |
|:--------------------:|:-------------------- |
|AWS IoT Core|エッジデバイスをクラウドに接続させ、それらのデバイス管理や通信のセキュリティを担保する |
|AWS IoT Device Management |IoTは一気に接続されるデバイスが増えていくという属性を持っています。それらのデバイスを属性化し、管理を簡易する |
|AWS IoT Device Defender | 全てのセキュリティソリューションをエッジで動かすリソースを確保できないケースがあります。その場合、エッジのセキュリティはゲートウェイの外側で担保する|
|AWS IoT Analytics |IoTから上がってくるデータに対して、リアルタイムでデータ分析をする |

モノ側

|サービス名 |詳細 |
|:--------------------:|:-------------------- |
|Amazon FreeRTOS |オープンソースの組込みシステム向けリアルタイムOS。64kbpsでも動作する。これによって接続できるデバイスが増えていく|
|AWS Greengrass|クラウド側で実行される処理を、ローカル環境のゲートウェイなどにオフロードし、軽減させる|

↓を見てどんな時にIotが使われているのか掴みましょう。

参考：
[AWS IoT ソリューションの進化と、それが生み出すビジネス成果]
(https://www.youtube.com/watch?v=XBhJrndZa4Q&feature=youtu.be)
[AWS IoTソリューション Introduction](https://www.youtube.com/watch?v=xaUhMjKjeL4&feature=youtu.be)
KitematicでSearchの返答がなくなる

# 概要
DockerのGUIツールであるKitematicにてイメージのSearchを実行しようとすると終わらなくなったので調査したところ回避方法がわかったので共有

# 環境
```
OS : macOS High Sierra
Docker : 18.06.1-ce-mac73
Kitematic : 0.17.5
```

# 原因
Kitematicの最新バージョンである0.17.5に問題があるらしい

# 回避方法
暫定的になってしまいますがバージョンを0.17.3に落とすことで解消しました。
下記のページにて「Kitematic-0.17.3-Mac.zip」をクリックしてダウンロード。
[ダウンロードページ](https://github.com/docker/kitematic/releases)

# 参考
20181129追記
[参考](https://github.com/docker/kitematic/issues/4234)
PHPでリンクをクリックしたら、新しいページを生成する

以下がindex.php

```php
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="keywords" content="XXX">
<meta name="description" content="XXX">
<title>XXX</title>
<link rel="stylesheet" href="/main.css">
</head>

<body>
<?php
try {
	//DB名、ユーザー名、パスワード
	$dsn = 'mysql:dbname=XXX;host=XXX';
	$user = 'XXX';
	$password = 'XXX';

	$PDO = new PDO($dsn, $user, $password); //MySQLのデータベースに接続
	$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //PDOのエラーレポートを表示
	$sql = "SELECT * FROM contents"; //SELECT文を変数に格納
	$stmt = $PDO->query($sql); // SQLステートメントを実行し、結果を変数に格納

	// foreach文で配列の中身を一行ずつ出力
	foreach ($stmt as $row) {
		echo "<a href='https://thejoinery.jp/item.php?id=";
		echo $row['id'];
		echo "'>";
		echo $row['name_en']."<br/>";
	}
} catch (PDOException $e) {
	exit('データベースに接続できませんでした。' . $e->getMessage());
}
?>

<?php echo $rows; ?>
</body>
</html>

```


以下が個別ページ

```php
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="keywords" content="XXX">
<meta name="description" content="XXX">
<title>XXX</title>
<link rel="stylesheet" href="/main.css">
</head>

<body>
<?php
try {
	//URLのidの値を取得
	$id = $_GET['id'];

	//DB名、ユーザー名、パスワード
	$dsn = 'mysql:dbname=XXX;host=XXX';
	$user = 'XXX';
	$password = 'XXX';

	$PDO = new PDO($dsn, $user, $password); //MySQLのデータベースに接続
	$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
	$result = $PDO->query("SELECT id FROM contents WHERE id = '$id'");
  while($row = $result->fetch(PDO::FETCH_ASSOC)){
    $rows .= $row['id']."</br>";
  }
} catch (PDOException $e) {
	exit('データベースに接続できませんでした。' . $e->getMessage());
}
?>

<?php echo $rows; ?>

</body>
</html>

```
PHPでMySQLから一つだけデータを取り出す

```php
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="keywords" content="XXX">
<meta name="description" content="XXX">
<title>XXX</title>
<link rel="stylesheet" href="/main.css">
</head>

<body>
<?php
try {
//DB名、ユーザー名、パスワード
	$dsn = 'mysql:dbname=XXX;host=XXX';
	$user = 'XXX';
	$password = 'XXX';

	$PDO = new PDO($dsn, $user, $password); //MySQLのデータベースに接続
	$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
	$result = $PDO->query("SELECT id FROM contents WHERE id = 47329"); //MySQLのid列が47329の行だけを抽出
  while($row = $result->fetch(PDO::FETCH_ASSOC)){
    $rows .= $row['id']."</br>";
  }
} catch (PDOException $e) {
	exit('データベースに接続できませんでした。' . $e->getMessage());
}
?>

<?php echo $rows; ?>

</body>
</html>
```
AmbariからNiFiのどんなものを集められるか？

# AmbariのNiFi監視：
![image.png](https://qiita-image-store.s3.amazonaws.com/0/133516/e33f23f6-a3c1-099f-a489-5279cecc0f2d.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/133516/4f876e73-6d91-756e-6a43-83e824d23026.png)

# AmbariのNiFiアラート
Ambariは監視と知らせる（Alert）ことは出来ます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/133516/69a24619-64a5-e14d-598c-eedbcce91222.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/133516/a680b559-2950-ee12-f088-ff229b439053.png)

方法は４つあります。

```
EMAIL 
SNMP (for MIB-based)
Custom SNMP
Alert Script
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/133516/d910507c-f50a-1fc9-bf0f-2179c602bda1.png)

どんな異常（あるいは閾値を越えた）が起きたら、どんな行動をするかはそれぞれ定義出来ます。


# Ambari Metrics
Metricsを監視するなら、Ambari Metricsはもっと優れています。
Metricsがもっと見やすい。

インストール時に集められるMetricsはクラスタレベルで、データフローレベルのMetricsはNiFiの設定により、取得することも出来ます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/133516/9f90ac60-cc63-2cb3-5bb5-79be146c8279.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/133516/17390761-2cc8-fb0d-c2fd-cac24b219b4b.png)
C++ Builder XE4 > TStringGrid と TCalendar > TStringGridにTCalendarの文字列をコピーして、背景色を変更する実装

```txt:動作環境
C++ Builder XE4
```

### 処理概要

- TCalendarとTStringGridがある
- TStringGridにTCalendarの文字列をコピーする
- TStringGridの一部のセルの背景色を変更する

### 実装

```Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ComCtrls.hpp>
#include <Vcl.Grids.hpp>
#include <Vcl.Samples.Calendar.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
	TButton *Button1;
	TCalendar *Calendar1;
	TStringGrid *StringGrid1;
	void __fastcall Button1Click(TObject *Sender);
	void __fastcall StringGrid1DrawCell(TObject *Sender, int ACol, int ARow, TRect &Rect,
		  TGridDrawState State);

private:	// ユーザー宣言
public:		// ユーザー宣言
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

```

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <memory>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	// カレンダー文字列のコピー

	StringGrid1->RowCount = 7;
	StringGrid1->ColCount = 7;
	StringGrid1->DefaultColWidth = 40;
	StringGrid1->FixedRows = 1;
	StringGrid1->FixedCols = 0;

	for(int ri=0; ri<7; ri++) {
		for(int ci=0; ci<7; ci++) {
			StringGrid1->Cells[ci][ri] = Calendar1->CellText[ci][ri];
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol, int ARow, TRect &Rect,
		  TGridDrawState State)
{
	if (ARow == 3) {
		StringGrid1->Canvas->Brush->Color = clRed;
		StringGrid1->Canvas->FillRect(Rect);

		StringGrid1->Canvas->Brush->Color = clWhite;
		String str = StringGrid1->Cells[ACol][ARow];
		DrawText(StringGrid1->Canvas->Handle, str.c_str(), str.Length(), &Rect, Position);
	}
}

```

### 動作例

![2018-11-28_18h18_01.png](https://qiita-image-store.s3.amazonaws.com/0/32870/442205c0-254e-b8a6-8e8c-0bbc37928f22.png)

### 備考

TCalendarのDrawCell()をoverrideして、色を付くようにする。
というのが早いという意見がある。

その方法は今のところ見つかっていない。
CloudWatch Logs Insightsを試す

# CloudWatch Logs Insights
今年のRe;Inventで公開されました。
[New – Amazon CloudWatch Logs Insights – Fast, Interactive Log Analytics | Amazon Web Services](https://aws.amazon.com/jp/blogs/aws/new-amazon-cloudwatch-logs-insights-fast-interactive-log-analytics/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+AmazonWebServicesBlog+%28Amazon+Web+Services+Blog%29)

簡単にまとめると、CloudWatch Logsのロググループに対してSQLを用いたクエリーを投げ、ログを集計することができるサービスです。
今まで、CloudwatchLogs見れたものではなかったのでとても素晴らしいアップデートだと思います。

東京リージョンでもう使えるようになってます。
お値段についてですが
> you pay $0.005 per GB in US East (N. Virginia), with similar prices in the other regions.

とあるので、Athena等を使用するときと同様期間で区切って不要なログの走査をしないように気をつける必要があります。

サンプル画面から試すと一瞬なのが

- VPCフローログ
- CloudTrailログ

なんかです。

今回はRDSの監査ログを参考に設定を入れてみたので紹介します。

# Aurora監査ログの仕様
[監査ログの詳細](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Auditing.html#AuroraMySQL.Auditing.Logs)

上記ドキュメントに記載されている通りの形式でログファイルがCloudWatchLogsに連携されます。

今回は連携されたログのObjectセクションに記載されているQueryのうち`SELECT`の件数を５分毎に集計してダッシュボードに表示してみます。

#　手順
マネジメントコンソールからCloudwatchへ移動し、[ログ　-　インサイト]を選択する。
![スクリーンショット 2018-11-28 18.01.46.png](https://qiita-image-store.s3.amazonaws.com/0/52141/622b0c68-0b7b-fa4e-0387-c43acf23107c.png)

上部の検索窓から対象のロググループを選択する
今回は監査ログを使用したのでデフォルトだと`/aws/rds`からはじまるロググループです。

![スクリーンショット_2018-11-28_18_02_53.jpg](https://qiita-image-store.s3.amazonaws.com/0/52141/31a92ab6-1aca-a796-4def-f84e16c7104a.jpeg)

```sql:Query
fields @message
  | parse "*,*,*,*,*,*,*,*,'*',*" as timestamp, serverhost, username, host, connectionid, queryid, operation, database, object,retcode
    | filter object like /SELECT/
    | fields username, object, timestamp
    | stats count(*) by bin(5m)
```

もともと入ってきたCloudWatchLogsのフィールドが自動的に
@logStream
@message
@timestamp

と解析されます。その中からログ本文である@messageを`parse`を使用してパースしていきます。
,で区切られてobjectフィールドのみ''でくくられているので、それがわかるように記載します。また、各フィールドの名前をつけます。
その後、objectに対して文字列のパターンマッチングを行い、５分感覚で件数を集計しました。

![スクリーンショット 2018-11-28 18.09.43.png](https://qiita-image-store.s3.amazonaws.com/0/52141/b00da29b-2a90-8a17-5b48-22d09dc461b6.png)

可視化のタブを押すとグラフが表示されます。
Alertの実装なんかは現状ひと手間加えないと無理そうですが、今後拡張されてそのままSNSに通知できるとかになれば手軽でいいですね。

> limit of four concurrent CloudWatch Logs Insights queries.

Queryは同時に４つまでしかダメっぽいです



ドキュメント記載が見当たりませんが(2018/11/28 18時現在)
logs配下のstart-queryがAPIエンドポイントになっているようです。CLIを更新したところhelpで確認できました

```bash:command
aws logs start-query \　#　クエリを開始する時間。
  --log-group-name \ # 対象のロググループ名
  --end-time \ # このクエリがまだ実行されている場合は、このクエリを終了する時間。UNIX秒の秒数で指定
  --query-string # Query文字列（UNIXタイム）　
```


# 参考
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/AnalyzingLogData.html
https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_StartQuery.html
【BurpSuite】IntruderでPayloadsのリストをインポートする方法

こんにちは。

Burp SuiteでIntruderのPayloadsにリストをインポートしたかったんですが、そもそもリストの作り方を書いてる記事が無いので書きます。


- Burp SuiteでIntruderタブを選択
- Payload Optionsにて、Load...を選択し、リストを読み込む
![burp.JPG](https://qiita-image-store.s3.amazonaws.com/0/299829/66e9c8df-48bd-cec1-930b-1303270d5763.jpeg)

- リストを作る（図はweb健康診断の例）
    - 任意のテキストエディタで一行ずつPayloadを入力
    - メモ帳だと文字化けする（UTF-8、Unicode）
    - SHIFT-JISだと文字化けしない
    - EOFは改行してもしなくても可
![web_kenkohsindan.JPG](https://qiita-image-store.s3.amazonaws.com/0/299829/25ea02a0-d5f8-1361-a48f-9f5cbfd0cf46.jpeg)

- 以上です
Xamarin.FormsでFirebase DebugViewの設定

公式のFirebaseのドキュメントにはXcodeやAndroid Studio用の説明しかなくXamarin用のドキュメントとして備忘録のために投稿。ほぼ、公式Firebaseのドキュメントと同じだがほんのちょっとだけ違う...

## Android
ターミナルにて以下のコマンドを実行するのみ

```
adb shell setprop debug.firebase.analytics.app <package_name>
```

※ `<package_name>` 部分にはアプリのパッケージ名を入力

## iOS
iOSのプロジェクトオプションを開く
構成　> Default の「追加のmlaunch引数」部分に以下を入力し「OK」をクリック

```
--argument=-FIRAnalyticsDebugEnabled
```
<img width="963" alt="スクリーンショット 2018-11-28 14.16.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/100644/1ec1504e-6a29-8d3c-8962-7401508b64d7.png">


上記設定の上エミュレーターもしくは実機で動作確認をするとFirebaseコンソールのDebugViewにて確認ができます。

<img width="1285" alt="スクリーンショット 2018-11-28 14.50.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/100644/0084ef5a-13f2-f5cd-317f-0d8ef278f074.png">

# 参考にしたサイト
[公式　イベントのデバッグ](https://firebase.google.com/docs/analytics/debugview?hl=ja)
[How can debug firebase analytics](https://forums.xamarin.com/discussion/93036/how-can-debug-firebase-analytics)
[Firebase Analytics DebugView の設定の仕方](https://qiita.com/donuzium/items/cec53c07c2a69600fd90)
Ruby on Rails チュートリアル　サーバー起動しなかった

rails s でサーバーが起動しない
エラー文　rails new APP_PATH [options]

[原因]
カレントディレクトリが間違っていた

[対応]
pwdで現在のディレクトリを確認
結果：home/ec2-user/environment
cdでディレクトリを移動
cd ~/environment/hello_app/
pwdで確認

結果：/home/ec2-user/environment/hello_app

rails s で無事サーバー起動
数値・金額用テキストボックスの紹介

#数値・金額用テキストボックスの紹介
通常の使い方です。ツールチップを出すのが大事です。
![num1-compressor.gif](https://qiita-image-store.s3.amazonaws.com/0/259123/6c26abbe-d278-d072-9b93-114432d66f8e.gif)
間違って文字を打った場合はこうなります。数字以外の文字を打つたびにツールチップを表示します。
![num2-compressor.gif](https://qiita-image-store.s3.amazonaws.com/0/259123/9ce13078-86b8-3692-e7a0-fa65d4c2dbc3.gif)
金額用は頭に￥マークとカンマ編集をします。
![amount1-compressor.gif](https://qiita-image-store.s3.amazonaws.com/0/259123/ace4a5f4-d345-9bdb-0750-d61cda263778.gif)
文字対策は数値と同様です。
![amount2-compressor.gif](https://qiita-image-store.s3.amazonaws.com/0/259123/b46ac338-8332-3bda-5001-2f0556236222.gif)

機能の詳細はDEMOページに記載しました。

#DEMO
https://wakaba-bbq.github.io/NumTextBox_Recommend/

#github
https://github.com/wakaba-bbq/NumTextBox_Recommend


#こだわり
今回は「PowerTip」というツールチップを使ってみました。
採用理由は**任意のタイミングでツールチップを表示することができる**からです。

数値・金額用のテキストボックスに一番必要なのは、ユーザが間違って文字を入力した際に、いかに気づかせるかだと思っています。

テキストボックスへのフォーカスやクリックした際のみならず、文字を入力したタイミングでツールチップを再表示してあげています。

gitにjs・htmlを載せていますので、使いたい方はご自由にどうぞ。
0～2のランダムな数値を3つ取得し、「それぞれの数値」と「最も数値が大きい変数」の情報を表示。※「最も数値が大きい変数」が複数ある場合は複数表示

```HTML
<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8">
   <title>if&amp;3つの数値から最大値を求める</title>
</head>
<body>
   <script>
        var rand1 = Math.floor(Math.random() * 3);
        var rand2 = Math.floor(Math.random() * 3);
        var rand3 = Math.floor(Math.random() * 3);
        document.write('<p>rand1: ' + rand1 + '</p>');
        document.write('<p>rand2: ' + rand2 + '</p>');
        document.write('<p>rand3: ' + rand3 + '</p>');
        
        
        //３つがすべて同じ値の場合
       
        if ( rand1 === rand2 && rand2 === rand3 ) {
            document.write('<p>3つは同じ値です</p>');
        }
        
        if ( rand1 === rand2 ){
            if ( rand2 >rand3) {
                document.write('<p>一番値が大きいのはrand1とrand2です</p>');
            }else {
                document.write('<p>一番値が大きいのはrand3です</p>');
            }
        } else if (rand1 === rand3) {
            if ( rand3 >rand2) {
                document.write('<p>一番値が大きいのはrand1とrand3です</p>');
            }else {
                document.write('<p>一番値が大きいのはrand2です</p>');
            }
        } else if (rand2 === rand3) {
            if ( rand3 >rand1) {
                document.write('<p>一番値が大きいのはrand2とrand3です</p>');
            }else {
                document.write('<p>一番値が大きいのはrand1です</p>');
            }
        } else if ( rand1 > rand2 && rand1 > rand3 ) {
            document.write('<p>一番値が大きいのはrand1です</p>');
        } else if ( rand2 > rand3 && rand2 > rand1 ) {
            document.write('<p>一番値が大きいのはrand2です</p>');
        } else if ( rand3 > rand2 && rand3 > rand1 ) {
            document.write('<p>一番値が大きいのはrand3です</p>');
        }
    </script>
</body>
</html>
SolidusのライブラリをVSCodeで開く方法

#はじめに
　.bashrcにてSolidusのライブラリのソースコード(solidus_core（モデル等） solidus_backend（管理画面等） solidus_frontend（ECサイト側機能等）)をVSCodeで開く方法をご紹介します。

##エディタの設定
下記の３行を１行ずつ実行して .bashrc （またはログインシェルの .rc ファイル）ターミナルを再起動してください。

```
export PATH=“$PATH:/Applications/Visual\ Studio\ Code.app/Contents/Resources/app/bin”
source ~/.bashrc
export EDITOR=code
```


再起動後、以下のコマンドを実行します。

```

# solidus_core（モデル等）
bundle open solidus_core

# solidus_frontend（ECサイト側機能等）
bundle open solidus_frontend

# solidus_backend（管理画面等）
bundle open solidus_backend
```