OmniAICreator/Qiita-1.07M huggingface dataset:
[Angular] (Tips) Angularのroutingを使わずにUrlだけ書き換える

## Angularのroutingを変えずにurlだけを変えたいと場合

#### すごく特殊ですが、以下の理由でangular上のルーティングは変えず(遷移させず)にURLだけ変更したい、ということがありました。

- 2種類のpathから1つのページ(コンポーネント群)を呼び出したい。 (path違いでコンポーネントの状態 `true/false` が変わる)
- httpリクエストでデータ取得処理をコンポーネントの初期化時に実行している
- ページ遷移後に、path(状態)の行き来をしたい
- リロードした際に同じ状態で再現して欲しい


#### ここでいう `2種類のpathから1つのページ(コンポーネント群)を呼び出したい。`というのはこういうことです。

```typescript:routing.ts
// HOGEでもFUGAでも HogeIndexPageComponentへ
const routes: SsRoute[] = [
  // hoge
  {
    path: HOGE.path,
    component: HogeIndexPageComponent,
    data: HOGE.data,
  },
  // fuga
  {
    path: FUGA.path,
    component: HogeIndexPageComponent,
    data: FUGA.data,
  },
];

export const routing = RouterModule.forChild(routes);
```


## このとき、状態を変更する際に `router.navigate`から遷移させると(ngOnInitなどのライフサイクルが再度回るのでhttpへのget処理などが無駄に)発生する

```typescript
// 通常の遷移処理
const url: string = 'fuga';
this.router.navigate([url], {replaceUrl: true});
// fugaのルーティングとして、構成コンポーネント群のライフサイクルが1から回る

```


---


## ということで今回とった方法として、Angularに知られずにurlを変える場合(非推奨)は `history.replaceState` を使う

```typescript
const url: string = 'fuga';
history.replaceState('', '', url);
// urlは変わるがライフサイクルはまわらない

```

もしかしたらangularの中にも既存でそういうrouterオプションがあるのかもしれませんが...探しきれませんでした。
日報ファイルをコピーするshellscriptを書いた

日報をMarkdownで書いています。

手作業でコピー・編集していた作業があったのですが、shellscriptを書いて自動化しました。

## スクリプト

機能はこんな感じです。

* 日報ファイルをコピーして今日の日付でファイルを生成します
  * すでに今日のファイルがある場合はコピーしません
* コピーしたファイルのパスを出力します
* 一行目を今日の日付で上書き
* Markdownの完了タスクを消します


（shellscriptあまり書き慣れていないのでツッコミ歓迎しています。）

```bash:copy-daily-report.sh
#!/bin/bash -eu

# 前日に書いた日報ファイルをコピー

# * 日報ファイルをコピーして今日の日付でファイルを生成します
#   * すでに今日のファイルがある場合はコピーしません
# * コピーしたファイルのパスを出力します

memoDir="$HOME/Documents/memo/_posts"
dailyReportSuffix="-daily-report.md"
weekTexts=(日 月 火 水 木 金 土)
week=${weekTexts[`date +%w`]}
todayText=`date "+# %Y/%m/%d ($week)"`

cd $memoDir
newestDailyReport=`ls -t *$dailyReportSuffix | head -1`
todayDailyReport=`date +%Y-%m-%d$dailyReportSuffix`

function echoDailyReportPath () {
  echo $memoDir/$todayDailyReport
}

if [ $newestDailyReport = $todayDailyReport ]; then
  echoDailyReportPath
  exit 0
fi

cp $newestDailyReport $todayDailyReport
# * 一行目を今日の日付で上書き
sed -i '' -e "1s|^.*$|$todayText|" $todayDailyReport
# * Markdownの完了タスクを消す
sed -i '' -e "/^ *[-+*] \[[xX]\].*/d" $todayDailyReport

echoDailyReportPath
exit 0
```

これをpathが通っている場所に置きます。

### 例

フォーマットはこんな感じで書いています。

```md:2019-02-02-daily-report.md
# 2019/02/02 (土)

## TODO

* [ ] hoge
* [X] fuga
  * [x] piyo
* [x] 123
* [ ] aaa
  * [ ] bbb

## memo

* あああああ
```

実行するとこのようなファイルを生成します。

```md:2019-02-03-daily-report.md
# 2019/02/03 (日)

## TODO

* [ ] hoge
* [ ] aaa
  * [ ] bbb

## memo

* あああああ
```

### 応用

コピーしたファイルのパスを出力するので、そのままエディターで開くことができます。


```
# fishにてVSCodeで開く例
code (copy-daily-report.sh)
```
【JS】三角関数を使用した回転アニメーション

回転するアニメーションに挑戦してみました。

◾️Demo
[回転アニメーション](http://practice.back.jp/js/animation/rotate/simple01.html)

## 処理の内容
- div.box.box0○の自動挿入。
- 三角関数を用い、座標を取得後回転させる。


```html:simple01.html
    <div id="boxArea"></div>
```

```html:simple01.pug
    #boxArea
```

```javascript:simple01.js

// ----- アニメーション実行 ----- //
  for (let i = 1; i < 6; i++) {

    const boxWrap = document.getElementById('boxArea'); // 追加したい要素の親要素を取得
    const createBox = document.createElement('div'); // divの作成
    createBox.classList.add('box', 'box0'+i); // divにクラスを付与
    boxWrap.appendChild(createBox); // div.boxの追加

    // 動作の対象
    const box = document.querySelector('.box0' + i);

    // 角度の設定
    let degree = 0;

    // 動作対象の各縦横幅取得
    const boxWid = box.clientWidth; //　横幅
    const boxHei = box.clientHeight; // 縦幅
    const boxWidHalf = boxWid / 2;
    const boxHeiHalf = boxHei / 2;

    // ループ
    loop();

    function loop() {

      // 回転させたい角度
      const rotation = (degree * Math.PI) / 180;

      // 回転位置
      const targetX = window.innerWidth / 2 + boxWid * Math.cos(rotation) - boxWidHalf;
      const targetY = window.innerHeight / 2 + boxHei * Math.sin(rotation) - boxHeiHalf;

      // stykeの付与
      box.style.left = `${targetX}px`;
      box.style.top = `${targetY}px`;

      // 増加させる角度（値の増減で回転スピード調整）
      degree -= 2;

      // 次の画面更新した際にLoop()を実行
      requestAnimationFrame(loop);
    }
  }
```

本当はなんとかトレインみたくしてみたかったのですが、タイムアップにより断念。
あとは、地球の周りを何か走らせたりしてみたかったですので、今後の課題ににします。
ASUS MB168B+ を Linux Mint (ubuntu) で利用する

ASUS MB168B+ は数年前に発売されたモバイル用のUSBディスプレイです。接続にはドライバが必要な製品になっていますが電源とディスプレイをUSBのみで賄うことができます。（今であれば Type-cの製品が欲しくなりますね）

* https://www.asus.com/jp/Commercial-Monitors/MB168BPlus/


# 環境

* Linux papa 4.18.0-13-generic #14~18.04.1-Ubuntu SMP Thu Dec 6 14:09:52 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

# インストール方法

```
git clone https://github.com/AdnanHodzic/displaylink-debian.git
cd displaylink-debian/ && sudo ./displaylink-debian.sh
```

ウィンドウマネージャの「画面」の設定をで確認できます。このあたりはWindowsやMacos同様のユーザビリティがありますね。使い方は普段どおりという感じです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/11540/471e1672-73cb-9ab0-bffd-7fe4a80a24a4.png)


# 補足

* 結構電力の消費が多いのか私の手持ちのノートブックでは特定のポート以外では電源が供給できませんでした。
* 画面の縦（これは回転せずに縦になり下が切れた）や180はうまく動作しませんでした。
* 速度としては普通に利用する分には最低限の速度が出ているように思えます。
Angular[メモ] ActivatedRouteで現在のpathを取得

#### angularで`ActivatedRoute` のメモ。

## すぐに値が欲しい場合は `snapshot` からとる。

`ActivatedRoute`で取れる値の型(下記)を見てみると、一部をのぞいて返り値が `Observable` です。(つまり非同期)

なので、コンポーネントの初期化のタイミングで1度だけ、何か値を取ってきて判定させたいようなときには基本、`snapshot`を使うことになりそうです。

(コンポーネントは変わらずにルーティングが変わる可能性のある場合(ヘッダーなどの共通コンポーネントなど)はsnapshotではなく、各Obervableを `subscribe` した方が良さそう)


