OmniAICreator/Qiita-1.07M huggingface dataset:
gcc の -finput-charset で UTF-8 以外を指定すると大変な目に合った

gcc にはソースファイルの入力文字セットを指定するオプション `-finput-charset` があります。これは可能な限り使用せずに、ソースファイルの文字セットは UTF-8 にしよう！　という話です。

## そもそも `-finput-charset` って何？

ソースファイルの文字セットを指定するためのオプションです。デフォルトは UTF-8 です。

cp932 (Shift-JIS) でソースが書かれていて、このオプションをつけていないとまれに問題を起こします。例えば、以下のコードは `-finput-charset` なしでは `n = 0` を出力します（わざとらしい例ですが）。

```cpp
#include <iostream>
int main() {
    int n = 0;
    // ここで n に代入する値の意味は、同梱の資料を見てください。
    // see: 〇〇設定表
    n = 42;
    std::cout << "n = " << n << std::endl;
}
```

昔懐かしい `表` の文字化け問題ですね。cp932 の `表` は 0x95 0x5c というバイト列ですが、0x5c は `\` のため、コメント行末尾に `\` が来たと解釈されて次の行 `n = 42` もコメント扱いされます。

`-finput-charset=cp932` をつければ、コンパイラは文字 `表` を 1 文字と正しく解釈するので上のコードはちゃんと `n = 42` を出力します。

## 問題が発生する例

問題はここからです。

試しに `-finput-charset=cp932` をつけて、以下の 1 行のコードをコンパイルしてみましょう。

```cpp:forward_listをincludeするだけのコード
#include <forward_list>
```

このコードはコンパイルが通りません。gcc 8.2.0, 7.3.0, 5.5.0 で確認しましたが全てエラーになりました。

```shell-session
$ echo '#include <forward_list>' > tmp.cpp
$ g++ -finput-charset=cp932 tmp.cpp
In file included from tmp.cpp:1:0:                                                                                     
/usr/include/c++/7/forward_list:38:31: error: failure to convert cp932 to UTF-8                                        
 #include <bits/forward_list.h>                                                                                        
                               ^
 (...以下略...)
```

なぜこうなるかというと、gcc の forward_list のヘッダファイル内で UTF-8 文字を使っているためです。

入力文字セットに cp932 を指定したので、gcc は iconv を使ってソースファイルを cp932 から gcc が使用するソース文字セットに変換してコンパイルします。そこで `#include <forward_list>` から読み込むヘッダファイル内に cp932 でない文字が含まれていると変換できないのでエラーになっていました。

ちなみに、UTF-8 文字は `bits/forward_list.h` の 783 行目にあります。

```shell-session
$ grep -P -n "[^\x00-\x7F]" /usr/include/c++/7/bits/forward_list.h
783:      // 23.3.4.5 modiﬁers:
```

え、UTF-8 文字なんてない？ いえ、よく見てください。`ﬁ` は fi という 2 文字ではなくて LATIN SMALL LIGATURE FI (\uFB01) という UTF-8 の 1 文字です。

推測ですが、実装したひとは non-ascii な文字を導入したつもりは全くなくて、pdf か web からコメントの文 `23.3.4.5 modiﬁers` をコピーしてきて混入したのではないかと思われます。

## どうするべきか？

`-finput-charset` を指定するのはやめて、ソースコードを UTF-8 にしましょう。

