OmniAICreator/Qiita-1.07M huggingface dataset:
【5分で作る】リアルタイムでTwitterを流すデジタルサイネージ【身も蓋もない】

CIVIC TECH FORUM2018(全国の市民活動×テックの活動報告LT大会)にて、Twitterの実況デジタルサイネージを展示しました！
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">【CTF2018｜<a href="https://twitter.com/hashtag/%E3%82%AB%E3%83%95%E3%82%A7?src=hash&amp;ref_src=twsrc%5Etfw">#カフェ</a>】 <a href="https://twitter.com/hashtag/civictechjp?src=hash&amp;ref_src=twsrc%5Etfw">#civictechjp</a><br>ツイッターサポーターの小笠原さん自作の、ラズパイを使ったツイッターハッシュタグ中継マシーン。<br>すげー！ <a href="https://t.co/JyWRwfhggL">pic.twitter.com/JyWRwfhggL</a></p>&mdash; CIVIC TECH FORUM (@civictechforum) <a href="https://twitter.com/civictechforum/status/1002782519131951105?ref_src=twsrc%5Etfw">2018年6月2日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


進行情報や離れた会場の様子の共有のために有効なので、イベント主催者の方は検討してみてはどうでしょうか？
今回は休憩スペースでツイートを投影したのですが、実際にツイートを眺めている参加者の方をいつもお見かけしました。

TweetDeckの見せ方を工夫するだけなので、誰でも超簡単に作れます！ぜひトライしてみてください。

# 機材
* ディスプレイまたはプロジェクター
* Raspberry Pi(Chromeが搭載されていればMacbookでもなんでもいいです)

# 作り方
1. 機材のセットアップ
2. TweetDeckを開く
3. BetterTweetDeckのCustomCSS機能で表示を調整する

## 1.機材のセットアップ
Raspberry Piとディスプレイを接続するほか、画面がいつの間にか真っ暗にならないようにスクリーンセーバーをOFFにします。
スクリーンセーバーの設定（参考）
http://www.geeks3d.com/hacklab/20160108/how-to-disable-the-blank-screen-on-raspberry-pi-raspbian/

