OmniAICreator/Qiita-1.07M huggingface dataset:
REST APIあるある

あるあるJSON構造

```TypeScript
// GET /api/users

{
	"data": [
		{
			"id": "12345",
			"name": "hoge",
			"age": 20,
			"companyId": "23456"
		},
		{
			"id": "12346",
			"name": "fuga",
			"age": 21,
			"companyId": "23456"
		}
	]	
}

// GET /api/companies

{
	"data": [
		{
			"id": "23456",
			"name": "Google"
		},
		{
			"id": "23457",
			"name": "Apple"
		}
	]	
}
```

「"id": "12345"」のユーザーの会社名を取得したいとき

```TypeScript
getCompanyName(companyId: string): string | undefined {
	const company = companies.find(company => company.id === companyId);
	return company?.name;
}
```

ってやらないといけない。

なのでこっちの構造の方が嬉しい。

```TypeScript
// GET /api/users

{
	"users": {
		"12345": {
			"id": "12345",
			"name": "hoge",
			"age": 20,
			"companyId": "23456"
		},
		"12346": {
			"id": "12346",
			"name": "fuga",
			"age": 21,
			"companyId": "23456"
		}
	}
}

// GET /api/companies

{
	"companies": {
		"23456": {
			"id": "23456",
			"name": "Google"
		},
		"23457": {
			"id": "23457",
			"name": "Apple"
		}
	}
}
```

```TypeScript
getCompanyName(companyId: string): string | undefind {
	return companies?.[companyId].name;
}
```
はじめてのパターン認識 第２章

## はじめに