STL に限らず、GitHub のかなり人気のライブラリ（例えば [catch2](https://github.com/catchorg/Catch2) とか）でも同じ問題があり、`-finput-charset` を使う限り結構な頻度ででくわします。
flashの中へリンクを埋め込む

ajaxで可能な限りページ変移させないアプリを作っていたため、リンクの数もできるだけ削りたかった。
そこで一部リンクをflahメッセージの中に組み込むことにした。

大して難しいことはやっていないが、意外に情報が少なかったため個人的な再利用用として置いておく。

以下のように書くと、flash[:success]の場合にリンクが設置される。

```ruby:_flash.html.erb
<% flash.each do |message_type, message| %>
  <div class="alert alert-<%= message_type %>">
    <%= message %>
    <% if flash[:success] %>
      <p><%= link_to 'リンクテキスト', "https://〜", target: '_blank' %></p>
    <% end %>
  </div>
<% end %>

```

flashメッセージもずっと残しておくと邪魔なので適当な時間が経過したら消す。
どこかで_flash.html.erb全体にidを指定しておく。

```
$("#flash").fadeOut(10000);
```

flashが表示されたり消えたりすると要素が上下してしまうので、z-indexを指定して要素の上に乗っける。
後は適当にお好みでいじる。
ちなみに以下は常に画面右下に配置されるようにしている。

```
#flash {
  position: fixed;
  top: 80%;
  left: 5%;
  width: 70%;
  height: 200px;
  text-align: center;
  font-size: 15px;
  z-index: 2;
}
```

要するにこのqiitaのflashとだいたい同じ感じのができる。

#以上！
コールバックがあるコルーチンをObservable化してみる

# コールバックがある場合のコルーチンをObservable化してみる 

コルーチン終了後の処理をコールバックメソッド的に書く方法が手段の一つとしてあります。

```csharp

    public IEnumerator CallbackCoroutine(Action<string> callback)
    {
        //なんかいろいろやる
        yield return new WaitForSeconds(5);
        
        callback("some methods completed");
    }

```

こういう処理はRxがあるならFromCoroutineで書けばいいのですが、なんかのこってるときにこれをObservable化したいなーと思ったのでちょっとやってみます。

## FromCoroutineだけではダメ

FromeCoroutineだけだと、コルーチンの終了をとるだけなのでコールバックの面倒は見てくれません。

## Createを使う

なのでCreateを使うのがシンプルかなと思います。

CreateメソッドはobserverがSubscribeされた時の挙動を全部記述してあげるメソッドです。
observerには,コールバックに渡されるパラメータをそのまま渡したいので次のようになります。

Subjectを使ってもいいですが, その場合Hot Observableになってしまうので扱い面倒くさくなります。

```csharp

    public IObservable<string> ToObservable()
    {
        return Observable.Create<string>(observer =>
        {
            StartCoroutine(CallbackCoroutine(s =>
            {
                //コールバックに入ってきた値をそのままobserverに渡します。
                observer.OnNext(s);
                observer.OnCompleted();
            }));
            // ここではcancellation tokenを返しますが
            // キャンセル機構を持っていないのでEmptyでいいでしょう
            return Disposable.Empty;
        });
    }

```

# まとめ
全部合わせるとこんな感じです

```csharp
using System;
using System.Collections;
using UniRx;
using UnityEngine;

public class ParameterCoroutine : MonoBehaviour {

    public IEnumerator CallbackCoroutine(Action<string> callback)
    {
        //なんかいろいろやる
        yield return new WaitForSeconds(5);
        
        callback("some methods completed");
    }

    public IObservable<string> ToObservable()
    {
        return Observable.Create<string>(observer =>
        {
            StartCoroutine(CallbackCoroutine(s =>
            {
                observer.OnNext(s);
                observer.OnCompleted();
            }));
            return Disposable.Empty;
        });
    }

    void Start()
    {
        ToObservable().Subscribe(Debug.Log);
    }

}

```

因みにですが, もしこのObservableをUnityのメインスレッド以外で起動したい場合は, Unityの仕様に併せてSubscribeOnしてあげて下さい。

### コールバックが三つも四つもある場合

知らん設計がおかしい
エラーとかはOnErrorに投げればいいよ
デジオシ(PDS5022S)を修理?してみた

## 症状

コントラスト調整ボリュームがとてもピーキー。
触れるだけで最小から最大まで振れる。
コントラストを調整できない。

## とりあえず分解してみる

ネットの分解記事を参考に分解。
背面のビス2本を抜き、上下のツメ計4箇所をはずすとパカっとひらける。
前面と背面の間にケーブルが何本か通っていて、長さにそれほど余裕が無いので、勢いよく開けると千切れそう。

背面には電源モジュールがついている。
容量抜けとかもよくある症状らしいけど、今の所電源周りに問題はないし、交換できるコンデンサも持って無いので、電源周りは今回はスルー。

電源と前面のメインボードとは、いくつかの配線やシールド線(裸の網線)でつながっている。
配線はコネクタを抜けば外れる。
シールド線ははんだ付けされてるので、半田ごてではずす。50Wの温調コテで剥がせた。でもあんまり余裕がない感じなので、電子工作用の20Wとかじゃ厳しい。

問題のボリュームは、ボリュームだけの基板になっていて、シールド等は無く、簡単に取り外すことができた。幸先がいい。
コネクタが固くて、ピンセットでこじろうと思ったらピンセットが曲がったりしたけど。

![2018-12-27_14-28-51_IMG_0027.jpg](https://qiita-image-store.s3.amazonaws.com/0/264452/7fd8f3e7-1eb9-ea0e-44fd-189afbe94ce9.jpeg)

![2018-12-27_14-27-56_IMG_0026.jpg](https://qiita-image-store.s3.amazonaws.com/0/264452/f2796c6b-a779-06cf-470e-bd06ee83e49c.jpeg)

![2018-12-27_14-27-46_IMG_0025.jpg](https://qiita-image-store.s3.amazonaws.com/0/264452/86c3ff5c-51e0-fcb9-2e84-df12644fe09e.jpeg)

ボリュームが1個と3線のコネクタが付いてるだけなのに、裏面にはいろいろ部品が乗ってる。
パスコンが2個、抵抗が2個、ジャンパが1個。
はんだ付けの品質はそれほど高くない?

片面基板なので、ボリュームを外すのは容易なはず。

シルクや部品のマーキングから、10kΩBカーブの可変抵抗ということが読み取れる。
シルクのVR103は「103個めの可変抵抗」という可能性も捨てきれないが、たぶん103は10x10^3Ωで10kΩという意味だろう。
裏面のシルクも、ジャンパは000、1.8kは182、0.1uFはC104と書いてあるから、表面も部品番号ではなく定数で間違いないはず。


部品を交換する場合は、多少不格好にはなるが、ツマミのスリットから配線を3本引き出し、オシロの筐体の外側に10kΩBカーブのボリュームをつければ、部品自体の交換は容易そうだ。

今回は、表面のツマミ?の部品からブラシが見えたので、ここに接点回復スプレーを入れてグリグリしてみた。
仮組みして電源を入れてみたところ、無事にボリュームとしての機能が回復したので、今回はそのまま組んで様子見をすることにした。

組み立て後に、簡単に液晶パネルを掃除した。
また、メイン基板には触っていないが、分解したことから、念のために自動校正を行った。

![2018-12-27_14-50-23_IMG_0036.jpg](https://qiita-image-store.s3.amazonaws.com/0/264452/605a4ea1-2790-fdad-920d-b4f530e18d94.jpeg)

このパネル、ノングレアだと思ってたが、グレアだった。表面の汚れでノングレア風になってたんだな。

ch1とch2を比べてみると、ch2が若干ノイズが多い気がする。誤差のレベルって感じだけど。

## その他

ショップの注文履歴によると、このオシロを買ったのは11年4月末なので、もうすぐ8年というところか。当時3.1万円で買ったらしい。
今なら少し性能向上したものが2.5万円で売ってる。

とっくに元はとってるし、若干の能力不足も感じてるし、いよいよダメになったら上位モデルを買おう、と思い続けてるんだけど、なかなか壊れない。
マネーフォワードクラウド経費APIβを使ってみる

#経費の申請
休み明けに経費の申請が止まっているとの連絡がきました。
確かに止まってます。まったく気が付かなかった・・
ステータスを確認して「何か」が連絡してほしいなぁっということで何かないかと見てみると！

For Developer
API連携 β (開発者向け)

という、イイものを見つけました。

#MFクラウド経費API β
https://expense.moneyforward.com/api/index.html
ドキュメントもしっかりある！しかもSwaggerで！えらい！ということで使ってみます。

#アプリケーション登録
アプリケーション一覧で、アプリケーションの作成ボタンをクリック
フォームに必要な情報を入力し、利用規約に同意して作成ボタンをクリック
Client IDとClient Secretが発行されました。
楽ちんです:grin:

#認証
[https://expense.moneyforward.com/api/index.html](https://expense.moneyforward.com/api/index.html)　で確認できるので、Authorizeしてみます。
![Authorized.PNG](https://qiita-image-store.s3.amazonaws.com/0/180278/94edc9ae-b748-ade9-42d4-d527700466d4.png)

Authorizedになりました。

#確認１
試打の office 事業所一覧でテスト

```
Server response Code 200
```

```Response.json
"offices": [
    {
      "id": "----------------------",
      "identification_code": "-------",
      "office_type_id": -,
      "name": "アステリア株式会社"
    }
  ]
```

#確認２
試打の ex_report 自分の申請リストでもテストしてみます
必須項目がoffice_idなので入力します。

```
Server response Code 403 Error:Forbidden
```

動きません。
自分に権限がないだけかと疑い社内管理者に問い合わせるも、問題なし。

あきらめかけるも
「確認１」の事業所一覧で取得した id が妙に長いことを発見

取得した値を使ってみます　→　申請リスト取得成功

「office_id - 事業所id」とか書いてあるから4桁-4桁のあの番号かと思ったけど、違うみたいです。

ともあれ、取得内容を見てみると

```Response.json
"ex_reports": [
  {
    "id": "----------------------",
    "ex_report_type_id": "----------------------",
    "office_member_id": "----------------------",
    "status": "approved",
    "title": "12月　交通費",
    "number": ----,
    "submitted_at": "2018-12-13T00:00:00.000+09:00",
    "approved_at": "2018-12-13T01:00:00.000+09:00",
    "created_at": "2018-12-13T00:00:00.000+09:00",
    "updated_at": "2018-12-13T01:00:00.000+09:00"
  },
```
statusが違う・・・

statusは下記のような値が返ってくるはずなので、
この申請は「paid：支払済み」が返ってきてほしいが「approved：承認済み」が返ってきてる

| 値 | 意味 |
|-----------|------------|
| unsubmitted       | 下書き        |
| waiting_step_one     | 第一承認待ち      |
| waiting_step_two       | 第二承認待ち        |
| waiting_step_three         | 第三承認待ち          |
| waiting_step_four       | 第四承認待ち       |
| waiting_step_five    | 第五承認待ち     |
| approved    | 承認済み     |
| paid    | 支払済み     |
| canceled    | 取消済み     |
| rejected    | 却下済み     |

さらに、支払日も取得できないことに気が付く
もしかして、支払日ってカスタマイズしたのか？と思い、再度社内管理者へ問い合わせるも、カスタマイズしてないとのこと

ムムムやりたい事はできなさそう:confounded:

今日のところは終了となりました。
掛け算オペレータによるリストの初期化に注意

無意識にこの罠にハマったので、残しておく。
リストの一部を変更したのに、すべてが変更されてしまう場合はだいたいこれ。

## 掛け算オペレータでリストを初期化

Python のリストを初期化する際、すべての要素が同じでよければ、下記のように掛け算オペレータを使って書くことができる。

```python
>>> a = [0] * 5 # すべての要素が0で、要素数5のリストを作成
>>> a
[0, 0, 0, 0, 0]
```

しかし、上記のような `0` という数値（immutable オブジェクト）ではなく、 mutable　オブジェクトを入れると大変なことが起こる。
[こちら](https://qiita.com/utgwkk/items/5ad2527f19150ae33322) で詳しく解説されているので、詳細は省いて実際の挙動を見ていく。

```python
# 要素 `0, 1, 2` を持つリスト、を5つ持つリストを作成
>>> b = [[0, 1, 2]] * 5
>>> b
[[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]]
# 0 番目のリストの 1 番目の要素（＝1）を 2 に変更する
>>> b[0]
[0, 1, 2]
>>> b[0][1] = 0
>>> b[0]
[0, 0, 2]
# しかし、すべてのリストで値が変更されてしまう。
>>> b
[[0, 0, 2], [0, 0, 2], [0, 0, 2], [0, 0, 2], [0, 0, 2]]
```

list は mutable オブジェクトなので、上記のような作り方をすると識別値（id）が同じオブジェクトでリストが満たされてしまう。
その結果、一つの要素だけを変更しているつもりでも、リスト内の全ての要素が変更されてしまう。
これは、同じく mutable オブジェクトの dict やユーザ定義クラスでも同じことが起きる。

```python
# dict でも同じことが起きる
>>> c = [{"d": 1}] * 5
>>> c
[{'d': 1}, {'d': 1}, {'d': 1}, {'d': 1}, {'d': 1}]
>>> c[0]["d"] = 2
>>> c
[{'d': 2}, {'d': 2}, {'d': 2}, {'d': 2}, {'d': 2}]

# ユーザ定義クラスでも同じことが起きる
>>> class E():
...     def __init__(self):
...         self.name = "E"
... 
>>> e = [E()] * 5
>>> e    # すべて同じ id であることが確認できる
[<__main__.E object at 0x7f9be776abe0>, <__main__.E object at 0x7f9be776abe0>, <__main__.E object at 0x7f9be776abe0>, <__main__.E object at 0x7f9be776abe0>, <__main__.E object at 0x7f9be776abe0>]
>>> e[0].name = "F"
>>> [ee.name for ee in e]
['F', 'F', 'F', 'F', 'F']
```

## 対処法1. リスト内包表記で初期化

一番すんなりいく解決策。

```python
>>> b = [[0, 1, 2] for i in range(5)]
>>> b
[[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]]
>>> b[0][1] = 0
>>> b
[[0, 0, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]]
```

## 対処法2. リスト内包表記 + zipを使う

zip でなんとか無理やりやってみたが、これは逆に手間が増える印象。

```python
>>> b = [list(z) for z in zip([0]*5, [1]*5, [2]*5)]
>>> b
[[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]]
>>> b[0][1] = 0
>>> b
[[0, 0, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]]
```

## 対処法3. 掛け算オペレータ + 代入時に新オブジェクト生成

掛け算オペレータをどうしても残したいなら、代入時に新idのオブジェクトを差し込むという手も。
膨大にリストの要素があって、なおかつほとんどは同じ値でいい場合はメモリの削減になるかも？

```python
>>> b = [[0, 1, 2]] * 5
>>> b
[[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]]
>>> b[0] = list(b[0])
>>> b[0][1] = 0
>>> b
[[0, 0, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]]
```

## 結論

素直にリスト内包表記で書くべし。
MojaveでEmacs26.1を野良ビルド

# はじめに
自分はMacでEmacsを使っているが、この1,2年ほど日本語のちらつき問題があり、パッチ付きビルドなどを使っていた。さらに、ここにきてMacOSがMojaveになり、描画エンジンの問題などもあり表示されないなどの現象も報告されているようだ。

- [Emacs 25.3/26.1をEMP版で快適に使う](https://qiita.com/takaxp/items/a86ee2aacb27c7c3a902)
- [MacOS Mojave(10.14)ではEmacsのレンダリングがおかしくなるらしい](https://tsuu32.hatenablog.com/entry/2018/09/29/023117)

いちEmacsユーザーの私では、原因を明確に特定し根本的な解決方法を実施することは不可能だが、とりあえずこの方法で行えばMojaveでEmacs26.1を野良ビルドできたという記事もあまりないので作成することにした。尚、本記事は以下の環境で作業がうまくいったというものであり、環境依存部分がかなりあるであろうことをご了承いただきたい。

# マシン環境
- MacBook Pro 15-inch ,2016
- プロセッサ 2.9GHz Intel Core i7
- メモリ 16GB 2133MHz LPDDR3
- OS macOS Mojave バージョン 10.14.2

# 作業手順
## 依存パッケージのインストール
このあたりは、configureやmakeをしながら止まったところでエラーメッセージやネットの記事調べ、解決したもの。

- Xcode
- autoconf (homebrew)
- gnutls (homebrew)
- texinfo (homebrew)
- automake (homebrew)
- pkg-config (homebrew)

## パス設定
texinfoはインストールしただけでは読み込まれない。パスの設定を以下で追加することで正しく読み込まれる。.bash_profileや.zprofileに以下を記載する。

```
export PATH="/usr/local/opt/texinfo/bin:$PATH"
```

## 環境変数設定
libxmlの読み込みでエラーがでる。こちらは以下の記事を参考に環境変数を設定することで解決。
- [Emacs-24.4 on OSX Yosemiteのビルド手順詳細](https://masutaka.net/chalow/2014-10-25-1.html)

```
export CFLAGS=`xml2-config --cflags`
```

# ビルド
千葉大学の山本氏のパッチが入ったソースコードを使ってビルドする。ご本人の公開リポジトリはこちら。
- [emacs-mac](https://bitbucket.org/mituharu/emacs-mac/overview)

あとは↑ページの記載にある通りにビルドする。私は以下のように作業した。

```
❯ git clone git@bitbucket.org:mituharu/emacs-mac.git
❯ cd emacs-mac
❯ ./autogen.sh
❯ ./configure --with-mac --enable-mac-app
❯ make
❯ sudo make install
```

これで、MacのApplicationディレクトリにEmacsがインストールされて無事に起動できる。
【Laravel】追加した空のディレクトリを Git 管理したい場合（.gitignore の書き方）

#やりたいこと

Laravel ディレクトリ内で下記の場所に新しいディレクトリ `files` を追加したとします。

```
Laravel
   ┗ storage
        ┗ app
           ┣ local
           ┃   ┗ files <- new
           ┗ public
```

このままでは新しく追加した `files` ディレクトリは Git 管理されません。
これを Git 管理できるように設定します。

#空のフォルダを Git 管理する

`app/` ディレクトリの中身を見てみると `.gitignore` というファイルが入っているかと思います。

```
Laravel
   ┗ storage
        ┗ app
           ┣ local
           ┣ public
           ┗ .gitignore <- !?
```

ファイル名からも想像できるように、このファイルは「Git で管理しないもの」を設定するためのファイルとなっています。

`app/` ディレクトリ内の `.gitignore` には下記のような内容が書かれています。

```Laravel/storage/app/.gitignore
*             # app/ ディレクトリ内のすべてのファイルを無視
!public/      # app/public/ ディレクトリは無視しない
!.gitignore   # app/.gitignore は無視しない
```

`*` は「すべてのファイルが対象」という意味、`!` は「無視しない（Git 管理する）」という意味になりますので、この場合は

> `app/` ディレクトリ内のすべてのファイルを Git 管理しないが、`app/public/` ディレクトリと `app/.gitignore` だけは Git 管理する

という設定になります。

#設定を書き換える

それでは新しく追加した `files` ディレクトリを Git 管理するように設定を書き換えます。

まずは `app/.gitignore` を下記のように編集します。

```Laravel/storage/app/.gitignore
*
!public/
!local/       # この行を追記
!.gitignore
```

これで `app/local/` がGit 管理できるようになりそうですが、Git は空のディレクトリを管理してくれません。

Git 管理するためには `app/local/` に何かしらのファイルを保存する必要があります。

そこで、`app/local/` 内にも `.gitignore` を保存することで Git 管理できるようにします。

```Laravel/storage/app/local/.gitignore
*
!.gitignore
!files/
```

これで `app/local/files/` ディレクトリも Git 管理できるようになりました。

さらにさら、これでは開発工程で `app/local/files/` ディレクトリに保存されたテスト用のファイルなども Git 管理されてしまうので、それは無視してもらいましょう。

```Laravel/storage/app/local/files/.gitignore
*
!.gitignore

# 逆に、Git 管理したいファイルがある場合は先頭に ! をつけてファイルを指定します。
```

`files` ディレクトリ内にも上記内容の `.gitignore` を設置することで不要なファイルを Git 管理から外すように設定できました。

#まとめ

あちこちに `.gitignore` が出てきましたが、最終的には以下のような構造になります。

```
Laravel
   ┗ storage
        ┗ app
           ┣ local
           ┃   ┣ files
           ┃   ┃   ┗ .gitignore
           ┃   ┗ .gitignore
           ┣ public
           ┗ .gitignore
```

正しく設定されていれば `files` ディレクトリも Git 管理できるようになっているかと思います。
includesしてもN+1クエリ問題が解決しない場合はcounter cultureを検討しよう

##0.はじめに

railsでN+1問題が発生した場合、とりあえずincludesで先にデータを読み込んでおけばいいんでしょ？と思っていた。
が、上記の方法でどうしても解決できないシチュエーションに陥った。
それは、countメソッドでデータの個数を数えたいときだ。
こういう場合、counter cultureというgemを導入して解決するといいっぽい。

##1.countメソッドでN+1クエリ問題が発生する具体的な例

例えば以下のように、UserとGroupがUserGroupを中間モデルとして、多対多の関係にあるとする。

```ruby:user.rb
class User
  has_many :groups, through: :users_groups
end
```
```ruby:group.rb
class Group
  has_many :users, through: :users_groups
end
```
```ruby:users_group.rb
class UsersGroup
  belongs_to :user
  belongs_to :group
end
```

次に、以下のようにcountでそれぞれのユーザーが所属するグループ数を取得しようとする。

```user_groups_count.html.erb
<% @users.each do |user| %>
  <%= user.groups.count %>
<% end %>
```

こうすると、当然のように大量のSQLクエリが発行されるが、includesで解決することはできなかった。

##2.counter cultureを導入しよう

user.groups.countでN+1クエリ問題に引っかかる。。。
この問題を解決するために、counter cultureというgemを導入します。

```
gem 'counter_culture'
```

```
bundle install
```

このgemを使用すると、countで毎回数え上げるのではなく、カラムに数値を保存して取り出せるようになります。
まずは、以下のコマンドを叩いて、親であるUserモデルにusers_groups_countというカラムを追加します。

```
rails g counter_culture User users_groups_count
```

```
rails db:migrate
```

続いて、中間モデルのUsersGroupに1行追記します。

```ruby:users_group.rb
class UsersGroup
  belongs_to :user
  counter_culture :user, column_name: "users_groups_count"
  belongs_to :group
end
```

以上で準備完了です。。
あとはuser.groups.countの代わりに、user.users_groups_countを使うことで、N+1クエリ問題を回避できます。

##3.注意点
既存データに対して使用したい場合は、counter_culture_fix_countsメソッドを使って値を更新する必要があります。
User.counter_culture_fix_countsを流しておけばOKです。

##4.最後に
備忘録的な意味合いが強いので、だいぶ雑に書いてしまいましたが、参考になれば幸いです。
Naming convention - 大文字・小文字に関わる命名規則を表す用語一覧

大文字・小文字に関わる命名規則を表す用語は、数が多いので整理しておく。

- linter を書く時に整理の必要を覚えた。その時のメモを今回清書した。
  - ref. [Protocol Buffer - protolint の説明と CI 導入手順 - Qiita](https://qiita.com/yoheimuta/items/2f8b293e46f8c114a84a)

single word（単一語） と compound word（複合語）で大別できる。

# single word

| 用語           | 別名              | 例           | 説明                                           |
|-----------------|------------------|-----------------|------------------------------------------------|
| Uppercase      | -          | FOO              | すべて大文字                                   |
| Lowercase      | -          | foo              | すべて小文字                                   |
| Capitalized    | UpperFirst          | Foo              | 先頭だけ大文字                                 |
| Uncapitalized    | LowerFirst          | fOO              | 先頭だけ小文字                                 |

# compound word

| 用語           | 別名              | 例:single+single->compound           | 説明                                           |
|-----------------|------------------|-----------------|------------------------------------------------|
| CamelCase      | LowerCamelCase          | foo+bar->fooBar | 複合要素（最初を除く）の先頭が大文字           |
| UpperCamelCase | PascalCase          | foo+bar->FooBar       | 複合要素の先頭が大文字                         |
| SnakeCase      | underscore_separated_names | fOo+bar->fOo_Bar              | 複合要素の区切りがアンダースコア               |
| UpperSnakeCase | CAPITALS_WITH_UNDERSCORES         | foo+bar->FOO_BAR              | 複合要素の区切りがアンダースコアですべて大文字 |
| LowerSnakeCase | -         | foo+bar->foo_bar              | 複合要素の区切りがアンダースコアですべて小文字 |

# 参考

- [prototool/strs_test.go at 43fb0e7a3b849ee691d8fe8ccdb09c19ce66ad0e · uber/prototool](https://github.com/uber/prototool/blob/43fb0e7a3b849ee691d8fe8ccdb09c19ce66ad0e/internal/strs/strs_test.go)
- [Lodash Documentation](https://lodash.com/docs/4.17.11#capitalize)
- [Style Guide  |  Protocol Buffers  |  Google Developers](https://developers.google.com/protocol-buffers/docs/style)
VSCode 用 SystemVerilogの拡張を作る（#9）

# シンタックスエラーを示す
VSCodeで書いていると、文法エラーがあると赤い波線などが出て「問題」に一覧表示されます。
以下のような機能です。

https://github.com/Rockdoor/systemverilog#diagnosis

この機能の実現は難儀しそうだと予想していましたが、ANTLRのエラーメッセージを少し加工してVSCodeに渡すとそれっぽい結果が出せたので楽でした。


# ANTLR4のエラーメッセージ回収
ANTLR4はデフォルトだとエラーメッセージをコンソールに表示して終わってしまいますが、ErrorListnerというリスナを再設定してやるとその挙動を変更できます。

とても簡単で、以下のコードがカスタムErrorListnerです。

https://github.com/Rockdoor/systemverilog/blob/master/src/sv_parser/sv_error.ts

```typescript
export class sv_error implements pg.ANTLRErrorListener<number> {
  diags: any;

  constructor() {
    this.diags = [];

    return this;
  }

  syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e) {
    let diag = {};
    diag["severity"] = vscls.DiagnosticSeverity.Error;
    diag["range"]    = {
      start: {line: line - 1, character: charPositionInLine},
      end:   {line: line - 1, character: charPositionInLine}
    }
    diag["message"]  = msg;
    diag["source"]   = "sv_parser";

    this.diags.push(diag);
  }
}
```

シンタックスエラーが起こると上記 syntaxErrorが呼ばれるので、そのたびにメッセージをLSP用の形式でdiagに保存していくだけです。
range情報があるとソースコード上に波線表示してくれるのでカッコいいわけですが、これもANTLR4から出てきます。


# エラーメッセージをVSCodeに表示
以下のようにErrorListnerをカスタムに置き換えて（単に追加でも良い）やると、パース毎にエラー情報を回収できます。

```typescript
    // invoke main parsing
    let chars  = new pg.ANTLRInputStream(repl_src);
    let lexer  = new svlex.SystemVerilogLexer(chars);
    let tokens = new pg.CommonTokenStream(lexer, svlex.SystemVerilogLexer.DEFAULT_TOKEN_CHANNEL);
    let parser = new svpar.SystemVerilogParser(tokens);
    let error  = new sv_error.sv_error();

    parser.removeErrorListeners();
    parser.addErrorListener(error);
    parser.buildParseTree = true;
```

これを元に、LSPで

```typescript
  connection.sendDiagnostics({
    uri: uri, 
    diagnostics: sva.filedb[uri].err.diags
  });
```

とすればVSCode上にエラー情報が表示されます。

送るべきデータ構造は公式の
https://microsoft.github.io/language-server-protocol/specification

```typescript
interface Diagnostic {
```

で定義されています。
ε-net Theorem の証明

![IMG_2216.png](https://qiita-image-store.s3.amazonaws.com/0/332653/6d06ac8f-38b1-a76f-6bd9-672513c1c0e5.png)
![IMG_2217.png](https://qiita-image-store.s3.amazonaws.com/0/332653/eff3b38e-41bf-bd58-371b-b6d734216393.png)
![IMG_2218.png](https://qiita-image-store.s3.amazonaws.com/0/332653/4f0279a8-0509-e166-ded8-9460c06c0de5.png)
![IMG_2219.png](https://qiita-image-store.s3.amazonaws.com/0/332653/a86add31-60fe-896e-1d34-8e8708d1334b.png)
![IMG_2220.png](https://qiita-image-store.s3.amazonaws.com/0/332653/4840da74-6f0f-ec16-6fe4-c58a65360257.png)
![IMG_2221.png](https://qiita-image-store.s3.amazonaws.com/0/332653/25bee137-26dc-2d54-6504-d45d93ab541c.png)
![IMG_2222.png](https://qiita-image-store.s3.amazonaws.com/0/332653/8ed529fd-c119-3709-ed36-c437114a2923.png)
LSL Animesh サンプルスクリプト

Twitter で初期化がうまくいかない時があるとかいてしまいましたが
再生したアニメをすべて破棄すればうまくいくようです

以下サンプル
スクリをリセットする際に Object が握っているアニメーションをすべて停止します

```[sample_start_animesh.lsl]
string g_anim = "つかいたいアニメ";

stop_all_animations()
{
    list curr_anims = llGetObjectAnimationNames();
    integer i;
    
    for(i = 0 ; i < llGetListLength(curr_anims) ; i++)
    {
        string anim = llList2String(curr_anims, i);
        llStopObjectAnimation(anim);
    }
}

default
{
    state_entry()
    {
        stop_all_animations();
        llStartObjectAnimation(g_anim);
    }

    attach(key id)
    {
        if(id)//有効なキーか NULL_KEY かを調べます
        {
            llStartObjectAnimation(g_anim);
        }
        else
        {
            llStopObjectAnimation(g_anim);
        }
    }
}

```
Google Cloud Certified - Professional Cloud Architect を取得するために（１／６）

#概要
Google Cloudの認定資格の一つであるProfessional Cloud Architectを取得するまでの軌跡をリアルタイムで記事として記録していく。
##Google Cloudって？
Googleが提供するクラウドサービス群の総称、コンピューティングサービスからデータ管理サービスまで様々なサービスが提供されている。詳細は[こちら](https://cloud.google.com/)を参照。 

##認定資格って？
Google Cloudが認定する[資格](https://cloud.google.com/certification/?hl=ja)、認定されるとGoogle Cloudを利用した設計から運用までのスキルがあることをアピールすることができる。トレーニングを受け試験に合格することで認定される。
今回は設計から運用までのスキルを必要とする[Professional Cloud Architect](https://cloud.google.com/certification/cloud-architect?hl=ja)という資格に挑戦する。
##何を記録していくの？
基本的にはどのようなトレーニングを行ったかと、トレーニングで学んだことを簡潔に記事としてまとめていく。これから当資格を目指す人の参考になればと思い経緯を記録していく。

##いつ試験受けるの？
2019年2月5日（火）

#筆者のGoogle Cloud歴
Google Cloudを使って1年程度、ただしApp EngineやCompute EngineやBigQuery等のサービスを個人的に利用しているだけで業務として利用しているわけではない。Java、Go、Pythonを使用したアプリ開発が可能。

#やる事
実施て予定のトレーニングは以下3つを予定している。クラスルームでのトレーニングも考えたが、コスト的に難しかったので今回は見送ることにする。

##書籍によるトレーニング
[Google Cloud Platform エンタープライズ設計ガイド](https://www.amazon.co.jp/Google-Cloud-Platform-%E3%82%A8%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%97%E3%83%A9%E3%82%A4%E3%82%BA%E8%A8%AD%E8%A8%88%E3%82%AC%E3%82%A4%E3%83%89-%E9%81%A0%E5%B1%B1-%E9%99%BD%E4%BB%8B-ebook/dp/B07C85YMCW/ref=sr_1_1?s=books&ie=UTF8&qid=1545889959&sr=1-1)を使用してGoogle Cloudの全体像や使ったことのないサービスの概要・使い方をトレーニングしていく。

##公式ドキュメントによるトレーニング
上記書籍に記載のないサービスや新しく追加されたサービスなどは[公式ドキュメント](https://cloud.google.com/docs/?hl=ja)を利用してトレーニングしていく。

##公式模擬試験の受験
公式に用意されている[模擬試験](https://cloud.google.com/certification/practice-exam/cloud-architect?hl=ja)で自分に足りない部分を見つけ出し、追加でのトレーニングを検討する。

#次回記事投稿予定
2019年1月4日（金）
[Rails] AWSを使ってデプロイした後のアプリ修正の仕方

デプロイしたもののレイアウトが崩れたなんてことがあると思います。
多分修正してgitに挙げた後クローンしてもいけますがコマンドだけでちょちょっと修正したいとき用のメモ。

因みに環境は
・Rails 5.2.2
・ruby 2.3.8p459 (2018-10-18 revision 65136) [x86_64-linux-gnu]
デプロイ環境
・aws 
・Apache
・Passenger

```
　$ ssh -i "/Users/ユーザ名/.ssh/〇〇〇〇.pem" ec2-user@<EIPのIPアドレス>
```
でec2ログイン。

```
$cd /var/wwww/html
$ls
sample_app (自分のアプリ名出るはず) 
$cd sample_app , $ls
app     config.ru  Gemfile.lock  package.json  README.md  tmp
bin     db         lib           public        storage    vendor
config  Gemfile    log           Rakefile      test
```
一旦htmlまで移動したらlsコマンドで自分のアプリ名確認。更にcdコマンドでアプリの中へ。
よくエディターでいじってたようなディレクトリたちが出てきます。
あとは編集したいものの1階層上くらいまで移動して($cd使う)　sudo vi 〇〇で開く。

```
　$ sudo vi application.html.erb(ここは開きたいファイル名)
```
vimで開けます。ESCとかaとか押すとinsertモードになるので直したいところ直しましょう。
入力が終わったらESCでコマンドモード(？)に戻して:wqまたはsiftキー＋zzで保存して終了。
ミスったときは:q!で保存しないで抜けられます。

ここまでで変更自体は出来てるんですが反映が出来てるかはちょっと別です。
viewとかは大丈夫みたいですがmigrationとかjsとかcssいじった場合はコンパイルします。手順は以下

```
$cd /../../..　　　　(var/wwwまで戻る。自分の現在地によって適宜。)
$sudo chown -R ec2-user:ec2-user html
```
で権限をec2ユーザに戻す。

```
$cd　(アプリの中まで戻る）
```
```
$bundle exec rake assets:precompile RAILS_ENV=production
$bundle exec rake db:migrate RAILS_ENV=production
```
コンパイルしなおす。コンパイルは2つやらなきゃいけないわけではなく、必要なほうだけで大丈夫。

```
$cd ..    (var/wwwに移動)
$ sudo chown -R apache:apache html
```

アパッチに権限を返す。

```
$sudo service httpd restart
```
で再起動。おしまい。
説明の為(主に前半)細かく分割してみたんですが、cd使うときはチルダでストレートに飛んで大丈夫です。
あと手順がもっと簡潔な方法があるかもしれないのであったら知りたいです、是非コメントにお願いします。
新しいRailsプロジェクトを作るときの手抜きコマンド

# 結論

```shell
echo source :rubygems and gem :rails.to_s > Gemfile
```

# どの辺が手抜きなのか

新しくrailsプロジェクトを作るときには空のGemfileを作って

```ruby:Gemfile
source :rubygems

gem 'rails'
```

って書いて保存して、コマンドラインから `bundle` `bundle exec rails new .`ってやるのですが、
最初のGemfileを作るのが面倒なので、どうにかラクにできないか考えていました。

# シングルクォートが消える
シェルにもよるのかもしれませんが、Bashで`'`を含む文字列をechoで出力するにはエスケープしないといけません。エスケープしないと消えてしまいます。

```shell
echo source \'https://rubygems.org\'  > Gemfile
echo gem \'rails\' >> Gemfile
```

ただ、これはBashとかのシェルの話で、Windowsのコマンドプロンプトにあるechoは`'`も`\`も消えません。
なので上のコマンドを実行すると円マークがそのまま出力されてしまいます。

```ruby:Gemfile
source \'https://rubygems.org\'
gem \'rails\'
```
Windowsでも使いたいので、シングルクォートを使わなくてもいいようシンボルを使いました。ライブラリの名前はシンボルだと怒られたので`to_s`して文字列にしています。

```shell
echo source :rubygems  > Gemfile
echo gem :rails.to_s >> Gemfile
```

# 二行も書きたくない
コマンド一回で作りたいので、Gemfileの内容を一行にする必要がありました。しかし`;`や`&`を使うとシェルが反応してしまいます。困ってたところRubyには`and`という演算子式があることを知って、これを使うことにしました。

```shell
echo source :rubygems ; gem :rails.to_s > Gemfile # ダメ
echo source :rubygems && gem :rails.to_s > Gemfile # ダメ
echo source :rubygems and gem :rails.to_s > Gemfile # オッケー！
```

# 完成
というわけで、WindowsでもMacでも使えるRails初期Gemfile作成コマンドです。
出力されたGemfileは、このあとに実行される`rails new .`によって上書きされ、その儚い命を終えるわけですが、、、

```shell
echo source :rubygems and gem :rails.to_s > Gemfile
```

最初のrailsコマンドを実行するためだけのGemfileをサクッと作れるコマンドということで、活用してもらえたら幸いです。m(_ _)m
brew ls で インストール先のディレクトリ 場所を探す ( which 的な )

lsで可能

```
$ brew ls <package_name>
```


[homebrew - How to find package for installed file in Brew? - Stack Overflow](https://stackoverflow.com/questions/19915683/how-to-find-package-for-installed-file-in-brew)








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
awslogs.log が圧迫してしまう場合に CloudWatch Logs エージェントのログの出力箇所を変更する

# 困った
ルートデバイスボリュームのディスク容量の検知があり、なぜか/var/log/awslogs.log が圧迫していました。

運用としてルートデバイスとは別にEBSを追加し、アプリケーションのログも含めそちらに/var/log/以下にシンボリックリンクを張っていたのですが、CloudWatch Logs エージェントのログは/var/log/以下に直接出るのでそうした対応を出来ておらず、圧迫されつつありました。
（ちなみにcodedeploy-agentとかは/var/log/aws/以下にあり、1クッション挟んでくれていたりします。）

# 原因：圧迫する一例
ログを見てみると、アプリケーションのログに改行が発生しており datetime_formatのWARNINGで埋められておりました。だめなログの量に引っ張られて、awslogs.logも圧迫してしまっていたという状況のようです。

```:awslogs.log抜粋
(略) - cwlogs.push.reader - WARNING -（中略） reason: timestamp could not be parsed from message.
```
参考：[【小ネタ】AWS Lambdaで複数行のログを送るときの挙動を調べてみた](https://dev.classmethod.jp/cloud/aws-lambda-multiline-logging/)

# 対応方針
そもそも論なので参考リンクに記載の通りログをちゃんとするのが良いのですが、圧迫は目の前に迫っているからアラートな訳でして、アプリケーションの変更を加えず一旦何とか対応をしたい場合があります。


# ログの出力箇所変更
**暫定対応**、かつ自己責任のもとログの出力箇所を変更しました。
こちらについて、現状では以下のファイルを修正する他に方法は無いようです。


```:/usr/sbin/awslogsdから抜粋
（略）
exec /usr/bin/env -i HTTPS_PROXY=$HTTPS_PROXY HTTP_PROXY=$HTTP_PROXY NO_PROXY=$NO_PROXY AWS_CONFIG_FILE=/etc/awslogs/awscli.conf HOME=/root /bin/nice -n 4 /usr/bin/aws logs push --config-file /etc/awslogs/awslogs.conf --additional-configs-dir /etc/awslogs/config >> /var/log/awslogs.log 2>&1
（略）
```

ここに直接指定されているので、書き換えます。
awslogsを再起動することで反映されます。
これで暫定対応ができました。

# logrotateの変更
と思ったら、logrotateの設定にも直接ログのパスが記載されてしまっているので、こちらも書き換える必要がありました。


```:/etc/logrotate.d/awslogsから抜粋
（略）
/var/log/awslogs.log {
（略）
```

今度こそ、無事に**暫定対応**ができました。

もちろん最初からちゃんとするのが良いのですが、運用って [そういうときもあるよね](https://twitter.com/k_r_r_l_l_/status/1036371830339067904) という気持ちが大事かなと思います。
git push --forceで履歴改ざんされたリモートブランチをローカルブランチにpullしなおす方法

なんらかの理由でgit push --forceされたmasterブランチがリモートにあり、手元のローカルにはそれが行われる前の古いmasterブランチがあるとする。ここで、手元の古いmasterブランチを捨てて、リモートの新しいmasterブランチをpullしたいとする。そんなときは、次のコマンドを実行する。

```bash
# 前提: 手元のブランチが古いmasterブランチであること
git reset --hard origin/master
```
centos7でsassc 2.0.0 with native extensionsのインストールに失敗

bundleに失敗するから、sasscだけ単独でインストールしてみた所、以下のエラーが発生。

```
$ gem install sassc -v '2.0.0' --source 'https://rubygems.org/'
Building native extensions. This could take a while...
ERROR:  Error installing sassc:
	ERROR: Failed to build gem native extension.

    current directory: /home/foo/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/sassc-2.0.0/ext
/home/foo/.rbenv/versions/2.5.3/bin/ruby -rrubygems /home/foo/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/rake-12.3.1/exe/rake RUBYARCHDIR=/home/foo/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/extensions/x86_64-linux/2.5.0-static/sassc-2.0.0 RUBYLIBDIR=/home/foo/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/extensions/x86_64-linux/2.5.0-static/sassc-2.0.0
cd libsass
make lib/libsass.so
mkdir lib
cc -Wall -O2 -I /home/foo/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/sassc-2.0.0/ext/libsass/include -fPIC -fPIC -c -o src/cencode.o src/cencode.c
src/cencode.c: 関数 ‘base64_encode_block’ 内:
src/cencode.c:50:5: 警告: 空の宣言です [デフォルトで有効]
     __attribute__ ((fallthrough));
     ^
src/cencode.c:64:5: 警告: 空の宣言です [デフォルトで有効]
     __attribute__ ((fallthrough));
     ^
g++ -Wall -O2 -std=c++0x -I /home/foo/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/sassc-2.0.0/ext/libsass/include -fPIC -fPIC -c -o src/ast.o src/ast.cpp
make: g++: コマンドが見つかりませんでした
make: *** [src/ast.o] エラー 127
rake aborted!
Command failed with status (2): [make lib/libsass.so...]

Tasks: TOP => lib/libsass.so
(See full trace by running task with --trace)

rake failed, exit code 1

Gem files will remain installed in /home/foo/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/sassc-2.0.0 for inspection.
Results logged to /home/foo/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/extensions/x86_64-linux/2.5.0-static/sassc-2.0.0/gem_make.out
```


gcc-c++が足りていないだけ。

```
$ sudo yum install gcc-c++
```

あらためてインストールし、成功

```
$ gem install sassc -v '2.0.0' --source 'https://rubygems.org/' 
Building native extensions. This could take a while...
Successfully installed sassc-2.0.0
Parsing documentation for sassc-2.0.0
Installing ri documentation for sassc-2.0.0
Done installing documentation for sassc after 4 seconds
1 gem installed
```
Xamarinで実機デバッグする時にプロビジョニング的なエラーがでる場合

久々にアプリでも作ってみるかとXamarinでちょっと遊んでみる

そして実機を繋いでXamarinでビルド

・
・
・

「そのデバイス、Provisioning Profileに入ってないかもね」的なエラーがでる

そういや、このiPhoneではやったことなかったかなと思い、Developerプログラムのサイトから手動でProvisioning Profileを作ってダウンロード

ダウンロードしたProvisioning Profileをダブルクリックした後に再度トライ

・
・
・

「そのデバイス、Provisioning Profileに入ってないかもね」的なエラーがでる

なんでだーっと悩んでいたところ、どうもダブルクリックで起動してたのはConfigurator2のアプリでした

しかも、このファイルは対象外だとかエラー出してる状態

![image.png](https://qiita-image-store.s3.amazonaws.com/0/201603/687fe842-185f-165a-caf2-995651ea4d68.png)

コンテキストメニューからXcodeを指定して読み込んだら、無事実機デバッグできるようになりました
Windowsのrouteコマンドに関するメモ（複数のネットワーク接続環境）

#動機
ある日、社内で利用しているBambooのAgentに悲劇が起きました。
そのAgentは社内ネットワークに接続されていますが、IT管理ポリシーの変更により、ADに紐付いた端末以外のインターネット接続が制限され、Webブラウザ上にてIDとPasswordをおよそ半日おきに入力することが必須になりました。
BambooのMaster Serverは社内イントラネット上に存在するため、そこへの接続は問題なかったのですが、AgentはBuildの際にコードサイニングを行うために外部のタイムスタンプサーバーを利用します。
何台もあるBamboo Agentへ必要に応じてWebブラウザを開いてIDとPasswordを入力することなど運用上不可能であるため、事実上利用が困難になりました。

#解決方法
運良く社内から利用可能なイントラを経由しない外部インターネットへの接続先が用意されていたため、社内LANと外部インターネットの両方へ接続することで解決しそうでした。
ただ、当然そのまま挿しただけだとメトリックの低いNICへトラフィックが一方的に流れるため、都合良くインターネット接続と社内LANへの通信を捌く必要がありました。

#routeコマンド
存在は知っていましたが、使ったことはなかったコマンドです。接続先に合わせて通るゲートウェイを変えてあげればうまくいくはず･･･と考えて調べ、実行した結果うまくいきました。

#やったコマンド

```
route print
route -p add 10.0.0.0 MASK 255.0.0.0 10.131.132.254 METRIC 1 IF 42
```
前提条件として、社内LANは10.~のネットワークで、外部インターネットは192.168.201.~というセグメントでした。
基本的には外部インターネットを利用して、イントラ上のマシンに接続する時に社内LAN経由で接続するようにしました。
ですので接続先は10.0.0.0/8の時、社内イントラネット側のゲートウェイを通すようにします。
IF番号はroute printでわかりました。

#おわりに
もうほんとに走り書きレベルのメモです。
何でもいいから書いていかないといつまで経っても書けないし、ショボい内容でもOutputしていくことを重視した結果ですのでご容赦ください。
python3でファイルの中身をリスト変数に代入する方法

テキストファイルの一覧をうまい感じでlist変数に入れて
Forループで処理とかできたらいいな。と思いやってみました。

単純に`readlines()`をすると改行が入るので、
`read().splitlines()`でやるといい感じでした。


以下の2つのファイルを用意します。

```list.txt 
aaaa
bbbb
cccc
dddd
eeee
```

```list.py
# -*- coding: utf-8 -*-

path_name='./list.txt'

with open(path_name, mode='r') as f:
    key_list1 = f.readlines()
with open(path_name, mode='r') as f:
    key_list2 = f.read().splitlines()


print("key_list1 : {}".format(key_list1))
print("key_list2 : {}".format(key_list2))
```

実行結果

```sh
ajitama@ajitama-ubu1810:~$ python list.py 
key_list1 : ['aaaa\n', 'bbbb\n', 'cccc\n', 'dddd\n', 'eeee\n']
key_list2 : ['aaaa', 'bbbb', 'cccc', 'dddd', 'eeee']
```
key_list2が望む結果となりました。
Python2でもPython3でも動作しました。

以前も悩んだので、メモしておきます。
React NativeのAndroid実行時にJavaScriptファイルがbundleされないエラーが沼だった。

React NativeのAndroid実行時にハマったエラーが結構しんどかったので記事にまとめることにしました。 今回のエラーはLinuxだとハマる沼なので他のOSだと分かりませんのでご了承ください。

実行環境: Ubuntu 16.04.5 LTS, Android 8.1.0
#JavaScriptファイルがbundleされなかった
React NativeはReactというJavaScriptライブラリを使ってNativeアプリ（スマホアプリ）を作ることができる便利なフレームワークです。 
今回ハマったエラーはJavaScriptファイルがbundleされていないというエラーです。 bundleされていないというのは複数のJavaScriptファイルが1つのファイルにまとめられていないという意味です。 以下が該当のエラーです。 

```:error
unable to load script from assets index.android.bundle
```

#一般的なエラーの対処法

- 開発サーバーのtcpポート番号とデバイスのtcpポート番号を揃える

```console
$ adb reverse tcp:8081 tcp:8081
$ react-native run-android
```
これは実機で開発している時の話ですが、開発サーバー（PC）とデバイス（スマホ）のtcpポート番号が違うとbundleが上手くいかないそうなので、まずこれを試してみました。 自分の場合はこれでは治らなかったので原因は別にあるようです。

- JavaScriptファイルを自分でbundleする

```console
$ midir android/app/src/main/assets/
$ react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res
$ react-native run-android
```
bundle自体が上手く行ってないと考えたので、react-native bundleというJavaScriptファイルを自分でbundleをするコマンドを以下を参考にして実行しました。
https://stackoverflow.com/questions/44446523/unable-to-load-script-from-assets-index-android-bundle-on-windows

しかし、以下のようなエラーが出ました。

```:error
Loading dependency graph...fs.js:1384
    throw error;
    ^

Error: watch /* アプリのどこかしらのファイルのパス */ 
ENOSPC
```
ENOSPCというエラーメッセージが出てますが、これが重要でした。

##ENOSPCとは
ENOSPCとはディスクに空きスペースがない時に起こるエラーです。しかし、Ubuntuではディスクに空きスペースがあってもこのエラーが起きることがあります。 それにはinotifyというLinuxのファイル監視用システムが影響しています。 inotifyが監視できるファイル数には上限があり、それを超えてしまった時同様にENOSPCを出します。

react nativeにはwatchmanという、コードの変化を発見して、自動でコンパイルしデバイスに更新を反映させるシステムがあります。 watchmanはファイルの監視にinotifyを用いており、これがENOSPCの原因になったと考えられます。

#ENOSPCへの対処法
先述した通りinotifyの監視ファイル数の上限に達したのがエラーの原因なので、上限を増やしてあげれば大丈夫です。 以下のコマンドを実行すれば上限を増やすことができます。

```console
$ echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
```

現在のinotifyの監視ファイル数の上限は以下のコマンドで確認できます。

```console
$ cat /proc/sys/fs/inotify/max_user_watches
```
同じ内容は以下のリンク先に書いてあります。
https://github.com/guard/listen/wiki/Increasing-the-amount-of-inotify-watchers

```console
$ react-native run-android
```
を実行したら上手くいきました！

#まとめ
`unable to load script from assets index.android.bundle`
というエラーが出た時はぜひ参考にしてください。
【rails5】年月の表示を変更する方法

【strftimeでyyyy年mm月、みたいに表示する方法】

strftime("%Y年%m月")
で出来る。

同じアルファベットでも大文字にするか小文字にするかで実行結果が変わる。

参考にした記事
https://code-examples-ja.hateblo.jp/entry/2014/09/06/Ruby%E3%81%A7%E6%97%A5%E6%99%82%E3%82%92YYYYMMDD%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E6%8C%87%E5%AE%9A%E3%81%AE%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88%E3%81%A7%E8%A1%A8%E7%8F%BE
Angular Materialでローディング（処理中）を実装する

2022/3/22 追記

`@angular/material": "13.2.6"` ではこの記事のコードではローディングが表示されない。
原因はこの [コミット](https://github.com/angular/components/commit/ea07fa8e640db87c6be1c12980c1295f0ffa013d) で MatSpinner クラスが消えたからっぽい。

MatSpinner クラスは消えたが mat-spinner タグは使えるので、自前で MatSpinner コンポーネントを実装して、ComponentPortal に渡すようにする必要がある。

```typescript:progress-spinner.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-progress-spinner',
  template: '<mat-spinner></mat-spinner>',
})
export class ProgressSpinnerComponent {}

```

---

Angular Materialでローディング（処理中）を実装するには、`Progress spinner`と`Overlay`を使う。

まず、Angular Materialをインストールする。

https://material.angular.io/guide/getting-started

```sh
ng add @angular/material
```

実装はこんな感じ。

```typescript:app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

// 追加
import { MatProgressSpinnerModule, MatSpinner } from '@angular/material/progress-spinner';
import { OverlayModule } from '@angular/cdk/overlay';

import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    MatProgressSpinnerModule, // 追加
    OverlayModule             // 追加
  ],
  // 追加
  entryComponents: [
    MatSpinner
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

```

```typescript:app.component.ts
import { Component, OnInit } from '@angular/core';
import { Overlay } from '@angular/cdk/overlay';
import { ComponentPortal } from '@angular/cdk/portal';
import { MatSpinner } from '@angular/material/progress-spinner';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'sample-progress-spinner';

  overlayRef = this.overlay.create({
    hasBackdrop: true,
    positionStrategy: this.overlay
      .position().global().centerHorizontally().centerVertically()
  });

  constructor(
    private overlay: Overlay
  ) { }

  ngOnInit() {
    // ローディング開始
    this.overlayRef.attach(new ComponentPortal(MatSpinner));
    setTimeout(() => {
      // ローディング終了
      this.overlayRef.detach();
    }, 3000);
  }
}

```

画面はこんな感じ。

<img width="1552" alt="スクリーンショット 2018-12-27 14.20.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/244226/41ffd951-4be5-9ee2-68a0-818ae6cea1e8.png">

Overlayを使えばHTMLは特にいじらずにローディングを実装することができる。
PHP勉強会@東京（12/26）at GMO Yours

PHP勉強会（12/26）に行ってきたので
レポートを書きます！

★メイン発表枠（20分）====================================================

■ 文系新卒者をエンジニアに育成して分かった10のコト(仮) @yujiod yu-jiさん
https://speakerdeck.com/yujiod/phpstudy-133-20181226

	分からないを３つに分解し
		１．大枠を理解しているけれど完全には説明できない（→問題ない）
		２．一部は分かるけれど全部は分からない（→分かるところまで説明させ残りを教える）
		３．本当に分からない（→図で説明）
	することが大事。

	【質問】新人にプログラムの面白さを教えるには？
	→ PHP勉強会に連れてくる？（笑）

■ 【雑談】AWS導入について
	 @koyhoge さんの話
	 AWSの資格というのがある。初級用の動画が無料で公開されているので、それからやってみれば？
 	 Azure、アリババクラウドの勢いがGCPを上回る。

■ PhpStorm と PHPUnit を連携してユニットテスト作成を楽にする @tenkoma Koji Tanakaさん
https://speakerdeck.com/tenkoma_/integrating-phpunit-with-a-phpstorm

	・PhpStormの設定の話

	【質問】テスト準備のデータをどう管理しているか？
	→ フィクスチャを使って管理。どうしても最後のときにはRunkit


★LT枠（5分）===========================================================

■ CarbonとMutableの話 @hanhan1978 Ryo Tomidokoroさん
https://speakerdeck.com/hanhan1978/carbontomutableobuziekutofalsehua

	Carbonというクラスを使うときにcopy()を使う必要があるらしい。わからん。

■ management3.0のワークショップを受講してみて @nemu1986 ねむさん
https://speakerdeck.com/masayoshifujiwara/management3-dot-0falsewakusiyotupuwoshou-jiang-sitemite

	人ではなくシステムをマネジメント？

■ 自作キーボードが楽しい！ @tomzoh 長谷川智希 さん / とむぞうさん
https://speakerdeck.com/tomzoh/lets-enjoy-a-diy-keyboard

	 LED輝くキーボード。 ハンダゴテ必須。
	部品は中国のAmazonみたいなショッピングサイトに沢山あるらしい。

■ AWS Lambda でPHPを動かしてみた(DynamoDBも使う) @Seiichi Akibaさん @akki_megane @Seiichi Akibaさん

	phpinfo()を出すまでのデモ

■ お得駆動開発??(仮) @niisantokyo @新倉 涼太さん

	自分にとってどうすればお得感があるかを意識すると新技術は導入しやすい

ありがとうございました！
Selenium Webdriverを使い、対象URLをブラウズしてキャプチャを取得する

Selenium Webdriverで簡易的なブラウザテストを行いました
1500ページ弱のキャプチャが必要だったので、だいぶ捗りました

## やりたいこと
- 対象URLをブラウズしてキャプチャを取得する

## 事前準備
同一ディレクトリに下記を配置します。

- url.txt　（テスト対象URL）
- web_test.py　（実行スクリプト）
- images/　（画像格納フォルダ）


## テスト対象URL一覧作成(url.txt)

basic認証が面倒だったので、URLに直で書きました
下記のように改行区切りで一覧を作成します

```
https://id:password@テスト対象DNS/
https://id:password@テスト対象DNS/about/
```

## スクリプトの実行

### 動作環境

```
$ pip3 list
Package    Version
---------- -------
Pillow     5.3.0  
pip        10.0.1 
selenium   3.14.1

$ python3 -V
Python 3.7.0
```

### web_test.py　実行

```
from selenium import webdriver
from PIL import Image
import time

# Webdriver
browser = webdriver.Chrome(executable_path='/Library/Frameworks/Python.framework/Versions/3.7/selenium/chromedriver')

# url一覧を読み込ませる
f = open('url.txt')
urlList = f.read()
f.close()
urls = urlList.split('\n')

count = 1

for url in urls:

  # コンソールに対象URLを表示
  targetUrl = str(count) + ":" + str(url)
  print(targetUrl)

  # 対象urlをブラウズ
  browser.get(url)
  time.sleep(3)

  # 画面キャプチャを取得
  imagefile = "images/dev_test_" + str(count) + ".png"
  browser.save_screenshot(imagefile);
  time.sleep(3)

  count　+=　1
```

キャプチャの取得には、Python Imaging Library (PIL)を使いました
images/配下にdev_test_(nunmber).pngで画像が入っていきます

# 課題
ページサイズによっては画像が見切れてしまう。フルスクリーンで画像を取得するように修正するべき
スクリプト起動後、最初にブラウザでUserAgentを切り替えればスマホビューでもテストを行うことができますが、コードでの切り替え方法を模索中
[AWS] Lambdaをローカルで開発するためにAWS SAMに入門してみた (Hello World編)

## Features
- aws samを利用してテンプレートプロジェクトが作れるので楽です
- Makefileは利用するgoライブラリだけをDLするように変更してください
- テンプレートのgo fileを変更して新しいfunctionを作成してください

## Requirement
- golang:1.11.4
- pip
- python
- docker (local lambda test)

## Installation
- aws-cli
- aws-sam-cli
- golang (1.x)

### aws-sam-cli
AWS公式サイトに則って、aws-sam-cliをDLする。<br>
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html

1. pythonとpipを入れる

	```
	$ brew install python
	$ pip install --upgrade pip
	$ pip install --user --upgrade setuptools
	```

2. aws-cliを入れてconfigureを設定をする

	```
	$ pip install awscli --upgrade --user
	$ aws configure
	```

3. aws samコマンドをセットアップする。

	```
	$ pip install --user --upgrade aws-sam-cli
	※ 既に古いバージョンを入れてる人は一旦uninsallする
	$ npm uninstall -g aws-sam-local
	```

4. pathを通す

	```
	$ USER_BASE_PATH=$(python -m site --user-base)
	$ export PATH=$PATH:$USER_BASE_PATH/bin
	```

5. コマンドが使えるかの確認

	```
	$ sam --version
	SAM CLI, version 0.10.0
	```

### golang (1.x)
1. golangインストールに使うgoenvのインストール

	```
	$ brew install goenv
	$ goenv -v
	goenv 1.23.2
	```

2. DLできるgoを確認

	```
	$ goenv install -l
	```

3. 1.xのgolangをインストール

	```
	$ goenv install 1.11.4
	```

4. 利用するgolangのバージョンを指定

	```
	$ goenv global 1.11.4
	$ go version
	go version go1.11.4 darwin/amd64
	```
	※ 切替可能なgolang versionの確認は↓

	```
	$ goenv versions
	```

## Usage
1. samを利用してテンプレートをインストール

	```
	$ sam init --runtime go1.x --name hello
	```
	※ 確認

	```
	$ cd hello
	$ tree
	.
	├── Makefile
	├── README.md
	├── hello-world
	│   ├── main.go
	│   └── main_test.go
	└── template.yaml
	```

2. Makefileを修正して、buildが通るようにする

	```
	$ vim Makefile
	~
	all: deps clean build # <- 追加

	deps:
	#       go get -u ./...	 # <- コメントアウト
    	    go get -u github.com/aws/aws-lambda-go/events # <- 追加
    	    go get -u github.com/aws/aws-lambda-go/lambda # <- 追加
	~
	```

3. buildする

	```
	$ make
	```

4. Api Gatewayのイベント作成
 Api Gatewayがリクエストを受けると、イベントを発行してaws lambdaに渡されます。
 このイベントを表しているjsonファイルを作成します。

	```
	$ sam local generate-event apigateway aws-proxy  > get_event.json
	```

5. lambdaをローカルで動かす
 sam local invoke を実行すると、lambdaが動きます。

 	```
	$ sam local invoke HelloWorldFunction --event get_event.json
	```

6. localでAPI Gatewayを動かす

	```
	$ sam local start-api

	~

	http://127.0.0.1:3000/
	```

	↓のURLにアクセスして、jsonを確認。

	```
	http://127.0.0.1:3000/hello
	```
Apacheのhttpd.confにPHPを設定する方法

[PHPモジュールの設定はhttpd.confに書かなくていい](http://beatnik.jp/blog/archives/558)というのを見て便利と思ったのでやってみた。

- 環境
    - macOS Mojave バージョン10.14.3
    - Apache 2.4.37 (Unix)
    - PHP 7.3.1 (cli)

# PHPの情報を確認する
```bash
$ which php
/usr/local/bin/php

$ php -v
PHP 7.3.1 (cli) (built: Jan 10 2019 13:15:37) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.1, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.1, Copyright (c) 1999-2018, by Zend Technologies

$ php --ini | grep php.ini
Configuration File (php.ini) Path: /usr/local/etc/php/7.3
Loaded Configuration File:         /usr/local/etc/php/7.3/php.ini
```

# PHP用の設定ファイルを作る
Includeで指定するディレクトリにPHP用の設定ファイルを作る。
今回の場合は、 `/usr/local/etc/httpd/extra` に `php71.conf` を作る.

```bash:PHP用の設定ファイルを作る
$ vi /usr/local/etc/httpd/extra/php73.conf

# httpd.confにをincludeする設定ファイル
#
# PHPの場所 : /usr/local/bin/php
# 対象バージョン : PHP 7.3.1 (cli) (built: Jan 10 2019 13:15:37) ( NTS )
#
# これ↓をhttpd.confに追記する
#Include /usr/local/etc/httpd/extra/php73.conf

#
# AddType allows you to add to or override the MIME configuration
# file specified in TypesConfig for specific file types.
#
AddType application/x-httpd-php .php

#
# Dynamic Shared Object (DSO) Support
#
# To be able to use the functionality of a module which was built as a DSO you
# have to place corresponding `LoadModule' lines at this location so the
# directives contained in it are actually available _before_ they are used.
# Statically compiled modules (those listed by `httpd -l') do not need
# to be loaded here.
#
LoadModule php7_module "/usr/local/Cellar/php/7.3.1/lib/httpd/modules/libphp7.so"

#
# DirectoryIndex: sets the file that Apache will serve if a directory
# is requested.
#
<IfModule dir_module>
    DirectoryIndex index.php
</IfModule>

#
# php.iniの場所
#
PHPIniDir "/usr/local/etc/php/7.3/php.ini"


# 保存して確認する。
$ ls -l /usr/local/etc/httpd/extra/ | grep php
-rw-r--r--  1 mana  apache   1224 12 21 00:26 php71.conf #<<< バージョン違いもあると便利
-rw-r--r--  1 mana  apache   1065  3  3 18:50 php73.conf
```

# httpd.confに作った設定ファイルを設定する
```conf:httpd.confの一番最後
# PHPの設定
# Include /usr/local/etc/httpd/extra/php71.conf
Include /usr/local/etc/httpd/extra/php73.conf
```

# 見てみる
```bash
# 起動する
$ apachectl start
```

見てみる・・・できた！便利だ。
![スクリーンショット 2019-03-03 19.26.00.png](https://qiita-image-store.s3.amazonaws.com/0/159761/2e4db3fc-71cc-1e48-e122-2a47849c049e.png)
SVG形式で驚異的なサイズダウンした話

# 過大なネットワーク ペイロードの回避

弊社で運営する「[持ち家計画](https://mochiie.com/)」というサイトがあります。
最近リビルドが終わって新しいデザインに生まれ変わりました。
そこでPageSpeed Insightsなどでサイトパフォーマンスの評価も測定するようになったのですが、
なかなかどうして辛い結果になります。

![88ca1773-1520-5d34-b6fc-e86abff99b91.png](https://qiita-image-store.s3.amazonaws.com/0/54497/d94badf9-3668-cbf8-5519-967949c44484.png)

そこで１項目ずつ要因を潰していくわけになるのですが、
まず、**モザイクデザインの画像が重い**、というのが目に付きました。

たとえはファーストビューのこの部分、

<img width="767" alt="ad36617f-eba6-8fa0-534a-df993c6bcc19.png" src="https://qiita-image-store.s3.amazonaws.com/0/54497/c6ec301f-4502-4b38-6c06-51cbf610e589.png">

中央を透明にくり抜いたフレームタイプのpng画像、minify後で**224KB**ありました。
マルチデバイス対応ということで、2480x1228もあるんで妥当なサイズではあるんですが。

![5d510321-64a3-d0e3-a8f1-0d6348ccf2e6.png](https://qiita-image-store.s3.amazonaws.com/0/54497/5f6082c6-2c81-1c0b-d2dc-ab7a4b54463c.png)
他にも、同じ様に縦横サイズがでかい、ついでにファイル容量もでかい（最大500KB超のも）というのが数ファイルあったので、このモザイク画像をなんとかしようとなりました。

# PNG形式からSVG形式に変更

諸般の事情で縦横サイズは現状のまま（2480x1228！）と決まりました。
ではパターンを簡略化するか？境界の色数節約する？解像度落とすか？とああだこうだ考えたのですが、ひたすら手間がかかります。正直、効果も疑問だし結果も見えないので気が進みません。

幸い、素材データはパスとパターンを組み合わせたaiデータで作ってありました。 
「とりあえず画像形式変えてみるか」と横着の一心で、**SVG**で書き出し直しました。

![45dd922e-e430-fa61-8a10-9c1710fb30f1.png](https://qiita-image-store.s3.amazonaws.com/0/54497/e0b67453-a43e-9f29-3247-fd667d4e132b.png)
そしたらなんと**44KB**に！
パターンとか外部ファイル化して読んでいるわけでもなく、ちゃっんと期待通りに画像でした。

[SVGOMG](https://jakearchibald.github.io/svgomg/)でminifyをかけると**25KB**まで落ちました。
![081d2745-361a-c068-19a4-0c3095915d4f.png](https://qiita-image-store.s3.amazonaws.com/0/54497/21b5358a-fc86-ba8a-0da4-d48650d8bacb.png)


この時点で**1/10**までファイル容量が下がってます。
横着がベストソリューションを生んでくれました。

# gzip圧縮で更に軽く！

持ち家計画では**gzip**を利用しているので、XMLベースのベクター画像であるSVG画像は圧縮効果が期待できます。
実際にアップしてみたところ、なんと**4.7KB**に。
１〜２割くらい軽くなるといいねなんて話てたんですが、これは期待以上でした。
![c4aa015a-75f6-9fcd-5065-f687f1972899.png](https://qiita-image-store.s3.amazonaws.com/0/54497/9deeb9ae-6dd9-5024-16df-a75c808579c0.png)

※ファイル名は前述と異なります。

# 結果：驚異的なサイズダウン

224KB（PNG）→ 44KB（SVG）→25KB（SVGminify）→**4.7KB**（gzip）

## 効果がでた理由（想像）

- 単調なカラーデザインだった
- 座標指定できるタイプのシンプルなパターンが使われてた
- PNGは縦横サイズが大きいと容量も爆上がりするから比較しやすかった

画像によって適した形式があるのは承知の通り。
ただ今までPNGで作ってた画像をSVGで作る事も考えていいかもしれません。
普及のネックだったIE問題も解決できるので、使いみちが多そうです。

## 作成上詰まったところ
実は画面サイズによってはパスの隙間が目立つことがあありました。座標をあわせてもズレたので、小数点の丸め方とかなのかな？
今回は背景に薄い黄色の全塗りレイヤー置いて、隙間があっても目立たなくすることで解決しました。


# PSI評価は？
1点くらいあがったかなあ？
引き続き地道にがんばります。