OmniAICreator/Qiita-1.07M huggingface dataset:
Boring Sequence

- [Boring Sequence](https://atcoder.jp/contests/cpsco2019-s4/tasks/cpsco2019_s4_d)

## コンテスト中の考察(AC)

- 長さNの数列中に適当にK個数を置いていい感じにしたい。
- priority queue使えば行けるんじゃね？って思う。`1,2,1,2,3,4,5`みたいな配列をランレングス圧縮みたいな感じで`2,5`みたいにしてキューに突っ込む。そんで、大きい方から順に半分に分割していく。天才か？400をあっさり思いつくとか天才か？
- でもこの方針は間違えていた。天才じゃなかった。この考察では入力例2で落ちる。`2,7`→`2,3,3`→`2,1,1,3`になるけど、本当は`2,7`→`2,2,4`→`2,2,2,1`になるのが正しい。
- うーん、どーしよーかなー。
- DFS書けば多分行けるけどTLEするしなぁ。メモ化したいけど多分状態持ちきれない。
- お腹が空いたのでご飯を食べる。やはり米はうまい。
- 何も思いつかないので、チートシートを見る。「決め打ち」って単語が目に入ったので、これで解けるのでは？と思う。これ二分探索できるんじゃね？
- 答えを固定して二分探索をしてみる。ACする。やったぜ！



## 反省

- 時間かけすぎ。二分探索が見えるまでに40分くらいかかってる。

### どうすればよかったか

- 直接求めるのが難しそうなら答えの決め打ちを考えてみる。



## 理想の考察

- 直接求めるの厳しいから答えの決め打ちを考える。答えを決め打って二分探索するやつ
- 単調性があれば二分探索できる。単調性は`xxxxoooooo`みたいになってればいい（xは条件を満たさない。oは条件を満たす）。今回は、答えに対して単調性がある。答えが小さいほど石の個数は厳しくて、答えが大きいほど石の個数はゆるい。



## [コード](https://atcoder.jp/contests/cpsco2019-s4/submissions/5374977)

```cpp
#include <bits/stdc++.h>
using namespace std;

#define int long long

int N, K;
vector<int> a, v;

bool check(int mid) {
  int cnt = 0;
  mid++;
  for (int i = 0; i < N; i++) {
    if (v[i] % mid == 0) {
      cnt++;
    }
  }

  return cnt <= K;
}

// 二分探索
int bin() {
  int ok = N + 10;
  int ng = 0; // -1だとcheck()関数で受け切れないので死ぬ
  while (ok - ng > 1) {
    int mid = (ok + ng) / 2;
    if (check(mid)) {
      ok = mid;
    } else {
      ng = mid;
    }
  }

  return ok;
}

signed main() {
  cin >> N >> K;
  a.resize(N);
  for (int i = 0; i < N; i++) {
    cin >> a[i];
  }

  // 何個連続してるかっていう配列を作る
  int old = a[0];
  int cnt = 0;
  for (int i = 0; i < N; i++) {
    if (a[i] == old) {
      cnt++;
    } else {
      old = a[i];
      cnt = 1;
    }
    v.push_back(cnt);
  }

  int ans = bin();

  cout << ans << endl;

  return 0;
}
```



## 要点

- 答えを直接求めるのが厳しそうな時は二分探索を考える。
  - 「f(制約) = 答え」を「g(答え) = 制約」みたいにするイメージ。
  - そんで、関数g()に単調性があれば二分探索できる。
  - あと、okとngはcheck()関数が受け入れられる範囲の数を入れる。本番中範囲外の値を入れてバグらせた。
- 最大値の最小化は二分探索！！
CentOS7でKVM(仮想環境)を構築① インストール編

まずCPUが仮想化に対応しているか調べます。``VMX``はIntel、``svm``はAMD系CPUの仮想化機能です。

```console:
grep -E '(vmx|svm)' /proc/cpuinfo

flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm epb ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt dtherm ida arat pln pts spec_ctrl intel_stibp flush_l1d
```

<br>KVMに必要なパッケージをインストールします。

```console:
# yum -y install qemu-kvm libvirt virt-install virt-manager bridge-utils
```
&nbsp;``qemu-kvm``：KVMは仮想CPU演算用カーネル。qeumがハードウェアエミューレータ
&nbsp;``libvirt``：仮想用の汎用APIライブラリ。ESXiやXenなども管理可能
&nbsp;``virt-install``：仮想ゲスト作成用ツール
&nbsp;``virt-manager``：Xの管理コンソール。GUIコンソール用に念のためインストール
&nbsp;``bridge-utils``：Linux仮想ブリッジ。ゆくゆくはOVSも入れてみよう


<br>KVMカーネルモジュールを確認します。

```console:
# lsmod | grep kvm
kvm_intel             183621  0
kvm                   586948  1 kvm_intel
irqbypass              13503  1 kvm
```


<br>libvirtdの起動を確認します。

```console:
# systemctl status libvirtd

● libvirtd.service - Virtualization daemon
   Loaded: loaded (/usr/lib/systemd/system/libvirtd.service; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2019-05-12 14:24:40 JST; 28min ago
     Docs: man:libvirtd(8)
           https://libvirt.org
 Main PID: 6122 (libvirtd)
    Tasks: 19 (limit: 32768)
   CGroup: /system.slice/libvirtd.service
           tq5583 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/u...
           tq5584 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/u...
           mq6122 /usr/sbin/libvirtd

May 12 14:24:40 centos.lxdomain systemd[1]: Starting Virtualization daemon...
May 12 14:24:40 centos.lxdomain systemd[1]: Started Virtualization daemon.
May 12 14:24:40 centos.lxdomain dnsmasq[5583]: read /etc/hosts - 2 addresses
May 12 14:24:40 centos.lxdomain dnsmasq[5583]: read /var/lib/libvirt/dnsmasq/default.addnhosts - 0 addresses
May 12 14:24:40 centos.lxdomain dnsmasq-dhcp[5583]: read /var/lib/libvirt/dnsmasq/default.hostsfile
```
【読書備忘】現場で役立つシステム設計の原則② 第2章：場合分けのロジックを整理する

## 連載目次

[第1章：小さくまとめてわかりやすくする](https://qiita.com/marie_khr/items/5b9058da25e3b5959a4b)
[第2章：場合分けのロジックを整理する](https://qiita.com/marie_khr/items/91811a152ca48477d69a) →本記事
第3章：業務ロジックをわかりやすく整理する（公開予定）

## はじめに

この記事は、増田亨さんの著書「**現場で役立つシステム設計の原則**」の、主に私自身へ向けた読書備忘録です。（追ってサンプルコードも追加予定）

とても素晴らしい本だと思うので、興味を持たれた方はぜひ読んでみてください。
リンクは記事の最後にあります。

## 本章の概要
第2章：場合分けのロジックを整理する

区分や種別ごとの場合分けのロジック（if文による条件分岐など）は、
プログラムを複雑にするやっかいな存在。

第1章の「小さくまとめてわかりやすくする」考え方を場合分けのロジックにも応用し、
整理していきます。

## 覚えておきたいキーワード
今後、理解を深めたい（または覚えておきたい）と感じたキーワードのメモです。

### 早期リターン
複数の条件判定がある場合に、判定結果が確定した時点で、ただちに return する書き方。
よく見かけるのは、判定結果を変数に格納して最後に return するケースです。

```java:悪い例
String result;
if(条件1){
    result = 結果;			
} else if(条件2){
    result = 結果;			
} else {
    result = 結果;			
}
return result;
```
このような書き方の場合、判定順の入れ替えが発生した時に修正が大変、などの副作用があります。
そこで下記のようにただちに結果を返すことで、コードがすっきり分かりやすくなります。これを「**早期リターン**」と呼びます。

```java:良い例：早期リターン
if(条件1){
    return 結果;			
} else if(条件2){
    return 結果;			
} else {
    return 結果;			
}
```
さらに else 句をなくし、以下のように記述することもできます。このような書き方は「**ガード節**」と呼ばれます。

```java:良い例：ガード節
if(条件1) return 結果;
if(条件2) return 結果;
return 結果;	
```
こうすると、それぞれのロジックが疎結合な状態となり、判定順の入れ替えや追加にも容易に対応できるようになります。

### 区分オブジェクト
それぞれの区分を異なるクラスとして切り出し、区分特有のロジックを各クラスに閉じ込めるやり方。
それぞれ同一インターフェースの実装クラスとしておき、使う側に、区分の追加や変更による影響を与えないようにします。

## 本章の個人的共感ポイント
本章のなかで特に共感したポイントのメモです。
開発現場で取り組んでみたい度合いを「★」の数で表現してみました。

### 判断や処理のロジックをメソッドに独立させる
>if 文の中にごちゃごちゃと書かれた計算式を変更するよりも、メソッドに抽出した式を変更するほうがかんたんで安全です。変更すべき箇所とその影響範囲を特定のメソッドに閉じ込めることができます。（p50）

取り組みたい度：★★★★★
メソッドに切り出す時の単位やタイミングはいつも悩むところです。
今までは「複数の箇所から呼ばれたり、何度も繰り返し実行される処理であること」を基準にメソッド化することが多かったのですが、この本を読んで考え方が変わりました。意味のあるかたまりをメソッドとして抽出することで、処理の意図をコメントではなくメソッド名で説明できるようになりますし、テストもしやすくなります。

### 複文は単文に分ける
>文の中に文を書く「複文」は、日本語の文章であれ、プログラミング言語の記述であれ、意図をわかりにくくします。そこで、複文を分解して、単文を並べるシンプルな構造に変えます。（p52）

取り組みたい度：★★★★★
文章の構造を説明する言葉として「単文」「重文」「複文」などがあります。
参考：[単文・重文・複文とは
](https://prowriters.jp/grammar/text_structure)

複文とは、ひとつの文章のなかに複数の単文が含まれているものを指しますが、日本語の文章でもプログラムでも、わかりにくい状態になりがちです。条件分岐が複雑で、if 文が何重も入れ子になってしまっているプログラムを何度も見たこともあります。
適切な単位で切り出して全体の見通しを良くし、意図をつたえやすい状態にするというのは、日本語の文章でもプログラムでも、全く同じことが言えるのではないでしょうか。

私自身は、日本語の文章を書くときには「相手に意図が伝わるかどうか」をとても気にするので、プログラムも同じくらい意識しなくては、と反省しています。。

### 区分ごとの業務ロジックを区分オブジェクトで分析し整理する
>入り組みがちな区分ごとの業務ロジックを、区分ごとに別のクラスに独立させた区分オブジェクトは、オブジェクト指向らしいコードの整理のやり方です。(中略)クラスに分けることで、特定の場合のルールや計算方法を変更しても、影響範囲をそのクラスに閉じ込めることができます。（p62）

取り組みたい度：★★★☆☆
区分の追加や変更は、業務アプリケーションの世界ではよくある事です。
区分オブジェクトなら、呼び出し元や他の区分のロジックに影響を与えることなく、安全かつ楽に対応できるので、影響範囲の調査やテストも楽になりそうです。
ドメイン駆動設計ならではの考え方と思いますが、もう少し理解を深めてから取り入れたいと感じたため、★3つとしました。

## 次回予定

第3章：業務ロジックをわかりやすく整理する
5/13週中に投稿します。

## 参考文献

[現場で役立つシステム設計の原則 ~変更を楽で安全にするオブジェクト指向の実践技法](https://www.amazon.co.jp/dp/477419087X)
第2章：場合分けのロジックを整理する（p47〜p66）
Leetcode #13: Roman to Integer

```swift
private let dict = ["I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000,
                    "IV": 4, "IX": 9, "XL": 40, "XC": 90, "CD": 400, "CM": 900]
                    
func romanToInt(_ s: String) -> Int {
    var sum = 0
    var index = 0
    var s = Array(s)
    while index < s.count-1 {
        if let value = dict[String(s[index...index+1])] {
            sum += value
            index += 2
        } else {
            sum += dict[String(s[index])]!
            index += 1
        }
    }
    if index == s.count-1 {
        sum += dict[String(s[index])]!
    }
    return sum
}
```
Installing GDC on macOS via Homebrew


## 210515

They added official gdc support to macOS on gcc11. Now official gcc package installs gdc.

## original

From GCC 9, GDC (D frontend) is available on GCC. However, it is not stable on macOS and a little tweak is required.

- gcc/config.gcc, gcc/config/darwin-d.c, gcc/config/t-darwin
    - We need to tell gcc that D configuration is ready.

- gcc/d/modules.cc
    - Section name needs to be segment,section format.
    - As libphobos/libdruntime/gcc/sections/osx.d mentions it, we selected `__DATA,__minfodata`.

- libphobos/configure
    - We disabled shared library.
    - Otherwise core/thread.d fails to compile.
    - By the way I have not heard of mach-dylib built with D.

- libphobos/libdruntime/config/x86/switchcontext.S
    - We stripped section manipulation according to https://stackoverflow.com/questions/20907946/error-unknown-directive-type-func-function .

- libphobos/libdruntime/gcc/drtstuff.c
    - start_minfo / stop_minfo needs to be compiled also on mach.
    - As these two needs to be executable, we selected `__TEXT,minfo`.

- libphobos/libdruntime/gcc/sections/osx.d
    - We disabled libgphobos.dylib / libgdruntime.dylib warning.
        - Please note that libgphobos.a / libgdruntime.a are not affected but the compile option would be complex because -static would not work on macOS. 
    - Also we add temporal `d_dso_registry`.

----

- This is combined as https://github.com/cielavenir/homebrew-ciel/blob/master/patch/gcc9.patch and testing formula is in https://github.com/cielavenir/homebrew-ciel/blob/master/patch/gcc.rb .
- PR is at https://github.com/Homebrew/homebrew-core/pull/39712 .

- Bottles are in https://dl.bintray.com/cielavenir/homebrew/ . For ease, I have upload the same file for high_sierra and mojave as well as sierra.
Vue.jsとaxiosでAPIからデータを取得して表示する

# この記事でやること
静的なHTMLから検索条件を指定してAPIに接続してデータを取得、表示します。記事では手っ取り早くローカルPCに保存したHTMLからAPIに接続します。

## 接続するAPI
ユーザIDを指定して問い合わせると、ユーザ名とタイムスタンプをJSONで返してくるAPIをAWS上に用意しました。
以前書いたこっちの記事
[Raspberry PiとPaSoRiでFelicaのNFCタグを読んでみる](https://qiita.com/kikuyan8540/items/7f7d13e6ccb8324b6f87)
の続きで、タッチ情報をIFTTTの代わりにAWS DynamoDBに蓄積するように変更。ユーザ情報を引いて名前と直近のタッチ時間をRambdaとAPI Gateway経由で取得できるようにしています。
こちらについては改めて記事にする予定です。

## HTMLのソース
```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>NFC demo</title>
  </head>
  <body>
    <div id="app">
        <input v-model="userid" placeholder="User ID">
        <button v-on:click="query">Query</button><br>
        <dl v-if="info">
          <dt>ID</dt><dd>{{info.id}}</dd>
          <dt>Name</dt><dd>{{info.name}}</dd>
          <dt>Date</dt><dd>{{info.timestamp|dateformat}}</dd>
        </dl>
        <div v-else="info">No touch data.</div>
    </div>
    <script src="https://unpkg.com/vue/dist/vue.min.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="app.js"></script>
  </body>
</html>
```

## JavaScriptのソース
```javascript:app.js
const apiUrl = "https://********.********.amazonaws.com/default/nfcDemoGetTouchTime"
const apiKey = "{APIキー}"
const config = {headers: {
    'Content-Type': 'application/json',
    'x-api-key': apiKey
}}

Vue.filter('dateformat', function(value){
    if (!value) return ''
    var zp = function(num){
        return (num < 10) ? '0'+ num: num
    }
    var dt = new Date(value * 1000)
    var dtstr = dt.getFullYear() + '-' + zp(dt.getMonth() + 1) + '-' + zp(dt.getDate()) + ' '
                + zp(dt.getHours()) + ':' + zp(dt.getMinutes())
    return dtstr
})

var app = new Vue({
    el: "#app",
    data:{
        info: null,
        userid: null
    },
    methods:{
        query: function(event){
            var querydata = {'id': this.userid}
            axios
            .post(apiUrl, querydata, config)
            .then(response => {
                this.info = response.data
                console.log(this.info)
            })
            .catch(error => console.log(error))
        }
    }
})
```

## 動かしてみる
index.htmlとapp.jsを適当なフォルダに保存して、ブラウザからindex.htmlを開きます。
![初期画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404407/d1b8f2fe-6126-7928-1546-a5831c7b910f.png)

ユーザIDをフォームに入力してQueryボタンを押すと...
APIからJSONで問い合わせ結果が返ってきます。

```json:
{"id": "test1", "name": "\u30c6\u30b9\u30c8\u30e6\u30fc\u30b6\u30fc\uff11", "timestamp": 1557545262.413307}
```

![実行画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404407/1ef76439-9587-45b5-f62d-40ecbb01268c.png)
問い合わせ結果が画面に反映されました。

## 参考にしたドキュメント
Vue.jsは日本語版の公式ドキュメントが充実しているのでいろいろ助かります。
[axios を利用した API の使用](https://jp.vuejs.org/v2/cookbook/using-axios-to-consume-apis.html)
[フィルター — Vue.js](https://jp.vuejs.org/v2/guide/filters.html)

## 残課題
APIキーがソースから丸見えなので、外部にホスティングするときは、Cognitoで認証するとかアクセス制御の仕組みが必要になります。
rndcコマンドで bind(named) をコントロールする

# rndcコマンドの用法
[参考](https://docs.oracle.com/cd/E19253-01/819-0382/dnsref-8/index.html)

## usage
```bash:
rndc [-b address] [-c config] [-s server] [-p port] [-k key-file ] [-y key] [-V] command
```

| コマンド | 用法 |
| :--- | :-- |
| reload | named.confとゾーン情報をリロードする。 ※１ |
| reload ゾーン名 | ゾーンを指定しゾーン情報をリロードする。 ※１ |
| reconfig | named.confと、新しく追加したゾーンのみリロードする。|
| stats | サーバの統計情報をファイルに書き出す。<br>/var/named/data/named_stats.txt |
| status | サーバのステータス情報を表示（標準出力）する。|
| dumpdb<br> -all<br> -cache<br> -zones | キャッシュデータをファイルにダンプする。<br>cacheとzone<br>キャッシュ<br>ゾーン<br>/var/named/data/cache_dump.db |
| flush | サーバのキャッシュをすべて消去する。|
| | ＊＊＊ゾーン転送関連＊＊＊ |
| notify ゾーン名 | @master: ゾーン更新の通知。serialが増加していること |
| retransfer ゾーン名 | @slave: ゾーンの強制転送。serialチェックを無視 |
| refresh ゾーン名 | @slave: ゾーンの強制受信。即時メンテナンス |

※１：シリアル番号が増えているゾーン情報のみリロードする
Error trying to exec 'cc1plus': execvp: No such file or directory


#経緯

```
$ pip install matplotlib
```

これを実行すると、
Error trying to exec 'cc1plus': execvp: No such file or directory
と言われハマった。
検索すると

```
$ apt-get install g++
```

をすれば直るらしいけど直らなかった。よくよく調べると、gccとg++のバージョンを合わせないといけないとの事らしい。

#解決法
```
$ gcc --version
gcc (Raspbian 4.8.5-4) 4.8.5
```


```
$ dpkg -l | grep g++
g++  ・・・
g++-4.6 ・・・
```

うん。違うね...

はい、て事でgccにバージョン合わせます。下のサイト見て自分にあったバージョンを入れます。
[g++をUbuntuへインストールする](http://kaworu.jpn.org/cpp/g++をUbuntuへインストールする)


```
$ sudo apt-get install g++-4.8
```

再起動して、再度pip使ってmatplotlibインストールすると、ちゃんと入りました。
fontforgeのグリッド合わせ

-http://fontforge.github.io/en-US/
fontforgeはwindowsだと頻繁にエラーが発生する。グリフ一つ毎に保存必須。

-位置の更新
1. アスタリスクがttfによってずれていたり、アローがずれている場合、fontforgeを使ってttfを修正する事が出来る。但し、この場合、オリジナルが別のアプリで生成されている等で、固有のスクリプトが存在している可能性がある。
2. オリジナルの命令を削除する。グリフを選び、ctrl+Aで全てのポイントを選び、ヒント＞ヒント命令を削除。自動位置合わせ等のスクリプトを削除する。
3. グリッドを合わせる。ctrl+Aで全てのポイントを選び、表示＞グリッド合わせ＞show grid fitでグリッドを読み込む。そして、なぜか、もう一度、表示＞グリッド合わせ＞show grid fitを選び位置をアップデートする。windows固有?

-整数の丸め込み。
1. ttfに出力する場合にエラーが発生する。***coordinate intagerのエラーは全て編集時に小数点が内在している事に起因する。ctrl+Aで全てのポイントを選び、エレメント＞座標を丸める＞整数に。これでエラーは消える。
Desktop : Opencv webcam preview

<H5>Goal</H5>
Show Camera Preview 

```OpenCV_webcam3.java
import javax.swing.JFrame;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.videoio.VideoCapture;

public class OpenCV_webcam3 {

	static {
		System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
	}
	
	public static void main(String[] args) {
	
		VideoCapture camera = null;
		camera =  initWebcam();
		JFrame frame1 = new JFrame("Show image");
		frame1.setTitle("從 webcam 讀取影像到 Java swing 視窗");
		frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame1.setSize(640, 480);
		frame1.setBounds(0,0,frame1.getWidth(),frame1.getHeight());
		Panel panel1 = new Panel();
		frame1.setContentPane(panel1);
		frame1.setVisible(true);
		
		if(camera.isOpened()) {
			Mat webcam_frame = new Mat();
			camera.read(webcam_frame);
			frame1.setSize(webcam_frame.width(),webcam_frame.height());
			
			while (true) {
				camera.read(webcam_frame);
				panel1.setimagewithMat(webcam_frame);
				frame1.repaint();
			}
			
		}else {
			System.out.print("Error");
		}
		
	}
	
	
	private static VideoCapture initWebcam() {
		VideoCapture cameraCapture = new VideoCapture();
		cameraCapture.open(0);
		
		return cameraCapture;
	}
}
```
<H5>Result</H5>
![camera_preview.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276243/55e97568-4a77-6eb9-8d9d-ae384784d816.jpeg)
template method pattern

# template method pattern
## ケース

アルゴリズムの部分部分を置き換え可能にしたいとき。

## 結果
### pro

デフォルト挙動から部分のみを容易に変更できる。

### con
実装をオーバーライドしないといけない。(継承する必要が高い)

## 実装対象

AbstractClass テンプレートメソッドとオーバーライドされうるメソッドの実装
ConcreteClass 必要なオーバーライド実装

## おまけ
hook operationを定義してサブクラスに拡張を許すことも可能
AbstractClassは何もしない名前だけのオペレーションを定義し、
テンプレートメソッドはそれを呼び出す。
こうすることで、AbstractClassはConcreteClassに任意の処理を挟み込むことを許す。

## example
```
class AbstractOrder {
    // template method
    func order(input: Input) {
        validate()
        pay()
        payHookOperation() // hook operation
        updateStock()
        notify()
    }

    func validate() { // do something }
    func pay() { // do something }
    func payHookOperation() {} // do nothing!!
    func updateStock() { // do something }
    func notify() { // do something }
}

class DegitalOrder: AbstractOrder {
    // 必要なもののみオーバーライド
    func updateStock() { // 在庫管理してない、デジタル商品を扱う }
}

AbstractOrder().order()
DegitalOrder().order()
```
postしたデータをsessionに保存して利用する with FuelPHP

ただのメモ

formで入力した値をsessionに保存して利用したい時
HTTPのPostからFuelPHPのPostで受け取ると値が消える(そもそも記録されてない説)

#####ダメな例

```html:dataPost
<form action="hoge" method="post">
    <input type="text" name="data">
    <button type="submit">submit</button>
</form>
```
　　　　　　　　　　　　　　　　　　　↓

```php:hoge
data = Input::post('data');　
Session::set('data', $data);
```

こうするとhogeの一行目で値が消える
値を保存したい時は、HTTPメソッドかFuelPHPのメソッドかどちらか一方だけを使うと消えない

#####良い例

```php:postForm
<?php
use Fuel\Core\Form;
echo Form::open("hoge");
echo Form::input('data','');
echo Form::button('','send');
echo Form::close();
```
　　　　　　　　　　　　　　　　　　　↓

```php:hoge
<?php
use Fuel\Core\Session;
$data = Input::post('data');
Session::set('data',$data);
echo Session::get('data');
```
~~そもそもメソッドが別物だから当たり前~~
#zsh + #Mac でコンソールに現在入力中の行をクリップボードにコピーする例

# つ、ついにできたぞ！

結果としては、ものすごく簡単だった。

# ~/.zshrc

```

function peco-history-current-pbcopy() {
  print "$BUFFER" | tr -d "\r\n" | pbcopy
}

zle -N peco-history-current-pbcopy
bindkey '^P^O' peco-history-current-pbcopy


```

# 実行

- コマンド入力中に Control + P O を押す


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/1789








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
アクセスログ解析備忘録

今日はWebサーバにおけるアクセス解析のお話です。
Webサーバ運用時に切っても切り離せないのが、
アクセスログの解析ですが、障害時にはさくさく調査して原因を解明しないといけないので、
ある程度テンプレを用意しているのですが、今回はそれの一部を公開したいと思います。

## アクセス数集計

* 分単位での集計

```
ionice -c2 -n7 nice -n19 egrep 'TIME' log | egrep -v "除外したいIP" | awk '{print $4}'| cut -c 2-18 | sort  | uniq -c
```


* 10分単位での集計

```
ionice -c2 -n7 nice -n19 egrep 'TIME' log | egrep -v "除外したいIP" | awk '{print $4}'| cut -c 2-17 | sort  | uniq -c
```

* Apache %D(リクエスト処理時間ms)

```
ionice -c2 -n7 nice -n19 egrep 'TIME' log | egrep -v "除外したいIP" | awk '{print $NF,$0}'| sort -nr
```

* Apache %D 時間別統計

```
ionice -c2 -n7 nice -n19 egrep "TIME" log | egrep -v '除外したいIP' | awk '$NF >= 2000000{ print $4}' | cut -c2-18 | sort -n | uniq -c
```

* アクセス元IPを集計

```
ionice -c2 -n7 nice -n19 grep '時刻' log | egrep -v "除外したいIP" | awk '{print $1}' | sort -n | uniq -c | sort -nr
ionice -c2 -n7 nice -n19 grep '時刻' log | egrep -v "除外したいIP" | awk '{print $1}' | cut -d: -f2 | sort -n | uniq -c | sort -nr
```

* アクセス先のドメインを集計

```
ionice -c2 -n7 nice -n19 grep "時刻" log | egrep -v "除外したいIP" | awk '{print $1}' | cut -d: -f1 | sort -n | uniq -c | sort -nr
```

* アクセス先URIを集計

```
ionice -c2 -n7 nice -n19 grep '時刻' log | egrep -v "除外したいIP" | awk '{print $7}' | sort -n | uniq -c
```

* リファラーを集計

```
ionice -c2 -n7 nice -n19 grep '時刻' log | egrep -v "除外したいIP" | cut -d\" -f4 | sort | uniq -c
```

* User-Agentを集計

```
ionice -c2 -n7 nice -n19 egrep '時刻' log | egrep -v "除外したいIP"  |awk -F\" '{print $6}' | sort | uniq -c | sort -nr
```

* UAを集計

```
ionice -c2 -n7 nice -n19 grep '時刻' log | egrep -v "除外したいIP" | cut -d\" -f6 | sort | uniq -c
```

### おまけ

基本的には上記のワンライナーを使えば集計できるのですが、サービスや設定によっては使えない場合があります。
なので、そういった場合は随時コードを調整する必要があります。 そういった時に使えるのが下記のコマンドです。

    cut 指定した文字で切り取る
        -d '区切り文字'　 区切り文字の指定
        -f 数値　　　　 フィールド(場所)の指定

    awk 空白単位でログを分割
        '{print $数値}' 何番目の空白か

    sort 並べ替え
        -n 整数順に並べる
        -r 順序を反転する

    uniq 集計したログをまとめる
        -c 同じものをまとめてカウントする
strategy pattern

# strategy pattern


## ケース

あるクラス(Context)の振る舞いのみを変えたいとき イコール 振る舞いだけが違う似たクラスがたくさんあるとき
あるクラスの内部アルゴリズムを交換可能にしたいとき
実行条件によって振る舞いが多岐にわたるとき=処理を固定して注入する
クライアントが振る舞いの種類を知っているとき

逆にそうじゃないケースは単なるコンポジションと移譲のケース。

## 結果
### pro

継承無しで振る舞いのみを変えられる。

### con

クライアントが、振る舞いを決定する必要がある。当然決定するために、知っている必要もある。
状況によってはContextとStrategyの結合度が高まる。

## 実装対象

振る舞いを変えたいクラス(Context)。これがStrategyオブジェクトを保持する。
Strategyクラスのインタ＝フェイス
具体的なStrategyインターフェイスの実装

## 難しさ
結果のcons で述べたが、ContextとStrategy間のインターフェイスに注意しなければならない。

ContextオブジェクトはStrategyにパラメータを渡すケースがある。(多くの場合そう)
方針は2つ
1. Strategy インターフェイスがContextオブジェクト自体を受け取る。
2. Strategy インターフェイスが各Strategyの最大公約数な引数を受け取る。

1のメリット
新しい種類のStrategyの追加が容易になる。(デメリットでもあるが)

1のデメリット
結合度が高くなる。

2のメリット
結合度が低く保てる。

2のデメリット
あるStrategyは必要のないデータを受け取ることになる。 イコール あるConcreteStrategyクラスだけを見たとき依存が不透明になる。


## example
```
// Strategy
protocol PaymentStrategy {
    func pay(input: PaymentInput) -> Bool
}

// 最大公約数なinput
protocol PaymentInput {
    var address: String
    var name: String
    // etc
}

// Context
class  Order {
    let paymentStrategy: PaymentStrategy

    init(paymentStrategy: PaymentStrategy) {
        self.paymentStrategy = paymentStrategy
    }

    func doOrder(input: OrderInput) {
        // exec validation
        // some process

        let isSuccess = pay(input: input) // OrderInputは PaymentInputも満たすとする。

        // some process
    }
}

let paymentStrategy = CreditCardPaymentStrategy() // PaymentStrategyインターフェイスを満たすもの
let order = Order(paymentStrategy: paymentStrategy) // PaymentStrategyインターフェイスを満たすもの
order.doOrder(input: OrderInput)
```
Leetcode #14: Longest Common Prefix

```swift
func longestCommonPrefix(_ strs: [String]) -> String {
    if strs.isEmpty {
        return ""
    }
    if strs.count == 1 {
        return strs[0]
    }
    var prefix = ""
    for (idnex, char) in strs[0].enumerated() {
        for i in 1..<strs.count {
            guard index < strs[i].count else {
                return prefix
            }
            let sIndex = strs[i].index(strs[i].startIndex, offsetBy: index)
            if strs[i][sIndex] != char {
                return prefix
            }
        }
        prefix += String(char)
    }
    return prefix
}
```
Desktop : OpenCV take a clear picture

<H5>Goal</H5>
Last time OpenCV taking a dark picture, this time modify some code and get a clear picture.

```OpenCV_webcam2.java

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.videoio.VideoCapture;

public class OpenCV_webcam2 {

	static {
		System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
	}
	
	public static void main(String[] args) {
		VideoCapture camera = new VideoCapture();
		camera.open(0);
		
		if(!camera.isOpened()) {
			System.out.println("Error");
		}else {
			Mat frame = new Mat();
			try {
				System.out.println("使用 webcam 拍照明亮版");
				camera.read(frame);
				Thread.sleep(500);
				camera.read(frame);
				Thread.sleep(500);
				camera.read(frame);
				Thread.sleep(500);
				
				Imgcodecs.imwrite("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\frame_clear.jpg",frame);
				System.out.println("拍照完成");
				
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
		camera.release();
	}
}

```
<H5>Result</H5>
![frame_clear.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276243/256f14df-351c-8966-49db-996e5e43e67a.jpeg)
MySQLスロークエリについて

今日はWebサーバにおけるDBのお話です。
WebサーバでLoadアベレージが上がる要因の一つにDBがあげられます。
これはWebアプリケーションサーバがDBに対してクエリを投げたときに、 DB側でのクエリ処理能力を上回り遅延するのが要因の一つになりうるのです。
遅延したクエリ、つまりはスロークエリを分析することにより、負荷上昇を防ぐためのチューニングや、
DBのスペックアップを検討するのに役立つのです。

### DBでのクエリの確認手法

```
    MySQL
        show processlist;
        show full processlist\G
```

```
    PostgreSQL
        SELECT * FROM pg_stat_activity;
```


上記のコマンドをDB上(MySQL or PostgreSQL)で実行すると、
実行されているクエリが表示されるので、実行時間を確認してみれば
クエリの滞留があるかどうか判別できる。

他にもスロークエリログを出力させるさせる手法もある。

```
set global slow_query_log=1; // 0でOFF, 1でON

set global long_query_time=1; // スロークエリログとして出力する実行時間のしきい値(秒単位)

set global slow_query_log_file ='/usr/local/var/mysql/slow_query.log'; // スロークエリログの出力先
```

### スロークエリ集計コマンド

```
ionice -c2 -n7 nice -n19 tail -n1000000 /usr/local/var/mysql/slow_query.log | awk '/^# Time/{ d=$3; t=$4; } (/^# Query/ && d){ c=$2; q=$3; print d,t,c,q; }' | cut -d : -f 1,2 | sort -n | uniq -c | less
```

```
ionice -c2 -n7 nice -n19 tail -n1000000 /usr/local/var/mysql/slow_query.log | grep timestamp | cut -d= -f2 | awk '{print strftime("%Y-%m-%d %H:%M",$1)}' | sort | uniq -c | less
```
[失敗]DB120

AR9342+QCA8337というターゲットはAtherosのコードでDB120とよばれるようです。これをちょっといじってみて問題がいくつかあったので書き留めておきます。

まずu-bootですがu-boot_modでAR9342を使ったターゲットはTP-Link TL-WR1041N v2だけで、これも同じ構成のようなので、ビルドしてFlashに焼いてみましたが、二つ問題があります。

一つはシリアルのデフォルトの115200ボーで入力ができないということです。おそらく分周したクロックが微妙にずれていて、出力はFTDIのチップが良きにはからってくれるので見れますが、入力はAR9342が認識できないのではないかと思われます。FreeBSDのカーネルも同じ状態でした。9600では問題なく入力ができました。ひょっとすると個体差があるのかもしれませんが、ボーレートの設定にワークアラウンドを入れる必要があるのかもしれません。

PLLの設定がビルド設定とコードでの認識と、Flashから読み込む仕組みがあるようですが、これが正しく動いていないようにも見受けられます。これが影響している可能性もあるかもしれません。

このチップのシリアルは2.5Vのようですが、3.3Vトレラントだと思います。確認のため自作FT231モジュールに2.5V対応入れてみました。

二つ目はネットワークが使えません。AR9342にもSwitchが入っていますし、ちょっと設定が複雑なので、うまくできてないのかもしれません。u-boot_modのPHY(SWITCH)のコードはs17とs27というコードがあり、QCA8337はs17のようです。

仕方がないのでbootとZRouterでビルドしたFreeBSDのu-bootイメージをflashromでFlashに焼いてみて起動してみました。hintsをmips/conf/DB120.hintsを参考に修正したところswitchが二つ認識できましたが、AR8226として認識されてしまいます。arswitch.cの

```
id = arswitch_readreg(dev, AR8X16_REG_MASK_CTRL);
```

が0x0201になってしますようです。QCA8337のデーターシートはないのでわからないのですが、正しくはAR8327以降の数値になっていると思われます。

QCA8337はAR8337と同じものと思われます。

ブートログはこんな感じです。

http://dmesgd.nycbug.org/index.cgi?do=view&id=4943

Switchが正しく設定できてないので、もちろんネットワークは使えません。

Flashを低温半田ではがしたときに、パターンを痛めてしまったのですが、かろうじてオンボードでFlashを焼く方法が発見できたので、また気が向いたら試してみようと思います。

https://qiita.com/yamori813/items/d89ef516d41e73406add
【Ruby基礎】アルファベットの名前からイニシャルを作る【メソッド：split,map,join,upcase】


codewarsの問題を解いていて、できなかったので、自分で整理。
問題はこちら→[(8kyu)Abbreviate a Two Word Name](https://www.codewars.com/kata/abbreviate-a-two-word-name/train/ruby)

>Write a function to convert a name into initials. This kata strictly takes two words with one space in between them.
The output should be two capital letters with a dot seperating them.
It should look like this:
Sam Harris => S.H
Patrick Feeney => P.F


##まずは解答例

解答例は、以下のとおりです。

```
def abbrev_name(name)
  name.split.map { |s| s[0]}.join('.').upcase
end
```

では、順をおって解説していきます。


##必要なメソッドは４つ

このために必要なメソッドは以下の４つです。

**１　splitメソッド([【Ruby入門】splitで文字列を分割しよう！](https://www.sejuku.net/blog/41681))**

splitメソッドは引数を区切り文字として文字列を分割して配列として返すメソッド。
引数を指定しない場合は、空白文字で区切られる。
空白文字として扱われるのは、” “(半角スペース)、”\n”(改行コード)、”\t”(タブ)など。

```
（例）
区切り文字指定しない場合
str = "I like eating"
 
array = str.split
 
p array
→["I", "like", "eating"]


区切り文字指定する場合
str = "I,like,eating"
 
array = str.split(",")
 
p array
→["I", "like", "eating"]

区切り文字は任意の文字で分割することもできる
str = "123456"
 
array = str.split("34")
 
p array
→["12", "56"]

```

上記は一部の例で、ほかにもいろいろな使用法があるので、気になる方は引用サイトをご覧ください。





**２　mapメソッド([Ruby mapメソッドについて](https://qiita.com/ecoyamas/items/07c9174d307e1ea66361))**

配列の要素の数だけ繰り返し処理を行うメソッド。

```
書き方は
配列の入った変数.map {|変数名| 処理内容 }
です。

（例）
a1 = [100, 200, 300]
a2 = a1.map { |x| x * 3 }
p a2 # [300, 600, 900]

各要素にメソッドを適用するときは、以下のように省略して書くことができる
オブジェクト.map(&:メソッド名)

a = ["HOGE", "FUGA"]
p a.map(&:downcase) # ["hoge", "fuga"]

```

mapは処理後に戻り値で配列を作成してくれ,元の配列が上書きされることはありません。



**３　joinメソッド([Rubyリファレンス:join (Array)](https://ref.xaio.jp/ruby/classes/array/join))**


`array.join(sep = $,)`
joinメソッドは、配列の各要素を文字列に変換し、引数sepを区切り文字として結合した文字列を返します。

```
arr = ["hello", "world", 123]
puts arr.join(", ")
→hello, world, 123

puts arr.join
→helloworld123
```




**４　upcaseメソッド[Ruby 2.6.0 リファレンスマニュアル > ライブラリ一覧 > 組み込みライブラリ > Stringクラス > upcase](https://docs.ruby-lang.org/ja/latest/method/String/i/upcase.html)**

全ての小文字を対応する大文字に置き換えた文字列を返します。 
※大文字を小文字にしたいときは、downcaseメソッドを使用すればいいです。



```
（例）
p "stRIng? STring.".upcase   # => "STRING? STRING."
```


##コードを書く考え方

```
今回は、最初に与えられるnameが文字列なので、まずはsplitメソッドで分割して、配列にします。

name = "taro tanaka"

この段階でこうなる
name.split
→["taro","tanaka"]

次にmapメソッドで配列の一番最初の文字だけ引き出す
name.split.map{|s| s[0]}
→["t","t"]


joinメソッドで配列の各要素を'.'で区切り、文字列に変換
name.split.map{|s| s[0]}.join('.')
→t.t


最後に、大文字にするためupcaseメソッドを追加
name.split.map{|s| s[0]}.join('.').upcase
→T.T

```

またほかにも多くの[回答例](https://www.codewars.com/kata/abbreviate-a-two-word-name/solutions/ruby)があり、参考になります。



###今日学んだこと


- splitメソッドは、文字列を分割し、配列にする。
- mapメソッドは配列に対して、同じ処理を繰り返し行う。
- joinメソッドは、配列の要素を文字列に変換し、引数を区切り文字として、結合した文字列を返す。
- upcaseメソッドは、小文字を大文字に変更する。



以上で、今日のコード基礎勉強でした。
今回は、メソッドの基本的な使用法を使った回答法でしたが、ほかにもメソッドは応用的な使い方があるようです。
次回以降でさらに深ぼりしていこうと思います。

間違いがありましたら、お手数ですがご教示ください。
chromeのオートコンプリート(支払い方法)の判断基準について

##経緯
自動入力が有効になる場合にautocomplete属性を指定していなくても可能であることにふと気づいて、判断基準について調べてみた。

##名前入力フォーム

###自動入力対応(名前：Label)
```html:index.html
<label for="">Name on card</label>
<label for="">名前</label>
<label for="">姓名</label>
```
###自動入力対応(名前：name)
```html:index.html
<input type="text" name="ccname" id="" value="">
<input type="text" name="名前" value="">
```
###自動入力対応(名前：id)
```html:index.html
<input type="text" name="" id="ccname" value="">
<input type="text" name="" id="名前" value="">
```

##カード番号
###自動入力対応(名前：name)
```html:index.html
<input type="text" name="card" value="" maxlength=""  size="">
<input type="text" name="cardnumber" value="" maxlength=""  size="">
```

###自動入力対応(名前：id)
```html:index.html
<input type="text" name="" value="" id="card">
<input type="text" name="" value="" id="number">
<input type="text" name="" value="" id="cardnumber">
```

##有効期限入力フォーム
###自動入力対応(名前：name)
```html:index.html
<input type="number" name="exp-month">
<input type="number" name="exp-year">
<input type="number" name="expiry">　※画面内に２個以上あるとダメ
```
###自動入力対応(名前：id)
```html:index.html
<input type="number" id="exp-month">
<input type="number" id="exp-year">
<input type="text" id="expiry">　※画面内に２個以上あるとダメ
```

##まとめ
- name属性で使用できる値はidでも同様に使えるっぽい
- class属性は全般的に判断基準に用いられないない
- 素直にautocompleteを付けておくのが一番楽
- autocomplete="off"は無効
- 日本語もちゃんと対応してるあたりはすげーなと思った



||label|name|id|class|autocomplete|
:-:|:-:|:-:|:-:|:-:|:-:|
|クレジットネーム|◯|◯|◯|×|cc-name|
|カード番号|×|◯|◯|×|cc-number|
|有効期限|×|◯|◯|×|cc-exp|


##参考サイト
https://developers.google.com/web/fundamentals/design-and-ux/input/forms/
https://greenido.github.io/Product-Site-101/form-cc-example.html
【Swift】Xcode10.2ではSwift3.0はもう使えない？？

# "SWIFT_VERSION '3.0' is unsupported, supported versions are: 4.0, 4.2, 5.0"

久しぶりにSwift3.0で書いたコードをメンテナンスしようと思ってみたらこのようなエラーに遭遇したので共有しておきます．
Xcode9まではSwift3で書いたコードも自動でコンパイルしてくれていたのですが，Xcode10からはSwift3.0で書いたものはコンパイルがそもそもできません．（実機でデバッグとかしようと思っても動かない状態になります）

Xcode10.2ではSwift3からSwift4への移行が必要になります．
そのため，以下のエラーが出てきます．
> "SWIFT_VERSION '3.0' is unsupported, supported versions are: 4.0, 4.2, 5.0"

解決方法は以下になります．

## 手順
1. まずはじめに **Targets** を選択
2. **Build Settings** を選択
3. **Swift Compiler - Language** の **Swift Language Version** を **Swift 4.2** に変更

コンパイルする際のSwiftのバージョンを指定してあげることで，コンパイル自体はできるようになります．
コンパイルができるようになったことで変更すべき箇所もわかるようになるため，そこを直してあげるというような形になります．
Leetcode #18: 4Sum

```swift
func fourSum(_ nums: [Int], _ target: Int) -> [[Int]] {
    var answer = [[Int]]()
    let nums = nums.sorted()
    for i in stride(from: 0, to: nums.count-3, by: 1) {
        if i > 0 && nums[i] == nums[i-1] {
            continue
        }
        for j in stride(from: i+1, to: nums.count-2, by: 1) {
            if j > i+1 && nums[j] == nums[j-1] {
                continue
            }
            var start = j+1
            var end = nums.count-1
            while start < end {
                if nums[i]+nums[j]+nums[start]+nums[end] == target {
                    answer.append([nums[i], nums[j], nums[start], nums[end]])
                    while start<end && nums[start] == nums[start+1] {
                        start+=1
                    }
                    while start<end && nums[end] == nums[end-1] {
                        end-=1
                    }
                    start+=1
                    end-=1
                } else if nums[i]+nums[j]+nums[start]+nums[end] > target {
                    while start<end && nums[end] == nums[end-1] {
                        end-=1
                    }
                    end-=1
                } else {
                    while start<end && nums[start] == nums[start+1] {
                        start+=1
                    }
                    start+=1
                }
            }
        }
    }
    return answer
}
```
Desktop : OpenCV take a picture

<H5>Goal</H5> 
Take a picture using opencv with webcam.


```opencv_webcam1.java
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.videoio.VideoCapture;

public class Opencv_webcam1{

	static {
		System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
	}
	
	public static void main(String[] args) {
		VideoCapture camera = new VideoCapture();
		camera.open(0);
		
		if(!camera.isOpened()) {
			System.out.println("Camera not open");
		}else {
			Mat frame = new Mat();
			try {
				System.out.println("使用 Webcam 拍照");
				camera.read(frame);
				Imgcodecs.imwrite("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\frame.jpg",frame);
				System.out.println("拍照完成");
				
			}catch (Exception e) {
				e.printStackTrace();
			}
			camera.release();
		}
		
	}

}

```
<H5>Result</H5>
![frame.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276243/11ca6473-2951-b521-a2e0-dabd0e629043.jpeg)
【PHP】オブジェクト指向を学ぶ[その1]

#オブジェクト指向
オブジェクト指向を学ぶために軽い自己紹介するコードを作ってみます。
まず
`・class設計・・・設計図`
`・インスタンス ・・・もの`
と言う考えを念頭におきます。

##コード
```index.php
<?php

//クラス定義
class Self_Introduction{

    // プロパティー
    // 変数定義
    private $name;
    private $age;

    // インスタンスが生成されると同時に処理が走る
    public function __construct($name, $age){
        $this->name = $name;
        $this->age  = $age;
    }

    // メソッド
    public function hello(){
        echo "私の名前は{$this->name}です。<br>年齢は{$this->age}才です。";
    }

}

// インスタンス生成
$user = new Self_Introduction("太郎", "35");

// メソッド呼び出し
echo $user->hello();

// 結果
// 私の名前は太郎です。
// 年齢は35才です。
```

classの中には、定数や変数そして関数 ("メソッド" といいます) を含めることができます。

##解説
まずclassを定義します。
class名の一文字目は大文字にする習わしがあるみたいです。

このclassの中で変数を定義したりconstructを書いたりメソッドを書いたりします。

そして、`$user = new class名(引数);`とすることでclassを使うインスタンスと言うものを生成し、メソッドを呼び出すことで一連の流れは終了です。

##インスタンス生成で何が起きているか
`$user = new Self_Introduction("太郎", "35");`この部分で何が起きているのか。

インスタンスが生成されると同時にclass内の`__construct()`に処理が走ります。
すると、インスタンスが生成された時の引数「("太郎", "35")」が`__construct()`で処理されます。

##メソッド呼び出し
`echo $user->hello();`最後にメソッドを呼び出します。
$userは`class Self_Introduction`を使ったインスタンスです。
Self_Introductionの中の`hello();`メソッドを使用しますと言った意味合いが近いと思います。

そして、メソッドに処理が走る結果として、自己紹介が行われると言った流れになります。

##アクセス権について
３つのアクセス権があります。
`public`・・・どこからでもアクセス可能
`private`・・・クラスとサブクラスからアクセス可能
`proected`・・・クラスからアクセス可能

こちらを踏まえて以下のコードを見てみます。

```index.php
class Access{
    
    public $public = "publicです";
    private $private = "privateです";
    protected $protected = "protectedです";

    function accessHello(){
        echo $this->public;
        echo $this->private;
        echo $this->protected;
    }
}

$hoge = new Access();
echo $hoge->public; //publicです
echo $hoge->private; //出力されません
echo $hoge->protected; //出力されません
$hoge->accessHello(); //publicですprivateですprotectedですと出力されます
```
実際インスタンスを生成してアクセスしてみるとこのような結果になります。
privateとpritectesdは外部からはアクセスできないので出力はされません。

ですが`accessHello()`はどうでしょうか？
全てが表示されています。
どう言うことかというとprivateでもprotectedでも同じクラス内のメソッドの中で処理が書かれています。
そして、メソッド自体のアクセス権は何も記されていないのでpublicです。


なので外部で`accessHello()`と呼び出すとクラス内で処理された結果が呼び出されるので、privateでもprotectedでも出力されるんですね。

次回はセッター、ゲッターについて書きます。

**※何か間違っていること、これも覚えておいた方がいいと言うことがあれば是非教えてください**
Typescriptでreduxのmiddlewareを書く

Typescriptでreduxのmiddlewareを書こうと思ったら型がよくわからなくなったので、覚書。
[この](https://qiita.com/IzumiSy/items/2e61a6c33a8ffd2fae9d)書き方だと古いのかうまく行かなかったので。

## 結論

reduxのindex.d.tsを読めばわかることなのですが...

```Typescript
import { Middleware, MiddlewareAPI, Dispatch, AnyAction } from 'redux';

export const timerMiddleware: Middleware = 
  <S extends AppStore>({ getState }: MiddlewareAPI<Dispatch, S>) => 
    (next: Dispatch<AnyAction>) => 
      (action: any): any => {
        /* middlewareの処理 */
        return next(action);
      };
```

## 参考
[TypeScriptでReduxミドルウェアを作る](https://qiita.com/IzumiSy/items/2e61a6c33a8ffd2fae9d) - [@IzumiSy](https://qiita.com/IzumiSy)
複数形ラベル名設定をオブジェクト設定画面に表示する方法

# 事象
複数形ラベル名設定がオブジェクト設定画面に表示されない事象が発生しました。

# 理由
複数形概念が存在しない言語の場合は複数形ラベル名設定が表示できないらしい。

# 解決方法
組織のデフォルト言語設定を英語に変更する。

**組織情報 → デフォルト言語 → 英語（複数形概念を持つ言語）**

## 設定画面
組織情報のデフォルト言語を英語に変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31622/e5bfb04c-5f04-4175-0d18-765255b8617b.png)

上記設定後、オブジェクト設定画面で複数形ラベル名が設定できるようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31622/7396631d-2591-79c6-507e-8634dbe425c1.png)
5分で立てるリダイレクタ

たまにリダイレクタたてたいなとなるが、それだけのために、アプリケーションを常に起動しておくだけのサーバーとか設置したくない・管理したくないみたいなことはよくあると思います。

[C95 今年の冬コミで出す本](https://circle.53ningen.com/#c95)で各地の時刻表とか案内ページへ飛ぶ QR コードをうめこもうとしてたのですが、外部サイトで URL 変更などがあるとアレなので、制御できるようにしたいなという気持ちで、原稿作業も押しているのでサクッと終わらせたいという気持ちで API Gateway + Lambda でリダイレクタを作りました。

構成管理もダルいので AWS が出してる [chalice](https://github.com/aws/chalice) というフレームワークを使うことにしました。それは何？という説明をする前に実装をみちゃったほうが早いと思うので紹介します。

## 環境構築

macOS で開発してデプロイします

```sh
$ sudo pip install chalice
$ # project を作る
$ chalice new-project c95-redirector
$ cd c95-redirector/
```

準備おわり


## 実装コード

なんか勝手にできる `app.py` を編集

```py
from chalice import Chalice, Response

app = Chalice(app_name='c95-redirector')

def getRedirectResponse(url):
    return Response(body='', status_code=301, headers={'Content-Type': 'text/plain', 'Location': url})

@app.route('/kumamoto/airportbus-timetables')
def kumamoto_airportBusTimetables():
    url = 'https://www.kyusanko.co.jp/sankobus/airport/limousine/'
    return getRedirectResponse(url)

@app.route('/kumamoto/citytram-timetables')
def kumamoto_cityTramTimeTables():
    url = 'https://www.kumamoto-city-tram.jp/Sys/web01'
    return getRedirectResponse(url)
```

リダイレクタの実装おしまいです

## デプロイ

```sh
$ aws configure
$ chalice deploy
Creating deployment package.
Updating policy for IAM role: c95-redirector-dev
Updating lambda function: c95-redirector-dev
Updating rest API
Resources deployed:
  - Lambda ARN: arn:aws:lambda:ap-northeast-1:😂:function:c95-redirector-dev
  - Rest API URL: https://qd30h0cdoj.execute-api.ap-northeast-1.amazonaws.com/api/
```

デプロイ完了です

## 叩いて遊ぶ

```sh
$ curl -i https://qd30h0cdoj.execute-api.ap-northeast-1.amazonaws.com/api/kumamoto/citytram-timetables
HTTP/2 301
content-type: text/plain
content-length: 0
location: https://www.kumamoto-city-tram.jp/Sys/web01
date: Thu, 15 Nov 2018 16:07:28 GMT
...
```

5 分で終わった

## 破壊して遊ぶ

```sh
$ chalice delete --stage dev
Deleting Rest API: qd30h0cdoj
Deleting function: arn:aws:lambda:ap-northeast-1:😂:function:c95-redirector-dev
Deleting IAM role: c95-redirector-dev
```

さよなら😢

## 感想

API Gateway, Lambda のリソース管理、何も書かずに勝手にやってくれるので、便利


## おまけ

リージョンエンドポイントにカスタムドメインを設定する手順メモ。

まずは aws route53 change-resource-record-sets コマンドで送るリクエスト内容を作る

```sh
$ vi /tmp/setup-dns-record.json
...
$ cat /tmp/setup-dns-record.json 

{
  "Changes": [
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "c95.53ningen.com",
        "Type": "A",
        "AliasTarget": {
          "DNSName": "😂.execute-api.ap-northeast-1.amazonaws.com",
          "HostedZoneId": "Z1YSHQZHG15GKL",
          "EvaluateTargetHealth": false
        }
      }
    }
  ]
}
```

setup-dns-record.json を作った上で以下を実行する

```sh
aws route53 change-resource-record-sets \
    --hosted-zone-id {your-hosted-zone-id} \
    --change-batch file:///tmp/setup-dns-record.json
```
Rails チュートリアル  第11章　学習内容のメモ

#第11章アカウントの有効化
- 本章ではユーザの新規登録時に、該当のユーザが本当にそのメールアドレスの持ち主であることを確認する機能を追加する

##Activationトークンのコールバック
- 6章で実装した`before_save`コールバックではオブジェクトが保存される直前、オブジェクトの作成時や更新時にそのコールバックが呼び出される
- 今回はオブジェクトの作成時のみにコールバックを呼び出したいので、`before_create`コールバックを使用する
- 以下のように実装する。

```app/models/user.rb
class User < ApplicationRecord
  attr_accessor :remember_token, :activation_token
  before_create :create_activation_digest
  validates :name,  presence: true, length: { maximum: 50 }
  .
  .
  .
  private

    # 有効化トークンとダイジェストを作成および代入する
    def create_activation_digest
      self.activation_token  = User.new_token
      self.activation_digest = User.digest(activation_token)
    end
end
```

##アカウント有効化のメール送信
- 有効化メールを送信するための、メイラーを作成する
- メイラーの構成は、コントローラーのアクションとよく似ており、メールのテンプレートをビューと同じように定義できる
- メイラーは`rails generate`で生成できる

## 本番環境でのメール送信
- テストはパスしていたが、ユーザ登録の際に送付されたURLをクリックした際に以下のページが表示された

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/353542/e58b838d-39c9-7198-66f4-c35e66c536f0.png)

- 本番環境の設定を誤っていた
- 以下の`'<your heroku app>.herokuapp.com'`の箇所を自身のherokuアプリのURLに変更することで解決

```config/environments/production.rb
Rails.application.configure do
  .
  .
  .
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  host = '<your heroku app>.herokuapp.com'
  config.action_mailer.default_url_options = { host: host }
  ActionMailer::Base.smtp_settings = {
    :address        => 'smtp.sendgrid.net',
    :port           => '587',
    :authentication => :plain,
    :user_name      => ENV['SENDGRID_USERNAME'],
    :password       => ENV['SENDGRID_PASSWORD'],
    :domain         => 'heroku.com',
    :enable_starttls_auto => true
  }
  .
  .
  .
end
```

##メモ
- rails serverを立ち上げようとすると、以下のように表示され起動できなくなった
- 
```
$ rails s
=> Booting WEBrick
=> Rails 3.2.14 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
A server is already running. Check /worktest/sample/tmp/pids/server.pid.
Exiting
```

- バックグラウンドでrails serverが立ち上がっていることが原因
- `＄　ps aux | grep puma`でrails serverプロセスを検索し、
- `kill -9 ”プロセスID”`でプロセスを停止しようとするができない
- `-bash: kill: (37580) - No such process`と表示される
- プロセスIDが自動で切り替わるバグが発生している？？
- 以下のURLを参考にして対処した

[Rails sのプロセスが切れない時](https://qiita.com/motty93/items/d22c1eb8f5128f8cd7f8)
未経験フリーターがエンジニアになるための計画

#現状
- ITとは無関係の学歴
- 地方在住
- 正社員歴なし
- エクセルは使えない（閲覧と簡単な入力のみ）

#どうなりたいか
- 正社員で働きたい
- システム開発に携わるエンジニアになりたい
    - 仕事やプライベートでWebシステムやアプリケーションを利用してきたことで、システムの開発に携われるエンジニアの仕事に魅力と将来性を感じた。    
- 早く経験を積んで技術力を身に付けたい
-　地方在住だが仕事がなければ大阪で探したい

#やっていること

- ProgateでJavaの勉強
    - なぜJavaなのか→汎用性が高い
- 参考書でITパスポートの勉強
- 無料サイトや本を見ながらExcelの独学（キングソフトの表計算ソフトで代用）
- Qiitaに登録


#どうやってエンジニアを目指すか
- Oracle Java BronzeとITパスポートの資格取得
- 未経験可・研修ありのSESの会社に応募する
- SESの会社に入って経験を積んでキャリアアップ
私が勧めるVSCode拡張機能

# はじめに
[Visual Studio Code](https://code.visualstudio.com/) (以後、VSCode)は、Microsoftが開発したマルチプラットフォームのエディターです。

拡張機能が豊富で、ユーザーはそれらの拡張機能を自由に導入することができます。

その中で、私がおすすめする拡張機能をご紹介いたします。

※拡張タイトルの後にあるcodeブロックは、各拡張機能の識別子です。

## Japanese Languagee Pack for Visual Studio Code ```ms-ceintl.vscode-language-pack-ja```

デフォルトのVSCodeは英語です。それを日本語に変更したいときに使用する拡張機能です。

Microsoftから出ているため、翻訳の充実度は安定しています。

[詳細](https://marketplace.visualstudio.com/items?itemName=MS-CEINTL.vscode-language-pack-ja)

## Material Icon Theme ```pkief.material-icon-theme```

各ファイルの拡張子や名前、フォルダ名によってアイコンが変わる拡張機能です。
種類がとても豊富なので、様々な言語で適応できるアイコンテーマです。

[詳細](https://marketplace.visualstudio.com/items?itemName=PKief.material-icon-theme)

## Python ```ms-python.python```

PythonをVSCodeで編集するときにおすすめの拡張機能です。
pylintをpipでインストールすれば、文法に不備があったりするとハイライトしてくれたりします。
virtualenvにも対応しています。
(他にも機能がたくさんあります)

[詳細](https://marketplace.visualstudio.com/items?itemName=ms-python.python)

## Discord Presence ```icrawl.discord-vscode```

あくまでおまけ的存在です。

Discordにステータスを表示できる拡張機能です。
ファイル編集しているとそのファイルを編集しているというステータスをDiscordに表示できます。
もちろん、プライベートな内容のファイル編集になる場合はコマンドから止めることもできます。

[詳細](https://marketplace.visualstudio.com/items?itemName=icrawl.discord-vscode)

-----

まぁこんなもんです。他にもたくさん拡張機能があるので自分にあった拡張機能を探してみてください。
Leetcode #17: Letter Combinations of a Phone Number

```swift
private let dict: [Character: [Character]] = ["2": ["a","b","c"], "3": ["d","e","f"], "4": ["g","h","i"],
                                              "5": ["j","k","l"], "6": ["m","n","o"], "7": ["p","q","r","s"],
                                              "8": ["t","u","v"], "9": ["w","x","y","z"]]

func letterCombinations(_ digits: String) -> [String] {
    if digits.isEmpty {
        return []
    }
    var answer = [String]()
    var ar = [Character]()
    helper(Array(digits), 0, &ar, &answer)
    return answer
}

private func helper(_ digits: [Character], _ index: Int, _ ar: inout [Character], _ answer: inout [String]) {
    if index == digits.count {
        answer.append(String(ar))
        return
    }
    for char in dict[digits[index]]! {
        ar.append(char)
        helper(digits, index+1, &ar, &answer)
        ar.removeLast()
    }
}
```
IntelliJ を Maven artifact からスタートした時の問題

# インテリセンスや、ライブラリをエディタが認識できない

IntelliJ を使っていて、Maven artifact 生成からプロジェクトを開始した時にインテリセンスはおろか、Mavenのタスクだとコンパイルできるのに、エディタが認識しない。結構悩んだけど、これをヒントに解いた

* [IntelliJ not able to resolve classes of external Libraries for Maven projects](https://intellij-support.jetbrains.com/hc/en-us/community/posts/207108385-IntelliJ-not-able-to-resolve-classes-of-external-Libraries-for-Maven-projects)

結局したとこは、

プロジェクト右クリック > Maven > ReImport 

で解決。（そんなん知らんわ）

ちなみに、その前に調査しているときに、関係ないと思うけど、ソースディレクトリと、テストのディレクトリの設定をした。
場所が、プロジェクトを選択して、File > Project Settings > Modules > Source で設定できる。

でも多分ReImportで解決していると思われる。

# Kafka Client をIntelliJで実行すると slf4j エラー

```
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
```

くそハマった。これは、上記のURLを見ると、ライブラリをpom.xml に足すと良いと言われる。ブログや、スタックオーバーフローもそう言っているが、全く解決できなかった。しかし、知らん間に治った。おそらく、ライブラリを追加した設定が本来有効であるはずなのに、古いものをみていた雰囲気があるが、今となっては原因はわからない。

```
   <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.25</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-jdk14</artifactId>
      <version>1.7.25</version>
    </dependency>
```

pom.xml に上記のをたして、clear,install,compile とかしても、治らなかったので、手動で確認しようとして、下記のプラグインを入れて、ゴネゴネしていて、久々にIntelliJから実行すると、意味わからないけど、動作した。

```
        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>exec-maven-plugin</artifactId>
          <version>1.2.1</version>
          <configuration>
            <mainClass>simplearchitect.App</mainClass>
          </configuration>
        </plugin>
```

* [SLF4J warning or error messages and their meanings](https://www.slf4j.org/codes.html#StaticLoggerBinder)
* [Solving Failed to load class “org.slf4j.impl.StaticLoggerBinder” Error](https://examples.javacodegeeks.com/enterprise-java/slf4j/solving-failed-load-class-org-slf4j-impl-staticloggerbinder-error/)

これは多分IntelliJの挙動を私が理解していないため。このライブラリは、IntelliJ からではなく、MavenのDependencyを参照しながら、アプリをマニュアルで実行するプラグイン。`mvn exec:java` で動作する。こちらでは問題なく動いていた。

ちなみに、ターゲットのライブラリのバージョンを知るには

```
mvn dependency:tree
```
もしくは、IntelliJ のmaven パネルで確認すると良い。

# Error: java: javacTask:source release 8 requires target release 1.8

これは、artifact で生成したテンプレートが、1.7になっていたため。pom.xmlを書き換える。

```
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
```

しかし、これだけではダメで、上記のReImport が必要。Preference > Build, Execution, Deployment > Compiler > Java Compiler のプロジェクトの、Target bytecode version が古いままのため。


忘れないようにメモ