```typescript:router_state.d.ts
export declare class ActivatedRoute {
    /** An observable of the URL segments matched by this route */
    url: Observable<UrlSegment[]>;
    /** An observable of the matrix parameters scoped to this route */
    params: Observable<Params>;
    /** An observable of the query parameters shared by all the routes */
    queryParams: Observable<Params>;
    /** An observable of the URL fragment shared by all the routes */
    fragment: Observable<string>;
    /** An observable of the static and resolved data of this route. */
    data: Observable<Data>;
    /** The outlet name of the route. It's a constant */
    outlet: string;
    /** The component of the route. It's a constant */
    component: Type<any> | string | null;
    /** The current snapshot of this route */
    snapshot: ActivatedRouteSnapshot;
    /** The configuration used to match this route */
    readonly routeConfig: Route | null;
    /** The root of the router state */
    readonly root: ActivatedRoute;
    /** The parent of this route in the router state tree */
    readonly parent: ActivatedRoute | null;
    /** The first child of this route in the router state tree */
    readonly firstChild: ActivatedRoute | null;
    /** The children of this route in the router state tree */
    readonly children: ActivatedRoute[];
    /** The path from the root of the router state tree to this route */
    readonly pathFromRoot: ActivatedRoute[];
    readonly paramMap: Observable<ParamMap>;
    readonly queryParamMap: Observable<ParamMap>;
    toString(): string;
}
```

## Componentの初期化のタイミングでパスパラメーターを取ってくるとき
```typescript
// --------------------------------------
// idというpath paramをとって判定する
constructor(private activatedRoute: ActivatedRoute){
}

ngOninit(){
 const { snapshot } = this.activatedRoute;
// snapshotを参照する
 if (!snapshot.params.id) {
     // idがなかった場合の処理
     // console.log('id is none);
    } else {
    // idがあった場合の処理
    console.log(snapshot.params.id);  
    }
}
```

## 現在のルーティングのpathを取得する

```typescript
import * as _ from 'lodash';

// activatedRouteからpath(配列)を取り出す
const path:string[] =  _.map(this.activatedRoute.snapshot.pathFromRoot, (ars: ActivatedRouteSnapshot) => {
 if (_.isNil(ars.url) || _.isEmpty(ars.url)) {
  return null;
 }
 return (_.first(ars.url) as UrlSegment).path as string;
}).filter(val => val);

// localhost:8080/hoge/fugaの場合
// console.log(path);  // -> [ 'hoge','fuga'] 
```
AWS開発中に機能が追加されていく。。最新情報のチェック方法は？

仕事でAWS関連の設計・開発作業を行っているのですが、こんなことがありました。

開発中に最新機能がリリースされました。
そして、一週間後に気が付いて、あ、これ使える。。
ほんと、たまたま、気づきました。
そこで最新情報のチェック方法を整理しようと思います。

## 最新情報がのっているページ
https://aws.amazon.com/jp/new/

とりあえず、毎日「AWSからの最新のお知らせ」だけ、ちらみする。

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/350277/797d3a52-d491-48be-382e-f0acb46fcfe5.png)

↓↓↓
ただし、まぁ見るの忘れてしまうし、最新情報がないときにページを開くのも不毛かな。

## メールでお知らせしてもらうようにする
先ほどと同じページの一番上です。

