OmniAICreator/Qiita-1.07M huggingface dataset:
AWS Backup運用時の検討項目

# はじめに

仕事でAWS Backupを使う機会があり、色々調べた内容をまとめます。

# AWS Backupとは

AWSのバックアップ機能は既に存在していますが、AWS Backupはそれらの機能を一元管理するためのサービスです。
具体的にはバックアップのスケジューリングやバックアップの管理（ローテーションなど）を一つのインターフェースで操作することができます。

https://aws.amazon.com/jp/backup/

AWS Backupでは「バックアッププラン」という単位で管理し、その中に「バックアップルール」（実行スケジュール）と「リソース」（取得対象）を定義します。

![awsbackup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319027/7e904c46-6d97-4210-aafa-9e1b369c04e7.png)


# 作成時の項目

AWS Backupでバックアップ運用を設計するにあたり、検討するべき項目をまとめます。

（※以下、作成時の表示順序とは異なります）

## バックアップ取得対象

取得対象の設定方法は下記2種類です。

- タグ指定 : 指定したタグが設定されているリソース
- リソース : 任意のリソースID（個別指定）

取得対象の数が多くない＆今後増えることがない場合はリソースID直指定の方が設定は楽ですが、基本的にはタグ指定で設定すると思います。


## 取得スケジュール

バックアップを実行する時間とその周期を指定します。

- 取得周期 : 12時間毎、毎日、毎週、毎月
- 取得時間 : 任意の時間（UTC指定なので、JSTにする場合は-9時間で記載）
- バックアップウィンドウ : 1時間～8時間

取得周期と時間は上記がデフォルトセットですが、cron形式で細かく設定することもできます。
（例えば30分おきに取得など）
また、バックアップウィンドウは「この時間の間に取得する」という時間帯であり、任意の時間決め打ちで取得することができない点だけ注意が必要です。
（ただ、オンラインで取得可能なので実運用ではあまり意識しなくても良いと思います）

## 保管期限

作成後何日（あるいは週、月、年）経過したら削除するかを指定します。
あくまで世代数ではなく作成からの日数のため、一日に何回も取得するスケジュールの場合は考慮が必要です（あまり無いと思いますが）
ちなみに削除タイミングは「バックアップ実行時」です。


## コールドストレージへの移行

バックアップをGlacierに保管するかどうかの設定です。
設定は任意ですが、有効にした場合、最低でも90日保管とする必要があります。
（システムバックアップ用途では不要ですが、監査要件などで長期保管が必要なデータを取る際には利用を検討しても良いと思います）


## リージョン間コピー

取得したバックアップを他のリージョンにコピーするかどうかの設定です。


## バックアップボールト

公式ドキュメントでは「バックアップを整理するためのコンテナ」と説明されていますが、主に下記を個別に設定したい場合に使う設定です。
任意で作成するか、デフォルト（Default)を使用するかを選択します。

- バックアップを暗号化するキーを指定
- バックアップへのアクセス権を設定

具体的には、マルチテナント（1つの基盤に複数のシステムが共存）でバックアップリソースの管理を厳密にしたい場合に使うようです。
（特に要件が無ければデフォルトで良いと思います）


## IAMロール

任意で作成するかデフォルトのIAMロールを使用するかを選択します。

この場合のIAMロールはAWS Backup内のバックアップやその他のリソースへのアクセスを制御するものです。
デフォルトでは「AWSBackupDefaultServiceRole」というロールが自動で作成されてアタッチされますが、これもバックアップボールトと同じく、実行権限を厳密に管理したい場合以外はデフォルトで良いです。

少し細かい話をすると、AWS Backupに関する事前定義済みのポリシーは下記4つです。
「AWSBackupDefaultServiceRole」ではこの内③と④が適用されています。

①AWSBackupFullAccess　：　フルアクセス
②AWSBackupOperatorAccess　：　取得対象追加、バックアップ/リストアを実行可能（スケジュール作成不可）
③AWSBackupServiceRolePolicyForBackup　：　バックアップ取得を実行可能
④AWSBackupServiceRolePolicyForRestores　：　リストアを実行可能

## 復旧ポイント（タグ追加）

取得したバックアップリソースに対し、任意でタグを追加できる機能です。
例えば、定期的に取得しているバックアップとそれ以外を分けて管理したい場合などに使えます。
（特に気にしない場合は設定不要）


# 補足

余談ですが、バックアッププランには他リソースと同様にNameなどのタグを付けて管理することが可能ですが、AWS Backupはタグエディターでの一括検索（及び編集）の対象にはなっておらず、個別に編集する必要があります。（2020/2/15時点）

明らかに正しい動作には見えないので、その内修正されるかもしれません。
（AWS Backup自体比較的新しめの機能なので、まだ実装が追い付いてないだけだと思います）
Amsterdam Compiler Kitをとりあえず動かす

# Amsterdam Compiler Kitとは

https://en.wikipedia.org/wiki/Amsterdam_Compiler_Kit
http://tack.sourceforge.net/
http://tack.sourceforge.net/about.html

ANSI C,Pascal,Modula-2,BASICなどをコンパイルしlinux(32bit)、CP/M、RaspberryPi、AT互換機の起動可能なフロッピーのイメージなどで実行できるバイナリを生成します。またZ8000や6805などのクロスアセンブラもあります。
今回できたのはWSL上のUbuntu 16.04LTS上で動作するAmsterdam Compiler Kitの環境とCP/Mエミュレータ上でのバイナリの動作確認までです。


## 動作環境の構築(V6.1pre1 20200216)
・Windows10 WSL(Ubuntu18.04LTS)

(1)必要なツールの準備(gcc,make,ninja-build,flex,bison)

```

$ sudo apt install gcc make ninja-build flex bison
```
(2)ダウンロード

```
$ git clone https://github.com/davidgiven/ack
```

(3)インストール

```
$ cd ack ; make
...
$ sudo make install
```

## 動作環境の構築(V6.0pre5)

Windows10上のWSL(Ubuntu16.04LTS)で確認しました。

(1)ダウンロード
https://github.com/davidgiven/ack/releases/tag/release-6-0-pre-5
注意！Source code(tar.gz)の方でないとビルドできません。以下のURLより取得。
https://github.com/davidgiven/ack/archive/release-6-0-pre-5.tar.gz

(2)Makefile修正
展開後、Makefile内の　PREFIX = /usr/local　を有効にする。
DEFAULT_PLATFORMの指定はlinux386なりcpmなり書き換え。

(3)必要なソフトウェア
gcc,make,flex,bisonはデフォルトのWSL(Ubuntu16.04LTS)には入っていないのでsudo apt installで入れておく。

(4)インストール
make でwarningが多数出るがビルドは通る。sudo make installで/usr/local/以下にackがインストールされる。

## 使い方（V6.0pre5の例)

examples/ 以下に各種ソースファイルのサンプルがあります。言語は拡張子で判別します。
.c　C言語
.b　B言語
.p　Pascal
.bas　BASIC
.mod　Modula-2
.ocm　Occam 1

ターゲットとなるシステムは-mで指定。ここでのシステムはプロセッサとその周辺を含んだ計算機システムやOSのことでプロセッサ単体のことではありません。
linux386　Linux 32bitバイナリ
pc86　AT互換機のフロッピーディスクブートイメージ
rpi　Raspberry Pi
cpm　CP/M

ここではCP/MをターゲットにModula-2で書かれた数当てゲームをコンパイルします。
ack -mcpm examples/hilo.mod
 base : 00000100
 text = 00007CD3
 rom  = 00000603
 data = 0000011A
 bss  = 000015BD
TOTAL = 000099AD

これでcpm.comというバイナリができました。これをWindows上で動くCP/Mエミュレータで実行します。
TAKEDA, toshiyaさんのCP/M Player for Win32を使用しました。
http://takeda-toshiya.my.coocan.jp/cpm/index.html
展開しcpmconsというフォルダ内にcpm.exeという実行ファイルを確認します。これがエミュレータ本体です。

Windows10(Update1909適用済)からWSLのファイルイメージにアクセスするにはエクスプローラから\\\\wsl$と入力して参照します。これで先程のcpm.comをcomconsフォルダ以下にコピーします。

実行はコマンドプロンプトからcpm.exe cpm.comでOK。

※cpm.comはMS-DOSのコマンドとみなされ、かつ同名のcpm.exeよりも優先されるので単にcpm cpm.comと入力するとエラーになります。cpm.exeとコマンド名を打ち込むかcpm.comをリネームすることで対処してください。

※-mlinux386で32bit版のlinux用バイナリが出力できますが、WSLでは32bit版の実行ができません。

その他、-Oで最適化、-fpでソフトウェアによる浮動小数点の指定ができます。

## 今後の調査

・~~Ubuntu18.04LTS(実機およびWSL上)ではビルド時にyacc周りでエラーが出てインストールできない~~
・~~ソフトFPUの指定(ack -mcpm -fp xxx)でライブラリが見つからない~~
・ackで指定できるオプションの種類
・各種クロスアセンブラの方法
Lodashの備忘録

# Lodashとは？