[はじめてのパターン認識](https://amzn.to/37iEey0) を読み進めて理解した内容を章ごとにまとめていきます。随時アップデート予定。

## 各章のまとめ

- [はじめてのパターン認識 第１章](https://qiita.com/drafts/3067edb7019665d8d3b9/edit)
- [はじめてのパターン認識 第２章 - この記事](https://qiita.com/TaigoKuriyama/items/802d2eddf4c1e1ca6106)

## 2.1 識別規則と学習法の分離

はじめてのパターン認識では、回帰は扱わず、識別問題のみを扱う。

### 2.1.1 識別規則の構成法

- 識別規則は入力データからクラスへの写像
   - 写像の実現方法は識別規則によってさまざま
      - 関数値の正負
      - ダミー変数表現
      - 事後確率の最大値
      - 決定木の終端ノード
- 写像とは？
   - 2つの集合があるとき、一方の集合の要素を他方の集合の要素に結びつける対応関係
   - 1つの集合を入力データ、もう１つの集合をクラスを考える
   - **機械学習とは結局、入力を出力に移す写像そのものを自動的に取得する手法** と考えてよい

### 2.1.2 教師付き学習

- 識別規則の学習
   - 識別規則は、入力データ(特徴ベクトル)からクラスへの写像を $y=f(x)$ という関数を用いて表現するが、この $f()$ を学習データを用いて決めること
- 学習データ
   - 入力データとそのクラスを指定したデータを対にしたもの
- 教師データ
   - クラスを指定したデータ
   - ２クラスの場合には、$t$ $\in$ \{ $-1,+1$ \} で表す
   - クラスが３以上ある場合は、ダミー変数表現を用いて $t=$ {  $0,1,0,0,0,0,0$ }$^T$ のように表す
- 学習データセット
   - 学習に用いられる全ての対の集合のこと。$D_L$ と表す
- 学習の目的
   - 学習データを正しく識別できる $w$ を求めること
   - 識別関数例：$y = f(x;w) = w_1x_1 + ・・・ + w_dx_d = w^Tx$
   - 学習データセットを用いて、識別関数の出力と教師データの誤差が小さくなるようにパラメータ $w$ を調整する

### 2.1.3 教師付き学習と線形回帰

- 関数近似(回帰)
   - 教師入力として２値 $t$ $\in$ \{ $0,1$ \} ではなく任意の関数値が与えらえる場合は、識別関数は入力 $x$ に対して与えられた関数値を出力するように学習が行われる
- 教師付き学習
   - 入力が所属するクラス $t$ $\in$ \{ $0,1$ \} などの教師がいる学習

### 2.1.4 教師なし学習

- 教師なし学習
   - 入力データ間の距離や類似度、統計的な性質に基づいてクラスを自動的に生成することが目的

## 2.2 汎化能力

- 学習
   - 学習データに対する識別関数の出力値と教師データの誤差が最小になるように識別関数のパラメータを調整すること
- 汎化能力
   - 未知のデータに対する識別能力
- 汎化誤差
    - 未知のデータと識別関数の出力との誤差

### 2.2.1 学習データとテストデータの作り方

- 真の誤り率
   - 真の分布 $p$ に従う学習データを用いて設計し、真の分布 $p$ に従うテストデータを用いてテストした時の誤り率
   - 真の分布とは、母集団の $d$次元特徴の分布
- 再代入誤り率
   - 母集団から学習データをサンプリングし、テストにも同じデータを用いて測定した誤り率のこと
   - 再代入謝り率が低い場合は、識別器の能力を何らかの方法で上げる必要がある
- 100円硬貨の識別をするとき
   - 国内の全100円硬貨の集合を母集団とする
   - バイアス(偏り)
      - 100円硬貨 7000枚を学習データ、3000枚をテストデータとしたとき合計は 10000枚になるがこれらは母集団(真の分布)からサンプリングされており、重さや透磁率などの平均や分散が真の分布と同じにならない

#### ホールドアウト法

- データを２つに分割し、一方を学習データとして使用し、もう一方を誤り率を計算するためのテストデータとして使用する
- ホールドアウト誤り率
   - ホールドアウトで分割したテストデータを用いて計算した誤り率のこと

#### 交差検証法

- データを $m$ 個のグループに分割し $m-1$個のグループのデータを使って識別器を学習し、残りの１つのグループでテストを行うことを $m$回繰り返しそれらの誤り率の平均を性能予測値とする
- 手元にあるデータ全てを学習とテストに使うのでより良い性能予測を行うことができる
- データの分割が偏る可能性がある

#### leave-one-out 法

- データの数(レコード数)とグループの数を等しくした交差検証法
- １つを除いた全てのデータで学習し、除いた１つでテストすることをデータ数分繰り返す
- 時間かかりそう

#### ブートストラップ法

- 再代入誤り率の偏りを補正するために利用
   - 再代入誤り率の偏りとは、学習データと同じデータを使ってテストをした場合、誤識別率は真の識別率よりも低く出るがこの差のこと
- ブートストラップサンプルという N個のデータからN回復元抽出(サンプルしたデータを元に戻す)を行って作ったサンプルを使って学習データ、テストデータにも使用して算出した誤識別率を $ε(N^*,N^*)$ としたとき
   - $bias = ε(N^*, N) - ε(N, N)$



## 参考

- [写像への目覚めー機械学習とは写像の構築であるー](https://thinkit.co.jp/article/16322)
- [はじめてのパターン認識　第2章 - Qiita](https://qiita.com/ssnnkkhh/items/a722b97ee9f9c061c4b7)
- [ブートストラップとは](https://oku.edu.mie-u.ac.jp/~okumura/stat/bootstrap.html)
AAC Navigationでnavigate同時実行時のクラッシュへの対処法

## 問題

例えば、AAC Navigationのnavigate()するボタンを２つ同時に押すなどした時に以下のように怒られクラッシュする。

```
2020-02-13 15:24:08.709 21427-21427/jp.studysapuri.for_school.dev.debug E/AndroidRuntime: FATAL EXCEPTION: main
    Process: jp.studysapuri.for_school.dev.debug, PID: 21427
    java.lang.IllegalArgumentException: navigation destination jp.studysapuri.for_school.dev.debug:id/action_mypageFragment_to_searchSchoolByConditionFragment is unknown to this NavController
```

## 原因
navigate()が２つ同時に実行された場合、2つ目の実行時には現在の画面（ナビゲーションgraphのnode）が1つ目の遷移先になっているため、画面に紐つくactionが無いことになってしまう。

## 回避策

今いるnode（画面）に紐つくactionが有るかを確認しあればnavigate()を実行、なければ何もしないようにするような拡張関数（以下の例ではnavigateSafe()）を作り、navigate()の代わりに使う。

```kotlin

import android.os.Bundle
import androidx.annotation.IdRes
import androidx.navigation.*

fun NavController.navigateSafe(
    @IdRes resId: Int,
    args: Bundle? = null,
    navOptions: NavOptions? = null,
    navExtras: Navigator.Extras? = null
) {
    val action = currentDestination?.getAction(resId) ?: graph.getAction(resId)
    if (action != null && currentDestination?.id != action.destinationId) {
        navigate(resId, args, navOptions, navExtras)
    }
}

fun NavController.navigateSafe(
    node: NavDirections,
    navOptions: NavOptions? = null
) {
    val action = currentDestination?.getAction(node.actionId) ?: graph.getAction(node.actionId)
    if (action != null && currentDestination?.id != action.destinationId) {
        navigate(node, navOptions)
    }
}
```
Dockerでfailed to get keyring during saving token, operation not permittedが出たら

1. keyctlがインストールされていない。`apt install keyutils`
2. dockerの初期設定でkeyutilsが無効になっている。`docker run --rm -it --security-opt seccomp=unconfined debian:jessie \
    unshare --map-root-user --user sh -c whoami`

参考
https://docs.docker.com/engine/security/seccomp/
https://github.com/Azure/azure-storage-azcopy/issues/193
vscodeのテーマカラーをカスタマイズ

## はじめに

[公式ページ](https://code.visualstudio.com/api/references/theme-color)で、テーマカラーのカスタマイズができることを知ったので、愛用のvscodeを自分好みにカスタマイズしてみました。

## デフォルトで用意されているテーマカラー

vscodeの設定から、テーマカラーを変えることができます。

設定から検索バーで、「color theme」と打つと、一番上に出てきた選択欄から配色テーマを変えることができます。

<img width="1501" alt="スクリーンショット 2020-02-13 20.14.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519787/6486a994-9890-3d8c-8348-e086c58b6c38.png">

##### Default Dark+

<img width="1501" alt="スクリーンショット 2020-02-13 20.12.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519787/311f2b2e-7a96-1f5d-3df4-14593911576b.png">

##### Default Light+

<img width="1501" alt="スクリーンショット 2020-02-13 20.12.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519787/83f0e97a-7f96-9053-d3b2-dada9231221a.png">

##### Solarized Dark

<img width="1501" alt="スクリーンショット 2020-02-13 20.12.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519787/2995c9ae-ac3f-75bd-d6fd-c25cba9d1cde.png">

## MYテーマカラー

Default Dark+をベースに、カスタマイズしてみました。青が好きなので、青を多めに使いました。また選択している箇所は、強調して見えるようにしたかったので、赤紫色にしてみました。

<img width="1501" alt="スクリーンショット 2020-02-13 20.20.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519787/cd4f8041-eea1-6287-3299-60189aecf718.png">

下記のファイルを、setting.jsonに貼り付けることで、適用できます。もしこの配色が気に入った人はぜひ適用してみてください！

```setting.json
"workbench.colorCustomizations": {
    // アクティビティバー
    "activityBar.background": "#021d5269", // アクティビティバーの背景色
    "activityBar.foreground": "#ffffff", // アクティビティバーの前景色
    "activityBar.border": "#646464", // アクティビティバーの境界線
    // サイドバー
    "sideBarSectionHeader.background": "#373746", // サイドバーセクションヘッダーの背景色
    "sideBarSectionHeader.border": "#8db3ff46", // サイドバーセクションヘッダーの境界線の色
    "sideBar.background": "#292931", // サイドバーの背景色
    "sideBar.foreground": "#a0a0a0", // サイドバーの前景色
    "sideBar.border": "#646464", // サイドバーの境界線
    "list.activeSelectionBackground": "#2c88d377", // アクティブな状態のセクションの背景色
    "list.focusBackground": "#2c88d377", // フォーカス状態のセクションの背景色
    "list.hoverBackground": "#193c5877", //ホバー状態のセクションの背景色
    // ヘッダー、タブ
    "editorGroupHeader.tabsBackground": "#2929316e", // ヘッダーの背景色
    "tab.activeBackground": "#0319464f", // アクティブタブの背景色
    "tab.border": "#8db3ff46", // タブの横線
    "tab.inactiveBackground": "#2929316e", // 非選択タブの背景色
    // エディター
    "editor.selectionBackground": "#cc25a265", // 選択領域の強調色
    "editor.lineHighlightBackground": "#9e99ee11", // 選択している行の強調色
    "editorLineNumber.foreground": "#a2bdddbb", // 選択行番号の文字色
    "editorBracketMatch.background": "#2c88d377", // 対応する括弧の背景色
    // ステータスバー
    "statusBar.background": "#23468b", // ステータスバー背景色
    "statusBar.foreground": "#ffffff", // ステータスバー前景色
    "statusBar.border": "#646464", // ステータスバー前景色
    // スクロールバー
    "scrollbarSlider.background": "#0d478a99", // スクロールバーの色
    // walcomeページ
    "welcomePage.background": "#2231419c"
},
```


こんな感じで、下に貼り付けるだけで、適用できます。あとは、さらに自分好みにカスタマイズしてみてください。

<img width="1501" alt="スクリーンショット 2020-02-13 20.32.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519787/2790f843-38b0-be18-b104-62d458ba2cc3.png">
Larave Facadeの使い方


#ファサードとは
ファサードとは、コンテナを通じてオブジェクトにアクセス方法を提供するクラスのことです

#公式サイト

https://readouble.com/laravel/5.5/ja/facades.html

#制作物のゴール

Hogeファサードの作成
hogehpgeを出力する

#サービスプロバイダーの作成

```
$ php artisan make:provider HogeServiceProvider
Provider created successfully.
```

##hogeクラスの登録

```php:app/Providers/HogeServiceProvider.php
    public function register()
    {
        $this->app->bind(
          'hoge',
          'App\Http\Compornents\Hoge'
        );
    }
```

bind()メソッドの第一引数にはいわゆる識別子としての名前を記載する
第二引数には、対象となる独自処理クラスであるHogeクラスを渡します。
今回の設置箇所はApp\Http\Compornents\Hogeとする。

#ファサードクラスの作成

laravel/app 配下にFacadesディレクトリを作成し、その中にHoge.phpを作成

コンポーネントの登録名を取得する為のアクセサーgetFacadeAccessor()メソッドを以下のように定義します。

```php:app/Facades/Hoge.php

<?php
namespace App\Facades;

use Illuminate\Support\Facades\Facade;


class Hoge extends Facade
{
  protected static function getFacadeAccessor() {
    return 'hoge';
  }
}
```

#独自処理クラスの作成

laravel/app/Http 配下に Components ディレクトリを作成し、その中にHoge.phpを作成

```php:app/Http/Components/Hoge.php
<?php
namespace App\Http\Components;

class Hoge
{
  public function echoHoge()
  {
    return 'HOGEHOGE';
  }
}
```

#サービスプロパイダーとエイリアスの登録

```php:config/app.php
<?php

return [
    'providers' => [

        App\Providers\HogeServiceProvider::class,

    ],

    'aliases' => [

        'Hoge' => App\Facades\Hoge::class,

    ],

];
```

#tinkerで動作確認

```
$ php artisan tinker
Psy Shell v0.9.12 (PHP 7.3.13 — cli) by Justin Hileman
>>> Hoge::echoHoge();
=> "HOGEHOGE"
>>> 
```
cssの基礎知識

##ブロック要素とインライン要素について
ブロック要素：
見出し・段落など一つのブロックとして主にページ全体のレイアウトを行うために使う要素。
（div,p,tableなど）

インライン要素：
主にブロック要素の中身として用いられる要素。文章の一部を装飾するときなどに使われる。
（a・strongなど）

##classセレクタ・idセレクタについて
class：
種別名を割り当てるもので、 同じclass名を、1ページ中に何度でも使うことができる。

id：
固有の名前を割り当てるもので、 同じid名は、1ページ中に1度しか使えない。

##webフォントとは
webサーバー上で提供されているフォントファイルのこと。
どの端末からアクセスしたときでも、同じフォントを表示させることができる。
LinuxへのVMware-Toolsのインストール方法

#はじめに
VMware-Tools をインストール方法で，いつもと違う方法をとる必要があったため，その方法を備忘録としてメモする．

##前提
- OSはRedHat Enterprise Linux 7.6
- VMware-Tools はVMware 公式サイトよりダウンロード
- 対象ソフトウェアは，VMware-Tools-10.1.0-core-4449150.tar.gz

#ファイルのダウンロード

VMware 公式サイト (https://my.vmware.com/web/vmware/details?downloadGroup=VMTOOLS1010&productId=614) より
VMware-Tools-10.1.0-core-4449150.tar.gz をダウンロードする．

#ダウンロードしたファイルのアップロード

TeraTerm やscp 等を用いて，/tmp にファイルをアップロードする．

```sh:実行コマンド
scp VMware-Tools-10.1.0-core-4449150.tar.gz [ユーザ名]@[IPアドレス]:/tmp
```

ls コマンドで，実行結果を確認する．

```sh:確認結果
ls /tmp
VMware-Tools-10.1.0-core-4449150.tar.gz
```

#ファイルを解凍する

アップロードしたファイルを解凍する

```sh:実行コマンド
cd /tmp
tar zxvf VMware-Tools-10.1.0-core-4449150.tar.gz
```

ls コマンドで，実行結果を確認する．vmtools ディレクトリが作成される．

```sh:確認結果
ls /tmp
vmtools
```

#iso をマウントする

作成されたディレクトリの中にある linux.iso をマウントする．

```sh:実行コマンド
mount /tmp/vmtools/linux.iso /mnt
```

#ファイルを解凍する

linux.iso の中にあるVMwareTools-10.1.0-4449150.tar.gz を解凍する．このファイルを既に持っていれば，上記の手順は不要であり，適当なディレクトリで本ファイルを解凍すればよい．

```sh:実行コマンド
mkdir /tmp/work
cp /mnt/VMwareTools-10.1.0-4449150.tar.gz /tmp/work
cd /tmp/work
tar zxvf VMwareTools-10.1.0-4449150.tar.gz
```

ls コマンドで，実行結果を確認する．vmware-tools-distrib ディレクトリが作成される．

```sh:確認結果
ls /tmp/work
vmware-tools-distrib/
```

#インストーラを実行する

ようやく見慣れた光景にまできた．
インストーラのperl スクリプトを実行する．

```sh:実行コマンド
cd /tmp/work/vmware-tools-distrib/
./vmware-install.pl
```

この時点で，以下のようなエラーメッセージが出力された場合，perl がインストールされていないので，perl をインストールする．

```sh:エラーメッセージ
-bash: ./vmware-install.pl: /usr/bin/perl: 誤ったインタプリタです: そのようなファイルやディレクトリはありません
```

perl をインストールする．

```sh:perlのインストール
yum install perl 
```

再度インストーラを実行する．

```sh:実行コマンド
./vmware-install.pl
```

設定をウィザード形式で尋ねられるが，お好みの設定にしてください．最後に，Enjoy というメッセージが出てくれば，インストール完了です．
TextView内の特定の文字列に対して手軽にタップイベントを追加する

Androidアプリ内のTextViewに対してWebのハイパーリンクのようなタップイベントをつけたい事がたまによくあるので、通常のonClickイベントと同じ使い勝手でなるべく簡単に扱えるようKotlinの拡張関数を書いてみました

## 使用感イメージ

下記のスクリーンショットのように使うイメージです。
よくある利用シーンとしては「利用規約」や「プライバシーポリシー」の文言にタップイベントをつけたりするときとかですかね

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129872/216f86e1-f1b2-3962-b824-d20358e78a57.png" width="320"> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129872/c06628ab-9ef8-b716-48b1-4ba57a3fe213.png" width="320">

利用側のコードもここまで簡潔に記述するのを目的にしてみます

```kotlin:MainActivity.kt
hyperLinkTextView.text = "Hello World!"
hyperLinkTextView.addHyperLink("Hello") {
    Toast.makeText(this, "'Hello' clicked!", Toast.LENGTH_SHORT).show()
}
```

## ソースコード

実際のタップイベントや文字色の変更、下線を引いたりするのは`SpannableString`を使用しますが、ベタ書きすると煩雑なコードになりやすいので今回の利用用途に特化した拡張関数を書いてみます。

```kotlin:HyperLinkExtension.kt
fun TextView.addHyperLink(linkText: String, callback: ((view: View) -> Unit)) {
    val spannableMessage = SpannableString(text)
    val pattern = Pattern.compile(linkText)
    val matcher = pattern.matcher(text)
    while (matcher.find()) {
        spannableMessage.setSpan(object : ClickableSpan() {
            override fun onClick(textView: View) {
                callback.invoke(textView)
            }
        }, matcher.start(), matcher.end(), Spanned.SPAN_INCLUSIVE_INCLUSIVE)
    }
    text = spannableMessage
    movementMethod = LinkMovementMethod.getInstance()
}
```

また、追加でこんな形の引数をとる拡張関数も同時に生やしておくと便利かもしれません

```kotlin:HyperLinkExtension.kt
fun TextView.addHyperLink(@StringRes vararg linkTextRes: Int, callback: ((view: View) -> Unit)) {
    linkTextRes.map { addHyperLink(it, callback) }
}

fun TextView.addHyperLink(@StringRes linkTextRes: Int, callback: ((view: View) -> Unit)) {
    addHyperLink(context.getString(linkTextRes), callback)
}

fun TextView.addHyperLink(vararg linkText: String, callback: ((view: View) -> Unit)) {
    linkText.map { addHyperLink(it, callback) }
}
```


## 制限

今回書いたコードでは利用側の簡潔さと引き換えに以下の制限が存在します。

- 判定に含まれる文字列が複数ある場合はすべてタップイベントの対象となります。
- 同じTextViewに対して`addHyperLink()`を複数使用しタップイベントを適用する文字列が重なった場合は、先に`addHyperLink()`したタップイベントが優先的に処理されます。
- 内部的に`setText()`を行なっているため、改めて外側から`setText()`を行なった場合は条件に一致していたとしてもリンクが無効になります。

この辺りが要件に合わない場合は内部の判定の仕方や代入の方法を調整してみてください :bow: 
あと正規表現とか駆使して判定したい方はMatcherあたりをごにょってもらえるといいかもしれないです。

## 参考

- 「TextView の一部のリンク化＋クリックイベントの指定、をサクッと作る」
    - https://qiita.com/suzukihr/items/19a2ec4b9a163b151164
- TextViewのリンク化いろいろ
    - https://qiita.com/ntsk/items/52a1c92a3288cd7d9f3a
初心者によるプログラミング学習ログ 238日目

100日チャレンジの238日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

238日目は

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>238日目<br>・youtubeで、portfolio模写<br>・udemyで、css講座<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1227688578789998592?ref_src=twsrc%5Etfw">February 12, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
2/13 授業ノート

#復習
・CSS(Cascading Style Sheets)：HTML文書に装飾・レイアウトを施すための言語のこと
・CSSについて
　list-style: none; /*中黒を取る*/
　padding-left: 0; /*左側余白を取る*/
　text-decoration: none; /*下線を取る*/
・HTMLについて
　div→ブロック要素をグループ化
　span→インライン要素をグループ化


#今日習ったこと
**CSSの記述**
・ display: block; /*インライン要素をブロック要素に*/
・疑似クラス(教科書P83)
　→ある要素が特定の条件を満たしたときにだけ反応するセレクタを作るためのモノ
:link→未訪問リンク
:visited→訪問墨リンク
:hober→マウスが乗った時
:active→マウスがクリックされている時
:focus→フォーカスされている時
ex:)
```nav a{
    text-decoration: none;
    padding: 15px 0;
    display: block;
    background: #fdc;
}```
↓以下を追加するとリンクにマウスが乗った時に色が変化する
```nav a:hover{
    background: #900;
    color: #fff;
}```

#感想
そろそろノートを取るのが大変になってきた。
今更ながら、授業聞きながらノート取ってまとめるのって体力要るんだなと思った。
文字の位置をpaddingで調整するの難しすぎる。
練習あるのみか。
基本情報技術者　マネジメント系　第1章 プロジェクトマネジメント⑥


#　⑥コスト見積もりと評価(プロジェクトコストマネジメント)

## 見積もりの技法

### 類推見積もり
過去の実績値と元に

### 係数見積もり
基準値に作業量を表す値を乗じて見積もる。

### 三点見積もり
最善値、最悪値、最も頻発する値
の3点で見積もる。

### 専門家の判断
デルファイ法など専門家の力を活用する。

## 工数を表す単位
「人日」や「人月」という単位を用います。

基本、人数x日数(月数)で計算します。

## ファンクションポイント法
機能の数と複雑さを元に、システムの規模を見積もります。

補正係数をかけて得点調整を行うこともあります。

## アーンドバリュー法
進捗をPV,EV,AC三つの金銭価値とに置き換えて扱います。

CVとSVという差異から予算、計画内に治っているか確認します。

### PV(Planned Value, 計画価値)
所定期間内に、作業に見積もられた予定金額

### EV(Earned Value, 獲得価値)
出来高、進捗パーセンテージを表します。

### AC(Actual Cost,実コスト)
EVの出来高に費やしたコスト 

## アーンドバリュー法　差異

CVとSVという差異から予算、計画内に治っているか確認します。

### CV(コスト差異)
CV=EV-AC

0以上で予算内
0未満で予算オーバー

### SV(スケジュール差異)
SV=EV-PV

0以上で計画通り
0未満で計画遅延
CentoOS7でDVWAの設定手順

# CentoOS7でDVWAを設定

[前回の記事](https://qiita.com/rui-watanabe/items/b7224a7f0094af0225a9)では、DockerでDVWAの設定をしました。

しかし今回はサーバーの勉強などのため、今度は一から**CentoOS7でDVWAを設定**をしていきたいと思います。

# 前提条件
- MySQL、httpd、phpインストー済みのCentos７サーバー（ファイヤーウォールも解放済み）

# MySQLの初期設定

MySQLのインストール後はパスワードなどが設定されていないので、初期設定をします。

```
# mysql_secure_installation
```

上記のコマンドを打ってrootのパスワードを設定し、テストDBや匿名ユーザーが必要かなどを用途に合わせて、選択してください。

その後dvwaというDBを作成するために、MySQLの中に入っていきます。

```
# mysql -uroot -p
Enter password: 

mysql> create database dvwa;
mysql> show databases; #作成されたか確認
mysql> quit
```

# DVWAインストール

DVWAのインストールはGitHubからできるので、ドキュメントルート下に移動してからwgetコマンドでインストールします。(今回はStable版である1.9をインストール）

```
# cd /var/www/html
# yum install -y wget
# wget https://github.com/ethicalhack3r/DVWA/archive/v1.9.zip
```

次にインストールしたDVWAのzipファイルを展開し、ディレクトリを移していきます。(zipファイルは不要のため削除）

```
# yum install unzip; unzip v1.9.zip
# rm v1.9.zip 
# mv DVWA-1.9/ dvwa
```

これで展開したDVWAを、ドキュメントルート/dvwaに移すことができました。

# DVWAのMySQL設定

最後に先ほどMySQLで設定したパスワードを、dvwaの設定ファイルに書き込みます。

```
# cd /var/www/html/dvwa/config/
# vi config.inc.php

$_DVWA[ 'db_password' ] = '設定したパスワード'; 
```

これで設定は完了です。

サーバーのIPアドレス/dvwa/setup.phpにアクセス後、Create/Reset Databaseを押し、Usernameをadmin、Passwordをpasswordと入力します。

無事ログインできたら、CentoOS7でDVWAの設も完了になります。

#参考URL
https://blog.8tak4.com/post/150120471965/dvwa-on-centos
https://github.com/ethicalhack3r/DVWA
RDKitでターゲットデータベースから類似化合物を検索するコマンドを作成し処理時間を確認

#はじめに

RDKitで、クエリ化合物に対し、ターゲットデータベース(といってもただのSDF)から類似化合物を検索するのにどの程度の時間がかかるのだろうか、ということが気になったためコマンドを書いてみた。

#ソース
類似度を計算する場合、フィンガープリントを生成し、Tanimoto係数で類似度スコアを求めるのが一般的だ。フィンガープリントは化学構造をビット化したもので様々な手法が存在する。ここではビット数が少なくメジャーなMACCS Keysを利用してみた。

```python
import argparse
from rdkit import Chem
from rdkit.Chem import Descriptors, AllChem
from rdkit import rdBase, Chem, DataStructs


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("-query", type=str, required=True)
    parser.add_argument("-target_db", type=str, required=True)
    args = parser.parse_args()

    # queryの読み込み
    mol_block = ""
    with open(args.query) as f:
        for line in f:
            mol_block += line

    query_mol = Chem.MolFromMolBlock(mol_block)

    # SDFの読み込み
    target_sdf_sup = Chem.SDMolSupplier(args.target_db)

    # FignerPrintの計算(query)
    query_fp = AllChem.GetMACCSKeysFingerprint(query_mol)

    # FignerPrintの計算(target)
    target_fps = [AllChem.GetMACCSKeysFingerprint(mol) for mol in target_sdf_sup]

    for i, target_fp in enumerate(target_fps):
        result = DataStructs.TanimotoSimilarity(query_fp, target_fp)
        print(i, result)


if __name__ == "__main__":
    main()
```

#使い方
こんな感じ。argparseちゃんありがとう。

```
usage: StructureSimilaritySearch.py [-h] -query QUERY -target_db TARGET_DB

optional arguments:
  -h, --help            show this help message and exit
  -query QUERY(mol)
  -target_db TARGET_DB(sdf)
```

#処理時間
例によってRDkitのSolubilityのtrainデータ1024件をtargetにして検索。queryは適当です。
そうすると、1秒程度で返却。万単位ならこのままでもそこそこいけそうだ。

#参考
- https://future-chem.com/rdkit-fingerprint/
ディレクトリとlinuxコマンドについて

###ルートディレクトリ・ホームディレクトリとは？

ルートディレクトリ：階層構造の最上位にあるディレクトリ
ホームディレクトリ：各ユーザーに割り当てられたディレクトリ

###それぞれに移動するためにターミナルで打つべきコマンド
ルートディレクトリへの移動

```
> cd /
```
ホームディレクトリへの移動

```
> cd 
あるいは
> cd ~
```

###ターミナルでのフォルダやファイル名の補完機能について
ターミナルでファイル名等の入力をするときに、途中まで入力してからTabキーを押すと、残りに文字が自動で入力される。
該当するファイル等が複数ある場合は、Tabを２回押すと候補のリストが表示される。

###移動の例
絶対パス

```
~/Desktop/text
```

相対パス

```
text
```
pythonでvim pluginを書く時にファイル分割する

## 背景
[Pythonでvim pluginを書く](https://qiita.com/zakuro9715/items/98449dd4c6b9e1d61ef5)

上記リンクの記事を参考にVim(Neovim)のpluginを作っています。
Pythonファイルが大きくなり分割しようとしたところ、少しつまずいたので解決法を共有します。

この記事では、例としてrequestsモジュールを用いてWebページのタイトルを表示するプラグインを作ってみます。

### ディレクトリ構成とファイルの中身
```
sample-vim-plugin
  plugin/
    sample_vim_plugin.vim
  src/
    sample_vim_plugin.py
    requests_caller.py
```

```vim:plugin/sample_vim_plugin.vim
scriptencoding utf-8

if exists('g:loaded_sample_vim_plugin')
	finish
endif
let g:loaded_sample_vim_plugin = 1

let s:save_cpo = &cpo
set cpo&vim

py3file <sfile>:h:h/src/sample_vim_plugin.py

function! sample_vim_plugin#print_title(url)
	py3 sample_vim_plugin_print_title(vim.eval('a:url'))
endfunction

let &cpo = s:save_cpo
unlet s:save_cpo
```
```py:src/sample_vim_plugin.py
import vim
import requests_caller

def sample_vim_plugin_print_title(url):
	print(requests_caller.get_title(url))
```
```py:requests_caller.py
import requests
from bs4 import BeautifulSoup

def get_title(url):
	response = requests.get(url)
	soup = BeautifulSoup(response.text, 'lxml')
	return soup.title.text
```

私はdeinでプラグインを管理しているので、tomlファイルに上記のプラグインを追加しneovimを起動すると
`ModuleNotFoundError: No module named 'requests_caller'`
と言われます。

このモジュール見つからない問題を解決したいと思います。

[「Python における 'runtimepath' の処理」](https://vim-jp.org/vimdoc-ja/if_pyth.html#python-special-path)に
> Python では、'runtimepath' のパスのリストを使う代わりに、vim.VIM_SPECIAL_PATH
という特別なディレクトリが使われます。このディレクトリが sys.path 内で使われる
とき、そして vim.path_hooks が sys.path_hooks 内で使われるとき、'runtimepath'
の各パス {rtp} に対して {rtp}/python2 (or python3) と {rtp}/pythonx (両バー
ジョンで読み込まれる) のモジュールがロードされます。

とあります。

よって、二つの方法が考えられます。

## 解決法1: ディレクトリの名前を変更する
runtimepathの直下にpython2,python3,pythonxのディレクトリがあればロードされるとのことなので、srcディレクトリをpython3にリネームします。
当然読み込む部分を変える必要があるので、下記のように変更します

```diff:plugin/sample_vim_plugin.vim
- py3file <sfile>:h:h/src/sample_vim_plugin.py
+ py3file <sfile>:h:h/python3/sample_vim_plugin.py
```

## 解決法2: sys.pathに追加する
ディレクトリの名前を変えたくない場合は、直接sys.pathに追加します。

```diff:plugin/sample_vim_plugin.vim
+ let s:sample_vim_plugin_root_dir = expand('<sfile>:p:h:h')
  py3file <sfile>:h:h/src/sample_vim_plugin.py
```

```diff:src/sample_vim_plugin.py
  import vim
+ import sys
+ import os
+ plugin_python_dir = os.path.join(vim.eval('s:sample_vim_plugin_root_dir'), 'src')
+ sys.path.append(plugin_python_dir)
  import requests_caller
```

## まとめ
- python2, python3, pythonxディレクトリにPythonファイルを置く
- sys.pathにPythonファイルをおいたディレクトリを追加する

という二つの方法でプラグインが動くようになります。

有名どころで言うと、[davidhalter/jedi-vim](https://github.com/davidhalter/jedi-vim)では解決法1(pythonx)を使っているみたいです。
ソースコードをチラ見しただけですが、[Shougo/denite.nvim](https://github.com/Shougo/denite.nvim/blob/master/autoload/denite/_main.py#L29)や[Shougo/deoplete.nvim](https://github.com/Shougo/deoplete.nvim/blob/master/autoload/deoplete/_main.py#L29)では解決法2を使っているように見えます。
【Spark AR】Native UI SliderでSkin Smoothing 

MaterialのSherder Type>Retouching>Skin SmoothingをNative UI Sliderで使いたいくてちょっといじってみたんだけど、公式のソースをコピペしたらエラーが出たので修正。

＞[Adding the Native UI Slider](
https://sparkar.facebook.com/ar-studio/learn/documentation/docs/native-ui-slider/)

Exampleの1行目が`NUI`なのに8行目で`NativeUI`使ってるので、それ揃えるのが正解。

```js
const NUI = require("NativeUI");
const M = require('Materials');
const Time = require('Time');

// Slider
var lastSliderValue = 0.5;
const mat = M.get('angery_mat');
const nativeUISlider = NativeUI.slider;
```

上記を修正したら`mat.opacity`を`skinSmoothingFactor`に。

[Scripting Object Reference](https://sparkar.facebook.com/ar-studio/learn/documentation/reference/scripting/summary/)からたどってって[RetouchingMaterial](https://sparkar.facebook.com/ar-studio/learn/documentation/reference/classes/materialsmodule.retouchingmaterial)参照。
iPadでもSwiftUIで遊べるドン！

こちらの記事で、XcodeのPlaygroundでSwiftUIが書ける旨が解説されていますが、iPadでも可能です。外出時に思いついたコードを試すなど、とても良さそうです。
https://qiita.com/shtnkgm/items/387132cd9633a59e7390

軽くサンプルのスクショ載せて解説します。忘れた時に参考できるような形です。

![515A5131-FD09-46BC-A0C6-FB413BCB34DB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114709/b8b33e7b-fd88-a39f-807b-48e44e83e80c.png)

# ポイント UIHostingViewControllerを使う
XcodeではPreviewProviderでプレビューを見る事ができますが、Playgroundにプレビューはありません。なので、UIKitの時にもPlaygroundでViewを検証するのに使っていたPlaygroundSupportのモジュールを利用します。 `PlaygroundPage.current.liveView`にUIHostingViewControllerを割り当てる事でliveViewを表示できるようになります。
【備忘】ubuntu+apache2+php7(docker) on centOS6

# 前提
vagrant+censos6+docker installは済

## ubuntuのインストール
```bash
docker pull ubuntu:latest
```

## ubuntuの起動
```bash
docker run -it -p 8080:80 --name SOMETHING_NAME ubuntu /bin/bash
```

## ubuntuの初期設定

```bash
apt update
# vim
apt install vim

# 日本語化
apt install language-pack-ja-base language-pack-ja
locale-gen
echo export LANG=ja_JP.UTF-8 >> ~/.profile
source ~/.profile

# php
apt install software-properties-common #これないとadd-apt-repoが使えない
add-apt-repository ppa:ondrej/php
apt update
apt install php7.2 php7.2-common php7.2-cli php7.2-fpm php7.2-mysql php7.2-dev php7.2-mbstring php7.2-zip

# apache
apt install apache2
apt install libapache2-mod-php7.2 #これないとapache+phpが使えない

# redis
apt install redis-server
apt install php-redis
```

# virtualHostの設定
```apache
touch /etc/apache2/sites-available/vhost_XXX.conf

<VirtualHost *:80>
    ServerName 192.168.0.11:8080
    ServerAdmin webmaster@virtual.host
    DocumentRoot /var/www/html_XXX
    ErrorLog /var/log/apache2/virtual.host.error.log
    CustomLog /var/log/apache2/virtual.host.access.log combined
    LogLevel warn
</VirtualHost>
```
あとは/var/www/html_xxx/info.phpとかでphpInfoでも出してみる

## 詰まりどころめも
### vagrantの中のdockerの中のapacheにアクセスしたいがどうしたら
dockerのポートフォワードで解決
### [vimが文字化け](https://qiita.com/ldap2017/items/29205c388bfb24d9b0f1)
デフォで日本語使えるとか甘え
### apache起動したもののphpが生テキストになる
apache2に拡張モジュールとしてphp7モジュールが必要だった
基本情報技術者　マネジメント系　第1章 プロジェクトマネジメント⑤


# ⑤PERT(プロジェクトタイムマネジメント)
PERTはアローダイアグラムを用いて日程や余裕日程のない(クリティカルパス)
を分析する技法です。


## アローダイアグラムについて
1,矢印順に作業を行います。
2,複数の矢印が集まる場合、集まってからでないと始めれません
3,ダミーアローがある場合、矢印が集まって、かつダミーアロー元の作業が始まってないとできません。
4,上に升目を用意して最早、最遅結合点時刻を書き込みます。

### ダミーアロー
実際の作業があるわけではないです。
依存関係がある時書きます。
作業日数は0日とします。


## 最早結合点時刻
1,最初の地点から0として書いていきます。
2,作業日数をプラスしていきながら順に書いていきます。
3,複数集まる場合は最も大きな物を採用します。

## 最遅結合点時刻
1,終わりの地点から最早の数値より書いていきます。
2,遡って書いていきます。
3,複数集まる地点は再早とは逆に最も小さい物を採用します。

## クリティカルパス
最早と最遅の時刻が同じ値である結合点を
全て通るように結んだ経路がクリティカルパスです。
[Flutter/Mac] Android StudioでWidgetのプロパティ一覧を表示する

Flutterでは、Widgetのプロパティ(コンストラクタの引数)を変更して挙動をカスタマイズして開発していくので、各Widgetのプロパティ一覧がみれるととても便利です。
MacのAndroid Studioではプロパティ一覧を見る（サジェストする）ショートカットは、`control + space` ですが、OSの入力ソース切替と競合するため、デフォルトの状態では表示されません。

#### OSのショートカットを無効にする

`システム環境設定 / キーボード / ショートカット / 入力ソース` で無効にすることができます。
![スクリーンショット 2020-02-13 18.15.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30719/885dabf4-660c-5373-adc0-bd73227d34cd.png)

#### 結果

Widgetのカッコ内にカーソルを合わせて、`control + space`を押すとプロパティが表示されます。

![スクリーンショット 2020-02-13 19.05.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30719/bc34d640-67e8-62dd-6e1a-5f6fb551baec.png)

#### おまけ

他にも多くの便利なショートカットなどが以下の記事で紹介されています。

* [Flutter 開発者向け Android Studio (IntelliJ) Tips](https://qiita.com/ssoejima/items/9de164dd7a50064ad9f9)
ラズパイにApache2を導入してみる

#今回の目標
Raspberry PiにApache2を導入して、とりあえずHalloWorld!!を表示してみる

###インストール
まずはお決まりのパッケージリストのアップデートとソフトウェアのアップデート

```
pi@raspberrypi:~$ sudo apt-get update
```


```
pi@raspberrypi:~ $ sudo apt-get upgrade
```
を実行

そしてApache2をインストールします。

```
pi@raspberrypi:~ $ sudo apt-get install apache2
```

で、インストール出来たかを確認

```
pi@raspberrypi:~ $ apachectl -v
Server version: Apache/2.4.38 (Raspbian)
Server built:   2019-10-15T19:53:42
```
こんな感じに表示されたらインストール出来てる

次に、ラズパイのローカルIPアドレスを確認する

```
pi@raspberrypi:~ $ ifconfig
```
```
inet 192.161.***.***  netmask 255.255.255.0   broadcast 192.168.***.***
```
という表示のinet 192.168.***.***の部分がローカルIPのはず

そのローカルIPを``http://192.168.***.***`という感じに入力すると...
![Screenshot from 2020-02-13 18-25-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584794/6b70b5c3-97cc-1275-6d24-c285fd2bebc5.png)
こんなのが表示される。
これが表示されれば導入完了

###HalloWorld!!を表示してみる
この、「/var/www/html/」ディレクトリ内にページファイルを作成したら表示されるようなので、example.htmlという名前で作成します。

```
pi@raspberrypi:~ $ sudo vim /var/www/html/example.html
```
と入力するとエディタが出てきてファイルを編集できます。
※この場合はvimでの編集です。「vim」の部分を変えてお好みのエディタでどうぞ

```html
<h1>HelloWorld!!</h1>
<p>example!!</p>
```
こんな感じで書いて、先程使ったURLの最後の部分にファイル名を入力する`http://192.168.***.***/example.html`
するとexample.htmlファイルで作成したページが表示されます。
![Screenshot from 2020-02-13 19-15-46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584794/1e867d2a-0931-83ca-d3fe-b46594ec2c1d.png)

##参考資料
[Apache2でラズパイをWebサーバに!](http://usicolog.nomaki.jp/engineering/raspberryPi/raspberryPi_Apache2.html)
一般化割当問題

## 一般化割当問題とは
機械 $i$ が仕事 $j$ を行ったときの負荷 $W_{ij}$ を考える. また, 機械 $i$ には処理能力制限 $R_i$ があるとする。仕事 $j$ を機械 $i$ に割り振った際の利潤を $R_{ij}$ とする。このとき、利潤を最大化するにはどのように割り当てればよいか。

## 回答例
```python
def GAP(Resource, Profit, Weight):
    m,n = Profit.shape
    lp = pulp.LpProblem(sense=pulp.LpMaximize)
    z =  np.array([pulp.LpVariable("z_{}_{}".format(j,i), cat='Binary') for j in range(m) for i in range(n)]).reshape((3,2))
    for j in range(n):
        lp += pulp.lpDot(Weight[:,j],z[:,j]) <= Resource[j], "resource_{}".format(j)
    for i in range(m):
        lp += pulp.lpSum(z[i]) == 1
    lp += pulp.lpDot(z.flatten(), Profit.flatten())  
    lp.solve()
    print(pulp.LpStatus[lp.status])
    print(np.vectorize(lambda x: x.value())(z))
    for name, c in lp.constraints.items():
        print("name: {}, slack: {}, Dual: {}".format(name, c.slack, c.pi))
```
【Android】アプリを多言語化/ローカライズしたい（RTL対応あり）

# 概要
作成していたAndroidアプリを国外で配信する可能性があったため、アプリを日本語以外にも対応させたかった。
そこで、アプリを多言語化（ローカライズ）する方法や、アラビア語などの右読み言語（RTL; Right To Left）の場合はどうするかを調べてまとめた。

# 多言語対応方法
## リソースを用意する
`<アプリプロジェクト>/app/src/main/res`の中には、例えば以下のようなリソースのディレクトリが格納されている。

- `drawable`（画像）
- `values`（色や文字列などの値）
- `layout`（レイアウト）

対応したい言語のリソースディレクトリを用意すると、Android端末の設定を拾って、その言語に対応した表示になる。
ディレクトリの名前は次のようにする。

- `<リソースのタイプ>-<言語コード>[-r<地域コード>]`  
`res/values-ja`、`res/values-en-rGB`など
- `<リソースのタイプ>-b+<言語コード>[+<地域コード>]`  
`res/values-b+en+001`など

そしてディレクトリの中に該当するリソースを用意する。

```res/values/strings.xml
<resources>
  <string name="title">Title</string>
<resources>
```

```res/values-ja/strings.xml
<resources>
  <string name="title">タイトル</string>
<resources>
```

※端末の設定に当てはまるものがない場合、読み込むリソースがなくなりアプリの強制終了などが起こり得るため、言語を指定しないデフォルトのリソースディレクトリを用意しておく。

## 多言語対応の要素を表示する
上で用意したリソースを要素に指定する。
指定の仕方は`@<リソースのタイプ>/<リソースのname>`

```main.xml
<TextView
    android:id="@+id/textView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/title" />
```

これで、言語設定が日本語の場合は"タイトル"、それ以外の場合"Title"という文字列が表示される。

## 多言語対応の要素をコードで利用する
`R.<リソースのタイプ>.<リソースのname>`で利用することができる。

```Main.kt
textView.text = R.string.title // TextViewにテキストをセットする
```

## RTL、双方向テキストへの対応
アラビア語は右から左に読む（RTL）。
←`　　　　　　　　　　　　　مرحبا هناك`←

しかし、テキスト中に数字・左から右に読む言語（LTR; 英語など）を含む場合は、その部分はLTRになる。
←`　　　　　　　　　　　　　مرحبا هناك`12345678←

基本的にはシステムのデフォルト処理によってその通りに表示されるが、ローカライズしたテキストに逆方向のテキストを挿入した場合などは適当な表示にならないことがある。

- メッセージの先頭に挿入されている
- 数字や区切り記号で始まる

その場合は[`BidiFormatter`](https://developer.android.com/reference/kotlin/androidx/core/text/BidiFormatter)クラスの`unicodeWrap()`メソッドを用いる。

また、Android 4.2（APIレベル17）以上ではレイアウトミラーリングもサポートされている。
`AndroidManifest.xml`に以下を記述する。

```AndroidManifest.xml
<application
    ...(略)...
    android:supportsRtl="true">
</application>
```


# 参考記事
[Localize your app](https://developer.android.com/guide/topics/resources/localization.html?hl=JA)
[複数の言語と文化をサポートする](https://developer.android.com/training/basics/supporting-devices/languages?hl=JA)
[言語とロケール](https://developer.android.com/guide/topics/resources/multilingual-support?hl=JA)
[代替リソースを提供する](https://developer.android.com/guide/topics/resources/providing-resources.html?hl=JA#AlternativeResources)
VPC概要

# VPC

- 仮想のネットワーク空間のこと
- AWSアカウント作成をするとデフォルトで1つVPCが作成されているが、通常は使用しない
- IPアドレスの範囲=VPCの範囲
- AZをまたぐことができる。
- リージョンをまたぐことはできない。

# サブネット

- 小さなネットワークに分割管理できる
- AZをまたぐことはできない
- 分割単位は/24がオススメ。第3オクテットで数値を切り変えることで管理しやすい。
    - 10.1.1.0~255/24:Subnet1
    - 10.1.2.0~255/24:Subnet2
    - 10.1.3.0~255/24:Subnet3
    - 10.1.4.0~255/24:Subnet4
- 最初の4IPと最後の1PはAWSが内部的に使用する。

## サイダー表記

- /8だと第2,第3,第4オクテットが自由に使える。
- /16だと第3,第4オクテットが自由に使える。
- /24だと第4オクテットが自由に使える。
- /32だと特定の1つのIPアドレスを示すことになる

## ルートテーブル

- サブネットの通信制御をする。
- Target項目のLocal=VPC内部のこと。この指定があることでVPC内の各インスタンスは通信可能となっている。

# インターネットゲートウェイ,EIP,セキュリティグループ,ネットワークACL

## インターネットゲートウェイ

- インターネットと通信するにはVPCにインターネットゲートウェイをアタッチする。
- ルートテーブルにインターネットゲートウェイの設定をする
- VPC内はプライベートIPで通信し、インターネットゲートウェイから外に出る時はパブリックIPが使用される。
- NAT変換機能とも言える

## EIP

- インスタンスにアタッチ/デタッチ可能
- インスタンスが再起動、停止、終了した場合も同じIPアドレス
- **どこにもアタッチしていない状態だと課金される**

## セキュリティグループ

- **EC2インスタンス単位**で設定するファイアウォール
    - 正確にはENIに付与するもの
- **拒否ルールではなく許可ルールを設定する**

## ネットワークACL

- **サブネット単位**で設定するファイアウォール

# NATゲートウェイ,ENI

## NATゲートウェイ

- セキュリティを保ったままインターネットに接続したいときに使う
- NATゲートウェイをパブリックサブネットに配置し、プライベートサブネットでNATゲートウェイへのルーティングを設定する
- 必ずEIPをアタッチしなければならない。

## ENI(Elastic Network Interface)

- VPC内の仮想NICサービス
- EC2インスタンスやNATゲートウェイにアタッチして使用するもの
- EC2インスタンスのIPアドレスの正体はENI
- EC2インスタンスはデフォではeth0にENIが1つアタッチされている

# VPCエンドポイント

- リージョンサービス(S3やLambda等)にVPCからプライベートに接続するサービス
- **インターネットを経由せずに接続することができる** 
- どのサブネットから接続するかを指定するとそのサブネットのルートテーブルにプリフェックスリストID(※)が追加される
    - (※)AWSが使用するプライベートIPの範囲を示すもの

### Gateway型

- S3,DynamoDBがサポートしている
- ルートテーブルに設定
- 安価

### Interface型

- 実態はENI
- プライベートリンク機能がサポートされているAWSサービスが対象となる
- セキュリティグループをアタッチして使用する

# VPCピアリング

- 他のVPCと接続したい場合に使用する
- 異なるVPCに配置されたEC2インスタンス同士が同一ネットワークかのように接続できるようになる
- 接続リクエストが無事承諾されればルートテーブルにピアコネクションIDが追加される
- CIDRが重複していると接続できない

# 引用

https://www.youtube.com/watch?v=aQpMBqn5mRY&list=PLtpYHR4V8Mg-hNPfIpCToq3ZLhvXMHFel
https://www.youtube.com/watch?v=lqsiWw-eDzQ&list=PLtpYHR4V8Mg-hNPfIpCToq3ZLhvXMHFel&index=2
https://www.youtube.com/watch?v=OjQSkvjw23c&list=PLtpYHR4V8Mg-hNPfIpCToq3ZLhvXMHFel&index=3
https://www.youtube.com/watch?v=vePEKj2gR3k&list=PLtpYHR4V8Mg-hNPfIpCToq3ZLhvXMHFel&index=4
https://www.youtube.com/watch?v=e7fJ7mva3QI&list=PLtpYHR4V8Mg-hNPfIpCToq3ZLhvXMHFel&index=5
https://www.youtube.com/watch?v=4sZ7n7KmJYs&list=PLtpYHR4V8Mg-hNPfIpCToq3ZLhvXMHFel&index=6
各OSのBluetoothの仕様 

# 各OSのBluetoothの仕様

[iOS](https://developer.apple.com/accessories/Accessory-Design-Guidelines.pdf)

場所
>25.5 Advertising Interval
The accessory should first use the recommended advertising interval of 20 ms for at least 30 seconds.
If it is not discovered within the initial 30 seconds, Apple recommends using one of the following longer
intervals to increase chances of discovery by the device:
● 152.5 ms
● 211.25 ms
● 318.75 ms
● 417.5 ms
● 546.25 ms
● 760 ms
● 852.5 ms
● 1022.5 ms
● 1285 ms

>推奨される広告パターンと広告間隔は次のとおりです。
>最初に、20ミリ秒間隔で少なくとも30秒間アドバタイズします
>30秒後に検出されない場合は、152.5ミリ秒、211.25ミリ秒、318.75ミリ秒、417.5ミリ秒、546.25ミリ秒、760ミリ秒、852.5ミリ秒、1022.5ミリ秒、1285ミリ秒のいずれかの長い間隔に変更できます。
>重要： これらの特定の間隔は、正確に使用される間隔です！これらの実際の間隔からのわずかな偏差でさえ、発見までの時間を劇的に増加させる可能性があります。
>

[Android](https://drive.google.com/file/d/1dhYuP0u5Zg4wMeDKp46OcWXnV_j1-LeT/view?usp=sharing)


>The blog post “What to keep in mind when developing your BLE Android app” contains a section with advertising. According to the blog, the allowed advertising intervals are the following:
>a. ADVERTISE_MODE_LOW_LATENCY – Advertising interval: 100 ms
>b. ADVERTISE_MODE_BALANCED – Advertising interval: 250 ms
>c. ADVERTISE_MODE_LOW_POWER – Advertising interval: 1000 ms
【VBA】タイプを一括作成できる便利ツール

https://portal.bizrobo.com/ja/%E8%A3%BD%E5%93%81/bizrobo%EF%BC%81-basic/%E3%82%A2%E3%83%89%E3%82%AA%E3%83%B3%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8-%E3%81%A8-%E8%A3%9C%E5%8A%A9%E3%83%84%E3%83%BC%E3%83%AB?title=Type%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E4%B8%80%E6%8B%AC%E7%94%9F%E6%88%90%E3%83%9E%E3%82%AF%E3%83%AD

<img width="832" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/49dfacb7-e1d9-a960-3574-f4c57120705a.png">

<img width="796" alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/8a998c3c-e445-1690-5346-d0793dd4c146.png">

<img width="72" alt="3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/68821eee-aef3-49f5-b726-66283a4c2acf.png">
入力して実行すればすぐにできる
ESXi上の仮想マシンをシンプロビジョニングのまま別のデータストアに移行する

# はじめに
ストレージが小さなESXi上にOpenShiftクラスタを作っていたらディスクフルになってしまったので対処。

概ね「[コマンドでシンプロビジョニングの仮想マシンを別のデータストアに移行する](https://mseeeen.msen.jp/migration-to-another-data-store-with-thin-provisioning/)」に
記載されている通りだが、 vmdkが複数存在する場合等にこの手順だと上手くいかないので
その補足も兼ねて備忘録。

もし行う場合は自己責任で実施してください。責任は持てません。
もっと良い方法があればご教示頂ければ幸いです。
確認していないがスナップショットがロストするかもしれません。

# 備忘録
作業フォルダに移動。

```
[root@localhost:/vmfs/volumes] cd /vmfs/volumes/
[root@localhost:/vmfs/volumes] pwd
[root@localhost:/vmfs/volumes] ls -la
total 3076
drwxr-xr-x    1 root     root           512 Feb 13 09:16 .
drwxr-xr-x    1 root     root           512 Feb 12 09:32 ..
drwxr-xr-x    1 root     root             8 Jan  1  1970 5e01bc25-426f662b-3f8a-00110a6cc48c
drwxr-xr-t    1 root     root         77824 Feb 13 06:45 5e01bc3f-1e7f497b-04bf-00110a6cc48c
drwxr-xr-x    1 root     root             8 Jan  1  1970 5e01bc42-f24a25db-2ba3-00110a6cc48c
drwxr-xr-t    1 root     root         73728 Feb 13 06:48 5e43c766-c967c2e2-2084-00110a6cc48c
drwxr-xr-x    1 root     root             8 Jan  1  1970 c6af847e-087b87b1-f6cd-6a0e99cb4ee8
drwxr-xr-x    1 root     root             8 Jan  1  1970 cf92f677-c0052692-b144-2b029c7d3c8e
lrwxr-xr-x    1 root     root            35 Feb 13 09:16 datastore1 -> 5e01bc3f-1e7f497b-04bf-00110a6cc48c
lrwxr-xr-x    1 root     root            35 Feb 13 09:16 datastore2 -> 5e43c766-c967c2e2-2084-00110a6cc48c
```

変換対象のvmdkファイルを確認する。
この中で対象は

- vm.vmdk
- vm-000001.vmdk

sesparseやflatは変換エラーとなる。

```
[root@localhost:/vmfs/volumes] ls -la datastore1/bootstrap/*.vmdk
-rw-------    1 root     root     4574973952 Feb  7 07:52 datastore1/vm/vm-000001-sesparse.vmdk
-rw-------    1 root     root           374 Feb  7 00:19 datastore1/vm/vm-000001.vmdk
-rw-------    1 root     root     171798691840 Jan 31 01:15 datastore1/vm/vm-flat.vmdk
-rw-------    1 root     root           531 Jan 30 12:34 datastore1/vm/vm.vmdk
```

thin形式に変換しつつデータを移す。

```
[root@localhost:/vmfs/volumes] mkdir datastore2/vm/
[root@localhost:/vmfs/volumes] vmkfstools -i datastore1/vm/vm.vmdk -d thin datastore2/vm/vm.vmdk
[root@localhost:/vmfs/volumes] vmkfstools -i datastore1/vm/vm-000001.vmdk -d thin datastore2/vm/vm-000001.vmdk
[root@localhost:/vmfs/volumes] find datastore1/vm/* -not -name "*.vmdk" -exec cp {} datastore2/vm/ \;
```

ストレージ移行したい仮想マシンをESXi WebUIで「アクション」→「登録解除」する。  
　注意）「登録解除」ではなく「削除」してしまうと新しいストレージ (datastore2/vm相当) での動作環境前に
　　　　　 古いストレージからデータが削除されてしまうので必ず「登録解除」にすること。  

新しいストレージで「仮想マシンを登録」でvmdkファイルを選択する。
初回パワーオン時は「質問」ダイアログが立ち上がるので「コピーしました」を選択し「回答」ボタンをクリックする。

正常に起動し状態に問題がないようなら古いストレージからデータ (datastore1/vm相当) を削除。
削除方法はデータストアブラウザかSSH。
Slack APIでリクエストを検証する。を実装してみる。

## やりたいこと

HTTPリクエストが、Slackからのリクエストなのか確認する
[Slackからのリクエストを検証する](https://api.slack.com/docs/verifying-requests-from-slack)

## AWS周り

API Gatewayを使っていたのでHTTPヘッダを編集

**POST->メソッドリクエスト->HTTPリクエストヘッダー**
<img width="971" alt="スクリーンショット 2020-02-13 12.41.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150799/c95496ba-c3a2-d2fb-3c18-2acba765c074.png">

**POST->統合リクエスト->HTTPヘッダー**

<img width="978" alt="スクリーンショット 2020-02-13 13.08.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150799/e8e4ccff-5d24-50aa-0574-36d556718d32.png">

## サーバー側コード
flaskで書いてます。

```python
app = Flask(__name__)
@app.route("/", methods=["POST"])
def root():

    slack_signing_secret = b'MY_SLACK_SIGNING_SECRET'
    request_body = request.stream.read().decode()
    timestamp = request.headers['X-Slack-Request-Timestamp']
    if absolute_value(int(time.time()) - int(timestamp)) > 60 * 5:
        #タイムスタンプが5分以上ずれていたら、それはDDoS攻撃の可能性が高いので無視する。
        return
    sig_basestring = 'v0:' + timestamp + ':' + request_body
    my_signature = 'v0=' + hmac.new(
            slack_signing_secret,
            sig_basestring.encode("utf-8"),
            hashlib.sha256
            ).hexdigest()
    slack_signature = request.headers['X-Slack-Signature']
    if hmac.compare_digest(my_signature, slack_signature):
        print("request is ok")
    else:
        print("bad request")
```

## ライブラリにありました
[python-slackclient](https://github.com/slackapi/python-slackclient)に関数がありました。ありがたい。

```python
from slack import WebClient
client = WebClient(slack_bot_token)

app = Flask(__name__)
@app.route("/", methods=["POST"])
def root():

    slack_signing_secret = "MY_SLACK_SIGNING_SECRET"
    request_body = request.stream.read().decode()
    timestamp = request.headers['X-Slack-Request-Timestamp']
    signature = request.headers["X-Slack-Signature"]
    if absolute_value(int(time.time()) - int(timestamp)) > 60 * 5:
        #タイムスタンプが5分以上ずれていたら、それはDDoS攻撃の可能性が高いので無視する。
        return

    valification_flag = client.validate_slack_signature(
            signing_secret=slack_signing_secret,
            data=request_body,
            timestamp=timestamp,
            signature=signature
            )

    if valification_flag:
        print("request is ok")
    else:
        print("bad request")
```

## 困ったこと

もともと`flask.request.form`でペイロードを取得していたのですが、
`flask.request.stream`を使うと`byte`になってしまいます。

そして、どちらかを使うと`request`の中身は空になります。
なので、今回は`byte to json`を以下のように書きました。

```python
import urllib.parse
dict_data = json.loads(urllib.parse.unquote_plus(request_body).split("=",1)[1])
```
むりやり

## 追記(2020.3.31)

先の項目で`parse`の`unquote`には以下の二種類ある。

```python
urllib.parse.unquote()
urllib.parse.unquote_plus()
```

今回はunquote_plus()を使わないといけなかったので修正した。
Google日本語入力：かな入力の工夫

#Google日本語入力でかな入力する時に困りごとと解決法

Google日本語入力に限ったことかどうかは、他のIMEをほとんど使っていなないのでわからないが、かな入力をしていると時々不便なことにぶつかる。それをどうやって回避しようかというお話です。

もっとよいソリューションがあれば改訂しますが、とりあえずリリース。

##１．漢数字が面倒：入力切り替えのキーバインドで！
縦書き原稿を書いていると、数字の表記で悩むことがある。全角数字は間抜けに見えるし、半角数字は横向きになる。

**「縦横中」**という機能があれば2桁数字を立ててくれるが、それ以外の数字は横向きになる。

いっそ漢数字にしてしまうほうが見栄えがいい。

しかし、たとえば「**二〇一九年**」と打ちたいとき、ローマ字入力だと普通に数字を打って変換すれば漢数字になる。しかし、**かな入力では数字は直接打てない。**

全角英数字や半角英数字には、かなで打ってから、Ctrl+pやCtrl+tで変換できる(後述)。
　　**例：かなで「ふわぬよ」 → Ctrl+p → 「２０１９」**
しかし、**そこから漢数字には変換してくれない。

**Googleのケチケチケチ。**

数字から漢数字に一発変換するには、半角でも全角でもいいから、**直接数字を入力する必要がある。**かな入力ではそれができないから、入力前に「英数字入力」か「全角英数字入力」に切り替えなくてはならない。

そこで、キーバインド設定の登場だ。例えばおいらの場合。

**入力文字なし：Ctrl+Henkan：全角英数字に入力切替え**
**入力文字なし：Shift+Henkan：ひらがなに入力切替え**

と登録する。こうすると、漢数字を打ちたい場所で、

Ctrl+Henkan → 「２０１９」 → 変換 → 「二〇一九」 → Shift+Henkan

となる。ローマ字入力に比べて二手間余分にかかるが、自分が覚えやすい、操作しやすいキーバインドを設定することで、入力効率は向上するはずだ。

##２．英数字への最速変換：ショートカットキーで！
かな入力は英数字を入力する時が面倒だ。たとえば、

**「ＣＲＴは英語でCasode Ray Tubeの略です」**

という文を入力するとしよう。「ＣＲＴ」は全角、「Casode...」は半角だ。
これを正直にやるとすれば、

```
全角英数入力切替え → 「ＣＲＴ」 → ひらがな入力切替え
　→ 「は英語で」 → 英数入力切替え／IME無効化 → 「Casode....」
 　 → ひらがな入力切替え／IME有効化 → 「の略です」
```

と、かなりの手間だ。これが、ショートカットキーを使うと入力方法を切り替える必要がなくなる。

* **Ctrl+t：半角英数に変換**
* **Ctrl+p：全角英数に変換**
* **Ctrl+i：カタカナに変換**

この３つのキーバインドを覚よう。上の入力はこうなる（確定作業は省いている）。

```
Shift+「そすか」 → Ctrl+P
　 → 「は英語で」 → 「Shift+そちとらしい」 → Ctrl+t
　 → Shift+Space → 「Shiftp+すちん」 → Ctrl+t
　 → Shift+Space → 「Shiftp+かなこい」 → Ctrl+t → 「の略です」
```

要するに、入力したかなに対し，漢字変換する代わりにCtrl+t/Ctrl+pで**半角英数変換／全角英数変換する**ということ。

以下、注意点だ。

* 変換したい英数字の大文字／小文字に見合ったキー入力が必要。
    -  **大文字の"Ｃ"**を出したいなら、**「Shift+そ」**。
* 長い英文だと、全角入力のままでは半角空白(Shift+Space)が面倒。
   - 英単語が続なら、IME OFFにするほうが手っ取り早い。

### ◆Ctrl+i のカタカナ変換も意外と便利だ。
**「コレをココにブッ挿してクれクれタこラ」**みたいに、文の一部がカタカナの時には自然な変換はしてくれない。明示的に入力するときにはカタカナ変換キーが便利だ。

手順は2通り可能だ。
1. 変換したい単語だけ入力してCrtl+i
2. 混在入力し、変換してから文節を調整してその部分だけCtrl+i

おいらは確実な方がいいので、1.を使っている。

※Ctrl+iを間違えていたので修正しました(2020/04/02)
JavaのpathとPackageに関するメモ

①前提
構成ディレクトリ
- stage11
    - test10
        - BondTest.java
        - issues
            - Position.java
            - Bond.java 
現在地
カレントディレクトリはtest10となっている．

実行ファイルと呼び出すファイル
　実行ファイルはBondTest.java
　実行ファイルから呼び出すファイルはPosition.javaとBond.java

②package名に関して
package名はソースファイルが入っているフォルダ名1つをつけてあげる

BondTest.java
　package test10;
Position.java
　package issues;
Bond.java
　package issues;

③クラスパス
packageのルートディレクトリをつけることが肝であった．
今回はBondTest.javaはpackage test10であるからstage11を指定する必要がある．
また呼びだすファイルはpackage issuesであるから一つ上のtest10を指定する必要がある．
クラスパスは以上の2つある．

④import
import文はBondTest.javaからPosition.javaとBond.javaを呼びだす際に必要になる．BondTest.javaのpackageがtest10であるから相対パスは，issues.~となる．よって

BondTest.java
　import issues.Position;
　import issues.Bond;

⑤javacとjava
いよいよjavacでコンパイルしてjavaで実行するわけである．
javac -cp ..:. BondTest.java
が正解である． 
.. は実行ファイルのpackageのルートディレクトリである．
. はPosition.javaとBond.javaのpackage issuesのルートディレクトリ．
ファイル名はBondTest.javaであるのも意外と間違えてtest10.BondTest.javaとかやりたくなるが書かない．

次にjavaコマンドで実行する．-cpはそのままであるからほぼ変わらないが，重要な点が一点あった．
javac -cp ..:. test10.BondTest.java
が正解なのである．javaコマンドでは，package名から書くことを忘れがちになるので注意が必要である．

最後にまとめると，

　ディレクトリが揃っていること
　実行ファイルのディレクトリにいること
この前提のもとで，
　package名のルートディレクトリをクラスパスに指定すること
　package名をjavacではつけずjavaではつけることになること

このあたりが要点になる．ディレクトリ構成が異なる人はうまくいかないことがあるかもしれないので検索して自分の形に合ったディレクトリを見つけることが重要である．
Vuetifyのv-text-fieldで自動補完されないようにする

# 概要

ログインID入力欄で入力内容がキャッシュされちゃうのはいやだった。
Vuetify2.xのドキュメントをみてもautocompleteのカスタマイズについてはあるが、逆の説明がなかった。


# 解決編

なんのことはなく、inputタグと同様 autocomplete="off" と記述するだけだった。

```
<v-text-field autocomplete="off" rounded clearable maxlength=9>
```

...みたいにv-text-field自身にないpropを指定すると、そのままinputタグにレンダリングされる模様。
ドキュメントのpropばかり気にしていたが、実は変換されるHTMLのほうで確認すればすぐわかることだった orz
上記の例のようにmaxlengthを指定すれば、文字数も制御できる。
pandasでリストをくっつけてDataFrameにする

#やりたいこと
リストを下に足していってDataFrameを作成する

#作り方
任意のリスト**randam_list**を下に追加していきます。

```Python
df_randam = pd.Series(randam_list,index=df.columns)
df = df.append(df_randam,ignore_index=True)
```
randam_listの要素数がdfのindexの数と一致していないと、エラーが出るので気を付けてください。
また、df.append()の時のignore_index=Trueなしでエラーが出たので、同じようにはまった人は付けてみて下さい。
textareaでPOSTされたtsvフォーマットのデータを受け取ってパースするメモ

テンポラリファイル作ってうまいことやる。

```php
$tmp = tmpfile();
fwrite($tmp, $_POST['text']);
rewind($tmp);
$meta = stream_get_meta_data($tmp);
$file_path = $meta['uri'];

$files = new SplFileObject($file_path);
$files->setFlags(
    \SplFileObject::READ_CSV |
    \SplFileObject::READ_AHEAD |
    \SplFileObject::SKIP_EMPTY |
    \SplFileObject::DROP_NEW_LINE
);
$files->setCsvControl("\t");

foreach($files as $key => $line) {
    //ここでなんやかんや
}
```