リリースノート、ニュースレターを購読する。を選択
![レター2.png](https://qiita-image-store.s3.amazonaws.com/0/350277/bb73a45c-f727-c951-3ff1-10f72132207c.png)

ここでメールアドレスを登録
![De.PNG](https://qiita-image-store.s3.amazonaws.com/0/350277/b533adcc-1e2d-8273-bc5a-3c65f6724a0c.png)

↓↓↓
現在、私はここでメールアドレスを登録した状態です。
まだ、一通もメールが来ていないので、
メールが来たら最新情報ページの内容が届いているか見比べてみようと思います。

## 追加（コンテナのロードマップ）
https://github.com/aws/containers-roadmap/projects/1

このようなものもあるのですね～。
![rd.PNG](https://qiita-image-store.s3.amazonaws.com/0/350277/48976a08-45b1-eb08-b547-5186563f330d.png)
AR.jsでHTMLを表示する

# はじめに

AR.jsでHTMLを表示する方法について書きました。

## やりたいこと

HTMLで書いた内容をAR.jsでARとして表示したい。

## 完成図

<img width="375" alt="IMG_2722.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/199332/6ea9fb1d-38be-570d-4b64-140fec9d1c71.png">

# 実装

## どうやって表示するか

まず、HTMLの内容をどうやって表示するかですが、これにはHTML Shaderという、DOM要素をマテリアルとしてA-Frameのオブジェクト上に貼り付けることができるコンポーネントを使います。

まず、head内で必要なコンポーネントを読み込みます。HTML Shaderにはhtml2canvasが必要らしいので、それも読み込みます。

```html:index.html
<script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script>
<script src="https://cdn.rawgit.com/jeromeetienne/AR.js/1.6.2/aframe/build/aframe-ar.js"></script>
<script src="https://unpkg.com/aframe-html-shader@0.2.0/dist/aframe-html-shader.min.js"></script>
<script src="http://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
```

次に、a-scene要素の前に表示したい内容をHTMLで書きます。ここでは単純にtestと書いてあるだけですが、当然日本語や画像も入れることができます。

```html:index.html
<div id="test">
    <h3>test</h3>
</div>
```

次に、HTMLを貼り付けるオブジェクトを用意します。`material="shader:html;target: #test;"`と指定することで先程のdiv要素をマテリアルとして貼り付けています。

```html:index.html
<a-plane width="1" height="1" rotation="-90 0 0" material="shader:html; target: #test"></a-plane>
```

これで良さそうですが、このままではdiv要素がAR画面の上に来てしまうのでCSSでz-indexを指定して裏に隠します。

```css:style.css
#test {
    height: 200px;
    width: 200px;
    z-index: -50;
    background-color: #FFF;
}
```
ここで問題があり、HTML Shaderの特性上このままでは全体的にぼやけてしまいます。そこで、もとのHTML要素を大きめにすることではっきり見えるようにします。

```css:style.css
#test {
    height: 1000px;
    width: 1000px;
    z-index: -50;
    background-color: #FFF;
    font-size: 500%;
}
```

完成したHTMLはこちらです。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
		<script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script>
		<script src="https://cdn.rawgit.com/jeromeetienne/AR.js/1.6.2/aframe/build/aframe-ar.js"></script>
		<script src="https://unpkg.com/aframe-html-shader@0.2.0/dist/aframe-html-shader.min.js"></script>
		<script src="http://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
		<link rel="stylesheet" href="style/style.css">
    </head>
    <body>
        <div id="test">
            <h3>test</h3>
        </div>

        <a-scene embedded arjs='debugUIEnabled:false;' vr-mode-ui="enabled: false">
            <a-marker preset="hiro">
				<a-plane width="1" height="1" rotation="-90 0 0" material="shader:html; target: #test"></a-plane>
			</a-marker>
			<a-entity camera></a-entity>
		</a-scene>
    </body>
</html>
```

[デモページ](https://quizzical-pasteur-aadf25.netlify.com/)
<img src=https://qiita-image-store.s3.amazonaws.com/0/199332/68855c5b-5384-5905-3839-ac48acfcbdcb.png width=300px>

マーカー
<img src=https://qiita-image-store.s3.amazonaws.com/0/199332/ede09173-497a-25e1-f932-c48d2dbfd16c.png width=400px>
ドライブレターを変える方法

# はじめに

Windows環境では「Cドライブ」や「Dドライブ」など、ドライブにアルファベットの文字が割り当てられていますが、このアルファベットの文字をドライブレターと呼びます。
業務用アプリの都合などで、どうしてもドライブレターを変更しなければならないシーンがある時は、以下のように「コマンド」と「GUI」の2通りの方法でドライブレターを変更することができます。

# コマンドで変更する方法

## diskpartコマンドの実行

* コマンドプロンプトを開き、"diskpart"コマンドを実行します。

```text:dos
C:\>diskpart
```

## diskpart.exeを使ったドライブレターの変更

* diskpartコマンドを実行して開いたウィンドウ（C:\WINDOWS\system32\diskpart.exe）で、以下の手順でドライブレターを変更します。
 1. "list volume"と入力して、ボリュームの一覧を表示します。
 2. "select volume=0"と入力して、volume0（Dドライブ）を選択状態にします。
 3. "assign letter=X"と入力して、volume0（Dドライブ）をXドライブに変更します。
 4. 最後に再び"list volume"と入力して、ドライブ名が変更されたことを確認します。

```text:diskpart
DISKPART> list volume

  Volume ###  Ltr Label        Fs    Type        Size     Status     Info
  ----------  --- -----------  ----  ----------  -------  ---------  --------
  Volume 0     D                NTFS   Partition    465 GB  正常
  Volume 1         WinRE Tools  NTFS   Partition    500 MB  正常
  Volume 2         Recovery     NTFS   Partition     15 GB  正常
  Volume 3     C   Windows      NTFS   Partition    216 GB  正常         ブート
  Volume 4         SYSTEM       FAT32  Partition    100 MB  正常         システム

DISKPART> select volume=0

ボリューム 0 が選択されました。

DISKPART> assign letter=X

DiskPart はドライブ文字またはマウント ポイントを正常に割り当てました。

DISKPART> list volume

  Volume ###  Ltr Label        Fs    Type        Size     Status     Info
  ----------  --- -----------  ----  ----------  -------  ---------  --------
* Volume 0     X                NTFS   Partition    465 GB  正常
  Volume 1         WinRE Tools  NTFS   Partition    500 MB  正常
  Volume 2         Recovery     NTFS   Partition     15 GB  正常
  Volume 3     C   Windows      NTFS   Partition    216 GB  正常         ブート
  Volume 4         SYSTEM       FAT32  Partition    100 MB  正常         システム
```

# GUIで変更する方法

1. ［コントロールパネル］から［管理ツール］へ進み、［コンピュータの管理］を開く。
4. ［コンピュータの管理］画面で［ディスクの管理］を選択する。
5. ドライブレターを変更したいボリュームを右クリックして、［ドライブ名とパスの変更］を選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/7d1ec097-3a2b-e82b-712c-538c984c204d.png)
6. ［ドライブ名とパスの変更］画面で［変更］ボタンを押して、［次のドライブ文字を割り当てる］という項目で、任意のドライブレターを選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/237129a3-f684-0af6-eae2-f46259344e03.png)
micro:bitとScratch3.0がつながらない時に確認して欲しいこと


2019年1月Scratchが3.0にバージョンアップしたことによりmicro:bitとScratchを簡単に連携させられるようになりました。

しかし、ある条件を満たす場合ドはまりすることが判明しています(2019年2月3日現在)

■まったく初めて連携する場合
問題ありません。
下記ページのガイドに従ってください。
Scratch LinkというソフトウェアをPC/MACに入れた後、専用のHEXファイルをmicro:bitに入れる流れです。
https://scratch.mit.edu/microbit


■以前一度Scratch Linkをインストールしたことがある場合
残念ながらドはまりする可能性があります。
上記ページで最新版をダウンロードしてインストールしようとしても
”最新版が入っているからインストールはキャンセルするね！”とメッセージが出てインストールがキャンセルされます。


⇒対応策「旧Scratch Linkを手動で先にアンインストールする」だけです。最新版がインストールされ、平和に連携を楽しむことができます。
PHP Laravel ログイン実装

#PHP Laravel ログイン実装
今回はサーバ側にも手を出そうと思い、PHPフレームワークのLaravelというのを使用して、ログイン機能を実装してみました。
※実に簡単でした。。。(Laravel便利ですね)

##環境
Ubuntu 18.04.1(AWS)
PHP 7.2.14
Laravel 5.7
Mysql 5.7.25

##前提
本記事ではPHP、Laravelのインストールは既に終わっている程で話を進めますので、もしまだインストールが終わっていない場合は別記事などで終わらせてください。

##Laravelプロジェクトの作成
ターミナルで下記を打ち込みます。
```laravel new loginProject
```

もしこれでできない場合は下記を試してください。
```composer create-project --prefer-dist laravel/laravel blog
```

色々とファイルとディレクトリが作られますが、とりあえずはおいといてください。
(僕もあまり全貌を理解してはいません....)

##Auth作成
ターミナルで下記を打ち込みます。
```php artisan make:auth
```

これはauthというライブラリ？のようなものが自動的にログインに必要なもの(登録、ログイン、リマインダーなど)を作成してくれるコマンドになります。
違ってたらすいません。。。

```php artisan migrate
```

##DB設定
プロジェクト直下の.envというファイルを開いてください。
下記の[]内の部分を変更してください。

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=[your database name]
DB_USERNAME=[your mysql username(etc root)]
DB_PASSWORD=[your username's password]

##SMTP設定
DB設定の中の.envというファイルで、下記の[]内の部分を変更してください。
今回はgmailを使用しました。

MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=465
MAIL_FROM_ADDRESS=[your gmail address]
MAIL_FROM_NAME=[your name]
MAIL_USERNAME=[your gmail address]
MAIL_PASSWORD=[your gmail password]
MAIL_ENCRYPTION=SSL

※GithubなどにPushする場合は、この.envファイルというのはPushしてはいけません。

##サーバ起動
ターミナルで下記を打ち込みます。
```php artisan serve
```

下記にアクセスして登録、ログイン、リマインダーが動いていれば成功です。
http://localhost:8000

##AWSの場合
AWSなどでグローバルIPを使用している場合はリマインダーのパスワード再設定のリンクがひらけないかもしれません。
これはURLにlocalhostが代入されているからなので、.evnファイルを開いて下記の[]部分を変更しましょう。

APP_URL=[your ip address or DNS(etc http://gmail.com)]

以上です。
まだ始めたばっかでわからないことが多いので、もし間違っていたらご指定頂けると幸いです。
Openshift Origin (OKD)のAll-in-One Serverをインストールしてみた

# はじめに
OKD(以前はOpenShift Originと呼ばれていたもの)のAll-in-One ServerをmacOSで動かしているVirtualBox上の仮想マシン(CentOS7)にインストールしてみました。

# 前提条件
- ホストマシン：macOS
- 仮想環境：VirtualBox 6.0
- ゲストマシン：CentOS 7.6.1810
- OKD：v3.11.0-0cbc58b

# ゲストマシンの最新化と必要パッケージのインストール
　細かい手順は省略しますが、こんな感じ

    $ yum update
    $ yum install docker

# バイナリのダウンロードしてゲストマシン内の適当な場所に展開
　ダウンロード先：https://www.okd.io/download.html
　検証したバージョン：v3.11.0-0cbc58b-linux-64bit.tar.gz

# 設定ファイルの修正
　基本的な作業はGitHubで公開されているドキュメントを参考にすると良いでしょう。
　https://github.com/openshift/origin/blob/v4.0.0-alpha.0/docs/cluster_up_down.md

- /etc/containers/registries.conf

　このファイルを修正

    [registries.insecure]
    registries = ['172.30.0.0/16']

- /etc/docker/daemon.json

  このファイルを修正

    {
        "insecure-registries": [
        "172.30.0.0/16"
        ]
    }

# SE LinuxとFirewallの停止
　作業する際、問題の切り分けを簡単にするため、いくつかの機能を止めました。

  - SE Linuxをdisabled
  - Firewalldをstop

# クラスタの起動
　ホストマシンからアクセスできるようにNATの設定をVirtualBoxにしています。
　ホストマシンからはlocalhost:8443でアクセスしたいため、オプションで追加しています。

    $ oc cluster up --public-hostname="localhost" --base-dir="/opt/okd" --no-proxy="localhost" --routing-suffix="localhost"

# ホストマシンからアクセス

  https://localhost:8443/console
  アクセスするとログイン画面が表示されます。
　ログインユーザ名、パスワードは`oc cluster up`コマンドの出力の最後に表示されます。

<img width="960" alt="okd_webconsole.png" src="https://qiita-image-store.s3.amazonaws.com/0/184483/b128ed2b-2c26-d733-c31f-2a334ca77568.png">

ただ、現在、ログイン後にError表示が出ます。おそらくNAT関連で上手くいっていないところがありそうです。あと一歩。

<img width="960" alt="okd_webconsole_error.png" src="https://qiita-image-store.s3.amazonaws.com/0/184483/d2d8901e-4483-8160-1afd-d4df425761eb.png">


ゲストマシン<->ゲストマシン間ではOKでした。
ゲストマシン<->ゲストマシンで通信させる際は、`oc cluster up --public-hostname="localhost" ...`のlocalhost部分をゲストマシンのIPに変更してください。
ViewModelから画面を閉じる処理

# ViewModelから画面を閉じる処理

画面を閉じる処理を通して処理の追加方法の例を示します。
見やすいよう一部省略や改行位置を変更しています。

## Action

View側の画面を閉じる処理。

```c#
using Prism.Interactivity.InteractionRequest;
using System.Windows;
using System.Windows.Interactivity;

namespace Sample.ViewUtilities {
    public class CloseWindowAction : TriggerAction<DependencyObject> {
        protected override void Invoke(object parameter) {
            if (parameter is InteractionRequestedEventArgs e) {
                Invoke(AssociatedObject, e);
            }
        }

        private void Invoke(DependencyObject sender,
            InteractionRequestedEventArgs e) {
            if (sender is Window window) {
                window.Close();
                e.Callback?.Invoke();
            }
        }
    }
}
```

## ViewModel

Viewに画面を閉じる処理を指示。

```c#
public InteractionRequest<Notification> CloseWindowRequest { get; private set; }
public DelegateCommand CloseWindowCommand { get; private set; }

public SampleWindowViewModel() {
    CloseWindowRequest = new InteractionRequest<Notification>();
    CloseWindowCommand = new DelegateCommand(ExecuteCloseWindowCommand,
        CanExecuteCloseWindowCommand);
}

private bool CanExecuteCloseWindowCommand() {
    return true;
}

private void ExecuteCloseWindowCommand() {
    CloseWindowRequest.Raise(null);
}
```

## XAML

```xml
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:prism="http://www.codeplex.com/prism"
xmlns:ViewUtilities="clr-namespace:Sample.ViewUtilities"
・・・
<i:Interaction.Triggers>
  <prism:InteractionRequestTrigger
    SourceObject="{Binding CloseWindowRequest}">
    <ViewUtilities:CloseWindowAction/>
  </prism:InteractionRequestTrigger>
</i:Interaction.Triggers>
・・・
<Window.InputBindings>
  <KeyBinding Modifiers="Ctrl" Key="W"
    Command="{Binding CloseWindowCommand, Mode=OneWay}"/>
</Window.InputBindings>
・・・
<Menu>
  <MenuItem Header="ファイル(_F)">
    <MenuItem Header="閉じる(_X)"
      Command="{Binding CloseWindowCommand, Mode=OneWay}"/>
  </MenuItem>
</Menu>
```
Android キーボードを隠す方法

#Android キーボードを隠す方法
今回はAndroid開発においてキーボードをJavaコードで隠す方法を記載します。

##簡単なのでもうコード書きますね笑
``` Java
 public static void hideKeyboard(Activity activity) {
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    View view = activity.getCurrentFocus();
    if (view == null) {
        view = new View(activity);
    }
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
```

これをUtilsクラスみたいなところに記載して、引数にActivityを渡せば完了です。
今回は登録画面などでフォーカスが離れた時にキーボードを隠す必要があったので、実装しました。
パンプキン

- [パンプキン](https://atcoder.jp/contests/jag2017summer-day1/tasks/jag2017summer_day1_k)

## 考察

- 召喚と抽出の2つの操作があって、どうすればいいのかよくわからない
- なので、最初に全てのカードを抽出した状態にする。すると、あとは召喚するかしないかだけを考えれば良くなる。
- 最初に全てのカードを抽出した状態にするので、初期状態のマナは$\sum_{i=0}^{N-1}Gi$となる。
- カードを走査する。そのカードを抽出に使用する場合は何もしない（初期状態で全てのカードを抽出用として使ったので）。
- そのカードを召喚に使用する場合、マナを$Ci$消費するので初期のマナから$Ci$が引かれる。さらに、抽出するはずだったマナを$Gi$を取り消すことになるので、初期のマナから$Gi$が引かれる。
- つまり、カード$i$を召喚するとマナは$-(Ci+Gi)$されることになる。
- よってこのゲームは、「初期状態のマナが$\sum_{i=0}^{N-1}Gi$。カードを召喚すると$-(Ci+Gi)$される。このとき、召喚できるカードは何枚か？」というゲームに落とし込むことができる。
- 召喚すると減るマナ$Ci+Gi$は小さいほうが良い。よって、$Ci+Gi$が小さい方からカードを召喚するのが最善手であることがわかる。



## 解法

1. 初期状態のマナを$\sum_{i=0}^{N-1}Gi$とする。
2. $Ci+Gi$の配列を作り、昇順にソートする
3. [0, N)の区間を捜査し、$Ci+Gi$が小さいものから召喚していく



## [コード](https://atcoder.jp/contests/jag2017summer-day1/submissions/4151549)

- インデックスの情報を使うかもしれないから`{Ci+Gi, i}`の配列にしたけど、結局インデックス使わなかったから普通の配列でもよかった

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

#define int long long

using p = pair<int, int>;

int N;
vector<int> C, G;
vector<p> A; // A[i]: {Ci+Gi, i}

signed main() {
  cin >> N;
  C.resize(N);
  G.resize(N);
  A.resize(N);

  int mana = 0;
  for (int i = 0; i < N; i++) {
    cin >> C[i] >> G[i];
    mana += G[i];
    A[i] = {C[i]+G[i], i};
  }
  sort(A.begin(), A.end());

  // ここから先がゲームしてる部分
  int ans = 0;
  for (int i = 0; i < N; i++) {
    if (A[i].first <= mana) {
      ans++;
      mana -= A[i].first;
    }
  }

  cout << ans << endl;

  return 0;
}
```



## 要点

- 初期状態を、全てのアイテムを取った状態とする。そして全て取ったアイテムのうち、どれを取り去るのかを考える
  - この考え方典型っぽい
  - そうすることで、考えることが減って簡単な問題に落とし込むことができる。



## 感想

- 典型知ってないと初見で解くのはきつそう。
- ミドリムシくん、TABくんありがとう。
- かぼちゃおいちい〜:heart:って助言、すごく役に立ちました。こうきさんありがとうございました。
【Terser】Nuxt.jsで突然ビルドエラーが発生したときの対応法

# はじめに
現在、Nuxt.jsとNetlifyを使用して個人で開発を行なっています。
その際にNetlifyでビルドを行なったときに突然エラーが発生するようになりました。
本記事では、そのときの対処法について、備忘録として記したいと思います。

# エラー内容
ビルドを行なったときに、以下のようなエラーが発生するようになりました。

```
5:39:27 PM: ERROR in 6f8075b97658f08b5126.js from Terser
5:39:27 PM: TypeError: Cannot read property 'minify' of undefined
5:39:27 PM:     at minify (/opt/build/repo/node_modules/terser-webpack-plugin/dist/minify.js:175:23)
5:39:27 PM:     at module.exports (/opt/build/repo/node_modules/terser-webpack-plugin/dist/worker.js:13:40)
5:39:27 PM:     at handle (/opt/build/repo/node_modules/worker-farm/lib/child/index.js:44:8)
5:39:27 PM:     at process.<anonymous> (/opt/build/repo/node_modules/worker-farm/lib/child/index.js:51:3)
5:39:27 PM:     at emitTwo (events.js:126:13)
5:39:27 PM:     at process.emit (events.js:214:7)
5:39:27 PM:     at emit (internal/child_process.js:762:12)
5:39:27 PM:     at _combinedTickCallback (internal/process/next_tick.js:142:11)
5:39:27 PM:     at process._tickCallback (internal/process/next_tick.js:181:9)
```

# 対処法
package.jsonに下記の記述を追記するとビルドが正常に行われるようになりました。

```json:package.json
"resolutions": {
  "terser": "3.14.1"
}
```

# 4.参考
- [Terser v3.16.0 breaks terser-webpack-plugin #66](https://github.com/webpack-contrib/terser-webpack-plugin/issues/66)
Windowsでrubyをつかう。WEBrickが立ち上がるまで

WindowsでRubyの開発を行いたいと思ったことがきっかけ
Ruby導入からRailsプロジェクトの作成、WEBrickが起動するまでのまとめ
Qiitaとか投稿したこがないけど、やってみようかな
アウトプットすることを覚える
見苦しいところが多々ありますが、ご指摘していただけるとありがだいです。m@@m

## 開発環境
* **Windows7(x64)**
* Ruby2.5.3p105 (2018-10-18 revision 65156)
* Rails5.2.2

## rubyインストール
Windows用のRubyが[ここで](https://rubyinstaller.org/downloads/)公開されてる。development kit がついている以下のものをダウンロードする

* Ruby+Devkit 2.5.3-1 (x64)

インストーラを実行すればrubyが導入される
今回はC直下にインストールv@@v

## Railsのインストール
コマンドプロンプトで以下を実行する

    gem install rails

## SQLite3の実行ファイルをダウンロード

[ここ](https://www.sqlite.org/download.html)から以下のものをダウンロードする

* Source Code
 * sqlite-amalgamation-3260000.zip・・・C直下に展開

* recompiled Binaries for Windows
 * sqlite-dll-win32-x86-3260000.zip・・・C:\Ruby25-x64\binにsqlite3.dllを投入
 * sqlite-tools-win32-x86-3260000.zip・・・C:\Ruby25-x64\binにsqlite3.exeを投入

## SQLite3のライブラリをインストール

SQLite3のソースコードと実行ファイルのディレクトリを指定しコマンドプロンプトで以下を実行


    gem install sqlite3 --platform=ruby -- --with-sqlite3-include=C:\sqlite-amalgamation-3260000 --with-sqlite3-lib=C:\Ruby25-x64\bin

※SQLite3のインストールでハマりました、以下のページを参照して脱出
　[WindowsでRailsTutorialするときに気をつけること](https://qiita.com/jun_moka/items/a83a8149bc97cedc16b5)

## Railsプロジェクトを作成
コマンドプロンプトでRailsのプロジェクトを作成したいフォルダを指定(今回はd:\app\rails)し以下を実行

    rails new プロジェクト名

d:\app\railsにプロジェクト名のフォルダが作成されている
これだけでrailsのプロジェクトができちゃうのね

## WEBrickを起動する
d:\app\rails\プロジェクト名 を指定しコマンドプロンプトで以下を実行

    rails server WEBrick

http://localhost:3000/にアクセス
WEBrickが正常に起動していれば、地球の上に立っている人々が表示される

コマンドでWEBrickを指定せず、サーバを起動させるとPumaが起動した
バージョンによってデフォルトで起動するサーバが違うのか...?

## 参考
[Ruby on Rails入門](https://www.javadrive.jp/rails/)
ここで紹介されている内容を実行しました
【R】箱ひげ図を描く方法

箱ひげ図は、複数のグループ間でデータの分布を図示して比較する方法です。
ごく基本的な作図で、t検定や分散分析（ANOVA）の結果と併せて用いられることが多いと思います。

# 解析に使うデータ

* 以下のデータは、ある山の東側（east）と西側（west）で測定した葉のサイズ（mm^2）です。

```:leaf_size.csv
east,west
4632.4,4159.1
3481,3844.4
3267.8,3135.0
3130.9,2837.2
3108,2801.2
2575.4,2587.8
4556.9,5180.1
4343.5,3635.9
4130.3,2651.1
2824,2642.7
```

# 箱ひげ図の描画

## 最も単純な箱ひげ図の描画

* 上記の"leaf_size.csv"をデータフレームとして読み込んだ場合、このデータフレームを"boxplot"関数の引数として指定するだけで箱ひげ図を描画できます。

```r:Rのコンソール
> # leaf_size.csvを読み込んで、"leaf_size"という名前のデータフレームに格納する。
> leaf_size <- read.table("C:\\leaf_size.csv", header=TRUE, encoding="CP932", sep=",")
> # 箱ひげ図の描画
> boxplot(leaf_size)
```

![boxplot_01.png](https://qiita-image-store.s3.amazonaws.com/0/312166/5ccbfe61-893d-8261-0c65-b9371a5d0a94.png)


## 軸のラベルとタイトルを指定した箱ひげ図の描画

* X軸のラベルは"xlab"パラメーター、Y軸のラベルは"ylab"パラメーターで指定できます。
* グラフのタイトルは"main"パラメーターで指定できます。

```r:Rのコンソール
> # Y軸のラベルとタイトルを指定した箱ひげ図の描画
> boxplot(leaf_size, ylab="leaf size(mm^2)", main="Leaf size in Mt.Miyatsuka")
```

![boxplot_03.png](https://qiita-image-store.s3.amazonaws.com/0/312166/2d4be722-a76c-448f-0f1e-4d66f5db0c7b.png)
Vagrant upでエラーが出て躓いた時の解決方法


#背景

VagrantとVirtualBoxを使って仮想環境を構築しようとしていたところ、Vagrant upで躓きました。
試行錯誤するうちに原因が分かり、解決できたのでその時の手順を残しておきます。（殴り書きですがお許し下さい）

#問題
Vagrant upが実行できず、仮想マシンの立ち上げが出来ない。

#エラーの内容

```
There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.

Command: ["startvm", "06d68c13-7910-4f8f-a263-e9424395d7cf", "--type", "headless"]

Stderr: VBoxManage: error: The virtual machine 'username_default_1549175601821_34118' has terminated unexpectedly during startup with exit code 1 (0x1)
VBoxManage: error: Details: code NS_ERROR_FAILURE (0x80004005), component MachineWrap, interface IMachine
```
エラーの内容としては、<b>「Vagrantが、VirtualBoxをVBoxManageを使って実行する際にエラーが発生しました。そのコマンドとstderr（標準エラー出力）は、以下の通りです」</b>といった内容です。

```
Command: ["startvm", "06d68c13-7910-4f8f-a263-e9424395d7cf", "--type", "headless"]
```

要は、startvm（=Start Virtual Machine）コマンドを実行したところ、エラーが発生したとのこと。
`06d68c13-7910-4f8f-a263-e9424395d7cf`は仮想マシンの名前です。

#原因
結論としては、<b>VirtualBoxが正しくインストールされていなかった</b>ようです。（何という致命的なミス...）

VirtualBoxをアンインストール→再インストールすれば解決するという記事がいくつかあったので、その通りに実行するも解決せず。何度か上記を繰り返しているうちにこの原因に気づきました。

![](https://i.stack.imgur.com/zwPwz.png)

#対処法
System software from〜のところをAllowにすることで正しくインストールができます。

![](https://i.stack.imgur.com/VCr9e.png)

#結果

Booting VM....で上記エラーが表示されてしまい躓いてしまいましたが、無事に仮想マシンを立ち上げることができました。

```
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
==> default: Forwarding ports...
    default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
```
PostgreSQL のデータ移送方法（テーブル単位）

# PostgreSQL　を利用したデータ移送

## はじめに

PostgreSQLを利用したデータ移送の要件がありました。
別々のDBからDBへデータ移送をするということだが、同一なのはテーブル名とカラムのみで、ユーザーやスキーマが異なる要件があり、作ってみました。


## テーブル情報を含んだ移送

・アーカイブ経由
- スキーマレベル、データベース全体を移送したい場合は、アーカイブ形式が最も簡単
- pg_restore ではテーブル単位の挿入も可能で、pg_dump で大きくバックアップを取り、pg_restoreで個別にデータ挿入が可能

**移送元と移送先のユーザ、スキーマの構成が同じ場合はこれが最も簡単**

```sh
pg_dump -Fc 
pg_restore
```
参考：[PostgresSQLのbackup, restore方法まとめ](https://qiita.com/rice_american/items/ceae28dad13c3977e3a8)

ただし、移送元と移送先のDDL構造が異なる場合、これを利用できないため、
本記事を作成。


・スクリプト経由
- pg_dump でSQLファイル（DDL/DML）が生成され、これを経由して実行
- sed コマンドで、ddlのユーザ名（1か所のみ）、スキーマ名（結構多い）の置換を実施
- sed コマンドでsearch_path を追加（DDLに記載していれば問題ないはずだが、念のため追加）

```sh
# db -> sql
pg_dump --username=user_test --table trgt_tbl--schema test -h localhost -p 5432  db_nm> trgt_tbl.sql


# dump_sql include
# if you change the owner
#--- in script 
#--- 'ALTER TABLE before_test.trgt_tbl OWNER TO before_user;' 
# sed -i-e "s/OWNER TO before_user/OWNER TO after_user/g" 

# if you change the schema 
# sed -i-e "s/before_test/after_test/g" 


# if you want to specify schema because psql does not have the property of schema
sed -i 'set search_path to test;' trgt_tbl.sql

# sql -> db
psql -h localhost -p 5432 -U test -d db_nm < trgt_tbl.sql

```
※　ただし、本件の致命的なパターンとして、移送元のユーザー名とスキーマ名が同じで、移送先のユーザー名とスキーマ名が別々の場合、置換できず、上記のツールは利用できない。
※　そのため、下記のパターンを作成


## データのみの移送

シェルで一度に実施したい場合があったので作成してみました。

〇ポイント
・コピーコマンドでCSVを経由しています。
・スキーマを考慮するために、set search_path to を指定できるようにしています。
・一時ファイルの削除処理（ローカルにファイルを配置するため、ループして利用するとディスクフルになる可能性があるため。）



```sh

set -x;

# input db info
input_db_user="test"
input_db_url="localhost"
input_db_port=5432
input_db_name="db_name"
input_db_schema="test"

# output db info
output_db_user="test"
output_db_url="localhost"
output_db_port=5432
output_db_name="db_name"
output_db_schema="test"

# target table
trgt_tbl=$1; shift

# convert data from jt-db to temp-csv
export PGPASSWORD=${input_db_user}
psql -h ${input_db_url} -p ${input_db_port} -U ${input_db_user}  -d ${input_db_name}  << EOF

set search_path to ${input_db_schema};
\COPY ${trgt_tbl} to ${trgt_tbl}.csv CSV HEADER;

EOF

# convert data from temp-csv to dev-db
export PGPASSWORD=${output_db_user};
psql -h ${output_db_url} -p ${output_db_port} -U ${output_db_user}  -d ${output_db_name}  << EOF

set search_path to ${output_db_schema};
truncate table ${trgt_tbl};
\COPY ${trgt_tbl} from ${trgt_tbl}.csv CSV HEADER;

EOF

# delete temp-csv for disk full
rm ${trgt_tbl}.csv

```
R - 個人メモ

統計ソフトRを試用開始。

たった1行で、複数列間の散布図を瞬時に描ける点に、Excelとの違いを実感。

####グラフ - 散布図

```
> data(iris)
> plot(iris[, 1:4])
```
![Iris.png](https://qiita-image-store.s3.amazonaws.com/0/189863/2cda8a77-a4c1-7f49-4054-a26e0673037a.png)


---
####ヒートマップ

```
> data(iris)
> heatmap(as.matrix(iris[, 1:4]))
```
![Heatmap.png](https://qiita-image-store.s3.amazonaws.com/0/189863/b7b2cba4-d657-0d10-760f-fd654a7cc2d0.png)


---
####確率分布
例: ガンマ分布。期間θ毎に、ランダムな事象がk回発生するまでの時間の分布。
![Gamma-Eq.png](https://qiita-image-store.s3.amazonaws.com/0/189863/faa8a93e-0559-d2e3-8594-0bfc92d97aba.png)

```
> par(ann=F)
> curve(dgamma(x, shape=1, scale=1), from=0, to=8, ylim=c(0, 1))
> par(new=T)
> curve(dgamma(x, shape=2, scale=1), from=0, to=8, ylim=c(0, 1), lty=2)
> par(new=T)
> curve(dgamma(x, shape=4, scale=1), from=0, to=8, ylim=c(0, 1), lty=3)
```
![Gamma(a124-t1).png](https://qiita-image-store.s3.amazonaws.com/0/189863/735033a2-bc8e-efe6-489b-acec75acbe1f.png)

---
####データの結合等
+ データの読み込み

```
> x <- read.table("~/test.txt", header=TRUE, sep="\t")
```


+ 列の削除

```
> data <- data[, c("Column1", "Column3")
```


+ 列名の変更

```
> colnames(data) <- c("A", "B", "C")
```


+ データの結合

```
> data <- merge(data1, data2, by="ColumnTest1", all=TRUE)
```

横(縦)に並べて結合。同じ行(列)数。

```
> data <- cbind(data1, data2)
> data <- rbind(data1, data2)
```
+ ソート

```
> idx <- order(data$Column, decreasing=T)
> data[idx, ]
```

---
####インストール
+ R: https://cran.r-project.org/
+ RStudio: https://www.rstudio.com/products/rstudio/download/
CentOS7にてユーザ・グループ作成する手順

VPSでCentOS7をレンタルした際に実施する、ユーザ手順を記載する。
一部、VPSのサービス依存の手順がある場合は、筆者が利用しているDTIのサービスを前提として記載するので注意。

# 前提
以下の名称で作成する。
実行コマンドもこの前提で記述する。

- ユーザ名：py-app
- ユーザグループ名：py-app
- sudo権限：root権限で全コマンドの実行権限を付与（＝wheelグループへの追加）

# rootユーザでSSH接続

```
web-commandernoMBP:~$ ssh root@{IPアドレス} -p 3843
root@{IPアドレス}'s password: 
[root@dos-vps-srv136 ~]# 　
```

# ユーザ追加
## ユーザ追加コマンド
user追加コマンドを実行

```
[root@dos-vps-srv136 ~]# useradd py-app
```

## ユーザへのパスワード設定コマンド
先ほどのコマンドで作成したユーザにはパスワード設定がされていません。
ですので、以下のコマンドで設定します。

```
[root@dos-vps-srv136 ~]# passwd py-app
ユーザー py-app のパスワードを変更。
新しいパスワード:
新しいパスワードを再入力してください:
passwd: すべての認証トークンが正しく更新できました。
[root@dos-vps-srv136 ~]# 
```

## ユーザとグループが作成されたことを確認
以下のコマンドで、先ほど作成したユーザを確認可能です。
※grepして、"py-app"のみを抽出しています。

```
[root@dos-vps-srv136 ~]# cat /etc/passwd |grep py-app
py-app:x:1000:1000::/home/py-app:/bin/bash
[root@dos-vps-srv136 ~]# cat /etc/group |grep py-app
py-app:x:1000:
[root@dos-vps-srv136 ~]# 
```

# 追加したユーザにsudo権限追加
## wheelユーザの定義確認
CentOSでは、/etc/sudoersにsudo権限を持ったユーザグループについて記述されています。
まず、visudoコマンドを用いて、上記ファイルの内容を確認します。

```
[root@dos-vps-srv136 ~]# visudo 
```

以下の通り、wheelユーザの定義がコメントアウトされずに生きた状態となっていれば問題ありません。

```
## Allows people in group wheel to run all commands
%wheel  ALL=(ALL)       ALL 
```

※"%wheel"始まりの行がコメントアウトされていた場合は、コメントアウトを外しておきます。

## py-appユーザをwheelグループに追加
usermodコマンドで、py-appユーザをwheelグループに所属させます。

```
[root@dos-vps-srv136 ~]# usermod -aG wheel py-app
```

## wheelグループに追加されたことを各員
以下のコマンドで確認します。

```
[root@dos-vps-srv136 ~]# groups py-app
py-app : py-app wheel 
```
VSCodeでgitのconflictを解消させる話

# 目的
今回は以下を行っていきます。

+ gitでconflictが発生する状況をちょっとだけ理解してみる
+ 実際にconflictを発生させてみる
+ 発生したconflictをVSCode上で解決してみる

※間違いや分かりにくい点は、どんどん指摘してもらえると助かります。（お手柔らかによろしくお願いします。。）

## conflictって何？？

|　![Untitled Diagram (1).png](https://qiita-image-store.s3.amazonaws.com/0/190554/82be909a-010a-d099-53d8-f96e2bb607c4.png) |
|---|

簡単にconflictの発生する可能性のある作業フローのイメージを用意しました。
以下の手順で作業していくと仮定します。
1. まず、Masterを元にしてBranch_AとBranch_Bを作成します。
2. Branch_Aで、あるファイル（ここでは、conflict.txtとしておきます。）を修正します。
   修正した分をcommitしてMasterにPullRequestを行います。
   Masterに対して変更分をマージします。
3. 次にBranch_Bでの作業に移ります。ここでもconflict.txtを修正します。（Branch_Aでの修正とは異なるようにすること）
   修正が完了したらcommitして、MasterにPullRequestを行います。

これでconflictが発生します。
つまり、複数人で開発している際に各々が別々のファイルで作業している分にはMasterに対して変更分がそのまま吸収されていきますが
同じファイルを修正していた際に、どちらの修正をMasterに反映させるか（あるいは、どちらの修正も反映させる）を判断してねと言われるのがconflictです。
conflictを日本語にすると『衝突』と言う意味になります。

## 実際にconflictを発生させてみよう！
理解できているかを判定するのに、自分の環境でも発生させてみます。

### ①Branch_Aで修正
| <img width="1280" alt="スクリーンショット_2019-02-03_16_49_02.png" src="https://qiita-image-store.s3.amazonaws.com/0/190554/db3247ed-10b0-3901-e803-705463be6636.png"> |
|---|
今回はconflict.txtに文章を追加しています。
これをcommitしてGitHub上でPullRequestをします。
今の段階ではconflictが発生しないので、そのままmergeします。

|<img width="1003" alt="スクリーンショット_2019-02-03_17_03_34.png" src="https://qiita-image-store.s3.amazonaws.com/0/190554/dca173e9-aece-5e70-6c1b-225745a8bae3.png">  |
|---|

### ②Branch_Bで修正

| <img width="1920" alt="スクリーンショット_2019-02-03_17_31_27.png" src="https://qiita-image-store.s3.amazonaws.com/0/190554/3196f33e-d12a-1cb7-8c13-4f4451be5020.png"> |
|---|

①と同様にconflict.txtに文章を追加しています。
これをcommitしてGitHub上でPullRequestをします。

| <img width="790" alt="スクリーンショット_2019-02-03_17_35_35.png" src="https://qiita-image-store.s3.amazonaws.com/0/190554/cd93de29-245b-79bd-d953-659f24655ec8.png"> |
|---|

conflictが発生しました。
ここからは、VSCode上でconflictの原因を調査していきます。

## VSCode上でconflict解消を行う
具体的には以下の手順で行います。
1. ローカルに保存してあるmasterを最新にする
2. Branch_Bに対して、masterをMergeする
3. Mergeした際にBranch_B上でconflictが発生して、VSCode上で確認できるので解消する
4. 解消した分をcommitしてPushして、MergePullRequestができるようになっていることを確認

### 1.ローカルに保存してあるMasterを最新にする
masterに移動　`git checkout master`
masterの最新を取得　`git pull`

### 2. Branch_Bに対して、masterをMergeする
Branch_Bに移動　`git checkout Branch_B`
Branch_BにmasterをMergeする　`git merge master`

### 3. Mergeした際にBranch_B上でconflictが発生して、VSCode上で確認できるので解消する

|　<img width="1920" alt="スクリーンショット_2019-02-03_17_59_45.png" src="https://qiita-image-store.s3.amazonaws.com/0/190554/21444842-4cc6-f2f4-ea22-67daac6f233f.png"> |
|---|

Accept Both Changeを選択します。

### 4. commitしてPush、MergePullRequestができるようになっていることを確認
あとは、MergePullRequestをして完了！

|<img width="822" alt="スクリーンショット_2019-02-03_18_18_28.png" src="https://qiita-image-store.s3.amazonaws.com/0/190554/bd62eefc-dc9c-2de1-5554-9f1c03341291.png">|
|---|

## まとめ
今回は単純なconflictを発生させて、それを解消する手順をまとめてみました。
しかし、ファイルの編集でのconflict以外にもファイルの存在に関わるconflictもあります。
色々なパターンを再現してみて、実務に役立てればいいかなと思っています。
アジャイルなチームのほうがドキュメントがしっかりしていた話

久しぶりの大きいチーム。
今までは少人数で、アジャイルなチームだった。

次のところは大きいチームではあるが割と安定して定期的にプロジェクトをリリースしているようだ。
ガチガチに固まってんのかなーとかドキュメントどんだけ書いてるんだろうなーめんどくさそうだなーとか考えてた。

違った意味で面倒だった。

# 見ててこない全体像

それなりに歴史のあるシステムなのでいろいろ負債もありそうだなーと思ってドキュメントを探しにいった。
が、出てこない。
サーバ構成はおろか、サブシステムがいくつあるのかも把握できなかった。

いや、ドキュメントはある。
最近の案件のスケジュールやら体制図、詳細な仕様書なんかはたくさん出てくる。
だが一向にシステム構成や機能一覧といったドキュメントが出てこないのだ。

いろいろな人に聞きに行くことで、ようやく全体像が見えてきた。
細かいドキュメンテーションが面倒そうだと思ったら、まさかまずシステム構成を書き起こすところから始まるとは・・・

何故こんな事になっているのか。
長く続くと「ソースコードと仕様の乖離が」という話はよくあるが、そんなレベルではない。

# アジャイルなドキュメンテーション

これまでのチームではどんなドキュメントだったかを振り返ってみる。
（アジャイルはドキュメントを書かない、なんて謎の誤解はもう無いと信じつつ）

これまでもドキュメントだけで全体像を把握できたとは言わないが、
ある程度の理解はできたし、後で「アレどうなってたっけ？」となった時に見に行く先のあたりを付けることはできていた。

- ソースコードで分かる事は書かない
- ソースコードで分からない（分かりづらい）事は、むしろちゃんと書く
- 全体像や一覧、目的や背景が多くなる

工程で言う下流に当たる部分、これはソースコードから読み解きやすいので重視されない。
逆にソースコードから読み取れない上流に当たる部分、こちらが重視される。

また、アジャイルなチームではより横断的・自律的な動きを求められる、というのも
上流よりのドキュメントが重視される理由の一つだろう。

# ウォーターフォールでのドキュメンテーション

一方ウォーターフォールやプロジェクト型と言われる方ではどうか。
経験が浅いので正確ではないかもしれないが、考えてみた。

- 次の工程 = 下流が作業できるようにドキュメントを書く。
- ソースコードで分かるとかは関係ない。ソースコードを書くためのドキュメントだから。
- 別の人が次工程を実施することもある前提で書く。

現工程では前工程での成果物を元に次の工程で必要なものを作るのが目的となる。
そのため、今の工程よりも下流の工程で必要なドキュメントを作ることが重視される。

極端に言えば、仮に今の工程の内容に若干の修正が入ったとしても、
下流に向けてのドキュメントが正しく書かれていれば問題ない。

これによって、下流工程を実施するメンバは上流工程をそこまで気にしなくても良くなる。

# 何のためのドキュメントか

ウォーターフォールの方は、明らかにリリースまでをゴールとしたドキュメントとなっている。
ウォーターフォールプロジェクトのゴールはリリースなのだ。

困るのは、このドキュメンテーションが保守や改修時にも継承されていくこと。
一度作ったものはなかなか捨てられないもので、下流重視のドキュメンテーションは引き継がれてしまう。

最初に作る時に必要なドキュメントと、保守や改修時に必要なドキュメントっていうのは違うと思うのだが
プロジェクトを繰り返し実施するようなチームだと、そこがあまり意識されないのだろうか。

アジャイルな場合は、最初からアップデートする前提で活動を行っている。
もちろんすべてのドキュメントをアップデートしていくのは難しいため、
今作るために必要な一時的なドキュメントと、今後のためにアップデートしていくためのドキュメントは
明確に分けていたことが多かった気がする。

# チームの体制と役割の違い

今までのチームでは、あまり役割が固定化されていないことが多かった。
ある程度の役割が振られていることもあるが、明確に入れ替えがあったこともある。

そのため、役割関係なくいろいろ知っておく必要がある。
システムに関して知らくても良いことなんて、ない。

ウォーターフォールなチームでは、役割が固定されがちだ。
少なくともプロジェクト中に見る範囲が大きく変わることはないだろう。

逆に見える範囲を絞ることで自分の範囲に集中しろ、ということな気もする。

なのでいきなり全体を拾う必要はないので、そういったドキュメントも必要ない。
作業をしていく上で、なんとなく全体像を理解していくのだろう。

# っていう考察をして

自分を納得させようと思ってたんだけど、最近ちょっと状況が変わった。

だいぶ細かい、今でもバリバリ使ってるドキュメントもだいぶ雑だった。
作業する人の暗黙知に頼りまくっている感じ。

うーん。
ProbablyPrimeで素数判定

Golangでの素数判定には`math/big`の[`ProbablyPrime`](https://golang.org/pkg/math/big/#Int.ProbablyPrime)が使える。

メソッドのシグネチャは `func (x *Int) ProbablyPrime(n int) bool`。
このメソッドは疑似ランダムで選ばれた`n`個の数字を用いて`x`が(おそらく)素数かどうか判定する。
`x`が素数なら必ず`true`を返し、`x`がランダムに選ばれた素数でない数字なら**おそらく**`false`を返す。
false-positive (素数でないのに誤って素数と判定してしまう)確率は最大で$(\frac{1}{4})^{n}$。

$2^{64}$よりも小さい数字なら返り値は100%正しい。

```golang:main.go
package main

import (
	"fmt"
	"math/big"
)

func main() {
	var prime, nonPrime big.Int
	prime.SetString("20988936657440586486151264256610222593863921", 10)
	nonPrime.SetString("20988936657440586486151264256610222593863922", 10)
	fmt.Println(prime.ProbablyPrime(0)) // 素数の場合
	fmt.Println(nonPrime.ProbablyPrime(0)) // 素数じゃない場合
}
```

実行結果

```bash
$ go run main.go
true
false
```
Amazon Linux/Amazon Linux 2 の AMI ID の場所

# この記事の内容
Amazon Linux と Amazon Linux 2 の AMI ID 一覧が記載されているページへのリンク。
Terraform にて AMI ID の変数に入れる値一覧を探していて Amazon Linux についてはすぐにページを見つけられたものの、Amazon Linux 2 はなかなか見つけられなかったためメモ。

# Amazon Linux
- リージョン、種別ごとに表になっていて見やすいです。
- https://aws.amazon.com/jp/amazon-linux-ami/

# Amazon Linux 2
- Amazon Linux 2 AMI ID という見出し部分に記載されています。
- リージョンごとに AMI ID が記載されていますが、表ではないので若干見にくいです。
- https://aws.amazon.com/jp/amazon-linux-2/release-notes/
osmdroid を使って Android の OpenStreetMap  地図に マーカーを表示する

[osmdroid を使って OpenStreetMap を Android に表示する](https://qiita.com/ohwada/items/c3741fb14a5142035314)
の続きです

### MainActivity.java

 タイトル, 説明, 緯度, 経度からマーカーのリストを生成する

```
    List<OverlayItem> items = new ArrayList<>();

			items.add(new OverlayItem(タイトル, 説明, new GeoPoint(緯度, 経度)));
```

マーカーをクリックした時の処理

```
			mMyLocationOverlay = new ItemizedIconOverlay<>(items,
					new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
						@Override
						public boolean onItemSingleTapUp(final int index, final OverlayItem item) {
     // Toast　を表示する
					Toast.makeText(this, item.getTitle(), Toast.LENGTH_LONG).show();
							return true; // We 'handled' this event.
						}

						@Override
						public boolean onItemLongPress(final int index, final OverlayItem item) {
     // Toast　を表示する
					Toast.makeText(this, item.getTitle(), Toast.LENGTH_LONG).show();
							return false;
						}
					}, getApplicationContext());
			this.mMapView.getOverlays().add(this.mMyLocationOverlay);
		}
```

地図にマーカーを重ねる

```
			final MinimapOverlay miniMapOverlay = new MinimapOverlay(this,
			mMapView.getTileRequestCompleteHandler());
			mMapView.getOverlays().add(miniMapOverlay);
```

以上でマーカーが表示される
![markers.png](https://qiita-image-store.s3.amazonaws.com/0/64075/6d5bb505-9d84-8ff3-59fa-351fb079783b.png)

github にソースを公開した

https://github.com/ohwada/Android_Samples/tree/master/Osmdroid2

ひと工夫しています。
csv　ファイルからマーカーのリストを生成するようにした。

csv　ファイルの例

```
横浜, 35.4472391, 139.6414945
```
データベース管理者タスク

社内でAmazonRedshiftの保守を担当することになったので、データベース管理者のタスクを覚書として残しておこうと思います。
すでにRedShiftが社内にはあったのですが、設計資料もないし、設定値やネットワークもどう考えても急ぎでとりあえず作ったみたいな感じだったので１から始めないといけないなと感じています。でもDMSだけはちゃんと使ってる。。。（担当者でこれほど違いがでるのかと思ってしまったけど）
DMLの作業でメモリ不足ですみたいなクエリエラーが出てしまって業務が止まることくらいは想定すべきでしょうね（設計側も作業者側も）

以下はデータベース管理者タスクです（自分用の覚書ですが。。。）
個々の作業について細かくは書きませんがタスク出しの出発点くらいにはなるでしょう。

●データベースシステムの構築にかかわる作業
　・Postgresソフトウェアのインストール
　・データベースの作成
　・ネットワーク環境の構成
　・データベースとソフトウェアのアップグレード
●日々の運用管理にかかわる作業
　・インスタンスの起動・停止
　・データベース記憶域構造の管理
　・ユーザーおよびセキュリティの管理
　・スキーマ・オブジェクト（表・索引・ビューなど）の管理
　・バックアップの計画・実行
　・データベースの積極的な監視と障害予防措置
　・パフォーマンスの監視・チューニング
●トラブルシューティング
　・障害発生時のリカバリの実行
　・データベースの監視によって判明した問題への対処
　・診断およびサポートサービスサポートサービスへのエラーの報告

大きく分けて３分類ほどに分割してます。

【余談】
RedShiftはPostgresに似て非なるものなのでお作法が違ったりします（一意制約がないとか）
RedShiftを運用していくうえで知識が足りないので管理の前にお勉強が必要です(´；ω；`)ｳｯ…
music21を使う環境構築

# はじめに

http://miso-soup3.hateblo.jp/entry/2018/12/20/223705

こちらの記事から環境構築を行った時の備忘録です。

## インストール

```terminal
$ python3 -m venv env
$ . env/bin/activate
$ pip install jupyter
$ pip install music21
$ pip install pyknon
$ brew cask install lilypond
$ brew cask install musescore
```

jupyter 入れた後は 再読み込みが必要でした。

## 設定

MuseScoreのバージョンが2から3にあがっていたので、初期設定のままではうごきませんでした。

<img width="628" alt="スクリーンショット 2019-02-03 17.22.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/12362/3181d7d9-6d38-26a5-bd15-aee19df0193a.png">

environment.pyのMuseScoreの設定はここ

<img width="729" alt="スクリーンショット 2019-02-03 17.25.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/12362/7a5088ae-9ea2-d3f8-7b7c-75a2a8d47bee.png">

http://web.mit.edu/music21/doc/usersGuide/usersGuide_24_environment.html
より
下記を実行すると~/.music21に設定が保存されます。

```python
from music21 import environment

us = environment.UserSettings()
us.create()
us['musescoreDirectPNGPath'] = '/Applications/MuseScore 3.app/Contents/MacOS/mscore'
us['musicxmlPath'] = '/Applications/MuseScore 3.app/Contents/MacOS/mscore'

```
~/.music21を消した場合は再起動するまでメモリ上で設定を保持しているような挙動でした。

## VS Codeでの動作確認用

```py
#%%
from music21 import environment

us = environment.UserSettings()
us.getSettingsPath()

#%%
from music21 import environment

us = environment.UserSettings()
us.create()
us['musescoreDirectPNGPath'] = '/Applications/MuseScore 3.app/Contents/MacOS/mscore'
us['musicxmlPath'] = '/Applications/MuseScore 3.app/Contents/MacOS/mscore'

#%%
from music21 import note,stream

stream1 = stream.Stream()
note = note.Note("C4", quarterLength = 1)
stream1.repeatAppend(note, 4)
stream1.show()
```

# 参考

http://web.mit.edu/music21/doc/installing/installAdditional.html

# さいごに

VSCode1つで開発できてしまって
環境構築はコマンドライン完了できるのは素敵です。
Amazon RDSについてまとめてみた

RDSとはAmazonがクラウド上で提供しているRDBMSです。
下記のデータベースエンジン群からインスタンス作成を行うことができます。
- Amazon Aurora
- PostgreSQL
- MySQL
- MariaDB
- Oracle データベース
- SQL Server
システム開発時にRDBMSとしてRDSを使用するにはいくつかのメリットが存在します。
# 高いスケーラビリティ
## インスタンスストレージ
RDSはパフォーマンス向上のため3種類のストレージタイプを提供しています。
### 汎用 SSD
汎用SSDは、ほとんどのデータベースワークロードで使用できる、コスト効果に優れたストレージです。
汎用SSDではどのくらいの数のリクエストまでは一定のパフォーマンスを保てるかが決まっている中で、I/Oのバースト機能を利用することでバランスを保つことができます。
汎用SSDはデフォルトで540万I/Oクレジットの初期I/Oクレジットバランスを受け取ります。
この値は30分間で3000IOPSのパフォーマンスバーストを維持するために十分であるため、さまざまなワークロードで最適なストレージです。
しかしながら、ワークロードによっては、3,000 IOPSのバーストストレージクレジットバランスが枯渇する場合があります。
※I/Oクレジットは毎秒たまるが、それを上回るI/Oリクエストが発生すると枯渇の可能性が生じる
そのため、ストレージサイズによってベースパフォーマンス(IOPS)やバースト期間を確認し、ワークロードのニーズを満たすようにストレージ容量を計画する必要があります。

### プロビジョンドIOPS
予測可能なパフォーマンスと一貫して低いレイテンシーを実現する必要がある本稼働アプリケーションには、プロビジョンドIOPSストレージが推奨されています。
プロビジョンドIOPSストレージは、一貫したパフォーマンスを要件とするオンライントランザクション処理 (OLTP) ワークロード向けに最適化されています。
※入出金処理システム等

### マグネティック
下位互換性としてサポートされているストレージ。
利用にはいくつかの制限が設けられており、非推奨。

## リードレプリカ
DBインスタンスのレプリカDBとして読み取り処理をスケールアウトすることが可能。
※インスタンスやストレージをマスターと異なるタイプに設定することも可能
読み取りクエリをアプリケーションからリードレプリカにルーティングすることにより、1つのDBインスタンスのキャパシティーを伸縮自在にスケールし、ワークロードを緩和できます。
必要な場合、リードレプリカをスタンドアロンのDBインスタンスに昇格させることも可能です。
リードレプリカは Amazon RDS for MySQL、MariaDB、PostgreSQL、Amazon Aurora で利用できます。

# 可用性と耐久性
## マルチAZ配置
RDSはマルチAZ配置にすることで高い可用性を実現することができます。
マルチAZ配置ではインスタンス作成時に、本稼働用とは異なるAZにスタンバイインスタンスにデータを複製します。
もしも本稼働側のAZで障害が発生した際には、異なるAZに配置されているスタンバイインスタンスに自動でフェイルオーバーしますので、
DBのダウンタイムが極めて短くなります。
自動フェイルオーバーはAZの機能停止以外にも下記の場合に適用されます。
- プライマリ DB インスタンスのエラー
- DB インスタンスのサーバータイプ変更
- DB インスタンスのオペレーティングシステムでソフトウェアのパッチ適用中
- DB インスタンスの手動フェイルオーバーが [Reboot with failover] を使用して開始された
## バックアップ
RDSは自動バックアップ機能によりスナップショットを作成し保存しています。
※新しいDBインスタンスに対してデフォルトで有効
スナップショットでは個々のデータベースだけではなく、そのDBインスタンス全体をバックアップしているため、インスタンスの復元が容易です。
※スナップショットから既存のDBインスタンスに対する復元は不可
自動バックアップはインスタンスのバックアップウィンドウ中にに実施され、指定したバックアップ保持期間に従ってDBインスタンスの自動バックアップを保存します。
また、スナップショットはユーザの好きなタイミングで手動で作成することは可能なため、汎用性があります。
## リストア ポイント イン タイム
また、RDSではDBインスタンスを特定の時点に復元し、新しいDBインスタンスを作成することができます。
DBインスタンスを特定の時点に復元するには、5分ごとにAmazon S3にアップロードしているトランザクションログを利用します。
DB インスタンスの復元可能な直近の時間を調べるには、AWS CLI の describe-db-instances コマンドを使用し、
DBインスタンスの [LatestRestorableTime] (=DBインスタンスの最新の復元時間)フィールドに返される値を参照します。
取得したこの時間から最新の復元時間にDBインスタンスを復元することができます。