OmniAICreator/Qiita-1.07M huggingface dataset:
LibreOfficeのカラーパレットを作るためのpythonスクリプト

**概要**
MSPowerPointからLibreOfficeImpressに移行を試みたが不満に感じる点がいくつかある．
不満の1つにカラーパレットを作るのが面倒なことが挙げられる．
本記事ではカラーパレットを作るためのpythonスクリプトの例を示す．

環境

- Ubuntu 16.04
- LibreOffice 5.1.6.2
- Python 3.6 (Anaconda 4.3.14)

---

使い方：スクリプト内の変数に適当な値を入れて走らせる．
すると，カラーパレットができるので，LibreOfficeから呼び出して使う．

![Screenshot from 2017-03-12 00-44-39.png](https://qiita-image-store.s3.amazonaws.com/0/129263/c6f9efa0-628e-b33b-d834-c705d8b00cb2.png)


```python:get_color_pallete.py
import getpass
import colour # pip install colour 

USERNAME = getpass.getuser() 
PALLETE_PATH = "/home/"+ USERNAME + "/.config/libreoffice/4/user/config/"
# 出来上がったカラーパレットの置き場所

### xmlのフッター・ヘッター ###
HEADER = """<?xml version="1.0" encoding="UTF-8"?>
    <ooo:color-table xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
        xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
        xmlns:xlink="http://www.w3.org/1999/xlink"
        xmlns:svg="http://www.w3.org/2000/svg"
        xmlns:ooo="http://openoffice.org/2004/office"
    >\n"""
FOOTER = "</ooo:color-table>"
### xmlのフッター・ヘッターここまで ###


pallete_name = "mytheme" # office側で表示されるパレット名

color_dir = { # 色をここに記載する
    "00_fg_color": "#fefefe",
    "01_bg_color": "#303030",
    "10_main_bright": "#80F2E8",
    "11_main_normal": "#26A69A",
    "12_main_dark": "#1A736B",
    "20_accent_bright": "#f68880",
    "21_accent_normal": "#F44336",
    "22_accent_dark": "#612925",
}


def adjust_hue(c_base): # オリジナルの色から明度を調節して6色作って（パワポみたいに）リストを返す
    c_list = []
    c_luminance = c_base.luminance
    for i in range(3, 0, -1):
        c_new = colour.Color(c_base.hex)
        c_new.luminance = c_luminance + (1. - c_luminance) * (i / 4.)
        c_list.append(colour.Color(c_new.hex).hex_l)
    for i in range(1, 4):
        c_new = colour.Color(c_base.hex)
        c_new.luminance = c_luminance - c_luminance * (i / 4.)
        c_list.append(colour.Color(c_new.hex).hex_l)
    return c_list

def get_color_sequence(c_hex): # オリジナルの色を含む12個分の色のリストを返す
    c_base = colour.Color(c_hex)
    c_list = [c_base.hex_l]
    for i in range(5):
        c_list.append(c_base.hex_l)
    c_list += adjust_hue(c_base)
    return c_list

def pallet_color_setting_in_xml(c_name, c):
    return "<draw:color draw:name=\"" + c_name + "\" draw:color=\"" + c + "\"/>\n"
    

f = open(PALLETE_PATH + pallete_name + ".soc", "w")
f.write(HEADER)
for c_name in sorted(color_dir.keys()):
    c_list = get_color_sequence(color_dir[c_name])
    for i, c in enumerate(c_list):
        f.write(pallet_color_setting_in_xml(c_name + str(i), c))
f.write(FOOTER)
f.close()
```

**参考**

- [GitHub - vaab/colour: Python color representations manipulation library (RGB, HSL, web, ...)](https://github.com/vaab/colour)
- [LibreOffice Color Palette &laquo;  Practica Technical](http://www.practicatechnical.com/libreoffice-color-palette)
- [LibreOfficeメモ [nofuture.tv]](http://www.nofuture.tv/libreoffice#hue360%E3%81%A7%E4%BD%9C%E3%81%A3%E3%81%9F%E3%82%AB%E3%83%A9%E3%83%BC%E3%83%91%E3%83%AC%E3%83%83%E3%83%88%E3%82%92libreoffice%E3%81%A7%E4%BD%BF%E3%81%86)
FlowComponentでカンタン画面遷移

![flow.gif](https://qiita-image-store.s3.amazonaws.com/0/54076/3f33ebb1-9a7b-15a8-fab5-e4e094a7bb5c.gif)

[サンプルFramerファイル](https://framer.cloud/TyQXs)
[サンプルSketchファイル](https://drive.google.com/open?id=0B9aCukJROnQGeEhFNWQ2ekhfMFU)

Framerの長所は細やかなインタラクションが作れることですが、逆にカンタンな画面遷移が作りづらいことがFramerの弱点でしたが、[FlowComponent](https://framer.com/docs/#flow.flowcomponent)がリリースされたおかげで最近はその弱点も克服されつつあります。


## 初期設定

```CoffeeScript
#Flow Componentを作成します。ページを入れておく容器のようなものです。
flow = new FlowComponent
 
#レイヤーA（ページ）を表示する
flow.showNext(layerA, animate: true)
```

## 指定したページに遷移する　showNext("移動先のレイヤー名")
![Group 3.png](https://qiita-image-store.s3.amazonaws.com/0/54076/b636c606-9aa7-2e85-f31a-779bf034f00f.png)
flowComponentの中身を入れ替えて、指定したページを表示します。加えてオプションでは

- animateの有無
- （ページ要素が大きい時は）scrollの有無

を設定することができます。


## 一つ前のページに戻る　showPrevious()
では、逆に今来たページを戻る時はどうするのでしょうか？
そんな時は**showPrevious()**を使います
![Group 4.png](https://qiita-image-store.s3.amazonaws.com/0/54076/17ef05c4-658f-72ff-3918-b17d70741a07.png)
back1ボタンレイヤーをクリックした際に一つ前のレイヤーに戻るコードが書けました。()をつけ忘れることが多いので気をつけて下さい。

**showNext**と違い以前の画面がどの画面であったかをいちいち考えて指定する必要がないので、**showPrevious**の便利なところです。

**showNext**と**showPrevious**を駆使して、下のような画面遷移はすぐに作ることができます。
[サンプルFramerファイル](https://framer.cloud/TyQXs)
![flow.gif](https://qiita-image-store.s3.amazonaws.com/0/54076/3f33ebb1-9a7b-15a8-fab5-e4e094a7bb5c.gif)
GitHubでwordpress管理

# 構成
![スクリーンショット 2017-03-11 22.20.45.png](https://qiita-image-store.s3.amazonaws.com/0/70116/6985ccb4-4857-a038-606c-ee8a84a1debc.png)

blog（wordpress）のデータをGitHubで管理できるように設定しました。
クライアント側の設定はいつも通りのGitHubとのremote設定。GitHub側のデプロイするリポジトリのSettingのWebhookの設定で外部サーバへデプロイする仕組みを用意します。

# 設定に関して
## Webhooksの項目を使います
![スクリーンショット 2017-01-15 15.21.31.png](https://qiita-image-store.s3.amazonaws.com/0/70116/18338733-4cbd-c74b-5e2d-1aaccb2ca2ac.png)
設定を埋めてゆきます。

## 受け取りファイルの設定
受け取りのファイルを作ります。権限は実行を指定します。
公式サイトを確認しつつ、受け取りファイルを作ります。
<ul>
<li>https://git-scm.com/book/ja/v2/GitHub-%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%81%AB%E3%82%88%E3%82%8B-GitHub-%E3%81%AE%E6%93%8D%E4%BD%9C</li>
<li>https://developer.github.com/webhooks/</li>
</ul>

<pre>＜?php
$SECRET_KEY = 'Secretに入れた文字列';
$LOG_FILE = dirname(__FILE__).'/hook.log'; #ログを取る場所

if (! isset($_SERVER['HTTP_X_HUB_SIGNATURE'])) die();
if (! $_SERVER['HTTP_X_HUB_SIGNATURE'] === sha1($SECRET_KEY)) die();
$json_string = file_get_contents('php://input');
$payload = json_decode($json_string, true);
if (! $payload['ref']) die();

if ($payload['repository']['full_name'] === 'アカウント名/リポジトリ名' &amp;&amp; $payload['ref'] === 'refs/heads/更新該当のブランチ') {
  shell_exec("sh deploy.sh");
  file_put_contents($LOG_FILE, date("[Y-m-d H:i:s]")." ".$_SERVER['REMOTE_ADDR']." git pulled: ".$payload['head_commit']['message']."\n", FILE_APPEND|LOCK_EX);
}else{
	file_put_contents($LOG_FILE, date("[Y-m-d H:i:s]")." invalid access:認証通っていません ".$_SERVER['REMOTE_ADDR']."----\n", FILE_APPEND|LOCK_EX);
}
?＞
</pre>
※上部スクリプトは
http://takemikami.com/2016/01/11/GitHubWebhookgit-pushdeploy.html
を参考にさせていただいております。ありがとうございました。

## デプロイ実行の用意
受け取って、リクエストが指定したリポジトリからで、イベントとキーが一致したら、
gitコマンドを実行するシェルスクリプトを作成します。権限は受け取りファイルと同じ実行を指定します。
<pre>#!/bin/sh
cd /home/tomtomhouse/www/www.tomo.mobi/wordpress
git --git-dir=.git pull origin master
</pre>
受け取りのプログラムファイルもgitコマンドを打つシェルスクリプトもファイルの権限は「実行」に設定します。
この時、SSH通信でRSA暗号のパスフレーズが必要のときは、ssh-keygenでキーを生成するときにパスフレーズの設定を無しで作ると良いです。

# 備考
.gitignoreはGitHubのものを使うのが良いと思います。
<a href="https://github.com/github/gitignore/blob/master/WordPress.gitignore">https://github.com/github/gitignore/blob/master/WordPress.gitignore</a>
(Chrome専用) ふつうのカラーピッカー作った

![b.png](https://qiita-image-store.s3.amazonaws.com/0/152179/ed286854-0dbd-84e9-be44-40e63a9ed690.png)

外部ライブラリへの依存の無い、ごく簡素なカラーピッカーを作りました：
https://github.com/a-nakanosora/ANColorPicker

Electronで使用することを目的としているので、動作確認ブラウザはChromeのみです。(多分Firefoxでも動くと思います。)

ライセンスは`The Unlicense`です。

## 使い方

![f.gif](https://qiita-image-store.s3.amazonaws.com/0/152179/8c28650d-82e1-cc85-1dd8-df34b55673eb.gif)



```js
const {ANColorPicker} = require('./ancp')

const ancp = new ANColorPicker()
document.body.appendChild(ancp.getContainer())

const callback = ({rgb, hsv, isTrusted})=> console.log("rgb:",rgb, "hsv:",hsv, "isTrusted:",isTrusted)
ancp.onChange(callback)
```

モジュールを読み込んだ後 `new ANColorPicker()` でカラーピッカーのインスタンスを生成。`ancp.getContainer()` でDOMが得られるので適当な場所に配置します。 `ancp.onChange(callback)` で色が変更された時のハンドラを登録します。(引数については後述。)

プログラム側からカラーピッカーの選択色を変更するには `setColor()/setColorHsv()` を使用します：

```js
// RGB
const [r,g,b] = [200,100,50]
ancp.setColor(r,g,b)

// HSV
const [h,s,v] = [310,100,200]
ancp.setColorHsv(h,s,v)
```


## API

- `new ANColorPicker(size=200)`
    カラーピッカーを生成。引数にはカラーピッカーのサイズ(pixel)を指定。

- `ancp.getContainer()`
    カラーピッカーのコンテナDOMを取得。これをDOMツリー上の適当な場所に`appendChild()`することでカラーピッカーが表示されます。

- `ancp.onChange(callback)`
    カラーピッカーの選択色が変更された際に呼ばれるハンドラを登録。
    `callback`には第一引数に`rgb`,`hsv`,`isTrusted`それぞれのメンバが格納されたオブジェクトが与えられます。

    - `rgb` ： R,G,Bそれぞれの値が格納された配列。  
         (値域は`0 <= R,G,B <= 255`)

    - `hsv` ： H,S,Vそれぞれの値が格納された配列。   
         (`0 <= H <= 360` , `0 <= S,V <= 255`)

    - `isTrusted` ： ブール値。選択色がユーザ入力によって変更された場合は`true`が、`setColor()/setColorHsv()`によって変更された場合は`false`が与えられます。

- `ancp.setColor(r,g,b)`
    カラーピッカーの選択色をRGBで指定。

- `ancp.setColorHsv(h,s,v)`
    カラーピッカーの選択色をHSVで指定。



## 参考

当スクリプトを作成するにあたり下記のページを参考にさせていただきました：

- RGBとHSV・HSBの相互変換ツールと変換計算式 - PEKO STEP  
  http://www.peko-step.com/tool/hsvrgb.html
【Laravelメモ⑩】データベースのデータ参照

# 前提
- DBと接続可能な設定が完了しておりテーブルといくつかのデータが入っている
    - テーブル名：users
    - フィールド：idがある
- Eloquentモデル作成済(User.php)

# 動作
localhost:8000/select
にアクセスするとidフィールドの値を全部表示する

# 設定メモ

## ルーティング
```php:web.php抜粋
Route::get('select','testController@select');
```

## コントローラー
```php:testController.php抜粋
    public function select(){
    	$user = new User();
    	$users = $user::all();
	return view('select', compact("users"));
    }
```

## ビュー

```php:select.blade.php
@foreach ($users as $user)
	{{ $user->id }}
@endforeach
```
MacOS Sierra で、右Commandキーで日本語入力モード切り替えを行う

MacOS のキーバインド変更の神ソフトである [Karabiner](https://pqrs.org/osx/karabiner/) は、MacOS Sierra では動作しない。そのため、右Commandでの日本語入力モード切り替えのトグルを設定するためには、別のソフトを使う必要がある。これを行うためのソフト [⌘英かな](http://applech2.com/archives/20160801-cmd-eikana.html) があるが、ここでは Karabiner の Sierra 対応版サブセットである [Karabiner-Elements](https://github.com/tekezo/Karabiner-Elements/blob/master/README.md) を使った方法を記載する。

1. [Karabiner-Elements](https://github.com/tekezo/Karabiner-Elements/blob/master/README.md) をダウンロードしてインストールする。
2. right_command を keypad_num_lock にアサインする。
   <img width="776" alt="Karabiner-Elements.png" src="https://qiita-image-store.s3.amazonaws.com/0/108825/74ed8b39-8c03-7e1d-695f-f3e0f2c7b2ec.png">
   keypad_num_lock にアサインした理由は、別のキーにアサインしたところ、下記のショートカットの設定で F13 などになってしまい、画面輝度変更などの機能が動いてしまうため。
3. OS の System Preferences → Keyboard → Shortcuts → Input Sources → Select next source in Input menu で右コマンドを押すと「[X]」みたいなキーになる。
   <img width="648" alt="Keyboard_Preferences.png" src="https://qiita-image-store.s3.amazonaws.com/0/108825/5b1a781a-3492-5af0-070e-76ae33d6a9d6.png">

以上。

その他、キーバインドを変更したい場合は Karabiner-Elements の設定を行うのがよい。
Raspberry PI 3で遊ぶ環境を用意する(3:日本語入力とAudio出力確認)

Raspbianで日本語入力できる環境と、Audio出力を確認する


#日本語入力設定できるようにする

↓のサイトを見つけた。ここを参考にすればいけそう。
https://www.raspberrypi.org/forums/viewtopic.php?f=82&t=33381
フォントは本にあったvlgothicをインストールしたので、
ibusのインストールだけ実施。

ここで問題があって、「半角/全角」のボタンを押しても、
うまくibusの入力が反映されない…。日本語入力できない。。。
色々調べてたら↓のサイトに答えがあった。
http://linux99.exblog.jp/15920177

書かれている通り、再起動した後、ibusの設定をUS→日本語(Anty)に切り替えたら、
日本語入力ができるようになった。「半角/全角」で切り替わるようになったので、
これでOK。


#Audio出力を確認する
Raspberry-PI 3 ではAudio設定を、
　・Auto
　・強制HDMI
　・強制3.5mm jack
の3つに設定できるようだ。

>$sudo rasp-config
>　→　7 Advanced Options
>　　→　A4 Audio

ブラウザから適当に音が流れるようにして、
強制3.5mm jackに設定して、イヤホン挿して確認したところ音がした。
強制HDMIだと、テレビから音が出てこない…。
なんでだろう。。。

調べたところ↓を発見。
http://qiita.com/plsplsme/items/57b8d79d3725497fd69b
まずはこのサイトでの確認方法でイヤホンの確認方法で確認してみる。

これの/opt/vc/src/hello_pi/hello_audio/hello_audio.binを使ってみる。
…と思ったらバイナリなかった。
/opt/vc/src/hello_pi/ にREADMEがあって、
必要なライブラリからビルドしてくれるスクリプトまであったので、
これを叩いて見たところ、バイナリができた。

hello_audio.binを実行したところ、音が出た。
いよいよ本命のHDMIでの確認をやってみる。
> $ amixer cset numid=3 2
> $ speaker-test -t sine -f 600

HDMI接続したテレビからは音が出てこない。

/boot/config.txtで
hdmi_drive=2をコメントアウトし、再起動させてみて試す。

> $ amixer cset numid=3 2
> $ speaker-test -t sine -f 600

HDMI接続したテレビからは音が出てこない。
…と思ったが、デスクトップ右上に配置されてるボリュームをあげた所、音が出た！

嫌な予感がしたのでもう一回 /boot/config.txt を編集し、
hdmi_drive=2 をコメントして、再起動後、出るかを試す。
…音が出た。。。

つまり、元々音が出ていたが、ボリュームが小さかっただけだったようだ。
それにしても、バーを3/4まで上げないと音が出ないとは…。
(ボリュームコントロール75で音が聞こえた)
テレビとの相性なのかなぁ。

まぁ音が出たので、HDMIについても確認完了とする。
Androidに標準でインストールされているブラウザのタブの色を変える


## はじめに
いろいろとサイトをスマホで見ていると、たまにサイトのイメージカラーと同じ色になったり、下のメニュバーのアイコンもそれに合わせた色になったり、ちょっとかっこよかったので調べてみました。

イメージ的には以下のような感じです。
![Kobito.Z9Pgng.png](https://qiita-image-store.s3.amazonaws.com/0/91816/70a6e07c-6769-b1c7-628c-5b230b4e4d3e.png "Kobito.Z9Pgng.png")

から…

![Kobito.XjjtHF.png](https://qiita-image-store.s3.amazonaws.com/0/91816/c3400a05-d635-eaed-7812-0a22694ac85b.png "Kobito.XjjtHF.png")

に！
ちゃんと一番下のメニューバーのところも変わってます！
（なんか、スクショしたけど解像度高くない？って感じたり、ちょっと大きすぎないって考えたり）

最近のサムスンの端末はやけに解像度が高くなっていて、すぐに内蔵のストレージを圧迫しだすので困ったものですが…
でも、自分的には高解像度の方がいいので、設定はそのままですが…

**こんなに大きくなくても、見たらわかりますよね（笑）**

## やること
簡単です。
HTMLのhead部分に以下を記載するだけ！

```html:追記部分
<meta name="theme-color" content="green" />
```

これで、ちょっとかっこいいサイトでも作れそう！

以上、おわり！
自作Pythonその3 - Amazonの商品検索プログラム

痒いところに手が届く範囲がすきなんです。

index = "All" のジャンル指定は以下のリンク先で確認してください。
[商品カテゴリーの指定(SearchIndex)](https://www.ajaxtower.jp/ecs/itemsearch/index2.html)

これ結構さいつよだと思います。

```py3
import bottlenose
from bs4 import BeautifulSoup
import webbrowser

class Content:
    pass

class Amazon():
    def __init__(self):
        AMAZON_ACCESS_KEY_ID = ""
        AMAZON_SECRET_KEY    = ""
        AMAZON_ASSOC_TAG     = ""
        self.amazon = bottlenose.Amazon(AMAZON_ACCESS_KEY_ID, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG, Region="JP")
    def search(self,query,index="All"):# index = Videoなどジャンル
        response = self.amazon.ItemSearch(SearchIndex=index, Keywords=query, ItemPage=1, ResponseGroup="Large")
        xml  = response.decode('utf-8','strict')
        soup = BeautifulSoup(xml, "html5lib")
        data = soup.findAll('item')
        for d in data:
            url   = d.detailpageurl.text
            title = d.title.text.replace("[","【").replace("]","】")
            con       = Content()
            con.asin  = d.asin.text
            con.amazonjs= '[amazonjs asin="%s" locale="JP"]' % d.asin.text
            con.title = title
            con.url   = url
            con.link  = '<a href="%s">%s</a>' % (url,title)
            con.price = d.formattedprice.text
            con.img   = d.largeimage.url.text
            yield con

class SelectAmazon():
    def __init__(self,query,index="All"):
        data = list(Amazon().search(query,index=index))
        while True:
            for i,datum in enumerate(data):
                print("%s:%s" % (i,datum.title))
            try:
                put = int(input('番号を選択:'))
                break
            except:
                continue
        self.asin  = [datum.asin for datum in data][put]
        self.title = [datum.title for datum in data][put]
        self.url   = [datum.url for datum in data][put]
        self.price = [datum.price for datum in data][put]
        self.img = [datum.img for datum in data][put]
        self.amazonjs = [datum.amazonjs for datum in data][put]
        self.link  = [datum.link for datum in data][put]

def main():
    A = SelectAmazon(input("検索ワード："),index="All")
    webbrowser.open(A.url)

if __name__ == '__main__':
     main()

```
家に帰ると小林さんちのメイドラゴンのカンナちゃんが「おかえりー」って言ってくれる装置を作った

#動機
ねえ、カンナちゃん可愛すぎない？帰ってきておかえりって言ってくれたら最高じゃない？というわけで作った。
#使うもの
・人感センサー([SB412A](http://akizukidenshi.com/catalog/g/gM-09002/ "SB412A"))
・Raspberry Pi3
・ブレッドボード
・ジャンプワイヤー
・スピーカー(3.5mmプラグ)
#ライブラリインストール
mp3を再生するにはライブラリが必要なので再生するためのライブラリのmpg321をインストールする
```
sudo apt-get install mpg321
```
#配線
人感センサーをRaspberry PiのGND、5V、25ピンにそれぞれ繋ぐ
#音源
[11話のニコ動公式配信](http://www.nicovideo.jp/watch/1490166985 "11話のニコ動公式配信")から取ってきた(3分40秒付近)
okaeri.mp3という名前でpythonと同じディレクトリにおいておく
#コード
小林さんが書いてたPythonを使う。 
                    
```Python:okaeri.py
# -*- coding: utf-8 -*-
from __future__ import print_function
import socket
import commands
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(25, GPIO.IN)
from contextlib import closing

def main():

  while True:
    inputValue = GPIO.input(25)
    if (inputValue == True):
      okaeri()
    time.sleep(10)

def okaeri():
    print("おかえりー")
    #mp3再生コマンド実行
    check = commands.getoutput("mpg321 okaeri.mp3")

if __name__ == '__main__':
  main()
```

#動画
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">おかえりー <a href="https://t.co/Lmt4wQy5tw">pic.twitter.com/Lmt4wQy5tw</a></p>&mdash; tsumugu@暇人 (@tsumugu1515) <a href="https://twitter.com/tsumugu1515/status/847819334990807040">2017年3月31日</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

ニコ動にもあげた(宣伝)
[家に帰るとカンナちゃんが「おかえりー」って言ってくれる装置作った！](http://www.nicovideo.jp/watch/sm30924330 "家に帰るとカンナちゃんが「おかえりー」って言ってくれる装置作った！")

#参考
[RaspberryPiで人感センサーを作る](http://qiita.com/inaBowBow/items/dca01622d086f113db00 "RaspberryPiで人感センサーを作る")
【初心者投稿-13】年度末の多忙につきサボってました

#昨日までのおさらい
PHPに苦戦！からの２日間更新なし(勉強もしてなかった)
自分、普段は営業マンにつき年度末の数字に追われてました笑

もちろん、その間もノートで振り返ったりしてましたけど…笑

#明日から再スタート
PHPに負けずにとにかくやりきる！土日は幸運にも活動できそうです笑

最近、初心者でプログラミングを習得した方の記事とか読んでて感化されている笑

#学習の記録
* Progate11日目
* 今日の勉強時間：30分
* 総学習時間：12時間
* 今日嬉しかったこと：elseとかifとか英語かよ！って突っ込みたくなるような内容多くね！
pexpect, Expect.pm


手元から適当なサーバに `rsync` する例

## Expect.pm

```perl:sample.pl
#!/usr/bin/env perl
use strict ;
use warnings ;
use Expect
my $command = join " ",
    '/usr/bin/rsync -aqz',
    '/PATH/TO/from/',
    'foo@example.com:/PATH/TO/to/'
    ;
my $obj = new Expect;
$obj->spawn($command);
$obj->expect(1,$command);
$obj->send("PASSWD\n");
$obj->interact;
$obj->soft_close();
```

```shell-session:
$ perl sample.pl
```

## pexpect

インストールは手軽。

`python2.6` で適当なローカルディレクトリに入れたもの。 

```
$ pip install --install-option="--prefix=/PATH/TO" pexpect
```

```python:sample.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
sys.path.append( '/PATH/TO/lib/python2.6/site-packages')
import pexpect
command = " ".join([
    '/usr/bin/rsync -aqz',
    '/PATH/TO/from/',
    'foo@example.com:/PATH/TO/to/'
])
cmd = pexpect.spawn(command)
cmd.logfile = sys.stdout
cmd.expect(".assword:*")
cmd.sendline("PASSWD")
cmd.interact()
```

しかし、`cron` に乗っけようとすると `mode = tty.tcgetattr(self.STDIN_FILENO)` あたりでエラーになる。
回避方法もありそうな気もするが、`perl` 版の方は動くし、追いかける気もしないので、使わない。
Expect.pm のインストール


`cpan` が使えない、且つ、`plenv` 突っ込む程でもないときに、ソースからローカルに入れる[^1]。

[^1]: `CentOS` で、`perl-devel` が入ってないサーバにインストールするときには、心が折れて、`plenv` で突っ込んだ。もちろんルート権限持っていない。


## install

```
$ mkdir -p test/src
$ cd test/src
```
### IO::Stty

`Makefile.PL` がない。もちろん、`Module::Build` なんて入っていないサーバなので、`Makefile.PL` を作って対応する[^2]。

[^2]: もちろんソースをざっと見て、単純にインストール出来そうな事を確認の上で。

```
$ wget -q http://search.cpan.org/CPAN/authors/id/T/TO/TODDR/IO-Stty-0.03.tar.gz
$ touch Makefile.PL
$ cat Makefile.PL
use ExtUtils::MakeMaker;
WriteMakefile(
    'NAME'          => 'IO::Stty',
    'VERSION_FROM' => 'lib/IO/Stty.pm'
);
$ perl Makefile.PL INSTALL_BASE=$HOME/cmd
$ make
$ make install
```

### IO::Tty (IO::Pty)

```
$ wget -q http://search.cpan.org/CPAN/authors/id/T/TO/TODDR/IO-Tty-1.12.tar.gz
$ tar zxf IO-Tty-1.12.tar.gz
$ cd IO-Tty-1.12
$ perl Makefile.PL INSTALL_BASE=$HOME/cmd
$ make
$ make install
```
### Expect

```
$ wget -q http://search.cpan.org/CPAN/authors/id/S/SZ/SZABGAB/Expect-1.32.tar.gz
$ tar zxf Expect-1.32.tar.gz
$ cd Expect-1.32
$ perl Makefile.PL INSTALL_BASE=$HOME/cmd
$ make
$ make install
```
iOS10.3で変わったファイルシステムAPFSとは


##APFSとは

Apple File System (APFS)の略でよくあるファイルシステムのmac版(windowsでいうFAT32など)です。

##今までのファイルシステムとは何が違う？

今までのファイルシステムはHFS+というシステムでした。
iOS10.3から新しいシステムであるAPFSが導入されるのですが、
アップルによるとAPFSはSSDに最適化されたファイルシステムで、暗号化が強化されています。
そして、SSDに最適かされているためスピードが速くなるそうです！！

詳細はこちら
https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/APFS_Guide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40016999-CH1-DontLinkElementID_27

##デメリットは？？問題は出てないの？

情報が少ないですが。以下のような問題が出ているようなので開発者は注意が必要なようです。

・ファイル名がunicode正規化されない
（更新途中）
リストAに書かれた内容からリストBの各行を除いたものを取得する

# とい
リストAに書かれた内容からリストBの各行を除いたものを取得せよ。

# こたえ

```
$ cat A.txt
1111
2222
3333
4444
5555
$ cat B.txt
1111
3333
$ cat a.txt b.txt | sort | uniq -u
2222
4444
5555
```

uniqコマンドは重複行を削除するコマンド。
あえて重複させて`-u`オプションで除外してやればよい。
ただし、sortされていないといけないのでsortコマンドをはさむ。

| オプション        | 説明              |
|:-----------------|:------------------|
|  -u, --unique    |  重複行を削除する（ユニークな行だけ出力） |


# 参考

Linuxコマンド集 - 【 uniq 】 ソート済みのファイルから重複した行を削除する：ITpro http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230918/

uniq コマンド | コマンドの使い方(Linux) | hydroculのメモ https://hydrocul.github.io/wiki/commands/uniq.html
LINE Messaging APIのPush Messageを使ってみる


LINEのAPIでボットをつくるためにReplyMessageを使う例をよく見かけるのですが、PushMessageを使った例があまり見つからなかったので、メモとして残しておきます。

使用言語 : Python3.5

```python:app.py
import os
import requests
import json

LINE_CHANNEL_SECRET = os.getenv('LINE_CHANNEL_SECRET')
LINE_CHANNEL_ACCESS_TOKEN = os.getenv('LINE_CHANNEL_ACCESS_TOKEN')

def push_message():
    endpoint = 'https://api.line.me/v2/bot/message/push'
	
    header = {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer {' + LINE_CHANNEL_ACCESS_TOKEN + '}'
    }

    payload = {
        # toには32桁のuserIdをいれる。
        'to': 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
        'messages': [
            {
                'type': 'text',
                'text': 'Hello LINE'
            }
        ]
    }
    payload = json.dumps(payload)

    r = requests.post(url=endpoint, headers=header, data=payload)
    print(r.status_code)

if __name__ == '__main__':
    push_message()

```
[Swift3.0]Alamofire + SWXMLHash を使用してXMLをパースする。

備忘録。
XMLをURLから取得し、パースする。
以下公式リンク
[Alamofire](https://github.com/Alamofire/Alamofire)
[SWXMLHash](https://github.com/drmohundro/SWXMLHash)
##サンプル
~~~Swift
let url = "hogehoge.com"
        Alamofire.request(url).response{ response in
           let xml = SWXMLHash.parse(response.data!)
            print(xml["hoge"]["hoge"].element?.text)
        }
~~~
以上。
javascriptで設定できない税込価格を求める（その方法の検討）

## 設定できない税込価格

税込価格は一般的に、税抜価格*(1+税率)の小数点以下切り捨てになると思います。
この計算方法だと、例えば税率8%では税込価格13円は設定できません。無駄に忌み数。

```js
Math.floor(12 * 1.08)
// 12
Math.floor(13 * 1.08)
// 14
```

なので、そういった数をどーしても税込価格にしたい場合は特別な配慮が必要になります。桁丸め方法を変えると別の数が使えなくなるので、統一するのも難しい。

自分はDBに入れる時に税抜き額と税額を入れるようにしました。一応逆算もできるし、桁丸め方法も求めることはできる。入力は税抜きでも税込みでも、DBに入れる前に計算して出してやればいいので。

まぁこういうのがどれくらいあって、どれくらい使いそうな数字で出てくるか気になったので出してみることにしました。

## コード

以下をchromeのコンソールに入れて呼び出す。

```js
getInvalidIncludeTaxPrices = (taxRate=1.08, i=1, max=100000, interval=1000) => {
	n = Math.floor(i*taxRate)
	array = []
	while(n < max){
    	i = i + 1
		m = Math.floor(i*taxRate)
		b = m - n > 1 && (m-1) % interval === 0
		n = m
	
    	if(b){
        	array.push(m-1)
		}
	}
	return array
}
```

結果

```
getInvalidIncludeTaxPrices()
// [13000, 26000, 40000, 53000, 67000, 80000, 94000]
```

消費増税

```
getInvalidIncludeTaxPrices(1.1, 1, 100, 1)
// [10, 21, 32, 43, 54, 65, 76, 87, 98]
```

うまい棒どうすんのか気になります。
あと法則性もありそうな。数列として式に書けるんだろうか……。

## もう少しうまく書けないか

arrow functions と default parameters を使えてホクホクといった感じですが……
とりあえず普通のfor文は使ってなさすぎて書式を忘れた。do-whileは合いそうな気もしますがまぁやらないとします。

### 再帰で書けないか

まず再帰で書けないかと反射的に思いますが、回数的にStackOverflowになるのが見える。
末尾再帰最適化があればいいんですが

[末尾再帰による最適化 - Qiita](http://qiita.com/pebblip/items/cf8d3230969b2f6b3132#javascript%E3%81%A7%E3%81%AE%E6%9C%AB%E5%B0%BE%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%97%E6%9C%80%E9%81%A9%E5%8C%96 "末尾再帰による最適化 - Qiita")

まだブラウザが対応してないらしい。

### 関数型っぽく書けないか

`Range(1,100).map(() => {...})`みたいなの。今っぽい。フリーランチが終わって結構経つしマルチスレッドでパラレルだ！
しかしながら、これは昨日書いた通り最初に全部展開してしまうため、判定する数が多くなってくるとメモリを大食いしそうに見えます。

[javascript iteratorのnext呼び出しタイミング - Qiita](http://qiita.com/thrakt/items/5a100c219e4bc8677e9a "javascript iteratorのnext呼び出しタイミング - Qiita")

結局普通のfor文じゃないかという感じになりました。

じゃあまぁ普通のwhileでいいかな。

## chromeのconsoleが便利

ES6のおかげで色々楽に書けるようになっています。ちょっとした処理をするのに便利。ブラウザがあれば
Googleスプレッドシートとかでも同じ物を求められますが、ちょっとめんどくさそう。
javascriptならGASも使えるし、ポテンシャルあるなぁと改めて思いました。
gradlewから任意のユニットテストを実行する

昔からどうやるんだろう :thinking:  と思ってたんですがググったらStackOverFlowがヒットした。

[Running a specific unit test with gradle
](http://stackoverflow.com/questions/19565857/running-a-specific-unit-test-with-gradle)

ユニットテストの場合以下のようになる。

```
./gradlew {YourModule}:test{BuildVariant}UnitTest --tests "*{ClassName}.{MethodName}"
```

`--tests` の引数を `*{ClassName}`に変えるとクラス全体が実行される。 単なる正規表現でのマッチなので `"*{MethodName}"` だけでも問題ない。

インストルメントテストの場合こう書くらしい。こちらはまだ試してない

```
gradle -DconnectedInstrumentTest.single=UnitTestName connectedInstrumentTest
```


[追記]
公式のドキュメントにも記載を見つけることが出来た。
http://gradle.monochromeroad.com/docs/userguide/java_plugin.html
AWSのS3で静的サイトをホスティングしてみた。

AWSのS3で静的サイトをホスティングしたので、気づいたことを自分用にメモしておく。

##S3とは
Amazon S3 は、インターネット用のクラウドストレージ。
参考にしたURL
http://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/WebsiteHosting.html


##手順
1.AWSのコンソールにサインインして、s3のバケットを作成する。
→ココから https://console.aws.amazon.com/s3/
参考：http://docs.aws.amazon.com/ja_jp/AmazonS3/latest/user-guide/create-bucket.html
・バケット名は独自ドメインと同じにする。
・リージョンは現在地に近い場所、例：Tokyo



2.静的webサイトとしてバケットを設定
a.バケットの [Properties] パネルで [Static Website Hosting] をクリック
b.[Enable website hosting] を選択
c.[Index Document] ボックスにindex.htmlを追加

3.アクセス権限の設定
a.バケットの [Properties] ペインの [Permissions] をクリック
b.[Add Bucket Policy] をクリック
c.下のバケットポリシーをコピーし、Bucket Policy Editor に貼り付け
※example-bucketは、自分のバケット名と置き換え。

```
{
  "Version":"2012-10-17",
  "Statement":[{
	"Sid":"PublicReadForGetBucketObjects",
        "Effect":"Allow",
	  "Principal": "*",
      "Action":["s3:GetObject"],
      "Resource":["arn:aws:s3:::example-bucket/*"
      ]
    }
  ]
}
```

4.index.htmlをアップロード
a.https://console.aws.amazon.com/s3/にアクセス、[Bucket name] リストで、オブジェクトのアップロード先のバケットの名前を選択
b.[Upload] を選択します。
c.ローカルにindex.htmlとテストファイルを作成し、uplload。
※バケットが空の場合、[Get started] または [Upload] を選択できる。
参考：http://docs.aws.amazon.com/ja_jp/AmazonS3/latest/user-guide/upload-objects.html
symfony 1.4 メモ（モデル）

1. [symfony 1.4 メモ（アクション）](https://qiita.com/shotets/items/dd56c98d397a42fa4f50)
2. [symfony 1.4 メモ（context）](https://qiita.com/shotets/items/ffa0baa3f930d8992dcb)
3. **symfony 1.4 メモ（モデル）**
4. [symfony 1.4 メモ（schemaの書き方）](https://qiita.com/shotets/items/f55d9e625c78bb8f05e6)
5. [symfony 1.4 メモ（Doctrine）](https://qiita.com/shotets/items/e7638a72fa90c687ab81)
6. [symfony 1.4 メモ（フォーム）](https://qiita.com/shotets/items/8343167452d42d67b93e)
7. [symfony 1.4 メモ（コマンド）](https://qiita.com/shotets/items/82d1f9f8d00f25e65197)
8. [symfony 1.4 メモ（ユーティリティ）](https://qiita.com/shotets/items/ca32b99e43badfe53f98)

## モデルClassの継承

```:Classの継承
Model > BaseModel > sfDoctrineRecord > Doctrine_Record > Doctrine_Record_Abstract > Doctrine_Access > Doctrine_Locator_Injectable ...
```

`ProjectConfiguration` にて Dctrine のオプションを変更することができる。
そのうちの `baseClassName` を使えばオリジナルのモデルClassを承継に組み込むことができる。

```php:ProjectConfiguration.class.php
class ProjectConfiguration extends sfProjectConfiguration
{
	public function setup()
	{
		$this->enablePlugins('sfDoctrinePlugin');
	}
	
	public function configureDoctrine(Doctrine_Manager $manager)
	{
		$manager->setAttribute(Doctrine_Core::ATTR_USE_DQL_CALLBACKS, true);
		$manager->setAttribute(Doctrine_Core::ATTR_AUTO_ACCESSOR_OVERRIDE, false);
		sfConfig::set
		(
			'doctrine_model_builder_options',
			array
			(
				'baseClassName' => 'originalDoctrineRecord',
			)
		);
	}
}
```

```:Classの継承
Model > BaseModel > originalDoctrineRecord > sfDoctrineRecord > Doctrine_Record > Doctrine_Record_Abstract > Doctrine_Access > Doctrine_Locator_Injectable ...
```

ちなみにデフォルトの Dctrine のオプション設定は以下

```php
'generateBaseClasses'  => true,					// 基底クラスを生成するかどうか
'generateTableClasses' => true,					// テーブルクラスを生成するかどうか
'packagesPrefix'       => 'Plugin',
'suffix'               => '.class.php',			// 生成クラス用に使うサフィックス
'baseClassesDirectory' => 'base',				// 基底クラスを生成するディレクトリ
'baseClassName'        => 'sfDoctrineRecord',	// モデルが継承するスーパークラス
```

## ビヘイビア

schema ファイルで actAs を定義しているモデルは
自動的に以下の機能を有している。

### Timestampable:
自動的にcreated_atとupdated_atフィールドが生成され、
生成時、更新時にそれぞれ自動更新される。

### SoftDelete:
自動的にdeleted_atフィールドが生成され、deleteメソッドを使って削除すると日付が入り、論理削除される。
論理削除されたデータは問い合わせてもヒットしない。

オリジナルのビヘイビアも設定可能

```yaml:schema.yml
ModelName:
  actAs:
    Timestampable:      ~
    SoftDelete:         ~
    originalBasicModelTemplate: ~
```

## デフォルトで用意されているメソッド

```php
// プロパティを追加できる。
$this->mapValue('updater');

// そのオブジェクトが新規か更新かを判別できる。
$this->isNew()

// 更新されたフィールドがあるかどうか。
$this->isModified()

// イベントの前後に処理を追加したいときに使う。
$this->preSave($event)
$this->postSave($event)
$this->preDelete($event)
$this->postDelete($event)
$this->preUpdate($event)
$this->postUpdate($event)
$this->preInsert($event)
$this->postInsert($event)

// モデルのプロパティを配列にしたものを取得する。
$this->toArray($deep = true, $prefixKey = false)

// 配列でモデルのプロパティを更新する。
$this->fromArray(array $array, $deep = true)

// モデルをtypeで指定した形式にしたものを取得する。type: array, xml, yml, json
$this->exportTo($type, $deep = true)

// typeで指定した形式のデータでモデルのプロパティを更新する。
$this->importFrom($type, $data, $deep = true)

// メモリ解放。
$this->free()
AWS del ami/snapshot 

#via ssm (bash)
```shell:
export list=$(aws ec2 describe-images --owner self --query 'Images[][ImageId]' --output text | xargs)

for i in ${list[@]}
do
  aws ssm start-automation-execution --document-name AWS-DeleteImage --parameters ImageId=$i
done

```

tag:Name filter `--filter "Name=tag:Name,Values=xxxx-001"`


#via boto3

```shell:
./list-ami.py > list
./del-ami.py < list
```

```python:list-ami.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import boto3
import sys

client = boto3.client('ec2')


def _list_ami():

    _filters = [
        {'Name': 'tag-key', 'Values': ['hoge']},
        {'Name': 'tag-value', 'Values': ['fuga']}
        ]

    ret = client.describe_images(
        Filters=_filters
    )

    # pirnt snapshot
    for img in ret['Images']:
        print img['ImageId']

def main():
    _list_ami()


if __name__ == '__main__':
    main()

```

```python:del-ami.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import boto3
import sys

client = boto3.client('ec2')


def _del_ami(ami_id):
    ret = client.describe_images(ImageIds=[ami_id])

    # deregister_ami
    print "del-ami : " + ami_id
    client.deregister_image(ImageId=ami_id)

    # delete snapshot
    for snap in ret['Images'][0]['BlockDeviceMappings']:
        if 'Ebs' in snap:
            print "del-snap: " + snap['Ebs']['SnapshotId']
            client.delete_snapshot(SnapshotId=snap['Ebs']['SnapshotId'])


def main():
    for line in sys.stdin:
        _del_ami(line.rstrip())


if __name__ == '__main__':
    main()


```
「GenerarizedNewTypeDerivingで自分用Monadを作る」ってなに！？（具体例編）

# この記事の目的
　現在おそらくまだ、主流なMonadインスタンスの作り方である、GenerarizedNewTypeDerivingを用いた方法の理解の手助け。
軽く検索した限り、本記事タイトルについての具体例が（わかりやすさ特化な例はありましたが、具体特化の例は）見つからなかったので、紹介してみます。

あと、Monadを作ることの楽しさの布教。

　GenerarizedNewTypeDeriving拡張を学ぶ筋道と、実例を示します！


# そもそもGenerarizedNewTypeDerivingとは？
　Haskellのnewtypeは、元となる型と（圏論的な）同型を作るキーワードです。
（値構築子と、パターンマッチの解凍 もしくは レコードの関数、を同型射とした同型。間違ってたら教えてください ＞＜）

つまりは「元となる型ができることはnewtypeで作る型もできる」ってことなのですが、newtypeがstrong typedefであるが故に、型クラスの情報をnewtypeは忘れ去ってしまいます。
その情報を思い出させるのが`GenerarizedNewTypeDeriving`拡張です！

- strong typedef とは？ ==> [本の虫: C++1yに提案されている不透明エイリアス(opaque alias)](https://cpplover.blogspot.jp/2013/09/c1yopaque-alias.html)

　具体的には、以下を可能にします。

```haskell
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}

import Data.String (IsString)
import Data.Text (Text)
import qualified Data.Text.IO as TIO

newtype MyString = MyString { unMyString :: Text }
  deriving (IsString)  -- GenerarizedNewTypeDerivingがないと、ここを書けない

txt :: MyString
txt = "アホ毛"

main :: IO ()
main = TIO.putStrLn . unMyString $ txt
```


# 実際どのように、自分用Monadを作るのか？
　これについては、こちらがわかりやすいかなと思います。

- [モナドの実装いろいろ - Qiita](http://qiita.com/philopon/items/6c202200e266548275ea)


# 具体例
　さて本題ですが、今回僕が作ったものは
ログと、構文上のブロックのネスト数という状態を保持した、不純なパーサです。

実際使っているプロジェクトはここにあります（ただしWIP）

- [aiya000/eliningen - GitHub](https://github.com/aiya000/eliningen)

~~まあ…不純なパーサは個人的には好ましくないとは思いますが……。~~

~~ここは言い訳なので読まないで良いんですが
なぜ良くないと思うのにParsecTをMonadStateとして使ったのかというと、パースログを取りたかったんですよね。
でもmegaparsecのParsecTはMonadWriterではなかったので、MonadStateを使おうということに決めました。 苦し紛れ。
そしたらやっぱり、状態も使いたいじゃないですか。 めっちゃ見やすくしたくなった。
ということで使いました……。
実際はログへのみの副作用として状態が使われています。
状態を読み出してパース結果に影響を与えたりしてないので、セーフセーフ！！~~

```haskell
-- | Current state of ElinParser
data ElinState = ElinState
  { _parseLogs      :: [ParseLog]
  , _parseNestLevel :: Int
  } deriving (Show)

-- | Parser with parsing logs
newtype ElinParser a = ElinParser { _runElinParser :: ParsecT Dec Text (State ElinState) a }
  deriving ( Functor, Applicative, Monad
           , Alternative, MonadPlus
           , MonadState ElinState, MonadParsec Dec Text
           )

-- | A log of ElinParser
data ParseLog = Message Text     -- ^ Simple message
              | ParsedItem Text  -- ^ Ex: '(', ''', ')' or some symbol
  deriving (Show)

-- | Run parser and extract result and logs
runElinParser :: ElinParser a -> Text -> (Either (ParseError Token Dec) a, [ParseLog])
runElinParser parser source =
  let initialState = ElinState [] 0
      bareness     = _runElinParser parser
      (result, ElinState logs _) = flip runState initialState $ runParserT bareness "" source
  in (result, reverse logs)
```

`ElinParser a`は

- ElinStateという状態を持ち
- Textを食べる

というパーサです。  
ElinStateは後にmakeLensesされます。


# おわり
　Operationalモナドも使ってみたいんですが、まだ使ったことないんですよね〜。

- [Freeモナドを超えた！？operationalモナドを使ってみよう - モナドとわたしとコモナド](http://fumieval.hatenablog.com/entry/2013/05/09/223604)
:remoteを利用してセレクトボックスを動的に描画する

# 【実現出来ること】
* 親子関係にあるセレクトボックスがあるとき、親のセレクトボックスの値で、子のセレクトボックスの選択肢を動的に制御する
* railsの"remote"の仕組みを利用する

[![https://gyazo.com/9a21c3e3b6c2b1656a8fb9903507b9cd](https://i.gyazo.com/9a21c3e3b6c2b1656a8fb9903507b9cd.gif)](https://gyazo.com/9a21c3e3b6c2b1656a8fb9903507b9cd)

# 【やり方】 
## 環境
* rails 5

## モデル・テーブルデータ

* usersテーブルはid, color_id, vegetable_idカラムを持つ
	
	| id 	| name 	| color_id 	| vegetable_id 	|
	|----	|------	|----------	|--------------	|
	|    	|      	|          	|              	|

* colorsテーブルはid, nameカラムを持つ

	| id 	| name 	|
	|----	|------	|
	| 1  	| 緑   	|
	| 2  	| 黄   	|
	| 3  	| 青   	|

* vegetablesテーブルはid, name, color_idカラムを持つ

	| id 	| name 	| color_id 	|
	|----	|------	|----------	|
	|  1  	|   キャベツ   	|      1    	|
	|  2  	|   ほうれん草   	|    1      	|
	|  3  	|   小松菜   	|         1 	|
	|  4  	|   バナナ   	|        2  	|
	|  5  	|   レモン   	|       2   	|
	|  6  	|    トウモロコシ  	|    2      	|
	|  7  	|    人参  	|       3   	|
	|  8  	|   トマト   	|     3     	|
	|  9  	|    唐辛子  	|      3    	|


## コード

* ルーティング

```config/routes.rb
Rails.application.routes.draw do
  resources :users
  
  # selectからremote: trueでpostされるデータを受け取り、getで描画するための準備
  match 'dynamic_vegetable', to: 'users#dynamic_vegetable', via: [:get, :post]
end
```
* view

```app/views/users/new.html.erb
<%= form_for(@user, url: {action: :create}) do |f| %>

<!-- remote: trueを追加することでajaxでparams[:user][color_id]をpostできる -->
<div>
  <%= f.select :color_id, options_from_collection_for_select( @color, :id, :name),
  {prompt: '野菜の色を選択'}, {data: {remote: true, url: url_for(action: :dynamic_vegetable)}} %>
</div>

<!-- 色を選択するとここに動的にセレクトボックスが描画される -->
<div id="vegetable-select">
  野菜
</div>

<%= f.submit '登録', name: 'commit' %>

<% end %>

```
* コントローラ

```app/controllers/users_controller.rb
def new
  @user = User.new
  @color = Color.all
end

def dynamic_vegetable
  # vegetablesをcolor_idで絞り込んで取得する。
  @vegetable = Vegetable.where(color_id: params[:user][:color_id])
end
```
* セレクトボックスを動的に描画するためのview

```app/views/users/dynamic_vegetable.js.erb
// 受け取った@vegetableを元にselectボックスを描画する
$('#vegetable-select').html(
  "<%= j(select :user, :vegetable_id, options_from_collection_for_select(@vegetable, :id, :name)) %>"
);
```


## 解説

* viewでselectにremote: trueを設定する。これにより、選択した時にparams[:user][:color_id]が指定のurlにpostされる。このparamsを後のコントローラのアクションで使うことが出来る。
* ajaxのpostでを受け取ってアクションに流すためのルーティングを追加する。
	* 「 match 'dynamic_vegetable', to: 'users#dynamic_vegetable', via: [:get, :post]」
* コントローラに、postでうけとったparamsのcolor_idに基づいて@vegetableを取得するアクションを追加する
* js.erbファイルを用意して、@vegetableに基づいてセレクトボックスを描画するコードを書く。セレクタで指定した箇所のみが部分的に更新され描画される。



# メモ
* これぐらいのデータ数であれば、Color.all, Vegetable.allを一度のリクエストで全部JSONで渡し、ローカルでjavascriptを書いた方が早い
* データ数が多量（1000以上？）なら、ajaxで都度リクエストした方がよい。
* remote使わずに、javascriptでajax書いて、JSONを返すアクションを書いて実装することは可能だけど、個人的には、今回紹介した様に、remoteで書いた方がコードの見通しが良くなる気がするので好き。
charttick Rails


1. Gemfile

```
$ bundle install
```


以下の内容を追加

```rb:Gemfile
gem "chartkick"
```

2. application.html.erb

JavaScriptのloadスクリプトの追加

```applicatoin.html.erb
<%= javascript_include_tag "//www.google.com/jsapi", "chartkick" %>
```

3. 円グラフの追加

円グラフの表示

```erb
<%= pie_chart [["Football", 10], ["Basketball", 5]] %>
```

SQLite3で日付ごとに表示する方法
[ActiveRecord4での集計をいろいろまとめた | | Scimpr Blog](https://blog.scimpr.com/2015/04/25/activerecord4%E3%81%A7%E3%81%AE%E9%9B%86%E8%A8%88%E3%82%92%E3%81%84%E3%82%8D%E3%81%84%E3%82%8D%E3%81%BE%E3%81%A8%E3%82%81%E3%81%9F/#i-3)
Swift3.0におけるアラート制御

iOS　7まではUIAlertViewを利用してアラート制御をしていたのですが,iOS 8からはUIAlertControllerを利用してアラート制御することが推奨されています。

UIAlertControllerを使ってどのようにアラート制御するのか整理しました。
<h2>開発環境</h2>
*Xcode Ver 8.2.1-*
*Swift 3.0*
*iOS 10.2*
*iPhone 7 Plus Simulator*

<h2>UIAlertController実装の手順</h2>

実装の手順をコードだけでなく,図でも表しましたので参考にして下さい。
![処理手順の画像](https://qiita-image-store.s3.amazonaws.com/0/145535/8d3a0e9e-fe7b-c989-1e19-96b7315fb555.jpeg "UIAlertControllerの実装イメージ図")

 <dt>1.UIAlertControllerの作成</dt>
  <dd>アラートを構成するボタンやテキストボックスを入れる入れ物を構築します。UIAlertControllerを作成するコードは以下です。</dd>
  <dd>```let コントローラー名 = UIAlertController(title: "アラートのタイトル",message: "アラートの説明", preferredStyle: UIAlertControllerStyle.alert)```</dd>
 <dt>2.アラートの部品の作成</dt>
  <dd>アラートを構成する部品を作成します。主に,OKボタンやCANCELボタン,テキストボックスなどです。また,自分オリジナルの部品を作成することもできます。部品を作成するコードは以下です。</dd>
  <dd>```let 部品名 = UIAlertAction(title: "部品名", style:UIAlertActionStyle.default){ 
(action: UIAlertAction) in
//            以下はボタンがクリックされた時の処理
　　　　　　　　　　　　print("Hello")
        }```</dd>
 <dd>この時,UIAlertAction.defaultの.defaultを.cancelなどに変えることで,キャンセルボタンを実装できます。</dd>
<dt>3.部品をUIAlertControllerに追加</dt>
 <dd>1で作成した入れ物(コントローラー)に部品を追加していきます。追加するコードは以下です。</dd>
  <dd>```コントローラー名.addAction(部品名)```</dd>
<dt>4.アプリにアラートを表示させる</dt>
 <dd>最後は今まで作成した入れ物(コントローラー)をアプリに表示させる動作です。</dd>
  <dd>```present(コントローラー名,animated: true, completion: nil)```</dd>

<h2>サンプルコード</h2>
```swift:ViewController.swift
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
//    アラートボタンがクリックされた時の実装
    @IBAction func tapAlertButton(_ sender: Any) {
//        ① コントローラーの実装
        let alertController = UIAlertController(title: "test",message: "アラートボタン", preferredStyle: UIAlertControllerStyle.alert)
        
//        ②-1 OKボタンの実装
        let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default){ (action: UIAlertAction) in
//        ②-2 OKがクリックされた時の処理
            print("Hello")
        }
//        CANCELボタンの実装
        let cancelButton = UIAlertAction(title: "CANCEL", style: UIAlertActionStyle.cancel, handler: nil)
        
//        ③-1 ボタンに追加
        alertController.addAction(okAction)
//        ③-2 CANCELボタンの追加
        alertController.addAction(cancelButton)
        
//        ④ アラートの表示
        present(alertController,animated: true,completion: nil)
    }
}

```
<h2>実行結果</h2>
実行結果は以下のようになります。

<img width="414" alt="Simulator Screen Shot 2017.03.31 20.09.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/145535/348389c6-e583-b6ee-4b9c-28071f1c69e1.png">

以上,Swift3.0でアラートを制御する方法でした。
Azure Media Servicesの導入編

#Media Servicesを作成します。

※Microsoft Azureアカウントは取得済み前提としています。

###◎まずはMicrosoft Azureにログインします。
 ※Azureダッシュボード画面 2017年3月31日現在

###◎Microsoft Azure画面左側の[新規]をクリックします。
![2017-03-31_16h12_00.png](https://qiita-image-store.s3.amazonaws.com/0/93051/3622d3aa-525f-4e99-f95d-82746262356e.png)

###◎検索ボックス内に[media services]と入力するか、下の赤枠の[Web+モバイル]をクリックします。
![2017-03-31_16h12_39.png](https://qiita-image-store.s3.amazonaws.com/0/93051/46462fc9-07b9-9749-a628-7e4e933c653d.png)

###◎[Media Services]をクリックします。
![2017-03-31_16h13_12.png](https://qiita-image-store.s3.amazonaws.com/0/93051/fa2cf781-37c2-0f4b-ef63-7394eed7a517.png)


###◎必須項目を記入していきます。
![2017-03-31_16h13_42.png](https://qiita-image-store.s3.amazonaws.com/0/93051/4b8e88bf-8957-0fbf-855f-a4221e9c3d30.png)

###◎アカウント名を入力します。
![2017-03-31_16h15_29.png](https://qiita-image-store.s3.amazonaws.com/0/93051/e3e43135-db76-59de-06ca-b3278b7dcd6e.png)

###◎サブスクリプションはデフォルトのままで
![2017-03-31_16h15_36.png](https://qiita-image-store.s3.amazonaws.com/0/93051/0c025ada-8776-48eb-bfab-db098006d2cc.png)

###◎リソースグループ、新規作成にチェックを入れて、リソースグループ名を入力します。
![2017-03-31_16h15_41.png](https://qiita-image-store.s3.amazonaws.com/0/93051/131699f3-2401-10d5-bd51-a6392ff07903.png)

###◎リージョンの場所は、ご自由に
![2017-03-31_16h15_48.png](https://qiita-image-store.s3.amazonaws.com/0/93051/29a615ce-343e-bc94-7bdc-930c0bdf502b.png)

###◎ストレージアカウントの作成をします。
![2017-03-31_16h15_54.png](https://qiita-image-store.s3.amazonaws.com/0/93051/a5db41dc-9d14-198e-1aee-0177730db0df.png)

###◎新規作成を選びます。
![2017-03-31_16h16_02.png](https://qiita-image-store.s3.amazonaws.com/0/93051/7c454cef-75da-9360-b220-453b550fa8f8.png)

###◎ストレージの名前を入力する。
[パフォーマンス]はデフォルトのままで[レプリケーション]も**とりあえず**デフォルトのままで
![2017-03-31_16h16_13.png](https://qiita-image-store.s3.amazonaws.com/0/93051/fff4efb5-b7a4-6c35-a476-a52f58f10cc0.png)

###◎[OK]をクリックします。
![2017-03-31_16h16_18.png](https://qiita-image-store.s3.amazonaws.com/0/93051/00649af8-fcb0-67b7-13ed-1ba4463d2171.png)

###◎必要事項を入力出来た状態です。
![2017-03-31_16h17_08.png](https://qiita-image-store.s3.amazonaws.com/0/93051/635b2604-bac4-bfdc-49dc-ab2ac6c65045.png)

###◎最後に、[作成]ボタンをクリックします。
　※[ダッシュボードにピン留めする]にチェックを入れておきます。
![2017-03-31_16h17_13.png](https://qiita-image-store.s3.amazonaws.com/0/93051/30974825-1ab4-0b00-499e-a550752ca902.png)

###◎ダッシュボード画面に、作成中のアイコンが表示されます。
数分でデプロイ完了します。
![2017-03-31_16h17_59.png](https://qiita-image-store.s3.amazonaws.com/0/93051/4e259ed1-4277-8e33-ae61-1f84aabf776a.png)

###◎Media Servicesの作成されるとダッシュボードに表示されます。
これで完成！なんて簡単なんだ・・・
![2017-03-31_16h25_50.png](https://qiita-image-store.s3.amazonaws.com/0/93051/b9683b32-60d5-34c2-5574-5183e6e54c8f.png)

###◎ダッシュボードに作成された[Media Services]をクリックすると概要画面が表示されます。
![2017-03-31_16h27_03.png](https://qiita-image-store.s3.amazonaws.com/0/93051/7a213930-618b-1973-1b08-65584d59550b.png)

これで、Azure Media Servicesの導入が完了しました。
とりあえず作成してみた用です。
symfony 1.4 メモ（アクション）

今さら symfony 1.4 と言われそうですが、まだ稼働しているアプリがあるので、自分用のメモ書きです。

1. **symfony 1.4 メモ（アクション）**
2. [symfony 1.4 メモ（context）](https://qiita.com/shotets/items/ffa0baa3f930d8992dcb)
3. [symfony 1.4 メモ（モデル）](https://qiita.com/shotets/items/535204c3e7ad1decdab4)
4. [symfony 1.4 メモ（schemaの書き方）](https://qiita.com/shotets/items/f55d9e625c78bb8f05e6)
5. [symfony 1.4 メモ（Doctrine）](https://qiita.com/shotets/items/e7638a72fa90c687ab81)
6. [symfony 1.4 メモ（フォーム）](https://qiita.com/shotets/items/8343167452d42d67b93e)
7. [symfony 1.4 メモ（コマンド）](https://qiita.com/shotets/items/82d1f9f8d00f25e65197)
8. [symfony 1.4 メモ（ユーティリティ）](https://qiita.com/shotets/items/ca32b99e43badfe53f98)


## アクションの継承

```
moduleActions > autoModuleActions > sfActions > sfAction > sfComponent
```

Adminジェネレータで生成するとcacheフォルダにアクション（autoModuleActions）やテンプレートが生成される。
追加したいアクションや上書きしたいアクションについて、モジュールアクションやモジュールテンプレートを追加する。

### generatorのカスタマイズ

`/data/generator/sfDoctrineModule/default` に `autoModuleActions` のテンプレートが入っている。
オリジナルのテンプレートを作り、モジュール毎の `generator.yml` に作成したテーマを指定すれば
オリジナルのテンプレートで `autoModuleActions` を作れる。

`sfDoctrineGenerator` を継承するオリジナルのgeneratorクラスを作っておけば
generate時の振る舞いもカスタマイズできる。

```yaml:generator.yml
generator:
  class: originalDoctrineGenerator
  param:
    model_class:           ModelClassName
    theme:                 original_admin_theme
```


autoModuleActions の継承元を変更しておけば
全アクション共通の処理が書けるアクションClassを作ることができる。

継承を追加した場合

```
moduleActions > autoModuleActions > オリジナルActions > sfActions > sfAction > sfComponent
```

generateコマンド

```bash
php symfony doctrine:generate-admin app_name module_name
```

## デフォルトで用意されているアクションのメソッド

```php
// モジュール名を返す。
$this->getModuleName()

// アクション名を返す。
$this->getActionName()

// contextを取得する。
$this->getContext()

// ブラウザ入力、フォーム入力を取得する。
$this->getRequest()

// ヘッダー情報やステータス情報などを取得する。
$this->getResponse()

// セッション情報（userオブジェクト）を取得する。
$this->getUser()

// モジュールとアクション名でのforward。
$this->forward($module, $action)

// URLによるリダイレクト。ルーティングでのリダイレクトも可能。
$this->redirect($url, $statusCode = 302)

// プレーンなテキストを出力する。Ajax処理の出力に使える。
$this->renderText($text)

// テンプレートの指定。
$this->setTemplate($name, $module = null)

// レイアウトの指定。
$this->setLayout($name)
```


## マジックメソッド

アクションclass内では特にプロパティーの宣言をしなくともプロパティを自由に追加できる。

例えば、以下のように値を代入すると、テンプレート上でもその値を使うことができる。smartyのアサインのような定義も不要。

①アクション上でプロパティ宣言していないfooに値を設定。

```php
$this->foo = "test";
```

②テンプレート上で$fooが使える。

```php
echo $foo;
```
GoogleMapsAPIで地図上に画像とテキストを設置してみた

GoogleMapsAPIを触ってみたいと思い、公式サイトを見ながら地図上にいろんなものを表示させて遊んでみました。

今回はその中から、地図上に任意の画像とテキストを設置する方法を紹介したいと思います。

## GoogleMapsAPIとは

Google Maps APIは、2005年2月にリリースされたGoogleマップのAPIです。

高機能なGoogleマップをwebサイトやアプリで使うことができ、地図上で様々な表現を行うことが可能です。

## 地図上に任意の画像とテキストを設置する方法
今回は下の写真のように地図上の任意の場所にマーカーを設置し、mouseoverすると任意の画像とテキストが表示されるという動きを作ってみたいと思います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/146968/223bfff6-c5a3-a3c0-ea7f-cdff2060986f.png)


このような描写を再現するには、[情報ウィンドウ](https://developers.google.com/maps/documentation/javascript/infowindows?hl=ja)という機能を使います。
まずはGoogleMapAPIを利用するために下記のscriptを読み込ませます。

```
<script src="http://maps.google.com/maps/api/js?sensor=true"></script>
```

※GoogleMapsAPIをサーバ上で動かす場合は、APIkeyが必要になります。APIKeyの取得方法は下記でご確認下さい。
参考：[Google Maps の APIキー を簡単に取得する](https://nendeb.com/276)

次はhtmlの記述。マップを表示したい場所をdivで囲みます。

```html
<div id="map"></div>
```

width、heightを指定してあげないとマップが表示されないので、cssも記述。

```css
#map {
  width: 600px;
  height: 400px;
}
```

下準備が終わったら、ここからマップを表示するためのscriptを記述していきます。
コードの内容はコメントアウト文を参考にして下さい。

``` javascript
var map = null;
var infowindow = new google.maps.InfoWindow();

function init() {
  
  //マップの初期状態を設定
  var option = {
  zoom: 6,
  center: new google.maps.LatLng(35.4093320, 136.7566470),
  mapTypeId: google.maps.MapTypeId.ROADMAP,
  disableDefaultUI: true
  };
　
  // 吹き出しを閉じる処理
  map = new google.maps.Map(document.getElementById("map"), option);
  google.maps.event.addListener(map, "click", function() {infowindow.close();});

  // 任意の位置にマーカーを追加
  var point = new google.maps.LatLng(35.673264, 139.760668);
  var marker = create_maker(point, "info", "<img src='画像パス' /><br><p>テキスト</p>");

  var point = new google.maps.LatLng(34.6545182, 135.4289645);
  var marker = create_maker(point, "info", "<img src='画像パス' /><br><p>テキスト</p>");

  var point = new google.maps.LatLng(35.1709150, 136.8815369);
  var marker = create_maker(point, "info", "<img src='画像パス' /><br><p>テキスト</p>");
}

function create_maker(latlng, label, html) {
  // マーカーを生成
  var marker = new google.maps.Marker({position: latlng, map: map, title: label});
  // マーカーをマウスオーバーした時の処理
  google.maps.event.addListener(marker, "mouseover", function() {
  infowindow.setContent(html);
  infowindow.open(map, marker);
  });
}

google.maps.event.addDomListener(window, "load", init);
```

##まとめ
簡単になりますが、上記のような記述でGoogleMapAPIを用いて地図上に画像とテキストを設置することができました。
コンテンツ内に地図を用いたいケースは多々あると思うので、GoogleMapAPIで様々な表現をする手段を勉強していきたいと思います。