OmniAICreator/Qiita-1.07M huggingface dataset:
各ネットワーク機器 コマンド

■HP①
config取得
>display current-configuration

ポート、フィルタ
>display interface brief

vlan
>display vlan all

ルーティング
>display ip routing-table

arp
>display arp

mac
>不明

lldp
>display lldp neighbor-information list (datail)

ステータス確認
>display lldp status

lldpをenable
>lldp enable

長いconfig等をenter押下せずにすべて流す
>screen-length disable

特権モード(display)
>system-view

■HP②
config取得
>show running

ポート、フィルタ
>show interfaces brief

vlan
>show vlan

ルーティング
>show ip route

arp
>show arp

mac
>show mac-address

lldp
>show lldp info remote-device

ステータス確認
>show lldp config

長いconfig等をenter押下せずにすべて流す
>terminal length 0

■Apresia
config取得
>show running

ポート、フィルタ
>show interface　status

vlan
>show vlan

ルーティング
>show ip route

arp
>show arp

mac
>show mac-address-table

lldp
>show lldp statistics

長いconfig等をenter押下せずにすべて流す
>terminal length 0

■Buffalo
config取得
>show running-config

ポート、フィルタ
>show interface

vlan
>show vlan brief

ルーティング
>show config ip routing

arp
>show arp

mac
>show mac-address-table

lldp
>不明

長いconfig等をenter押下せずにすべて流す
>terminal length 0

■CenterCOM
config取得
>show config dynamic

ポート、フィルタ
>show interface

vlan
>show vlan brief

ルーティング
>show ip route

arp
>show ip arp

mac
>不明

lldp
>不明　多分ない

長いconfig等をenter押下せずにすべて流す
>terminal length 0

■Century Systems
config取得
>show running-config

ポート、フィルタ
>不明

vlan
>不明

ルーティング
>不明

arp
>不明

mac
>不明

lldp
>不明

長いconfig等をenter押下せずにすべて流す
>terminal length 1

■Cisco
config取得
>show running-config

ポート、フィルタ
>show interface

vlan
>show vlan

ルーティング
>show ip route

arp
>show arp

mac
>show mac address-table

lldp
>show lldp neighbors

長いconfig等をenter押下せずにすべて流す
>terminal length 0

■Fujitsu
config取得
>show running-config

ポート、フィルタ
>show interface

vlan
>show vlan brief

ルーティング
>show ip route

arp
>show arp

mac
>show mac detection

lldp
>show lldp

長いconfig等をenter押下せずにすべて流す
>terminal pager 0

■Panasonic
config取得
>show config

ポート、フィルタ
>不明

vlan
>show vlan

ルーティング
>不明

arp
>show arp

mac
>show mac

lldp
>show lldp

長いconfig等をenter押下せずにすべて流す
>不明

■ProCurve
config取得
>show running-config

ポート、フィルタ
>show interfaces

vlan
>show vlans

ルーティング
>show ip route

arp
>show arp

mac
>show mac-address

lldp
>show lldp config

長いconfig等をenter押下せずにすべて流す
>terminal length 0
PrologによるPrologインタプリタ

#はじめに
O-Prologのテストを兼ねて、PrologでPrologインタプリタを書くということをしてみました。お遊びです。本格的なものではありません。

#超手抜きバージョン

```prolog

%prolog in prolog

pp :- 
    repeat,
    nl,write(': ?- '),
    read(X),
    (X=halt -> abort;true),
    (call(X) -> write(yes);write(no)),
    fail.

```


LispでLispインタプリタを記述する場合、evalを使っていいのなら、それはとても容易いことです。(print (eval (read))) で済んでしまいます。同様にPrologのresolveの部分をcall/1を使っていいのなら、上記のようなコードになります。しかし、これではつまりません。


#少し手を加えて


call/1を自前で書いてみます。組込み述語は処理系のものを呼び出すことにします。predicate_property/2で判別しています。O-Prologの場合にはbuilt_inを返すようになっています。（このあたりはISO-Prologの規格でも曖昧なようで、各種処理系によってばらつきがあります）

組込述語ではないユーザー定義の述語だった場合には、その定義された節をclause/2を使って呼び出します。そしてその本体部をmy_callで実行します。

連言と選言も自前で処理することにしました。

```prolog

%prolog in prolog

pp :- 
    repeat,
    nl,write(': ?- '),
    read(X),
    (X=halt -> abort;true),
    (my_call(X) -> write(yes);write(no)),
    fail.

%builtin
my_call(X) :-
    predicate_property(X,built_in),
    call(X).
%user predicate
my_call(X) :-
    predicate_property(X,dynamic),
    clause(X,true),
    write(X),
    get_char(D), %discard EOL
    get_char(Z),
    (\+(Z = ';') -> true;fail).
%user clause
my_call(X) :-
    predicate_property(X,dynamic),
    clause(X,Y),
    Y \= true,
    my_call(Y),
    write(X),
    get_char(D), %discard EOL
    get_char(Z),
    (\+(Z = ';') -> true;fail).
%variable
my_call(X) :-
    var(X),
    call(X).
%conjunction
my_call((X,Y)) :-
    call(X),
    my_call(Y).
%disjunction
my_call((X;Y)) :-
    call(X),!.
my_call((X;Y)) :-
    call(Y).

```

#動作
ちょっと表示がおかしいところもあるますが、それっぽく動作するようにはなりました。

```prolog

O-Prolog Ver 1.19(hiromi)
| ?- ['prolog.pl'].
yes
| ?- pp.

: ?- assert(human(taro)).
yes
: ?- assert(human(jiro)).
yes
: ?- human(X).
human(taro);
human(jiro);
no
: ?- assert((error(X) :- human(X))).
yes
: ?- error(jiro).
error(jiro)
yes
: ?- halt.
| 

```

#改良、拡張
my_callの部分をいろいろ書き換えると面白いと思います。Prolog処理系の動作について興味をもっていただけたら嬉しいです。
超簡単なECサイトを作った

https://torina.top/detail/418/
この方のサイトを参考に、stripe決済を組み込んだ超簡単なecサイトを作ってみました。

１　djangoをインストールして、プロジェクト、アプリを作ります。

２　base.htmlを作って、project/urls.pyに以下を足します。

```
path('',include('base.html')),
```

　　　まずページが出るかrunserverで確認します
　
３　ここから、上記のブログ記事を参考にhtmlファイル、models.py、views.pyを作ります

　　　※忘れそうな所
　　　＠htmlファイル内で別のHTMLを指定する時

```
{% url app:(htmlの前)　pk=book.pk %}→{ url 'htmlの前', pk=book.pk}
```

　　　＠この記事ではtemplateview（汎用ビュー）を使っているため、urls.pyが少し変わります

```
 path('', views.IndexView.as_view(), name='book_list'),
 path('<int:pk>/detail/', views.DetailView.as_view(), name='book_detail'),
```
　　
４　今回は商品の画像も入れたいため、ImageFieldをBookモデルに足します。