便利関数をまとめたJavaScriptライブラリです。
配列処理や単なる値の操作だけでなく、イベント処理を制限したりなど様々な関数があります。
ドキュメントを眺めていると面白い関数がたくさんあったので、気になった関数たちを紹介していきます。

- [lodash　公式ドキュメント](https://lodash.com/docs/4.17.15)

## _xor

* 配列の同じ値をまとめて、新しい配列を返す

```js
const arr2 = [2,3,4,4]
  const arr=[...arr2]

  const _arr = _.xor(arr)

  console.log(_arr)
// [2,3,4]
```

## _has

* 引数に渡したオブジェクトのキーを検索し、キーが存在すればtrueを返す



```js
var object = { 'a': { 'b': 2 } };
_.has(object, 'a');
// => true
```

## _sortBy

* 第一引数に対象の配列、第二引数にソートしたいkey名


＊[faker.js](https://github.com/marak/Faker.js/) というダミーデータを作成してくれるライブラリを使用しています。

```js
const targets: any[] = [];

for (let i = 1; i < 1500; i++) {
  targets.push({
    name: faker.company.companyName(),
    owner: faker.name.firstName()
  });
}
const res = _.sortBy(targets, ['name','owner']);

console.log(res);
// name,ownerの昇順で並び替えられる

```


## _compact

-  [falsy](https://developer.mozilla.org/ja/docs/Glossary/Falsy)な値を取り除き、新しい配列を返す

``` js
const target = [0, 1, false, 2, '', 3]
const res = _.compact(target);

console.log(res)

// [1,2,3]
```

## _flatten

- 入れ子の配列を一階層なくす
	
```js
const target = [['hello'],'world']
const res = _.flatten(target);

console.log(target)

// ["hello", "world"]
```

##  _pull
 * 第一引数に対象の配列、第二引数に取り除きたい値を渡し、配列を返す


```js
for (let i = 1; i < 10; i++) {
  targets.push('トマト');
}

const _res = _.pull(targets, "トマト");

console.log(_res);

// []
```
CircleCIでVue.jsアプリをFirebaseにデプロイする

以前作ったVue.jsアプリ、これはFirebaseでHositingさせてもらってます。

https://no-smoke.web.app/

当時の記事はこれです。

https://qiita.com/qoAop/items/9d8375de98b74dd55b60

Vue.jsアプリをFirebaseHostingにデプロイするには、

```sh
yarn build
yarn deploy
```

で、デプロイしてました。

ただ、厳密（？）には、これだけじゃなくて、```firebase login```、して```firebase use [プロジェクト]```をしておかなければならないわけです。

で、本題ですがこれをCircleCIで自動化したれということです。

始めたばかりなので設定ファイルに過不足があるかと思いますがこんな感じで設定しておけば、```git push origin master```すれば、CircleCIのほうでビルドしてFirebaseにHostingまでしてくれるようになります。

## CircleCIの設定

一点注意することがあります。Macのコマンドラインでfirebase loginをするとブラウザが立ち上がりますがそういうことは無理なので事前にDeploy用のアクセストークンを取得して完全にコマンドで操作できるようにしなければなりません。

それで、Firebaseのアクセストークンを取得して、ついでにデプロイ用のプロジェクトIDも設定します。画面はこんな感じです。

![circle-env.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51116/227f7b43-28ad-f526-8871-060fefdb55ee.png)

こうすると、CircleCIのconfig.ymlの中で変数として利用できるようになります。

## ディレクトリ構成はこんな感じ

Vue.jsとFirebaseでプロジェクトつくるとこんな感じになってると思います。

プロジェクトのトップレベルに.circleci/config.ymlを作るのがポイントだそうです。

```txt
.
├── .circleci
│    └── config.yml
├── .env
├── .env.development
├── .env.production
├── .eslintrc.js
├── .firebase
├── .firebaserc
├── .git
├── .gitignore
├── .node-version
├── README.md
├── babel.config.js
├── dist       <-------- build したもの
├── firebase.json
├── firestore.indexes.json
├── firestore.rules
├── functions
├── node_modules
├── package.json
├── public
├── src
├── storage.rules
├── vue.config.js
└── yarn.lock
```

## .circleci/config.yml

中身はこんな感じです。テストなしｗ、ビルドしていきなりデプロイしちゃいます。

```yaml
version: 2
jobs:
  build:
    working_directory: ~/app
    docker:
      - image: circleci/node:10
        environment:
          LANG: ja_JP.UTF-8
          TZ: Asia/Tokyo
    steps:
      - checkout # ソースコードを作業ディレクトリにチェックアウト
      - run:
          name: install & build
          command: |
            yarn install
            yarn build
      - persist_to_workspace:
          root: . # workspaceのrootパスを永続化する、要は共有
          paths:
            - . # rootからの相対パス
  deploy:
    working_directory: ~/app
    docker:
      - image: circleci/node:10
        environment:
          LANG: ja_JP.UTF-8
          TZ: Asia/Tokyo
    steps:
      - attach_workspace: # persist_to_workspaceで設定したディレクトリを利用する
          at: .
      - run:
          name: deploy firebase hosting
          command: |
            yarn global add firebase-tools
            `yarn global bin`/firebase deploy --only hosting --project "${PROJECT_ID}" --token "${FIREBASE_TOKEN}"
workflows:
  version: 2
  build_and_deploy:
    jobs:
      - build
      - deploy:
          requires: # buildが成功したら実行
            - build
          filters:
            branches:
              only: master # master branchのみdeploy
```

これでいい感じにデプロイするようになりました〜
【Next.js】getInitialPropsでfsを使う場合

## 環境
- Next.js 9.2.1

## getInitialProps内でファイルを読み込む

Next.jsでファイルを読む場合、raw-loaderを用いる方法もあるが、普通にfsを用いることもできる。

今回はpythonファイルを読み込む例。

```tsx:src/pages/index.tsx
import fs from 'fs';
import { NextPage } from 'next';
import React from 'react';
// codeをrenderするコンポーネント
import { CodeArea } from '../containers/CodeArea';

type InitialProps = {
  pythonCode: string;
};

const Index: NextPage<InitialProps> = props => (
  <>
    ...
    <CodeArea code={props.pythonCode} />
    ...
  </>
);

export default Index;

Index.getInitialProps = async () => {
  const pyFile = fs.readFileSync("./src/codes/python_code.py");
  return { pythonCode: pyFile.toString() };
};
```

しかし、fsをそのまま使用すると以下のようなエラーに遭遇する。

```bash
[ wait ]  compiling ...
[ error ] ./src/pages/index.tsx
Module not found: Can't resolve 'fs'
...
```
これはwebpackがブラウザ向けにバンドルする際、fsモジュールが解決できないことで起こる。
`package.json`を以下のようにすればOK

```json:package.json

{
  ...
  "browser": {
    "fs": false
  }
}
```

## zeit Nowで運用する場合

上記のままデプロイすると、404が。
.babelrcにプラグイン`babel-plugin-static-fs`を追加する必要がある。

```json:.babelrc
{
  "plugins": ["babel-plugin-static-fs"]
}
```
ubuntu 16.04 LTSをインストールする簡単な手順メモ

# 目的
ubuntu 16.04 LTSをBOOTする簡単な手順メモ

# 準備

１．以下からubuntu 16.04 LTS Bootイメージを取得

> [ubuntulinux.jp/News/ubuntu1604-ja-remix](https://www.ubuntulinux.jp/News/ubuntu1604-ja-remix)
> ubuntu-ja-16.04-desktop-amd64.iso（ISOイメージ）

２．etcherでイメージをUSBメモリに書き込む(容量は8GB以上などを準備する）

> [etcher](https://www.balena.io/etcher/)

３．USBをインストール対象PCに挿してPCを起動

# 備考
USB Boot開始しない場合はBIOSから起動順序を変更する。

# 参考
[ubuntu 16.04 LTSをUSBからBOOTするメモ](https://qiita.com/konzo_/items/6adfd816c54a4d9d6418)
Goroutineを雑多にまとめる

Goroutineの文法を自分用メモとしてまとめる。

# sync.WaitGroup

複数のスレッドで並列処理を行う際、その全ての完了を確認するために使用できる。WaitGroupのカウンタを用いる。(Javaのjava.util.concurrent.CountDownLatchによく似ているらしい)

```go
// WaitGroupの値を作る
wg := &sync.WaitGroup{}

 // wgのカウントをインクリメント
wg.Add(1)
go func(wg *sync.WaitGroup) {
    // wgのカウントをデクリメント
    defer wg.Done()
    処理
}
// カウントが0なら次に進める
wg.Wait()
処理
```

[注意] `Addされるカウントの合計 = Done()の合計個数`である必要あり

# チャネル
* 中身の個数が決まってるのが`bufferred channel`、決まっていないのが`unbufferred channel`。

```go
// チャネルの作成
ch = make(chan int)
 
// チャネルへ値を突っ込む
ch <- x

// チャネルから値を取り出す
y := <- ch

// チャネルの中身をループ
// もし他にプログラムが入っていない、つまり、このchに新しい値が入る可能性がないならばループ前にcloseする必要あり
close(ch)
for c := range ch {
    処理
}
```

* `fan out` / `fan in`

```go
// 順にfan out / fan in 
def(first <-chan int, second chan<- int){
    処理
}
``` 

* { 無限for, select文 }からの抜け方

```go
Outerloop: 
    for {
        select {
        case <-ch:
            fmt.Println("Out!")
            break OuterLoop
        default:
             処理
        }
    }
}
```

# sync.mutex
複数のgoroutineから一つの変数を書き換えたいときに使う。

```go
// お目当ての変数とMutexを含む構造体を定義する
type Counter struct{
    v map[string]int
    mux sync.Mutex
}

// それを使う
func (c *Counter) Inc(key string) int {
    c.mux.Lock()
    defer c.mux.Unlock()
    return c.v[key]++
}
```


# 参考
* [sync.WaitGroupの正しい使い方](https://qiita.com/ruiu/items/dba58f7b03a9a2ffad65)
ラズパイのGPUメモリ割当てとマイクラのスクショ、VNC

## ラズパイでマイクラのスクショを撮る
Qiitaではありませんが、2年前に書きました。
[「ラズパイでマイクラの画面を撮る方法」](https://code2create.club/ja/blog/how-to-take-minecraft-screen-on-raspberry-pi/)

Raspbian標準インストール、ファンクションキーにも割当されているscrotではマイクラのウィンドウを撮れないので、raspi2pngで置き換え、日付と時刻を入れたファイル名で保存できるようにする方法。

その後、マイクラのウィンドウを大きくするとエラーが出て撮れないことがあったり、遅いWindowsマシンからのVNC接続で調子が悪い時があるな、、と思いつつ、原因を特定できていませんでしたが、あるきっかけから調査して判明したことがあるので記録に残します。

結論から言うと、GPUメモリ割当てが重要。ちなみに、ラスパイ3B、Raspbian Stretchでの話です。

## GPUメモリ割当ての影響

メモリ割当てを色々変えながら試したところ、色々と影響がありました。RealVNC Server-Viewerでの接続も使っています。（マイクラ画面をリモート接続したいときは、RealVNC Server側でOptions/Trouble Shooting/Optimize screen capture の Enable direct capture modeにチェックを入れる）

1. 32MB： VNCがつながらない！ マイクラが動かない！ ウィンドウが真っ暗。おまけにマイクラ終了もできない！おそらく起動中でスタックしてる。
2. 48MB： VNCつながる。マイクラ動かない。ウィンドウが真っ暗だが、終了はできる。
3. 64MB： VNCつながる。マイクラが動くが、全画面表示にすると真っ白。スクショも撮れるが、ウィンドウサイズに制限有り。
4. 80MB： マイクラを全画面にしてスクショを撮れる。（必要ないけど）マイクラウィンドウを1920x1080より大きくしていくと、割とすぐに真っ暗に。
5. 96MB： 余裕あり。なんやかんや耐える。

GPUメモリは、CPUメモリと合わせて計1GBをシェアしています。96MBを超えて増やすと今度はCPUメモリ割当てが少なくなり、全体の動作が緩慢になる原因に。2GB、4GBのバージョンのあるラズパイ4だとこのあたりは余裕が出てくる部分ですね。


GPUメモリ割当て （このあと、「パフォーマンス」タブで設定、再起動）
![Screen Shot 2020-02-03 at 1.29.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5412/57f31a74-ed8d-477f-bd74-6c0bae166e3d.png)

RealVNC設定 （Enable direct capture modeにチェック）
![RealVNC_Server_Option.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5412/86592118-fc12-fc96-a4f9-d377d2397a5e.png)

VNC経由マイクラ全画面スクショ例
![snapshot-20200202-154929.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5412/2a452c00-fce5-c74f-126d-81a00414d6fe.png)
初めてのQiita

# 1 はじめまして
どうもこんにちは、yusukeと申します。

関西圏在住の社会人です。電子工作とかプログラム、raspberry piとかをいじってるものです。
なにか完成したら備忘録程度に書き記そうかなと思います。まだまだ初心者なので、参考にならないと思いますが....
あくまで趣味なので、途中で辞めるかも。内容も薄いと思います。

# 2 info
学んでいる言語 ： Arduino, C, Nodejs, Html, Python, SQL
使用機器 ： Arduino, raspberrypi, Windows10
開発環境： VisualStudio, etc...
趣味 ： 読書, ゲーム, 電子工作, プログラミング, アニメ鑑賞 etc...


# 3 Qiitaをどのようにして使っていくか
1.学んだことの備忘録、作ったものの紹介
　学んだことを、見やすくまとめて、わかりやすく説明できたらいいなと思います。

2.技術紹介
　ガイドラインには、
> ☝ プログラミングに関する記事を投稿しよう
Qiitaは「プログラミングに関する知識を記録・共有するためのサービス」です。プログラマーが興味を持つものではなく、プログラミングに関する記事を投稿しましょう。

　と書いてますので、プログラミングに関する技術情報などを紹介できたらいいなと思います。

# 4 資格
・第1級海上特殊無線技士
・第3級陸上特殊無線技士
・CCNA
・普通自動車運転免許

# 5 最後に
こんな人間ですが、どうぞよろしくおねがいします。
Twurl で連携アプリ認証し、アクセストークンとシークレットを取得

Twitter API で遊んでいるときに、開発者アカウント以外のサブアカウントでアクセストークンが欲しくなったので、twurl で連携アプリ認証して取得してみました。
認証処理を自力で実装する必要がなくなります (外部に公開するアプリの場合は結局作らないといけませんが) 。

参考「[GitHub - twitter/twurl: OAuth-enabled curl for the Twitter API](https://github.com/twitter/twurl)」

# 1. インストール

Twurl のインストールに Ruby を使用するのであらかじめインストールしてください。
古いバージョンの Ruby だとインストールできません。

参考「[Ubuntu で最新版の Ruby をインストール - Qiita](https://qiita.com/kerupani129/items/77dd1e3390b53f4e97b2)」(Ubuntu の場合)

```bash:インストール
gem install twurl
```

# 2. 連携アプリ認証

アプリの API キーと API キーシークレットから、アプリの認証画面の URL を取得します。

```bash:連携アプリ認証画面&nbsp;URL&nbsp;取得
twurl authorize --consumer-key '...' --consumer-secret '...'
```

Twitter にログインした状態のブラウザで URL を開き、認証ボタンを押します。
すると PIN コードがブラウザ上で表示されますので、ターミナル上で待機している twurl に入力すれば認証完了となります。

# 3. アクセストークンとアクセストークンシークレットの取得

`twurl` コマンドからはアクセストークンとアクセストークンシークレットが見えないようになっているため、ローカルに保存されているファイル `~/.twurlrc` を `cat` コマンドなどで直接見ます。

```text:~/.twurlrc&nbsp;(イメージ)
---
profiles:
  twitterdev:
    aQYdF8KMEKn2f28GEeOyhMFGR:
      username: twitterdev
      consumer_key: aQYdF8KMEKn2f28GEeOyhMFGR
      consumer_secret: 3TKyJ08KDXPNpnUznlgqAHeCFrcI9UktoFfvOrfrLuipDjOceL
      token: 766494776020356823-isa427xU1StuTg61eKTWYLSR5BL11qk
      secret: gORljqA8Og1GRSE6lx3rpkwLf5al1f0onHei3A5Wr14cC
configuration:
  default_profile:
  - twitterdev
  - aQYdF8KMEKn2f28GEeOyhMFGR
```

(※値はダミーです。実際にアカウント twitterdev で認証したわけではありません。)

`token` と `secret` の値から、アクセストークンとアクセストークンシークレットを調べることができます。
GoogleのCloud Vision APIでの結果出力で困ったこと

# JSONファイルを出力しようと思ったら、ファイルの最初と最後に変な文字が入っていた問題

そもそも、関数を理解していないんじゃないかと思ったので、ちゃんと理解しなきゃと痛感。

## 参考にしていたサイト
ここを参考にベースを作ってました。
[Google Cloud Visionを使ってみた](https://www.itbook.info/web/2016/11/google-cloud-vision%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%9F.html)

### やっていたこと
そもそも、何をしていたかというと、Cloud Vison APIをたたいて取得したresponse結果をpickle.dumpでファイル出力していました。
したら、先頭に「�X~」など変な文字は入るし、末尾には「q.」が入って困っていました。
そのため、出力したファイルをjson.loadができなかった。
※pickle.loadはできていた

```python

response = requests.post(ENDPOINT_URL
   ,data=json.dumps({"requests": img_requests}).encode()
                             ,params={'key': api_key}
                             ,headers={'Content-Type': 'application/json'})
        
result = json.dumps(response.json()['responses'], ensure_ascii=False, indent=4)
print(result)
f = open("./output.json", 'wb')
pickle.dump(result, f)
```    
### 解決
以下のように処理を変えたら、json.loadで読み込める形で出力できた。


```python

f = open("./output.json", 'wb')
f.write(result.encode("UTF-8"))
``` 

</br>
</br>
</br>

これ、書いてて思って、以下で試してみたけれど、
最初の問題と変わらず。理解不足。わかったら追記したい。
バイナリ形式だったからとか？なんにせよ、調査。

```python

f = open("./output.json", 'wb')
f.write(result.encode("UTF-8"))
``` 

以上。
Ruby / Rails資料

## Rails関連の情報源

### Railsガイド
* [Action Controller の概要](https://railsguides.jp/action_controller_overview.html)
* [レイアウトとレンダリング](https://railsguides.jp/layouts_and_rendering.html)
* [Rails のルーティング](https://railsguides.jp/routing.html)
* [Active Record マイグレーション](https://railsguides.jp/active_record_migrations.html)
JavaでABNF書いてメールアドレスのぱーす

プログラム中でメールアドレスのパースは難しいとか言われているのでABNFのフル機能のほんものを実装してみた。
いろいろ詰め込んだ結果、JSONやJSON Pointer、JSON Patchまで簡単に実装できる。

IETFのRFCではABNFがよく使われている。メールだったりJSONなんかが有名で、IPアドレスやURLの書き方までABNFだったりする。
その割にあまり一般的なツールやライブラリとして出回っているのは数えるほどしかみたことないのでさっくりと作ってみた。

構造はParserを拡張してびるだー的なものを作って、びるだーでテキストからオブジェクトに変換するだけ。
ABNF自体もABNFで書かれているが、これは最初なのでビルダーだけで作る。
JSONなども書式を指定すればパーサができるので出力されるパーツを組み上げるビルダー的なところを組み込めばできあがり。

SoftLibRFC にRFCの一部ABNFをまとめているのでそれを使ってみるところの紹介。
必要なのは、SoftLibRFC,SoftLibABNF,SoftLib の3つ。SoftLibJSONは使わない。
現状ソースコードのみなので各自適度に使ってみたら。

net.siisise.abnf.rfc.IMF5322 というクラスがRFCのメールのABNFでRFC 5322ほぼそのまま。
IMF5322.angleAddr くらいがメールアドレスのみの定義にちょうどいいかな。
定義はREG という変数に格納されているのでpublicにしてないのはそこから取ってきてもいいしpublicにしてもいい。

```
boolean b = IMF5322.REG.ref("angle-addr").eq(メールアドレス);
```

くらいでbooleanな判定ができるかな。
個別のABNFはABNFクラス。
boolean eq(String) 完全一致 やboolean is(String) 先頭一致といったメソッドがあるのでお試しください。
Packet というクラスとあわせると、いろいろできるのだけど今回は省略。
ABNF同士をかけあわせて大きくしていくことができる。

まとめて使うには

ABNFReg に名前をつけて登録できるし、定義の中で参照も可能。
.rule(name,ABNF)と.rule(name,rule) .rule(rule) はどれもABNFの登録。
.ref(String)や.href(String)は名前で登録したABNFを持ってくる。
登録順序の関係が前後することがあるので登録していないものを取ってくるかこないかの違いがある。
.rulelist(String)で複数定義の一括登録も可能。改行が必要かもしれない。

拡張していくといつのまにかJSONも乗っかるので不思議。

SoftLibRFC
https://github.com/okomeki/SoftLibRFC
SoftLibABNF
https://github.com/okomeki/SoftLibABNF
SoftLib
https://github.com/okomeki/SoftLib
RFC 5234 ABNF
https://tools.ietf.org/html/rfc5234
RFC 8259 JSON
https://tools.ietf.org/html/rfc8259
【Rails】リロードしないとJavaScriptが動かない！【簡単に解決】

#はじめに
以前`jQuery`を使ってタブメニューの切り替えを実装したときに、
ビューを開いた__初回__は非同期で切り替わるのに、
別のページに移動したり
「戻る」ボタンを押したあと再びタブメニュー画面に戻ると、、、、

動かない、、、！なぜだ、、！

なんて経験をして1日無駄にしたことがあります。
__jQueryやビュー画面のコードは間違ってないはず！なぜ！__って人向けの記事です。

#解決方法①

各`link_to`ごとに`turbolinks`とやらを無効にすればOKです。簡単です。

```erb

<%= link_to "ホーム", root_path, data: {"turbolinks" => false} %>
```
`data: {“turbolinks" => false}`は遷移先ページのみ`turbolinks`を切ることが出来ます。

※`turbolinks`とは、ページ遷移を`Ajax`に置き換え、`JavaScript`や`CSS`のパース(解析・変換)を省略することで高速化する`gem`で、`Rails4`からはデフォルトで使用されています。↓


```gem
gem 'turbolinks', '~> 5'
```

#解決方法②
`js`ファイルに`"turbolinks:load"`を記述すればOKです。簡単です。

```javascript

document.addEventListener("turbolinks:load", function() {
  // ...
})
```

#まとめ

`turbolinks`を無効化する方法として、__`gem`ファイルから直接削除__する方法もあるようですが、
元々`turbolinks`はページの読み込みを__高速化するgem__です。

ボタンを押すたびに画面が初期化され、
一旦真っさらになった後、再度`js`やら`css`を読み直す。。。待ってられません。

その辺の処理を`Turbolinks5`が全部やってくれているんです。

なるべく
__①個別のページ（link_toごと）に無効にするか、__
__②jsファイルにコードを加えるだけにしましょう。__

参考
https://qiita.com/suzy1031/items/d3a8e96fe4d31111d22e
sklearn準拠モデル作成をしてGridSearchCVを行いたい時にハマったこと

ちょこっと詰まったことのメモ

自作するクラスの\_\_init\_\_()において、
引数とインスタンス変数の名前を揃えないとエラーが出ちゃいます.
例えば、以下のような歪みのあるコイン投げで二値分類を行うようなsklearn準拠モデルを作成した時、self.p = thetaみたいな感じで引数とインスタンス変数の名前を揃えないと以下のようなエラーが出ます.

```python

from sklearn.base import BaseEstimator, ClassifierMixin
from sklearn.model_selection import GridSearchCV
import numpy as np


class MyClassifer(BaseEstimator, ClassifierMixin):    
    def __init__(self, theta=0.5):
        self.p = theta
         
    def fit(self, X, y):
        return self
        
    def predict(self, X):
        return np.random.binomial(size=X.shape[0], n=1, p=self.p)
    
    def score(self, X, y):
        return (sum(self.predict(X)==y)/len(y))
    
X = np.random.normal(0, 1, (100, 10))
y = np.ones(X.shape[0])

params = {'theta':list(np.arange(0,1.1,0.1))}

model = MyClassifer()
gridsearch = GridSearchCV(model, params, cv=3, verbose=0)
gridsearch.fit(X,y)

print("best theta:{}".format(gridsearch.best_params_))
print("score:{}".format(gridsearch.score(X,y)))
```

```python
<ipython-input-9-e4c006ec5090> in predict(self, X)
     12 
     13     def predict(self, X):
---> 14         return np.random.binomial(size=X.shape[0], n=1, p=self.p)
     15 
     16     def score(self, X, y):

mtrand.pyx in mtrand.RandomState.binomial()

TypeError: must be real number, not NoneType
```

確認すると、

```python

model = MyClassifer(theta=0.7)
print("score:{}".format(model.score(X,y)))
print("theta:{}".format(model.get_params()))
```

```

score:0.77
theta:{'theta': None}
```
thetaがnoneになってますね。

ちゃんと揃えてあげて実行すると、ラベルを全て1としているのでtheta=1がGridSearchの結果正しく確定されています

```python
from sklearn.base import BaseEstimator, ClassifierMixin
from sklearn.model_selection import GridSearchCV
import numpy as np


class MyClassifer(BaseEstimator, ClassifierMixin):    
    def __init__(self, theta=0.5):
        self.theta = theta
         
    def fit(self, X, y):
        return self
        
    def predict(self, X):
        return np.random.binomial(size=X.shape[0], n=1, p=self.theta)
    
    def score(self, X, y):
        return (sum(self.predict(X)==y)/len(y))
    
X = np.random.normal(0, 1, (100, 10))
y = np.ones(X.shape[0])

params = {'theta':list(np.arange(0,1.1,0.1))}

model = MyClassifer()
gridsearch = GridSearchCV(model, params, cv=3, verbose=0)
gridsearch.fit(X,y)

print("best theta:{}".format(gridsearch.best_params_))
print("score:{}".format(gridsearch.score(X,y)))
```

```
best theta:{'theta': 1.0}
score:1.0
```

sklearn準拠モデルを作成するときは、BaseEstimatorを継承しますが、[document](https://scikit-learn.org/stable/modules/generated/sklearn.base.BaseEstimator.html)または[ソースコード](https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/model_selection/_search.py)に以下のことが書かれています。

```
All estimators should specify all the parameters that can be set at the class level in their ``__init__`` as explicit keyword arguments (no ``*args`` or ``**kwargs``).
```

上記プラス引数とインスタンス変数の名前を揃えることに気をつける
【レコメンド】内容ベースフィルタリングと協調フィルタリング

# レコメンドシステムについて

レコメンドシステムとは、利⽤者にとって有⽤と思われる対象，情報，または商品などを選び出し，
それを利⽤者の⽬的に合わせた形で提⽰するシステムです。近年ではAmazonをはじめとする多くのwebサービスで実装されており、多くの人になじみのあるものとなってきました。

Amazonなどでは複雑なアルゴリズムを複数組み合わせてレコメンドシステムを構築しているようですが、今回はレコメンドを行うにあたり基礎となる**内容ベースフィルタリング**と**協調フィルタリング**についてまとめます。



# 内容ベースフィルタリング

あるユーザーが購⼊した商品のタグ情報から、類似の商品を探し推薦する方式です。
ユーザーが購入した商品のタグ情報を基に、ユーザーがどのような分野に興味があるのかを蓄積し、類似の商品を探して提案します。

![slide1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573779/f299f92a-8a78-dadd-2520-88d21202a8ce.png)


この方式ではタグ情報を基に様々なレコメンドを行える一方、**レコメンドしたい商品には必ずタグ付けを行なわなければならない**というデメリットがあります。例えば上画像にある「入門Python3」は、商品登録時にタグ「#python」を付けたために、別のPython関係の書籍が販売されたの後にレコメンドされます。タグ「#python」がなければレコメンドされることはありません。
また、そもそもとしてタグ「#python」が適切かどうかも考えなくてはなりません。ユーザーの趣向を考慮したうえで**緻密なマーケティングを行いタグを設計する**必要があります。
そのため内容ベースフィルタリングは時間およびコストがかかってしまうという特性があります。


# 協調フィルタリング

ユーザーの⾏動履歴等を元に、**購⼊パターンの近いユーザーを探し出して商品をレコメンド**します。この際、アイテムの性質、タグ情報などは全く考慮しないという特徴があります。

![slide2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573779/e55d6f89-a9bc-b923-187c-2e02f2b0bde2.png)

上画像では、まず各商品にはタグがついていません。DBにも各ユーザーが過去に何の商品を買ったかの情報を記録します。そしてユーザーごとの購入履歴から類似性の高いユーザーを選びます。(例では類似ユーザーは一人だけ選ばれるものとする)
結果として、Aさんと購入趣向が近いDさんが過去に購入した商品がAさんにレコメンドされます。ユーザーの購入履歴を軸にするため、各商品のタグ情報は不要となります。

しかし協調フィルタリングでは、誰にも購入されていない商品はレコメンドされることがないといった大きなデメリットがあります。


# ハイブリッドフィルタリング
内容ベースフィルタリング、協調フィルタリング、実用するにはそれぞれ大きなデメリットを有しています。そのためシステム構築の際には、各フィルタリングの良いところを組み合わせてレコメンドシステムを構築してくことが一般的であり、これらはハイブリッドと呼ばれます。
クラスとインスタンスについて

クラスは属性、メソッドを定義する場所
インスタンスはクラスに基づいた実態を作成する


流れ
クラスの生成 

```ruby
class クラス名(頭文字は大文字)
end
```

クラスメソッドを定義する
定義

```ruby
class クラス名(頭文字は大文字)
 def self.メソッド名
 end
end
```

呼び出し

```ruby
クラス名(頭文字は大文字).メソッド名（引数）
```

インスタンスの生成　newメソッドをつかう

```ruby
変数 = クラス名(頭文字は大文字).new
```
インスタンスメソッドの生成
※インスタンス定義のクラス内で生成する必要

```ruby

def メソッド名
end
```
呼び出し
インスタンス.メソッド名

クラス変数
クラス内であればどこでも使用できる変数。クラスメソッド、インスタンスメソッドどちらでも使用できる
定義
クラスの定義内で定義する

```ruby
class クラス名
    @@クラス変数
  end
```
インスタンス変数
インスタンス内で使用できる変数。インスタンスメソッドの中でのインスタンス変数(@が付いた変数)の値は、そのインスタンスメソッドを利用したインスタンスが持つインスタンス変数の値になる
定義

```ruby
def インスタンス名
  @インスタンス変数 = gets.chomp
end
```

クラス変数はクラスで共通の変数となる
インスタンス変数はインスタンス内で共通の変数となる



initializeメソッド
インスタンスメソッドが生成されたと同時に実行されるインスタンスメソッド

```ruby
def initialize
  変数の定義など
end
```
【Swift5】Gmail API を使って取得したBase64のメール本文をデコードする方法

基本は[こちらのJavaで書かれた方法](https://qiita.com/hsn/items/5779fc8b41d4aecaeb83)と同じことがしたいわけだが、Gmail API ではメール本文がBase64という形式にエンコードされて返ってくる。これががURL-Safeな形式になっている関係でデコードに苦戦したのでメモ。

##Gmail API での Get の方法
公式リファレンスは下記。https://developers.google.com/gmail/api/v1/reference/users/messages/get
実際に`Try it now`でどういう値が返ってくるのかを試すことができる。

このヘッダーパラメーター？として付与できる`format`がデフォルトでは`full`なのだが、`raw`の場合に取得できるメール本文（正確には`raw`の中にある本文に該当する部分）と違い、URL-Safeな形式に変換されたBase64の文字列が返ってくる。

具体的には「+」→「-」、「/」→「_」、「=」→削除という風に変換された形式でしか取得できない。これを最終的にUTF-8の文字列にしたいので、いろんなメソッドを使って変換するのに苦労した。

##デコードの流れ
- Gmailから返ってくるのはString型のエンコードされた本文
- 一度URL-UnsafeなBase64のData型にする
- それをStringに戻す（これで`format: raw`の場合と同じ文字列が取得できる）
- 再度Data型にする
- UTF-8でStringにする

```swift

func decodeParts(_ parts: [[String: Any]]) -> [String: String]? {
        var decodedParts: [String: String] = [:]
        
        for part in parts {
            guard let partId = part["partId"] as? String,
                let body = part["body"] as? [String: Any],
                let bodydata = body["data"] as? String else {
                    return nil
            }
            
            guard let urlUnsafebase64Data = GTLRDecodeWebSafeBase64(bodydata) else {
                return nil
            }
            
            let base64EncodedString = urlUnsafebase64Data.base64EncodedString(options: .lineLength64Characters)
            
            guard let base64Data = Data(base64Encoded: base64EncodedString, options: .ignoreUnknownCharacters) else {
                return nil
            }
            guard let utf8DecodedString = String(data: base64Data, encoding: .utf8) else {
                return nil
            }
            decodedParts["\(partId)"] = utf8DecodedString
        }
        return decodedParts
    }
```
Swiftは久々に書くのでコードがキレイでなかったり無駄が多いと思う。神な方からのコメントや編集リクエスト待ってます。

Base64→UTF-8の変換は以下のWebサービスが使いやすいです。
https://www.base64decode.org/

もしこの記事が役に立ったら、いいねしてくれると喜びます。

## 参考リンク
https://qiita.com/myam314/items/e852a46ea7f9bfcdb163
ECRへdockerイメージをプッシュする

# 前提
- AWSCLIのプロファイルに設定しているロールにECRへのプッシュ権限が付与されていること


# プッシュ手順
1. 既存のdockerイメージをプッシュ対象のECRのリポジトリ名でタグ付けする

    ```
    docker tag [イメージ名]:[タグ] ************.dkr.ecr.[リージョン名].amazonaws.com/[イメージ名]:[タグ]
    ```

1. ECRにログインする

    ```
    aws ecr get-login --region [リージョン名] --profile [プロファイル名] --no-include-email
    ```

1.  ログイン時に出力されたコマンドをそのまま実行する

    ```
    docker login -u AWS -p ....
    ```

1. プッシュが成功する

    ```
    docker push ************.dkr.ecr.ap-northeast-1.amazonaws.com/[イメージ名]:[タグ]
    The push refers to repository [************.dkr.ecr.ap-northeast-1.amazonaws.com/[イメージ名]:[タグ]
    2fa8ef43ad02: Pushed
    86b4af74de0a: Pushed
    22eb95f4fc93: Pushed
    994608ddeff8: Pushed
    9b45b652ddec: Pushed
    bab15691846d: Pushed
    0981bda35722: Pushed
    7c936d88235a: Pushed
    6a0acc9d77fd: Pushed 
    1f3fe4130dc5: Pushed 
    03901b4a2ea8: Pushed 
    latest: digest: sha256:2b8dc8ea58fea30fb7be0d7f1bf6182f07336e4191887dc503f26af440211238 size: 2617
    ```
新規Railsプロジェクト作成手順(Rails 6)

# 目的
Ruby on Rails 6，MySQL，RSpecを用いた環境を構築し，サーバーを起動してエラーなく最初のページが表示されるようにする．

# 開発環境
MacOS High Sierra 10.13.6
Ruby 2.7.0
Ruby on Rails 6.0.2.1

# 前提
1. rbenv,Rubyのインストール
2. MySQLのダウンロード
3. rbenvへのbundleインストール(下記)

```
$ rbenv exec gem install bundler
$ rbenv rehash
```

# 手順
1. プロジェクトを作成したいディレクトリに移動
2. Railsインストール
3. 上記のRailsを元にrails new
4. Railsプロジェクトのセットアップ

# 1. プロジェクトを作成したいディレクトリに移動
```
$ mkdir projects
$ cd projects
```

# 2. Railsインストール
1. Gemfile作成
2. Gemfile書き換え(もちろんvimをはじめとしたエディタで編集してもおk)
3. Railsインストール

```
$ bundle init
$ cat << EOS > Gemfile
source "http://rubygems.org"
gem "rails", "6.0.2.1"
EOS
$ bundle install
#指定したバージョンのRailsがインストールされていることを確認
$ bundle list
```
`bundle install`に`--path vendor/bundle`をつけるかどうか論議が発生しますが，基本的には付けなくて大丈夫とのこと．
またBundler2.1においては`--path`オプションをつけると警告が出ます．それを回避するためには以下のようにしてbundlerの設定を変更する方がベターですが，この設定を行わなくても基本的にはおkです．

```
$ bundle config set --local path 'vendor/bundle'
```

ちなみに自分は以前pathを指定しておりその名残でvendor/bundleにbundle_pathが通っているため，以下ではbundle execを頭につけてrailsコマンドを実行しますが，そうでない方は単純にrailsコマンドを入力していただければいいかと．


# 3. 上記のRailsを元にrails new
```
# alias設定
$ alias be='bundle exec'
$ be rails new app_name -B -d mysql --skip-test
```

rails newの際にオプションをつけることでMySQLおよびRSpecのためのプロジェクトであることを示しています．
`-B`は`--skip-bundle`と同義であり，先のbundle installにおいて`vendor/bundle`へのパス指定を行わなかった場合は必要ないと思われます．

# 4. Railsプロジェクトのセットアップ

残念ながらこれだとRails6で標準のwebpackerがインストールされていないため，サーバーを起動してもエラーが起こります．なのでこれを解決するために以下．

```
$ brew install yarn
$ be rails webpacker:install
```

yarnは一度インストールしておけば問題ないですが，webpackerは`(be) rails new`してプロジェクトを新規作成するたびにする必要があります．

次にRSpecをgemに追加．もちろんプロジェクト内のGemfileに対して．

```
group :development, :test do
  (省略)
  gem 'rspec-rails'
end
```

毎度おなじみbundle install．

```
$ bundle install
```

`bundle install`が作成したプロジェクト内の`vendor/bundle`に対して行われた場合には，そのディレクトリをgitで扱わないようにするために以下を追加します．

```
$ echo '/vendor/bundle' >> .gitignore
```

そして最後にデータベースを生成し，サーバーを起動します．

```
$ be rails db:create
$ be rails s
```

これでエラーなくサーバーが起動されるはず．

# ※ ローカルにRailsをインストールした場合
2でローカルのvendor/bundleにbundle installした場合，Gemfileやvendor/bundleを消すのがいいかと．
新しいプロジェクト作成するたびに溜まっていってしまうので．

```
$ rm -f Gemfile
$ rm -f Gemfile.lock
$ rm -rf .bundle
$ rm -rf vendor/bundle
```

# 最後に
ようやく環境が整ったのでゴリゴリポートフォリオ作っていきたいと思います．

# 追記

Rails 6で環境整えたはいいものの，やはりまだ情報が出回ってないということで初心者のうちはRails5でポートフォリオ作ることにします．
現場の環境としてもまだまだ5系が多いというお話もお聞きしますし．
Aureliaの環境構築メモ

## Aureliaってなに
知らないよー昨日飲み会で布教されたばっかりだもん（白目
取り合えずは、現存色々あるReactやVueと違って**あまり主張のないframework**っていう地位を築いているようでした。

その発想自体は個人的にどストライクだー( ͡° ͜ʖ ͡°)
とおもって、早速いじってみようとおもいry。。。

なんと、日本ではまだあまり布教されていない＆２０１５年の記事多すぎわロタだったので最新の記事はほとんど英語のものばかりですた！！！（しかも出てきた記事のトップが昨日飲んだ方の愛のこもったmidiumだった笑）

ということで、一旦あれですね・・・。

最新の環境構築方法だけ載せておくね！！！！！笑


## 環境

```shell
$ npm -v
6.13.7

$ yarn -v
1.17.3
```

## 構築順序

### 1.Aureliaのコマンドを使えるようにする
まずはAureliaのコマンドを入れないとお戯れできないので、早速入れていきましょう

```shell
$ npm install -g aurelia-cli
```

以下を叩いてバージョンが出ればOK

```shell
$ npm au -v
6.13.7
```

### 2.Aureliaをインストール
`au`が使えるようになったら、Aureliaをインストールしたい階層まで移動して、以下を叩きます

```shell
$ npx au new
```

「YOU、プロジェクト名何にしたいの？」って聞かれてます。
任意の名前入れましょう

```shell
Please enter a name for your new project: aurelia-app
```

「どんな感じで開発する？」って聞かれてます。
個人的趣味で今回はtypeScriptを使う選択をしました。

```shell

Would you like to use the default setup or customize your choices?

Default TypeScript App
```

### 3.Aureliaを起動
早速起動してみませう
インストールしたファイル配下に移動し、以下を叩きましょう

```shell
$ yarn au run --open
```

ブラウザが開き、以下が表示されたら成功。
地味だなぁ・・・。
ロゴくらいは入れて欲しいお気持ちだった。
<img width="532" alt="スクリーンショット 2020-02-15 17.21.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130133/5362ec49-07e3-2a31-3172-1a488c76e58a.png">


## まとめ
英語アレルギーだから環境構築だけで満足した。
もし興味がある方はいじってみてくださいーーーーー！
[Rails]ransackを使わずに検索機能の実装

## 実装すること
投稿(Item)のタイトル(title)の検索

## モデルの作成

```
$ rails g model Item title:string
$ rails db:migrate
```
## ルーティングの作成

```config/routes.rb
Rails.application.routes.draw do

    get "search" => "items#search", as: 'search'

end
```

## Itemコントローラーの作成・編集

```
$ rails g controller items
```

```app/controllers/items_controller.rb
class ItemsController < ApplicationController

    def search
	    #itemのtitleを曖昧検索
      	@items = Item.where('items.title LIKE(?)', "%#{params[:search]}%").order(created_at: :desc)
      	#フォームに入力した内容を取ってくる
      	@search_result = "#{params[:search]}"
    end
end
```

## ビューの編集
### 投稿一覧
検索フォームはパーシャルにします。

```app/views/items/index.html

<div class="search">
    <%= render 'items/search_form' %>
</div>
```

### 検索フォーム

```app/views/items/_search_form.html

<%= form_tag(users_search_path, :method => 'get') do %>
    <%= text_field_tag :search, params[:search], class: "form-control", id: "search_area", placeholder: "タイトルを入力"%>
    <%= submit_tag '検索' %>
<% end %>

```

### 検索結果

```app/views/items/search.html

<h2>タイトル"<%= @search_result %>"の検索結果(<%= @items.count %>件)</h2>
<% @items.each do |item| %>
    <%= item.title %>
<% end %>
```

## 最後に
最後までご覧いただきありがとうございます。
初学者ですので間違っていたり、分かりづらい部分もあるかと思います。
何かお気付きの点がございましたら、お気軽にコメントいただけると幸いです。

## 参考
gemを使わずに検索機能を作ろう！複数テーブルの検索にも対応可能！
https://qiita.com/chain_saw_man/items/07faf8fed3224c1dccfb
Ruby on Rails 検索機能拡張 (railsチュートリアル)
https://qiita.com/mochikichi321/items/5c9630c5d87b47130942
Ubuntu で最新の Ruby をインストールする方法

<font color="#ff8080">※ 2022/06/25: インストール手順を一部変更。記事全体を修整。</font>

※ Ubuntu 以外の環境でも同様の方法でインストールできる場合がありますが、より説明を抽象化しないといけなくなるため、本記事では Ubuntu 用として書いています。

# 1. 既に `apt` や RVM でインストールされている場合は一度アンインストール

本記事では `apt` や RVM 以外の手段でインストールするため、既に `apt` や RVM でインストールされている場合は一度アンインストールします。

```bash:apt の場合の Ruby アンインストール
sudo apt purge ruby rbenv ruby-build
rm -rf ~/.rbenv
```

※ RVM の場合の Ruby アンインストールは本記事では略。

# 2. インストール

Ruby のインストール方法は複数ありますが、本記事では `rbenv` と `ruby-build` を `git clone` して `rbenv install` します (`apt` は使いません) 。

(必要な他ツールのインストールは `apt` を使っても大丈夫です。)

```bash:Ruby のインストールに必要なツールをインストール
sudo apt update
sudo apt install gcc make
sudo apt install libssl-dev zlib1g-dev
```

```bash:Ruby をインストール
git clone --depth 1 https://github.com/rbenv/rbenv.git ~/.rbenv

# rbenv の高速化
cd ~/.rbenv && src/configure && make -C src

# .bashrc や .bash_profile 等に以下の記述を追加
# 
# export PATH="$HOME/.rbenv/bin:$PATH"
# eval "$(rbenv init - bash)"
# 
# source ~/.bashrc 等で再読み込み

git clone --depth 1 https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build

# インストール可能な Ruby のバージョンを確認
rbenv install -l

# バージョンを指定して Ruby をインストール
# ここではバージョン 3.1.2
rbenv install 3.1.2

# バージョン切り替え
# ここではバージョン 3.1.2
rbenv global 3.1.2

# source ~/.bashrc 等で再読み込み
```

※ libssl-dev のバージョンによってインストールに失敗する場合があります。場合によって対処法が異なるので、本記事では具体的な対処法は略。"The Ruby openssl extension was not compiled." 等で調べてください。

参考「[GitHub - rbenv/rbenv: Manage your app's Ruby environment](https://github.com/rbenv/rbenv)」
参考「[GitHub - rbenv/ruby-build: Compile and install Ruby](https://github.com/rbenv/ruby-build)」

# 3. 説明

## 3.1. `sudo apt install` を使わない

`sudo apt install` すると最新版の Ruby にできず、また、`/usr/bin` 以下にインストールされるため、`gem` 等を使用する際も毎回 `sudo` が必要になります。
`sudo` なしで `gem` を使用し、かつ Ruby を最新版にしたいなら、`sudo apt install` は使えません。

(必要な他ツールのインストールは `apt` を使っても大丈夫です。)

参考「[GitHub - rbenv/rbenv: Manage your app's Ruby environment](https://github.com/rbenv/rbenv)」

## 3.2. `git clone` する

`rbenv` と `ruby-build` に関しても `sudo apt install` だと最新にできない可能性があるため、`git clone` を用いてインストールします。

## 3.3. RVM でなく rbenv を使用する

場合によるかもしれませんが、本記事では RVM でなく rbenv を使用して Ruby をインストールします。

理由は下記の参考記事を参照。

参考「[Why rbenv? · rbenv/rbenv Wiki · GitHub](https://github.com/rbenv/rbenv/wiki/Why-rbenv%3F)」

## 3.4. rbenv の高速化

下記の参考記事を参照。

参考「[GitHub - rbenv/rbenv: Manage your app's Ruby environment](https://github.com/rbenv/rbenv)」

## 3.5. その他の Ruby インストール方法

下記の参考記事を参照。

参考「[Installing Ruby](https://www.ruby-lang.org/en/documentation/installation/)」

## 3.6. インストール時間に関して

個人的な記憶では、以前はインストールにかなり長い時間がかかっていた気がするのですが、現在確認するとそこそこの時間でインストールできました。

以下の条件が異なっているためかもしれません:

- 旧環境:
    - ストレージは HDD
    - Windows Subsystem for Linux (WSL。おそらくバージョン 1)
    - Ubuntu 16.04
    - Ruby 2.7.0
    - rbenv 高速化なし
- 新環境: 
    - ストレージは SSD
    - Windows Subsystem for Linux (WSL) 2
    - Ubuntu 22.04
    - Ruby 3.1.2
    - rbenv 高速化あり
MacでのBLEデバッグツールを調べてみる (2020年2月版)


Mi Band 4にBLEアクセス出来ないかを調べていて、MacでのBLEデバッグのツールをいくつか試したのでまとめてみます。

ちなみにmacOS Catalina(mac book pro 2019)です。

## Light Blue

一番よく使ってましたが......

* [Light Blue](https://apps.apple.com/jp/app/lightblue/id639944780?mt=12)

> ![](https://i.gyazo.com/b214b12bb08e6cd0524bd8944aaf2e26.png)

現在は公開されていない模様です。

> ![](https://i.gyazo.com/271fe69ffa74ea2994ef2dc3e91c678a.png)

残念orz

[iPhoneアプリ版](https://apps.apple.com/jp/app/lightblue/id557428110)は健在です。

## BlueSee

[BlueSee BLE Debugger](https://apps.apple.com/us/app/bluesee-ble-debugger/id1336679524?mt=12)というものを使ってみました。

> ![](https://i.gyazo.com/9075213daffaa2f4c1c818da940bb41e.png)

## Bluetooth Explorer

Appleの公式ツールです。

Xcodeが無いと使えないみたいな噂がありましたが、Xcode無しでも使えました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">xcode無しでいけました！</p>&mdash; 菅原のびすけ (@n0bisuke) <a href="https://twitter.com/n0bisuke/status/1228567956067479552?ref_src=twsrc%5Etfw">February 15, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

こちらのApple Developersのページからダウンロードできます。

> https://developer.apple.com/download/more/?=additional%20Tools

> ![スクリーンショット 2020-02-15 15.29.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/31746819-7edb-477e-4806-379a0f387e6e.png "スクリーンショット 2020-02-15 15.29.35.png")

`Additional Tools (for Xcode11が現時点最新)`というツール群の中に同梱されてました。

> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/f1815352-0bd8-e635-d861-04e744ffa388.png" width="200px">

> ![スクリーンショット 2020-02-15 15.29.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/f4daa260-ff72-ae61-920b-e632132ca789.png "スクリーンショット 2020-02-15 15.29.41.png")

* Low Energy Devices

機能ありすぎて分からなくなりそうですが、`Devices > Low Energy Devices`を開くと使えます。

> ![スクリーンショット 2020-02-15 15.45.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/2096dae6-d5d5-efc6-8782-78842e5eb695.png "スクリーンショット 2020-02-15 15.45.07.png")

## Bluetility

https://github.com/jnross/Bluetility/releases

> Bluetility is inspired by LightBlue, a free bluetooth utility published by Punch Through Design. Bluetility was created to resolve issues in this tool, and add missing features:

って書いてるのでLightBlueにインスパイアされてるツールのようです。

> ![](https://i.gyazo.com/a2723c9efb67d4c58e9088de86663cae.png)

少し触ってみましたがシンプルに確認したいだけの時には良いかもしれません。

## 所感

前に使っていたLight Blueがすごく良かったので、その代替になるツールを探すような感じでしたね。

全体的にちょっと触っただけですが、BleeSeeが良さげかなぁという印象です。
Bluetooth Explorerと並行して使ってみて絞ってみたいと思います。

そもそもはMi Band 4を試したいモチベで調べてた内容なので、こっちについてもそのうちまとめます。 ちなみにMi Band 4はiPhoneとのリコネクトが強いので、試すときはiPhoneのBluetoothをオフにしてたりします。 iPhone版のBLEデバッグツールはこの使い方だと使えないんですよね...

> ![](https://i.gyazo.com/be6c533fc7cbf7cc2a7563acbb42ab8f.jpg)
> 参考: https://speakerdeck.com/n0bisuke/sok-mi-band-4wojavascriptde-number-iotlt-vol60-at-docs
Amazon EBSのマルチアタッチ機能とAzure Shared Disksを比較してみる

## はじめに
米国時間の 2020/2/13 に Azure Shared Disksのプレビューが、
2020/2/14 に Amazon EBS のマルチアタッチ機能がそれぞれ発表されました。
これまで[OCI](https://blogs.oracle.com/cloud-infrastructure/announcing-multiple-instance-attachment-of-shareable-readwrite-block-volumes)以外のパブリッククラウドでは提供されていなかった
ブロックストレージを共有ディスクとして接続可能になる機能です。

**Announcing the preview of Azure Shared Disks for clustered applications**
https://azure.microsoft.com/en-us/blog/announcing-the-preview-of-azure-shared-disks-for-clustered-applications/

**New – Multi-Attach for Provisioned IOPS (io1) Amazon EBS Volumes**
https://aws.amazon.com/jp/blogs/aws/new-multi-attach-for-provisioned-iops-io1-amazon-ebs-volumes/

## 機能や制限等の対応
それぞれ特徴がありそうでしたので、各ドキュメントを参照し記載しました。
2020/2/15時点の情報です。

||Amazon EBS Multi-Attach|Azure Shared Disks|
|---|---|---|
|リリースステータス|2020/2/14～ 一般利用可能|2020/7/16~ 一般利用可能|
|対応リージョン|バージニア北部/オレゴン/アイルランド/ソウル|米国中西部|
|対応ボリュームタイプ|Provisioned IOPS SSD(io1)|Premium SSD P15(256GB)以上|
|配置制限|同一AZ内|[近接通信配置グループ](https://azure.microsoft.com/ja-jp/blog/introducing-proximity-placement-groups/)内|
|接続可能な最大インスタンス数|16|10(P60以上)|
|I/Oフェンシング|未対応|SCSI PR|
|ブートボリュームとして使えるか|×|×|
|バックアップ|スナップショットを取得可能|Azure Backup/Site Recoveryは未対応|
|ボリューム作成後の変更|不可|maxShares値を変更可能|
|追加料金|無し|追加のマウントは、ディスクサイズに基づいて課金|

## 参考
**Attaching a Volume to Multiple Instances with Amazon EBS Multi-Attach**
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volumes-multi.html
https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ebs-volumes-multi.html

**Azure shared disks**
https://docs.microsoft.com/ja-jp/azure/virtual-machines/linux/disks-shared
**Enable shared disk**
https://docs.microsoft.com/ja-jp/azure/virtual-machines/linux/disks-shared-enable
Windows 10 でどこいったかよくわからないフォルダメモ

別に変わってないやつもいますが現在の場所ということで。

### SendTo (送る)

エクスプローラーのパス欄に sendto って打てば出てくる
(`%USERPROFILE%\AppData\Roaming\Microsoft\Windows\SendTo`)

### スタートアップ

sendto から１つ上 (`Alt+↑`) にいって `スタートメニュー` -> `プログラム` -> `スタートアップ`
(`%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup`)

### Taskbar (Quick Launch)

sendto から２つ上にいって `Internet Explorer` -> `Quick Launch` -> `User Pinned` -> `TaskBar`

(`%USERPROFILE%\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned`)

タスクバーにピン留めした cmd.exe の作業フォルダを変更する時などに使う。

### おまけ：コントロール パネル

エクスプローラーに `コントロール パネル` (**半角スペース注意**) って打てば出てくる。後はピン留めなりすれば良い。
JavaScriptの継承について確認

# 概要
昔、勉強したが、知識が曖昧になってきているので再度調べてみる。
( Backbone.jsの学習時に登場したため... )

## サンプルコード
JavaScriptの継承を行ったサンプルを作ってみる。

```html:./src/html/extend.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>JavaScriptの継承について</title>
</head>
<body>
    <h1>prototypeを使った継承</h1>
    <p>オブジェクトを継承してみる。</p>

    <script>
      // Animalオブジェクト
      function Animal(name) {
        this.name = name;
      }
      Animal.prototype.talk = function() {
        console.log(this.phrase);
      };

      // Animal2オブジェクト (static変数あり)
      var Animal2 = (function() {
        var uid = 0;
        return function () {
          this.uid = uid;
          uid++;
        };
      })();

      // -------------------------------------------------------------------
      // オブジェクトの継承

      (function() {
        // Dogオブジェクト (Animalを継承する)
        function Dog(phrase) {
          this.constructor('Dog');
          this.phrase = phrase;
        }
        Dog.prototype = new Animal(); // prototype, constructorのコピー (talk関数)
        var myDog = new Dog('Hello World.');
        myDog.talk();            // → Hello World.
        console.log(myDog);      // → Dog {name: "Dog", phrase: "Hello World."}
      })();

      (function() {
        // Dog2オブジェクト (Animal2を継承する)
        function Dog2() {
          this.constructor();
        }
        Dog2.prototype = new Animal2(); // prototype, constructorのコピー (talk関数)
        console.log('dog2(1)', new Dog2()); // dog2(1) Dog2 {uid: 1}
        console.log('dog2(2)', new Dog2()); // dog2(2) Dog2 {uid: 2}
        console.log('dog2(3)', new Dog2()); // dog2(3) Dog2 {uid: 3}
      })();

      // -------------------------------------------------------------------
      // Object.createメソッド

      (function() {
        function Dog (phrase) {
          Animal.call(this, 'Dog');
          this.phrase = phrase;
        }
        Dog.prototype = Object.create(Animal.prototype);
        Dog.prototype.constructor = Dog;

        var myDog = new Dog('Hello World.');
        myDog.talk();            // → Hello World.
        console.log(myDog);      // → Dog {name: "Dog", phrase: "Hello World."}
      })();

      (function() {
        // Dog2オブジェクト (Animal2を継承する)
        function Dog2() {
          Animal2.call(this);
        }
        Dog2.prototype = new Animal2();
        console.log('dog2(1)', new Dog2()); // dog2(1) Dog2 {uid: 4}
        console.log('dog2(2)', new Dog2()); // dog2(2) Dog2 {uid: 5}
        console.log('dog2(3)', new Dog2()); // dog2(3) Dog2 {uid: 6}
      })();
      // -------------------------------------------------------------------
    </script>
</body>
</html>
```

## 動作確認
どちらの方法でも継承できているようです。
※ chromeでの確認
![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142279/aeff6aca-cff8-2450-687c-ffc1880c064f.png)

## まとめ
古い内容になり、現在では書くことがほとんどないと思いますが、動きを確認するため、書いてみました。

## 参考サイト
- [入門Backbone.js](https://www.shoeisha.co.jp/book/detail/9784798140018)
- [Github Gist - y-yu/inherit](https://gist.github.com/y-yu/3301790)
『これからはじめるVue.js実践入門』の正誤表など


jQueryからのステップアップとして『基礎から学ぶVue.js』で挫折。『これからはじめるVue.js実践入門』が分かりやすそうだったので、再チャレンジ中。ただ、おかしな点がいくつか出てくるので、その度に追記していく。

## 対象書籍
『これからはじめるVue.js実践入門』初版第1刷

## 正誤表など
- 45～47ページ
  - _.debounceメソッドは、「遅延」関数ではなく、「抑制」関数、または「間引き」関数と呼ぶほうが正しい。遅延では実行のタイミングを遅らせるだけで必ず実行されてしまう。 
- 49ページ
  - 上部のソースコード内の、thisをthatに退避するコードは、蛇足。おかげでthisについて深く知ることができたけれど。
- 77ページ
  - サンプルコード誤り。thisをthatなどに退避させていないため、テンプレートに反映されず、図3-20のようにはならない。正しいサンプルコード「model_file.js」は下記の通り。

```js
new Vue({
  el: '#app',
  data: {
    message: ''
  },
  methods: {
    onchange: function() {
      let fl = this.$refs.upfile.files[0];
      let data = new FormData();
      let that = this;
      data.append('upfile', fl, fl.name);
      fetch('upload.php', {
        method: 'POST',
        body: data,
      })
      .then(function (response) {
        return response.text();
      })
      .then(function (text) {
        that.message = text;
      })
      .catch(function (error) {
        alert('Error: ' + error.message);
      });
    }
  }
});
```

- 77ページ
  - Note「ref属性の意味」の「id、name、class属性を利用するということは、コードの側がテンプレートの構造を把握していなければならない」というのは、おかしい。id属性はそのページでユニークなのでテンプレートの構造を把握する必要がない。
- 93～100ページ
  - サンプルHTML誤り。table要素直下にth要素を配置するのはHTML5の構文エラー。
- 113ページ
  - `<p v-html="message"></p>`はHTML5の構文エラーになる恐れがあるため、`<div v-html="message"></div>`が正しい。
- 114ページ
  - Note「テンプレート文字列」の右の「ES20XX」は「ES2015」の誤り。
Devise ログインボタン押せない

# 問題
ログインボタン押せない
リロードするとログインボタンを押せるようになる

# 解決方法

```ruby:Gemfile
gem 'turbolinks', '~> 5'
```
を

```ruby:Gemfile
# gem 'turbolinks', '~> 5'
```
コメントアウトするとうまく行きます。

bundle updateでコメントアウトを反映させましょう

```terminal:ターミナル
$ bundle update
```

```js:app/assets/javascripts/application.js
//= require turbolinks
# ↑これも消しましょう
```
【AWS】EC2 apacheにファイルをアップロードする方法&エラーが発生した時の対処



#apacheにアップロード方法

teratermの左上のファイルを押して、SSH SCRを選択

1.fromにアップロードしたいファイル
2.Toに../../var/www/html
3.Sendを押す

![apache.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543413/1b2ddc03-1bf0-eaaa-95dc-9238069e94cb.png)


#フォルダ

ご自身のターミナルから下記コマンドを実行してください。
※EC2にsshでログインした先のターミナルで行うのではありません。

```
//実行場所
C:\Users\TOSHI\Desktop

//アップロードコマンド
scp -r -i C:\Users\ユーザー\Desktop\ssh2.pem test ec2-user@18.222.213.115:/var/www/html


```

##解説
C:\Users\ユーザー\Desktop\ssh2.pemは.pemまでのパス
ssh2.pemの後のtestはアップロードしたいフォルダ名です。

末尾のvar/www/htmlはアップロード先のパス


#パーミッションエラーの対処法
アップロードする際にパーミッション関係のエラーが出た人は下記の問題です。

>いろいろ、調べると接続してる「ec2-user」には書き込む権利がないようで、
やり方もいろいろあるようですが、 ファイルを操作するディレクトリ配下すべての
所有者をログインしてるアカウントにしてしまうとうというのが簡単そうなので
これをやることに。
>
引用：WASのEC2でSFTPは繋がったけどフィル操作ができない・・・ORZ
https://irodory.jp/web/server/104


ということで、さっそくターミナルにて下記実行

```
chown -R ec2-user /var/www/html
```

その後アップロードできました。
【railチュートリアル】AWS S3のパブリックアクセスの設定方法【2020年最新】

rails チュートリアルで作成したアプリに画像アップロード機能をつける際にハマったのでメモ。


S3のパブリックアクセスの設定に関して最新の記事がなかったので書きます。

heroku上にアップロードしたアプリの画像投稿ができない。

![スクリーンショット 2020-02-15 16.41.0741.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568461/6b888af5-db47-3ec6-7057-391463f40fa7.png)
↑この場所からファイルを選択し、文字を入力してアップロードするとheroku特有のlogを見ろ的なエラーが出ました。

## 原因
S3のパブリックアクセス設定を変更する


## 解決法

### 設定したS3バケット名をクリックし、「パブリックアクセス設定を編集する」をクリックする。
<img width="1432" alt="スクリーンショット 2020-02-15 16.34.4034.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568461/2f3883fe-9b3b-1dfd-f292-a6b3bf6e444d.png">

### 「アクセス権限」→「ブロックパブリックアクセス」にとび、5つのチェック全てをオフにして設定ほ保存する。
<img width="1405" alt="スクリーンショット 2020-02-15 16.33.5133.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568461/93301a4e-fc31-8df1-cf3b-9a812b856e84.png">


### 再びherokuにデプロイする

```
$ git add -A
```
```
$ git commit -m"S3の設定を保存"
```
```
$ git push
```
```
$ git push heroku
```

これで本番環境で画像投稿機能を使うことができます。