OmniAICreator/Qiita-1.07M huggingface dataset:
Package > get_syougayaki_tare() > パッケージの購入と自作の検討

### 仕様

- return (おいしい)生姜焼きのたれ

## 実装検討

- 1. 市販品のパッケージ(生姜焼き用たれ）を購入する
    - 保守
        - パッケージをソース(sauce)管理する場所
    - 再利用性 (なし)
        - 生姜焼きのみ (特殊な使い方を除く)
    - テスト
        - 総合テスト実施済
    - 注意点
        - 同じ結果が出る製品を将来いつまで入手可能かは不明
- 2. 市販品の関数(おろし生姜チューブ)を購入する
    - 保守
        - 関数をソース(source)管理する場所
            - パッケージよりは負荷(体積)は小さい
    - 再利用性 (あり)
        - 生姜焼き
        - きのこの生姜煮
        - あさりとしょうがの佃煮
        - etc
    - テスト
        - 単体テスト実施済
        - 総合テストの成否は別要因が混入する
            - member変数: しょうゆ、みりん、酒
    - 注意点
        - 同じ結果が出る製品を将来いつまで入手可能かは不明
- 3. 外部から購入せずに、作る
    - 保守
        - なし (使いきる)
            - 材料の生姜の保守は検討していない
    - 再利用性 (なし)
        - 生姜焼き
    - テスト
        - 単体テスト未実施
        - 総合テスト未実施
    - 利点
        - 保守コストは不要
        - 技術力の向上
        - 要素技術は別用途にも使える
        - 一旦技術を獲得すれば、将来長期間使用し続けることが可能
            - OS環境の変更にも対応可能
    - 注意点
        - 自作時間がかかる
        - テストされていない
        - 技術を獲得するまでシステムは不安定になる可能性はある
        - 生姜おろし準備のための作業も別途必要

### 購入か自作か

Which path will you choose?

「目的は何か」を考慮して、その目的にそった選択肢を選ぶと良いと思う。

購入することにより、リソースを別用途に投入したいのであれば、その選択も正しい。
自作することにより要素技術を獲得し、それが将来別の案件で役立つのであれば、その選択も正しい。
Raspberry Pi Zero OGTモードでのUSB操作

先日購入したRaspberry Pi Zero WHにUSBハブを接続した際、
認識してくれなかったので色々調べてみました。

## 認識しなかった原因
購入したUSBハブが「OGT(ホスト機能)」対応端末以外使用できないデバイスだった

## 解決方法
Raspberry Pi をOGTモードで動作するようにする

## 使用したUSBハブ
秋葉原で購入
![media-20180211.jpg](https://qiita-image-store.s3.amazonaws.com/0/199056/b0296b5f-cd2d-a690-9965-4354a920c95e.jpeg)

## 設定方法

1. Rasbianを入れたSDカードをPCに接続する
2. マウントしたSDの「boot」配下の2ファイルを修正

## cmdline.txtの修正
`boot\cmdline.txt`に以下の赤文字部分の設定を追記
※1行に沢山書かれています。長いので対象部分まで省略

rootwait <font color="Red">modules-load=dwc2,g_ether</font> quiet splash plymouth.ignore-serial-consoles

「rootwait」と「quiet」の間に追記します。

## config.txtの修正
`boot\config.txt`の最下部に以下設定を追記します。

<font color="red">dtoverlay=dwc2</font>

## 接続確認
上記の設定が終わりましたら、Raspberry Piにmicro SDを挿入し、USBハブを接続してマウスやキーボード操作が行えるかチェックします。

以上で終了です。
USB Type B しか使えないのでハブが必要なのがちょっと使いづらいですよね・・・
それを言ったらMacのType Cも同じか。。。

## 参考サイト
https://www.raspberrypi.org/blog/programming-pi-zero-usb/
css の before after が表示されないとき


## 対象

css (sass) 普段あんまり書かない人


## 問題

css の疑似要素の before や after を使おうとしたけど表示されない

## 原因


```css
.section:before {
  content: '';
}
```

のように `content` を入れなきゃだめ (height や width を指定してても)


また [free-style](https://github.com/blakeembrey/free-style) などで js の中に書く場合は

```js
{
  content: `''`;
}
```
のようにシングルクォテーションの周りをダブルクォートや バッククォートで囲まないとなので注意する
Google Chart API を使用したQRコード生成

## そもそも Google Chart は何者なのだろうか？

　簡単にまとめれば、無料で使えるグラフィックツール。

　棒グラフ、折れ線グラフなどの基本的なグラフに加えて、地理グラフのようなリッチなコンテンツも提供されており、パラメータを指定するだけで簡単に作成できる。

　詳しくは下記公式サイト参照
─[公式サイト](https://developers.google.com/chart/)

##Google Chart API の Image APIを使用してQRコードを生成する

　現在非推奨のため、サービスが停止される可能性もあり、そのあたりは注意。

**基本のフレーム**

     http://chart.apis.google.com/chart?

　上記Root URIにパラメータを指定していく

**セットするもの**

| パラメータ  　　　　　　| 必須/オプション 　　　　　　　　|   　内容　 |
|:-----------------|------------------:|:----------------------------:|
| cht             |           必須| Chart Typeを指定する。QRコードの場合はcht=qrと指定。|
| chs          |            必須|       Chart Sizeを指定する。幅x高さ。       |
| chl             |              必須 |        エンコードするデータを指定する。        |
| choe               |            オプション |   Chart Output Encodingを指定する。日本語対応の場合はShift_JISを指定。         |
| chld           |             オプション |       エラー訂正のレベルを指定。       |

[公式リファレンス](https://developers.google.com/chart/infographics/docs/qr_codes)

**試しにQiitaに飛ばすQRコードを生成してみる**

https://chart.apis.google.com/chart?cht=qr&chs=300x300&choe=Shift_JIS&chl=https://qiita.com

**プログラム内での動的な生成**

chl=　に値を渡すように組めばできる

**jQueryによるサンプルコード**

```html:qiita.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>QRコード生成</title>
    </head>
    <body>
        <h1>QRコード生成</h1>
        <p>
            <!-- データ入力 -->
            <input type="text" id="msg">

            <!-- エンコード処理イベントボタン -->
            <input type="button" id="button" value="変換">
        </p>
        <div id="barCode"></div>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
        </script>
        <script>
           $(function(){
            // 変換ボタン押下時の処理
            $('#button').click(function(){
                // データ取得　日本語対応のためencodeURIComponentで処理
                var msg = encodeURIComponent($('#msg').val());
                // QRコードを置くためのimgタグ生成
                var img = $('<img>').attr('src','https://chart.apis.google.com/chart?cht=qr&chs=150x150&choe=Shift_JIS&chl='+msg);
                // 生成したimgタグの挿入
                $('#barCode').html(img);
             });
           });
        </script>
    </body>
</html>
```
【VBA】シート名の自動生成関数


#説明
1. ブック名とシート名を引数に与える。
2. 指定したブックに同じ名前のシートが存在した場合には，メッセージボックスで上書きするかを確認。
    * 「はい」の場合 → 同名のシートを消去してそのシート名を返す。
    * 「いいえ」の場合 → シート名の後ろに(1)からの引数を加え，名前被りがないかチェック。自動で名前被りのない引数に調整しそのシート名を返す。

#例
ブック「book1.xlsx」にシート「sheet1」と「sheet1(1)」が存在するとき，引数にブック名「book1.xlsx」，シート名「sheet1」を渡した場合。

メッセージボックスの上書き確認
    1. 「はい」を選択 → シート名「sheet1」が返される。
    2. 「いいえ」を選択 → シート名「sheet1(2)」が返される。

#コード
```vb
Function CheckName(BookName, SheetName) As String
    '宣言
    Dim ws As Worksheet
    Dim flag As Boolean: flag = False
    Dim flag2 As Boolean: flag2 = True
    Dim btn As Long
    Dim tmpName As String
    
    '同じ名前のシートがないかチェック
    For Each ws In Workbooks(BookName).Worksheets
        If ws.name = SheetName Then flag = True
    Next ws
    '同じ名前のシートが存在した場合
    If flag = True Then
        btn = MsgBox("既に出力シートが存在します。上書きしますか？" & vbCr & _
                        "(「いいえ」を選択した場合は別名のシートに出力します)", vbYesNo + vbQuestion)
        '「はい」を選択
        If btn = vbYes Then
            Application.DisplayAlerts = False
            Workbooks(BookName).Worksheets(SheetName).Delete
            Application.DisplayAlerts = True
        '「いいえ」を選択
        Else
            Dim i As Long: i = 1
            Do While flag2 = True
                flag2 = False
                tmpName = SheetName & "(" & i & ")"
                For Each ws In Worksheets
                    If ws.name = tmpName Then flag2 = True
                Next ws
                i = i + 1
            Loop
            SheetName = tmpName
        End If
    End If
    'シート名を返す
    CheckName = SheetName
End Function
```
APIKitでplistファイルを読み込む


APIKitでplistの読み込みをする必要があったので、以下のような対応をしました。

## DataParserを定義
APIKitはデフォルトでJSONを扱うようになっていると思いますが、DataParserをオーバーライドできるので、どのようなデータ形式も読み込めると思います。
plistはiOSにPropertyListSerializationというクラスがあるので、これで一発でいけます。



```swift
final class PlistDataParser: DataParser {
    var contentType: String? {
        return "application/x-plist"
    }

    func parse(data: Data) throws -> Any {
        do {
            let options: PropertyListSerialization.ReadOptions = []
            let plist = try PropertyListSerialization.propertyList(from: data, options: options, format: nil)
            return plist
        } catch {
            debugPrint("error")
            return []
        }
        
    }
}
```

データのデコード部分はHimotokiを利用していましたが、plistのパースのやり方がわからなかったので、そこは自力でパースさせました。

個人的にplistは巨大なデータのパース速度がJSONに比べて早いのでたまに利用します。
Ubuntu + GTX 1070 > link: GeForce 390.65ドライバ(Windows 10)不具合情報 | link: CUDA 8.0の更新

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
```

### 現状

TensorFlowを動作している環境において、NVIDIAのドライバは以下のようになっている (2018/02/11現在)。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/1f82c86d-97e2-a5a8-c98a-7156a2ff9c4a.png)

### link1

以下を見つけた。

[【GPU】 GeForce 390.65 ドライバ 不具合情報](http://blog.livedoor.jp/nichepcgamer/archives/1069569652.html) @ ニッチなPCゲーマーの環境構築 

情報感謝です。

上記のドライバ(390.65)はWindows 10向けのもののようだ。
http://www.nvidia.co.jp/download/driverResults.aspx/129148/jp

### link2

[CUDA 8.0とcuDNN 6をUbuntu 16.04LTSにインストールする](https://qiita.com/JeJeNeNo/items/05e148a325192004e2cd)
> CUDA 8.0の更新

cuda-8-0だけの更新方法が紹介されている。

情報感謝です。
Ubuntu > apt > security関連のupdate表示 > apt list --upgradable | grep security | リンク:how-can-i-install-just-security-updates-from-the-command-line

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
```

```bash
$ apt list --upgradable | grep security

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

libminiupnpc10/xenial-updates,xenial-security 1.9.20140610-2ubuntu2.16.04.2 amd64 [1.9.20140610-2ubuntu2.16.04.1 からアップグレード可]
```

https://packages.ubuntu.com/xenial/net/libminiupnpc10

### 適用

上記だけを適用するには下記のようにする。

```bash
$sudo apt install libminiupnpc10/xenial-updates
```

### link

https://askubuntu.com/questions/194/how-can-i-install-just-security-updates-from-the-command-line

「ソフトウェアの更新」で表示される「その他のアップデート」を含めて全部をupgradeして環境が壊れないかは、もう少し情報を探した方がよさそう。

MeltdownかSpectre環境でNVIDIAドライバの更新問題を書いたQiita記事があり、それにコメントをしたが、見つけられない。投稿者が削除したのだろうか？
Python 3: print と return について（超基礎）

# `print()`と`return`について

## 関数の定義で`print()`と`return`どちらをつかうべきか？

* `print()`・・・表示するだけ
* `return`・・・戻り値を返す

```pycon:print()で表示するだけの関数を実行した
>>> def print_hello():
...     print("hello")
...
>>> print_hello()
hello
```

```pycon:returnで返ってきた"hello"という文字列をprint()で表示した
>>> def return_hello():
... return "hello"
...
>>> return_hello()
'hello'
>>> print(return_hello())
hello
```

---

## ジェネレータ関数で理解を深める

* ジェネレータ関数では，`return`の代わりに`yield`を用いる
* ジェネレータ関数を定義して，イテレータのように値を次々を取り出せるオブジェクトを作ることができる

---

### **Question**：`range(10)`から奇数を返す`odds`というジェネレータ関数を定義し，返された3番目の値を見つけて表示せよ．

---
* `odds()`を実行するとジェネレータ・オブジェクトであることが分かる．

```pycon:yieldを用いた場合
>>> def odds():
...     for num in range(1, 10, 2):
...         yield num
...
>>> for count, number in enumerate(odds(), 1):
...     if count == 3:
...         print(number)
...         break
...
5
```

---

* `odds2()`では，`return`によって`for`文で現れる最初の値が返される．
* `odds2()`は`int`型であることが分かる

```pycon:returnを用いた場合
>>> def odds2():
...     for num in range(1, 10, 2):
...         return num
...
>>> odds2()
1
>>> odds2()
1
>>> for count, number in enumerate(odds2(), 1):
...     if count == 3:
...         print(number)
...         break
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
```

---

* `odds3()`では`print()`によって1から10までの奇数が表示される
* `odds3()`は`NoneType`型で，これはイテラブルでないのでエラーを吐く

```pycon:printを用いた場合
>>> def odds3():
...     for num in range(1, 10, 2):
...         print(num)
...
>>> odds3()
1
3
5
7
9
>>> for count, number in enumerate(odds3(), 1):
...     if count == 3:
...         print(number)
...         break
...
1
3
5
7
9
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not iterable
```
---

## `NoneType`とは？

```pycon:Noneの型はNoneTypeである
>>> type(None)
<class 'NoneType'>
```
`NoneType`についてはまとめ中...
ローカル開発環境URLをlocalhost:3000以外に変更する

# やりたいこと
`localhost:3000`でなく`アプリ名:3000`でローカルの動作確認を出来るようにしたい

↓↓↓今回やりたいことのゴール

![image.png](https://qiita-image-store.s3.amazonaws.com/0/222024/f57c018e-eea2-53b3-bcc0-edee4ae6250d.png)

# 背景
ローカルで自分の作ったRailsアプリの動作確認の際に毎回`localhost:3000`にアクセスするのですが、`localhost:3000`でデフォルトのままだと何かイケてない気がする...
`アプリ名:3000`でアクセス出来るようにしたい

# 前提
Macを使用していること

# 手順
1.`etc` ディレクトリ以下の`hosts` (ローカルホストの設定ファイル)を書き換える

```ruby

# ターミナルで以下のコマンド実行

> sudo vim /etc/hosts

```
2.hostsファイル内のローカル・ループバック・アドレス（127.0.0.1部分）の同じ行にアプリ名を追記する

```ruby

# hostsファイル内

##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1       localhost  → こちらも残しておけば、通常のlocalhost:3000でもアクセス出来る
<中略>
127.0.0.1       アプリ名　     → 今回追加するもの


```

3.`rails s`で、`アプリ名:3000`でアクセス出来ればOK
![image.png](https://qiita-image-store.s3.amazonaws.com/0/222024/df111379-021b-1818-2814-ccecd03aeb0d.png)

# まとめ
現在の会社の開発環境構築手順の中にhostsを書き換える部分があり、
そこではじめて、hostsのローカル・ループバック・アドレス（127.0.0.1部分）を編集することで`localhost:3000`ではなく、`アプリ名.dev:3000`や`アプリ名.test:3000`でアクセス出来ることを知りました。
専門学校だったり、参考書であまり触れない部分だと思うので、
知らない方向けに投稿させて頂いた次第です！

# 注意
2017年末あたり、Chromeのバージョンアップの際に、開発環境のURLに`.dev`を含む場合は、開発環境も`https`に対応させないとアクセス出来なくなってしまいました...
`アプリ名.dev`は使わない方が無難かもしれません。

↓↓↓実際の画面

![image.png](https://qiita-image-store.s3.amazonaws.com/0/222024/815a2106-9f27-84a4-da9f-764ce7d5cdbd.png)
PHPの中にJSを書く方法

# なんてことはない

yahooに画面遷移する

```php
echo '<script>location.href="https://www.yahoo.co.jp/";</script>';
```

3秒後にグーグルに遷移する

```php
echo <<<EOM
<script type="text/javascript">
    setTimeout(function(){
  window.location.href = 'https://www.google.co.jp/';
}, 3*1000);
</script>
EOM;
```

#参考

[Header location doesn't work in my wordpress plugin.
](https://stackoverflow.com/questions/22376491/header-location-doesnt-work-in-my-wordpress-plugin)
【メモ】 playframework + vuejs

この文書はplayframeworkとvuejsを使うときに私が最初にやったことを記録するためのメモです。playframeworkは5年くらい経験がありますが、vuejsは初心者です。考え違いなどあると思いますが、見つけたら適宜修正します。

playframeworkでvuejsを使おうと思って、調べると[play-vue-webpack](https://github.com/gbogard/play-vue-webpack)というのが見つかります。試してみると、結局vuejsは8080ポート、playframeworkは9000ポートを使っています。`sbt run`でnodejsとplayframeworkが同時に起動できるのは良いと思います。あと、distでまとめてコンパイルできるようですが、私はvuejsはWEBサーバ側に置くつもりなのでそこにメリットを感じません。一方、build.sbtで色々やっているようで、これだと、vuejs、playframeworkのそれぞれでバージョンアップがあっても、双方にメンテが入る可能性が高そうです。そこで、playframeworkとvuejsを別々に考えていくことにします。

1. 前提
    - java8、sbt、nodejs、npmは適度に新しいものがインストールされているものとします。
    - OSはubuntuを使っています。

2. playframeworkの準備
名前は適当に設定して、それ以外は、デフォルトのまま。
http://localhost:9000 で確認後、playframeworkは停止させます。
```
sbt new playframework/play-scala-seed.g8
cd [プロジェクト名]
sbt run
```

3. vue-cliのインストール(最初だけ) 
webpackを使いたいのでcliをインストールしておきます。
```
sudo npm install --global vue-cli
```

4. vuejsのインストール
playframeworkとvuejsは同じディレクトリの方が便利なので、1で決めたディレクトリにcdしてから以下の作業をする。
http://localhost:8080 で確認。
```
vue init webpack [vuejsの格納ディレクトリ名]
cd [vuejsの格納ディレクトリ名]
npm run dev
```

5. IDEの準備
最後に、私はeclipseで開発するので、./project/plugin.sbtにsbteclipseを追加して、`sbt eclipse`でインポートできるようにします。
未経験中途採用でエンジニアになった自分の経験から、新人教育を考える。

うちの会社は毎年中途で未経験者を取っていて、年齢も20代前半から30代半ばとかまで様々。
自分は27で前職をやめて、プログラミングや情報処理系資格勉強をして28でIT業界に転職。

それからかれこれ5年強になりますが、その中の経験から新人教育で必要だと思ったことを書いてみます。


#意味不明な言葉対策

やっぱり異業種転職はコレが大きな壁になってるんじゃないかと思うんですよね。
技術的な単語でも、打ち合わせで当然のように出てくる言葉でも、「？」が頭に浮かぶことが多々。

バッファ？エビデンス？？レビュー？？？デプロイ？？？？

さらにはその現場現場で使われる固有名詞も出てきたりで、もうそれだけでアレルギー反応出ちゃう人もいるかと。

なので新人には、極力そうゆう言葉を使って喋ることにしてます。耐性をつけるため。
それに、他者の人にいきなり聞くより、同社の先輩に聞く方がまだハードルは低いでしょうし。

実はそれなりに居るであろう、「カタカナ語をちゃんと理解してないで雰囲気で使ってる人」にはならないように、という意味合いも。


#生活残業はさせない
生活残業が染みついちゃってる人、いますよねぇ。。。
プグラマーはその存在にではなく、あくまで実績に対して報酬が発生するべきだと思っているので、新人にはキッチリ時間内で作業完了させることを意識させてます。
まぁ明らかに定時で終わらない作業量を振られたらどうしようもないですが･･･

新人の内はそりゃあスムーズに作業が進むわけもないので、毎時の進捗確認も必須。
不明点が出た時は、とりあえず5〜10分ぐらいなら考えて、調べて、ってやってみて、その時間でわからなければすぐ質問する。を徹底させます。

最初はどうしても不明点が多すぎて残業せざるをえなくなることもあるかもしれないですが、

　2時間オーバーしちゃうけど残業すればいいやぁ

でなく

　今回は2時間オーバーしちゃったから、次はせめて1時間半。その次は1時間で済ませられるようにしよう

と思わせるように誘導できれば成功。

8時間で終わる作業は8時間で終わらせる。
みんな定時で帰ろうよ。体にも心にもその方が健康だよ。


#自分の作業を人に説明できるように意識させる

仕事の中で自分の脳にInputした知識は、同量、もしくはさらに負荷情報を付けて他者にOutputする。
帰社日にはそうゆう機械を作るようにしてます。

人に説明するのは自分の頭の中の情報整理になるので、自分にもプラスだし、同僚の先輩でも知らないような作業をしていることだって当然あるわけで、その先輩も知識のInputができる、と。


#やたらと本を買わない
たまにやたらと本を買いたがる新人がいます。
買うのは別に良いと思いますが、正直自分は、新人のレベルの内は、丁寧に説明されてるWebサイトでライトな知識を広くつけて行った方がいいと思ってます。
まず1年でも着実にそれで知識を付けられたら、それからもう一歩レベルを上げるための一つの手段が本という、それぐらいの感覚です。

あと、本を買いたがる新人は、買ったら1から10まで順を追ってやることに執着してしまう気がします。
最初から全て理解出来るのなんてごく一部の超優秀な人なので、まず1冊さらっと全体読んでみて、わかりそうなところから着手していく、というやりかたを進めてます。


#新人は出来なくて当然
ということを結構わかってない人は多い印象。
というか、「出来なきゃいけない」とか、「出来ないわけない」とか、そんなことを思っているフシのある人に出会うことも。

**身の程を知れ！**

と、言い方は悪いですが思います(笑

新人がなんでも出来るなんて、誰も思ってません。

自分が出来ること、出来ないこと。ちゃんと理解して、出来ないことは聞く。

当然のことですし、これは自分が今でも、そして今後もずっと意識し続けることだと思ってます。
railsをインストールしたのにrailsコマンドが使えない！？原因は単純なことだった

CentOSにrails環境を構築しようと思い、インストール等を済ませていざ、railsコマンドを使用したところ、「コマンドが見つかりません」となった。
何故だ。。。と思い、調べていくと以下のようなエラーが出ていた。

```
[root@localhost ~]# gem install rails
Fetching: concurrent-ruby-1.0.5.gem (100%)
Successfully installed concurrent-ruby-1.0.5
Fetching: thread_safe-0.3.6.gem (100%)
Successfully installed thread_safe-0.3.6
Fetching: tzinfo-1.2.5.gem (100%)
Successfully installed tzinfo-1.2.5
Fetching: i18n-0.9.4.gem (100%)
Successfully installed i18n-0.9.4
Fetching: activesupport-5.1.4.gem (100%)
ERROR:  Error installing rails:
        activesupport requires Ruby version >= 2.2.2.
```

最後の行にERRORを発見。サポートしているrubyは、2.2.2だと言っているようだ。rubyのバージョンが2.2.0だったので、2.2.2に変えてみることに。


**インストール対象を確認しインストールし直し**
```# rbenv install -l```
```# rbenv install -v 2.2.2```
```# rbenv rehash```

**バージョンを2.2.2へ切り替え**
```# rbenv global 2.2.2```
バージョンを再確認すると2.2.2になった

```
[root@localhost ~]# ruby -v
ruby 2.2.2p95 (2015-04-13 revision 50295) [i686-linux]
```

**railsを再度、インストール**

```
[root@localhost ~]# gem install rails
Fetching: concurrent-ruby-1.0.5.gem (100%)
Successfully installed concurrent-ruby-1.0.5
Fetching: thread_safe-0.3.6.gem (100%)
Successfully installed thread_safe-0.3.6
Fetching: tzinfo-1.2.5.gem (100%)
Successfully installed tzinfo-1.2.5
Fetching: i18n-0.9.4.gem (100%)
Successfully installed i18n-0.9.4
Fetching: activesupport-5.1.4.gem (100%)
Successfully installed activesupport-5.1.4
Fetching: mini_portile2-2.3.0.gem (100%)
・
・
・
```
今度は、ERRORにならず、インストールが進んだ。


**railsコマンドを使ってみる**

```
[root@localhost ~]# rails -v
Rails 5.1.4
```
よし！動いた。rubyとrailsのバージョンには注意が必要だ。
Google Homeに任意の言葉を喋ってもらう方法 Golang編

Google Homeに任意の言葉をしゃべって欲しい、そんな時ってありますよね?

現在は `google-home-notifier` というプログラムを使う方法が主流ですが、
この記事では、Goのパッケージを利用した方法を紹介します。

https://github.com/ikasamah/homecast

# コードの取得
```
# Goがインストールされていない場合
# $ brew install go

$ go get -u github.com/ikasamah/homecast
```

# サンプル実行
まずは example を起動してみます

```
$ go run $GOPATH/src/github.com/ikasamah/homecast/example/main.go

# GOPATHが設定されていない場合は以下
# $ go run ~/go/src/github.com/ikasamah/homecast/example/main.go
```

これで、ローカルネットワーク内のGoogle Homeが `Hello World`と喋ります。

次は、サンプルのHTTPサーバーを起動しましょう。

```
$ go run $GOPATH/src/github.com/ikasamah/homecast/example/server.go
```

サーバーが起動したら、ブラウザ等で次のURLにアクセスしましょう
http://localhost:8080/?text=こんにちは&lang=ja

`text`パラメータで指定された内容をGoogle Homeが喋ってくれます。
firebaseのチュートリアルで、Error: Missing or insufficient permissions.と言われた時の解決法メモ



firebaseのチュートリアルを行おうとしていたら、以下の部分でチュートリアル通りの画面がでなかった。
[codelabs](https://codelabs.developers.google.com/codelabs/firestore-web/#3)

開発ツールを開くと、以下のエラーが出ていた。

```
Error: Missing or insufficient permissions.
```

権限管理の何か、、というので、firebaseコンソール権限周りを見ていたら、データベースの設定で怪しげなところが。

![2018-02-11.png](https://qiita-image-store.s3.amazonaws.com/0/99876/0c1d606b-b115-4c49-b117-645dfcc155a3.png)

cloneしたファイルの中に、データベースの設定があったのを思い出す。

```json:firestore.rules
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}
```

これをコピーして、公開したらエラーは消えた。

![2018-02-11 (1).png](https://qiita-image-store.s3.amazonaws.com/0/99876/c2aa6a19-f371-21cf-dfdd-f4991de6646a.png)

※追記

次の項目に、データベースルールの変更法について記述ありましたね。

[5. Write Data to Firestore](https://codelabs.developers.google.com/codelabs/firestore-web/#4)

[チュートリアルソース※開始時点](https://github.com/hibohiboo/develop/tree/1845e48013940f21a776be68697ea991d4a7c119/tutorial/lesson/friendlyeats-web-master)


[チュートリアルソース※終了時点](https://github.com/hibohiboo/develop/tree/master/tutorial/lesson/friendlyeats-web-master)

## 追記

※ [データを安全にクエリする](https://firebase.google.com/docs/firestore/security/rules-query?hl=ja) も一読したほうがよさそう。

> あるアプリに、ユーザーが作成した story ドキュメントのリストを表示するページを含めるとします。次のクエリを使用してこのページのデータを取得できそうに思えますが、セキュリティ ルールと同じ制約が含まれていないため、このクエリは失敗します。
> 無効: クエリの制約がセキュリティ ルールの制約と一致していない

```
// This query will fail
db.collection("stories").get()
```
ESP-WROOM-02 (ESP8266) ファームウェアアップデート

# はじめに
ESP-WROOM-02のファームウェアを最新(2017/12/30現在、2.1.0）にアップデートした際の作業内容について纏めます。

# 環境とパーツ
- Windows 10 Pro PC環境
- ESP-WROOM-02　
    - [CEREVO社製](http://cerevo.shop-pro.jp/?pid=91592223)ブレイクアウトボードに実装
    - [こちら](http://bril-tech.blogspot.jp/2015/07/okiot.html?m=1)の記事を参考に、GPIOをモード選択が可能なようにJP2,JP3部分に10KΩのチップ抵抗を追加してます。
    ![R0012150.JPG](https://qiita-image-store.s3.amazonaws.com/0/100712/821b1bf5-4abf-550d-9498-793a43bc4344.jpeg)
- シリアル変換(FTDI FT232RL 3.3V 5.5V USB to TTL)
    - 私はAliexpress購入しました。
    ![2017-12-30 19.14.47.jpg](https://qiita-image-store.s3.amazonaws.com/0/100712/bd4bb11b-291f-1385-462d-ff03687b8433.jpeg)
- ブレッドボード
- 3.3V定電圧レギュレータ
    - 秋月電子購入品 [低損失三端子レギュレータ 3.3V 500mA TA48M033F(SQ)](http://akizukidenshi.com/catalog/g/gI-00538/)
- 抵抗10KΩ（EN,RSTのプルアップで使用）
- タクトスイッチ（RSTボタン）

# 回路
ブレッドボードに写真のように配線しました。
TA48M033Fには、5.0Vを入力させています。そのままVCCから3.3Vを取っても良いかもしれませんが電流不足を懸念してこのようにしました。
![2017-12-30 19.09.54.jpg](https://qiita-image-store.s3.amazonaws.com/0/100712/5b80eb8b-dd76-fd81-e7f2-1587ae81ab64.jpeg)


# ファームウェアとツールダウンロード
以下のサイトから、ファームウェアと書き込みツールをダウンロードします。

- ファームウェアダウンロード
    - http://www.espressif.com/en/support/download/sdks-demos
- 書き込みツールダウンロード
    - http://www.espressif.com/en/support/download/other-tools
- ESP8266 AT命令セット（ファームウェアの情報が記載）
    - http://www.espressif.com/en/support/download/documents

尚、2017/12/30現在以下のバージョンが最新でした。

- ファームウェア
    - ESP8266_NONOS_SDK-2.1.0
    ![WS000001.JPG](https://qiita-image-store.s3.amazonaws.com/0/100712/1ca3a524-bd14-50b5-411c-b34e11aa7f06.jpeg)

- 書き込みツール
    - FLASH_DOWNLOAD_TOOLS_V3.6.2.2
    ![WS000002.JPG](https://qiita-image-store.s3.amazonaws.com/0/100712/d86dc989-748c-f810-23e6-18b3d0fcb90e.jpeg)

- ESP8266 AT命令セット
    - ESP8266 AT Instruction Set Version 2.1.0
    ![WS000003.JPG](https://qiita-image-store.s3.amazonaws.com/0/100712/0e06f8a2-0a2c-600f-df4d-81d88600d0db.jpeg)


# ファームウェアアップデート実行
書き込みツール（FLASH_DOWNLOAD_TOOLS_V3.6.2.2）を立ち上げ、ファームウェアを指定します。
![スクリーンショット 2017-12-30 15.07.59.png](https://qiita-image-store.s3.amazonaws.com/0/100712/1c2053cb-34ae-7661-8ae9-589fb21ada0b.png)

以下、ツール起動後に変更した内容です。

|項目|値|
|:--|:--|
|Download Path Config|ファームウェアバイナリのパス@書き込み先アドレス|
|CrystalFreq|26MB|
|FLASH SIZE|32Mbit-C1|
|COM|COMポート|
|BAUD|115200|

ファームウェアと書き込み先アドレスの指定は、「ESP8266 AT Instruction Set Version 2.1.0」のドキュメント内「1.2.6 32Mbit Flash, Map' 1024KB + 1024KB」を参照して、入力しています。
![WS000004.JPG](https://qiita-image-store.s3.amazonaws.com/0/100712/b2458d7c-ed92-d1a9-b490-3bde7c21bf29.jpeg)


準備ができたら__[START]__ボタンを押します。

# アップデート結果

```
AT+GMR

AT version:1.4.0.0(May  5 2017 16:10:59)

SDK version:2.1.0(116b762)

compile time:May  5 2017 16:37:51

OK

```

以上です。
Oracle インデックス一覧 list_indexes.sql Oracle11.2.0 以降限定

```SQL:list_indexes.sql
--
--  インデックス一覧
--
-- history
--    2018/02/24 ORDER BY句の位置を修正
--    2018/03/03 INDEX_TYPEの表示位置を修正
--
SET ECHO OFF
SET FEEDBACK OFF
SET LINESIZE 500
SET PAGESIZE 50000
SET TERMOUT OFF
SET TRIMSPOOL ON
-- SPOOL pass includes_CONNECT_IDENTIFIER and SYSDATE
COLUMN SYSTEM_DATE    NEW_VALUE SYSTEM_DATE
SELECT '_'  || TO_CHAR(SYSDATE, 'YYYYMMDD_HH24MISS') AS SYSTEM_DATE FROM DUAL ;
SPOOL list_indexes_&&_CONNECT_IDENTIFIER.&&SYSTEM_DATE..log
-- Windows ↑,  UNIX/Linux では ↓ を有効に
-- SPOOL list_indexes_\&&_CONNECT_IDENTIFIER.\&&SYSTEM_DATE..log
BREAK ON TABLE_NAME ON INDEX_NAME ON CONSTRAINT_TYPE
COLUMN TABLE_NAME       FORMAT A30
COLUMN INDEX_TYPE       FORMAT A30
COLUMN INDEX_NAME       FORMAT A30
COLUMN CONSTRAINT_TYPE  FORMAT A21
COLUMN COLUMN_NAMES     FORMAT A300
SELECT DISTINCT
    A.TABLE_NAME
  , A.INDEX_TYPE
  , A.INDEX_NAME
  , A.CONSTRAINT_TYPE
  , NVL2(A.COLUMN_NAMES, '(' || A.COLUMN_NAMES || ')', NULL) AS COLUMN_NAMES
FROM(
    SELECT
         TA.TABLE_NAME
       , IX.INDEX_TYPE
       , NVL(IX.INDEX_NAME, '#no index#') AS INDEX_NAME
       , CASE CN.CONSTRAINT_TYPE
             WHEN 'C' THEN 'CONSTRAINT'   -- 表に対する検査制約
             WHEN 'P' THEN 'PRIMARY KEY'  -- 主キー
             WHEN 'U' THEN 'UNIQUE'       -- 一意のキー
             WHEN 'R' THEN 'REFERENCES'   -- 参照整合性
             WHEN 'V' THEN 'WITH CHECK'   -- ビューでのチェック・オプション付き
             WHEN 'O' THEN 'READ ONLY'    -- ビューでの読取り専用
             ELSE
                 CASE
                     WHEN IX.UNIQUENESS = 'UNIQUE INDEX' THEN
                         IX.UNIQUENESS
                 END
         END AS CONSTRAINT_TYPE
       , LISTAGG(IC.COLUMN_NAME || DECODE(IC.DESCEND, 'DESC', ' DESC'), ', ')
                    WITHIN GROUP(ORDER BY IC.COLUMN_POSITION)
                    OVER(PARTITION BY TA.TABLE_NAME, IX.INDEX_NAME) AS COLUMN_NAMES
    FROM USER_TABLES TA
    LEFT OUTER JOIN USER_INDEXES IX  -- 索引のないテーブルもある 
    ON  IX.TABLE_NAME  = TA.TABLE_NAME
    INNER JOIN USER_IND_COLUMNS IC
    ON  IC.TABLE_NAME  = IX.TABLE_NAME
    AND IC.INDEX_NAME  = IX.INDEX_NAME
    LEFT OUTER JOIN USER_CONSTRAINTS CN  -- 制約のないテーブルもある
    ON  CN.TABLE_NAME      = IX.TABLE_NAME
    AND CN.CONSTRAINT_NAME = IX.INDEX_NAME
    WHERE
        TA.DROPPED = 'NO' -- except trash box, since oracle10.1.0
    AND TA.TABLE_NAME NOT IN
        (
        'CHAINED_ROWS'  -- except Oracle side table
      , 'EXCEPTIONS'
      , 'PLAN_TABLE'
      , 'PLAN_TABLE$'
        )
    ) A
ORDER BY
    A.TABLE_NAME
  , A.INDEX_NAME ;
SPOOL OFF
CLEAR BREAKS
COLUMN TABLE_NAME       CLEAR
COLUMN INDEX_NAME       CLEAR
COLUMN CONSTRAINT_TYPE  CLEAR
SET ECHO ON
SET FEEDBACK ON
SET LINESIZE 80
```
参考
[LISTAGG SQL language reference Oracle11.2.0 以降でサポートされた](https://docs.oracle.com/cd/E16338_01/server.112/b56299/functions089.htm#CJABDFBD)
そすう

最速で素数を求めるほにゃららが酷かったので
以下

第一引数までの素数をコンソールに出力

```c#:prim.cs
namespace ConsoleApplication1
{
    class Program
    {
        private static int input;
        private static bool[] sieve;
        private static int limitSqrt;

        static void Main(string[] args)
        {
            input = int.Parse(args[0]);
            sieve = new bool[input + 1];
            limitSqrt = (int)System.Math.Sqrt((double)input);

            sieve[0] = false;
            sieve[1] = false;
            sieve[2] = true;
            sieve[3] = true;

            for (int x = 1 ; x <= limitSqrt ; x++)
            {
                for (int y = 1 ; y <= limitSqrt ; y++)
                {
                    int n = (4 * x * x) + (y * y);
                    if (n <= input && (n % 12 == 1 || n % 12 == 5))
                    {
                        sieve[n] = !sieve[n];
                    }
                    n = (3 * x * x) + (y * y);
                    if (n <= input && (n % 12 == 7))
                    {
                        sieve[n] = !sieve[n];
                    }
                    n = (3 * x * x) - (y * y);
                    if (x > y && n <= input && (n % 12 == 11))
                    {
                        sieve[n] = !sieve[n];
                    }
                }
            }
            for (int m = 5; m <= limitSqrt; m++)
            {
                if (sieve[m])
                {
                    int m2 = m * m;
                    for (int i = m2; i <= input ; i += m2)
                    {
                        sieve[i] = false;
                    }
                }
            }
            for (int i = 0 ; i <= input ; i++)
            {
                if (sieve[i])
                {
                    System.Console.Write(i.ToString() + ",");
                }
            }
        }
    }
}
```
OrmaとKotlinでデフォルトコンストラクタに@Column でないプロパティを入れると@setter constructor parameters must satisfy all the @column fields が発生する

#症状
一部の項目をデーターベースで管理したくないオブジェクトがあって、コンストラクターでColumnを指定しないフィールドを設定するとビルドに失敗した。

``` kotlin
@Table
class OrmaTodo(
        @Setter("id") @PrimaryKey var id: Long,
        @Setter("foo") @Column var foo: String,
        var bar:Int? = null
)
```

上記のコードをビルドしようとすると、以下のメッセージが出て失敗する。
barプロパティは Setterを指定していないのだけれど。。。
>Error:(51, 2) error: [OrmaProcessor] The @Setter constructor parameters must satisfy all the @Column fields

#環境
Ormaのバージョンは4.2.5

```groovy
    kapt 'com.github.gfx.android.orma:orma-processor:4.2.5'
    compile 'com.github.gfx.android.orma:orma:4.2.5'
```

#対策
プライマリーコンストラクターでなければ大丈夫

```kotlin
@Table
class OrmaTodo(
        @Setter("id") @PrimaryKey var id: Long,
        @Setter("foo") @Column var foo: String
) {
    constructor(id:Long, foo:String, bar:Int?) : this(id, foo) {
        this.bar = bar

    }
    var bar: Int? = null
}
```

コンストラクターで指定する必要がないプロパティであれば、コンストラクタから単に外すだけでもOK

```kotlin
@Table
class OrmaTodo(
        @Setter("id") @PrimaryKey var id: Long,
        @Setter("foo") @Column var foo: String
) {
    var bar: Int? = null
}
```
YQL で IKEA の商品在庫数を取得してみた。

YQL(Yahoo Query Language)を使って何かしたいなと思い、
IKEA の商品在庫数が PC ページからだと見えなくて、スマホページからだと見えていたので、
YQL と javascript で商品在庫数を取得してみました。

それを元に react でガワを作って、now にあげたページは[こちら](https://ikeastocksearch-kuqaahrrcn.now.sh/)になります。

## YQL について

YQL の詳細は[こちらの記事](https://qiita.com/nyatto/items/94c3f7cac14e8e8ef50f)を参考にしました。  
YQL Console が廃止になったので、[こちら](https://developer.yahoo.com/yql/)のページで試しながら YQL を組み立てました。

## IKEA の商品在庫数のページ

IKEA では商品毎に商品 ID が振られ、商品ページが存在するのですが、
商品毎に商品在庫情報の XML ページが存在します。
そのページを今回は YQL で取得し、javascript で整形しました。

YQL のクエリはこんな感じ

`select * from xml where url = 'http://www.ikea.com/jp/ja/iows/catalog/availability/30339293 '`

実際に使うエンドポイントはこのようになります。

`https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%20%3D%20'http%3A%2F%2Fwww.ikea.com%2Fjp%2Fja%2Fiows%2Fcatalog%2Favailability%2F30339293%20'&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys`

## YQL を使った javascript のコード

今回は、エラーハンドリングもなしで、データ取得できる前提で作っています。。。
また、在庫を見たいのが関東近辺の店舗だけだったので、
データ取得後関東近辺の店舗情報だけを取得しています。

```javascript
import axios from 'axios';

export default async function getStockInfo(productNo) {
  const API_URL = `https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%20%3D%20%27http%3A%2F%2Fwww.ikea.com%2Fjp%2Fja%2Fiows%2Fcatalog%2Favailability%2F${productNo}%27%20%20&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys`;

  const storeMap = {
    '448': '港北',
    '447': 'Tokyo-Bay',
    '887': '新三郷',
    '359': '立川'
  };

  const results = await axios.get(API_URL);
  const status = results.data.query.results['ikea-rest'].actionResponse.code;
  const localStore =
    results.data.query.results['ikea-rest'].availability.localStore;

  const storeData = localStore.filter(function(value, index) {
    for (let d in this) {
      if (d === value.buCode) return value;
    }
  }, storeMap);

  const stocks = storeData.map(dd => {
    return {
      storeName: storeMap[dd.buCode],
      stock: dd.stock.availableStock
    };
  });

  return { status, stocks };
}
```

## YQL使ってみて

YQL知らなかった時は、GoogleAppsScriptでCORS回避するとかしていたのですが、
YQLの方が断然楽に作れるので、YQLもっと使っていきたいと思います。
Pythonで一定時間ごとに処理を実行する

pythonで一定間隔ごとに処理をしたい場合、以下のように単純にsleepしてしまうと、一定間隔でなくなってしまう。

```bad.py
import time

def worker():
    print(time.time())
    time.sleep(8)

interval = 5
while True:
    worker()
    time.sleep(interval)
```

実際にこの例だと5秒おきに実行したかったのに、13秒おきに実行されてしまう。

```
1518294594.6087666
1518294607.611248
1518294620.6149857
```

以下のようにベースとなる時間を決めてそこからの時間差分を考慮するとできる。

```schedule.py
import time
import threading

def worker():
    print(time.time())
    time.sleep(8)

def schedule(interval, f, wait=True):
    base_time = time.time()
    next_time = 0
    while True:
        t = threading.Thread(target=f)
        t.start()
        if wait:
            t.join()
        next_time = ((base_time - time.time()) % interval) or interval
        time.sleep(next_time)
```

waitがTrueの場合、同時実行されるスレッドは1つのみとなり、待ち時間以内に処理が終わらなかったら次のタイムスロットまで待つ。
（この例だと、5秒以内に処理が終わらないので+5秒さらに待つ）

```
>>> schedule(5, worker)
1518295406.8357077
1518295416.849788
1518295426.8451777
```

waitがFalseの場合は、きっちり5秒ごとに実行される（複数スレッドになりうる）

```
>>> schedule(5, worker, False)
1518295478.5527058
1518295483.5534766
1518295488.5580828
```
keras-rlとOpenAI Gymで強化学習（ breakoutサンプル）

# はじめに
 今回はkeras-rlとOpenAI Gymで強化学習を試します。今回は数年前にdeepmindのvideoでも紹介されていた breakout です。

# 参考にしたコードなど
　breakoutサンプルについては、下記のgithubを参考にさせていただきました。

https://github.com/openai/gym
https://github.com/matthiasplappert/keras-rl/blob/master/examples/dqn_atari.py

# breakout サンプル
　はまったところは一点だけ。cmakeが入っていないと gym[atari] のインストールでエラーになる。cmakeが必要なことは、githubのREADMEにはしっかり書いてあり、私が読んでなかっただけです。
　また、jupyter-notebookで動かすため、引数周りのコードを変更しました。書き換えたコードは下記に置きました。

https://github.com/kznx/kznxtest/blob/master/atari_01.py
　
# トレーニング結果
　デフォルトの1750000step完了には、13時間ほどかかりました。本格的な強化学習にはGPUは必須な様です。

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/keras?src=hash&amp;ref_src=twsrc%5Etfw">#keras</a>-rl と <a href="https://twitter.com/hashtag/opengym?src=hash&amp;ref_src=twsrc%5Etfw">#opengym</a> で強化学習。1750000 step 完了すると、ほとんどミスしないレベル。 wwww   reinforcement learning by opengym, breakout sample (1750k steps) <a href="https://t.co/mLDaEwFZNk">https://t.co/mLDaEwFZNk</a> via <a href="https://twitter.com/YouTube?ref_src=twsrc%5Etfw">@YouTube</a></p>&mdash; Kazutoshi Nakano (@kznx) <a href="https://twitter.com/kznx/status/962417297020223489?ref_src=twsrc%5Etfw">February 10, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


# 最後に
　breakoutサンプルを試してみました。もう少しstepを増やせばdeepmindが公開していたvideoぐらい上手くなるかもしれません。
環境変数を用いて手間なく Rails をメンテナンスモード (HTTP 503) に切り替える 

サイトメンテナンス時には HTTP 503 Service Unavailable を返すようにするのが SEO の観点から好ましいです。

設定を行う箇所として、ロードバランサ、Rails アプリ、Web サーバなど色々な選択肢が考えられますが、今回は「環境変数のみを用いて設定変更を可能にする方法」を説明します。

# 背景
「新機能デプロイ時、メンテナンスモードに切り替えたいんだけど、そんな手間のかかることはしたくなくて、社内の IP から以外は全部 503 返したいだけなんだよなー。あと、アプリエンジニアだけで完結させたいなー」

# メリット
システム構成次第なところもありますが、環境変数 の変更はロードバランサ、Rails アプリ、Web サーバの設定変更に比べ、非常に手間が少ないです。
例えば、AWS OpsWorks ではブラウザ上から簡単に環境変数の変更、デプロイによる反映が行なえ、ものの数ステップでメンテナンスモードへの移行が完了します。

また、この機能を実現するために必要な Rails の設定も非常に簡素な点もメリットです。
「そんな大掛かりなことしたくなくて、一定期間 503 が返れば良いんだけど……」というケースに最適だと思います。

# デメリット
以下に実現できることとして書きますが、実現方法も切替時の設定方法も非常にシンプルなため、機能自体もシンプルです。
Rails アプリ側でもっと複雑な制御がしたいんだけど……というケースであれば [biola/turnout](https://github.com/biola/turnout) のような gem を利用するのが良いかもしれません。

# 実現できること
* 環境変数を用いて以下の設定が可能
    * メンテナンスモードの ON/OFF
    * IP アドレスによるホワイトリストの指定

# 実現方法
以下の設定を app/controllers/application_controller.rb に追加するだけで完了です。

```ruby
class ApplicationController < ActionController::Base
  before_action :render_503_except_for_whitelisted_ips, if: :maintenance_mode?

  def maintenance_mode?
    ENV["MAINTENANCE_MODE"] == "true"
  end

  def render_503_except_for_whitelisted_ips
    ips_in_whitelist = (ENV["ALLOWED_IPS"] || "").split(",")
    return if ips_in_whitelist.include?(request.remote_ip)

    render(
      file: Rails.public_path.join("503.html"),
      content_type: "text/html",
      layout: false,
      status: :service_unavailable,
    )
  end
end
```

また、ここでは public/503.html を読み込むようにしていますので、必要に応じて変更してください。

# 利用方法
以下の環境変数を設定し、それを反映するだけです。

| キー | 値 |
| --- | --- |
| MAINTENANCE_MODE | "true" を設定するとメンテナンスモードへ移行します |
| ALLOWED_IPS | アクセスを許可したい IP アドレスをカンマ区切りで指定します |

`rails server` を使った例だと、以下のようになります。

```bash
$ MAINTENANCE_MODE=true ALLOWED_IPS=192.168.145.2,192.168.145.3 bin/rails s -b 0.0.0.0
```

以上、とっても簡単！

# まとめ
環境変数を利用すると楽ちん！

# リンク
* [necojackarc/Control Maintenance Mode (Render 503) by Env Vars with Rails.md - Gist](https://gist.github.com/necojackarc/35bac9f8cdeed5cf828e22d318bdb5d3)
CSSで画像を中央揃えにして、両脇にはみ出した部分を切り捨てる。

# TL;DR
```CSS:style.css
div{
    width: 200%;
    margin: 0 -50%;
    text-align: center;
}
```

# やりたかったこと
下のリンクにしたものを作るとき、画像を縦方向に画面いっぱい表示して、横にはみ出した部分は切り捨てたかった。

http://circle9.work/mics/megami/megami.html （拙作: ふるよにメガミランダマイザ）

# やったこと
画像を入れる`div`の`width`を`200%`にして、マイナスのマージンを使って左右均等に画面外へ飛ばした。`200%`という数字は、`100%`より大きいこと以外に意味はないので、適宜もっと大きい値にしたり小さい値にしたりしてやってください。他にもやり方はあるだろうけど、難しいCSSプロパティを使わずに実装できる唯一の方法だと思います。

```HTML:test.html
<!-- 一部のみ -->
<div>
    <img src="hoge.jpg">
</div>
```

```CSS:style.css
body{
    overflow-x: hidden;
}
img{
    height: 100%;
}
div{
    height: 100vh;
    width: 200%;
    margin: 0 -50%;
    text-align: center;
}
```

##面倒なこと

なお、`overflow`系のプロパティは、iOSのSafariで変な挙動を示す。
Mota hone ke upay

 इस पोस्ट में आपको  <a href="https://hindiinformations.com/mota-hone-ke-upay">Mota hone ke upay</a> बताऊंगा | आज कल लोग मोटा होने के तरीके रोज ढूंढते है, अगर आपका खान-पान भी अच्छा है, पर फिर भी मोटा नहीं हो पाते है, और आप अपने दुबलेपन से बहुत परेशान रहते है तो आइए हम आपको मोटा होने के उपाय बताएँगे |
Raspberry Pi3 無線LAN設定

volumioセッティング時に無線LAN設定について色々調べたので残しておきます。

## 注意
私の知識不足かと思いますがvolumoをコマンドラインから無線LAN設定を行うと、
volumoのWEB画面を表示した際、ずっとくるくるしたまま表示できなくなります。

そのため、volumioのセットアップを行う方は初めに有線接続してから
WEB画面にて無線LAN設定を行ってください。

## 環境

|機器・OS|バージョン|
|:--|:--|
|Raspberry Pi|3|

## SSID・パスワード設定

以下のファイルにご自身のSSID,パスワードを設定します。
※初期状態だと[nano]コマンドしかエディタは無いと思います。

念のため、[nano]コマンドの使用方法も記載しておきます。

```bash
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf
```
終了する時は[Ctrl+X]で終了し、[y]を押下してEnterで上書き保存します。

```:/etc/wpa_supplicant/wpa_supplicant.conf
country=JP
ctrl_interface=DIR=var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
         ssid="自身のSSID"
         psk="自身のパスワード"
}
```

## DHCP設定
使用している環境がDHCPならば、以下の設定ファイルを修正します。
固定IPの設定については参考にさせていただいた記事をご覧ください。
[参考記事](https://qiita.com/hotchpotch/items/dfcb9bd02baf67223eb0)

```:/etc/network/interfaces
#iface wlan0 inet manual #ここをコメントアウト
iface wlan0 inet dhcp #ここを追記
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf #ここも追記
```

## ネットワーク再起動
以下のコマンドで無線LAN設定を再起動します。

```bash
sudo ifdown wlan0
sudo ifup wlan0
```

正しく設定できていればdhcpcが開始され、DHCPサーバーからIPアドレスが割り当てられます。
失敗時は設定を見直してください。
(スペルミス、パスワードのミスに注意)

## 接続確認
まず、以下のコマンドでIPアドレスが割り当てられているか確認します。

```bash
ip a
#表示内容は長いので割愛
```
[wlan0:]に記載されたIPアドレスがDHCPより割り当てられたアドレスです。

他のPCからpingコマンドを使用し、応答があるか確認します。

## 最後に
上記の設定を全て行った後、volumoにアクセスしてもずっとくるくるしたままでしたので
最終的に諦めて有線LANにてセットアップしました。
volumioの無線LAN設定は無理に頑張らず、有線にてセットアップすることをお勧めします。

※そもそもミュージックプレイヤーとして使用するだけだと思いますので
emacsでrubyを快適に書くためにしたこと

emacsでのrubyの環境構築系の記事は沢山あるが、自身の備忘としてまとめておく。

# 導入したもの
・ruby-block：endに対するdoやwhileなどをハイライト
・ruby-electric：do endなどの自動補完
・robe：ruby-mode用オムニ補完ツール
・company：コード補完用パッケージ
・pry：rubyインタプリタ

### ruby-blockの設定
endにフォーカスしたらすぐにdoをハイライトしたいのでdelayを0にした。

```lisp:ruby-block.el
; ruby-block-delay を0.50 → 0に設定
(defcustom ruby-block-delay 0
  "*Time in seconds to delay before showing a matching paren."
  :type  'number
  :group 'ruby-block)
```

```lisp:ruby-block.elc
ruby-block-delay 0
```

導入に関する手順などは他に充実しているサイトが沢山あるため割愛。ただ自身の環境で試したところ、すんなりいかなかったところがあったため、ハマりどころをまとめておく。

【参考】
[auto-complete + rsense の代わりに auto-complete + robe をつかう](http://codeout.hatenablog.com/entry/2014/02/04/210237)

# ハマったところ
すんなり設定できなかったところを中心にまとめていく。
## emacsにrubyのパスを通す
rubyのバージョンをrbenvで管理しているため、emacsにパスを明示的に通してあげないといけない。

```lisp:init.el
;; rbenvパス設定
(setenv "PATH" (concat (expand-file-name "/usr/local/var/rbenv/shims/ruby") (getenv "PATH")))

(require 'rbenv)
(setq rbenv-installation-dir "/usr/local/var/rbenv")
```

## 【暫定対応】M-x inf-rubyで呼び出されるirb(pry)の設定について
rubyのオムニ補完を有効化するには
`M-x inf-ruby`
`M-x robe-start`
をする必要があるが、このときinf-rubyで起動されるirbが認識しているrubyのバージョンが古いままだった。
irbが認識しているrubyのバージョンは次のように確認する。

```ruby
irb(main):001:0> RUBY_VERSION
=> "2.0.0"
```

rbenvで管理しているアクティブなrubyを認識させたかったのだが、これに手こずった。
というか結局パスの通し方がよくわからず、ゴリ押しで設定した。

【分かったことと対応】
・デフォルトでM-x inf-rubyで呼ばれているirbは`/usr/bin/irb`であり、これはデフォルトで導入されている古いバージョンのものである。
・色々調べたが、どのようにすればinf-rubyで呼び出されるirbの向け先を変更できるかが分からなかった。
・仕方がないので、`/usr/bin/irb`を退避させ、`irb -> /usr/local/var/rbenv/shims/pry`とシンボリックリンクを貼って強制的に読ませた。

## init.el設定
```elisp:init.el
;; rbenvパス設定
(setenv "PATH" (concat (expand-file-name "/usr/local/var/rbenv/shims/ruby") (getenv "PATH")))

(require 'rbenv)
(setq rbenv-installation-dir "/usr/local/var/rbenv")


;; do endなどの補完
(require 'ruby-electric)
(add-hook 'ruby-mode-hook '(lambda ()
          (ruby-electric-mode t)))
(setq ruby-electric-expand-delimiters-list nil)


;; 補完機能
;; robe-modeの有効化とcompanyとの連携
(add-hook 'ruby-mode-hook 'robe-mode)
(autoload 'robe-mode "robe" "Code navigation, documentation lookup and completion for Ruby" t nil)
(eval-after-load 'company
  '(push 'company-robe company-backends))

(add-hook 'ruby-mode-hook (lambda()
	  (company-mode)
	  (setq company-auto-expand t)
	  (setq company-transformers '(company-sort-by-backend-importance)) ;; ソート順
	  (setq company-idle-delay 0) ; 遅延なしにすぐ表示
	  (setq company-minimum-prefix-length 1) ; 何文字打つと補完動作を行うか設定
	  (setq company-selection-wrap-around t) ; 候補の最後の次は先頭に戻る
	  (setq completion-ignore-case t)
	  (setq company-dabbrev-downcase nil)
	  (global-set-key (kbd "C-M-i") 'company-complete)
	  ;; C-n, C-pで補完候補を次/前の候補を選択
	  (define-key company-active-map (kbd "C-n") 'company-select-next)
	  (define-key company-active-map (kbd "C-p") 'company-select-previous)
	  (define-key company-active-map (kbd "C-s") 'company-filter-candidates) ;; C-sで絞り込む
	  (define-key company-active-map [tab] 'company-complete-selection) ;; TABで候補を設定
	  (define-key emacs-lisp-mode-map (kbd "C-M-i") 'company-complete) ;; 各種メジャーモードでも C-M-iで company-modeの補完を使う
	  ))
```
新しくなったenebularを使ってみる Vol.2　～Amazon EchoとMbedを繋げて照明をコントロール～

#enebularにノードを足す
[enebular](https://enebular.com/)には[Node-RED](https://nodered.jp/)対応のノードを追加できることがわかったので、Amazon Echoと繋げられるノードを足してみました。
enebularについては以前（[新しくなったenebularを使ってみる Vol.1](https://qiita.com/jksoft/items/e3d047ac44237e0cb30e)）の記事で紹介してます。

とりあえず、最終的には照明のコントロールを音声でできるようにすることを目指して、実験しつつ確認していきます。

#Node-RED Alexa Home Skill Bridgeを足す
[Node-RED Alexa Home Skill Bridge](https://alexa-node-red.bm.hardill.me.uk/)については、こちら（[Amazon Echoとラズパイで、音声で照明をon/offする](https://qiita.com/kikuzo/items/753b5065dde9633bda18)）の記事を参考にしました。
アカウントを作って、デバイスを追加するだけです。

enebularにノードを足すのも同じようにサイドバーのadmin項で「node-red-contrib-alexa-home-skill」と入力して、インストールするだけです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/109992/4828d600-2f8c-4fe2-d27d-10bf65559f92.png)

ノード一覧の一番下にAlexa用のノードが追加されました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/109992/c82e00e4-a4db-75d0-6cec-f9a1847ef123.png)

#Amazon Echoの設定
私が持っているのはEcho Dotですが、どれでも一緒だと思います。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/109992/8dcbeda7-2b06-502f-a40e-1cea9d799875.png)

Amazon Echoとリンクしてるスマホアプリのメニューからスキルを選んで「Node-RED」で検索するとスキルが出てくるので、それを使えるようにします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/109992/bdac71ce-19a0-114c-59bf-fbce7d5b3fbb.png)

Node-RED Alexa Home Skill Bridgeで作ったアカウントでログインして、設定したデバイスを追加するだけです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/109992/963711f9-a4d6-fe76-8dba-9bed82504e11.png)

#確認用のフローを作る
とりあえず、確認するために簡単なフローを作ってみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/109992/d163557f-0e7b-d59a-d14a-a4bc69ee5b9d.png)

Alexa Homeノードの設定もNode-RED Alexa Home Skill Bridgeで作ったアカウントでログインして、設定したデバイスを追加するだけです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/109992/b31a1d94-0463-82a3-34ac-2ef94432fe8c.png)

設定が終わったらデプロイします。Amazon Echoと接続が完了したらノードの下に表示されているステータスがconnectedになります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/109992/c6cb5957-3df8-5b9e-ae2c-d630919c7bc1.png)

#確認する
Amazon Echoに向かって、Alexaの起動コマンドとスマホアプリで設定したデバイス名＋「をつけて」と言うとdebug出力に「true」とでました。
ちなみに私の設定では「コンピュータ ライトをつけて」と言うと反応します。
また、「をつけて」の部分を「をけして」にすれば「false」とでました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/109992/ac23bb36-aac9-36bf-17a1-61eb1049aca7.png)

意外とすぐできたので、この時点で感激でした。

#照明をコントロールするためには
enebularからデバイスとと繋げないと照明をコントロールできません。
デバイスは[以前の記事](https://qiita.com/jksoft/items/e3d047ac44237e0cb30e)でも使ったNUCLEO-L432KC（Mbed）+ Multi IoT Boardを使います。我が家の照明は赤外線でコントロールできるようになっているので、[Multi IoT Board](http://www.runele.com/ca1/47/p-r-s/)の赤外線送受信機能を使えばコントロールできると思います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/109992/4d02a6f3-ed4e-c6a0-7716-f33fbae98da3.png)

デバイスとenebular間のやりとりは[Milkcocoa](https://mlkcca.com/)を使おうと思ってます。フロー的にはこんな感じ？
![image.png](https://qiita-image-store.s3.amazonaws.com/0/109992/5cec3c15-ac20-4418-714c-2c1ba84a86c5.png)

#以降、まとめ中
[VisualStudio]リソースファイルからアイコンの使用する。

リソースファイルの使用について調べてたら意外と見つからなかったので残します。

```c#:外部ファイルからアイコンの使用
NotifyIcon mNotifyIcon = new NotifyIcon(); 
mNotifyIcon.Icon = new Icon("Icon1.ico"); 
```

```c#:リソースファイルからアイコンの使用
NotifyIcon mNotifyIcon = new NotifyIcon(); 
mNotifyIcon.Icon = Properties.Resources.Icon1;
```

[参考サイト](https://msmania.wordpress.com/tag/notifyicon/)
SAP Cloud Connectorのインストール

Cloud Connectorのインストールを行いました(Windows)。

以下を参照しました。
[SAP Cloud Platform Cloud Connector setup for secure on-premise connectivity](https://www.sap.com/developer/tutorials/hcp-cloud-connector-setup.html)

※Step9まで実施。


##**Step 1: Download the cloud connector**
こちらからダウンロード
https://tools.hana.ondemand.com/#cloud

バージョンは、2.10.2

![スクリーンショット (730)_LI.jpg](https://qiita-image-store.s3.amazonaws.com/0/22526/c8d6ec44-02a6-1700-326c-eed08c59bf3e.jpeg)


##**Step 2: Begin installation**
![スクリーンショット (766).png](https://qiita-image-store.s3.amazonaws.com/0/22526/f1cdc9a7-962b-d20b-2595-3af9fc328087.png)

![スクリーンショット (767).png](https://qiita-image-store.s3.amazonaws.com/0/22526/b26a1814-bb98-c770-2caa-ebaabee737c1.png)


##**Step 3: Choose a port**
![スクリーンショット (768)_LI.jpg](https://qiita-image-store.s3.amazonaws.com/0/22526/5aa04bf8-db73-d90c-98f8-d524cd272e50.jpeg)



##**Step 4: Finishing the installation**
![スクリーンショット (769).png](https://qiita-image-store.s3.amazonaws.com/0/22526/4e163ccf-4d5b-142f-b9eb-98a69e05e6c7.png)

![スクリーンショット (770).png](https://qiita-image-store.s3.amazonaws.com/0/22526/68030b7c-8ff5-a583-f54f-f0b8f6b300e4.png)

![スクリーンショット (771).png](https://qiita-image-store.s3.amazonaws.com/0/22526/c99e8342-5371-de35-f89f-68c889a36cd7.png)

![スクリーンショット (772).png](https://qiita-image-store.s3.amazonaws.com/0/22526/d1ba7b8c-f472-9b23-d4bb-bed0f4acd112.png)

![スクリーンショット (773).png](https://qiita-image-store.s3.amazonaws.com/0/22526/1cf16090-fc97-1309-0415-bdfcee7a7067.png)


##**Step 5: Check cloud connector status**

![スクリーンショット (774).png](https://qiita-image-store.s3.amazonaws.com/0/22526/12a5f8a7-1f2a-d0a6-71f7-c29152e7f386.png)

![スクリーンショット (775)_LI.jpg](https://qiita-image-store.s3.amazonaws.com/0/22526/8f6c5e1f-b567-e8f6-879e-fa37b596201d.jpeg)


##**Step 6: Verify connection**
![スクリーンショット (776).png](https://qiita-image-store.s3.amazonaws.com/0/22526/c1d4aff2-1e2f-8eb2-699f-1a1d352cfa67.png)


##**Step 7: Initial Configuration**
![スクリーンショット (777).png](https://qiita-image-store.s3.amazonaws.com/0/22526/ee9d3031-c0f6-0f6f-0b3a-c3028ddb4fd1.png)


##**Step 8: Define Account**
![スクリーンショット (778)_LI.jpg](https://qiita-image-store.s3.amazonaws.com/0/22526/56e6136f-22eb-f41a-8439-876c4cc169e4.jpeg)



##**Step 9: Check connection state**
![スクリーンショット (779)_LI.jpg](https://qiita-image-store.s3.amazonaws.com/0/22526/9a4752ce-e248-6dfb-1e32-f595614b9238.jpeg)


おしまい。
マウスでクリックしたオブジェクトの情報を取得する

画面上のキャラクターをマウスでクリックして、キャラクターが持つ会話テキストを表示したかったのでまずはマウスでクリックしたオブジェクトの情報を取得することに。

```c#:C#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GetObject : MonoBehaviour {

    public Camera camera_object; //カメラを取得
    private RaycastHit hit; //レイキャストが当たったものを取得する入れ物
	
	void Update () {
        if (Input.GetMouseButtonDown(0)) //マウスがクリックされたら
        {
            Ray ray = camera_object.ScreenPointToRay(Input.mousePosition); //マウスのポジションを取得してRayに代入
            
                if(Physics.Raycast(ray,out hit))  //マウスのポジションからRayを投げて何かに当たったらhitに入れる
            {
               string objectName = hit.collider.gameObject.name; //オブジェクト名を取得して変数に入れる
                Debug.Log(objectName); //オブジェクト名をコンソールに表示
            }
        }
    }
}
```

Unityのマニュアルを参照しながら作成。(参照元:[カメラからの Ray](https://docs.unity3d.com/ja/current/Manual/CameraRays.html))

```Public Camera camera_object```にMain Cameraをアタッチして使用。

![20180210_01.gif](https://qiita-image-store.s3.amazonaws.com/0/185127/7bcd3904-b7c4-528d-a2cc-0e76d2f2a873.gif)

できました。
複数gitが存在する場合に優先順を変更する

# はじめに
macでgitを使用してたらなぜかhomebrewでのアップデートしてもgitのバージョンが更新されない事象を発見。
調べたところ、gitがXcodeおよびCommand Line Toolsのインストール時とhomebrewによるインストールで二つ入ってしまっていた。

# したいこと
現在xcode側の/usr/bin/gitを使用するようになってしまっている為、
homebrewでインストールした/usr/local/bin/gitを使用するように変更したい。

# 対処法
やり方は複数あるが、パスの設定をいじって優先順を変更してあげればOK。
ターミナルを立ち上げて~/.bash_profileを編集する。
`vi ~/.bash_profile`

以下の様な設定を追加。
`export PATH=/usr/local/bin:$PATH`

環境変数PATHの頭に今回優先させたいディレクトリのパスを追加すると、先に書かれたパスが優先して読み込まれる様になるため、/usr/local/binのgitを優先して読み込んでくれるようになる。

編集が完了したら以下のコマンドで変更を適用。
`source ~/.bash_profile`

ターミナル再起動でもOK。
めでたしめでたし。