OmniAICreator/Qiita-1.07M huggingface dataset:
秋月のプラズマボールを動かす

# はじめに
プラズマボールを買ったのですが電源の±を間違えてドキドキしたのでメモ
全体像はこんな感じ
電源にプラスマイナス間違えずにつなげればいいだけなんだけど間違えてしまった・・・（プラズマボールが死ななくてよかった）

![alt](https://d2l930y2yx77uc.cloudfront.net/production/uploads/images/6239605/picture_pc_c082fb8d92697f506e71ec0a2539f232.jpg)

実際に動いている動画は下記です
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">秋月電気で買ってきたプラズマボールを動かしてみた！<br><br>かっこいいー <a href="https://t.co/wUeifIJkXn">pic.twitter.com/wUeifIJkXn</a></p>&mdash; まりーな (@marina10172013) <a href="https://twitter.com/marina10172013/status/988034515812536321?ref_src=twsrc%5Etfw">2018年4月22日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 必要なもの
## プラズマボール

プラズマボール（PBL40U-01）700円
説明書によると
[プラズマボール　ＰＢＬ４０Ｕ－０１　日本製](http://akizukidenshi.com/catalog/g/gM-05645/)

>■主な仕様
・入力電圧：ＤＣ１２Ｖ（±１０％）
・消費電流：ＭＡＸ　１７０ｍＡ
・使用温度範囲：５～５０℃


なので直流12Vで1,7A以下の電源を探しました

![alt](https://d2l930y2yx77uc.cloudfront.net/production/uploads/images/6239607/picture_pc_b657287805a07abb21eab83cf0d5d798.jpg)

## スイッチングACアダプター(950円)
プラズマボールの仕様書から12Vくらいで、1.5Aより小さい電源を探しました。自分が秋月電子にいったときは外のワゴンの下辺りにありました
[スイッチングＡＣアダプター１２Ｖ１．５Ａ　１００Ｖ～２４０Ｖ　ＧＦ１８－ＵＳ１２１５－Ｔ](http://akizukidenshi.com/catalog/g/gM-02194/)
![alt](https://d2l930y2yx77uc.cloudfront.net/production/uploads/images/6239610/picture_pc_54afd5011c673f1a7e2107aedaeb8e15.jpg)

## メスのケーブル(250円)
上の電源とプラズマボールをつなげるのに買いました
[ＤＣジャック付ケーブル１．８ｍ　（２．１ｍｍ）　ＭＣ－２３７６](http://akizukidenshi.com/catalog/g/gC-06566/)

電源は下記の赤く囲まれている部分をみたら外側がマイナスで内側がプラスということはわかるのですが
<img width="237" alt="screenshot.png" src="https://qiita-image-store.s3.amazonaws.com/0/176479/a79da7ed-2c81-3476-9391-c9eaa16a4f2d.png">

メスに差し込んだあとの配線がどっちがプラスでどっちがマイナスなのかわからない・・・

![alt](https://d2l930y2yx77uc.cloudfront.net/production/uploads/images/6239612/picture_pc_5fb4768c305ffb5afd67b4275eee5622.jpg)

実験してみたところ
どうやら白線が入っているケーブルが内側（今回でいうとプラス）のようです
![alt](https://d2l930y2yx77uc.cloudfront.net/production/uploads/images/6239615/picture_pc_b5a8526f7873b3d62e0b3d633bad1f3d.jpg)
無事に繋げられました
きれいですね・・・
![alt](https://d2l930y2yx77uc.cloudfront.net/production/uploads/images/6239624/picture_pc_af816e001326d581bb81960760f22478.jpg)
単独で実行可能な Ktor アプリケーション の jar を生成する


最近覚えた Kotlin を使って新規で Web API サーバを作り始めた結果、単独で実行可能な jar ファイルの生成でつまづきました。
公式のチュートリアルではうまく行かなかったので、やったことを書いていきます。

[shadow][shadow] をうまく使えなかった話です。

IDE 上で実行可能な状態にするまでは、 「[KtorでJSONを返すまで][ktor-json]」 を参考にしました。

## 環境
* IntelliJ IDEA ULTIMATE 2018.1
* Java 8 (java version "1.8.0_91")
* Kotlin 1.2.40
* [Ktor 0.9.0][ktor]
* Gradle 4.5.1
* Groovy 2.4.12
* macOS High Sierra 10.13.3 (開発環境)
* CentOS Linux release 7.4.1708 (Core) (デプロイ先サーバ)

## つまづくまで
Ktor 公式の [Setting up Project in IntelliJ IDEA][ktor-intellij-setting] を見ながら開発環境を整えました。
「[KtorでJSONを返すまで][ktor-json]」 を参考に、 JSON を返却できるところまで進めました。

ローカルでの動作が確認できたので、とりあえずサーバにデプロイしたいと考えました。

デプロイするにあたり [Ktor 公式のデプロイ方法][ktor-fat-jar] を眺めていると、スタンドアロン実行可能な jar ファイルを生成できるというものを発見しました。
すなわち、

```bash
java -jar yourapplication.jar
```

で Web アプリケーションが起動するとのことでした。
しかし、公式ページを参考に `build.gradle` に [shadow][shadow] を用いてパッケージ生成をさせようと試みましたが、これがまるでうまく行きませんでした。
どう直してもMainクラスを参照できないのです。

[shadow][shadow] を用いて jar ファイルを生成した結果、全てのクラスファイルが shadow ディレクトリ配下に配置されていました。
これでは、 `io.ktor.server.${jettyやnetty}.DevelopmentEngine` を参照できません。

## 解決方法
stackoverflow で見つけた方法をもとに、自分で gradle の task を定義しました。
参考にした回答は [こちら][stackoverflow] です。

```java
task fatJar(type: Jar) {
    manifest {
        attributes "Implementation-Title": project.name,
                "Implementation-Version": version,
                "Main-Class": mainClassName
    }
    baseName = project.name
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    exclude "META-INF/*.RSA", "META-INF/*.SF", "META-INF/*.DSA"
    with jar
}
```

[Ktor 公式のデプロイ方法][ktor-fat-jar] をもとに `build.gralde` を書き進めていれば、 `mainClassName` はすでに定義してあります。
これを `Main-Class` に指定した task `fatJar` を作成しました。
これにより、

```bash
gradle fatJar
```

で `build/libs/${project.name}-${version}.jar` が生成されます。
生成された jar ファイルは

```bash
java -jar ${project.name}-${version}.jar
```

で実行できます。

## 終わりに
自前で gradle task を定義することで、スタンドアロン実行可能な jar ファイルを生成できました。
もしかしたら [Ktor 公式の shadow を用いた方法][ktor-fat-jar] に手を加えることで対応できるのかもしれません。

Ktor, Kotlin, Gradle ともにまだ理解が浅いですが、Apache Tomcat を用いたWebサーバよりはとっつきやすいかと思います。

[ktor-json]: https://qiita.com/KissyBnts/items/1e1caa636941391a380e
[shadow]: https://github.com/johnrengelman/shadow
[ktor]: https://github.com/ktorio/ktor
[ktor-intellij-setting]: https://ktor.io/quickstart/intellij-idea.html
[ktor-fat-jar]: https://ktor.io/servers/deploy.html
[shadow]: https://github.com/johnrengelman/shadow
[stackoverflow]: https://stackoverflow.com/a/48565836
はじめてのAlexa Skill開発

# 目次
- 概要
- Amazon Echoとは
- Amazon Alexaとは
- Alexa Voice System(AVS)とAlexa Skill Kit(ASK)

## まとめ
- Amazon Echoとは
    - Amazon.comの開発した音声認識端末

- Amazon Alexaとは
    - クラウドベースの人工知能（AI）音声認識サービス

- Alexa Voice Service(AVS)とAlexa Skill Kit(ASK)
    - Alexaはサードパーティによる拡張が可能。主な方法は以下の２つ
    - AVS
        - AVSとは：Amazon Alexaと接続を提供できるツール
        - 実現できること：「マイク」「スピーカー」「インターネット接続」ができる端末に、Echoと同じ機能をもたせる
    - ASK
        - ASKとは：音声で操作する機能を簡単に開発できる無料のSDK
        - 具体的には、API、ツール、ドキュメント、コードサンプル
        - 実現できること：Skillという形で標準では備えていない拡張機能の実装


# 1. 概要
Amazon EchoのCustom Skill開発が初めて！という人に向けた、開発における概念を抑えます。

# 2. Amazon Echoとは
Amazon.comの開発した**スマートスピーカー**。Google Homeの友達。
様々なことを**音声のみ(ハンズフリー)で操作**できる端末である。
例えば・・・

- 「Alexa、今日の天気は？」聞くと、居住地域の今日の天気を教えてくれる
- 「Alexa、JR東日本で総武線」と聞くと、総武線の遅延情報を教えてくれる
- 「Alexa、タイマー15分」と言うと、15分のタイマーをセットしてくれる
- 「Alexa、おはよう」と言うと、この日歴史では何があったのか教えてくれる

# 3. Amazon Alexaとは
Amazon Echoやその他音声認識端末が使える、**クラウドベースの人工知能（AI）音声認識サービス**。
受け取った音声を自然言語処理し、テキスト文字列に変換することができる。

### 主な機能
#### ユーザー発話後（Request生成と送信）

- Speech to Text
    - 音声を文字列に変換
    - AWSで独自に実装するなら、Amazon Lex
    - （今記事では解説しないが）Slots割り当てもここで行う

####主処理後（Response受信と発話処理）

- Text to Speech
    - 文字列を音声に変換
    - AWSで独自に実装するなら、Amazon Polly


【Skill実行におけるAlexaのイメージ】
![image.png](https://qiita-image-store.s3.amazonaws.com/0/197517/a3990786-0868-8625-686c-f40d371c08f9.png)
引用元：https://www.sbbit.jp/article/cont1/34026

# 4. Alexa Voice Service(AVS)とAlexa Skill Kit(ASK)
## AVSとは
Amazon Alexaと**接続を提供できるツール**、及びAlexa搭載製品を開発するためのキット。
チップセット、音声処理テクノロジー、AVS APIを活用したクライアントソフトウェアが含まれており、簡単に音声デバイスが構築できる。

## ASKとは
Amazon Echoに**拡張機能を提供できるツール**、及び独自に開発するためのキット。
多くの拡張機能はこれを用いて作られ、Custom Skill(Alexa Skill)という形で提供される。

#次回
独自にAlexaSkill(Custom Skill)を作ることについて
SlotやUtteranceなど、開発に必要な概念を抑えます

#余談1. 「AI」スピーカーではないの？
公式にはGoogleもAmazonも「スマートスピーカー」である。
Amazon Echo自体はただ「マイク」と「スピーカー」を持ち、「インターネット接続」を行えるだけの端末であり、「発話者の言葉を学習し、返答を変えていく」機械学習チックなことはまだ実現できていないし、端末に実装されてすらいない。
また、接続先に音声認識機能があるため、どちらかというとその部分がAIである。（自然言語処理のみの機会学習）

#参考文献
『Amazon Alexaとは何か？ アマゾンの音声認識技術の使い方を基礎から解説する』
https://www.sbbit.jp/article/cont1/34026
『Alexaスキル開発トレーニングシリーズ 第1回 初めてのスキル開発』
https://developer.amazon.com/ja/blogs/alexa/post/6e716e5c-55b0-445b-b936-9cfac4712e7b/training-1
『AVSとは』
https://developer.amazon.com/ja/alexa-voice-service/learn
『ASKとは』
https://developer.amazon.com/ja/alexa-skills-kit
DS18B20仕切り直し

# 始めに
[以前の記事](https://qiita.com/twinoze/items/6b2d06c4ab5cbc23d62d)でDS18B20を使用した温度入力をしようとしたが、GPIOにアナログ入力がないためにあきらめて・・・と書きました。
が、ほかの方からの指摘で、このセンサーはアナログではなく、1-Wireというれっきとしたデジタル通信にて温度情報を出力するセンサーとの情報を頂きました。
そこで今回はリベンジ！とばかりにリトライしてみます。

# とりあえず初期化
扱い慣れている方にとってはまったく問題ないのかもしれませんが、何分初心者。行き詰った際に何が悪影響しているのか切り分けするだけの知識もありません。とりあえずラズパイを初期化することにしました。
電源を入れた直後の画面に「Shift」と表示されます。これが表示されている間にキーボードのShiftキーをおします。
すると、NOOBSによるOS管理画面になります。
ここで、インストールするOSの種類を選択する画面になります。
今回はシステムを初期化するのが目的のため、前回同様Rasbianを選択しました。
インストール開始時に、以前のデータを上書きするか確認があるため、これを「はい(Y)」にすると、インストールが開始されました。
[ モニタの写真を撮ってはいたのですが、極端に移りが悪かったため掲載を遠慮しましたm(__)m ]
# 下準備
ラズパイのコンフィグファイルに以下の行を足します。

```text:/boot/config.txt
dtoverlay=w1-gpio-pullup,gpiopin=4
```

合わせて以下の行も足します。

```text:/etc/modules
w1-gpio
w1-therm
```
設定修正後にシステムを再起動します。

```
$ reboot
```

# 回路
最終的に、この様に接続しました。
![DS18B20_2.png](https://qiita-image-store.s3.amazonaws.com/0/248779/eca02104-d14b-be70-ea26-237cb88a6e14.png)
[DS18B20の素子の向きに対して電源とGNDの向きが逆じゃないか？との指摘があり画像を修正しました。ご指摘ありがとうございました。]
当初プルアップを接続していませんでしたが、その場合次項の[アドレス確認]で確認しているDS18B20のアドレスが表示されませんでした。
2KΩのプルアップ抵抗で認識する様になりました。
また、手元にセンサーが二つあったので二つを並列に接続しました。

# アドレス確認
接続しているDS18B20のアドレスを確認します。

```
$ls -l /sys/bus/w1/devices/
```
![Screenshot_20180423_013235.png](https://qiita-image-store.s3.amazonaws.com/0/248779/4987838a-45ca-9e0d-1503-83727a16cebd.png)

1-Wireのデバイスは、重複のない64bitのアドレスを持っているとのこと。
上記コマンドで確認可能なアドレスは、これを表しています。
今回接続したセンサーのアドレスは[28-*****]の物です。

# プログラム
```python:ds18b20_main.py
#!/usr/bin/python
# coding: utf-8
import time
from ds18b20_sub import get_temp

print ("DS18B20 test Start!")
try:
	while 1:
		temp0=get_temp(0)
		temp1=get_temp(1)		
		print('temp0:{0:3.3f} degC\ttemp1:{1:3.3f} degC'.format(temp0, temp1))
		time.sleep(1)
except:
    pass
print ("DS18B20 test End!")
```
```python:ds18b20_sub.py
#!/usr/bin/python
# coding: utf-8
# モジュールをimport
import os
import glob

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
path = '/sys/bus/w1/devices/'

# センサー入力
def get_w1_slave(id):
	devdir = glob.glob(path + '28*')[id]
	device = devdir + '/w1_slave'
	file = open(device, 'r')
	lines = file.readlines()
	file.close()
	return lines

# 温度データ
def get_temp(id):
	cnt = 0
	lines = get_w1_slave(id)
	while lines[0].strip()[-3:] != 'YES':
		sleep(0.1)
		if cnt > 3 :
			return -1
		cnt = cnt + 1
		lines = get_w1_slave(id)
	pos = lines[1].find('t=')
	if pos != -1:
		strtemp = lines[1][pos + 2:]
		temp_c = float(strtemp) / 1000.0
		return temp_c
```

![Screenshot_20180423_130104.png](https://qiita-image-store.s3.amazonaws.com/0/248779/86051142-dd57-ceae-cf70-1a00d8c150f8.png)

2本の温度センサーの値を取得することが出来ました。
片方のセンサーを手で触ってみると、温度が変化するのが分かります。

# 感想
先にテストしていたI2Cと同じく温度の情報を比較的簡単に取得できました。
I2Cでは、表示出力が行えるLCDモジュールなどもあるようです。
今回使用したDS18B20が使用している1-Wireではどんな機器があるのでしょうか？ちょっとググった感じでは、I2Cの方が使いやすい機器が多いように感じました(^^ゞ
Oracleインスタンスが起動時に読み込んだ環境変数を確認する


pmonが読み込んでいる環境変数を/proc/<PID>/environファイルから確認する。
文字化け問題が発生し、インスタンスのNLS系の環境変数を確認するときに使用。


```
ps -ef | grep [p]mon | awk '{print "/proc/" $2 "/environ"}' |xargs strings
```

以下、実行例。


```
$ ps -ef | grep [p]mon | awk '{print "/proc/" $2 "/environ"}' |xargs strings
XDG_SESSION_ID=2
HOSTNAME=ol122a
SELINUX_ROLE_REQUESTED=
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=10.0.2.2 56610 22
SELINUX_USE_CURRENT_RANGE=
SSH_TTY=/dev/pts/0
USER=oracle
ORACLE_SID=orcl
ORACLE_BASE=/u01/app/oracle
MAIL=/var/spool/mail/oracle
<中略>
SKGP_SPAWN_DIAG_PRE_EXEC_TS=1524400254
SKGP_SPAWN_DIAG_PRE_FORK_TS=1524400254
SKGP_SPAWN_DIAG_POST_FORK_TS=1524400254
```

変数にORAを含むものを表示。

```
$ ps -ef | grep [p]mon | awk '{print "/proc/" $2 "/environ"}' |xargs strings| grep ORA
ORACLE_SID=orcl
ORACLE_BASE=/u01/app/oracle
ORACLE_HOME=/u01/app/oracle/product/12.2.0.1/dbhome_1
ORA_NET2_DESC=9,12
ORACLE_SPAWNED_PROCESS=1
```
PM 午後2平成27年度 問2 情報システム開発プロジェクトにおける品質の評価、分析について

問題文をフロー化してみた
青のオブジェクトが問題文から拾い上げたもの
赤の部分が問題文をさらに具体化(PMBOXや情報処理のテキストに載っている手法を書いている）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/136860/8b884399-38da-0e4d-39c3-2147ba5d7fea.png)

フロー化して気がついたのだけど、問題文が品質の評価、分析のフローとしてよくできていると思う
ask v2の俺的テンプレ

色々間違いがいあるかもだから随時更新して行く予定

```
$ mkdir sample
$ cd sample
$ npm init
$ npm install --save ask-sdk
```

`index.js`

```js
'use strict';

const Alexa = require('ask-sdk');
const other = require('./other.js');

const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  handle(handlerInput) {
    var msg = 'LaunchRequestgが呼ばれたときに発動します';

    return handlerInput.responseBuilder
      .speak(msg)
      .reprompt(msg) // これがあることによって会話が終了しない
      .getResponse();
  }
};

// 自分で定義したインテント
const sampleIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'sampleIntent';
  },
  handle(handlerInput) {
    var msg = "自分で定義したインテントの時に呼ばれます";

    return handlerInput.responseBuilder
      .speak(msg)
      .reprompt(msg)
      .withSimpleCard('カードを表示します', msg)
      .getResponse();
  }
};

//exports.handler = Alexa.SkillBuilders.custom()
exports.handler = Alexa.SkillBuilders.standard()
  .addRequestHandlers(
    LaunchRequestHandler,
    other.HelpIntentHandler,
    other.SessionEndedRequestHandler,
    sampleIntentHandler)
  .addErrorHandlers(other.ErrorHandler)
  .lambda();
```

`other.js`

```js
module.exports = {
  HelpIntentHandler: {
    canHandle(handlerInput) {
      return handlerInput.requestEnvelope.request.type === 'IntentRequest'
        && handlerInput.requestEnvelope.request.intent.name === 'AMAZON.HelpIntent';
    },
    handle(handlerInput) {
      var msg = 'ヘルプって言われた時に発動するよ';

      return handlerInput.responseBuilder
        .speak(msg)
        .reprompt(msg)
        .withSimpleCard('Hello World', msg)
        .getResponse();
    },
  },

  SessionEndedRequestHandler: {
    canHandle(handlerInput) {
      return handlerInput.requestEnvelope.request.type === 'SessionEndedRequest';
    },
    handle(handlerInput) {
      return handlerInput.responseBuilder.getResponse();
    },
  },

  // v1のunhandledと同等。
  ErrorHandler: {
    canHandle() {
      return true;
    },
    handle(handlerInput, error) {
      return handlerInput.responseBuilder
        .speak('もう一度おねがいします')
        .getResponse();
    },
  },
}
```
Spring Bootの依存性注入（DI）設定方法

Spring Frameworkの依存性注入（Dependency Injection）を設定する方法をまとめました。

### コンポーネントのスキャン対象指定

デフォルトでは `@ComponentScan` が付与されたクラスのパッケージと同階層以下のパッケージをスキャンする。その他のクラスをスキャン対象にしたい場合は`scanBasePackage`にパッケージ名を指定する。

```java
// @SpringBootApplicationなどの複合アノテーションに指定することもできる。
@ComponentScan(scanBasePackages={"com.example"})
```

### 依存性注入（DI）設定

#### Springアノテーションを使う場合

依存するオブジェクトを `private`  `final` なメンバとして定義して、コンストラクタで依存オブジェクトを引数で受け取るコンストラクタを定義する。Lombokを使う場合は下記のように記載できる。

##### コンポーネント定義

```java
@Component
class ComponentA { ...
```

##### DI設定

```java
@RequiredArgsConstructor
class ClassA {
	// @Autowiredは省略できる。
	private final ComponentA componentA;
	...
```

以前は`final`でないメンバもしくはそのSetterに`@Autowired`を指定するのが主流であった。

```java
class ClassA {
	@Autowired
    private ComponentA componentA;
	...
```

```java
class ClassA {
	private ComponentA componentA;
	@Autowired
	public void setComponentA(ComponentA componenA) {
		...
```

コンストラクタを利用することには以下のメリットがあるため、現在はこちらが推奨されている。

- DIなしでも利用可能なモジュールになる。（利用側でコンストラクタで依存関係を設定すればよい。）
- `final` 修飾子を付けられる。（DIオブジェクトを格納する変数を書き換えることは通常ない。）

#### JSR-330アノテーションを使う場合

Java標準なので他のDIコンテナに乗り換えやすい。

##### コンポーネント定義

```java
@Named // もしくは@ManagedBean
class ComponentA { ... }
```

##### DI設定

コンストラクタ（もしくはSetter）に`@Inject`を指定する。（Setterでも可。）

```java
@RequiredArgsConstructor(onConstructor=@__(@Inject))
class ClassA {
	private final ComponentA componentA;
	...
```

もしくは、メンバに`@Inject`を指定する。

```java
class ClassA {
	@Inject
	private ComponentA componentA;
    ...
```

### 参考

- http://pppurple.hatenablog.com/entry/2016/12/29/233141
- https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#using-boot-spring-beans-and-dependency-injection
- https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-standard-annotations
Rails Tutorial 2周目覚書（2章）

##第2章 Toyアプリケーション
scaffoldでおもちゃアプリを作る章。
モデルやコントローラー、ビューの各リソースで何ができるか解説するための章っぽいですが、ある程度勉強した人ならサラッと流せる感じ。コラムの方が勉強になった気がする。RESTとか。

###rakeコマンドについて
Rails5以降からrailsコマンドに統合された。古いHow toを見て混乱しないように。
>※Unixでは、ソースコードから実行用プログラムをビルドするために主にMakeというツールが使われてきた。Rakeはいわば、Rubyで記述することのできるRuby版のMakeといった言語。
Rails 4以前のアプリケーションでは、rakeコマンドのバージョンをGemfileで定義しているため、Bundlerのbundler execコマンドを通して実行する必要があった。
例：$ bundle exec rake db:migrate

###データ型について
>string型の上限がかなり大きいのでそこに保存するとかなり余ってしまいます。text型ならもっと手頃で、かつ最大長を必要に応じて大きくすることもできます。

らしい。軽く調べたけどさっぱりだったので課題として残しておこう。
textだとlimitいじれるっぽいのは分かるんだけど、DBによっても違うっぽい？

2章はホントこれくらいしか...
ただ、さくっと進めるからといって13章までのペースを見誤ると痛い目に合う気がします。
後半の章は1章数日掛かると見積もった方が良いかも。だれだ3日で全部終るとか言った奴は。
Rails Tutorial 2周目覚書（1章）

#目的
一通りはやってみたが、最近触れてないこともあり時間が経つと忘れがち。
何が出来たかは大体覚えていても、__どうやってやったか__、もっと言えば__それはどこに書いてあったか__すら忘れている。
調べなおせば良いとはいえ、これでは時間の無駄が多すぎるので、要点やほほーっと思った点、忘れそうな（忘れていた）点、知らなかったことなどを適当にまとめていこうと思う。

##第1章　ゼロからデプロイまで
主に開発環境を用意する章。
万が一これを読んだ方がwindows環境なら、お勧めはチュートリアルと同じくcloud9。windows7なんかで頑張ってしまうと謎不具合に悩まされるし正直時間の無駄になると思います（というかなった）。初級者だとクラウドなんて聞くと気後れしてしまいますが、思った以上に簡単なので急がば回れで。

###Bundlerについて
rails newで勝手に実行されてる。
バージョン番号を指定しない限り、Bundlerは自動的に最新バージョンのgemを取得。

###gemのバージョン指定について 
>マイナーアップグレードでも問題発生の可能性があるため基本はがっちり指定。
\>=という記法では常に最新のgemがインストールされ、~> 4.0.0という記法ではマイナーバージョンの部分に相当するアップデート済みのgem (例: 4.0.0から4.0.1) をインストール。
コマンドラインでgem list (gem名)を実行して各gemの正確なバージョン番号を知ることも出来る。
group指定でdevelopmentやtest環境のみに利用する(つまりproduction環境では使わない)gem設定も可能。
bundle installを実行すると「まずbundle updateを実行してください」というようなメッセージが表示される場合がある。その場合は、メッセージのとおりにbundle updateをまず実行。

###gitコマンドの流れ

1.systemセットアップ(1PC1回のみ）
`$ git config --global user.name "Your Name"`
`$ git config --global user.email your.email@example.com`

2.初期化
`$ git init`

3.ステージング
`$ git add -A`

4.コミット（メッセージ付き）
`$ git commit -m "Initialize repository"`

5.ビットバケットへの（リモート）リポジトリ追加
`$ git remote add origin git@bitbucket.org:<username>/hello_app.git`

6.プッシュ
`$ git push -u origin --all`

7.ブランチを切っての流れ
`$ git checkout -b topic-branch`
`$ <ファイルを作成したり編集したり削除したり...>`
`$ git add -A`
`$ git commit -a -m "Make major mistake"`
`$ git checkout master`
`$ git merge topic-branch`
`$ git branch -D topic-branch`
`$ git push`

###herokuについて
コミットしてherokuにリポジトリ作成してプッシュする流れ
`$ git commit -am "Add hello"`
`$ heroku create`
`$ git push heroku master`

heroku　renameコマンドで名前変更できる。

トラブル系
Cloud9でHerokuが使えなくなったりする。Qiitaで調べればたぶん解決できる。
nodeのバージョンを8.3.0以上にしなさいと言われるのでアップデートすれば良い。
今日の学習

#・学習内容
・IPアドレスの変更
・パソコンの名前変更
・OSの種類
・USB 3.0
#・IPアドレスの変更方法
まず、ネットワークのアイコンがあるかを確認しあればアイコンを右クリック
そしてプロパティを選択します。アイコンがなければデスクトップを右クリック
個人用設定→テーマ→デスクトップアイコン設定から追加ができる。
後は下記の手順通りです。

アダプターの設定の変更
![スクリーンショット (3).png](https://qiita-image-store.s3.amazonaws.com/0/249277/e9830b18-4b7e-7f34-bd1e-4664f5ab4474.png)
Wi-Fいと書いているところを右クリック→プロパティ
![スクリーンショット (4).png](https://qiita-image-store.s3.amazonaws.com/0/249277/5433ccb3-43a2-3d7a-613d-da4f32de33ec.png)
インターネットプロトコルをダブルクリック
![スクリーンショット (5).png](https://qiita-image-store.s3.amazonaws.com/0/249277/b60d0879-cff1-2ba1-b7f8-919c29efd44d.png)
後は自分が記入したいIPアドレスを入力する。最後に再起動をします。
![スクリーンショット (6).png](https://qiita-image-store.s3.amazonaws.com/0/249277/58aaabcb-8da4-bcf4-4143-b0d056224a8e.png)
#パソコン名前変更
デスクトップにあるPCアイコンを右クリック→プロパティ→設定の変更から画像の番号の順に設定していけばできます。
![スクリーンショット (8).png](https://qiita-image-store.s3.amazonaws.com/0/249277/2e69afab-bfbb-7322-1423-a8b81f4b9d75.png)

#・OSについて
・**OS**とはコンピューターを動かすためのソフトウェアです。
コンピューター全体を管理し制御し、人が使えるようにする役割をもっています。
OSにはケータイ用パソコン用があります。
ケータイでは**Googleのアンドロイド**、**アップル社のIOS**が使われています。
パソコンでは**マイクロソフト社のWindows****アップル社のMac OS**
**AT&T社のUNIX**があります。

#・USB3.0
USB3.0の転送速度はUSB2.0の10倍である5Gbps
RailsのGeocoderで複数カラムの住所から緯度経度を取得

初心者です。geocodingの記事はたくさんありました。ただ、おそらくあたりまえすぎるからだと思いますが、住所が複数カラムにわかれている場合の対応方法の記事を見つけられませんでしたので、投稿します。

以下の投稿を参考にしてgemのインストールなど進めました。
https://qiita.com/kentana20/items/de6dbaadc0a2c086a339

fruitsテーブルに、fruit_address2(都道府県)、fruit_address3(市区町村以下)カラムがあり、geocodingするため、latitude(緯度)、longitude(経度)カラムを追加しました。

```fruit.rb
# fruit_address2とfruit_address3を結合
def fruit_address
  "%s %s"%([self.fruit_address2,self.fruit_address3])
end

# fruit_addressが更新されたときにgeocoding
geocoded_by :fruit_address
after_validation :geocode
```
もっといいやり方があるかもしれませんが、こう書いたら住所更新時に緯度経度が登録されました。
IPython notebook 事始め（基本操作）

#Pythonでデータ分析したいガチ初心者です
勤務先でのデータ分析は基本的にExcelで行いますが、
Pythonで分析できるようになりたい。
その方がかっこいい気がするし、
Excelで膨大なデータを扱うこと自体に限界があるし。
そこで、個人的に勉強を始めました。

##注意
筆者の個人用PCはMacbookです。
Windowsだと操作が多少異なるかもしれません。

#起動
ターミナルに ` ipython notebook ` と打ち込みます。

```terminal
$ ipython notebook
```
![立ち上げ.png](https://qiita-image-store.s3.amazonaws.com/0/207484/a56ce0f4-795e-d0c0-09b8-eeb0af2d58fa.png)


実行すると、localhostで立ち上がりました。

<img width="1277" alt="スクリーンショット 2018-04-22 17.13.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/207484/b5efb84e-8d20-73d4-11ef-a8310ec25b6d.png">

#新規作成
右端の"New▼"ボタンを選択し、
"Python3"を選択します。

<img width="1178" alt="スクリーンショット 2018-04-22 17.15.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/207484/e00dd96c-56a2-9d38-7454-589208967094.png">


#計算させてみる
例えば、`　2+2　`　を実行します。
実行は "▶︎｜Run"ボタン　か　Ctrl+Enter　のどちらかです。

<img width="1206" alt="スクリーンショット 2018-04-22 17.20.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/207484/175ad170-7ba1-e0f0-9ba6-ea1c953309a0.png">

行を追加するときは、左端の "+" でできます。
しかし、実行しながら次の行を追加するなら　Shift+Enter　が便利です。

<img width="1171" alt="スクリーンショット 2018-04-22 17.27.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/207484/b555a5da-f6ee-eb1e-8d4e-6822e4e2488b.png">

#コメントアウト
"Code"とあるところをプルダウンすると"Markdown"があります。
それを選びます。

<img width="589" alt="スクリーンショット 2018-04-22 17.32.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/207484/09df8537-7700-863d-cab2-3c4deda1f78f.png">

マークダウン記法に乗っ取り、
半角シャープと半角スペースを頭につけます。
シャープの数でコメントの文字の大きさが勝手に変わります。
日本語でもコメントアウトできます。

```
# 大きいクマ（シャープ１つで文字の大きさ最大）
## 中くらいのクマ（シャープ２つで一回り小さい文字）
### 小さいクマ（シャープ３つでさらに小さい文字）
```

<img width="539" alt="スクリーンショット 2018-04-22 17.34.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/207484/92bb28cf-e669-5d67-0458-88d6e9798e49.png">

実行するとこのように出力され Markdown だったところが自動的に Code に戻っています。

<img width="568" alt="スクリーンショット 2018-04-22 17.34.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/207484/6a85cfe3-db46-f0f9-414b-be9fdf6982a4.png">



#ファイル名変更
ファイル名を書きましょう。
Jupytorタイトルの右に "Untitled1"とあります。

<img width="577" alt="スクリーンショット 2018-04-22 17.39.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/207484/e87fe152-65bc-b82d-276f-2eeaffa0e78d.png">

それをクリックすると、タイトルを編集できます。

<img width="1170" alt="スクリーンショット 2018-04-22 17.40.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/207484/e78b97d3-b380-3657-4735-68fa91c2ebb3.png">

ここではファイル名をとりあえず 森のクマさん にしました。

#保存
File の Save and Checkpoint を選ぶか、
左端のフロッピーディスクのアイコンをクリックします。

<img width="360" alt="スクリーンショット 2018-04-22 17.42.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/207484/b2e9e905-e1a7-96c2-25a8-443a182ed716.png">

#終了
ターミナルで Ctrl + C を実行すると、
終了していいかどうか聞かれるので5秒以内に同意しましょう。
5秒以内に答えないとこうなる。

<img width="649" alt="スクリーンショット 2018-04-22 17.44.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/207484/3358a6a5-e572-a006-46e8-d1f1400720c7.png">

それで、notebook の localhostを閉じます。
railsチュートリアル　sample_appにログインしようとすると

エラーが出る。
内容→No route matches [POST] "/signup"

解決→Why the url: signup_path? That is your error, and its not how the tutorial does it. See railstutorial.org/book/sign_up#code-signup_form But if you do want to rename it, you do need to then add another route manually (post "signup", to: "users#create") 

参考→https://stackoverflow.com/questions/45885303/rails-tutorial-ch11-no-route-matches-post-signup
M5STACK(ESP32)でiBeaconを受信してみる

# M5STACK(ESP32)でiBeaconを受信してみる

## 経緯
先日、M5STACKを購入しました。
M5StackはESP32を搭載していて、WiFiとBLEが使えるので、IoT GWとして使えるなあということで、BLEの機能を使って、iBeaconを受信することをやってみました。

## 準備（開発環境）
Arduino IDE 1.8.5
手順は、M5Stackの公式HPにあったMac OSX向けの手順で構築した環境です。
ESP32 Arduino Coreインストール手順
```
mkdir -p ~/Documents/Arduino/hardware/espressif && \
cd ~/Documents/Arduino/hardware/espressif && \
git clone https://github.com/espressif/arduino-esp32.git esp32 && \
cd esp32 && \
git submodule update --init --recursive && \
cd tools && \
python get.py
```
## コード
```c:test.ino
// M5STACK(ESP32)でiBeaconを受信してみる
// 2018/04/22 Programed by Kazuyuki Eguchi

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>

int scanTime = 10; // スキャン完了までの秒数

class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
  void onResult(BLEAdvertisedDevice advertisedDevice) {
    char uuid[60];
    BLEAddress addr = advertisedDevice.getAddress();
    int rssi = advertisedDevice.getRSSI();
    std::string data = advertisedDevice.getManufacturerData();

    if(data.length() == 25)
    {
      if((data[0] == 0x4c) && (data[1] == 0x00) && (data[2] == 0x02) && (data[3] == 0x15)) {
        sprintf(uuid,"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X"
          ,data[4],data[5],data[6],data[7],data[8],data[9],data[10],data[11],data[12],data[13]
          ,data[14],data[15],data[16],data[17],data[18],data[19]);
        int major = (int)(((data[20]&0xff) << 8) + (data[21] & 0xff));
        int minor = (int)(((data[22]&0xff) << 8) + (data[23] & 0xff));
        signed char power = (signed char)(data[24]&0xff);

        Serial.printf("addr=%s rssi=%d uuid=%s,major=%d,minor=%d,power=%d\n",addr.toString().c_str(),rssi,uuid,major,minor,power);
      }
    }
  }
};

void setup() {
  Serial.begin(115200);
}

void loop() {
  BLEDevice::init("");
  BLEScan* pBLEScan = BLEDevice::getScan();
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks(),true);   // 重複を許さない場合は、falseに変更のこと。
  pBLEScan->setActiveScan(true);
  BLEScanResults foundDevices = pBLEScan->start(scanTime);
  Serial.println("Scan done!");
}

```

## 気になること
コンパイル後のスケッチのサイズが結構大きい！

最大1310720バイトのフラッシュメモリのうち、スケッチが1227005バイト（93%）を使っています。
最大294912バイトのRAMのうち、グローバル変数が46628バイト（15%）を使っていて、ローカル変数で248284バイト使うことができます。

今後、WiFiのプログラムを追加すると、嫌な予感が！

以上、ご参考までに
AWKのrandが同じ乱数列を生成してしまう

awk(gawk)には乱数を生成する組み込み関数として`rand`が用意されているのですが、たとえば以下のようなソースコードで検証ができるように、実行のたびに同じような乱数列を生成してしまいます。

```bash
for _ in $(seq 5); do
  awk 'BEGIN{print(rand(), rand(), rand())}'
done
# 0.237788 0.291066 0.845814
# 0.237788 0.291066 0.845814
# 0.237788 0.291066 0.845814
# 0.237788 0.291066 0.845814
# 0.237788 0.291066 0.845814
```

awkの仕様なのか、gawkの実装がそうなのか、正直なところよくわからないのですが、乱数生成のシード値の初期値が一定になっているらしく、そのために実行のたびに同じような乱数列が生成されてしまうようです。したがって実行のたびに異なった乱数列を生成したいという場合は`srand`を使って、シード値を変更すればよい――と思って書いたのが以下のコードになります。

```bash
for _ in $(seq 5); do
  awk 'BEGIN{srand(); print(rand(), rand(), rand())}'
done
# 0.589234 0.904348 0.441211
# 0.589234 0.904348 0.441211
# 0.589234 0.904348 0.441211
# 0.50575 0.499608 0.730847
# 0.50575 0.499608 0.730847
```

結果から述べると、想定通りに動作しませんでした。確かに`srand`がシード値を書き換えてはくれているようですが、まだまだ同じような乱数列を生成してしまう。この原因をいろいろ調べたところ、`srand`は引数を省略したとき、実行時の時刻をシード値に設定するのですが、この「時刻」の単位が「秒」。つまり1秒以内に`srand`を呼び出すと、同じシード値が設定されてしまい、結果として同じ乱数列が生成されてしまいます。

よって`srand`の引数は省略せず、自前で用意したシード値を設定する必要がありそうです。そしてそのシード値を自前で用意する方法ですが、awkの外部で生成した乱数を利用することとします。たとえばbashの組み込み変数`RANDOM`で生成した乱数を-vオプションを使って、awk内部に引き渡し、これを`srand`の引数(=乱数のシード値)としたところ、想定通り動作しました(´・ω・｀)

```bash
for _ in $(seq 5); do
  awk -v seed="${RANDOM}" 'BEGIN{srand(seed); print(rand(), rand(), rand())}' 
done
# 0.975518 0.212486 0.0285477
# 0.838674 0.664669 0.070124
# 0.314944 0.212045 0.00891201
# 0.725379 0.64815 0.805276
# 0.109255 0.713515 0.799796
```

-vオプションの利用が難しい場合は「外部コマンドで乱数を生成、それを`getline`で拾って、シード値とする」という方法でも大丈夫そうです(´・ω・｀)

```bash
for _ in $(seq 5); do
  awk 'BEGIN{
    "seq 32767 | shuf -n 1" | getline seed
    srand(seed); 
    print(rand(), rand(), rand())
  }'
done
# 0.711337 0.206352 0.0366282
# 0.614835 0.52362 0.556768
# 0.666671 0.18371 0.66057
# 0.964642 0.860411 0.500877
# 0.95293 0.590551 0.826792
```

参考 www.kt.rim.or.jp/~kbk/gawk-30/gawk_13.html
Windows10でtelnetを使う方法

# 手順

- Windowsキーを押下して「プログラムの追加と削除」を検索
- 関連設定の「プログラムと機能」を選択
- 左側の「Windowsの機能の有効化または無効化」を選択
- 「Telnetクライアント」にチェックを入れて「OK」ボタンを押下

# 雑記

簡単な疎通確認する時にtelnetを使うことがあるんだけど、Win10だとデフォルトで入ってないのでメモとして。
numpyの配列操作備忘録

numpyの行列操作をすぐ忘れるので見返すための備忘録

### テストデータの作成
```
# 要素が0の行列 np.zeros(shape)
## 0が10個の配列
In [16]: np.zeros(10)
Out[16]: array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])

## 2行2列で要素が0の行列
In [17]: np.zeros((2,2))
Out[17]:
array([[ 0.,  0.],
       [ 0.,  0.]])

# 配列の作成 np.arange(start, stop, step)
## 0から9まで1ずつ増える配列
In [19]: np.arange(10)
Out[19]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

## 1から9まで1ずつ増える配列
In [20]: np.arange(1, 10)
Out[20]: array([1, 2, 3, 4, 5, 6, 7, 8, 9])

## 1から9まで2ずつ増える配列
In [21]: np.arange(1, 10, 2)
Out[21]: array([1, 3, 5, 7, 9])

# 配列を行列に変換 reshape(new_shape)
## 1~9の配列を3x3の行列に変換
In [23]: np.arange(1,10).reshape((3,3))
Out[23]:
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
```

### 行列から特定のデータの取得

```
# 1箇所指定して取得
## 1次元の場合 x[index]
In [26]: x = np.arange(10)

In [27]: x
Out[27]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [28]: x[3]
Out[28]: 3

In [29]: x[-1]
Out[29]: 9

## 多次元の場合 x[index1, index2, ...]
In [31]: x = np.arange(25).reshape((5,5))

In [32]: x
Out[32]:
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])

In [33]: x[1, 2]
Out[33]: 7

In [34]: x[-1, -2]
Out[34]: 23
```

```
# 範囲を指定して取得
## 1次元の場合 x[start:stop:step]
In [36]: x = np.arange(10)
In [41]: x
Out[41]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [40]: x[1:10]
Out[40]: array([1, 2, 3, 4, 5, 6, 7, 8, 9])

In [39]: x[1:10:2]
Out[39]: array([1, 3, 5, 7, 9])

## 多次元の場合 x[start1:stop1:step1, start2:stop2,step2, ...]
In [42]: x = np.arange(25).reshape((5,5))

In [43]: x
Out[43]:
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])

In [45]: x[1:-1, 1:3]
Out[45]:
array([[ 6,  7],
       [11, 12],
       [16, 17]])
```


参考：
http://wbhappy.hatenablog.jp/entry/2015/02/06/210000
https://qiita.com/supersaiakujin/items/d63c73bb7b5aac43898a
foreachで最初と最後を判別して処理する

備忘録
reset()
end()
を使用する方法もあるが下記だと、値の重複にも対応できる

```php:qiita.php
function body_import ($bodyColumn){
	$body = '';
	$length = count($bodyColumn);
	foreach($bodyColumn as $i => $value) {
		if ($i === 0) {
            //最初
			$body .= '{'.$i.':"'.$value.'",';
		}
		elseif($i === $length - 1){
            //最後
			$body .= $i.':"'.$value.'"},';
		}
		else {
			$body .= $i.':"'.$value.'",';
		}
	}
	return $body;
}
```
CloudWatch Logs からログをダウンロードするツールを作りました


## なにこれ？

AWS Lambda やアプリケーションのログ等を [CloudWatch Logs] に送信しています。安全に保管できて、他サービスにログの配信もできるので重宝しています。

ですが弱点がありまして、ログをテキスト (原文) としてダウンロードしなおすのに大変手間がかかります。

> 「CloudWatch Logs ダウンロード」等でググると、SDKを使ってスクリプトを書いている記事が沢山出てきます。私のローカルにも大量にあります。

ということで、簡単なツールを作りました。

* https://github.com/megmogmog1965/cloudwatchlogs-downloader

> ![DownloadLogs pane](https://raw.githubusercontent.com/megmogmog1965/cloudwatchlogs-downloader/feature/demo-images/_demo_images/DownloadLogs.png)

Windows, Mac 向けのインストーラを置いてあります。


## 公式 (AWS Console) の方法でダウンロードするには？

本家の方法があります。ロググループをS3にまとめてエクスポートできますね。

* [Amazon S3 へのログデータのエクスポート]

ただ、この方法は幾つか難がありまして...

* ログがほしいだけなのにいちいちエクスポートするの面倒
* S3の書き込み権限が必要 (～ReadOnlyAccess ではない)
* 直近のログ (最大12時間) のエクスポートが保証されない

> (公式より抜粋)
> ログデータは、エクスポートできるようになるまで最大 12時間かかる場合があります。

12時間以内のログも一見するとエクスポートしているように見えるのですが、実は歯抜けになっていたりします
(T_T)


[CloudWatch Logs]:https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html
[Amazon S3 へのログデータのエクスポート]:https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/S3Export.html
MacにはAltがない

Alt+F+Aで名前をつけて保存、という簡単な操作もmacOSでは出来ない。


・不馴れな状態ですべてのショートカットを覚えきる前に、
・マウス操作で画面端まで移動するなんて無駄な事は到底できない。


システム環境設定からキーボードに移動して、下記赤枠内のチェックボックスをオンにすることでようやく
解決した。

![スクリーンショット 2018-04-22 19.00.47.png](https://qiita-image-store.s3.amazonaws.com/0/252434/28a4a503-097a-a900-e843-11b0008700c9.png)
Unityでハンドスピナー回すだけのアプリを作ってみた

# Unityでハンドスピナー回すだけのアプリを作ってみた

前からAndroidを公開してみたかったのと、アプリ作りの練習になると思い作って公開した。

## 開発環境
Unity2017.1.0f3

## 公開までの一連の流れ
・Unityでプロジェクト作成、開発
・Play Consoleでアプリの作成
・UnityでPlayer Settingを設定、Key Storeを作成、ビルド
・Play Consoleでアプリのリリース管理の設定、アプリのアップロード
・Play Storeでリリース

## Unityでやること
プロジェクトを作った後、Switch PlatformでAndroidに設定。
Player Settingにリリースに変更が必要な項目を入力
####ビルド(リリース)するために変更が必要な項目
・Bundle Identifier
Play Consoleでアプリの作成で作った(com.***.com)のようなドメイン
・Key Store
・Key
#### アップデートの時に変更が必要な項目
・Version
・Bundle Version Code

Android SDKを設定。
Android SDKをダウンロードした後、ディレクトリをUnityに登録。
あとは最初のBuild時に自動でアップデート等が走る(かなり長い)。

apkファイルを実機テストして確認したらOK。

## Play Consoleでやること
左のメニューに！的なアイコンがでるのでその項目をすべて設定していく。
内部テスト版、アルファ版、ベータ版、リリースの順で公開する。(ベータ版以前はとばしても可)
リリースの管理画面でアプリをアップデートする。
設定をして公開。

## 躓いたところ
Buid and Runでアプリが実機にインストール出来なかった場合、apkを実機に送ってインストールする。
リリースの際アプリのアップデートが弾かれる場合はBundle Version Codeが全開と変わっているか確認する。

## アプリの中身
ハンドスピナーはInkscapeで描いた(SVGファイル)。
https://gist.github.com/TeraokaAkihiro/bd14e69f0a756a055a739508f7527133
Kritaで色付けして、エクスポート。
UnityでSpriteの設定でインポートして配置。
スクリプトはGithubで管理。
https://github.com/TeraokaAkihiro/HandSpinner
回転はタッチ離した時、今タッチしている場所と前の複数フレームでタッチした場所の差をGetDiff関数で計算している。

```cs
public float GetDiff(Vector2 p1, Vector2 p2)
{
  float dx1 = 0f - p1.x;
  float dy1 = 0f - p1.y;
  float dx2 = 0f - p2.x;
  float dy2 = 0f - p2.y;
  float rad1 = Mathf.Atan2(dy1, dx1);
  float rad2 = Mathf.Atan2(dy2, dx2);
  float diff = rad1 * Mathf.Rad2Deg - rad2 * Mathf.Rad2Deg;
  return diff;
}
```
回転数のカウントは360度を3つのエリアに分割して判定している。

```cs
float angleZ = _transform.eulerAngles.z;
if(angleZ < 120f)
{
  rotationPart = 1;
}
else if(angleZ < 240f)
{
  rotationPart = 2;
}
else
{
  rotationPart = 3;
}
```

前のフレームから+1か-2、-1か+2で正転逆転を判定している。

Tweet機能も付けてみた。(参考→[【Android】UnityでTwitter投稿する \- スマゲ](http://smartgames.hatenablog.com/entry/2016/03/13/185224))

```cs
Application.OpenURL("http://twitter.com/intent/tweet?text=" + WWW.EscapeURL(text));
```

Button押したら走るようにするだけなのでかなり楽

戻るボタン押したら終了([UnityでのAndroidバックボタン対応 \- Qiita](https://qiita.com/WassyPG/items/12030494688cba02ce1b))

```cs
if (Input.GetKeyDown(KeyCode.Escape))
{
  Application.Quit();
}
```

消す前の確認があるならばダイアログ出すのも良いかもしれない。


## 残っている問題

・ハンドスピナーから離したときのスピードが安定しない
・回転数は保存されず終了したら0になる
・AdMobで広告を表示しようと思ったができなかった

## 感想

AndroidアプリのリリースはUIがしっかりしてて、法律まわりはすこし難しかったが、あまり調べること無く設定出来た。
Unityはググればコピペで済むことが多く楽だった。
回転数に関しては全く出てこなかったので自分で考えるしかなかったがパッと思いついてよかった。

AndroidアプリをリリースするならUnityがあるのでかなり簡単で時間もかからないので試してみては。
MacBookAirでCordovaを使った Androidアプリ開発

先日の記事の続きのような感じになっています。
実は、初期のままでのビルドが出来なくて、試行錯誤を続けていました。
Cordovaのplatformのversionをアップグレードすることで、解決できること知りました。

参考にした記事は、こちらです。

https://qiita.com/bathtimefish/items/7304f11ba4bbb36fd02d

https://forum.ionicframework.com/t/ionic-build-android-error-spawn-eacces/88358/10

http://aircolor.hatenablog.com/entry/2018/01/22/170237

無事にビルド出来ました。
そして、ブラウザで表示を確認する方法を知りました。
http://apoc.jp/cordova-hybridapp-development-setup/

ただ、AVDマネージャーを起動する方法を迷い、色々と調べていました。
この記事を読んで、ターミナルからコマンドで起動できました。
http://yuzu441.hateblo.jp/entry/2014/12/26/114321

でも、PATHを設定しても、コマンドで起動することができず悩んでいます。
Androidというコマンド自体を起動できないのです。
そのため、Android studio起動画面で、プロジェクトを読み込んでデバッグする項目を選択して、ビルドできたapkファイルを読み込み、AVDマネージャーを立ち上げました。

![スクリーンショット 2018-04-22 18.32.19.png](https://qiita-image-store.s3.amazonaws.com/0/20977/eba6283c-2222-f28c-fe12-de42e312fe0d.png)


AndroidStudioをインストールするときに、Intel x86 Emulator Accelerator（HAXM Installer）のインストールも行いました。

でも、下記の記事を読んだら、インストールのファイルがインストールされただけで、実際には、フォルダまで行ってインストーラーを使ってインストールしないといけない事を知りました。

実は、Intel x86 Emulator Accelerator（HAXM Installer）をインストールしているときに、Macのセキュリティの表示が出たので許可を選択したのですが、許可のボタンをクリックしても許可されないので、困っていました。
そのこともあり、調べていました。

https://software.intel.com/en-us/articles/intel-hardware-accelerated-execution-manager-intel-haxm
![スクリーンショット 2018-04-22 17.30.46.png](https://qiita-image-store.s3.amazonaws.com/0/20977/ac8588fb-eb38-aa51-e67a-fc4ea8dbd372.png)
画像で示しているIntelHAXM_6.2.1.dmgを起動して、インストールしました。

フォルダの場所は、先にご紹介した記事を読んで、確認してください。
<sdk install location> / extras / intel / Hardware_Accelerated_Execution_Manager /
の順番でたどると、見つかると思います。

この記事を書きながら、エミュレーターの起動を確認できました。
![IMG_20180422_182959_286.jpg](https://qiita-image-store.s3.amazonaws.com/0/20977/99224971-853b-c7a5-12aa-20f0520a9eb6.jpeg)

##開発環境を作る時の肝
私は、ターミナルに慣れていなかったので、ネットで知った記事のターミナルのコマンドをそのままコピペして、インストールしていました。
そのため、Userの下のフォルダや、内蔵SSDが、ファイルやフォルダで、散らかってしまっていました。
今回、Cordovaでプロジェクトを作り、プラットフォームのバージョンを上げるなどディレクトリの操作を行う中で悟ったことがあります。
それは、何かをインストールするときは、先にフォルダを作る。
次に、そのフォルダに移動します。
```
$ cd /User/xxx
```

と行った感じで移動してから、インストールすると良いと思います。
あとからインストールした事を忘れてしまった場合でも、分かりやすいと思います。

##後書き
今回MacでCordovaの開発環境ができたので、タブレットPCで苦労して作らなくても良くなりました。
IDEは。visualstudioのMac版が入っていますが、別の物を使うかも知れません。

visualstudioのMac版は、Xamarinの環境になっています。
これにCordovaを追加できたらよかったのですが。
でも、ターミナルを使う事でビルドもデバッグもできる事を確認したので、頑張ってアプリを作っていきたいと思っています。
Xcodeをアンインストールしてしまっているので、iOSのアプリを作ることができません。
Monacaを使ったり、何か方法を模索していきたいと思います。

今のMacBookAirは、キーボード壊れているので、BluetoothまたはUSBのキーボードを使っています。
そのため、内蔵SSDが５００GB位あるノートパソコン買って、Xcodeも合わせてインストールして環境を作ることができたらと思っています。

２０１８/04/23加筆修正
ターミナルを閉じてターミナルを再起動したら、PATHの反映されて無事に使えるようになりました。
続きの記事を新しく書きました。
Androidでプッシュ通知したいときにFCM（Firebase Cloud Messaging)を使う手順

## あらまし
- FCMとAndroidでプッシュ通知やろうとして戸惑った話（よく考えるとQiitaに全部書いてある）
- AndroidプロジェクトでWear OSを含むプロジェクトを作成するとwearとmobileが作成される
- 設定がぱっと見勘違いしたり、デバッグ用署名証明書の出し方でちょっと戸惑ったりしたので簡単な手順を書いておく

## 作成したもの
- Android側アプリ - [GitHub ddfe503](https://github.com/keix1/InfoExplosion/tree/ddfe503331e25a8fe339288776028be15fb44a86)
- PC側Python - [GitHub c2365d7](https://github.com/keix1/FCM-Python/tree/c2365d72e9cec67614d3192806313bf4cc4442f3)

## 参考になった参考URL
1. [AndroidのPush通知(FCM)をサーバー知識無しで試してみよう](https://qiita.com/flatfisher/items/bdec83caf3c7f9c8917c)
2. [【Android】30分で実装するPush通知【Firebase】](https://qiita.com/SnowMonkey/items/7f08eb0275f2420c29eb#notifications%E5%B0%8E%E5%85%A5)
- [【Android】既存アプリにFirebaseを入れるときにハマった話](https://qiita.com/SnowMonkey/items/5b9019a936aa6762cf53)
- [firebaseのNotificationでプッシュ通知をやってみる](http://tks-lab.hatenablog.com/entry/2017/02/22/154652)

## 手順
### 1. [参考URL１](https://qiita.com/flatfisher/items/bdec83caf3c7f9c8917c)で[Firebase](https://firebase.google.com/?authuser=0)でプロジェクト作成しておく
   - プロジェクト作成中にデバッグ用署名証明書SHA-1を求められる
       - MacOSの場合は以下のコマンドで
       - ```keytool -v -list -alias androiddebugkey -keystore ~/.android/debug.keystore```
       - 要注意：パスワードを要求されるが、おそらく何もないのがデフォルトのため、そのままEnter
   - プロジェクト作成中にbuild.configの編集が紹介されるがとりあえずスルー 

### 2. Android Studio上で環境セットアップ
- 　Android StudioのTools>Firebase>Cloud Messaging>Set up~を選択
- 　①Connect to Firebaseする
- 　②Add FCM to your appする

### 3. app（mobileやwear）のbuild.gradleを編集する
- そのままだとうまくいかなかったため編集

``` mobileのbuild.gradle
dependencies {
    // もともとある以下のようなplay-serviceは削除
    // implementation 'com.google.android.gms:play-services-wearable:+'

    // 必要なものを追記
    implementation 'com.google.firebase:firebase-messaging:11.8.0'
    implementation 'com.google.firebase:firebase-core:11.8.0'
    
    //必要なものを追記
    implementation 'com.google.android.gms:play-services-base:11.8.0'
    implementation 'com.google.android.gms:play-services-gcm:11.8.0'
}
```

``` wearのbuild.gradle
dependencies {
    // もともとある以下のようなplay-serviceは削除
    // implementation 'com.google.android.gms:play-services-wearable:15.0.0'

    //必要なものを追記
    implementation 'com.google.android.gms:play-services-base:11.8.0'
    implementation 'com.google.android.gms:play-services-gcm:11.8.0'

    //必要なものを追記
    implementation 'com.google.firebase:firebase-messaging:11.8.0'
    implementation 'com.google.firebase:firebase-core:11.8.0'

}
```

### 4. とりあえず通知を送ってみる
- サービスが必要なのかと思い込んでいたが、通知を送るだけなら必要ない
- アプリをインストールしバッググラウンド状態にする
- [参考URL２](https://qiita.com/SnowMonkey/items/7f08eb0275f2420c29eb#notifications%E5%B0%8E%E5%85%A5)の雰囲気で通知送る
- バッググラウンドで通知送るだけならManifestの編集とかもいらない
- 冒頭に挙げたPythonスクリプトでも送れる

## 参考
- KotlinでAndroidのFirebaseトークン確認
    - onCreateにでも貼ってください

```kotlin

val CurrentToken = FirebaseInstanceId.getInstance().token
Log.d(TAG, CurrentToken)

```
CentOS7 minimalをinstallしたあと最低限使える様にする

# はじめに
いつも使っているCentOS7の中身がグチャグチャになってきたので再インストールしたのがきっかけ。
再インストールしたは良いものの、そのまんまだと色々問題があったので最低限使えるようした。
思ったよりCentOS7のminimalは何も入っていなかった。

# 環境
ホスト：Windows10 バージョン1607（OSビルド 14393.1198）
仮想化ソフト：VMware(R) Workstation 12 Player 12.5.6 build-5528349
仮想OS：CentOS-7-x86_64-Minimal-1708

# 設定すること
インストールは各自して下さい、インストール自体は他の記事を見て下さい。
基本的に`root`で動くことが前提です。
あと設定したにもかかわらず動かない場合はまず再起動してみて下さい。
コマンドの最初に`$`とか`#`がないのは付いているとコピーしにくいからです。

## networkに繋げる
インストール時にnetworkの設定をしていない場合に発生する問題です。
まずnetworkのserviceを停止させ、設定ファイルを編集します。

``` bash
/etc/rc.d/init.d/network stop
vi /etc/sysconfig/network-scripts/ifcfg-ens33
```

ONBOOTをyesにします、BOOTPROTがdhcpになっていなければdhcpにします。

``` bash
ONBOOT=yes
BOOTPROTO=dhcp
```

設定を編集したらnetowrkのserviceを開始します。

``` bash
/etc/rc.d/init.d/network start
```

### アップデート
一様ネットにつながるようになったらアップデートをしておきましょう。

``` bash
yum update -y; yum upgrade -y
```

## sudoを有効にする
インストール時に作成したuserの`sudo`が有効になっていないので有効にします。
`visudo`と打って`sudo`の権限を編集します。

``` bash
visudo
```

92行目辺りにあるroot ALL=(ALL) ALLを下の行に複製し、rootの所を自分のuser名に書き換えます。
これでインストール時に作成したuserが`sudo`を使えるようになります。

``` bash
root		ALL=(ALL)       ALL
(user名)	 ALL=(ALL)       ALL
```

## gccをインストール
minimalには最初から`gcc`が入っていないのでインストールします。
gccを使わないという方はしなくても良いですけれど、`wget`くらいは入れとくと良いです。

まず`wget`と`Development Tools`を入れます。
`Development Tools`だけでも`gcc`は使えるのですが、どうせなら最新版にしようということで`gcc 7.3.0`にします。

``` bash
yum install -y wget
yum group install -y "Development Tools"
```

`gcc 7.3.0`のソースコードを入手してビルドします。
`make`に時間が掛かるので注意です、終わった後に再起動して下さい。

``` bash
cd /usr/local/src
wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-7.3.0/gcc-7.3.0.tar.gz
tar zxvf gcc-7.3.0.tar.gz
cd gcc-7.3.0
./contrib/download_prerequisites
mkdir build
cd build
../configure --enable-languages=c,c++ --prefix=/usr/local --disable-bootstrap --disable-multilib
make
make install
shutdown -r now
```

## その他
他に自分は、`vim`と`git`をインストールして`.bashrc`や`vimrc`の設定とかをしています。
`docker`のインストールは[CentOS7にDockerをインストールする](https://qiita.com/inakadegaebal/items/be9fecce813cebec5986)の記事を見てインストールしました。

# 参考資料
[CentOSインストール後の設定メモ(minimal)](http://futurismo.biz/archives/1340/)
[CentOSでsudoコマンドが使えない場合の対処法](https://qiita.com/lrf141/items/86f2c48b193eac2feb7f)
[CentOS 7 gcc 7.2.0のソースファイルからのインストール](https://qiita.com/knutpb1205/items/2506f3a70f0a607aba81)
[CentOS7.2编译GCC7.3](https://www.cnblogs.com/nidey/p/8365250.html)
ubuntu16.04LTSにssh接続する際に必要な手順【超初心者向け】

#ubuntu16.04LTSにssh接続する際に必要な手順【超初心者向け】

初歩の初歩だが一連の流れを説明している記事がなかったので自分のリマインド用も兼ねて作成

基本的にLinuxディストリビューションであれば以下の手順でssh接続できるようになる　

- 22番ポートの開放
    - 22番ポートはssh接続用のポートなので
- openssh-serverの導入
- ipアドレスの固定
    - ipアドレスはマシンの再起動なので変わることがあるため

以上の手順で行われる

#具体的な手順
ubuntuの場合は具体的には以下のコマンドでできる
###1.ポート開放
```
$sudo ufw allow 22
$sudo ufw reload
```
もしファイアーウォールが起動してないと言われたら以下を実行

```
$sudo ufw enable
```

###2.openssh-server

```
$sudo apt-get install openssh-server
```
これでopensshがインストールできた

###3.ipアドレスの固定
ここまでの手順だけでもssh接続はできるがipが固定されてないため
ipが変わるたびそのアドレスを調べ直さないといけない
そのため、ipの固定を行う


- 現在のip確認

```
$ifconfig
```
これで現在のローカルipがわかる
loではなくensやらenpと書いてる方のinet addrとMaskの値をメモ


- ゲートウェイの確認

```
$route -n
```

Destination Gateway
0.0.0.0 192.168.x.x
こんな感じに出力されたら**192.168.x.x**の方がゲートウェイのアドレス
これもメモ


- DNSネームサーバーの確認

```
$cat /etc/resolv.conf
```
ネームサーバーをメモ（複数あれば２つともメモ）

---
これで必要な材料は揃ったので設定ファイル弄る

```
$sudo vi /etc/network/interfaces
```
*viやvimに慣れてない人はnanoがオススメ*

```bash:interfaces
# This file describes the network interfaces available on your system
# and how to activate then, For more information, see interfaces(5)

source /etc/network/interfaces.d/*

#The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto ens0
iface ens0 inet dhcp
```

このファイルを以下のように書き換える（ここでメモした値が必要）

```bash:interfaces
# This file describes the network interfaces available on your system
# and how to activate then, For more information, see interfaces(5)

source /etc/network/interfaces.d/*

#The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto ens0
iface ens0 inet static
        address [固定時に使いたいアドレス]
        netmask [Mask]
        gateway [ゲートウェイ]
        dns-nameservers [ネームサーバー]
```

*ちなみにネームサーバーが２つある場合は以下のように*
`dns-nameservers [ネームサーバー1] [ネームサーバー2]`

以下コマンドで設定を反映

```
$sudo ip addr flush dev [ifconfigで確認したネットワーク名,以下ens]
$sudo systemctl restart networking
$sudo kill `cat /run/dhclient.ens.pid`
$sudo rm /run/dhclient.ens.pid
```

一応サーバーを再起動

```
$sudo reboot
```

サーバーでifconfigでip確認して固定できていることを確認したら
お使いのsshクライアントでそのipにアクセス

接続できたら完了!

##参考
https://jyn.jp/ubuntu-localip-static/
Quo Vadis, Action Recognition? A New Model and the Kinetics Datasetを読んだ

# 1.どんなもの？
UCF101やHMDB51動画データセットではデータ数が少ないので,優れたビデオアーキテクチャを特定するのは困難
データ数が多いKinetics動画データセットで最先端のアーキテクチャを再評価(KineticsでpretrainingしてUCF101やHMDB51の精度をみる)
再評価したアーキテクチャと提案手法であるTwo-Stream Inflated 3DConvNetとの比較検証

# 2.先行研究と比べてどこがすごいの？
Inception、VGG-16、ResNetのような画像分類ネットワークを時空間特徴抽出器に膨らませたこと．
以前の3DConvNetはパラメータの高次元化とラベル付きビデオデータの欠如のために、最大でも8層だった．

# 3.技術や手法のキモはどこにあるか？
#2DConvNetを3Dに拡張させる
2Dアーキテクチャの畳み込みとプーリングのカーネルサイズを時間方向も考慮．NxNのカーネルはNxNxNになる．
# 2DConvNetで学習したフィルタの重みを3DConvNetに拡張させる
画像を複数コピーして静止画のような動画を作る
動画上のpoolingの活性化関数は、元の単一画像入力と同じでなければならない．
2Dの重みを時間次元に沿ってN回繰り返し、Nで割ることによって達成できる．

# Inception-v1ベースの3DCNN
依然としてtwo-streamの手法は有効であるため，この論文に従った方法 https://arxiv.org/pdf/1604.06573.pdf でInception-v1を適用して実験を行った

![スクリーンショット 2018-04-22 18.30.01.png](https://qiita-image-store.s3.amazonaws.com/0/249838/709e2a34-1954-05e5-db82-4fe72aeaac95.png)

# 4.どうやって有効だと検証した？
(a)~(d)と提案手法の(e)を比較
3D-ConvNetを除き，基本ネットワークとしてImageNet pretrained-v1を使用
![スクリーンショット 2018-04-22 18.30.13.png](https://qiita-image-store.s3.amazonaws.com/0/249838/26847872-d7a2-2835-0e0d-4ce2afb83808.png)
![スクリーンショット 2018-04-22 18.39.12.png](https://qiita-image-store.s3.amazonaws.com/0/249838/5af224e5-9e3c-36dc-d930-c5aa6ea9cd07.png)
http://openaccess.thecvf.com/content_cvpr_2017/papers/Carreira_Quo_Vadis_Action_CVPR_2017_paper.pdf
# 5.議論はあるか？
# ６.次に読むべき論文はあるか？

Learning Spatio-Temporal Features with 3D Residual Networks for Action Recognition (https://arxiv.org/pdf/1708.07632.pdf)
TouchDesignerでModbusを飛ばしてAZD-KDを制御する

[前回](https://qiita.com/ToyoshiMorioka/items/8a8453312839342c1b64)、[前々回](https://qiita.com/ToyoshiMorioka/items/8f92121f6bf6b9b6d9a0)をPythonでModbusの理解と共にPythonでのModbusの実装を検証してきました。
ここからTouchDesignerでAZD-KDをModbusを使って操作します。
制作したサンプルは[こちら](https://github.com/ToyoshiMorioka/PyModbusOnTD)。
Pythonで検討した結果、『ダイレクト運転以外TouchDesignerでは必要ないのでは・・・』という感じだったのでダイレクト運転のみ実装しています。
あとASCIIモード、絶対座標以外の動作は保確認ていません(前回のPythonのほうでサポートしたコードを書いた気がするが・・・)。

# PythonとTouchDesigner上のPythonを揃える
TouchDesignerを使っててかつTouchDesigner上のPythonを使ってる人は既に設定済かと思いますが、pipなどでインストールしたライブラリを使うためにはTouchDesigner標準のPythonではなく、普段自分の使うPythonへのリンクを貼っておく必要があります。
設定方法などは[ここ](https://qiita.com/oishihiroaki/items/e11dfa90638a13e2a5f5)などで紹介されているのでチェックしましょう。

# オリジナルのコンテナを組む
大きく2つのコンテナを作りました。1つは通信自体を管理するコンテナ『ModbusSerial』、もうひとつはモータのパラメータを管理するコンテナ『AZDKDParameter』です。
『ModbusSerial』ですが、シリアル通信だけはTouchDesigner純正の物を使うという手もあるですが、受信側はまだしも送信側は全然未整備な感じだったでPyModbusのModbusSerialClientをそのまま利用することにしました。
実装上のポイントはScript DATにPyModbus周りの実装を集中させ、他のパッチからのメッセージ(ConnectとかDisconeectとかSend Messageとか)はGUI経由で指令するようにしているところでしょうか。
普段慣れ親しんでるTouchDesignerのパッチングからすると右から左に何も繋がってなくて異様ですが・・・。

# パッチを組む
あとは普通にパッチを組んで行きます。
一点、modobusの通信速度があまり早くない(60fpsを切る)ことが懸念されたため、send commandoのトリガを作り、それをPulseのLFOで定期的に叩くことでコマンドを送信するようにしてコマンドを送りすぎないように設計しました。
これでもあんまり早くないのでちゃんと使うときはthread分けたほうが良いように思います。

# 完成
TouchDesignerのスライダに合わせてステッピングモータがぐりぐり動くようになりました。
エラーリセット系とか全然実装できてませんが、まぁMexe02と組み合わせればとりあえず動かせるのではないでしょうか。
備忘録

※ほぼメモ帳にする予定
# 【前置き】
pythonエンジニア認定試験受けに行こうと思ったら予約が間に合わなかった私ですどうも。

web系に転向する為にサーバー向け言語をやっていて、アウトプット的なものがぼやっとしていたのでとりあえず資格取得しに行くかという流れ。
直近でpythonとRubySilverは取りに行こうかなぁと、共に資格の勉強という方向でやってないのでもしかしたら資格向け勉強必要になるかも。

# 【自分の為のメモ書き】
pythonチュートリアル
https://docs.python.jp/3/tutorial/index.html
模擬試験
https://diver.diveintocode.jp/exam#exam-list

Ruby
模擬試験
https://diver.diveintocode.jp/exam#exam-list
ミニツク
http://www.minituku.net/
公式模擬問題
https://gist.github.com/sean2121/945035ef2341f0c39bf40762cd8531e0
Ruby公式資格教科書 Ruby技術者認定試験Silver/Gold対応
Rubyの方はRuby経験者でも覚えゲーになってる部分があり結構厳しそう。
サンプル問題の量を増やしてシューティングするのが一番だと思った。

簡易メモ
Map=collect←ブロックを繰り返し新しい配列を返す
find=detect←detectは要素に対してブロックを評価した値が真になった最初の要素を返す
find_all=select←ブロックを繰り返し真になった値の配列を返す
clear←空の配列、ハッシュを返す
chomp⇒文字列末尾の改行文字を削除する（\r \r\n \n）空文字指定した場合全ての改行コードを削除する
chop⇒文字列末尾文字を削除するメソッド
☆IO⇒rewind、seek、gets、read、readline
配列の演算
& ⇒ 両方含まれる
| ⇒ 一つでも含まれているもの
- ⇒ 左を右で引いたもの
+ ⇒ 自身同士を足す
<< ⇒ 配列を追加する
deleteは引数の各文字を削除して行く為ご注意
p cc.has_key?('nz')
p cc.key?('nz')
p cc.include?('nz')
p cc.member?('nz')
gets=readlineは1行読み込んで文字列を返す。getsはnil、readlineはEOF
"r" 読み込みモード
"w" 書き込みモード。ファイルが存在していればファイルを空にする。
"a" 書き込みモード。ファイルが存在していれば、ファイルの末尾から追記する。
"r+" 読み書き両用モード。ファイルの先頭から読み書きを行う。
"w+" 読み書き両用モード。ファイルが存在していればファイルを空にする。
"a+" 読み書き両用モード。ファイルの末尾から読み書きを行う。
split＋joinは実務的にもよく使いそう
?がついてるメソッドはtrueかfalseを返す。equal?の場合同じ参照かを判定する為注意が必要
inject⇒前ブロックの戻り値を渡す
atime(access time: 最終アクセス時間)はファイルを読み込んだ時に設定されます。
ctime(change time: 最終変更時間)はファイルのメタデータを変更した時、例えばアクセス許可、著作者、ファイル名を変更する時に設定されます。ctimeはファイルの内容を変更された時、mtimeと同じようにさらに変更されます。
mtime(modification time: 最終更新時間)はファイルに含むデータが変更された時に設定され、つまりデータの期間を表します。
IO#readlineメソッド, IO#readlinesメソッド, IO#getメソッドはすべて任意の引数の行区切り文字を受け取ります。
IO#write（1行）、puts（改行追加）、print（ほぼ一行）の違いについて
Filesplitはディレクトリ部分とファイル部分に分割し、末尾からスラッシュを取り除く
odd（奇数）even（偶数）

rails
http://cbt.odyssey-com.co.jp/railscp.html#rails4_2
https://diver.diveintocode.jp/exam#exam-list
http://jibun.atmarkit.co.jp/scenter/ittrain/
https://railstutorial.jp/?version=4.0

少し調べた感じ
rails 3 ブロンズ　難易度中
　rails 4 ブロンズ　難易度低
　rails 4 シルバー　難易度中
初期ブロンズしかなかったものをマイルドにして内容をシルバーに移植した感じ？
公式HPの出題範囲を見る限りそんな感じ

# 【今後の検討事項】
インフラ向けと言う事でAWS、と見せかけてメインがwindows環境でしかやったことなかったのでLPICを取得します。幸いゴールデンウィークなので捗りそう。触った事はあるのでそこまで苦戦しないと思いたい。
PHP5の取得。言語が違うだけで取得は簡単だろうという魂胆。WEB系やってる以上、書く事はなくとも読む事はあるだろうと。
他多数（状況に応じて優先順位つけて対応）

メモ
html5
rails
aws
lpic

# 【後書き】
今月は比較的余裕があったので転職活動＋勉強が捗りましたが忙しくなる可能性もありますからね・・・時間を無駄にしないようにしていきたいなと。現職だと何かと雑務で成長も出来ないので早めに移動したい・・・