## 2.TweetDeckを開く
Raspberry PiのChromiumで[TweetDeck](https://tweetdeck.twitter.com/)を開きます。
デジタルサイネージで表示したいタブだけを残し、残りのタブは閉じます。

## 3.BetterTweetDeckのCustomCSS機能で表示を調整する 
Chrome拡張の[BetterTweetDeck](https://chrome.google.com/webstore/detail/bettertweetdeck/micblkellenpbfapmcpcfhcoeohhnpob)では、以下のようにオリジナルのCSSでTweetDeckの表示をカスタマイズ可能です。
![Screen Shot 2018-06-03 at 18.02.24.png](https://qiita-image-store.s3.amazonaws.com/0/96286/95eff39f-98a7-ec90-48f9-2463addaeb66.png)

これを使って、私は主に次のように表示を変えました。
* カラムの幅を画面いっぱいにする。
* 全体的な色をイベントの雰囲気に合わせる。

Gistはこちら
https://gist.github.com/hiroga-cc/e7c0ad4d83128bf5a771718ab7a83a9b

完成したのがこちら！！
![Screen Shot 2018-06-03 at 18.20.07.png](https://qiita-image-store.s3.amazonaws.com/0/96286/1a9132ee-3f67-de4c-5d21-5165200d6b9a.png)


# まとめ
TweetDeckをそのまま使えばTwitter APIを使わず、プログラミングもせずにデジタルサイネージが作れます。
簡単な割にイベントでの効果は大きいと思うので、ぜひ検討してみてください！
VR開発中にOVRRaycasterで少しハマった話

VRと書きましたが主にOculusの話です、すみません。
# はじめに
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Unityのシーン中にHierarchyとInspectorを表示できるRuntime Inspector &amp; Hierarchyがデバッグに便利すぎる <a href="https://twitter.com/hashtag/OculusGoDev?src=hash&amp;ref_src=twsrc%5Etfw">#OculusGoDev</a> <a href="https://t.co/1eh6m20SLF">https://t.co/1eh6m20SLF</a> <a href="https://t.co/ypIwmxaUfJ">pic.twitter.com/ypIwmxaUfJ</a></p>&mdash; Mitsuhiro Koga (@shiena) <a href="https://twitter.com/shiena/status/1001553143845437440?ref_src=twsrc%5Etfw">2018年5月29日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

こちらのツイートを見て、今開発中のゲームのデバッグ機能として追加してみたところ、ハマったポイントがあったので、同じような境遇の人がいたら助けになるといいなあというところです。

結論から言うとOculusから提供されている**OVRRaycaster.cs**ではGraphics.raycastTargetの判定をしていないようです。
uGUI操作の時なんかうまく動かないなと思ったら以下を試してみてください。

```csharp:OVRRaycaster.cs
private void GraphicRaycast(Canvas canvas, Ray ray, List<RaycastHit> results) {
...
                if (graphic.depth == -1)
                    continue;
...
        }
```
上記のコードを以下のように修正します。

```csharp:OVRRaycaster.cs
private void GraphicRaycast(Canvas canvas, Ray ray, List<RaycastHit> results) {
...
                if (graphic.depth == -1 || !graphic.raycastTarget)
                    continue;
...
        }
```

これでうまく動きました。

これより下はRuntimeInspectorの紹介とOculusGoでuGUIを操作するときの備忘録です。

# メモ
今回使用したアセットは**UnityRuntimeInspector**です。
https://github.com/yasirkula/UnityRuntimeInspector
![イメージ](https://github.com/yasirkula/UnityRuntimeInspector/raw/master/images/img1.png)

こんな感じのヒエラルキ・インスペクタをゲームシーン上からプレビューできるようになります。

OculusGoにはRemoteContollerが付属しているので、こちらのコントローラからRaycastingを行い、uGUIのコントロールを行おうと目論みました。(今回はGazeInputは使用しませんでした)

調べてみるとOculus社がRayCastをマウスインプットのように変換するラッパーを提供されているようです。> **OVRInputModule.cs**、**OVRRaycaster.cs**

**使用方法**

- **OVRInputModule.cs**をStandardInputModuleの代わりにEventSystemにアタッチ
- **OVRRaycaster.cs**をGraphicRaycasterの代わりにCanvasにアタッチ

これだけで、RemoteContorollerからuGUIに対して入力を送ることができるようになりました、簡単ですね。
Realmを使ったデータベースの実装


基本的なRealmの実装の方法についてまとめます。
今回は現在作成しているアプリのコードを使って説明していきます。

## ⒈事前準備

まず始めに、build.gradleファイルにclasspathを追加します。

```Java
uildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2'
        classpath "io.realm:realm-gradle-plugin:5.1.0"
    }
}
```

上記のコードの「classpath "io.realm:realm-gradle-plugin:5.1.0"」が追加した部分です。

## ⒉オブジェクトの定義

次にRealmObjectのサブクラスを作成し、オブジェクトを定義します。

```Java
public class Recipe extends RealmObject {

    @PrimaryKey
    int id;
    @Required
    private String name;
    @Required
    private String cookingTime;
```

プライマリキーを使うことで、オブジェクトの作成と更新は少し遅くなりますが、検索は速くなります。
複数のフィールドをプライマリキーとして指定することはできません。

定義した後は、getterとsetterを用意します。


```Java
public int getId() {
        return id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setCookingTime(String cookingTime) {
        this.cookingTime = cookingTime;
    }

    public void setId(int id) {
        this.id = id;
    }


}
```

### ⒊モデルの定義

次にモデルを定義します。

新規作成と編集の更新は次のように行います。
プライマリキーを指定したモデルは、copyToRealmOrUpdate()を使ってオブジェクトを作成または更新をすることができます。



```Java
public class RecipeModel {

    private Realm mRealm = Realm.getDefaultInstance();

    /**
     * レシピの新規作成もしくは編集の更新
     *
     * @param recipeId    　レシピのid
     * @param recipeName  　レシピの名前
     * @param cookingTime 　調理時間
     */
    public void copyOrUpdate(@Nullable Integer recipeId, String recipeName, String cookingTime) {
        if (recipeId == null) {
            recipeId = makeRecipeId();
        }
        Recipe recipe = new Recipe();
        recipe.setId(recipeId);
        recipe.setName(recipeName);
        recipe.setCookingTime(cookingTime);

        mRealm.beginTransaction();

        mRealm.copyToRealmOrUpdate(recipe);

        mRealm.commitTransaction();
    }
```
idがnullの場合に新規作成を行います。

削除は次のように行います。


```Java
    /**
     * レシピの削除
     *
     * @param recipeId 　レシピのid
     */
    public void deleteRecipe(int recipeId) {
        mRealm.beginTransaction();

        // レシピの一覧から、recipeIdと一致するidのレシピの中で最初のものを取り出す
        Recipe recipe = mRealm.where(Recipe.class).equalTo("id", recipeId).findFirst();
        if (recipe != null) {
            recipe.deleteFromRealm();
        }

        mRealm.commitTransaction();
    }
```


## まとめ

①build.gradleファイルにclasspathを追加
②オブジェクトの定義
③モデルの定義

この３つのステップでRealmでは簡単にデータベースを実装できます。
是非試してみてください。
スクラムまとめ

#役割

## プロダクトオーナー
・プロダクトの結果責任を取る
・プロダクトバックログの管理者
・プロダクトバックログを常に最新に更新する。

## スクラムマスター
・妨害の排除
・デイリースクラムのファシリテート
・スプリント計画MTGのファシリテート
・アジャイル開発が上手く回るように支える

## 開発チーム
・3〜9人構成
・上下関係はない

#各種会議
## スプリント計画MTG
・今週のスプリントで開発するタスクを決める
・タスクの担当者を決める

## デイリースクラム
・前回のデイリースクラムからやったこと
・次回のデイリースクラムまでにやること
・困っていること

・時間は15分厳守
・必ず全員が3つの事柄について発言する

## スプリントレビュー
・そのスプリントでの成果を発表
・状況に応じてバックログの見直し
・質問やフィードバックをする

## スプリントレトロスペクティブ
・Keep (続けるべきこと)
・Problem (抱えている問題)
・Try (次にトライしたいこと)

今後のアクションプラン設定

# プロダクトバックログ
ツール
https://www.zenhub.com/
https://taiga.io/
https://trello.com/
RubyでYARD定義を使って実行時にメソッド引数と戻り値の型チェックを試みる

（Ruby のカンファレンスの度に、毎度話題になる？） Ruby に型が欲しい件ですが、個人的な見解を書いておこうと思います。ちなみに私は RubyKaigi 2018 に参加しておりません。Twitterのタイムラインでの賑わいを見ていただけです。

最近、Swift を触っててそのコンパイルの重さにうんざりしているので、 **型推論** は現代のマシンスペックでは基本的に辛いと思っています（カフェでノマドコーディングしたいので）。またメタプログラミングし放題の Ruby に導入するのは困難という認識です。

では、どういうときに **型定義** が欲しくなるのか考えてみます。
（続く）

[続きは tilfin's blog へ](https://blog.tilfin.com/2018/06/03/2018-06-03-172518/)
Rubocopを使ってみる

# Rubocopとは
RubocopはRubyのコーディングチェックツールです。


Github
https://github.com/rubocop-hq/rubocop

# インストール

```
$ gem install rubocop
```

# 使い方

```
$ rubocop
```

```
ファイルを指定して実行
$ rubocop sample.rb
```

# 実行結果の見方

```
Inspecting 12 files
.CCC..CCC.CC

Offenses:
```
「.」はエラーなし
「C」はコーディング違反


#Rubocopのオプション

```
ヘルプの表示
$ rubocop --help

ダブルクォーテーションをシングルクォーテーションに変換
$ rubocop --auto-correct
```


# エディタにRubocopを導入する

`Atomに導入する`
検索欄にrubocopと入力し、「linter-rubocop」をインストールします。

<img width="790" alt="スクリーンショット 2018-06-03 17.08.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/201127/07bf368b-98b7-d0a6-69cf-b75183ba8bfe.png">
ご使用のプロジェクトに基づき、あなたに役立つかもしれない拡張機能を特定しました

Visual Studio も親切になりました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/93227/9eed561a-9198-99ac-cece-31ba6c268a53.png)

Snippet Pack とは、コマンドを入力するときにリスト表示してくれる機能なので、インストールすることにします。

詳しくは、下記を参照
http://miso-soup3.hateblo.jp/entry/2016/01/08/172329
Linuxで突如ユーザーにログインできなくなった話


#突然エラーが出た
ユーザーにログインしようとすると以下のエラー。

```:Terminal
segmentation fault
```

#やったこと
ルートでログインし、testというユーザーを作成する。

```:Terminal
$ su
# useradd test
```

新規ユーザーの.bashrcをそのままコピーする。

```:.bashrc
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi
```

#元ユーザーの.bashrcがおかしい

```:.bashrc
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi
```

それを以下のように記述する。

```:.bashrc
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi
```

#おまけ
##.bash_profile

.bash_profileを変更してrbenvコマンドを使えるようにする。

```:.bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin

export PATH
```

rbenvがあるパスを指定。

```:.bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
```
AWS EFS をEC2にマウントしてみる

先日のAWS Summit Tokyo　2018　でEFSが7月に東京リージョンに対応されることが発表されました。
発表から丸3年…ようやく日本にもEFSがやってきます。
対応された直後から使えるように、EFSをEC2にマウントする方法について、予復習してみます。


#EFS作成

まずはマネジメントコンソールで既にEFSが対応されているソウルリージョン等に移動し、EFSのページを開きます。
そこから新規でファイルシステムの作成を行います。

最初の設定ページでは、配置するVPCとAZ、セキュリティグループを設定します。
セキュリティグループは、TCP2049番ポートがマウントするEC2から通るように設定する必要があるようです。
<img width="1278" alt="EFS設定1VPCAZ.png" src="https://qiita-image-store.s3.amazonaws.com/0/181363/40b63329-e6db-3a2b-5fd6-09f8b7d8523f.png">


タグとパフォーマンスモード、ディスク内容を暗号化するかどうかを設定します。
※パフォーマンスモード：汎用とIOPS特化があり、レイテンシを優先するか、スループットを優先するかで選ぶようです。
![efs設定2.png](https://qiita-image-store.s3.amazonaws.com/0/181363/0bc6f1d5-e498-ede5-4da8-bd62382dda17.png)

最後に確認。
<img width="1279" alt="EFS設定3レビュー.png" src="https://qiita-image-store.s3.amazonaws.com/0/181363/c5f42b94-d59f-8aeb-a164-24e3a31817d7.png">

これでEFSの作成は完了です。
<img width="1248" alt="EFSリスト.png" src="https://qiita-image-store.s3.amazonaws.com/0/181363/3e4f7204-5694-737f-3542-2ff08c5a73f7.png">


#EC2作成
AMIはAmazonLinuxを使って、t2.nanoで作成。
特別な設定はいりません。
※EC2の作成方法の詳細は@0084ken さんの[
記事](https://qiita.com/0084ken/items/b663f7bd56399c7d0d76)が参考になると思います。

![EC2作成.png](https://qiita-image-store.s3.amazonaws.com/0/181363/49ba87c1-7ff3-63c4-786f-0f0de0404a2e.png)
EC2作成時のEBSをマウントする感じで、EFSをマウントできると楽そうですが、今のところでき無さそうです。

#EFSをEC2にマウント
efs用のユーティリティを入れて、対象のファイルシステムを指定してマウントコマンドを実行するだけです。
この時、コマンドがタイムアウトした場合はセキュリティグループを確認してみてください。
(EFSに張っているセキュリティグループで、EC2からのTCP2049番ポートが開いているかどうか)

```shell
$sudo yum install -y amazon-efs-utils
$sudo mkdir [マウントしたいディレクトリ]
$sudo mount -t efs [ファイルシステムID]:/ [マウントしたいディレクトリ]
```

ディスクの残容量を確認してみると、実際にマウントされているのが分かります。
一番下のnfs4タイプのものがEFSで作成したファイルシステムです。

```shell
$ df -Th
Filesystem                                     Type      Size  Used Avail Use% Mounted on
devtmpfs                                       devtmpfs  232M   60K  232M   1% /dev
tmpfs                                          tmpfs     242M     0  242M   0% /dev/shm
/dev/xvda1                                     ext4      7.8G  1.1G  6.7G  14% /
fs-df2acfbe.efs.ap-northeast-2.amazonaws.com:/ nfs4      8.0E     0  8.0E   0% /home/ec2-user/efs
```

#まとめ
ファイルシステムの作成自体はマネジメントコンソールをポチポチするだけで出来ますし、
マウントも数行のシェルを叩くだけで簡単に出来ました。
セキュリティグループに穴を空け忘れていて少し詰まってしまいましたが…

一つの試行がかなり簡単に出来るので、
東京リージョン対応に向けて、幾つか試していきたいですね。

#参考
https://dev.classmethod.jp/cloud/aws/amazon-elastic-file-system-is-generally-available/
React 360を覗く

## React 360とは
React 360は、Facebook社製の3DおよびVR空間上のユーザーインターフェイスを実装するためのフレームワークです。Reactの上に構築されており、Reactユーザーなら馴染み深い様々なエコシステムを利用して開発していくことができます。  
もともとはFacebookとOculusが共同でReact VRというJavaScriptライブラリをリリースしていましたが、Oculusが独自にC++実装によるネイティブバージョンを開発しはじめたため、混乱を避けるためにオープンソースのReact VRをReact 360に改名しました。

React 360
https://facebook.github.io/react-360/

Githubを見るとStar数は6000以上になっており、HMDの普及によって最近注目度が高まっています。

## アーキテクチャ
React 360のアーキテクチャはReact Nativeのそれとよく似ています。
React NativeはネイティブのUIスレッドとは別にReactアプリケーション実行用のJSスレッドを立ててその橋渡しとなる非同期ブリッジを提供します。
React Nativeレンダラは、Reactコンポーネントがレンダリングされると、UIアップデート情報をシリアライズし、非同期ブリッジを介して送信します。UIスレッドはこの情報を受け取ってデシリアライズし、それに応じてネイティブUIを更新します。

<img src="https://qiita-image-store.s3.amazonaws.com/0/73643/a8bad265-6edb-2798-35f3-8a595008f9df.jpeg" width="400px">

これと同様にReact 360ではメインスレッドとは別にWebWorkerスレッドを立て、Reactアプリケーションコードを実行します。(React 360はブラウザ上で動作するため、先のUIスレッドがブラウザのメインスレッドにあたります。)
Reactアプリケーションコードはメインスレッドとは別のスレッドで実行されるため、requestAnimationFrameのパフォーマンス(FPS)を向上させます。別スレッドであるがゆえwindowやdocumentは参照できないので注意です。

<img src="https://qiita-image-store.s3.amazonaws.com/0/73643/58836467-f250-4fa1-d7c8-5648c1e34054.jpeg" width="400px">

React 360のプロジェクトは以下のコマンドで作成できますが、

```shell

react-360 init プロジェクト名
```
作成されるclient.jsがメインスレッド用、index.jsがWebWorkerスレッド用になっています。

### レンダリングの仕組み
React Componentがレンダリングされると、必要なUIアップデート情報をReact Nativeが提供する非同期ブリッジによってメインスレッドに通知します。(postMessage)
React 360はOVRUIと呼ばれるOculusのライブラリを利用して、UIアップデートのペイロードをThree.jsコマンドに変換し、WebGLを使用して3DシーンをCanvasにレンダリングしています。

## A-Frameとの違いは？
React 360はよく[A-Frame](https://aframe.io/)と比較されます。 
結局どっちつかったらいいの?といった疑問もちらほら見かけます。

A-Frameの最大の特徴はHTML(Web Components)ベースで実装できるのでJavascript詳しくない人でも簡単にコンテンツが作れてしまうところなのかなと思います。あとは視覚的に3D空間を編集できる[A-Frame Inspector](https://github.com/aframevr/aframe-inspector)が使えるところでしょうか。
個人的な感想ですが、インタラクションを伴う複雑なUIを構築したい場合はReact 360、パノラマViewなどちょっとしたVR体験をさせたい！といった場合はA-Frameを選択すればいいんじゃないかなと思っています。(いまのところ)

### aframe-react
最近はA-FrameをReactで扱えるようにしたaframe-reactなるものもあるようで、React 360と似てるけど何が違うの？みたいなissueがありました。
このissue(https://github.com/facebook/react-360/issues/18) でFacebookのamberroyは以下のように答えています。

- React 360アプリケーションはJavaScriptで書かれ、JSXタグはJSに変換されます。 A-FrameアプリケーションはHTML(カスタムHTMLタグ)を使用します（これをメリットととるかデメリットととるかはあなたがJSとHTMLどちらで作りたいかによります）

- React 360はReact Nativeの上に構築され、WebVR用のJSランタイムを備えていますが、aframe-reactはReact JSとA-Frameをブリッジするためのただの薄いレイヤーです。

React 360とaframe-react、表面上はよく似ているのですがランタイムが全く違うので、React Nativeの恩恵を受けたい場合はReact 360を選択するでいい気がします。

## 所感
React 360ってゲーム作れるのかな！と思って調べ始めましたが、そもそもゲーム向けにデザインされてるものではないですね、。
簡単なゲームなら作れそうですが、ローラーコースターみたいなコンテンツを作りたい場合はもう、直接Three.jsのAPI使ってゴリゴリ書く方が自由度高そうです。

まぁでもReactのエコシステムに乗っかってVRコンテンツを作っていけるのはだいぶ嬉しいですし、めんどくさかったVRディスプレイの検出周り(getVRDisplays)やVRシーンへの切り替え(requestPresent)を気にすることなくやってくれるので非常に便利です。

パフォーマンス面もちょっと気になるので、それはまた今度書いてみたいと思います。
claspを使ってGoogle Apps Scriptをローカルで開発・編集する その1 - claspを使ってみる

# claspとは

https://github.com/google/clasp

Google Apps Scriptをローカルで開発・編集するためのCLIツール。

## なぜclaspを使うのか
* gitなどでソースコードのバージョン管理をできるようにするため
* TypeScriptでコードを書けるようにするため
* webpackなどでモジュールを使えるようにするため
* 使い慣れたエディタでコードの編集ができるようにするため

# claspのインストール
## CLIのインストール

```
npm i @google/clasp -g
```

## Google Apps Script APIの有効化
https://script.google.com/home/usersettings からGoogle Apps Scriptを有効にする

## ログイン
```
clasp login
```
を実行して、Googleアカウントにログインする。

# 既存のスクリプトをローカルで編集してみる
## スクリプトのIDを調べる
https://script.google.com/home を開いて、cloneしたいスクリプトを開く。開かれたURL(https://script.google.com/home/projects/<スクリプトID>)からスクリプトIDを調べる。

## cloneする
```
mkdir housework-logger #clone先のローカルディレクトリを作る
cd housework-logger
clasp clone <スクリプトID>
```

`clone`するとファイル一式がローカルにダウンロードされる。これらのファイルを適宜`git`などに登録して管理する。

## スクリプトの編集
clone先ディレクトリ内でファイルを編集してみる

## スクリプトのアップロード
```
clasp push
```

`push`すると、ローカルディレクトリ内のファイルがサーバーにアップロードされる。アップロードされるだけでデプロイはされないので注意。なお、ウェブ上のエディタで編集したものをローカルにダウンロードしたい時は`pull`する。

## 確認
```
clasp open
```

`open`すると、ブラウザが立ち上がりそのスクリプトをウェブ上のエディタで確認できる。

なお、`clasp push`でスクリプトをアップロードしても、ブラウザ上のエディタでは手動でリロードをしないと変更を確認できないので注意。(自動リロード機能がないため)

# ここまででできるようになったことと次に試すこと
Google Apps Scriptのファイルをローカルで編集できるようになった。gitでバージョン管理ができるようになり、同時に使い慣れたエディタでの編集ができるようになった。

次の投稿では、スクリプトをTypeScriptで書けるようにしてみる。

[claspを使ってGoogle Apps Scriptをローカルで開発・編集する その2 - TypeScriptを使う](https://qiita.com/croquette0212/items/757f1833a85b76d963c9)
AutoCADのVBAマクロで、モデル空間とレイアウト空間の全テキストをCSV型式で出力する

# 作成したきっかけ
図面内のテキスト情報をExcelで比較したかった為

## 動作環境
- windows10
- AutoCAD2017

## AutoCAD画面（赤文字を出力したい）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/157498/17f1c8a3-c7ef-f518-df84-e640a8920150.png)

# VBA本文

```vb
Option Explicit

Sub テキスト情報をCSVに出力()

   Dim acDoc As AcadDocument
   Dim acEnt As AcadEntity
   Dim lines_count As Integer
      
    Dim p_xyz() As Double
    Dim str_data As String
    Dim i, num As Integer
  
    str_data = "空間名称,ﾚｲｱｳﾄ名,,テキストの内容,文字高さ,X座標,Y座標,Z座標" & vbCrLf
                      
   For Each acDoc In Documents
      For Each acEnt In acDoc.ModelSpace
         If (TypeOf acEnt Is AcadText) Or (TypeOf acEnt Is AcadMText) Then
            str_data = str_data & "ModelSpace,,"
            p_xyz = acEnt.InsertionPoint
            
              str_data = str_data & "モデル空間,""" & acEnt.TextString & """" & "," & acEnt.Height & "," & p_xyz(0) & "," & p_xyz(1) & "," & p_xyz(2) & vbCrLf
                        
         End If
      Next acEnt
   Next acDoc

  num = ThisDrawing.Layouts.Count
'
  For i = 0 To num - 1
  ThisDrawing.ActiveLayout = ThisDrawing.Layouts.Item(i)
  Debug.Print ThisDrawing.Layouts.Item(i).Name
  
    For Each acDoc In Documents
      For Each acEnt In acDoc.PaperSpace
         If (TypeOf acEnt Is AcadText) Or (TypeOf acEnt Is AcadMText) Then
            str_data = str_data & "PaperSpace," & acDoc.PaperSpace.Layout.Name & ","
            p_xyz = acEnt.InsertionPoint
            
              str_data = str_data & "レイアウト空間,""" & acEnt.TextString & """" & "," & acEnt.Height & "," & p_xyz(0) & "," & p_xyz(1) & "," & p_xyz(2) & vbCrLf
            
         End If
      Next acEnt
   Next acDoc
  Next i
  
  MsgBox "テキストのピックアップ終わり"
   
  Dim file_name_txt, file_name_csv As String

  file_name_csv = Environ("HOMEDRIVE") & Environ("hOMEPATH") & "\Documents\" & ThisDrawing.Name & "のテキスト抽出.csv"

  Open file_name_csv For Output As #1
  Print #1, str_data
  Close #1

  MsgBox "テキスト抽出しました。"
    
  Shell "C:\Windows\Explorer.exe " & Environ("HOMEDRIVE") & Environ("hOMEPATH") & "\Documents\", vbNormalFocus

End Sub
```

## 出力結果のサンプル（Shift-JISで出力）
空間名称,ﾚｲｱｳﾄ名,,テキストの内容,文字高さ,X座標,Y座標,Z座標
ModelSpace,,モデル空間,"{\fMS PGothic|b0|i0|c128|p50;わんわん}",2.5,36.2851367064068,-6.52786883406679,0
ModelSpace,,モデル空間,"{\fMS PGothic|b0|i0|c128|p50;abcde}",2.5,51.5677627384648,-6.73566893855514,0
ModelSpace,,モデル空間,"{\fMS PGothic|b0|i0|c128|p50;わんわん２}",2.5,18.9870629190264,74.9428743475937,0
viコマンドで制御文字を入力 coneta #2

####**制御文字**
　制御文字はもともとディスプレイ、プリンター、通信装置などを制御するための文字です。
　通常のテキストではあまり使われないため、現在は、文字入力を行うソフトウェアのコマンドとして使われることが多いです。

####**制御文字の種類**
　ASCIIの制御文字は0(0x00)～31(0x1f)、127(0x7f)ですが、拡張されています。詳しくはウィキペディアを参考にしてください。
【参考】
　　　[ウィキペディア(制御文字)]
(https://ja.wikipedia.org/wiki/%E5%88%B6%E5%BE%A1%E6%96%87%E5%AD%97)
　　　[ウィキペディア(ASCII)]
(https://ja.wikipedia.org/wiki/ASCII)

####**制御文字を入力するには**
　制御文字は一部(※)を除いて、キーボードに物理的なキーが存在しません。
　　　※　Tab、Esc、BackSpaceなどは専用のキーがあります。
　制御文字を入力する場合は`Ctrl`キーを押しながら、その制御文字に対応するキーを押下します。
　例えば制御文字`EOT`(伝送終了、End of Transmission、値0x04)に対応する文字は`D`(ディー、値0x44)なので、`Ctrl`キーを押しながら、`D`を押下すると、制御文字`EOT`を入力することができます。
　この制御文字は、「コントロール+D」、「`^D`」と表記し、「こんとろーるでぃー」または「こんとろーるでー」と発音します。
【参考】
　　　[ウィキペディア(キャレット記法)]
(https://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%A3%E3%83%AC%E3%83%83%E3%83%88%E8%A8%98%E6%B3%95)


　制御文字をそのまま入力すると、その制御文字に割り当てられている機能が働き、制御文字を文字として入力できない場合があります。
　`^V`を入力し、続けて制御文字を入力すると、制御文字の機能が抑止され、文字として入力することができるようです。
　例えばcatコマンドで標準入力をファイルにリダイレクトしているとき、`^C`を入力するとcatコマンドが終了しますが`^V^C`を入力すると`^C`がファイルに書き込まれます。

　「`^V`」による制御文字の機能抑止が、端末エミュレータソフトの働きなのか、ttyデバイスの働きなのかはよくわかりません。



####**viで制御文字を入力する**
　viの入力モードでも「`^V`」で制御文字の機能を抑止できますが、NUL(値0x00、`^@`)はこの方法で入力することができませんでした。
　ところが`^V^J`を入力するとなぜか`^@`が入力できました、おそらくvimの機能でなんとかしているのでしょう。

　いろいろ試したのですが、DEL(値0x7F、`^?`)は入力することができませんでした。
　どうしてもviでDELを入力したい場合は、コマンドモード(非入力モード)で以下をキーインしてみてください。

~~~
:r! echo -e "\x7F"
~~~

　DELだけの行が挿入されますので、後は適当に加工してください
　　※　DELもyankバッファに入れられるようです。
　この方法は面倒ですが、\x7Fを変えることにより、DEL以外の制御文字も入力できます。

####**環境**


ホスト　Windows10 COREi7 
VM　　　VirtualBox バージョン 5.2.8 r121009 (Qt5.6.2)
　　　　　CentOS Linux release 7.4.1708 (Core)
　　　　　3.10.0-693.21.1.el7.x86_64 #1 SMP Wed Mar 7 19:03:37 UTC 2018
GNU bash, バージョン 4.2.46(2)-release (x86_64-redhat-linux-gnu)
NVIM v0.2.0

---
PHPのインストール確認を php -v でやってはいけない（戒め）

#概要
- PHP のインストールに失敗しているのに php -v に成功する場合がある

#例
PHP 7 をインストールするため、次のコマンドを打ったとします。

```
$ sudo yum -y install php7.0 php70-mbstring php70-pdo
```

ここでは**誤って "php7.0" という存在しないパッケージを指定**しています。

実際にインストールされるのは以下です。

```
=======================================================================================================
 Package                  Arch             Version                        Repository              Size
=======================================================================================================
Installing:
 php70-mbstring           x86_64           7.0.30-1.29.amzn1              amzn-updates           1.3 M
 php70-pdo                x86_64           7.0.30-1.29.amzn1              amzn-updates           171 k
Installing for dependencies:
 php70-cli                x86_64           7.0.30-1.29.amzn1              amzn-updates           4.7 M
 php70-common             x86_64           7.0.30-1.29.amzn1              amzn-updates           1.2 M
 php70-json               x86_64           7.0.30-1.29.amzn1              amzn-updates            65 k
 php70-process            x86_64           7.0.30-1.29.amzn1              amzn-updates            79 k
 php70-xml                x86_64           7.0.30-1.29.amzn1              amzn-updates           310 k

Transaction Summary
=======================================================================================================
```

見てわかる通り**PHP 本体はインストールされていませんが、php -v を打つと、**

```
PHP 7.0.30 (cli) (built: May 10 2018 17:39:13) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
```

**とバージョン情報が表示されます。**

そのため、「バージョン情報が出るからインストールされているっぽいのに、なぜかPHPが動かない」という状況に陥ってしまいます。

#どうしてなのか
試しに php70-cli を単独で yum install してみた場合でも php -v ができました。
PHP 本体がなくても、cli パッケージがあればバージョン確認ができてしまうようです。

#結論
- 正確を期す場合は、php -v ではなく yum list installed | grep php* で確認
- yum のメッセージはよく読むべし
DiskMon の tray disk light を自動起動する

PC がフリーズした時、ストレージ アクセスを示す LED がないと原因が分からず、強制再起動すべきか判断できないことがあります。最近は LED の省略された端末や VDI 環境など、画面上でアクセス状況を確認しなければならないことが増えてきました。

この目的で [Process Explorer](https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer) の disk history の tray icon を使うのが一つの方法です。この方法は起動後の最大規模のアクセスを捉えやすい反面、それ以下のアクセスではグラフに目立った山が表れないという欠点があります。確定診断に役立つ、特異度の高いツールだと言えるでしょう。

一方、[DiskMon](https://technet.microsoft.com/ja-jp/sysinternals/diskmon.aspx) の disk light はアクセス有無を赤と緑で表示します。こちらは除外診断に役立つ、感度の高いツールだと言えるでしょう。併用することで、効果的な障害切り分けが可能になります。

ここでは、現在のユーザー (管理者) でログインした場合に DiskMon の disk light を自動的にトレイに入れるための設定を紹介します。合わせて、**電池節約のために電源接続時だけ起動するようにするための設定**と、逆に***バッテリー駆動時にも動作を継続するための設定***も記載しています。

1. タスク スケジューラを開く
1. 左ペインの "タスク スケジューラ ライブラリ" を選択
1. 右ペインから "タスクの作成" を開く
1. "全般" タブを以下のようにする
  - 名前(M): `DiskMon LED` など、適当な名前
  - "最上位の特権で実行する(I)" をチェック
1. "トリガー" タブを以下のようにする
  1. "新規(N)..." を開き、以下のように設定する
     - タスクの開始(G): ログオン時
     - "特定のユーザー(C)" を選択 (現在のユーザーになるはず)
  1. **AC 電源に戻した際に再度自動起動したい場合、**"新規(N)..." を開き、以下のように設定する。(イベントの発生契機について公式情報が見つからなかったため、他の環境でも動作するかは分かりません。)
     - タスクの開始(G): イベント時
     - ログ(O): システム
     - ソース(S): Kernel-Power
     - イベント ID(T): 105
1. "操作" タブを以下のようにする
  - "新規(N)..." を開き、以下のように設定する
    - "プログラム/スクリプト(P)": `C:\Program Files\Sysinternals\Diskmon.exe` (実際の場所に合わせて読み替えてください)
    - 引数の追加 (オプション)(A): `/l`
1. ***バッテリー駆動時にも動作を継続したい場合、***"条件" タブを以下のようにする
  - "コンピューターを AC 電源で使用している場合のみタスクを開始する(P)" をアンチェック
1. "設定" タブを以下のようにする
  - "タスクを停止するまでの時間(K)" をアンチェック

初回起動時は EULA への同意が必要です。

また、手元では上記設定直後にタスクから起動した際、なぜか tray light ではなく通常のウィンドウとして表示されてしまいました。手で (Ctrl+M) トレイに格納したところ、その後は動作するようになりました。うまく動作しなかった場合にはお試しください。
スコープの使い方と処理の引き渡し(サーブレット)

# スコープ

スコープとは、サーブレットやJSPを跨いでデータを共有したい場合に用いる保存領域のこと。
共有範囲に応じて以下の3種類がある。

- リクエストスコープ
- セッションスコープ
- アプリケーションスコープ


サーブレットのdoGetやdoPostメソッド内でスコープに保存し、
フォワードメソッドで次に引き渡す使い方が多い。

doGetメソッドとdoPostメソッドの宣言部分のテンプレートは次の通り。

```java:doGet,doPostメソッドの宣言
// doGet
Public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException{
}

// doPostも同じ
Public void doPost(HttpServletRequest request, HttpServletResponse response)
      Throws ServletException, IOException{
}
```



## リクエストスコープ
ブラウザからのリクエスト毎に生成されるスコープのこと。次のリクエストが来た場合やブラウザを閉じたり、アプリケーション・サーバーが再起動した場合は原則保持されない。

### 使い方

```java
// リクエストスコープに保存する
request.setAttribute("属性名", 保存したいインスタンス);

//リクエストスコープからインスタンスを取得する
型 名前 = (型) request.getAttribute("属性名");


// 属性名とはスコープを指し示すインデックスのこと
// 型とは保存したインスタンスの型のこと
// 名前とは取得したインスタンスにつけたい参照変数のこと
```




## セッションスコープ
ブラウザを閉じない、あるいはタイムアウトしない限り保持されるスコープ。

### 使い方

```java
// セッションスコープの保存領域を確保
HttpSession session = request.getSession();

// セッションスコープに保存
Session.setAttribute("属性名", 保存したいインスタンス)

// セッションスコープからインスタンスを取得
型 名前 = (型) session.getAttribute("属性名");
```



## アプリケーションスコープ
アプリケーション・サーバーが終了しない限り保持されるスコープ。ブラウザを閉じても保持される。

### 使い方

```Java
// アプリケーションスコープの保存領域を確保
ServletContext sc = getServletContext();

// アプリケーションスコープに保存
sc.setAttribute("属性名", 保存したいインスタンス)

// アプリケーションスコープからインスタンスを取得
型 名前 = (型) sc.getAttribute("属性名");
```




# 処理の引き渡し
処理を次のサーブレットやJSPに渡す際、スコープに保存したデータを引き継ぐにはフォワードというメソッドを用いる。データを引き継がない場合、リダイレクトを用いても処理を渡すことができるが外部サイトに引き渡す際に利用されることが多い。フォワードメソッドではサーバー内でしか処理を引き渡せない。


## フォワード
スコープに保存したデータを引き継いで、次のページに処理を引き渡す方法のこと。
サーバー側が自動的に次の処理を実行してブラウザに返す。同サーバー内で処理を引き渡す際は、特にデータの引き継ぎがなくてもフォワードを用いることがある。

### 使い方
```java
RequestDispatcher dispatcher = request.getRequestDispatcher("フォワード先");
dispatcher.forward(request, response);

// 次のパッケージが必要
import javax.servlet.RequestDispatcher;

// フォワード先はディレクトリ構成に従ってパスを書く
// 例えば：
request.getRequestDispatcher("/WEB-INF/jsp/hogehoge.jsp")
```



## リダイレクト
次にどこにアクセスすれば良いかをサーバーからブラウザに返し、ブラウザはその指定先に次の処理をリクエストする。この仕組の都合上、外部サイトへのアクセスに適している。

### 使い方
```java
request.sendRedirect("リダイレクト先");

// リダイレクト先はURLで指定しても良いし、同サーバー内であればファイル構成に従ったパスでも可
// 例えば：
request.sendRedirect("http://www.hogehoge.com")
request.sendRedirect("/サーブレット名")
```
Navigation(AAC)でBottomNavigationどうやるの

#**注意**

>こちらはnavigationの**preview版**時点での話です。リリース版では挙動が異なる可能性があるので信じないでください。

#はじめに

**Navigation**の[**Navigation Codelab**](https://codelabs.developers.google.com/codelabs/android-navigation/#0)のサンプルを見てて気になったのですが、BottomNavigationのmenu２つ目のFragment **どこでアタッチしてるんや・・・？**

navigationのfragment idもどこで呼ばれてるわけでも無し、Navigation使ってるからFragmentTransactionなんて呼んでるわけないし

気になったのでちょっとコード読みました。

#結論

**NavigationUI # setupWithNavController**がうまいことやってくれてます

上記のメソッドの引数で

```kotlin
setupWithNavController(
            @NonNull final BottomNavigationView bottomNavigationView,
            @NonNull final NavController navController)
```

結論これに渡してあげるだけ。もう少しだけ奥を見ていきます。

**NavigationUI # setupWithNaController**の中を見るとこんなのがございます。

```kotlin:NavigationUI#setupWithNavController
navController.addOnNavigatedListener(new NavController.OnNavigatedListener() {
    @Override
    public void onNavigated(@NonNull NavController controller,
            @NonNull NavDestination destination) {
        int destinationId = destination.getId();
        Menu menu = bottomNavigationView.getMenu();
        for (int h = 0, size = menu.size(); h < size; h++) {
            MenuItem item = menu.getItem(h);
            if (item.getItemId() == destinationId) {
                item.setChecked(true);
            }
        }
    }
});
```

**あ、僕もこんなの書いたことある！( ﾟдﾟ )**ってのが出てきました。

どうやら**menu idとnavigation.xmlのfragmentやactivityに設定したid**で紐づけているようですね。

navigationのidはnavigationファイルでファイルの紐づけを行うと自動で採番されるので、menuファイルで命名をミスらないように気をつけないといけないようですね。

#最後に

サンプルにもありますが、**NavigationView(Drawer)**や**ActionBar**などもNavigationUIクラスにあるので、
navigationファイルとその他必要なファイルさえあれば、Drawerのクリックとか、setSupportActionBarとかとか
めんどくさいことやらなくてもいいみたいです。
matplotlibを日本語対応に

たくさん記事があるけどはまったのでメモ。
環境はCentOS7，python3。

## matplotlibrcファイルの場所
Jupyter notebookに次を入力

```python
import matplotlib
matplotlib.matplotlib_fname()
```

私の環境ではAnacondaからインストールしたので次のような感じ。
```/(username)/anaconda3/lib/python3.6/site-packages/matplotlib/mpl-data/matplotlibrc```


## フォント(ttf)ファイルを置く場所
上記 ```matplotlibrc``` と同じフォルダにある```./fonts/ttf```下。
先ほどの例で具体的には
```/(username)/anaconda3/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf```下。

## DBの再構成
いろんな記事で```fontList.py3k.cach```を削除するように，とあったけどファイルが見つからなかった。
次のように一度rebuildすることで解決。

```
matplotlib.font_manager._rebuild()
```
Railsでよく使う、tryメソッドの使い方をまとめてみた

## tryメソッドとは何なのか

**オブジェクトがnilでない場合のみ、そのオブジェクトのメソッドを実行したい！**って時に使うメソッドです。

これを使うことによって、オブジェクトがnilの時にメソッドを使ってエラーを吐いてしまうのを防ぐことができます。

##tryメソッドを使えるようにする

Ruby単体では使うことができません。
なのでまず、ActiveSupportを使ってRuby言語を拡張する必要があります。

```
gem install activesupport
```

##tryメソッドの使い方

まず、以下の二つの式を見比べて見ましょう。

```ruby
user ? user.age : "年齢なし" #userがいるか確認している
```

```ruby
user.try(:age) || "年齢なし" #userがいるか確認していない
```

どちらも、**userがnilならばuserのage(年齢)を表示し、nilでなければ「年齢なし」を表示する処理**を書いています。

前者は、いちいちuserがnilなのか確認してメソッドを実行するか判断しているのに対し,

後者は、userがnilでない場合のみメソッドを実行しています。

こう見ると後者の方が簡潔ですよね。


また、以下のように連続して使うことも可能です。

```ruby
user.try(:posts).try(:content) #userがいればpostsを実行し、postsがあればcontentを出力
```



##tryとtry!の違い
また、tryの他に**try!**というものもあります。

違いはこんな感じです。

###try
**userがnilの時、何もしない**
userにメソッドが実装されてない時、何もしない

###try!
**userがnilの時、何もしない**

二つの効用をもつtryに対して、一つの効用しか持たないものがtry!ですね。
また、`user.try!(age)`の代わりに、`user&.age`を使うこともできるようです。

参考： https://www.sejuku.net/blog/21897
[備忘録]Java Silver SE8資格取得しました

# Java Silver SE8を受験しました
[Java SE 8 認定資格](http://www.oracle.com/jp/education/certification/jse8-2489021-ja.html)
つい先日OracleのJava Silver SE8の資格試験を受験してきました。
やっと肩の荷が降りたって感じです...笑
試験自体はやはり基本的なところから、様々なパターンの問題を出してくるので、逆にこの時どんな結果になるんだっけと考えるのが大変でした。そんな中で学んだことに抜けがあると多分地獄絵図ですよね、本当...。
それだけ難しいと感じました...人によって違うのでしょうけど。

# 使用した参考書
[オラクル認定資格教科書 Javaプログラマ Silver SE 8](https://www.amazon.co.jp/%E3%82%AA%E3%83%A9%E3%82%AF%E3%83%AB%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E6%95%99%E7%A7%91%E6%9B%B8-Java%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E-Silver-SE-8/dp/4798142735/ref=sr_1_2?ie=UTF8&qid=1528006865&sr=8-2&keywords=java+silver)
　→ 必須本。人によっては「黒本だけで十分」という人もいるみたいです。とりあえず何周かしてみましょう。

[徹底攻略 Java SE 8 Silver 問題集[1Z0-808]対応](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5-Java-Silver-%E5%95%8F%E9%A1%8C%E9%9B%86-1Z0-808/dp/4844339931/ref=sr_1_1?ie=UTF8&qid=1528006865&sr=8-1&keywords=java+silver)
　→ 超必須本。試験に非常近い問題が出ます。中にはほぼそのままのものが出るものも...。それだけ試験の内容を抑えていると言える参考書となっています。

[オラクル認定資格教科書 Javaプログラマ Silver SE 8 スピードマスター問題集](https://www.amazon.co.jp/%E3%82%AA%E3%83%A9%E3%82%AF%E3%83%AB%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E6%95%99%E7%A7%91%E6%9B%B8-Java%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E-Silver-SE-%E3%82%B9%E3%83%94%E3%83%BC%E3%83%89%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E5%95%8F%E9%A1%8C%E9%9B%86/dp/4798142743/ref=sr_1_3?ie=UTF8&qid=1528006865&sr=8-3&keywords=java+silver)
　→ お金と時間に余裕のある人だけ。正直この参考書に関しては消化しなくてもいいかなと思いました。黒本に比べて、問題の難易度は優しめです。ただこれと同じ内容のものがスマートフォンアプリとしても出ているので、(物理的に)手軽に勉強できるという利点があります。

# 参考にしたサイト様一覧
[Java8 Silver試験の備忘録](https://qiita.com/hhhhh/items/bdf5b5672f99573e3826)
[[java] Java SE 8 Silver メモ](https://qiita.com/kharigai/items/6cdcb9e66b327669703b)
[Java Silver資格取得に向けて気を付けるポイント](http://shiguregaki.hatenablog.com/entry/2017/03/22/Java_Silver%E8%B3%87%E6%A0%BC%E5%8F%96%E5%BE%97%E3%81%AB%E5%90%91%E3%81%91%E3%81%A6%E6%B0%97%E3%82%92%E4%BB%98%E3%81%91%E3%82%8B%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88)

# 試験前のポイント
* 1.紫本、黒本を読み込む
* 2.受験体験記を読む
* 3.実際に書く、どんな結果になるのかを自身で確認する

1は言わずもがなですね。ただこの二つだけやっても正直足りません。
2はとても助かりました。Silverに関しては試験勉強、試験自体に関して備忘録を残している人が多いので、試験のポイントをしっかりと抑えているようなアドバイスが載っていてとても参考になりました...。
3は必須です。逆に紫本黒本だけで受かる人はすごいと思う。いや、覚えるのは当然なんでしょうけど、座学だけでいけるなんて逆に尊敬しますよ...。

# 最後に
あれだけ勉強してもってことで、正直余裕かな？と勉強している中では思っていたのですが、
いざ試験を受けてみると試験の空気感に飲み込まれたり、自身で確認する部分が足りなかったり...。
当然自分がちゃんと問題範囲内の知識を備えていない部分があったというのもあったのですが、悔しかったですね。

何はともあれ合格はできたので、次はJava Goldを目指すぞ！と。
ネイティブなnodejsライブラリのインストールについて

###### node-gyp
ネイティブなnodejsライブラリをインストールするためのツール

###### windows-build-tools
Windows環境でnode-gypを使用するために必要なツール
windows-build-toolsをインストールするとpythonとpip(pythonのパッケージマネージャ)もインストールされれる。
[node.js]HerokuでMongoDBを使う

# 概要
ちょっとしたAPIサーバーを立てたかったのでHerokuで試してみた。

# 前提
- GitHubのリポジトリを紐付けるやり方でデプロイしている
- すでにコードは出来ている

# Herokuにデプロイ
## Procfile
ルートディレクトリに`Procfile`を作成

```
web: node ./bin/www
```

## MongoDB
### Add-ons
「Resources」→「Add-ons」
`mongo`と打つと`mLab MongoDB :: Mongodb`が出てくるのでとりあえず`Sandbox - Free`を選択して`Provision`をクリックする。
### MONGOLAB_URI
「Setting」→「Config Vars」→「Reveal Config Vars」
ここに`MONGOLAB_URI`がある。

### Heroku用にコード修正
```app.js
mongoose.connect('Herokuで表示されたMONGOLAB_URI(mongodb://heroku〜みたいなやつ)');
```
PlantUML導入手順 (Mac)

# 目的
- MacからplantUMLを使えるようにする
- githubでUMLのバージョンを管理できるようにする

## 導入したい理由
- 設計時のモデリングなど、excelなどを使いがちだが、それだとバイナリのため、差分管理ができない
- リポジトリに上げると更新するたびに全部書き換えになって思い
- そもそもバージョン管理ができない管理がおろそかになりがちになってドキュメントが信用できなくなってくる

## 環境
- plantUML
- plantUML Viewer 0.7.1

## 手順
### brewのトラブル対応
- brewで一発でダウンロードできる
- というが、ここで usr/local の権限でbrewが使えないという問題が発生したため、以下の方法で対処
- OSのバージョンの問題？なのか、最近この問題が発生し、対処が行われたらしい

> brew update: /usr/local 権限周りの問題＝更新で解消
> https://qiita.com/masa_36/items/a811c9335e2e985f6adc

### インストールの実行

```bash
brew install graphviz
brew install plantuml
```

### エディタ
- Atom に PlantUML Vieweを導入する
- パッケージからsetteing view画面を開く
![スクリーンショット 2018-06-03 14.53.32.png](https://qiita-image-store.s3.amazonaws.com/0/57455/2a62b251-47a5-ff59-9b78-c106fadff1af.png)

- plantumlで検索する
![スクリーンショット 2018-06-03 14.52.51.png](https://qiita-image-store.s3.amazonaws.com/0/57455/f7015240-2537-0a56-a08e-0fe2cdcb01ad.png)

- この二つのインストールを行う
![スクリーンショット 2018-06-03 14.52.37.png](https://qiita-image-store.s3.amazonaws.com/0/57455/f8dca837-374e-5b3b-a584-bfc0f5edafdc.png)

- コードを書き

```
@startuml
actor test

activate test
activate web
test -> web :order
activate business
web -> business : order
activate DB
business -> DB : search
DB -> DB : search recasive
business <-- DB :responce 
deactivate DB
web <-- business :responce 
deactivate business
test <-- web :responce 
@enduml
```

- `control + opt + p`

![スクリーンショット 2018-06-03 15.12.58.png](https://qiita-image-store.s3.amazonaws.com/0/57455/d5c0133d-3ad5-3462-7690-63afd611c65f.png)

- 図の保存
 - 画像ペイン上で右クリックで出力が可能
 ![スクリーンショット 2018-06-03 15.15.47.png](https://qiita-image-store.s3.amazonaws.com/0/57455/220ea2e8-56ed-186f-bae9-4591c9077a72.png)
- 拡張子がデフォルトではeps担っているが、拡張子をpng等に変更すると、その形で出力が行われる

- シーケンスずに限らず、ユースケース図、クラス図等の具体的な文法は、先行チートシートなどが参考にできる
> - PlantUML Cheat Sheet
> - https://qiita.com/ogomr/items/0b5c4de7f38fd1482a48



## 参考
> PlantUMLをMac OS Xで使う
> https://qiita.com/kohashi/items/1d2c6e859eeac72ed926

> PlantUMLを自動変換してLiveプレビューしてくれるAtom拡張 PlantUML-Viewer がイイ！
> http://pierre3.hatenablog.com/entry/2015/08/23/220217

> PlantUML Cheat Sheet
> https://qiita.com/ogomr/items/0b5c4de7f38fd1482a48
`where コマンド名`（具体的には`Python.exe`）で複数のpathがあるときに、pathの優先順位を変更する手順

# 手順のまとめ
1. コマンドプロンプトで `where コマンド名`を実行し、出てきたpathを覚えておく。
1. 「コントロールパネル」→「システム」→「システムの詳細設定」→「環境変数」に移る。
1. 1.で出てきたpathが含まれている環境変数を編集し、「上へ」「下へ」のボタンで優先順位を変更する。
    + たいてい `PATH` に入っている。

## 注意
この方法だと、優先順位が下ろされた方をコマンドプロンプトから呼び出すにはフルパスを入れなくてはならない。

# 背景
Anaconda3を再インストールしたときに、コマンドプロンプトで `python` コマンドを実行すると、なぜか `ImportError: no module named site` というエラーが出た。
しかしAnaonda3のインストール先で `python.exe` を実行すると起動した。
また、`jupyter notebook` も起動した。   

# 原因
使用しているPCに `python.exe` を持っているプログラムがanacondaのほかにも存在した。具体的には `MySQL Workbench` 。
`where python` で調べると、下図のように２つあることが判明した（図は修正後のもの）。   
![cmd_where_python.png](https://qiita-image-store.s3.amazonaws.com/0/146354/577c4984-28c5-439b-f757-2af4291c28f1.png)   

# 解決方法
今回は、これらのpathが環境変数 `PATH` に入っていたので、`PATH` の編集画面に入って下図のように順序を入れ替えた。   
![syspath_order.png](https://qiita-image-store.s3.amazonaws.com/0/146354/b46430e3-753e-6c53-b59f-415f8bc7b774.png)

# ちなみに
昔、Perl（DWIM Perl限定？）を入れていたときに `pip` が同じように衝突した覚えがある。
ヤフオク 出品者用 ブックマークレット「受取連絡待ち」足し算

# まぁ、なんていうか。

本当に作ろうとしていたものは、別のものなんですが、その途中で できたものです。

ヤフオクは2018年3月から、落札者さんが「受取連絡」しないと、出品者に入金されないようになりました。(カテゴリにもよる)

そのため、ヤフオクの[売上金管理](https://receive.wallet.yahoo.co.jp/)に、ずら～っと「受取連絡待ち」が並ぶようになりました。

それの合計額を表示するだけのブックマークレットです。

「俺 受け取ってない金額いくらあるんだろう？」それを知るためだけのものです。

単純に class=suspend (オレンジ色の文字)になっているものを足し算しているだけなので、「ヤフー審査中」も合計に含んでしまいます。


```javascript

javascript:void(function(){

var t=0,s;
var arrs=document.getElementsByClassName("suspend");

for(i=0; i<arrs.length; i++){
    s = arrs[i].innerHTML.replace(/[^0-9]/g, '');
    t = t + parseInt(s);
}

alert("合計額:"+t);

}())
```
## 動作確認環境

Windows 10
Google Chrome 67
mdadm（ソフトウェアRAID）の使い方

###### ソフトウェアRAID
複数の実体デバイス(/dev/sda?等)をまとめあげて、１つの仮想デバイス(/dev/md?)として見せる仕組み

###### RAIDの状態確認

```bash
cat /proc/mdstat
mdadm --detail --scan
mdadm --detail /dev/md1
```

###### RAIDからデバイスを切り離し（非アクティブに）

```bash
mdadm --fail /dev/md1 /dev/sda1
```

###### RAIDからデバイスを取り除く（--fail後のみ実行可能）

```bash
mdadm --remove /dev/md1 /dev/sda1
```

###### アクティブなデバイス数の変更(RAID0, RAID1のみ)

```bash
mdadm --grow /dev/md1 --raid-devices=2
```

###### RAIDの停止

```bash
mdadm --stop /dev/md1
```
[Ubuntu16.04] Laravel導入時のApacheのドキュメントルート設定

## ドキュメントルート設定

標準だと`var/www/html`になっている。
**今回は`var/ww/html`下にLaravelプロジェクトをおいている想定です。**

```bash

$ cd /etc/apache2/
#バックアップとっておく
$ sudo cp apache2.conf apache2.conf.cp
$ vim apache2.conf
```
```apache.conf
# 書き換え
<Directory /var/www/html>
      ↓  ↓  ↓
<Directory /var/www/html/laravel_project_path>
```

```bash

$ cd /etc/apache2/sites-available
$ sudo cp 000-default.conf hoge.conf
$ vim hoge.conf
```
```hoge.conf
# 書き換え
DocumentRoot /var/www/html
            ↓  ↓  ↓
DocumentRoot DocumentRoot /var/www/html/laravel_project_path/public

# 追加
<Directory "/var/www/html/laravel_project_path">
                AllowOverride All
                Require all granted
</Directory>
```

```bash

$ sudo a2dissite 000-default.conf
$ sudo a2ensite hoge.conf
# 権限変えとく
$ chown -R www-data:www-data /var/www/html/laravel_project_path
$ chmod -R 775 /var/www/html/laravel_project_path/storage
$ chmod -R 775 /var/www/html/laravel_project_path/bootstrap/cache
# 再起動
$ sudo service apache2 restart
```

これで完了
aws lambdaで開発中に発生するエラーおよびつまづきポイントまとめ

# 注意
この記事は2018年6月に作成された記事であり、AWSのアップデートによりこの内容が適用できない場合がありますのでご留意ください。

使用言語:node
バージョン:v8.11.1

# 過去に遭遇したエラー集
## 今まで動いていたlambda関数が(何もしてないのに)失敗するようになった,,,
s3に格納されているファイルのリストを返す関数なので、対象ファイルの増加に伴い実行時間が増加し、
timeoutの時間にひっかかった。timeoutの時間を伸ばすことにより解消。

## aws lambda update-function-codeがtimeoutする,,,
timeoutの原因については家の回線とか送信ファイルの量とか色々あるが、
大体は --cli-connect-timeout <timeout時間(sec)> でtimeout時間を長めにとればうまくいきやすい。

## grpcのライブラリが原因で実行時にエラーが出る,,,(自分はfirebaseのライブラリを使った時に出ました)

```
Unable to import module 'index': Error
Expected directory: node-v48-linux-x64-glibc
Found: [node-v57-darwin-x64-unknown, node-v57-linux-x64-glibc]
This problem can often be fixed by running "npm rebuild" on the current system
Original error: Cannot find module '/var/task/node_modules/grpc/src/node/extension_binary/node-v48-linux-x64-glibc/grpc_node.node'
(略)
```
出力にもあるように期待されているライブラリはnode-v48-linux-x64-glibcだが見つからない,と出ている。
期待されているやつ得るには以下のコマンドでgrpcをリビルドする必要がある。
`npm rebuild grpc --target=6.1.0 --target_arch=x64 --target_platform=linux --target_libc=glibc`
参考：[Make sure the Node library works on AWS Lambda #6443](https://github.com/grpc/grpc/issues/6443)

## Api Gatewayと紐付けたのに呼ばれない、、、  
Apiをデプロイしていない。Apiにlambda関数を紐づけたのに実行されない(CloudWatchにlambdaのログが出ない)などの場合、
Api Gatewayに対して行った修正がデプロイされていないことが原因である場合が比較的多かった。
aws lambdaはそれ単独で使うより、AWSの他サービスと連携して実行する場合があるので、
想定通りの結果が得られない場合は他サービスの設定が問題ないか調べると良い。
Unite2018 シロが紹介していたアセットで興味ありなもの

Unite2018 シロが紹介していたアセットで興味ありなものをまとめました。

観点：OculusGoの開発で使えそう&使ってみたいもの

# ツール系
* 014: Probuilder
* 029: Local Package Importer
* 035: UniRx
* 040: Object Labels/ Notes
* 057: ProGrid

# 見た目系

* 004 + 005: Post Processing Stack
* 032: Enviro -Sky and Weather
* 034: Tween
* 037: Easy Save
* 080: 6000+ Flat Buttons Icons Pack
* 081: Wet Road Materials
* 082  Sky Packages
* 084: Milkey Way Skybox
* 094: Poly Tool Kit
* 095: Vuforia AR + VR Sample
IntelliJ IDEAでホットデプロイ

１．
build.gradleに以下を追記

```gradle
compile("org.springframework.boot:spring-boot-devtools")
```

２．
IntelliJ IDEAの設定→コンパイルで自動ビルドのところにチェック

３．
Ctrl+Shift+Aでポップアップされたウインドウに「レジストリ」と入力して、compiler.automake.allow.when.app.runningにチェックする
[zsh]zsh compinit: insecure directoriesの警告が出ないようにする

# 概要
zshを起動するたびに以下の警告がでるので非表示に。

```zsh
zsh compinit: insecure directories, run compaudit for list.
Ignore insecure directories and continue [y] or abort compinit [n]?
```

# 解決
```zsh
$ cd /usr/local/share/zsh
$ sudo chmod -R 755 ./site-functions
```

```zsh
$ cd /usr/local/share/
$ sudo chmod -R 755 zsh
$ sudo chown -R root:staff zsh
```

一応これで警告は表示されなくなった。

# 参考
[https://stackoverflow.com/questions/13762280/zsh-compinit-insecure-directories/41674919#41674919](https://stackoverflow.com/questions/13762280/zsh-compinit-insecure-directories/41674919)
[zsh compinit: insecure directories and files, run compaudit for list. #433](https://github.com/zsh-users/zsh-completions/issues/433)
ブックマークレット用 Toastもどき。

# まぁ、タイトル通りです。

基本的に これ単体で使うことは想定していません。

ブックマークレットの中で、alert を使うと「閉じるのが面倒くさい」且つ「何も表示しないのは心許ない」という時に使ってます。

```javascript
javascript:void(function(){

var sc = document.scrollingElement.scrollTop; 

var text = document.createElement('span');
text.innerHTML='色は匂へど　散りぬるを<br><b>我が世誰そ　常ならむ</b><br><font color=red>有為の奥山　今日越えて</font><br>浅き夢見じ　酔ひもせず';

var ts = text.style;

ts.color = '#000';
ts.backgroundColor = 'white';
ts.padding = '15px';
ts.border = '1px solid gainsboro';
ts.boxShadow = '3px 3px 10px';
ts.zIndex = '100';

document.body.appendChild(text);

ts.position = 'absolute'; 
ts.top = 50 + sc + 'px'; 
ts.left = (window.innerWidth / 2)-(text.offsetWidth / 2) + 'px'; 

setTimeout(function () { text.style.visibility = "hidden"; }, 1500);

}())
```

ちなみに、removeChild せずに、CSSで非表示にしているだけなので、ゴミは残ります。

## 動作確認環境

Windows 10
Google Chrome 67
KotlinでDB接続

build.gradleに以下を追記

```gradle
https://qiita.com/kojisaiki/items/be5805bba172aab188c3
compile 'org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.2'
compile 'org.postgresql:postgresql'
spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/<DB名>
    username: <ユーザ名>
    password: <パスワード>
    driver-class-name: org.postgresql.Driver
```

参考
https://qiita.com/kojisaiki/items/be5805bba172aab188c3
KotlinでRest通信

build.gradleに以下を追記してfuelをインストール
`compile 'com.github.kittinunf.fuel:fuel:1.12.1'`

サンプルソース

```kotlin
// 同期処理
val triple = "https://www.google.co.jp/".httpGet().response()
// レスポンスボディを表示
println("同期処理の結果：" + String(triple.second.data))
```
Node.js : Basic Level - サーバー設定を実装してみる

```golang

var http = require ('http');
var settings = require('./settings.js')
console.log(settings);
var server = http.createServer();
var msg;
server.on('request', function(req, res){
     switch(req.url){
       case '/hello':
            msg = "Hello world";
            break;
       case '/about':
            msg = "How about you?";
            break;
       default:
            msg = "wrong page";
            break;

     }
     res.writeHead(200, {'Conten-Type': 'text/plain'});
     res.write(msg);
     res.end();
});
server.listen(settings.port, settings.host);
console.log("server listening ...");
```

参照：ドットインストール
https://dotinstall.com/lessons/basic_nodejs
Dockerコマンド

|機能|コマンド|
|:--|:--|
|バージョン参照|docker version|
|稼働中のコンテナを見る|docker ps|
|停止中のコンテナも見る|docker ps -a|
|コンテナの削除|docker rm <コンテナのName or ID>|
|停止中のコンテナを起動|docker start <コンテナのName or ID>|
|稼働中のコンテナに入る|docker attach <コンテナのName or ID>|
|イメージの作成、更新|docker commit <コンテナのName or ID> <イメージのName of ID>|
|イメージの参照|docker images|
|イメージの削除|docker rmi <イメージのName of ID>|
|||
|||
|||
|||
|||
|||
|||
|||
|||
Ubuntuの初期設定

###### ifconfigのインストール
```bash
apt-get install net-tools
```

###### pingのインストール
```bash
apt-get install iputils-ping
```

###### manのインストール
```bash
apt-get install manpages-ja
```

###### apt-getの使い方
```bash
# パッケージの検索
apt-cache search <パッケージ名>
# パッケージの削除
apt-get --purge remove
```

###### beep音の停止
```bash
vi  /etc/modprobe.d/pcspkr.conf
# 以下のテキストを追記
blacklist pcspkr
```

###### ディレクトリ名の文字化け対策
```bash
export LANG='ja_JP.UTF-8'
```

###### 文字コードUTF-8固定化
```bash
vi ~/.bashrc
# 以下を追記
export LANG=ja_JP.UTF-8
export LANG
```

###### wgetのインストール
```bash
apt-get install wget
```

###### Noto Sans CJKのインストール
```bash
wget https://ja.osdn.net/downloads/users/9/9930/NSCJKaR.tar.xz
tar xavf NSCJKaR.tar.xz
rm NSCJKaR.tar.xz
wget https://ja.osdn.net/downloads/users/10/10745/fonts.conf
mkdir -p ~/.local/share/fonts/ ~/.config/fontconfig/
mv fonts.conf ~/.config/fontconfig/
mv NSCJKaR/ ~/.local/share/fonts/
```

###### wineのインストール
```bash
apt-get install apt-file
apt-file update
apt-file search add-apt-repository
apt-get install software-properties-common

add-apt-repository ppa:wine/wine-builds
dpkg --add-architecture i386
apt-get update

apt-get install wine
```

###### ウィルスバスターのインストール
```bash
apt install clamav
```

###### Google Chromeのインストール
```bash
sudo wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
sudo sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
sudo apt-get update
sudo apt-get install google-chrome-stable
apt-get install libpango1.0-0

sudo vim google.list
# 1行だけ記載されているので、それをコメントアウトする
```
wordpressでのcustomizeメモ

# 画像の追加
```
$wp_customize->add_setting( 'header_img' );
$wp_customize->add_control( new WP_Customize_Image_Control( $wp_customize, 'header_img', array(
    'label' => 'ロゴ画像',
    'section' => 'img_section',
    'settings' => 'header_img',
    'description' => 'ロゴ画像を設定してください。',
)));
```

# テキストの追加
```
$wp_customize->add_setting( 'contents[main_text]', array(
    'default' => '',
    'type' => 'option',
    'transport' => 'postMessage',
));
$wp_customize->add_control( 'main_text', array(
    'settings' => 'contents[main_text]',
    'label'    => 'メインのテキストを入力して下さい。',
    'section'  => 'contents_section',
    'type'     => 'text',
));
```
Python×Seleniumでクローリング備忘録 

Seleniumでブラウザを自動操作してWebサイトをクローリングするためのメモ。
BeautifulSoupはJavaScriptでガチャガチャしているWebサイトのクローリングには
向かないようなので、今回はSeleniumでやってみた。ブラウザはGoogleChromeを使用。

---
# 実行環境

Windows10 
Python 3.6.0
Selenium 3.12.0
GoogleChrome  66.0.3359.181(64bit) 
ChromeDriver 2.38

---
# 準備すること
※前提としてChromeとpython3がインストールされていること

1.セレニウムのインストール
```$ pip install selenium
```
2.[ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/downloads)をダウンロード
　Pathが通っているところに配置するか、実行時の引数でDriverの場所を渡すようにする。

---

# 基本的な操作
Google検索で「Python」を検索してみる。
考え方的にはJavaScriptでDOM操作するときと大差ない感じ。

```python:google_search.py
from selenium import webdriver

# ChromeのDriverオブジェクト生成。(DriverにPathを通してない場合はここで引数として渡す)
driver = webdriver.Chrome(executable_path="C:\driver\chromedriver.exe")

# Googleのページを開く
driver.get("https://www.google.co.jp/")

#検索窓のelementを取得
search_box = driver.find_element_by_id("lst-ib")

#検索窓に"Python"を入力
search_box.send_keys("Python")

#検索ボタンのelementを取得
search_button = driver.find_element_by_name("btnK")

#検索ボタンを押下
search_button.click()

```
---

# その他クローリングに必要そうなこと
#### 1.要素の属性を取得
```python:get_attribute.py

#リンクのhref属性の値を取得
href = driver.find_element_by_tag_name("a").get_attribute("href")

#画像のsrc属性の値を取得
src = driver.find_element_by_tag_name("img").get_attribute("src")

#etc....

```

#### 2.画像を保存する
```python:save_image.py

import shutil
import requests
import base64

def save_image(src, file_save_path):

    #Base64エンコードされた画像をデコードして保存する。
    if "base64," in src:
        with open(file_save_path, "wb") as f:
            f.write(base64.b64decode(src.split(",")[1]))

    #画像のURLから画像を保存する。
    else:
        res = requests.get(src, stream=True)
        with open(file_save_path, "wb") as f:
            shutil.copyfileobj(res.raw, f)
```
#### 3.ブラウザを非表示で実行する。

画面を立ち上げずに裏で動いてくれるヘッドレスモードというモードがある。
普通に動かすよりもちょっとだけ処理が速いらしい。

```python:headless_mode.py

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

#ChromeのDriverオブジェクト生成時にオプションに引数を追加して渡す。
options = Options()
options.add_argument('--headless')
driver = webdriver.Chrome(chrome_options=options)

#DriverにPathを通していない場合はこんな感じで一緒に渡す。
driver = webdriver.Chrome(executable_path="C:\driver\chromedriver.exe",chrome_options=options)


```
---
#あとがき
単純なデータ収集なら、これくらいあれば問題なく作れました。

実際にクローリングする際のルールとして、
**「リクエストとリクエストの間隔を最低一秒空ける。」**
**「robots.txtで許可されていない部分はクローリング対象に含めない。」**
などを考慮してプログラムを組む必要がありそうです。
*（一歩間違えると攻撃してるのと大差なくなってしまいますね。）*