OmniAICreator/Qiita-1.07M huggingface dataset:
AWS Lambda (Python) でログレベルを環境変数から注入

```python:lambda_function.py
import logging
import os

logger = logging.getLogger(__name__)
logger.setLevel(os.getenv('LOG_LEVEL', 'WARNING'))

def lambda_handler(event, context):
    logger.debug('debug')
    logger.info('info')
    logger.warning('warning')
    logger.error('error')
    logger.critical('critical')
```

環境変数`LOG_LEVEL`を変える（DEBUGやINFOなど）とそのレベル以上のメッセージが出力され、何も設定していないと`WARNING`が設定される.
`logging.setLevel()`の引数に文字列が入れられるのがミソの模様.
[ メモ ] laravel Authファサード ログイン情報を取得

#オートログイン（auto login）

オートログインとは、
認証するための情報を事前に設定しておくことで自動でログインすることが出来る
laravelでは、この機能が標準で実装されている:grinning:

#使い方

```
use Illuminate\Support\Facades\Auth;

// 現在ログインしているユーザーの取得
$user = Auth::user();

// 現在ログインしているユーザーのID取得
$id = Auth::id();
```

#実際に使用してみました

スタッフを登録する際に、（権限を）adminかstaffのどちらかを選んで登録する
登録済みであるスタッフの編集は、adminの権限が無ければ出来ないようにしたい
（登録の際にadminにしたスタッフのみ編集可能・staffの場合は登録のみで編集は出来ない）

- 編集ボタンをadminのみに表示する

```ruby:index.blade.php
@if(Auth::user()->type == 'admin')

<a href="/users/edit/{{$user->id}}" class="btn btn-primary btn-sm">edit</a>

@end if
```
AIが不得意な日本語文法