![スクリーンショット 2018-07-29 21.50.37.png](https://qiita-image-store.s3.amazonaws.com/0/271893/c1ae3ecc-616a-67dc-bc78-8b0e1048dfb3.png)
![スクリーンショット 2018-07-29 22.23.02.png](https://qiita-image-store.s3.amazonaws.com/0/271893/52cf42e8-4882-8db4-67c6-e5a8a5e03036.png)
![スクリーンショット 2018-07-29 21.50.51.png](https://qiita-image-store.s3.amazonaws.com/0/271893/ba7c8935-8ca6-a0a8-b979-be29085a3b33.png)
![スクリーンショット 2018-07-29 21.54.39.png](https://qiita-image-store.s3.amazonaws.com/0/271893/84b17f56-bbf6-50e2-35ea-2ab8d36fe009.png)

期間：一週間（２０〜時間程度）

参考サイト
https://torina.top/detail/418/

https://qiita.com/narupo/items/e3dbdd5d030952d10661
[C#]  Google Drive API v3を使って特定のフォルダ下にあるファイルをダウンロードする

# 概要
前回、[[C#] Google Drive API v3を使ってGoogle Slidesを取得する](https://qiita.com/nori0__/items/4bcbb571ef347eea7cb3)を投稿したのですが、特定のフォルダ下のファイルだけダウンロードしたい時があったので備忘録としてまとめてみました。

# 特定のフォルダ下にあるファイルをダウンロードする
Google Drive APIでは、フォルダ含め全てのファイル再帰的に取ってきてしまうため、特定のフォルダ下にあるファイルだけが欲しい場合はリクエストパラメータのクエリ構文で指定する必要があります。
つまり、特定のフォルダIDと親フォルダのIDが一致するファイルだけを取得するように指定することが必要です。

ユーザー認証やDrive API serviceを生成する過程は[Google Drive APIs .NET Quickstart](https://developers.google.com/drive/v3/web/quickstart/dotnet)を参照。

クエリ構文で指定するファイルの属性の一覧は[Google Drive APIs Search for Files and Team Drives](https://developers.google.com/drive/v3/web/search-parameters)を参照。

```cs
            // フォルダ「HogeFolder」下のファイル一覧を取得する

            // リクエストパラメータの定義
            // service(DriveService)はユーザ認証部分なので割愛
            var listRequest = service.Files.List();
            listRequest.PageSize = 1;

            // 取得するフォルダの条件をクエリ構文で指定
            listRequest.Q = "(name = 'HogeFolder') and (mimeType = 'application/vnd.google-apps.folder') and (trashed = false)";
            listRequest.Fields = "nextPageToken, files(id)";

            // フォルダIDの取得
            var folderId = listRequest.Execute().Files.First().Id;

            // フォルダ「HogeFolder」下のファイルの条件をクエリ構文で指定
            // '{folderId}' in parentsにより、フォルダ「HogeFolder」下にあるファイルとフォルダのみが対象となる
            listRequest.Q = $"('{folderId}' in parents) and (mimeType != 'application/vnd.google-apps.folder') and (trashed = false)";
            listRequest.Fields = "nextPageToken, files(id, name)";

            // ファイル一覧の取得
            var files = listRequest.Execute().Files;

            // 一番最初にとれたファイルのIDを取得する
            var id = files.First().Id;

            // 保存するファイル先を指定する
            string saveTo = "HogeFolder";
            
            // ファイルをダウンロードする
            var request = service.Files.Get(id);
            var filest = new System.IO.FileStream(Path.Combine(saveTo, files.First().Name), System.IO.FileMode.Create, System.IO.FileAccess.Write);
            request.Download(filest);    
```

# 参考
http://yh9092.hatenablog.com/entry/2017/12/08/202855
Javaの基礎を振り返る

#前書き
Javaの復習をしていたのだけど、基本的な部分が微妙なところに気がついた。
自分の理解を記録しておく

#参照渡しと値渡し
参照渡し　→　メモリ上の場所を渡す
値渡し　　→　値をそのまま渡す

###Javaだとどうなの？
Javaには値渡ししかない
プリミティブ型　→　そのままの値渡し
オブジェクト型　→　参照「値」渡し

###参照値渡しとは
ポインタを渡すこと（メモリ上でデータが置かれている場所の情報）
なので
メソッドに参照値を渡すと元の値を操作できる

```
public void sampleMethod(Object o){
	o = 1;
}
```

ただしnewすると参照値の書き換えが起こるためそのあとで変更を加えても元の値に影響なし
でreturnしないと使われない参照値が誕生する

```
public void sampleMethod(Object o){
	o =  new Object();
	o = 1;
}
```

###Stringについて
Stringはオブジェクト型なので参照値渡しされる
でも値を置き換えても元の値が変わらない
→　変更不可のクラスだから
Stringは変更を加えるたび裏では新しいオブジェクトが作られてる（新ポインタに変更される）
よって元のオブジェクト変更ができない
よってこれは結果は同じでも値渡しとは違う動き


#コンポジション
あるクラスに別のクラスを取り込むこと

###なぜいる？
他のクラスを使うために継承があるが、継承を使うと予期しない動作をすることがあるため
＜継承＞

```
public class InstrumentedHashSet<E> extends HashSet<E> {
private int addCount = 0;

public InstrumentedHashSet(){
}

@Override
public boolean add(E e){
 addCount++;
 return super.add(e);
}

@Override
// addAllは内部的に引数をループしてaddしている
// そのためこのクラスではオーバーライドされたaddが使われカウントがaddの分とaddAllの分重なって進んでしまう。
// つまり継承してメソッドをオーバーライドする場合、対象メソッドが別のオーバーライドしたメソッドを利用しているとその影響を受けてしまう。
public boolean addAll(Collection<? extends E> c){
 addCount += c.size();
 return super.addAll(c);
}

public int getAddCount(){
 return addCount;
}
}
```

＜コンポジション＞

```
// 転送クラス
// 別にこれを作らなくてもコンポジション自体はできる。
public class ForwardingSet<E> implements Set<E>{
// コンポジション
private final Set<E> s;

// ここで使われるSetはあくまで引数で渡されたもの
public ForwardingSet(Set<E> s){
 this.s = s;
}

public void clear(){
 s.clear();
}

public boolean add(E e){
 return s.add(e);
}

public boolean addAll(Collection<? extends E> c){
 return s.addAll(c);
}

// Setの抽象メソッドをOverrideする(省略)
}


// ラッパークラス
public class RapperSet<E> extends ForwardingSet<E>{
private int addCount = 0;

// スーパークラスのベースにしたいSetを渡す
public RapperSet(Set<E> e){
 super(e);
}

@Override
public boolean add(E e){
　addCount++;
　return super.add(e);
}

@Override
public boolean addAll(Collection<? extends E> c){
addCount += c.size();
// ここで使われているaddAll()はスーパークラスで使われているaddAll()
// つまり引数として渡されたクラスのaddAll()。rapperSetのadd()は関係ない
return super.addAll(c);
}

public int getAddCount(){
return addCount;
}
}
```
【まだ未完成なので更新します】MySQL5.7 修正と罠のまとめ

# 間違えて投稿してしまいましたが、まだ未完成なので、更新します。

# 概要

MySQLのバージョンによる修正が何があったのか、バージョンアップすると既存のものにどのような影響を与えるのかをまとめる。そのうち8.0へのアップデートの修正点などもまとめる予定。先人の知恵をまとめることとなるので、悪しからず。本当に助かっております。


# 主な修正点

# 罠

日々の覚書: MySQL 5.7.4で導入されたdefault_password_lifetimeがじわじわくる の公開以来大反響をいただいていた （ブクマ がすごいことになっていて、思わず ばぐれぽ にブクマのリンクを貼り付けたほど）default_password_lifetime が。

5.7.11でついにデフォルト0になる！！！ やった！！！ やったよ！！！

ドキュメントはもう"default: 0 (>= 5.7.11)"の記載になってる。


これで、

MySQL 5.7にアップデートしてから

360日後にやってくる

パラメーターの意味は読んで字のごとく、「最後にパスワードが更新されてからこの期間が経つと、パスワードをEXPIREする」。暗黙のデフォルトは360で、単位は日。つまり何もいじらないと、新規作成したユーザーは360日後にパスワードがEXPIREされてアプリが止まる。。

事象がなくなった。


# 最低限これだけは知ってほしい5.7

16桁ハッシュのパスワードの廃⽌
default̲password̲lifetime 
sql̲modeのデフォルト値変更
log̲error̲verbosity vs. log̲warnings
テンポラリーテーブルがInnoDBに 15/172

# 一応知っていてほしい5.7

mysql.user.passwordカラムの廃⽌
認証周りの構⽂の変更
secure̲file̲priv
log̲timestamps
mysql̲install̲db
mysqld –initialize
InnoDBバッファプールの暖気がデフォルトでONに
binlog̲formatのデフォルト変更
rpmパッケージではvalidate̲passwordプラグインがデフォルトで有効
innodb̲default̲row̲formatの注意

#　参考

[MySQL 5.7にやられないためにおぼえておいてほしいこと](https://www.slideshare.net/yoku0825/mysql-57-53449734)
【javascriptでカウントダウンタイマーを作る】part.2 忘備録

# 完成形のイメージ
日本人の平均男性が80歳ぐらいまで生きると想定し、
自分の年齢を入力して余生を日数ではなく時間単位でカウントダウン表示する

#実装したい機能を言葉にしよう
今回考えなければならないは
**"自分の年齢と睡眠時間を選択した際に選択した値をどうやって表示するか"**

# 実装したい機能を細かくブレークダウンする
"自分の年齢と睡眠時間を選択した際に選択した値を時間単位で表示する"機能は、
以下のように細かく分けられる。

1 : プルダウンメニューを作る
2 : プルダウンメニューから選択した値を取得
3 : 取得した値を画面に出力
4 : 出力形式を調整(100000時間なら100000:00:00:000てな感じかな。)
etc....

# 今日の課題はプルダウンメニューを作る -> プルダウンメニューから選択した値を取得
htmlファイルに以下のように記述。

```html:life_timer.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charaset="utf-8">
<title>LIFE TIMER</title>
</head>
<body>
    <div id="timer">00:00:000</div>
    <div id="controls">
        <button id="min">Min</button>
        <button id="sec">Sec</button>
        <button id="reset">Reset</button>
        <button id="start">Start</button>

        <p>年齢を選択してください</p>
        <select id="age">Age</select>    <- こいつと
        
        <p>一日の睡眠時間を選択してください</p>
        <select id="sleep"></select>　　　　　　　　　　<- こいつ
    </div>
    <script src="life_timer.js"></script>
</body>

</html>
```
# javascriptでプルダウンメニューと選択した値の情報を変数で保持
ちなみにalertで選択した値を出力するようにしています。

```javascript:life_timer.js
 //年齢を選択する時に発火する関数
    setAgeNumber();

    function setAgeNumber(){
        for(var i = 10; i <= 80; i ++){
            var option = document.createElement("option");
            option.value = i;
            option.innerText = i;
            Age.appendChild(option);
        }
    }

    //年齢を選択するプルダウンメニューを変更したら発火
    Age.addEventListener('change',function(){
        var ageValue = document.getElementById("age").value;
        alert(ageValue);
    });


    //睡眠時間を選択する際に発火する関数
    setSleepNumber();

    function setSleepNumber(){
        for(var i = 1; i <= 24; i++){
            var option = document.createElement("option");
            option.value = i;
            option.innerText = i;
            Sleep.appendChild(option);
        }
    }

    //睡眠時間を選択するプルダウンメニューを変更したら発火
    Sleep.addEventListener('change',function(){
        var sleepValue = document.getElementById("sleep").value;
        alert(sleepValue);
    });


```
# 課題
明日は、
**"取得した値を画面に出力"**
に挑戦です。
java SE8 Goldの取得と勉強方法

javaの現場に戻ってきたので、その現場に長くいられるように箔をつけようという不純な動機でjava SE8 Gold(OCJP SE8 GOLD)(Java SE 8 Programmer II)を受験しました。一発で無事合格したので、勉強方法をまとめたいと思います。

## <a id="index" href="#index">目次</a>
* [いきさつと経歴](#section1)
* [勉強方法](#section2)
* [所感](#section3)


# <a id="section1" href="#section1">いきさつと経歴</a>
いきさつと経歴としては、冒頭にある通りjavaを使用している現場に1年近くいたあと、非常にマイナーな言語のプロジェクトにいました。その後、もろもろあってjavaの現場に戻ってきました。私はSIer所属で、私を売ってくださるのは営業と管理職の努力の賜物です。そのご恩に応えるべく既に取得済みだったjava SE8 SilverからGoldへランクアップすることにしました。

<p class="ec__link-index"><a href="#index">[↑ 目次へ]</a></p>

# <a id="section2" href="#section2">勉強方法</a>
勉強方法は大きく5カ月間にわたる3段階で実施しました。
まず、ホップとして、学習方法をググってみました。
特に参考になったサイトは、QiitaのKido Takeru様のサイトになります。
<a href="https://qiita.com/infhyroyage/items/04732bdc42b897bc8614">Java SE 8 Programmer IIの合格体験記とか語ってみる</a>Gold範囲を網羅的に説明があり、またどの書物を使って勉強すればいいか理解できました。
次にステップとして、本を購入したうえでコーディングを実施しました。
紫本、白本、黒本3冊を購入し、手始めに紫本を熟読しました。
その後、紫本のソースや黒本の問題のソースをコーディングしながら理解を深めていきました。
大体4カ月間このステップに費やしました。
最後のジャンプとして、黒本の模擬試験と黒本でダウンロードして手に入る問題さらにOracle公式に出している問題を1カ月間解き続けました。正直何か理解できたと思ったら、何かを混乱して理解し始めたりして、あまりよくなかった気がします。ただ、本番そっくりに近い問題もあり、頭がいい人や普段からSE8でコーディングしている人ならば、ステップなしでジャンプだけで受かるかもしれません。

<p class="ec__link-index"><a href="#index">[↑ 目次へ]</a></p>

# <a id="section3" href="#section3">所感</a>
私は朝一が頭回転するので、近所のテスト試験会場で最も早い時間で受けました。解答及び確認含めて時間は40分ほど余ってしまいました。試験後10分くらいして、合格と表示されたとき、信じられなくて、友人に自分の名前と合格かLineでスクショを確認してもらいました(笑)。もしかすると、問題が易しい回だったのかもしれません。乱数の神様に感謝。

<p class="ec__link-index"><a href="#index">[↑ 目次へ]</a></p>


編集後記
恐らく多くの人が言っている黒本最強説は揺るがないでしょう。ただ、Java SE11が間もなくリリースされる今取るメリットはあまりないかもしれません(笑)。

初稿：2018-07-29
rbenvでruby最新バージョンがインストールリストにない

## 環境
- mac
- Homebrew
- rbenv
- ruby-build

## 今回悩んだこと
rbenvでruby2.5.1をインストールしようと思って以下コマンドでインストールできるリストを表示したが、2.5.1が見当たらなかった。

```
$ rbenv install -l
```

## 解決するために行ったこと
- まずはHomebrewのアップデート

```
$ brew update
```

- rbenvのプラグイン```ruby-build```をアップデート

```
$ brew upgrade ruby-build
```

- 最後にもう一度 ```rbenv install -l``` でruby2.5.1が表示されているかを確認して、あとは通常通りインストールして終了
 
```
$ rbenv install 2.5.1
```


ここに忘れないように書き残しておく。
Sequelize-Autoを使ってみた。

# Sequelize とは
Node.js用のO/Rマッパー。

### O/Rマッパー とは
DBに対してSQLを実行した結果をオブジェクトにマッピングするライブラリ。CRUD処理がある程度実装されているものが多い。

# Sequelize の導入
[O/Rマッパー Sequelize による DB 連携](https://qiita.com/tatsurou313/items/2ba0387806b07f442b8c#or%E3%83%9E%E3%83%83%E3%83%91%E3%83%BC-sequelize-%E3%81%AB%E3%82%88%E3%82%8B-db-%E9%80%A3%E6%90%BA)

DB設計の段階など、まだDBを作っていないときは
DBを定義した雛形ファイルを作ってマイグレーションする。

[nodejs + express + sequelize webサーバ最小構成](https://qiita.com/yu-sa/items/d8edad8d9a91d0ddeb12#db%E4%BD%9C%E6%88%90-db-migration%E5%AE%9F%E8%A1%8C)

# 既存のDBスキーマからmodelを作りたい
フレームワークで用意されていることが多い。
[例]
SAStruts: [gen-entity](http://s2container.seasar.org/2.4/ja/s2jdbc_gen/tasks/gen_entity.html)
C# MVC.NET: [scaffold](https://qiita.com/Chrowa3/items/756abc2452f54df7a088#dizzy-scaffolding)
Rails: [migration](https://qiita.com/gctoyo/items/5866d4bcc8c4fe79a9db)

# sequelize-auto
[sequelize-auto](https://github.com/sequelize/sequelize-auto)を使ってみる。

### sequelize-autoをグローバルにインストール

```
$ npm install -g sequelize-auto
```

### mysqlをグローバルインストール(mysql2を要求される場合も)

```
$ npm install -g mysql
```

### sequelize-autoを実行する

```
$ sequelize-auto -h <ホスト名> -d <データベース名> -u <ユーザ名> -x [パスワード] -p [ポート番号]  --dialect [例：mysql] -c  -o [出力ディレクトリ]
```

## sequelizeで自動生成したmodelをインポートする
requireなどでインポートしても、sequelizeのメソッドが使えないので

```js

sequelize.import(＜相対パス＞)
```
とする必要がある。

```js

var findAll = function findAll(callback) {
    const player=sequelize.import('../models/player');
    player.findAll({attributes: ['id', 'name','team_id']})
    .then((record) => {
      callback(setResult(200, record, null));
    })
    .catch((err) => {
      callback(setResult(500, null, err));
    });
  };
```
Amazon Macieでs3に対する意図しないユーザーからのアクセスを検知する


こんにちは、ひろかずです。

s3に機密データを格納している場合、ACLを設定していても許可以外のユーザーからのアクセスがあるのか心配になりますよね。

今回は、Amazon Macieを使って簡単にアラートを作ることができたので、一筆書きます。

# 参考ドキュメント
[Amazon Macie ユーザーガイド](https://docs.aws.amazon.com/ja_jp/macie/latest/userguide/macie-ug.pdf)

# 前提条件
- オレゴンかバージニアリージョンにてMacieを有効化していること
- MacieでCloudTrailの情報を評価できる状態になっていること

# 工程
1. カスタムベーシックアラートの作成
2. SNSトピックの作成
3. 動作確認

# 1. カスタムベーシックアラートの作成
## 検出したい動作を抽出するクエリーの作成
クエリーの検索結果からベーシックアラートを作ります。
Macie管理画面のナビゲーションペインの`RESEARCH`を選択して、以下クエリー文をクエリー窓に入力します。

今回は、MYBACKETNAMEというs3バケットに対する、`GetObject`, `PutObject`, `DeleteObject`の操作を成否を問わず検出するクエリーにしました。

```
(eventNameErrorCode.key:"GetObject" OR eventNameErrorCode.key:"PutObject" OR eventNameErrorCode.key:"DeleteObject"); AND; resources.key:"arn:aws:s3:::MYBACKETNAME"
```

Search(虫眼鏡)アイコンをクリックすると、検索結果が表示されます。
検索結果を確認しながら、クエリーを調整するといいでしょう。

![Macie-s3-01.png](https://qiita-image-store.s3.amazonaws.com/0/46611/2cc9170b-3cb9-d537-09d8-08658a1b2911.png "Macie-s3-01.png")

## ホワイトリストに掲載するユーザー表記の確認

検索結果が妥当であれば、検索結果からホワイトリストに登録するユーザー表記を確認します。

- ホワイトリストには、Macie unique IDという形式で登録する必要があります。

検索結果の後半に`The following are top 10 matching results:`というセクションがあるので、展開します。

![Macie-s3-02.png](https://qiita-image-store.s3.amazonaws.com/0/46611/c64b312b-fffc-5193-c5de-7243d282bb62.png "Macie-s3-02.png")

Macie unique IDを見ると、`awsmacieservicecustomerservicerole`というものがありますね。
Macieのサービスロールによるアクセスなので、ホワイトリストに登録することにします。

- その他に、意図されているIAMロールやIAMユーザーのアクティビティを探して、Macie unique IDを控えておきます。

## カスタムベーシックアラートの作成
クエリー窓下の▲ボタンを選択して、カスタムベーシックアラートを作成します。

![Macie-s3-03.png](https://qiita-image-store.s3.amazonaws.com/0/46611/e6866f50-2590-6bd2-43e5-73ce97adcb66.png "Macie-s3-03.png")

アラートタイトルとディスクリプションを適宜設定します。

Severutyは、ひとまず`Informational`にしておきますが、検知状況を見ながら適宜調整するといいでしょう。
Whitelisted Usersには、このような形で登録しておきます。
最後に`Save`します。

![Macie-s3-04.png](https://qiita-image-store.s3.amazonaws.com/0/46611/66baac1d-fbfe-e9db-e73a-43d9206d3c67.png "Macie-s3-04.png")

# 2. SNSトピックの作成
[Amazon Macie ユーザーガイド](https://docs.aws.amazon.com/ja_jp/macie/latest/userguide/macie-ug.pdf)を参照して、SNSトピックを作成します。

# 3. 動作確認
ホワイトリストに掲載していないIAMユーザーを使って、当該バケットに対してPutとDeleteを行いました。
また、権限を外して、Putを行っています。

20分後くらいに検知がありました。

- 今回は、アラートタイトルを`Non Systematic Access to s3 Buckets`としました。

![Macie-s3-05.png](https://qiita-image-store.s3.amazonaws.com/0/46611/2bdcc7df-908a-c0bc-54bf-278da239cbad.png "Macie-s3-05.png")

アラート選択して、内容を確認します。

![Macie-s3-06.png](https://qiita-image-store.s3.amazonaws.com/0/46611/63fc5ab2-aa5f-b8df-f6f9-02ece9e9d9b9.png "Macie-s3-06.png")

試行回数は3回なので、Total resultsは合ってます。
Error codesが`AccessDenied`となってますね。
正しくは2回成功、1回失敗なのですが...

Alert detailsを見ると内訳がわかりますね。

![Macie-s3-07.png](https://qiita-image-store.s3.amazonaws.com/0/46611/9c433e4f-3f0f-ea33-9470-c4802a276ec9.png "Macie-s3-07.png")

検知内容を見る時は、Alert detailsを確認するといいでしょう。

# 最後に
これまでは、同じことをしたい場合は、Cloudwatch Events Rulesを使うのが定石だったと思いますが、選択肢が一つできた感じですね。

クエリーのアドホック分析をしながら、結果をアラートにできるので、設定は作りやすいと思います。

今日はここまでです。
お疲れ様でした。
[MySQL] 外部キー制約を無視して全テーブルのデータを削除する

「全テーブルのデータを一括で削除したい。」は、以下のコマンドで実現できます。

```
mysql -u[user] -p[password] [database name] -N -e  'show tables' | xargs -IARG mysql -u[user] -p[password] -e 'truncate table ARG' [database name]
```

しかし、外部キー制約のあるテーブルが存在すると以下のエラーメッセージが表示され、データを削除できないことが分かります。

```
ERROR 1701 (42000) at line 1: Cannot truncate a table referenced in a foreign key constraint
```

こんなときは、外部キー制約を無視する以下の命令を指示すればいいのですが、mysqlコマンドから抜けるたびに命令が無効になります。

```
SET FOREIGN_KEY_CHECKS=0;
```

なので、以下のようにデータを削除する寸前で命令を指示すれば期待通りに動作します。

```
mysql -u[user] -p[password] [database name] -N -e  'show tables' | xargs -IARG mysql -u[user] -p[password] -e 'SET FOREIGN_KEY_CHECKS=0; truncate table ARG;' [database name]
```
Visual Studio CodeのSettings Syncでtokenを再設定する方法

## 環境
- Visual Studio Code: Version 1.25.1
- OS: Mac OS High Sierra Version 10.13.6
- 言語設定: OS, VSCode 共に English

記事内で説明しているショートカットは、Mac以外の方は自分のOSのものに読み替えてください。

access tokenの生成方法やSettings Syncの設定方法はこの記事で説明しないので、公式ページやググって出てきた記事を参考にしてください。

**この記事は2018年7月29日時点のSettings Syncの最新バージョンで説明しているため、ご覧になっている方とは主に画面が異なっている可能性大です。
ただ、やること自体はほとんど変わらないはずです。**



## 問題
Gistのaccess tokenがわからなくなり、会社のPCでSettings Syncの設定ができず、tokenを再度generateしたらプライベートのPCでこうなりました。

```
Sync : Invalid / Expired GitHub Token. Please generate new token with scopes mentioned in readme. Exception Logged in Console.
```

![Invaild-or-Expired-token.png](https://qiita-image-store.s3.amazonaws.com/0/130946/8e5c6af5-d17f-86bf-c406-fff7e3833959.png)


こうなる理由は、Settings Syncのローカル設定（各PC毎の設定）で設定されているtokenが誤っているため。しかし、誤っていてもtokenを入力するダイアログは出してくれないため、自分で設定する必要があります。

Settings Syncの初回設定時はローカル設定のtokenが空なので、tokenを入力するダイアログを出してくれます。

![enter-token.png](https://qiita-image-store.s3.amazonaws.com/0/130946/1f73af00-c06e-edf1-d742-983d4b0a421e.png)



## やり方
`shift+cmd+p` でコマンドパレットを開く。`sync` と打って表示される `Advanced Options` を選択。

![Advanced-Options.png](https://qiita-image-store.s3.amazonaws.com/0/130946/a495f59f-ad60-7997-8c06-3ed4e4795ccd.png)


Advanced Options一覧が出るので `Edit Extension Local Settings` を選択。

![Edit-Extension-Local-Settings.png](https://qiita-image-store.s3.amazonaws.com/0/130946/2a52c0b6-7fd7-5b7a-9e9c-ba23a5b31d18.png)



`syncLocalSettings.json` が開くので、その中の `token` の値を古いtokenから新しくgenerateしたtokenに変更。

![syncLocalSettings.png](https://qiita-image-store.s3.amazonaws.com/0/130946/9c239b5f-fd49-c5b2-88ae-b86a00c48fea.png)


以上です。


ちなみに、`Advanced Options` のほとんどは、User Settingsでも設定可能、というよりコマンドパレットで設定したら `settings.json` に書き込まれるだけです。

![User-Settings.png](https://qiita-image-store.s3.amazonaws.com/0/130946/ef51cf54-25aa-61dc-f2c1-75012bc9aade.png)


## 参考
[Settings Sync - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync)
『一般ユーザーでssh接続できるDocker環境』をDockerファイルで作成する

リモートサーバーにssh接続をして作業をするという機会は多いと思います。

Dockerとssh接続できるようになれば、仮想のリモートサーバーとして扱えるためssh接続を利用したテストをローカルで行うことができます。
今回、『一般ユーザーでssh接続できるDocker環境』を作成するDockerファイルを用意したのでその共有をしたいと思います。


## 公開されている『ssh接続できるDocker環境』を作成するDockerファイル
<a href="https://docs.docker.com/engine/examples/running_ssh_service/" target="_blank">こちら</a>でssh接続できるDockerファイルが共有されているのでこれを利用します。

```Dockerfile
FROM ubuntu:16.04

RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd
RUN echo 'root:screencast' | chpasswd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config

# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

# For executing shellscript
RUN apt-get install -y git less vim sudo
RUN useradd -m isucon
RUN echo 'isucon:isucon' | chpasswd
RUN usermod -aG sudo isucon

EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
```


オリジナルのDockerファイルに一般ユーザーを作成する手順を追加します。
今回はisuconというsudo権限をもつ一般ユーザーを作成しています。

```diff
FROM ubuntu:16.04

RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd
RUN echo 'root:screencast' | chpasswd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config

# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

+ # Create User
+ RUN apt-get install -y git less vim sudo
+ RUN useradd -m isucon
+ RUN echo 'isucon:isucon' | chpasswd
+ RUN usermod -aG sudo isucon
+ RUN chsh -s /bin/bash isucon

EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
```



## Dockerファイルをビルドして環境を構築する

作成したDockerファイルをビルドしてDockerイメージを作成します。
ここではssh_script_sandboxというイメージ名のDockerイメージを作成しています。

```
$ docker build -t ssh_script_sandbox .
```

作成されたssh_script_sandboxというDockerイメージを利用してDockerコンテナを起動します。

ここではssh_script_containerという名前のコンテナをバックグラウンドで実行しています。
なお、ホストの20022番ポートとDockerコンテナの22番ポート(sshで利用されるポート番号)をポートフォワードしています。

```
$ docker run -d -p 20022:22 --name ssh_script_container ssh_script_sandbox
```

localhostの20022に対してssh接続することでDockerコンテナにログインできるようになります。

```
$ ssh isucon@localhost -p 20022
```


今回の詳細は<a href="https://nishinatoshiharu.com/how-to-use-dockerfile/" target="_blank">Dockerファイルの使い方は?具体例で学ぶ、他人が作った環境を共有する方法</a>でも解説をしているので、興味のある方はご覧になってください。

by <a href="https://twitter.com/nishina555" target="_blank" rel="noopener">@nishina555</a>
sudo権限をもつ一般ユーザーをDockerコンテナに作成するチートシート

プログラミングをしていて「検証環境をつくりたいなー」というときにDockerは非常に役にたちます。

シェルスクリプトのテストをするために『sudo権限をもった一般ユーザーが存在する環境』をDockerで構築したので、環境構築のチートシートを今回用意しました。

一般ユーザーの作成手順は、Dockerだけでなく、VPSを借りたときにも利用できるので活用していただければと思います。

## 今回作るDockerコンテナ

作成するコンテナは以下のようなスペックです

- OSはubuntu
- isuconというsudo権限をもつユーザーが存在する
- 一般ユーザー(isucon)のログインシェルは/bin/bash
- 最低限のコマンド(git, less, vimなど)がインストールされている

## Dockerコンテナを立ち上げ、ログインする

`docker run -it` でコンテナの立ち上げてコンテナにログインできます。

今回はubuntuのDockerイメージからshell_containerというコンテナ名のDockerコンテナを作成しています。

```
$ docker run -it --name shell_container ubuntu /bin/bash
```

## 必要なコマンドのインストール
ubuntuコンテナには基本的なコマンドもまだ用意されていないので、最低限のコマンドをインストールします

```
$ apt-get update && apt-get install -y git less vim sudo
```

## sudo権限をもつユーザーを作成する

ユーザーの作成をします。-mでホームディレクトリも作成します。

```
$ useradd -m isucon
```

isuconユーザーのパスワードを作成します。

```
$ passwd isucon
```

isuconユーザーにsudo権限を与えます

```
$ usermod -aG sudo isucon
```

isuconユーザーのログインシェルを変更します。

```
$ usermod -s /bin/bash isucon
```

## (補足) 作成したDockerコンテナを再利用する場合
docker commitをすることでコンテナの環境をDockerイメージとして保存することができます。

以下のコマンドでshell_containerというコンテナをshell_sandboxというイメージ名で保存できます。

```
$ docker commit shell_container shell_sandbox
```

以下のコマンドでcommitしたshell_sandboxのイメージからコンテナを立ち上げることができます。

```
$ docker run -it shell_sandbox /bin/bash
```

## まとめ
今回はdocker runを利用して『sudo権限をもった一般ユーザーが存在する環境』を作る手順の説明をしました。
今回の詳細は<a href="https://nishinatoshiharu.com/create-sandbox-with-docker/" target="_blank">Dockerでサクっと検証環境(テスト環境)を構築するための手順</a>でも解説をしているので興味のあるかたはご覧になってください。

by <a href="https://twitter.com/nishina555" target="_blank" rel="noopener">@nishina555</a>
Vue.jsでAPI通信中にloading表示をする

# はじめに

APIからのレスポンスを受け取るまではloading表示をしておいて、結果を受け取ってから内容表示するようにします。

## Js

```javascript:index.js
var app = new Vue({
    el: '#app',
    data: {
        results: [],
        loading: true
    },
    components: {
        'item-component': ItemComponent
    },
    mounted () {
        axios
            .get("api.php")
            .then(response => {
                this.results = response.data;
                this.loading = false;
            })
    }
});
```

`loading` のプロパティを用意し、初期状態では`true`にしておきます。
axiosでのAPI通信が終わったタイミングで`false`にします。

## (好みに応じて)loading表示の素材

必須では無いのですが、テキスト表示だけだと寂しいので、下記サイトから気に入ったloading表示を `loading.css` としてローカルに保存しておきます。

[Single Element CSS Spinners](https://projects.lukehaas.me/css-loaders/)

## HTML

下記のように `v-show` 属性に上記の`loading`を指定し、loading表示部分と結果表示部分が状況に応じて排他的に表示されるようにします。

```html:index.html
<div v-show="loading" class="loader">Now loading...</div>
<div v-show="!loading" class="itemContainer">
    <item-component
        v-for="(result, index) in results" :key="index"
        v-bind:id="result.id"
        v-bind:name="result.name"
        v-bind:value="result.value"
    >
    </item-component>
</div>
```
社内ナレッジを階層化し管理する

# 社内でナレッジ活用できていますか？
社内にある有益な情報を活用できていますか？
自分しか(もしくはあの人しか)知らない操作方法やコツはありませんか？
どこに情報を貯めればよいか明確ですか？

# ナレッジを貯められない・活用できないのはなぜか
このような負の連鎖に陥ってませんか？

ナレッジがないから貯めようとしても、
どこに貯めてよいのかわからないから**適当に貯める**
↓
適当に貯めるから、**情報の場所を把握できない**
↓
情報の場所を把握できないから、**貯める場所がわからない**
↓
貯める場所がわからないから、**適当に貯める**
↓
適当に貯めるから・・・

このような状態ではナレッジは正しく貯まりません。

![ナレッジ負のサイクル.png](https://qiita-image-store.s3.amazonaws.com/0/263190/84acd041-e7ea-34e7-9d1f-20584fd39538.png)

**似たような情報、どっちが正しいの？**
**管理されていないページ、これ信用できるの？**
**新規参画者の悲鳴、情報がまとまっている場所はないの？**

# いかにしてナレッジを貯めるのか
まずはナレッジを階層を意識して管理してみましょう。
ファイルサーバでもconfluenceでも構いません。

わかっているけど始められない、時間が取れない方は
下記の階層を参考に新しく階層を作ってみてはいかがでしょう？

## ナレッジを階層管理する
★プロジェクト階層
└サービス仕様
　　└サービスの目的
└システム仕様
　　└設計書
　　└サーバ構成図
　　└ネットワーク図
　　└開発・本番環境一覧
└ロードマップ
　　└スケジュール
　　└企画
　　└開発
└開発ドキュメント
　　└開発案件
　　　　└2018H1
  　　　　└XX開発
  　　　　└YY開発
　　└コーディングルール
　　└リリース手順
　　└テスト観点一覧
└事故・障害
　　└緊急時のルール
　　└過去の対応
　　　　└2018H1
　　　　　　└2018MMDD-XX事故
　　　　　　└2018MMDD-YY事故
└運用
　　└運用ルール
　　└アラート対応表
　　└運用手順書
　　　　└XX手順
　　　　└YY手順
└技術情報
　　└勉強会
　　　　└XX勉強会
　　└技術Tips
　　　　└XXする方法
　　└技術調査
　　　　└XXに関する調査
└チーム
　　└開発フロー
　　└スキルマップ
└MTG(議事録)
　　└2018H1
　　　　└2018MMDD-XX議事録
└etc
　　└どこに置いたらいいかわからない情報

## 階層化する上で気にしないといけないこと
![ナレッジサイクル.png](https://qiita-image-store.s3.amazonaws.com/0/263190/d9543d46-fe18-c2ea-9759-05c8b868f067.png)

- 必要な階層はあらかじめ作っておく
- 探しやすいような階層分けを心がける
- 困ったとき・急ぎのときのためになんでも置いて良い階層を作っておく(あとで整理する) 

# より良い状態を保つためには
## ルールを作りましょう
きっちりしすぎた細かいルールは形骸化する恐れもあります。
できるだけシンプルなルールを作ると良いでしょう。

ルールはいつのときでも絶対ではありません。
プロジェクトの状態が変わればルールも変わります。
柔軟にチームでルールを決めて変更していきましょう。

## 定期的にパトロールしましょう
参画歴の浅い人による更新や急いでいるときの資料作成、
予期せぬミスなどで階層が汚れてしまうこともあると思います。

1週間でも1ヶ月でもいいので、定期的に明らかにおかしい配置のものがないか確認しましょう。

コストはあまり割きたくないので、有志で数名で活動するとよいのではないかと思います。

## みんなで情報を育てる意識
情報は財産です。
今日あなたがハマって消費した時間はムダではありません。
次の誰かの役に立てばよいのです。

困ったらココを見る。困ったときのためにココに置く。
お互いに助け合うための目的をしっかり共有しましょう。
LINE BOTサーバがInternalServerErrorになる原因を突き止めた

為替レート等を確認するLINE BOTを作りたくて、先ずは、[先人の解説](https://qiita.com/yakan10/items/b7ad35c2cbba5db81462)を真似てHerokuにオウム返しのBOTを作ってみました。２度目は、為替データ等データベースは自前サーバにあるので、自前サーバ(DTI VPSのCentOS 6)にオウム返しサーバを立ててみました。

# 発生した問題

１度目同様、[LINE Developers](https://developers.line.me/ja/)でチャネルを作成し、``Webhook URL``に自前サーバのアクセスポイントを設定したのですが、LINE Developersのページでは、以下のようなエラーが表示され、何かおかしいことになっているようでした。

```:Webhook接続確認時のエラー
Webhookが無効なHTTPステータスコードを返しました（期待されるステータスコードは200です）
```

# 試したこと
## localhostで試してみる

自前サーバには開発ツールを入れてないので、手元の開発PCであれば詳しく原因追求できるだろうと試してみることにしました。

その際、Chromeの拡張機能の[Restlet Client](https://chrome.google.com/webstore/detail/restlet-client-rest-api-t/aejoelaoggembcahagimdiliamlcdmfm)を使って、以下のお試しJSONを入力しました。

```json:お試しJSONのBODY
{
  "events" : [
    {
    "replyToken": "012345",
    "message": {
      "type": "text",
      "text": "こんにちは"
      }
    }
  ]
}
```

まず、オウム返しBOTの初期化処理にて、アクセストークンやChannel Secretを間違えている（設定できていない）ことを疑ったのですが、仕込んだログを見る限りではきちんと設定できています。

先述したJSONをPOSTした際、``code 400, message Bad request syntax``等と表示されます。さらに、ログ表示が化けてしまい、エラーの内容がよくわかりません（結局ログが読めない件は解決していません）。

```:エラー内容
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://XXX.XXX.XXX.XXXX:5000/ (Press CTRL+C to quit)
121.95.125.202 - - [29/Jul/2018 17:29:06] code 400, message Bad request syntax ('\x16\x03\x01\x02\x00\x01\x00\x01ü\x03\x0û\x117\'G\x1dÙµÉ5\x0bÛ}âÇ ]+XÀÿ\x08¼\x1b\x80\x19ÿæa\x13\x01\x13\x02\x13\x03À+À/À,À0Ì©Ì¨À\x13À\x14\x00\x9c\x00\x9d\x00/\x005\x00')
121.95.125.202 - - [29/Jul/2018 17:29:06] "üeëù®rû7'GÙµÉ5
（中略）
HTTPStatus.BAD_REQUEST -
```

# 解決策

結論を言うと、自前サーバと開発PCでは、エラーの原因が異なっていました（開発PCでのエラーの原因は未だに不明です）。

``/var/log/httpd/ssl_error_log``を見れば一目瞭然でした。

```ssl_error_log
mod_wsgi (pid=9081): Failed to exec Python script file '/var/www/py/bot/app.py'.
mod_wsgi (pid=9081): Exception occurred processing WSGI script '/var/www/py/bot/app.py'.
Traceback (most recent call last):
  File "/var/www/py/bot/app.py", line 23, in <module>
    YOUR_CHANNEL_ACCESS_TOKEN = ini['line']['access_token']
  File "/opt/rh/rh-python35/root/usr/lib64/python3.5/configparser.py", line 956, in __getitem__
    raise KeyError(key)
KeyError: 'line'
```
オウム返しBOTでは、アクセストークンとChannel SecretをINIファイルに外出ししているのですが、それが読めていませんでした。

WSGI scriptと同じフォルダにあるINIファイルを読むように変更して解決しました。

```python:修正前
from configparser import ConfigParser
ini = ConfigParser()
ini.read('bot.ini')
```

```python:修正後
from configparser import ConfigParser
ini = ConfigParser()
config_file = os.path.join(os.path.dirname(__file__), 'bot.ini')
ini.read(config_file)
```

# 環境と条件
  * ホストOS： CentOS 6
  * ゲストOS： Ubuntu 16.04
  * Python 3.5

# 参考

  * [Django+HerokuでLINE Messaging APIのおそ松botを作るまで](https://qiita.com/yakan10/items/b7ad35c2cbba5db81462)
BigQueryのデータセットを東京リージョンで作成すると、クエリ実行時にロケーションの指定が必要になる

## 問題
- 2018/4からBigQueryが[東京リージョン](https://cloud-ja.googleblog.com/2018/04/BigQuery-arrives-in-the-Tokyo-region.html)で提供されるようになった
- しかし、東京リージョンでデータセットおよびテーブル作成をした後、クエリを実行すると、以下のエラーが発生する

```
Not found: Dataset ****, Please verify that the dataset exists and the correct location was used for the job.
```

## 解決方法
- オプションのロケーション指定でasia-northeast1を選択してクエリを実行する。これは記事作成(2018.7.29)時点では[必須のオプション](https://cloud.google.com/bigquery/docs/dataset-locations#specifying_your_location) である。

## 原因
- 東京リージョンはデータが格納方式がRegional locationsで、東京リージョンにしかデータが格納されていないため。一方、USやEUリージョンはMulti-regional locations方式でデータが格納されるため、リージョンの指定なしで検索が可能になる。

## 補足
- 東京リージョンがMulti-regional locationsになると、おそらくオプション指定は不要になると思われます。
- GCPはアップデートが早いので、今後に期待です。
ハッカソンに必要な備品や喜ばれるスポンサーグッズまとめ

ハッカソンのスポンサー担当を何度かさせていただくことがあったので、
「必要なグッズ」「あると尚良いグッズ」「スポンサーが提供すると喜ばれるであろうもの」といった観点からピックアップいたしました。

・ハッカソンを企画・運営する方
・ハッカソン会場を提供する方
・ハッカソンのスポンサーをする企業担当の方

の参考になりましたら幸いです。

##備品
**ペン**
・サインペンのようにある程度太さある方が見やすくて良い
・太いものと細いものを別で用紙するもしくは、両端で太さが違うものなどがベスト
・太い方は発表用に、細い方はアイディア出しなどのメモ用に使う

**画用紙**
・アイディアソンでのメモ用
・中間発表用にも使える
・子どもが使うお絵かき帳でOK。ちぎりやすく、程よく薄いので使いやすい
・稀に参加者から模造紙が欲しいと言われる場合もある。値段もはるので大規模ハッカソン向きかも

**ホワイトボード**
・Wifi情報やテーマなどを書ける
・全体共有であれば、スクリーンでも代用できる
・簡易ホワイトボードなどを用意して、各チームで使えるように用意することもある

**名札**
・必須ではないが、お互いの名前を呼びやすくなる
・ファシリテーターや司会も楽かも
・スポンサー担当や技術サポーターにつけてもらう手も

**OAタップ**
・PCだけでなく、デバイスなどを繋ぐ場合も多いので多めに用意しておく

**マイク**
・ファシリテーターの声が聞こえにくい場合もあるので、あるとベスト

**音楽を流すもの**
・PCからでもプレーヤーでもスマートスピーカーでもいいのだが、あると間が持つ

**飲食**
・ソフトドリンクでOK（お茶とか）
・コーヒーやチョコがあると嬉しい（個人の意見です）
・会場に自販機がある場合はそんなに神経質にならなくても良い
・昼食用のお弁当や、懇親会でのお酒やオードブル等

##ノベルティおすすめ品
**筆記具関連**
・ペンや付箋、ノートなどはアイディアソンで使えるのでその場で使ってもらえる可能性が高い

**エコバッグ**
　デバイスなど備品を持ってきている参加者も多いので、その日に使ってもらえる可能性あり

**お菓子**
　ビスコに文字や画像を入れられる「スマイルビスコ」や、
　ブラックサンダーにオリジナルパッケージを追加できる「Myブラックサンダー」など、
　そのほか何でもお菓子系は候補となる

##スポンサードおすすめ品
- ドリンクスポンサー、お菓子スポンサーなどの飲食系
  - ドリンクはラベル付きの水などであれば簡単に発注できる
  - お菓子は前述のとおり

泊りがけのハッカソンでは特に以下のものが喜ばれる傾向にあった
・マッサージグッズ（こりほぐしグッズなど）
・蒸気でホッとアイマスク
・汗拭きシート

##最後に
いつどこで開催されるのか、どんな人が参加するのか、何をテーマとしたハッカソンか、何日間あるのか、季節、などなど考慮する要素がたくさんあるので、都度比較検討すると良いと思います。
Raspberry Pi 3 Model BでiBeaconを発信する方法

##環境
- Raspberry Pi 3 Model B
- スマホ　→　arrows RM02 Android OS 5.1.1
- beacon検出アプリ
→　https://play.google.com/store/apps/details?id=de.flurp.beaconscanner.app&hl=ja

##インストールするもの
・bluez
・Node.js
・bleacon

##とりあえずビーコンとして動かす方法

以下のリンクを参考にbluezを導入。ただし、記事ではBluetoothのドングルを使用している。
Raspberry Pi 3 Model BではBluetoothが内蔵されているので、そのまま使えばOK。
https://jyun1.blogspot.com/2013/12/i-beacon-make-by-raspberry-pi.html

beacon検出アプリで以下のように検出できればOK。
![Screenshot_2018-07-29-17-33-51.png](https://qiita-image-store.s3.amazonaws.com/0/256346/77da4bbd-e95e-de3b-d591-4e78eb8fe00a.png)


##ビーコンの設定を細かく行えるようにする方法
Node.jsとbleaconを導入。jsファイルを編集することでビーコンの設定が可能。

Node.jsは以下のリンクを参考に導入。
https://github.com/hokaccha/nodebrew
https://qiita.com/ombran/items/c59525e429c9c363325d
https://qiita.com/yuyakato/items/a1225154445520dc2db3

bleaconは以下のリンクを参考に導入。
https://qiita.com/yuyakato/items/739443960fac2668f4a3#bleacon%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B

以下のリンクの「bleacon.js」にビーコンの設定を行える方法が記載されている。
ファイル名は適当でOK。今回は「testbeacon.js」にしておく。
https://qiita.com/FePlus/items/f2865085d2cd907fcc54

先ほどのjsファイルを以下のパスに作成した後に、実行すると以下のエラーが発生。
/home/pi/testbeacon.js

![snapshot1.png](https://qiita-image-store.s3.amazonaws.com/0/256346/9c6d3d9d-1d27-bab6-9a3d-f89be31b2741.png)

「node_module_register」で検索をしても何が問題なのかさっぱりわからなくて苦労した。

Node.jsを導入するときに設定した以下のパスが反映されていないのが原因だった。
export PATH=$HOME/.nodebrew/current/bin:$PATH

sudoで実行するときは設定を変更しておかないとユーザーが指定したパスは反映されないらしい。
以下の記事を参考に修正。
https://qiita.com/akito1986/items/e9ca48cfcd56fdbf4c9d

↓以下のように修正した。保存するときは「Ctrl + O」押下後に、「Enter」。終了は「Ctrl + X」。
![snapshot3.png](https://qiita-image-store.s3.amazonaws.com/0/256346/ce6d0abf-19de-63d4-f103-e3512a96c7dc.png)


再度実行してみた。このようになればOK。
![seikou.png](https://qiita-image-store.s3.amazonaws.com/0/256346/5b909e61-9c52-bc42-015d-514079313f31.png)

beacon検出アプリで以下のように検出できればOK。
![Screenshot_2018-07-29-17-34-22.png](https://qiita-image-store.s3.amazonaws.com/0/256346/fd607423-6464-c6a3-8e3c-31f8a502b3b7.png)
R初心者がmapplyでハマった話

## この記事について

急遽手元にある~100万件程度の緯度経度データセットに対していわゆるリバースジオコーディングをやることになり、[こちらの記事](https://qiita.com/uri/items/69b2c05f7b3a21d3aad3)を読みながらやることにした。
リバースジオコーディング自体はうまくいったものの、普段Rを使っていないのでRの基本的なところでハマったので備忘録がてら。
結論、`mapply()` はlistを返すので、データフレームでそれを扱いたい場合、適切な後処理をしましょう以上のものではないですが、普段Rをほぼ書かないのでかなり頓珍漢なことをやっている可能性が高く、もっと良い方法をご存知の方がいましたらご教示いただけますと助かります。

## ハマった時の状況

参考記事のリバースジオコーディング関数は、単一の緯度経度を受け付けて実行する形になっている。
ただし、手元にあるのはまとまった量のデータセットなので、for文とかでやるのは非効率。
↓
適当にググったら、そういう時にはRでは `apply()` 関数ファミリーが便利だと知る。複数の引数を取る場合には `mapply(func, arg1, arg2)` と[書くと良いと知る](https://stackoverflow.com/questions/6827299/r-apply-function-with-multiple-parameters)
↓
リバースジオコーディングの関数自体は(warningが出たものの)実行できた。
`View()`で結果を見てみると、いくつか欠損値はありつつも(これは想定通り)、いくつかデータをピックアップして結果を見比べてみても、正しくリバースジオコーディングができていそう。
↓
しかし、結果を`write_csv()`で吐き出そうとしたところ、データフレームにlistはが含まれているため出力できない旨のエラーが出る。確かに、書き出したいデータフレームを`head()`で見ると、`mapply()`関数の実行結果を格納した列の下(データ型?が書かれる部分)に`list`と書いてある。
↓
どういうことだってばよ???

## 解決策

結論、 `mapply()` で出力した結果は、データフレームの列に、単一のリストとして格納されてしまっていた。
(言い訳だけど、普段使っているpandasだとこういうことが起こらないので気づくまでにだいぶ時間がかかった。。)
なので、欠損値を補完してあげた上で `unlist()` でベクトル化?した結果を元の列に格納してあげることで解決した(ちなみに欠損値を補完せずに`unlist()`すると欠損値を含むrowが飛ばされてベクトル化しまい、元のデータフレームに結果を格納した際、欠損値が存在するrow以降のデータの順番が狂ってしまうのでダメ)。
コードは下記の通り。

```.R
# データ読み込み
df <- read_csv("my_geodata.csv")
# 都道府県レベルpolygon search(参考記事をベースに多少いじったもの)
df$pref <- mapply(find_city, df$lon, df$lat)
# データ整形(欠損値の補完とdfの型変換)
prefs <- lapply(df$pref, function(x) if (length(x) == 0) 0 else x)
df$pref <- unlist(prefs)
```
Knex.jsでのマイグレーション実行時に、dotenvモジュールが読み込まれない問題

## 概要

* expressを使ってWebアプリケーションを作成しており、設定は[dotenv](https://www.npmjs.com/package/dotenv)モジュールで管理している。
* [Knex.js](https://knexjs.org)を使用してマイグレーションを実行する際に、dotenvモジュールの読み込みがうまく行われずにはまってしまった。

## ファイル構成

.envファイルを作成し、DB接続等の設定を記述する。

```ini:.env
DB_CLIENT=postgres
DB_HOST=<hostname>
DB_PORT=<port>
省略...
```

マイグレーションの実行に必要なため、knexfile.jsを作成する。

各設定値は、dotenvモジュールで初期化されていることを想定して、`process.env`から読み込んでいます。

```js:knexfile.js
module.exports = {
  client: process.env.DB_CLIENT,
  connection: {
    host: process.env.DB_HOST,
    port: Number(process.env.DB_PORT),
    database: process.env.DB_DATABASENAME,
    user: process.env.DB_USER,
    password: process.env.DB_PASSWORD
  },
  seeds: {
    directory: './seeds'
  },
  debug: Boolean(env.DB_DEBUG)
};
```

## 原因

expressアプリを起動する際は、

```sh
$ node -r dotenv/config server.js
```

のように、明示的にdotenvモジュールを読み込んでいるため、問題なく`process.env`が初期化される。

マイグレーション時は、

```sh
$ knex migrate:latest --knexfile ./knexfile.js
```

のように実行しており、起動時にdotenvモジュールが読み込めていないことが原因でした。

## 解決策

knexfile.jsの先頭付近で、明示的にdotenvモジュールを読み込む処理を追加する。

```js:knexfile.js
// require.cacheにdotenvキーが未設定であれば、明示的に読み込む
if (!require.cache['dotenv']) {
  require('dotenv').config();
}

module.exports = {
  client: process.env.DB_CLIENT,
  省略...
};
```

参考: https://nodejs.org/api/modules.html#modules_caching
Registoryを変更してしまったときの戻し方メモ

#間違えてレジストリをいじってしまい，ほとんどのexeファイルが開かなくなったときの対処法
exeファイルに関するレジストリをregedit.exeでいじってしまい，動かなくなってしまった．

Windowsは以下の方法でレジストリを編集できる．
(Windowsが機能しなくなる恐れがあるのでなるべくいじらない，変更する前に必ずバックアップやエクスポートをしておくこと．)

1. registry  Editor (regedit.exe)
2. regedit.exeでエクスポートできる.rgファイルをダブルクリック

そこで，他の機能しているパソコンからWindows + R でregeditと入力し，registry editorを起動[1]した．
exeファイルを選択してから，ファイル→エクスポートを選択し，exeファイルのみのrgファイルをエクスポートした．
(エクスポート画面のselected branch がHKEY_CLASSES_ROOT\.exeとなる．)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/267311/ed6ac337-f0d2-92bd-8163-bda80dc31368.png)
これでエクスポートしたファイルを動かなくなったPCでダブルクリックすると，exeに関するregistryが更新され，動くようになった．

[1] [レジストリエディタを開く](https://support.microsoft.com/ja-jp/help/4027573/windows-open-registry-editor-in-windows-10)
[2] [Windowsレジストリ情報](https://support.microsoft.com/ja-jp/help/256986/windows-registry-information-for-advanced-users)
Mixed Realityポータルでデスクトップが表示されない不具合の対処

redditの記事をベースに解決対応しました。ハマりどころがあったため、念のためまとめておきます。
当記事に説明画像を添付しようとしたのですが、途中からerrorになってしまったため、文字ベースになります。

## 現象
- Mixed Realityポータルは起動できるし、アプリも正常に使える。
- デスクトップの表示だけができない。真っ黒。
![black_.jpg](https://qiita-image-store.s3.amazonaws.com/0/99134/07db10a9-efba-2d54-16a4-79fbb2d70cb6.jpeg)


# ハマリどころ
解決策適用中に以下が発生する可能性があるので実行時は要注意！
- GPUが認識されなくなる
- GPUが認識されないことでMixed Realityポータルが使用不可になる
- GPUが認識されないことでNVIDIA Control Panelが使用不可になる

# 参考リンク
- Reddit:[Desktop in Cliff House only BLACK](https://www.reddit.com/r/WindowsMR/comments/7d7vs5/desktop_in_cliff_house_only_black/)
- NVIDIA:[How do I customize Optimus profiles and settings?](http://nvidia.custhelp.com/app/answers/detail/a_id/2615/~/how-do-i-customize-optimus-profiles-and-settings%3F)

# 解決の流れ

## ハマリつつもディスプレイ表示解決に漕ぎつける糸口
1. NVIDIA control panelからruntime brokerに統合型グラフィックスを適用
2. RuntimeBroker.exeを右クリックして『グラフィックスプロセッサと共に実行』し統合グラフィックスを選択 
3. 最後の手段の再起動
(1.実施後、GPUが認識されなくなり、もろもろのトラブルが発生しましたが、2.で解決しました)

## 発生環境
Reddit記載を見るとノートPCで発生しがち？
- Mouse Computer NEXTGEAR-NOTE
- GeForce GTX1070
- 解決時Windows 10 バージョンはRS5 preview。現象はRS4，RS5(Preview)以前から発生。
 (Home から Proにupgradeしたが解決せず。本件解決目的のupgradeは不要)

# 対応
1.NVIDIA control panelからruntime brokerに統合型グラフィックスを適用
nvcplui.exeを実行し、NVIDIA control panelを起動する。 
 (私の環境では C:\Program Files\NVIDIA Corporation\Control Panel Client)

起動後、3D設定の管理 > プログラム設定 > 追加 の順で追加ウインドウを開き、RuntimeBroker.exeを追加
(※ RuntimeBroker.exeの場所はタスクマネージャを起動し、Runtime Brokerのファイルの場所を開くから見つけることができる。C:\Windows\System32\RuntimeBroker.exe)

2.このプログラム用の優先するグラフィックス プロセッサを選択する(O):から[統合型グラフィックス]を選択する
すると、下に適用とキャンセルが現れるので、適用を選択

ここまでやった時点で私のPCではGPUが認識されなくなり、Mixed RealityおよびNVIDIA control panelが起動できなくなりました。

そこからの復旧が以下です。

## 上記で解決せず、問題が発生した場合
2.RuntimeBroker.exeを右クリックして[グラフィックスプロセッサと共に実行] > [統合グラフィックス]を選択 
(※ RuntimeBroker.exeの場所はタスクマネージャを起動し、Runtime Brokerのファイルの場所を開くから見つけることができる。C:\Windows\System32\RuntimeBroker.exe)

3.それでもだめなら再起動

私の場合は以上で復旧および、Mixed Reality ポータルでのディスプレイ表示が解決しました。

# 謝辞
Facebook : HoloLens/Windows Mixed Reality ユーザーズグループにて、redditの解決済リンクを教えていただいたTakanori Hidaka様、ありがとうございました。
はてな/Qiita/GithubのMarkdown環境で画像のサイズ変更を行うには。

いつも忘れてしまうので、メモ程度に載せます。

### 『はてなブログ』

```bash:リサイズ前
[f:id:xxxxxxxxxx:plain]
```
↓

```bash:サイズ変更
[f:id:xxxxxxxxxx:plain:w300]
```
などと末尾に『:wサイズ』といった形でサイズを指定すれば大丈夫です。

### 『Qiita/Github』

```bash:リサイズ前
![代替テキスト](URL)
```

```bash:サイズ変更
<img src="画像のURL" width="サイズ">
```

といったimgタグを用いるとできる。Qiita/Githubに限らず

```
『![代替テキスト](URL)
```
の形式のものはimgタグでいけるところが多いです。
Dockerfileから新規イメージを作成する

##はじめに
Dockerfileから新規イメージを作成する手順をまとめてみました。
こちらに備忘録として残します。

##作成手順

<b>1.Dockerfileを作成する。</b>

```
# vi Dockerfile
```

```txt:/root/Dockerfile
# どのイメージをもとに新しいイメージを作成するか指定する。
FROM ubuntu

# 作成したユーザの情報
MAINTAINER Gen user <hogehoge@hoge.com>

# RUN: docker buildするときに実行されるもの（色々なものをインストールしたりすることができる）

RUN echo "now building..."

# CMD: docker runするときに実行されるもの。
CMD ["echo", "now running"]
CMD echo "now running..."
```
<b>2.Dockerfileから新規イメージを作成する。</b>
$ sudo docker build -t [作成するイメージ名] [保存先]

```
[root@docker ~]# sudo docker build -t test/echo .　     # . はカレントディレクトリに作成
Sending build context to Docker daemon  13.31kB
Step 1/5 : FROM ubuntu
 ---> 735f80812f90
Step 2/5 : MAINTAINER Gen user <hogehoge@hoge.com>
 ---> Using cache
 ---> 7cb7cdb095ec
Step 3/5 : RUN echo "now building..."
 ---> Using cache
 ---> 85212849bedd
Step 4/5 : CMD echo "now running"
 ---> Running in 35ce70f8b146
Removing intermediate container 35ce70f8b146
 ---> de6cd012f0cb
Step 5/5 : CMD ["echo", "now running..."]
 ---> Running in 1fdbebd8fabe
Removing intermediate container 1fdbebd8fabe
 ---> 059f6a69f3e2
Successfully built 059f6a69f3e2
Successfully tagged test/echo:latest
```

<b>3.新しい作成されたか確認する。</b>

```
[root@docker ~]# sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
test/echo           latest              059f6a69f3e2        4 minutes ago       83.5MB
ubuntu              latest              735f80812f90        2 days ago          83.5MB
centos              latest              49f7960eb7e4        7 weeks ago         200MB
```

以上
Intentでオブジェクトを渡す方法

IntentのputExtraにはオブジェクトを渡せないので、さてどうしたものかと思っていたのですが、
GSONを使ってJSON文字列に変換すれば、ただの文字列なので簡単に受け渡しをすることができました！

## Dependencies

* Kotlin
    * 今回はKotlinを使っていますが、Javaでも同様のことが可能です。
* GSON
    * ようは文字列にシリアライズ/デシリアライズができればいいのでGSONじゃなくてもいいです。

## オブジェクトのJSON文字列化

まずはオブジェクトです。データは単純にして、以下のようなものを使うことにします。

```Kotlin
data class Person(val name: String,
                  val age: Int,
                  val height: Int)

data class Team(val name: String,
                  val member: List<Person>)
```

で、例えば以下のようにオブジェクトを生成してあげて、`Gson().toJson()`で文字列変換してみます。

```Kotlin
private fun createObjectForTest(): String {
    // これは普通にKotlinのオブジェクトを生成してる
    val team = Team("サッカー部", listOf(
            Person("田中", 15, 179),
            Person("太田", 16, 169),
            Person("斎藤", 17, 180)
    ))

    // ここでオブジェクトを文字列に変換して返却してる
    return Gson().toJson(team)
}
```

Gsonを使うと超簡単にJSON文字列に変換できますね。
で、文字列のほうは以下のようにちゃんとJSON文字列に変換されてます。

```
// printlnで表示されたものをこぴっぺ
{"member":[{"age":15,"height":179,"name":"田中"},{"age":16,"height":169,"name":"太田"},{"age":17,"height":180,"name":"斎藤"}],"name":"サッカー部"}
```

整形するとこんな感じでいい感じ。

```JSON
{
   "member":[
      {
         "age":15,
         "height":179,
         "name":"田中"
      },
      {
         "age":16,
         "height":169,
         "name":"太田"
      },
      {
         "age":17,
         "height":180,
         "name":"斎藤"
      }
   ],
   "name":"サッカー部"
}
```

## putExtraで渡す

JSON文字列の変換方法はわかったので実際にIntentで渡してみます。
`MainActivity`に適当なボタンを配置してonClick関数を定義してセットします。

```Kotlin
// テスト用のオブジェクトを生成して返却します
private fun createObjectForTest(): Team {
    return Team("サッカー部", listOf(
            Person("田中", 15, 179),
            Person("太田", 16, 169),
            Person("斎藤", 17, 180)
    ))
}

fun onClickNextBtn(V: View) {
    val team: Team = this.createObjectForTest()

    val intent = Intent(this, SubActivity::class.java)
    // Gsonを使って文字列変換したものをセット
    intent.putExtra("key_team", Gson().toJson(team))

    startActivity(intent)
}
```

以上で、オブジェクトをIntentに乗せることができました。
あとは受け取り側で、"key_team"を指定して受け取ればいいですね。

## 受け取り側でJSON文字列をデシリアライズする

受け取り側はキーで値を取得できますが、もちろんStringなのでデシリアライズが必要です。
以下のように受け取った後に、`Gson().fromJson<>()`を使ってあげれば一発でもとに戻せます。

```Kotlin
// ここはJSON文字列
val json = intent.extras.getString("key_team")
// 型を指定して文字列からデシリアライズする
val team = Gson().fromJson<Team>(json, Team::class.java)
```

## まとめ
JSONは文字列なので、GSONを使って変換すれば、ほかにも色々使いどころがありそうです。
例えば、プリファレンスへの保存にも実はJSONが使えます。
皆さんも色々使ってみてください。
gitlab pagesのartifacts pathsはpublicじゃないとダメ

# 問題
buildはpassしてるのに、なぜかdeployがfailedになる

```.gitlab-ci.yml
image: node

before_script:
  - npm install

cache:
  paths:
    - node_modules/

pages:
  stage: deploy
  script:
  - npm run build
  artifacts:
    paths:
    - dist
  only:
  - master
```

# 解決
ドキュメントを見直すとgitlab pagesのartifacts pathsはpublicじゃないとダメらしい
build後にmvして解決した

```.gitlab-ci.yml
image: node

before_script:
  - npm install

cache:
  paths:
    - node_modules/

pages:
  stage: deploy
  script:
  - npm run build
  - mv dist public
  artifacts:
    paths:
    - public
  only:
  - master
```

# 参考
https://docs.gitlab.com/ce/ci/yaml/#pages