リカレントニューラルネットワーク(以下RNN)を利用した文字レベルの自動文章生成について、以前こちらの投稿「[10万件の飲食店クチコミからRNNで文章を生成](https://qiita.com/sudamasahiko/items/cf7e4b0f372aa41d5402)」[1]でご紹介しました。今回は、RNNで自動生成された文章について、形態素解析を用いて品詞の観点から分析してみたいと思います。

#RNNによる文章自動生成の例
まず、RNNによって自動生成された文章をいくつかお見せします。なお、ネットワークはRNNの一種であるGRU(Gated Recurrent Unit)を利用し、30万件の飲食店クチコミ文章を教師データとして用いています。定性的な評価基準として、以下、
 ・文法的に合っているもの、間違っているもの
 ・意味があっているもの、おかしいもの
と、かなりばらつきがある出力結果が得られています。それぞれお見せすると、

###文法も意味も良さそうなもの
> 味は普通です。
> しっかりと食べられる。
> こういうのが良いですね。
> その後は私の人気店になるのが懐かしい感じです。

###文法はよいが意味不明なもの
> そんなにラインナップしたので、マグロがない。
> 最後にひとりと一杯目。
> この店は、キールチキンはサラダもスライスです。
> この日は何がたっぷりな酒でした。

###意味はよいが文法が間違っているもの
> こちらもサラダしている。
> お好み焼きで、それにしてもらいにはおいしい。
> ご飯でもそれなりにスープがあればいただいたものがしいただけると嬉しい。
> の10時00くらい、お店には、入店しました。

###文法も意味もだめなもの
> の2016年1月オーダーするとおばずがありましたよね。
> 「いろいろ」「置いてある」のついしました。
> しゅっぱい、確かにパンと注文で注文した。
> それにして、カレーののまである。

#定量的評価
定性的な特徴としては、上記のように良し悪しを何となく判断できますが、ここでは少し観点を変え、文章生成に使用された品詞による定量的評価を行います。分析対象は、教師データの文書と生成文章とそれぞれ約3700文で比較を行いました。形態素解析による分かち書きの結果、それぞれ約5万6千語に分解し、品詞をカウントしました。なお、形態素解析の際の辞書は、定期メンテナンスが行われているmecab-ipadic-NEologd[2]です。

![hinshi.png](https://qiita-image-store.s3.amazonaws.com/0/242602/5ad3ead5-cb99-e579-6a58-f61c754dfa1a.png)

図1 教師データと生成データにおける品詞の使用頻度の比較

上記グラフでは、出現頻度の順番でヒストグラムを表示しています。教師データと生成データとを比較し、頻度が大きく、かつ集計数の差が大きかったもののに以下があります。
・固有名詞
・地名
・記号
・数
・サ変接続名詞
・接尾名詞
・並立助詞

#考察
図1のグラフにより、固有名詞や地名をRNNが自動生成するのはやや難があるいうことが言えます。固有名詞は教師データに比べ40%、地名は22%ほどしか生成できていません(以下、この比率を便宜的に再現頻度と呼びます)。固有名詞は本質的に多様であるため、学習が難しかったんだろうと推察できます。ちなみに、新宿や池袋などの大都市に限っては教師データでの出現頻度が高いため、文章生成時にも出現しています。また、数や記号の使用が乏しかったのも同じ理由かと考えられます。その他に顕著だった品詞としては、3つ、サ変接続名詞、接尾名詞、並立助詞が挙げられ、個人的には興味深いです。以下、RNNであまり学習できなかったものの一部を列挙します。

###名詞-サ変接続
再現頻度: 50%
> 使用、利用、検査、到着、追加、投入、びっくり、満足、訪問、料理

###名詞-接尾-一般
再現頻度: 29%
> 感、程度、店、系、盛り、揚げ、焼き、達、風

###助詞-並立助詞
再現頻度: 21%
> と、たり、や、とか、やら

文字レベルの文章生成に限っては、語彙の多様性をうまく再現することができません。つまり、多様な語彙のある文章の生成には、何らかの方法で語彙体系などの利用は必須であると言えます。ただ一方、てにをはなどのよく使われる文法については、隠れた文法の特徴を学習することが可能で、RNNの得意とするところかと思います。この点は、文法的に崩れていたとしても、よく使われる表現であれば学習することができます。

#課題とまとめ
形態素解析や係り受け解析など、計算言語学的な解析方法と、深層ニューラルネットワークとを、どう親和的に実装してゆくかが課題として考えられます。また、自動生成された文章に何らかのスコアを与えることができれば、敵対的な学習を実現することができるかもしれません。

#参考情報

[1]
[10万件の飲食店クチコミからRNNで文章を生成](https://qiita.com/sudamasahiko/items/cf7e4b0f372aa41d5402)
https://qiita.com/sudamasahiko/items/cf7e4b0f372aa41d5402

[2]
[mecab-ipadic-NEologd](https://github.com/neologd/mecab-ipadic-neologd)
https://github.com/neologd/mecab-ipadic-neologd
Raspberry Pi と Google Home で LINE と会話


# このメモは？
子供が Google Home に話しかけたら外出中の自分が返答できるようにしたい、ということで作ってみたときのメモ。
Google Home と　Raspberry Pi、 LINE、 Google Apps Script を使った構成になっている。
基本的には他の人の記事にあるものを真似ただけなので、その参考にした記事へのリンクと、いくつか躓いた点をメモとして残しておく。
2018/5/16 ver1.0 公開

# Raspbian OS導入から WiFi での ssh 接続まで
セットを組み立てて、キーボード、マウス、モニタをつなげて HW 的なセットアップは完了。
OSはここから落として入れた。
[Download Raspbian](https://www.raspberrypi.org/downloads/raspbian/)
ダウンロードに時間がかかる以外は特に問題なし。

OS起動後、ちょっと手間取ったのは、WiFi の設定。
普通に設定しても繋がらない。国設定をしないといけないらしい。
GUI だと、Raspberry Pi の設定のローカライゼーションのタブから無線LANの国設定を行った。
そのまま、GUIでWiFi設定も行う。IPは固定にしておく。

sshもGUIで有効化可能。
piのパスワードを設定してリブート。
手元のPCからssh接続出来ることを確認したら、キーボードとかは外せる。
初期設定はこれで完了。[^1]
[^1]: 初期設定でrootのパスワード変更を書いているサイトがいくつかあったがそれは良くない。rootはログイン不可のまま、sudoを使う方がいい


# Google Home の設定
外部接続されるので、IPを固定化しておいたほうが無難。
Google　Home の設定は弄らず、DHCPサーバー側に設定を入れることにして、MACに対してIPを予約して割り当てた。

# Raspberry Pi の設定
## google-home-notifier導入まで
Node.js のアップデートとgoogle-home-notifier の導入まではこちらの記事を参考にした。

[10分でSlackからGoogleHomeを喋らせるめちゃ速レシピ](https://qiita.com/m2u/items/b4bebd3e03930ee77f4d)

ただ、Node.js を調べると LTS ( Long Term Support ) のバージョンが8ということだったので、そこだけ8に変えてみた。インストールコマンドは本家を参考。
[Debian と Ubuntu ベースの Linux ディストリビューション](https://nodejs.org/ja/download/package-manager/#debian-and-ubuntu-based-linux-distributions-debian-ubuntu-linux)

```
curl -X POST -d "text=Hello Google Home" https://<ランダム文字列>.ngrok.io/google-home-notifier
```

が成功してGoogle Homeが喋れば、ここまでは終わり。GAS （ Google Apps Script ） に書くスクリプトは別の記事を参考にした。

## foreverとngrokのURL書き出し
永続化はこの記事を参考にした。
[google-home-notifier周りをほぼ自動化した](https://qiita.com/k_keisuke/items/3e67aa25a24f07656f47)
ほぼ、まるまるコピーで良い。
ちなみに
>curl叩いてGoogle先生喋ってくれて、よゆーやん、と思ってたら、
>サービスを立ち上げるたびにngrokのURLが変わってしまうことに気づき絶望した人。

まさにこの人でした。

ここで躓いたというか、後日気づいたのだけど、このままだと ngrok がタイムアウトで切れてしまう。AM 0時に切れるっぽい。
切れなくなるようにするには、
[ngrok](https://ngrok.com/) 
でIDを作成、ログイン後のページの Connect your account に書いてある authtoken のコマンドを実行する。


```sh

$ pwd
/home/pi/google-home-notifier/node_modules/ngrok/bin

$ ./ngrok authtoken xxxxxxxxx

$ ls ~/.ngrok2/
ngrok.yml

```

ngrok.yml ができれば、アカウントを使ってアクセス出来、タイムアウトはなくなった。[^2]
[^2]: ngrok は色々アップデートがあるらしく、以前は無料で出来たことが有料化したり、有料化したときに、free account がなかったりしていたっぽい。この仕様も変わるかも

#LINE Message API と GASの連携

LINEからGASへのwebhookは、この記事等を参考にした。

[Google Apps Scriptを使ってLINE Messaging APIでオウム返しをする](https://qiita.com/nogizakaJinro/items/e2a178c1cb7a0699a80f)

GASのスクリプトについては、先の[自動化記事](https://qiita.com/k_keisuke/items/3e67aa25a24f07656f47)のおまけ部分にあるスクリプトに次のようなのを足せば実現できる。

```js
function doPost(e) {
  var message_text = JSON.parse(e.postData.contents).events[0].message.text;

  notify2GoogleHome(message_text);
}

```

ここで躓いたのは、GAS の公開。スクリプトの修正したら、新規作成しないと反映されない……という初心者丸出しのミスで３０分くらい浪費した。

ここまでで、LINE に送信すると　Google Home がしゃべる設定が完成。


# Google Home からLINEへの送信 - IFTTTの設定

こちらは逆の Google Home から LINE への送信の設定。
IFTTTを使えばとても単純。

[IFTTTを使ってGoogle HomeからLineを送信する](https://qiita.com/jyoshida/items/f74afe3e421795cdd63c)

この記事でできるようになる。

IFTTTからのメッセージが来るグループと、LINEからGoogle Homeに飛ばすためのグループは別にしている。一緒にしたほうがLINE上の可読性は良さそうだけど、Google Homeがうるさくなると思われる。

# 出来たこと
例えば子供が帰ったときに
「ok google、 LINEに送信、帰ったよ」
というと、LINEに　
`[IFTTT]帰ったよ`
とメッセージが来るので、LINEに
`おかえり、宿題して待ってて`
と返すと、Google Homeが子供に話してくれるようになった。

満足。

-------
ColaboratoryにJsonファイルをアップロードしてPandasで読み込む


# やったこと

## コード

```python
from google.colab import files
import io
import pandas as pd

uploaded = files.upload()
df = pd.read_json(io.StringIO(uploaded['sample.json'].decode('utf-8')))

print(df.loc[:,['id', 'text']])
```

## 実行結果

```
                         id                              text
0                  features                          Features
1    b_l4reliTdWOSn9SiCmbJQ                              機能紹介
2              book-example                      Book example
```

# 本当にやりたかったこと

- Beautiful SoupでHackMDへログイン状態でアクセス
- Beautiful Soupで履歴データ(json形式)をエクスポート機能で取得
- Googleスプレッドシートに内容を出力

HackMDはログインフォームが無いタイプ(GoogleやFacebookで外部認証する系)なのだが、Beautiful Soupを使ってスクレイピングする方法がちょっと調べた限りでは分からなかった。
ひとまず手動でjsonファイルをダウンロードしてさわりだけ試してみた。
iOS 10.3でのSKStoreReviewControllerの導入とそれ以外でのレビューを促すことの禁止

# iOS10.3でレビューがアプリ内でできるようにない

iOS10.3でわざわざAppStoreアプリに遷移させなくても、iOSアプリ内でアプリのレビューができるようになりました。

`SKStoreReviewController`クラスの`requestReview`メソッドを使うことでそれが実現できます。

https://developer.apple.com/documentation/storekit/skstorereviewcontroller

Unityだったら、`UnityEngine.iOS.Device`クラスの`RequestStoreReview`でダイアログを表示できます。

https://docs.unity3d.com/ScriptReference/iOS.Device.RequestStoreReview.html

このメソッドもいろいろ制約とか、環境による挙動の違いがあるので、実際に使う際に↑の公式ドキュメントを参照してください。

# AppStoreへの製品ページへのリンクを置けるのは、設定画面のみ

`SKStoreReviewController`クラスの`requestReview`メソッドの[リファレンス](https://developer.apple.com/documentation/storekit/skstorereviewcontroller/2851536-requestreview)には、次のような記載があります。

> In addition, you can continue to include a persistent link in the settings or configuration screens of your app that deep-links to your App Store product page. 

超ざっくり「AppStoreのアプリのページへのリンクを、アプリ内の設定・構成ページに引き続き設置してもいいよ」らしいです。

SKStoreReviewControllerの登場前は、開発者が任意のタイミングで、リンクを用いてAppStoreに遷移させて、レビューを促すことができました。しかし本稿執筆時では、リンクを用いてAppStoreに遷移できるのは、設定・構成ページに限定されているようです。

正直、`SKStoreReviewController`の制限が痛い。つらい。


# 式API以外での「レビューを促すこと」は禁止されている

[App Store Review Guidelines](https://developer.apple.com/app-store/review/guidelines/)によると、

「1.1.7 App Store Reviews」にて

> Use the provided API to prompt users to review your app; this functionality allows customers to provide an App Store rating and review without the inconvenience of leaving your app, and we will disallow custom review prompts.

とあります。

ポイントは次の文。

> and we will disallow custom review prompts.

「prompt」とあるので、独自実装したレビューを促す画面はだめってことですね。

[App Store Review Guidelines](https://developer.apple.com/app-store/review/guidelines/)の日本語版、[App Store審査ガイドライン](https://developer.apple.com/jp/app-store/review/guidelines/)には、


> アプリケーションのレビューをユーザーに促すには、提供されているAPIを使用してください。ユーザーがアプリケーションから離れることなく、簡単にApp Storeでの評価とレビューを入力できるようになります。レビューを求めるカスタムのメッセージ画面を表示することはできません。

と訳されていました。

# まとめ

* `SKStoreReviewController`の導入でアプリ内でレビューできるようになった
* アプリ内からレビューページのAppStoreへのリンクは、設定・構成画面に限定されている
* 「App Store Review Guidelines」に、`SKStoreReviewController`など提供されたAPI以外でのレビューを促すことが禁止されている
__construct()の引数の継承

当然で周知のことかもしれませんが、たまに迷うのでメモ

```PHP
<?php
    class A{
        function __construct(string $value) {
            echo $value;
        }
    }
    class B extends A{

    }

    new A("hogeA");
    new B("hogeB");
```

とすると、出力は

```
hogeAhogeB
```

となります。自動で親のコンストラクタに引数が渡ります(継承してるんだから当たりまえ)

ただし、IDEを使っていると少し不便な点があります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/71557/719d0c47-40c3-6ac1-c6a0-30bcfa3eecb5.png)
IntelliJ IDEAのPHPのプラグイン(181.4203.513)を使うと、上記の画像のように`B`のコンストラクタの説明(？)が表示されません。

それだけです。
Jenkinsでビルドをmvnw(maven wrapper)で行う

# はじめに
やるのは簡単なのですが、メモ残しです

# 環境
どのOSでも同じ

# ジョブの設定
・新規ジョブ作成 -> フリースタイル・プロジェクトのビルドからジョブの作成を行う
・ビルドの「ビルドの手順」からOSに合ったものを選択する
Windows -> Windowsバッチコマンドの実行
Mac Linux -> シェルの実行
・コマンドにmvnwコマンドを書いて終わり！
Windows Mac Linux -> ./mvnw clean compile

# 最後に
gradleでも同じこと出来ます。

どうでもいいけどWindowsってやっぱ色々面倒くさいですね。
Delegate in Swift

# Delegate System in Swift
<b>Delegate</b> in Swift is a way of passing the data between class and class.

Let's say the teacher want to teach lesson to the student. So first of all we have to create a teacher. In this case teacher is a person who already understand the lesson. So we will create a protocol <i>Learn</i> for teacher here:
<pre>
protocol Learn {
    func learnLesson()
}
</pre>
Now let's create a teacher who conform to the <I>Learn</I> protocol:
<pre>
struct Teacher: Learn {
    func learnLesson() {
        print("This is lesson 1")
    }
}
</pre>
Now <I>Teacher</I> has the ability to print out lesson 1:
<pre>
var teacher = Teacher()
teacher.learnLesson() // this line of code will print out "This is lesson 1"
</pre>
A student want to learn lesson 1 from him, now he can delegate function <i>learnLesson()</I> to his student. Let's create a student who want to learn lesson 1:
<pre>
struct Student {
    var delegate: Learn?
}
</pre>
Now, we have a student that want to learn lesson. Let's delegate learnLesson to him:
<pre>
var student = Student()
student.delegate = teacher
</pre>
Now the student learned lesson 1 from the teacher:
<pre>
student.delegate?.learnLesson() // This is lesson 1
</pre>
CentOS7(インターネットなし)にRuby on Railsをインストールする





# CentOS7(インターネットなし)にRuby on Railsをインストールする



参考にさせていただいたサイト

- [Rubyのインストール](https://www.ruby-lang.org/ja/documentation/installation/)



<br>

検証で滅多にないことをしたので、履歴として書いておきます

1. Ruby2.5.1をソースからコンパイルしてバージョンアップ (2.0 —> 2.5)
2. Rails 5.1.4を入れてローカル起動


<br>

- 前提

  - 端末：mac (インターネットつながる)
  - Vagrant : CentOs7 (インターネットなし、Rubyは固定ver入れる)





<br> 



1. Ruby2.5.1をソースからコンパイルしてバージョンアップ (2.0 —> 2.5)



CentOs7

```bash
# Rails インストール失敗
gem install rails -v 5.1.4
# ERROR:  Error installing rails:
# 	activesupport requires Ruby version >= 2.2.2.

ruby --version # 低い
# ruby 2.0.0p598 (2014-11-13) [x86_64-linux]

rbenv # ない
# -bash: rbenv: コマンドが見つかりません

```



mac

```bash
# https://www.ruby-lang.org/ja/downloads/　から安定版をダウンロード

# 転送 (2210は一時検証用ポート)
scp -P 2210 -r ~/Downloads/ruby-2.5.1.tar.gz root@127.0.0.1:/work

```



CentOs7

```bash
# 中身見る
tar tvf /work/ruby-2.5.1.tar.gz 

# 解凍
mkdir ~/Ruby/
tar xvf /work/ruby-2.5.1.tar.gz -C ~/Ruby/

# コンパイル
cd ~/Ruby/ruby-2.5.1
./configure
make
make install

# 特にエラー無

# 確認
whereis ruby
# ruby: /usr/bin/ruby /usr/lib64/ruby /usr/local/bin/ruby /usr/local/lib/ruby /usr/share/ruby /usr/share/man/man1/ruby.1.gz

which ruby
# /usr/local/bin/ruby

/usr/local/bin/ruby --v
# ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]


# パスを反映させるために一回exitしてから再度ssh
exit

# 確認
ruby -v
# ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]

```



<br>

<br>



1. Rails 5.1.4を入れる



CentOs7

```bash
gem install rails -v 5.1.4

rails -v
# Rails 5.1.4


mkdir appfolder && cd appfolder

rails _5.1.4_ new testapp

cd testapp/

vim Gemfile

```



- Gemfile

```ruby
source 'https://rubygems.org'

gem 'rails',        '5.1.4'
gem 'puma',         '3.9.1'
gem 'sass-rails',   '5.0.6'
gem 'uglifier',     '3.2.0'
gem 'coffee-rails', '4.2.2'
gem 'jquery-rails', '4.3.1'
gem 'turbolinks',   '5.0.1'
gem 'jbuilder',     '2.6.4'
gem 'execjs'
gem 'therubyracer', platforms: :ruby

group :development, :test do
  gem 'sqlite3',      '1.3.13'
  gem 'byebug', '9.0.6', platform: :mri
end

group :development do
  gem 'web-console',           '3.5.1'
  gem 'listen',                '3.1.5'
  gem 'spring',                '2.0.2'
  gem 'spring-watcher-listen', '2.0.1'
end

# Windows環境ではtzinfo-dataというgemを含める必要があります
# gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
   
```



CentOs7

```bash
bundle update # bundle読み込み

bundle install # bundle実行

rails server # ローカル起動

```





<br>

- rbenvなし、yumなし、インターネットなし、の時にRailsをローカル起動させるまで、でした
  - 何かの際にどうぞ

<br>
[Android]SamsungとLGのEnvironment Class 比較。

# なに？＿

単純な疑問で試してみました。FileのPathが必要で自分が持っているのはＬＧとSamsungスマホで、
Environment　classのmethodの結果の差があるのか！

# Kotlinを使ってやろう。

コードは真面目に簡単です。

```kotlin:MainActivity.kt

var envPath = Environment.getDataDirectory().toString()
print("getDataDirectory : ")
println(envPath)
envPath = Environment.getDownloadCacheDirectory().toString()
print("getDownloadCacheDirectory : ")
println(envPath)
envPath = Environment.getRootDirectory().toString()
print("getRootDirectory : ")
println(envPath)
envPath = Environment.getExternalStorageDirectory().toString()
print("getExternalStorageDirectory : ")
println(envPath)
envPath = Environment.getExternalStorageState().toString()
print("getExternalStorageState : ")
println(envPath)

```


#結果。：）

結果は同じだった。


| Method       |       Samsung |    LG    |
|:-----------------|------------------:|:------------------:|
| ![image.png](https://qiita-image-store.s3.amazonaws.com/0/137182/086958f1-d72e-f312-a094-cb0e41c4211d.png)            |  /data |         /data        |
| ![image.png](https://qiita-image-store.s3.amazonaws.com/0/137182/005afa17-a6a5-4905-4ba9-2a926644bbd2.png)          |            /cache |       /cache        |
| ![image.png](https://qiita-image-store.s3.amazonaws.com/0/137182/14fd0443-cd27-fdf0-db44-d1e346d1d466.png)             |              /system  |        /system        |
| ![image.png](https://qiita-image-store.s3.amazonaws.com/0/137182/440cfef2-a946-64c7-4211-9813b756f1e3.png)               |                /storage/emulated/0 |      /storage/emulated/0        |


#Code

[ここにある](https://github.com/JAICHANGPARK/Android-File-101)

# 参考。

1. https://developer.android.com/reference/android/os/Environment
Flutterの導入

## 概要
- Googleが開発しているモバイルアプリケーションのためのSDK
- オープンソース。
- Dart言語で書かれている。


## 導入方法
### インストール
- [こちら](https://flutter.io/get-started/install/)のサイトからインストールする。

### macOSでの導入
#### システム要件

- 64bit macOS
- ディスク容量 700 MB
- 以下のツール
  - bash, mkdir, rm, git, curl, unzip, which



#### 導入手順
1. 公式サイトからダウンロード
1. 好きな場所にflutterディレクトリを移す。(Macなら`/Applications`配下が良さそう)
1. パスを通す。
```
  export PATH=/your/path/to/flutter/bin:$PATH
```
1. 起動に必要なソフトウェアがあるかを確認
```
flutter doctor
```

- `Missing Xcode dependency: Python module "six".`のエラーが起こったので、以下で対応。

```
brew reinstall python@2
pip install six
```

## 開発環境
### Android Studio
#### Pluginの追加
- Dart Plugin
- Flutter Plugin

`Preference > plugin`から検索してインストールできます。


#### Flutter SDKのパスを通す
インストールした場所 `/your/path/to/flutter` を指定すれば良い。


## IDEを使わない場合
プロジェクトの作成
```
flutter create $project
```

コマンドラインから実行
```
flutter run -d "$deviceName"
```

## 参考
- [公式サイト](https://flutter.io/)
- [github](https://github.com/flutter/flutter)
- [公式サイトの導入ページ](https://flutter.io/setup-macos/)
ATmega328PBをCrossPack for AVRから書き込む


## はじめに
旧Atmel社(現在はPICを擁するMicrochip社に買収)のアーキテクチャ、AVRの中でもATmega328系列は[Arduino Uno](https://store.arduino.cc/usa/arduino-uno-rev3)で採用されているなど特によく使われるマイコンと言えます。

DigikeyではATmega328PBは無印やP付きよりも安価に販売されており(2018年5月16日現在で[32TQFPが161円程度](https://www.digikey.jp/product-detail/ja/microchip-technology/ATMEGA328PB-AU/ATMEGA328PB-AU-ND/5638812))入手性が高いのですが、mega328Pとmega328PBは若干機能が異なる型番であり、当然Signature(後述)も異なるため、`avrdude`においては互換性がありません。
さらにいうとHomebrewでインストールされる最新版のCrossPack for AVR(2013-12-16)ではデバイス自体が定義されておらず、`-F`オプションで識別子を無視することでしか書き込みできません。
今回は安心して`avrdude`でmega328PBを扱える方法をまとめました。

## mega8系のマイコンまとめ
ATmegaシリーズの32ピンの型番(mega8,48,88,168,328)はフラッシュ容量や一部機能などが異なりますが、基本的にはピン配置などの互換性があります。
mega328PBはmega328Pの機能に加えてMicrochipのQTouch(静電容量タッチセンサ)機能の他一部I/Oの増強が行われています。
**詳細については[このドキュメント](http://ww1.microchip.com/downloads/en/AppNotes/Atmel-42559-Differences-between-ATmega328P-and-ATmega328PB_ApplicationNote_AT15007.pdf) にまとめられれています。**

| 型番 | Signature | PORTE | QTouchコントローラ | 消費電流＠1MHz,1.8V,25°C |
|:--|:--:|:--:|:--:|:--:|
| [ATmega328P](https://www.microchip.com/wwwproducts/en/ATmega328P)   | 1E 95 0F | - | - | 0.2 mA |
| [ATmega328PB](https://www.microchip.com/wwwproducts/en/ATmega328PB) | 1E 95 16 | ✓ | ✓ | 0.24 mA |

mega328Pのレジスタアドレス等はそのままmega328PBに引き継がれているため、ファームウェア自体については完全に後方互換性があります(コンパイル済みのプログラムをそのまま書き込める)。
ただし、mega328Pで電源/ADCに割り当てられていたピン(VccとGND1組とADC6,7)がPORTEに拡張されているため、mega328P用に設計した回路にmega328PBを実装する場合は、PORTEの出力設定を誤って短絡させないように注意が必要です。

## `avrdude`の新規デバイス追加方法
`avrdude`では付属している`avrdude.conf`内で定義されているデバイスのみを使用できます。
これに以下を追記してmega328PBを追加します。
(普通にHomebrewでインストールすると`/usr/local/CrossPack-AVR/etc/avrdude.conf`に配置されますが、直接編集せずに適当な場所にコピーして編集するほうが無難です)

```
(省略)

part parent "m328"
    id          = "m328p";
    desc        = "ATmega328P";
    signature       = 0x1e 0x95 0x0F;

    ocdrev              = 1;
;

# 以下を追加
part parent "m328"
 id        = "m328pb";
 desc      = "ATmega328PB";
 signature = 0x1e 0x95 0x16;
 ocdrev = 1;
;
# 以上を追加

(省略)
```
`ocdrev`は[Atmelのツール内で使用される何からしい](https://www.mail-archive.com/avrdude-dev@nongnu.org/msg04831.html)ですが、詳細は不明なのでとりあえずATmega328Pと同じ値に設定します。

オリジナルの`avrdude.conf`を編集した場合はこれで`atmega328pb`が使用できます。
コピーしたファイルを編集した場合は以下のように`-C`オプションでパスを指定することが必要です。

```bash:(bash)
$ avrdude -P usb -c your-favorite-writer -p atmega328pb -C /path/to/avrdude.conf -U flash:w:program.hex # 書き込み
```

## おまけ: Makefile
結果的に、`avrdude`では`atmega328pb`を指定して書き込みを行いますが、コンパイルは引き続き`atmega328p`を指定することなります。
私は以下のようなMakefileを使用しています。

```makefile:Makefile
DEVICE     = atmega328p
DEVICE_WR  = atmega328pb
CLOCK      = 8000000
MAIN       = main
OBJECT     = $(MAIN).o
WRITER     = avrispmkii
CONFIG     = avrdude.conf

COMPILE = avr-g++ -std=c++11 -Wall -Os -DF_CPU=$(CLOCK) -mmcu=$(DEVICE)
AVRDUDE = avrdude -P usb -c $(WRITER) -p $(DEVICE_WR) -C $(CONFIG)

all:	$(MAIN).hex

.cpp.o:
	$(COMPILE) -c $< -o $@

clean:
	rm -f $(MAIN).hex $(MAIN).elf $(OBJECT)

$(MAIN).elf: $(OBJECT)
	$(COMPILE) -o $(MAIN).elf $(OBJECT)

$(MAIN).hex: $(MAIN).elf
	avr-objcopy -j .text -j .data -O ihex $(MAIN).elf $(MAIN).hex
	avr-size --format=avr --mcu=$(DEVICE) $(MAIN).elf

flash:
	$(AVRDUDE) -U flash:w:$(MAIN).hex
```
MacでFluentdの環境構築

# 環境情報
* macOS Sierra 10.12.6
* ruby 2.4.1

# 手順

```cmd
# 作業ディレクトリに移動
$ cd {path_to_railsproject}

# fluentdをインストール
$ gem install fluentd

# 設定ファイルの作成（今回はroot/config/fluent配下に作成）
$ cd ./config
$ mkdir fluent
$ cd ./fluent/
$ fluentd --setup ./

# fluentdの起動
$ fluentd -c ./config/fluent/fluent.conf 
```

# 動作確認
```cmd
# fluent-loggerを追加
$ gem install fluent-logger

# railsコンソールの起動
$ rails c

> Fluent::Logger::FluentLogger.open(nil, host: "localhost", port: 24224)
> Fluent::Logger::FluentLogger.post("debug.test", { "hoge" => "fuga" })
```

場合によってはこちらのgemを使うのが便利
[act-fluent-logger-rails](https://github.com/actindi/act-fluent-logger-rails)
ask-sdkの俺的テンプレ（２）

俺ようです。３日に1回くらい編集するかも

```
npm install --save ask-sdk
npm install --save ask-auxiliary
```

***nodeがv8.10である必要あり***

`index.js`

```js
const Alexa = require('ask-sdk');
const other = require('./other.js');
const askAuxiliary = require('ask-auxiliary');
 
let skill;
exports.handler = async function (event, context) {
    if (!skill) {
      skill = Alexa.SkillBuilders.standard() 
        .addRequestHandlers(
            LaunchRequestHandler,
            StopHandler)
        .create();
    }
    return skill.invoke(event);
}
 
// スキル起動時の処理
const LaunchRequestHandler = {
    canHandle(handlerInput) {
        return askAuxiliary.isLaunchRequest(handlerInput);
        // return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
    },
    async handle(handlerInput) {
      var msg = "";
      return handlerInput.responseBuilder.speak(msg).reprompt(msg).getResponse();
    }
};
 
const sampleIntentHandler = {
  canHandle(handlerInput) {
  return askAuxiliary.isIntent(handlerInput, "sampleIntent");
    //return handlerInput.requestEnvelope.request.type === 'IntentRequest'
    //  && handlerInput.requestEnvelope.request.intent.name === 'sampleIntent';
    
  },
  async handle(handlerInput) {
    var msg = "自分で定義したインテントの時に呼ばれます";
    return handlerInput.responseBuilder.speak(msg).reprompt(msg).getResponse();
  }
};
```

`other.js`

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

      return handlerInput.responseBuilder
        .speak(msg)
        .reprompt(msg)
        .withSimpleCard('Hello World', msg)
        .getResponse();
    },
  },
  
  CancelStopIntentHandler: {
    canHandle(handlerInput) {
      return handlerInput.requestEnvelope.request.type === 'IntentRequest'
        && (handlerInput.requestEnvelope.request.intent.name === 'AMAZON.CancelIntent'
         || handlerInput.requestEnvelope.request.intent.name === 'AMAZON.StopIntent');
    },
    handle(handlerInput) {
      var msg = 'ストップ、キャンセル';

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

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

  // v1のunhandledと同等。
  ErrorHandler: {
    canHandle() {
      return true;
    },
    handle(handlerInput, error) {
      return handlerInput.responseBuilder
        .speak('もう一度おねがいします')
        .getResponse();
    },
  },
}
```
第4話 四色定理

この記事は[仮面ライダービルドの数式](https://qiita.com/izmktr/items/e26a624e79bce3edccc9)の第4話です。

```math
\max_{G:planer}\chi(G) =4
```

これは、四色定理の式です。
「平面を塗り分けるには、最大4色必要になる」といった意味になります。

四色定理は、「地図を塗り分けるのに必要な色は何色か」という問題で、
意味が理解しやすい割に証明が困難ため、四色問題とも呼ばれました。

この問題の証明の歴史もまた興味深いです。
図形を約2000通りのパターンに分け、
1つずつコンピュータを使って四色で塗り分けられることを証明しました。
1976年の当時のコンピュータですから、計算に約1200時間かかったそうで、
確認するのも困難だしバグの懸念もあって受け入れには難色を示されたようです。

現在ではもうちょっと整理されて、パターン数を約600通りまで減らされたり
Coqという証明用言語で書き直されたりと改良されていますが、
コンピュータを使うのは変わらず、手計算での証明はされていません。

なお、平面だけでなく曲面でも構いません。
地球のような球体の表面でも四色で塗り分けることができます。
ところが、ゲームの世界では四色で塗り分けられない地図が出てきます。
この話は第7話に続きます。
vagrant upでBoxのダウンロードエラーとなる場合の対処方法

## この記事の対象
- [[試して理解]Linuxのしくみ](http://gihyo.jp/book/2018/978-4-7741-9607-7)という本を読みはじめて、「いやいや物理サーバの用意は無理ですっ！」ってなり、おとなしくVagrantでubuntu-16.04環境を用意しようと、久しぶりに`vagrant up`したもののエラーが出てBoxのDL出来なかった人(自分)向け
- 歴史的背景によりVagrantのバージョンを最新にできない人

## tl;dr
DL URL変わってるようなので`Vagrantfile`の先頭に下記の設定追加して`vagrant up`すれば:ok_hand:

```:Vagrantfile
# 先頭に追加
Vagrant::DEFAULT_SERVER_URL.replace('https://vagrantcloud.com')
...
```
参考: https://github.com/hashicorp/vagrant/issues/9442#issuecomment-363080565

### 確認環境など
マシン: Mac
OS: macOS Sierra(10.12.16)

```console
// Vagrantのバージョン
$ vagrant -v
Vagrant 1.8.6

// VirtualBoxのバージョン
$ VBoxManage -v
5.1.8r111374
```


## 以下詳細
### Vagrantfileの記述例
こんな感じで行けるだろうと思って書いた例

```rb:Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.box = "bento/ubuntu-16.04"
  config.vm.network :private_network, ip: "192.168.33.10"
  config.vm.provider :virtualbox do |vbox|
    vbox.memory = "256"
    vbox.cpus = 2
  end
end
```

だがしかし…

```console
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'bento/ubuntu-16.04' could not be found. Attempting to find and install...
    default: Box Provider: virtualbox
    default: Box Version: >= 0
The box 'bento/ubuntu-16.04' could not be found or
could not be accessed in the remote catalog. If this is a private
box on HashiCorp's Atlas, please verify you're logged in via
`vagrant login`. Also, please double-check the name. The expanded
URL and error message are shown below:

URL: ["https://atlas.hashicorp.com/bento/ubuntu-16.04"]
Error: The requested URL returned error: 404 Not Found
```

### そこで

```rb:Vagrantfile
# 先頭に追加
Vagrant::DEFAULT_SERVER_URL.replace('https://vagrantcloud.com')
...
```

```console
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'bento/ubuntu-16.04' could not be found. Attempting to find and install...
    default: Box Provider: virtualbox
    default: Box Version: >= 0
==> default: Loading metadata for box 'bento/ubuntu-16.04'
    default: URL: https://vagrantcloud.com/bento/ubuntu-16.04
==> default: Adding box 'bento/ubuntu-16.04' (v201803.24.0) for provider: virtualbox
    default: Downloading: https://vagrantcloud.com/bento/boxes/ubuntu-16.04/versions/201803.24.0/providers/virtualbox.box
    default: Progress: 12% (Rate: 135k/s, Estimated time remaining: 0:49:09)
```
ATTiny13で温度計

ATTiny13で温度計を作ってみました。センサーにはLM61を使い一秒おきにアナログ値(0-1023)を シリアルで出力するように作りました。Arduino 1.0.6でBasicSerial3というライブラリを利用して600バイトくらいになりました。

LM61は秋月で4個200円で買った物ですが、今見てみたら1個60円と値上げされてました。

```C
/* tx and rx pin is hard code in BasicSerial3.S */

#define BAUD_RATE 38400

#include <BasicSerial3.h>

#define LM61_APIN  2

void setup() {
  // 10 sec wait at boot
  delay(10000);
}

void serOut(const char* str) {
   while (*str) TxByte (*str++);
}

void serNumOut(int val)
{
int div = 1000;
  while(div != 0)
  {
    TxByte('0' + ((val / div) % 10));
    div /= 10;
  }
}

void loop(){
  int temp;
  // val is 0 to 1024
  temp = analogRead(LM61_APIN);
  serNumOut(temp);
  serOut("\n\r");
  // wait 1 sec
  delay(1000);
}
```

出力はこんな感じです。

```
0529
0529
0529
0529
0529
0529
0529
0529
0529
0528
```

![写真（2018-05-16 22.14）.jpg](https://qiita-image-store.s3.amazonaws.com/0/104066/8391af37-5f3e-981c-280c-8766f3e187d1.jpeg)

[『昼夜逆転』工作室](http://jsdiy.web.fc2.com/lm3914_thermometer/)さんを参考にさせてもらい、LM61の出力を何かからはがしたNJM2904で2倍(Rf=5KΩ/Rg=5KΩ)にしてATTiny13に入れています。

このシリアル出力を蟹さんのmrubyで受けてThingSpeakに投げてテストしてました。実際の温度の計算はMATLABでおこないました。

ボーレートが38400なのは蟹さんのbootがこのボーレートでそのままmrubyで使っているからです。

Adruinoでfloatを使うとバイナリサイズが大きくなるので、生の値を蟹さんに渡しているのですが、そもそも蟹さんのmrubyはfloatが使えないので、そうするしかなかったです。
【Laravel】多対多のドキュメントがわかりくかったのでbelongsToManyの使い方を画像1枚にまとめたよ

# なぜ手書き？

手書きでパパッと書けたので、PCで図を作成するより楽だったからですごめんなさい

せめてスキャニングくらいしろ？

ごもっともです...
<br>


多分そのうちちゃんと図を作ります

# belongsToMany

Laravelで多対多を実装する際にはbelongsToManyかhasManyThroughの2種類があります（他は知らないです）


写真のような、中間テーブルに2つの外部キーを含む際にbelongsToManyを用います


公式ドキュメントでは引数に何を与えればいいのか理解するために読む量が多いので、可視化しました


以下、SNSによくある「あるユーザーが、どのユーザーをフォローしているのか」の例です


![22F141A7-0457-4041-8687-2EA9FECC1467.jpeg](https://qiita-image-store.s3.amazonaws.com/0/148373/d1cf316d-164f-a2f9-b406-0392d5ca377f.jpeg)
spring securityで自前のAuthenticationProviderが二回呼ばれて認証失敗する

# 現象
タイトル通り。

一回目の```AuthenticationProvider```呼び出しで```UsernamePasswordAuthenticationToken```を返して認証OKとしても、もう一度```AuthenticationProvider```が呼ばれて認証失敗となる。二回目の呼び出しではCredentialsがnullになるので認証失敗に終わる。

# 原因と解決策
[java - spring security custom AuthenticationProvider is called twice and fails - Stack Overflow](https://stackoverflow.com/questions/29073834/spring-security-custom-authenticationprovider-is-called-twice-and-fails/29078757)

<code>UsernamePasswordAuthenticationToken</code>のコンストラクタに引数が3つあるやつを使用する。これを使うと```isAuthenticated()```がtrueを返すようになる。これで二回呼ばれなくなる。
flutterはiphone5cじゃあ(2018/05/16時点で)動かないけどdevチャンネルなら動く

## 概要
flutterをbetaチャンネルで使おうとするとarmv7のios端末(iPhone5c以前)だとサポート外で動かない。でもdevチャンネルだとサポートしてくれているみたいなので、ちょいちょい設定したら動いたよ！

## 詳細
betaチャンネルだと、私の手持ちのiPhone5cだと動かなかった。
CPUアーキテクチャサポート外らしい。
この[iOSデバイス一覧表](https://qiita.com/takkyun/items/814aa45beee422a5f0c6)によると、iPhone5cまではarmv7というアーキテクチャで、flutterがサポートしているのはarm64、iPhone5s以降のアーキテクチャ。

しかし、この[記事](https://github.com/flutter/engine/wiki/iOS-Builds-Supporting-ARMv7)によると、[コミットハッシュde332ec](https://github.com/flutter/flutter/commit/de332ec78292c2d79fdb76034328f902c9087ee9)時点でarmv7もサポートしてくれているらしい。
そのコミットハッシュにはtaｇ:[v0.4.2](https://github.com/flutter/flutter/releases/tag/v0.4.2)が切られているので、最新版を追えば対応できそう。

調べてみるとflutterにはchannelと言うものがあって、それを切り替えることでmasterブランチやらbetaブランチやらを終えるらしい

- master: 一番新しくて一番不安定
- dev: masterよりマシでテストされてるが悪いビルドとやらが含まれることがあるよ
- beta: devの中から良いビルドを選んでるよ。この中では一番安定していて推奨だよ

channelの説明の参考https://github.com/flutter/flutter/wiki/Flutter-build-release-channels

先の0.4.2は、現時点(2018/05/16)で、betaには含まれていないけどdevには含まれている

今は2018/05/16
flutterのbetaチャンネルは v0.3.2
flutterのdevチャンネルは v0.4.4

### 手順
#### 手順1 flutterをdevチャンネルにする

```
$ cd project_root
$ flutter channel dev
$ flutter upgrade
```

#### 手順2 xcodeでarm64限定っぽい設定を解除
https://github.com/flutter/engine/wiki/iOS-Builds-Supporting-ARMv7 記事参照を推奨ですが、以下にも書いておきます

1. Targets->Runner->BuildSettings->Architecturesをarm64からStandart architectures(よくわからんけどサジェストされるやつ)に変更
2. Flutter/AppFrameworkInfo.plist->Required device capabilities keyを削除
3. Runner/Info.plist->Required device capabilities keyを削除

#### 手順3 run!

```
$ flutter run # iphone5cなどが接続されている前提
```

でうごいたよ！
AnsibleのVMwareモジュールを並列実行する

AnsibleのVMwareのモジュールはvSphere API(SOAP)を使って操作する作りになっています。
接続先はvCenter1台に対して複数のVMを操作する場合、普通にPlaybookを書くとシングル処理で動いてしまっていたので並列に動かすやり方例について記録しておきます。

# 1. VMwareモジュール

ここでは、例として `vmware_guest_file_operation` モジュールを使います。

[http://docs.ansible.com/ansible/latest/modules/vmware_guest_file_operation_module.html#vmware-guest-file-operation-module](http://docs.ansible.com/ansible/latest/modules/vmware_guest_file_operation_module.html#vmware-guest-file-operation-module)

## 1-1. シングル処理について

ドキュメントに従ってPlaybookを作ってみます。

```yaml
---
- name: VMware Module Test
  hosts: localhost
  gather_facts: no
  tasks:
    - name: copy file to guest os
      vmware_guest_file_operation:
        hostname: vCenterIP or FQDN
        username: administrator@vsphere.local
        password: secret
        validate_certs: no
        vm_id: "{{ item }}"
        vm_username: root
        vm_password: secret
        copy:
          src: ./testfile
          dest: /root/upload/testfile
          overwrite: False
      with_items:
        - devel
        - devel2
```

このPlaybookでは `devel` `devel2` に対して `testfile` をVMのゲストOSへコピーするものになっています。
実際に実行すると以下のようになります。

![ansible_vmware_01.gif](https://qiita-image-store.s3.amazonaws.com/0/180118/d4f048f2-1ec6-c046-9eab-3bb0d7101a2f.gif)

画面左上が `devel` で 右上が `devel2` です。
`with_items` では一つのタスクが終わったら次のタスクというふうに順番に実行されることがわかります。
これだと、一つ一つ実行していくのでVM数に比例して時間がかかります。

## 1-2. 並列処理について

並列処理にする例です。
`inventory` ファイルを使って並列化してみます。
以下はinventoryファイル例です。

```yaml
[vms]
devel ansible_connection=local
devel2 ansible_connection=local
```

Playbookでは `vm_id` にマジック変数の `inventory_hostname` を指定します。

```yaml
---
- name: VMware Module Test
  hosts: vms
  gather_facts: no
  tasks:
    - name: copy file to guest os
      vmware_guest_file_operation:
        hostname: vCenterIP or FQDN
        username: administrator@vsphere.local
        password: secret
        validate_certs: no
        vm_id: "{{ inventory_hostname }}"
        vm_username: root
        vm_password: secret
        copy:
          src: ./testfile
          dest: /root/upload/testfile
          overwrite: False
```

実際に実行すると並列にアップロードされていることがわかります。

![ansible_vmware_02.gif](https://qiita-image-store.s3.amazonaws.com/0/180118/7f167204-489d-3e0b-761b-0e7865029d1a.gif)

# 2. 注意

vSphere API経由からファイルをゲストOSへコピーする時はVMware Toolsが動作していなければなりません。
また、一度vCenter/ESXiを経由してゲストOSへコピーするためオーバーヘッドが大きいのでサイズがでかいファイルや一度に大量コネクションを張ると負荷が懸念されます。
※でかいサイズのファイルのコピーは正直遅いです。
準備：jQueryをCake2で使えるようにする

※この記事はCake２系の開発環境を利用する方を対象にしています。

## 🐧手順
開発環境内にjQueryを導入することでDBを経由するよりも少ない負担で処理が行えます。その準備手順を紹介です。

1.　jQueryをダウンロードします
2.　cakeフォルダに配置します


## 1.　jQueryをダウンロードします
jQueryのダウンロードサイトにアクセスします。赤枠をクリックします。
※　http://jquery.com/
![ダウンロード.png](https://qiita-image-store.s3.amazonaws.com/0/209786/08c59e50-cce0-cdf5-446f-4059f1e5032e.png)

上記を実施すると画面が切り替わりますので
以下のダウンロードリンクをクリックします。
![クリック.png](https://qiita-image-store.s3.amazonaws.com/0/209786/c62a1e1b-8190-0283-4efd-fc81ffd211d5.png)

新規タブにjQueryのソースコードがもじゃもじゃと表示されます。ソースコードの画面上で右クリック後「名前を付けて保存」を選択します。
![名前を付けて保存.png](https://qiita-image-store.s3.amazonaws.com/0/209786/238ce120-cbce-a9c5-d06d-a3ff164ddb64.png)

## 2.　Cake２にjQueryファイルを配置します
　①jQueryファイルの配置
　cakeフォルダ内の　app\webroot\js　に配置します。

　②app\View\Layouts\default.ctp　に以下を追記し保存します。

```php:default.ctp
<head>
 <?php 
//以下を追加
echo $this->Html->script('jquery-3.1.1.min.js');
?>
</head>
```

## ■準備完了！
おつかれさまです。以上で準備が整いました〇
java Optionalの基本的な使い方その1

Optionalってどんなんだったっけ・・？って時の自分用備忘録記事です。
ざっくりした考え方として「nullが入ってるかもしれないよ」というのが一目でわかる型がOptional型です。
まずは単純なnullチェックの例

```java
		if (name != null) {
			System.out.println(name);
		} else {
			System.out.println("名前がないよ");
		}
```
結果はもちろん

```console
// nameに"名前があるよ"と代入されている場合
名前があるよ

// nameがnullだった場合
名前がないよ
```

これをOptionalでやるとこんな感じ

```java
		Optional.ofNullable(name).ifPresentOrElse(result -> System.out.println(result),
				() -> System.out.println("名前がないよ"));
```
この場合も結果は以下の通り

```console
// nameに"名前があるよ"と代入されている場合
名前があるよ

// nameがnullだった場合
名前がないよ
```

そもそも通常のif文の場合ももっと書き方あるだろ…
とかそういうのは一旦置いておいて上記でやっていることの説明をすると
***Optional.ofNullable(name)***
の部分で引数の値がnullでない場合、その値を格納したOptinalを返しています。
名前の通りnullを許容するメソッドで、nullだった場合はOptionalのemptyメソッドで生成された空Optionalの返します。
この空のOptional、==new 空のOptionalと比較し…みたいなことはしません。

そこで出てくるのがOptionalクラスのメソッドであるifPresentです。
で、今回ifPresentを使用しようと思ったのですが、色んな場所でifPresentは使うべきではないといった記事をたくさんみました。
どうやら最初に取得したOptionalが空だった場合、elseの処理がめんどくさいって理由がメインの話でした。
なので今回、java9より新たに追加された***ifPresentOrElse***を使用しました。
***ifPresentOrElse(result -> System.out.println(result), () -> System.out.println("名前がないよ"))***
パっと見でわかりやすく、最初に取得したOptionalが空かどうかで処理を振り分けられるメソッドです。

こんな感じでnullの可能性がある値に対してif null等でアプローチせずに処理をかけ、
すっきり書けるだけで無くnullチェック忘れ等の防止にもつながるなぁ～みたいな利点があると思います。

今回はOptionalとはどんなもんかっていうことでここまで。
Google Cloud Bigtable のアーキテクチャ

Google の公式のドキュメントでは Bigtable のアーキテクチャを下記のように紹介しているが、実はここには記載されていない、わりかし重要な仕様や要素が含まれていたりするので、Bigtable の検索時の動作も含め、簡単にまとめました。

![スクリーンショット 2018-05-15 20.43.45.png (40.0 kB)](https://img.esa.io/uploads/production/attachments/6232/2018/05/15/32582/49ad1e1c-97e6-4009-9646-cd8d37f751fe.png)

# Bigtable の構成要素

- Node (Tablet Server)
- Chubby
- GFS (Colossus)
- SSTable (File)
- Tablet
- Root tablet
- Memtable
- tablet log


# データ
BigTable のテーブルのデータは、内部では複数の **Tablet** に分割されているので、例えば、User のデータを保持する User Table があれば、そのデータは **Tablet1**、**Tablet2**、**Tablet3** と複数の **Tablet** に分割されます。

※ **Tablet** 内のデータはキーの辞書順にソートされている

イメージ
![Big Table Architecture - Page 1.png](https://qiita-image-store.s3.amazonaws.com/0/190497/ccc49f88-3c20-acea-0e7d-541617817cd5.png)



# データの保存先
実際のデータは **Tablet Server** のメモリ上にある **memtable** というキャッシュと **GFS (GoogleFileStrage)** 上に **SSTable** 形式のファイル、さらに **Tablet log** にも保存されます。

※1 **Tablet log** は追記限定のため、ファイルの書き込み処理のオーバーヘッドを低減しています。
※2 **memtable** も追加書き込み方式のため、時間がたつとどんどん肥大化してしまうので、マイナーコンパクションという、その時点の **memtable** の内容を新しい **SSTable** に書き込んで、**memtable** をクリアする処理が定期的に走る。
※3 マイナーコンパクションとは別にメジャーコンパクションも存在するが、これはマイナーコンパクションで作成された **SSTable** と既存の **SSTable** を一つにまとめる処理のこと。


イメージ
![Big Table Architecture - Copy of Page 1.png](https://qiita-image-store.s3.amazonaws.com/0/190497/7d95a40f-4fd2-792d-3ecc-054a87b8b58e.png)


# RootTablet ・ Chubby Server
[データ](https://qiita.com/kei0405/items/d420efebcc4b8fb1c008#%E3%83%87%E3%83%BC%E3%82%BF) にもあったようにテーブルのデータは複数の**Tablet**に分割されるが、それとは別に **Root Tablet**、**META DATA Tablet** という特別な **Tablet** に他の**Tablet** がどの **Tablet Server** に振り分けられているのかが登録されている **Tablet** が存在する。
また、**Root Tablet** が担当している **Tablet Server** の情報は分散ロックサービスの **Chubby** にも保存されるため、クライアントは一度、 **Chubby** にアクセスして **RootTablet** の情報を取得した後、該当の **Tablet Server** にアクセスをして欲しいデータを取得するフローになっている。



※ **Chubby** 自身もマスタ・レプリカの冗長化された構成になっており、レプリカはいつでもマスタに昇格できるようになっている。


イメージ
![Big Table Architecture - Copy of Copy of Page 1 (1).png](https://qiita-image-store.s3.amazonaws.com/0/190497/eff4ebef-3078-1b8a-dda4-1ef16a9eb603.png)


# Master Server
**Tablet Server** の状態を管理する **Master Server** は、実はクライアントからはほとんどアクセスされなく、新規にテーブルを作成した場合や、既存の **Tablet Server** が障害で停止した場合に、他の **Tablet Server** のリソースを見て、余裕のあるものに **Tablet** を振り分けるといったことを行います。
そのため、 **Master Server** が停止した場合でも、問題なくテーブルにアクセスが可能になっている。

また、**Master Server** は **Chubby** から起動中の **Tablet Server** を把握して (**Tablet Server** は起動時に **Chubby** に自身の存在を登録する) 、サーバーの状態をチェックをしたり、 **Chubby** から取得した排他ロックを使って、データに矛盾が発生しないように **Tablet** の操作を行ったりもします。

イメージ
![Big Table Architecture - Copy of Copy of Copy of Page 1.png](https://qiita-image-store.s3.amazonaws.com/0/190497/da27fc52-d6a2-1b90-fac7-a81c66370cc9.png)

# 最後に
Bigtable は最近東京リージョンで利用可能になったり (2018/5/1)、異なるリージョンへのレプリケーションが可能になったりと、まだまだ開発が進んでいるイメージなので、今後のリリース内容にも目が離せないですね。



# 参考
https://cloud.google.com/bigtable/docs/overview?hl=ja
https://courses.cs.washington.edu/courses/csep552/13sp/lectures/6/bigtable.pdf
http://www.atmarkit.co.jp/ait/articles/0909/07/news096_2.html
http://kaihooo.com/distributed-storage/
https://www.apps-gcp.com/gcp-storage-service/
https://www.school.ctc-g.co.jp/columns/nakai2/nakai205.html
zsh-bd を再実装してみた

親ディレクトリへの移動が楽になるコマンド [Tarrasch/zsh-bd](https://github.com/Tarrasch/zsh-bd) を自分で実装してちょっと拡張してみた。

[ryutok/zbd](https://github.com/ryutok/zbd)


# 動機
引数なしで `bd` コマンドを実行したときに1つ上のディレクトリに移動したら楽なのになあっと思っていたら Github の issue にもう上がっていた。
[Feature request: bd with no arguments should move up one directory #18](https://github.com/Tarrasch/zsh-bd/issues/18)
ただ、作者にエイリアス `alias up='cd ../'` を登録すれば良いじゃんと言われしまっている…


# やりたかったこと
1. 引数無しで `bd` を実行したときに1つ上のディレクトリに移動
2. 現在のディレクトリを移動対象から外す
3. TAB補完で大文字・小文字を無視する
4. TABを押したときに表示される親ディレクトリのリストを親→子の順で表示する

1−3については zsh-bd の issue でも提案されている。4は単純に好みの問題で、zsh-bd では子→親の順で表示される。


# 実装
zsh-bd のライセンスが不明なので自分で一から作ることにした。
ソースコードは Github に置いてあります（[ryutok/zbd](https://github.com/ryutok/zbd)）。

## 概要
`__zbd:count` は与えられた名前のディレクトリの位置を調べる関数。
`__zbd:cd` は与えられた数だけ '../' を連結して `cd` を実行する関数。

引数が与えられた場合、まず `__zbd:count` でその名前の親ディレクトリがあるかを調べ、無かった場合には引数が数字なら直接 `__zbd:cd` にその数を渡す。引数が与えられていない場合、 `__zbd:cd` に1を渡して、1つ上のディレクトリに移動する。

## TAB補完
Google 検索で最初に見つけた方法は、別記事（[zsh-bd の Tab 補完で大文字・小文字を無視する](https://qiita.com/ryutok/items/6aa4a6cf1ccdf82cd313)）に書いたとおり、 `compctl` でコマンドの補完関数を指定するときに `-M <match_spec>` オプションで直接指定する方法。ただ、この方法だとユーザーごとに好みの `<match_spec>` を指定することができない。

そこで、[新しい補完システム](http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-System)（`compdef`, `compadd`) を用いることにした。これにより、`.zshrc` 内の設定 `zstyle ':completion:*' matcher-list <match_spec>` が反映される。補完システムを定義しているコードは以下の通り。

```zsh:zbd.zsh
function _zbd {
    declare -a args
    args=(
        '-h[print help]'
        '1:parents:__zbd:add_parents'
    )
    function __zbd:add_parents {
        __zbd:get_parents
        _wanted -V values expl 'parents' compadd $parents
    }
    _arguments $args
}


compdef _zbd zbd
```

最後の行 `compdef` で `zbd` コマンドに対する補完を定義する関数 `_zbd` を指定している。関数 `_zbd` では、配列 `args` を定義して `_arguments` に渡している。これにより、`zbd` を実行する際、ハイフンの後ではオプションが補完され、それ以外の場合は `__zbd:add_aprents` で生成される親ディレクトリが補完される。この書き方は [mollifier/cd-gitroot](https://github.com/mollifier/cd-gitroot) を参考にした。

`__zbd:get_aprents` は親ディレクトリのリストをグローバル変数 `$parents` に格納する関数で、その親ディレクトリのリストを `compadd` に渡すことで補完リストに追加している。ここで、 `_wanted` を用いているのは、親ディレクトリのリストを親→子の順のまま補完リストに表示するためである。（参考：[Custom zsh completion: custom sort?](https://stackoverflow.com/questions/48484755/custom-zsh-completion-custom-sort)）


# 実行例

![demo.gif](https://github.com/ryutok/zbd/raw/master/demo.gif)
Ubuntu 設定メモ

## ホームディレクトリ直下のディレクトリ名を英語にする

```
$ LANG=C xdg-user-dirs-gtk-update
```


## apt のリポジトリを国内のミラーサーバに変更

```
$ sudo sed -i'.bak' -E "s@http://(..\.)?(archive|security)\.ubuntu\.com/ubuntu@http://ftp.jaist.ac.jp/pub/Linux/u    buntu@g" /etc/apt/sources.list
```


## CapsLock を Ctrl にする

```
$ sudo vi /etc/default/keyboard
```

`XKBOPTIONS` を変更。

```
- XKBOPTIONS=""
+ XKBOPTIONS="ctrl:nocaps" 
```

再起動。


## タイムゾーン確認/変更

- 現在のタイムゾーンの確認

```
$ sudo timedatectl
```

- タイムゾーンを Asia/Tokyo に変更

```
$ sudo timedatectl set-timezone Asia/Tokyo
```


## Vim 8 のインストール (Ubuntu 16.04)

```
$ sudo add-apt-repository ppa:jonathonf/vim
$ sudo apt update
$ sudo apt install vim
```
Rails で <select> 要素とか <input type=radio> 要素を readonly っぽくする

- 編集不可かつリクエストには含めたい `input type=text` 要素を使いたい時、 [`readonly` 属性](https://developer.mozilla.org/ja/docs/Web/HTML/Element/Input#attr-readonly)を設定する
- しかし `readonly` は `<select>` とか `<input type="radio">` には効かない。
    - `disabled` にした入力要素はその form でのリクエストに含まれなくかる。なので選択中の値以外を `disabled` にするなどの工夫が必要

こんな感じ:

```html:some_form.html
<select name="some_selection">
  <option selected>one</option>
  <option disabled>two</option>
</select>

<label><input type="radio" name="some_radio" value="one" checked>one</label>
<label><input type="radio" name="some_radio" value="two" disabled>two</label>

```

Rails ではこんな感じ:

```erb:some_form.html.erb
<%= form_for @some_model do |f| %>
  <%= f.select :some_selection,
    options_for_select([[:one, selected: true], [:two, disabled: true]]) %>

  <label><%= f.radio_button :some_radio, :one, checked: true %></label>
  <label><%= f.radio_button :some_radio, :two, disabled: true %></label>
<% end %>
```
VisualStudio2017 > Reactテンプレート(TypeScript) > leaflet


VisualStudio2017のReactテンプレートを使ってleafletを表示します。　（IE11対応）

### 環境
バージョン：asp.net core 2.0

asp.net core 2.0のReactテンプレートはTypeScriptになります。
よってTypeScriptで記述していきます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/49910/bd19478e-3672-9b87-9400-81464aa0c0fa.png" width=300 />


## プロジェクト作成

React.jsテンプレートを使ってプロジェクトを作成します。

![image](https://qiita-image-store.s3.amazonaws.com/0/49910/4ca5ad8f-7078-1939-a459-ee61b83aea70.png)



## package.json

leaflet と@types/leafletを追加します。

```
"devDependencies": {
    "leaflet": "1.3.1"
},
"dependencies": {
    "@types/leaflet": "^1.2.7"
}
```


## components

### 不要ファイル削除

ClientApp/components/配下の不要なファイルを削除
以下のファイル群はすぱっと消す

* FetchData.tsx
* Counter.tsx
* NavMenu.tsx

### ファイル追加

マップ用のコンポーネント追加

* MapWorld.tsx

現状で以下のような構成になる
![image](https://qiita-image-store.s3.amazonaws.com/0/49910/967d561e-4430-ae7a-8456-f972943c51c5.png)


## ファイル修正

### routes.tsx

ファイルを削除したのでルーター設定も変更する。

```js:routes.tsx
import * as React from 'react';
import { Route } from 'react-router-dom';
import { Layout } from './components/Layout';
import { Home } from './components/Home';

export const routes = <Layout>
    <Route exact path='/' component={ Home } />
</Layout>;
```

### Layout.tsx

マップを全画面表示にする。

```js:Layout.tsx
import * as React from 'react';

export interface LayoutProps {
    children?: React.ReactNode;
}

export class Layout extends React.Component<LayoutProps, {}> {
    public render() {
        return <div id='root'>
            {this.props.children}
        </div>;
    }
}

```

### site.css

マップを全画面表示にするためのCSS設定。

```css:site.css
html, body {
    margin: 0;
    padding: 0;
    height: 100%;
    width: 100%;
}

#react-app, #root, #map, #mapUI {
    width: inherit;
    height: inherit;
    background-color: #000;
}
```

### MapWorld.tsx

Leafletを表示するコンポーネント

```js:MapWorld.tsx
import * as React from 'react';
import * as L from 'leaflet';
import 'leaflet/dist/leaflet.css';

export class MapWorld extends React.Component<{}, {}> {
    componentDidMount() {
        this.init();
    }

    private init() {
        let map = L.map('map')
        let basemapLayer = new L.TileLayer('http://{s}.tiles.mapbox.com/v3/github.map-xgq2svrz/{z}/{x}/{y}.png');
        map.addLayer(basemapLayer);
        map.setView([35.6693863, 139.6012974], 5);
    }
    public render() {
        return <div id="mapUI">
            <div id='map'>a</div>
        </div>;
    }
}
```



### Home.tsx

Leafletを表示するコンポーネントを表示する。


```js:Home.tsx
import * as React from 'react';
import { RouteComponentProps } from 'react-router';
import { MapWorld } from './MapWorld';

export class Home extends React.Component<RouteComponentProps<{}>, {}> {
    public render() {
        return <MapWorld />;
    }
}
```


以上
erb に Lodash.js (or Underscode.js) の _.template を書くときのエスケープ

# 問題

[Lodash.js](https://lodash.com/), [Underscore.js](http://underscorejs.org/) の `_.template` の記法 `<%= 変数名 %>`　が erb の記法が被っているため、erb で `_.template` のテンプレートを配信する時に困った。

# 解決策

- `<%%= %>` を使うと配信されるHTMLが `<%=  %>` になる
    - 参考: https://magazine.rubyist.net/articles/0017/0017-BundledLibraries.html
- `_.templateSettings` を設定するのでもいいけど、↑のが楽だと思う

## 例


こんな感じ:

```erb:some_template.html.erb
<script type="text/template" id="template">
  <div><%= "some value" %></div>
  <div><%%= some_javascript_var %></div>
</script>
```

これをhtmlにコンバートするとこうなる


```html:some_template.html
<script type="text/template" id="template">
  <div>some value</div>
  <div><%= some_javascript_var %></div>
</script>
```
pipでモジュールがインストールできないときの対処法メモ


`pip3 install`は使えるけど`pip install`はエラーが出て使えなかったときの一連の解決法です．
#環境
MacOSX 10.13.4

#方法
エラー内容はメモってなかったので忘れました．
SSLがなんとかって書いてあったはず．

##対処1：opensslをHomebrewでインストール
原因はデフォルトのopensslが古かったこと．
そこでHomebrewでopensslをインストールします．

```
brew install openssl
```

これだけではエラーは何も変わりませんでした．
どうやらbrewでインストールしたopensslが参照されておらず，
もともとMacに入ってたのが優先されてしまっているらしい．

brewの方を使ってもらうようにします．

##対処2：brewの方のopensslをリンクさせる


```
brew link openssl --force
```

でリンクします．

するとこんなエラーが

```
Warning: Refusing to link: openssl
Linking keg-only openssl means you may end up linking against the insecure,
deprecated system OpenSSL while using the headers from Homebrew's openssl.
Instead, pass the full include/library paths to your compiler e.g.:
  -I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib
```

調べると
>https://qiita.com/dasisyouyu/items/c9621c29b0fe79d2b7c4
>どうやらopensslへのlinkは貼れなくなったらしい

ということで，リンクさせるのはやめて，パスの設定をします．

##対処3：パスの設定

```
vi ~/.bash_profile
```

でbash_profileを開きます．
開いたら`i`でINSERTモードにして，適当な場所に

```
export PATH=/usr/local/opt/openssl/bin:$PATH
```

と書きます．
`Esc`でノーマルモードに戻ったら，`Shift+ZZ`で保存して終了．

```
source .bash_profile
```

を実行して変更を適用したら，ターミナルを再起動します．

#まとめ

```
which openssl 
```

でパスを調べて，```/usr/bin/openssl```から
`/usr/local/opt/openssl/bin/openssl`となっていたら成功です．

これでpipが使えるようになりました．
WSHのWScriptオブジェクトは`WSH`でも参照できる

タイトルの通り、WSH（[Windows Script Host](https://msdn.microsoft.com/ja-jp/library/cc392522.aspx "Windows Script Host のオブジェクト モデル")）で引数などの操作に使用する`WScript`オブジェクトは、`WSH`でも参照することができます。


```js:WSH_JScript.js
// ルートオブジェクト内変数列挙
// => WScript と WSH が表示される
(function(o){
	for ( var k in o )
		WSH.Echo(k);
})(this);

// 同じ物か判定
WSH.Echo(
	WSH === WScript ?
		"`WSH`と`WScript`は同じものです" :
		"`WSH`と`WScript`は違うものです" );
```

```vb:WSH_VBScript.vbs
Option Explicit

Call WScript.Echo("WScript")
Call WSH.Echo("WSH")
Call WSH.Echo("`WSH` type is " & TypeName(WSH)) 'Object

' 同じ物か判定
If WSH Is WScript Then
	Call WSH.Echo("`WSH`と`WScript`は同じものです")
Else
	Call WSH.Echo("`WSH`と`WScript`は違うものです" )
End If
```

一般的には`WScript`が使用されていますが、個人的には`WSH`の方が打ちやすく、わかりやすいと思います。