OmniAICreator/Qiita-1.07M huggingface dataset:
Adobe XDで画像書き出し時の解像度について


XDで画像を書き出す際の基本事項と、書き出し解像度について調べました。

・[画像書き出しの基本事項](#画像書き出しの基本事項)
・[書き出し画像の品質調査](#書き出し画像の品質調査)


#概要
XD（に限りませんが）の解像度の仕様を理解するためには、インプットとアウトプットそれぞれに解像度があることに注意して、操作画面やダイアログ画面で設定しようとしている項目がどちらについての設定なのかを意識すると理解がしやすくなります。XDにおいて、インプットの解像度（サイズ）はアートボードの解像度（サイズ）で、アウトプットの解像度（サイズ）は書き出しファイルの解像度（サイズ）です。編集（or 設定）可能なのは前者ついてのみであり、後者の解像度は自動的に決定されます（[画像書き出しの基本事項](#画像書き出しの基本事項)）。
また、解像度（サイズ）を決定する際には、（自動的に決定されてしまうため尚更）ビットマップ形式かベクター形式かも注意が必要です。その点が気になったので実際に実験して試してみました（[実際の書き出し画像の品質調査](#実際の書き出し画像の品質調査)）。



#画像書き出しの基本事項

##まず書き出す画像

フォーマット|書き出し先
---|---
PNG |iOS

##考慮すべきふたつのサイズ
既に説明したようにインプット、アウトプットふたつのサイズを考慮する必要があります。
・作成するアートボードのサイズ
・アートボード（or アセット）書き出しのサイズ
（前者がインプットで後者がアウトプットですが、XDではインプット／アウトプットという用語を用いないので、本記事でも以降は用いないことにします）

XDで設定可能なのは**主に前者**であり、後者はその設定にしがたって自動的に出力されます。

###作成するアートボードのサイズ
####アートボードのサイズ決定（設定）
XDでアートボードのサイズを意識するのは以下ふたつの場面です。
・アートボードの作成時
・アートボード（or アセット）の書き出し時

#####アートボードの作成時
XD起動時のデフォルト設定でiOSを選択すると等倍サイズ（1x）となっています。
・iPhone 6/7/8（375 x 667）＝　等倍（1x）
<div align="center">
<img src=https://qiita-image-store.s3.amazonaws.com/0/37598/fc9fd12d-3643-235e-acd9-ee1d387f50ab.png>
</div>

単純に2xで作成する場合は手動で750 x 1334にします。個々のiOSデバイスのサイズについては以下が参考になります。
[The Ultimate Guide To iPhone Resolutions](https://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions)

が、本記事ではデフォルトの1xを前提で話をすすめます。

#####アートボード（or アセット）の書き出し時
以下は書き出しの際に表示されるダイアログの画面で、フォーマット：PNG／書き出し先：iOSにしています。
![スクリーンショット 2019-01-04 16.46.51.png](https://qiita-image-store.s3.amazonaws.com/0/37598/c7eea862-4227-290f-242c-34d8f50da203.png)
一番下の“設定サイズ”は**作成したアートボードのサイズで出力サイズではありません**。ここで戸惑う人は多いようです（私も戸惑いました）。
[書き出しの設定サイズ（公式フォーラム）](https://forums.adobe.com/thread/2456298)
今回はアートボードを1xで作成しているので1xを選びます。

###アートボード（or アセット）き出しのサイズ
PNG画像を書き出すとアートボードのサイズ（今回は等倍：1x）をもとに、3種類のサイズのファイルが書き出されます。
・アートボード名（or アセット名）.png
・アートボード名（or アセット名）@2x.png
・アートボード名（or アセット名）@3x.png
アートボードを2xで作成した際の各ファイルの解像度については以下のリンク（公式）を参照してください。
[デザイン素材の書き出し](https://helpx.adobe.com/jp/xd/help/export-design-assets.html)。

#書き出し画像の品質調査

で、実はここからが本題
###等倍で作成して2x、3xで書き出した場合の画像の品質はどうなるのか。

結論としては、予想どおりですが、
**ビットマップは画像が荒くなり、ベクターついては画像の劣化はなかった**
です。
ここで言うベクター画像というのはIllustratorで作成したパスとXDで作成したオブジェクト。

###書き出しファイル1
<img src="https://qiita-image-store.s3.amazonaws.com/0/37598/ea0f7595-cd66-49af-0439-f07fe56f964d.png"  width="50%">

設定項目等 | 値
---|---
アートボードサイズ |iPhone 6/7/8（375 x 667）
ビットマップ画像（上半分）|375 x 667
ベクター画像（下半分）|375 x 667
テキスト（"解像度テストあいうえお"）|XDで打ち込んだもの
書き出し時の"設定サイズ"|1x

要するに、375 x 667のビットマップを3倍で書き出した画像です。
画像をクリックして拡大すると、テキストと下半分の画質は@3xで書き出しても劣化はありませんが、上半分の画像は劣化しているのがわかります。

###書き出しファイル2
<img src="https://qiita-image-store.s3.amazonaws.com/0/37598/ec6e3e92-7e36-dbe5-5ba9-b4284e11bbb3.png"  width="50%">

設定項目等 | 値
---|---
アートボードサイズ |iPhone 6/7/8（375 x 667）
**ビットマップ画像（上半分）**|**1125 x 2001**
ベクター画像（下半分）|375 x 667
テキスト（"解像度テストあいうえお"）|XDで打ち込んだもの
書き出し時の"設定サイズ"|1x

書き出しファイル1からの変更点は、ビットマップ自体を解像度を3倍に（375 x 667 => 1125 x 2001）したことです。上半分も画像は劣化はありません。


#さいごに
XDでアートボードを等倍（1x）で作成する際、レイアウトするビットマップ画像については最終アウトプットで必要となる解像度（サイズ）で用意するということになります。
当然の結果ですが、、

記載になにか間違いがあればご指摘お願いします。
VSCode+PyInstallerで実行ファイル名に自動でバージョンを付ける

VSCodeのカスタムタスクを用いて、PyInstallerで実行ファイルを作るときにバージョンを含んだファイル名を自動でつける。
git tagからverを生成します。(git describe)

[カスタムタスクの非公式ドキュメント](
https://vscode-doc-jp.github.io/docs/userguide/tasks.html#%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E3%82%BF%E3%82%B9%E3%82%AF)

Windowsでの環境ごとのpath指定があまりきれいではありません。Anaconda+conda環境が前提なので、そのほか環境ではうまく動かないかもしれません。


```tasks.json
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Run Pyinstaller",
            "type": "shell",
            "command": "./script/pyinstaller.sh",
            "windows": {
                "command": ".\\script\\pyinstaller.cmd ${config:python.pythonPath}"
            },
            "group": "build",
            "presentation": {
                "echo": true,
                "reveal": "always",
                "focus": false,
                "panel": "shared",
                "showReuseMessage": true,
                "clear": false
            }
        }
    ]
}
```

```script/pyinstaller.sh
#!/bin/sh

ver=`git describe --tags`
set -x
pyinstaller --onefile -n EXENAME_$ver main.py
```

```script/pyinstaller.cmd
@for /f "usebackq tokens=*" %%i in (`git describe --tags`) do @set VER=%%i
%1\..\Scripts\pyinstaller --onefile -n EXENAME_%VER% main.py
```
C#+VS Code でAtCoder やってみる(準備編)


c# で競プロの環境を構築した内容の備忘録です。

# 対象

以下の条件の方向けの記事になります。
- 競プロの環境を構築したい
- C# で競プロに参加したい
- Mac を利用している
- Visual Studio Code でコーディングしたい

# VS Code を使ったC#のコーディング環境構築

## VS Code のインストール

[VS Code のインストールリンク](https://code.visualstudio.com/)

## .NET Core SDK のインストール

[.NET Core SDK のインストールリンク](https://www.microsoft.com/net/core#windowscmd)

## C# のプラグインインストール

[VS Code のC#プラグインインストールリンク](https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp)

# 競プロのためのツール導入

## online-judge-tools のインストール

```
pip3 install online-judge-tools
```

# 環境構築(AtCoderの場合)

[この問題](https://atcoder.jp/contests/agc030/tasks/agc030_a)を解くと仮定して構築してみます。

## C# のプロジェクト作成

```
mkdir procon
cd procon
dotnet new console -o agc030_a
cd agc030_a
```
この後は、agc030_aディレクトリにあるProgram.cs を編集し、
コーディングします。

## コーディング後、test caseのチェック
上記の続きです。

```
cd ~/procon/agc030_a
oj dl https://atcoder.jp/contests/agc030/tasks/agc030_a
oj test -c "dotnet run --project $PWD"
```

このコマンドを実行すると、以下のようなテスト結果が出ます。

![スクリーンショット 0031-01-04 19.14.04.jpg](https://qiita-image-store.s3.amazonaws.com/0/21851/558fe10f-e867-8479-6816-06ce823679a9.png)


# 参考

- [[Visual Studio Code][C#] VSCodeでC#の環境を整える](https://qiita.com/koara-local/items/999f056b498b26d0e2c6)
- [競技プログラミングのための補助ツールを作った](https://kimiyuki.net/blog/2017/01/19/pr-online-judge-tools/)

# 次回予定(未定)
- C# で競プロする際のコーディング上の注意点
- C# で競プロする際のハック
探索アルゴリズム 応用情報技術者試験 対策日記@5

# 探索アルゴリズム
## 探索ってなに？
データの並びから目的のものを見つけ出すこと。
例えば [3,5,7,1,4,9,6,2,8] この中から4を見つける方法について考えてみましょう。

## 1. 線形探索
至ってシンプルな方法で、データの先頭から4かどうか一つずつ確認していく。
この場合は先頭から5番目に4があったので、5回の計算を行ったことになります。
n個のデータで線形探索を行うとき、最小で1回、最大でn回の探索が必要になります。
平均の探索回数はn/2回で、これはデータの個数nに比例しています。
よって計算量はO(n)となります。

## 2. 2分探索
2分探索は、ソートされたデータにしか使えません。今回のケースでは、あらかじめデータを[1,2,3,4,5,6,7,8,9]という風に並び替えておく必要があります。

まず、探しているデータと真ん中のデータを比較します。
真ん中の5は4より大きいので、4は真ん中より左の[1,2,3,4]にあることがわかります。
再び同じ様に、[1,2,3,4]の真ん中の2(または3)と4を比較します。
今度は真ん中の値より大きいので、2より右にあることがわかります。
この様に、「真ん中の値を比較→探しているデータが含まれない半分を捨てる」を探しているデータに辿り着くまで繰り返すのが2分探索です。

n回探索を行うと、データを二分する作業をn回行ったことになるので、$2^n$個までのデータを探索することができます。よって計算量はO($log_2{n}$)になります。(底2は省略して良い)

## 3. ハッシュ表探索
こちらも下処理が必要で、ハッシュ関数を用いて、予めデータをハッシュ値に基づいて格納しておきます。

例えば、ハッシュ関数が $h(x)=x \% 9$ (xを9で割った余り)だとします。
このとき、4のデータは4を9で割った余りが4なので、「4」の場所に格納されています。
すでにこの処理がされているので、探索の時にやることは再度4を9で割った余りを計算し、「4」の場所を探すだけです。

この方法では、データの大きさnにかかわらず、ハッシュ関数の計算を1度行うだけなので、計算量はO(1)となります。

ただし、例えば今回の場合では4と13ではハッシュ値が共に4で衝突する様に、違うデータでハッシュ値が重なる**シノニム**と呼ばれる問題が発生することがあります。

------
[ホームへ](https://qiita.com/k-y/items/dc2c9a3a8425712253e8)
コンテナ内のプロセスのログ出力先を標準出力/標準エラー出力に設定する方法

# はじめに
Docker を利用している場合、コンテナ内で動作しているプロセスのログは標準出力/標準エラー出力に出力させるのがベストプラクティスだと言われています。
（Docker が、コンテナの標準出力/標準エラー出力をログとして記録するため）

すでに Docker 環境を利用している方からすれば基本中の基本だとは思いますが、自分の備忘録という意味も込めてコンテナの各種プロセスのログ出力先を標準出力/標準エラー出力に設定する方法を今回は  2パターン（他にも設定の仕方はあるかもしれませんが下記2パターンで選択肢としては個人的には十分かと思います）のアプローチを紹介します。
# 設定のアプローチ
Docker のバージョンやホスト OS のバージョンによって設定方法が変わるわけではないので環境の記載は割愛します。

- 今回は、例として Nginx に対してログ設定を行います

## アプローチ ①（スペシャルファイルを指定）
まず、1 つ目のアプローチはシンプルに各種サービスの config ファイル内で設定できるログ出力先を標準出力/標準エラー出力のスペシャルファイルに指定する方法です。

```Nginx:nginx.conf
access_log  /dev/stdout  main;
error_log   /dev/stderr  warn;
```

特に工夫もなく本当に直接指定しているだけです。

##アプローチ ②（シンボリックリンクを貼る）
2 つ目のアプローチは、標準出力/標準エラー出力のスペシャルファイルに対して各種サービスで指定したログファイルのシンボリックリンクを貼る方法です。

公式の Nginx の Docker イメージはこちらの方法で設定されているので公式の Docker イメージを利用して確認および紹介したいと思います。

まずは、公式の Nginx の Docker イメージを利用してコンテナを作成します。

```Bash
$ docker run -d --rm nginx
4a285282d8a198b64e4d655c9e522a2a44fbb7198fe7c8f07affc26e365eb9b5
```
作成したコンテナの `nginx.conf` の内容を確認してみます。

```Bash
$ docker exec -it 4a285282d8a1 cat /etc/nginx/nginx.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}
```

アクセスログとエラーログの出力先は下記の通りに設定されています。

- アクセスログ
    - /var/log/nginx/access.log
- エラーログ
    - /var/log/nginx/error.log

次に、`/var/log/nginx/`のディレクトリ内容を確認します。

```Bash
$ docker exec -it 4a285282d8a1 ls -l /var/log/nginx
total 0
lrwxrwxrwx 1 root root 11 Dec 29 03:31 access.log -> /dev/stdout
lrwxrwxrwx 1 root root 11 Dec 29 03:31 error.log -> /dev/stderr
```
すると、スペシャルファイルに対してシンボリックリンクが貼られていることが確認できます。
# おわりに
既存システムの移行等を考慮すると、サービス自体には手を加えないパターン ② の方が好ましいと思います。
環境等に合わせて選択をしてみてください。
gethでPoAでプライベートチェーンを構築している場合、ブロック生成間隔を0にすれば自ずとAUTOMINING状態になる

# 背景
- fukumame55さんの以下の記事を参考にさせて頂き、EthereumのプライベートチェーンをPoAで構成した
    - https://qiita.com/fukumame55/items/b6005adb7cd301fc9188
- ブロック生成間隔を1秒にしたところ、トランザクションが含まれないブロックが大量に作られてしまう
- やはりfukumame55さんが同様の問題に対応するべく、トランザクションがある場合にだけブロックを生成するJSを紹介されていた(すごい)
    - https://qiita.com/fukumame55/items/bd57a5462e80bcc9125f
- 色々調べていたら、そもそもgethのPoA(clique)は生成間隔を0秒にすると、トランザクションがある場合にだけブロックを生成することがわかったため、これについて注意点とともに記す

# 手順
gethのPoA(clique)の[ソースコード](https://github.com/ethereum/go-ethereum/blob/master/consensus/clique/clique.go#L611)を見ると、「0-periodのチェーンの場合は空のブロックを作るの拒否する」との記述がある。
したがってこれにならい、ブロック生成間隔を0にすればトランザクションがある場合にだけブロック生成が行われるようになる。

直接genesis用のjsonファイルを触る場合は、以下のように記述すれば良い

```
    "clique": {
      "period": 0,
      "epoch": 30000
    }
```
- puppethを使ってjsonを作る場合はこんな感じで入力しておけばOK

```
Which consensus engine to use? (default = clique)
 1. Ethash - proof-of-work
 2. Clique - proof-of-authority
> 2

How many seconds should blocks take? (default = 15)
> 0
```
これで作ったチェーンはGanacheのAUTOMININGのようにトランザクションがある場合にだけブロック生成を行うようになる。

# 注意点
このチェーン上にtruffleでスマートコントラクトを`truffle migrate`でデプロイすると、

```
Running migration: 1_initial_migration.js
  Replacing Migrations...
  ... 0xe4b8bb5955711eaa4735e4c36d362079417d93fba61d7cfa425befa77cb8c735
```
という状態になって動かなくなることがある。検索してみると同様の症状が起きている人はいたが、gethを最新版にアップデートすれば直るといったおそらくまた違う問題についての記述しか見つからず、かなりハマった。

結局、↑の状態でgethのコンソール上で無駄にトランザクションを発行したら動いた。例えば、

```
eth.sendTransaction({'from':eth.coinbase, 'to':"0xcde196243a25c239b81b7aa6147b83e395ebe46e", 'value':web3.toWei(1, 'ether')})
```
で適当にethを送金してみるのが早い。一時的にトランザクションが空になったためブロックが生成されず、デプロイが進まない状態なのだろうか？

# 環境
- Geth/v1.8.20
- Truffle v4.1.15
SQL文　DELETE・TRUNCATE・DROPの違い

なんとなく違いが分かるようにまとめてみました。


DELETE文
----
テーブル内のデータを全削除または条件に一致したデータを削除する。

```
DELETE FROM テーブル名;
```
WHERE句で条件指定しないと表内の全てのデータが削除されるので注意してください。
COMMITしていなければロールバック可能です。

![delete.png](https://qiita-image-store.s3.amazonaws.com/0/315849/4bb2f2a1-1170-4f94-31c9-c94827f39c40.png)

※MySQLでCASCADEテーブル定義してある場合、親テーブルの削除と同時に子テーブルの削除を行うこともある。
https://qiita.com/masapiko/items/72b7f274585dac7ca0da

TRUNCATE文
----
テーブル内のデータを全削除する。

```
TRUNCATE TABLE テーブル名;
```
TRUNCATE文はWHERE句で条件指定できません。
テーブルごと削除してから再作成するのでDELETE文よりも高速です。
ただしロールバックができません。
※PosgreSQLはロールバックできる場合がある。

![TRUNCATE.png](https://qiita-image-store.s3.amazonaws.com/0/315849/c124a1a5-7a11-8711-5435-2c26a26cd90e.png)

DROP文
----
テーブル内のオブジェクトを完全に削除する。

```
DROP TABLE テーブル名;
```

完全に削除するのでロールバックができません。
表構造も残りません。
※DROP文はオブジェクトに対するSQL文なので索引なども削除できます。

![drop.png](https://qiita-image-store.s3.amazonaws.com/0/315849/a793a3f2-a4ce-630e-3ef7-20979ce549f9.png)

まとめ
----
同じタイトルをググれば同様の内容が書いてあると思いますが、
**「削除の条件がある場合はDELETE文」
「一度にすべて削除したい場合はTRUNCATE文」
「オブジェクト単位で削除したい場合はDROP文」**
って感じで覚えておくといいかもね
React Hooksでobject(オブジェクト)を使うCustom Hooks（カスタムフック）

HooksのuseStateでobject(オブジェクト)を使うのが面倒だったので、
useObjectというCustom Hooks（カスタムフック）を作ってみました。  

```typescript
import { useState } from "react";

export default function useObject<T>(obj: T) {
  const [state, setObj] = useState({ ...obj });

  const setState = (next: Partial<T>) => {
    setObj(prev => {
      return { ...prev, ...next };
    });
  };

  const prevState = () => {
    let result: any;
    setObj(prev => {
      result = prev;
      return prev;
    });
    return result as T;
  };

  return { state, setState, prevState };
}

```

使い方は  

```typescript
interface State {
  name: string;
  pass: string;
}
const initialState: State = { name: "", pass: "", num: 0 };

const App = () => {
    const { state, setState, prevState } = useObject(initialState);

    //通常のstate更新
    setState({name:"something"})

    //事前状態を利用するstate更新
    useEffect(() => {
        setInterval(() => {
          setState({ num: prevState().num + 1 });
        }, 1000);
    }, []);
}
```
stateがオブジェクトで、setStateでstateを更新できます。　
stateのプロパティでstateを更新する場合はprevState()で事前状態を取得します。　


Hooksによってクラスじゃなくて関数になったのでstate,setStateからthisがなくなった感じになってます。 
これで従来のクラスでのsetStateをReact Hooksで使えるようになったはずです...
事前状態を取得するあたりがなんか泥臭いのでいい方法があったら教えてください！

追記
prevState()はレンダリングの回数が増えるので別の方法でも書いてみましたが、事前状態を利用する場合、型の推論が効かないので入力補完が出来ない問題があります。

```typescript
import { useState } from "react";

export default function useObject<T>(obj: T) {
  const [state, setObj] = useState({ ...obj });

  type func = (prev: T) => Partial<T>;
  type obj = Partial<T>;

  const setState = <U extends func | obj>(next: U) => {
    setObj(prev => {
      if (typeof JSON.stringify(next) === "string") {
        return { ...prev, ...next };
      } else {
        return { ...prev, ...(next as func)(prev) };
      }
    });
  };

  return { state, setState };
}

```

使い方は

```typescript

    setState(prev => {
        return { num: prev.num + 1 };
    });
```
読み方・訳語

壊滅的な英語力でも頑張る。

*固有名詞の読み方
qiita:キータ
ansible:アンシブル
nginx:エンジンエックス apatchと並ぶwebサーバソフト
Vagrant:ベイグラント virtualboxなどと連携して仮想環境を操作
https://thinkit.co.jp/story/2015/03/19/5740

*一般英語:
delegate:権限を委譲する
vault:ボルト 貯蔵庫の意味 パスワードを暗号化して管理するソフトの名前にもなっている
https://dev.classmethod.jp/security/valut/


*訳語
ディレクティブ:指示文。プログラムそのものではなく、コンパイラなどの上位に指示を行う特殊構文。


随時更新
fetchでAPIのデータ取得

いまさらですが```fetch```を使ってAPIのデータを取得したので、そのメモになります。

## 条件

- resoponseは```true```または```false```
- ```true```の場合は対象のmoduleを表示。```false```の場合は非表示
- API通信エラーのときは```error message```を表示

## コード

``` javascript
const hoge = new Hoge('targetHoge', '.errorMessage');
// 対象のDOMがあったときだけAPIを叩く
if (hoge.targetElement) {
  hoge.getApiData();
}

class Hoge {
  /**
   *
   * @param targetElement 指定したIDがある場合だけjs処理をおこなう
   * @param errorMessageElement API通信エラーのときのDOM
   */
  constructor(targetElement, errorMessageElement) {
    this.targetElement = document.getElementById(targetElement);
    this.errorMessageElement = document.querySelector(errorMessageElement);
    this.apiUrl = '/api/foo.json';
    this.isHide = 'is-hide';
    this.isShow = 'is-show';
  }
  getApiData() {
    fetch(this.apiUrl)
      .then(response => (response.json()))
      .then(myJson => (myJson.fuga ? this.showModule() : this.hideModule()))
      .catch(() => {
        this.errorModule();
      });
  }
  hideModule() {
    this.targetElement.classList.add(this.isHide);
  }
  showModule() {
    this.targetElement.classList.add(this.isShow);
  }
  errorModule() {
    this.targetElement.classList.add(this.isShow);
    this.errorMessageElement.classList.remove(this.isHide);
  }
}
```

## fetchを使わずにresolve、reject処理を行う

fetchを使うとresolve、rejectの動作確認のため、APIのデータを用意したり、errorを起こさないといけなくて面倒なのでそれを回避する書き方。

``` javascript
class function http_client() {
  call() {
    return new Promise((resolve, reject) => {
		  this.foo(resolve, reject);
		}) ;
	}
  // $test.fooを読むのでスルーされる
	foo(resolve, reject) {
		fetch("").then(resolve).catch(reject);
	}
}

$test = new http_client();
$test.call();

// fetchを使わずにresolve、rejectの処理を確認
$test.foo = (resolve, reject) => {
	resolve({aaa: "aaa"});
};
```


## 参考サイト

- [Fetch 概説](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API/Using_Fetch)
GCP (Google Cloud Platform) の Compute Engine で爆速で Web アプリ環境を用意する全手順

## 前提

- GCP (Google Cloud Platform) の GCE (Google Compute Engine) を利用する
- サーバOS： は CentOS7 (OSが違う場合は、適宜読み替えてください)
- Web サーバは Nginx を利用する

## 手順

### GCP でユーザ登録

[GCP (Google Cloud Platform)](https://cloud.google.com/) でユーザ登録してください。
個人/ビジネス のタイプ選択や住所、クレカの登録は各自の内容を入力して登録を済ませる。

### インスタンス作成

メニューから「Compute Engine」の「VMインスタンス」を選択

<img width="1432" alt="GCE_設定_01.png" src="https://qiita-image-store.s3.amazonaws.com/0/199602/2e844fe9-baed-8b24-23ec-146cdb21e210.png">

インスタンス作成を選択。

『Compute Engine is getting ready. This may take a minute or more. Compute Engine documentation』っていうメッセージが出てる間は、まだインスタンス作成できないので、しばしお待ちください。

<img width="1532" alt="GCE_設定_02.png" src="https://qiita-image-store.s3.amazonaws.com/0/199602/fd90f28c-de26-5707-807c-c4c6bee74387.png">

「作成」ボタンか「クイックスタートを使用」で好きなサーバを立ててください。

ちなみに、筆者は今回「作成」を押して、OS「CentOS7」、HTTP/HTTPSトラフィック許可にチェック有り、のみを操作し、そのまま作成しました。

作成するとこんな画面になるはず。

<img width="1532" alt="GCE_設定_03.png" src="https://qiita-image-store.s3.amazonaws.com/0/199602/6848732a-5cb0-71c0-aa15-a8da54a5af4a.png">

### Web サーバ導入

まず、インスタンスのシェル画面を起動する。「SSH」のプルダウンから「ブラウザ ウィンドウで開く」を選択しウィンドウを立ち上げる。

<img width="307" alt="スクリーンショット 2019-01-04 17.06.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/199602/f2f21ee2-7a5c-acc0-c0ec-ce1c25efff87.png">

次に、Nginx をインストールする。今回は ContOS7 に入れてるので「[こちら](https://qiita.com/tomy0610/items/0884c77f1ac52957fa96)」の記事を参考にインストールする。

これで、`http://外部IPアドレス` にアクセスして、Web サイトが公開できた。
以上で Web アプリの環境が完成した。あとは、各自のソースコードを適所にデプロイしてあげるだけ。

## おまけ

独自ドメインの設定や、HTTPS対応もしたい場合は下記参照のこと

- 「[GCE で独自ドメインを設定する方法](https://qiita.com/tomy0610/items/adc839be9d100c0daf96)」
- 「[Web サイトを無料でHTTPS対応する方法](https://qiita.com/tomy0610/items/c0310555dace0da60ea2)」
Redisはデータの大きさに関係なくget/setの回数で遅さが際立ってくるぽい

追記: get,setに限らずexpire, delなど、とにかくredisにアクセスすると同様の結果になる。

Redisに短時間で大量のget/setをするとデータのサイズに関係なくむちゃくちゃ時間がかかってしまうようだ。
（変化自体は線形に増えているのだけど、体感時間としてはっきりわかってくるのが10000回あたりから）

以下、検証コード。

```Ruby
require 'benchmark'
require 'redis'

redis = Redis.new

repeats = [100, 1000, 10_000, 50_000, 100_000, 200_000, 500_000, 1_000_000]

repeats.each do |repeat|
  exec_time = Benchmark.realtime do
    (1..repeat).each do |_i|
      redis.set('record', 'input')
      record = redis.get('record')
    end
  end
  puts "#{repeat}: Redis working in #{exec_time.round(3)} sec"
end

puts "--------------"

repeats.each do |repeat|
    exec_time = Benchmark.realtime do
    (1..repeat).each do |_i|
      record = 'input'
      output = record.dup
    end
  end
  puts "#{repeat}: Variable working in #{exec_time.round(3)} sec"
end

```

実行結果 (Win10, Ruby 2.5.0, redis-server 3.2.1)

```bash
100: Redis working in 0.036 sec
1000: Redis working in 0.233 sec
10000: Redis working in 2.614 sec
50000: Redis working in 12.352 sec
100000: Redis working in 25.814 sec
200000: Redis working in 51.055 sec
500000: Redis working in 132.253 sec
1000000: Redis working in 279.764 sec
--------------
100: Variable working in 0.0 sec
1000: Variable working in 0.0 sec
10000: Variable working in 0.003 sec
50000: Variable working in 0.011 sec
100000: Variable working in 0.022 sec
200000: Variable working in 0.046 sec
500000: Variable working in 0.109 sec
1000000: Variable working in 0.216 sec
```

インスタンス間で共用しなければいけないデータで、かつメモリに乗せる必要があるという状況以外ではRedisの使用は避けたほうがよいのかも。
ElastiCache使うのとEC2のメモリ量増やすのとで、料金の差がそんなに大きな違いにならない気もするんだけど、どうなんでしょ。
ESXiでのクローニング後の話

これはESXi上にインストールしたLinux（RedHat6.3）をベースとして、大量にクローンを作る作業を行うにあたっての実クローニング作業を忘却録です。値とかは適度に読み替えつつ、各位の本番環境でやると思った通りにならない場合もあるからその時は笑って許すように。

##使用ソフトの一覧とバージョン（全て評価版に準ずるライセンス）
省略（一覧を箇条書きするの面倒なので察しましょう）

##下準備
"vSphere Web Client"にアクセスし、"vSphere Web Client"が動いてるVMを"vSphere Web Client"で操作出来るようにする。

##実作業（基本）
1. 基本VMを作る。注意点はネットワークアダプタで"VM Network"を選ぶくらい（アダプタタイプもVMXNET3が良いのかな）。プロセッサは1個、メモリは2GBを選択。
2. RedHatのインストール後、必要なソフトのインストールや各種の設定を実施。"VMware Tools"のインストールも忘れずに。
3. 全てが終わったら仮想マシンをシャットダウン。この時に ifcfg-eth[N]内のHWADDRやIPコメントアウトしておいた方が良い的な話を見ますけど取り敢えずこのままでも良いかと。

##実作業（ネットワーク周り）
1. 仮想マシンリストから仮想マシンにクローン作製を選択、途中ウィザード形式は環境によりけりの選択肢を。
2. 仮想マシンを起動。ログインはVMRCを使ってrootでログインするのが一番楽。
3. まず vi 辺りで /etc/sysconfig/network に書かれたホスト名を修正
4. 次に /etc/udev/rules.d/70-persistent-net.rules を思い切って削除、その上で再起動する。再起動後に同ルールファイルを開くと新しく自動生成されたHWADDRとeth[N]の組み合わせが出来てるのでeth[N]の番号を変える場合はここで指定し上書き保存
5. 該当する eth[N] を vi とかで開いて前項で調べたMACアドレス(HWADDR）に書き換える。合せてIPアドレスの変更も実施。
6. VMその物を再起動する
7. 再起動したら修正したIPアドレスにPINGを。飛ばなかったらHWADDRが一致してないのが理由としては一番濃厚。

##実作業（ボリュームグループの変更）
これに関しては変更した方が良いのかいまいち判らないけど一応変更の仕方を書いておきます。
redhat6の[公式ドキュメント](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/logical_volume_manager_administration/vg_rename)を見るとあっさり一つのコマンドを実行してね、としか書いてないですが、調べてみると設定ファイルの方も変更しないといけないようです。
具体的なコマンドは[Yosuke_Taka（はてなID）](http://you-tk.hatenablog.com/about)さんが書いた[LVMのボリューム・グループ名の変更方法](http://you-tk.hatenablog.com/entry/20130721/1374377748)を参考にしています（というかパクりました）。

##実作業（その他）
ほかにもホスト名だったりIPアドレスをベタ打ち設定するconfファイルや各種設定ファイルがあると思うのでそれを適時修正してください。

〆
Laravel + Vueの導入からコンポーネント作成まで

LaravelでVue.jsを使えるように設定したので一旦メモ。細かいところは一旦見ないで手順のみ記します。

## 環境について
- php 7.2
- laravel 5.7
- node 6.16
- npm 3.10.10

## Laravelアプリケーションの作成
Laravelのアプリケーションを作る。わからない人は以下の記事を参考に。Rails経験者向けと書いてありますが、Railsの部分無視すればRails初心者でもいけます。
[【Rails経験者向け】Laravelでhello worldして、簡単にフレームワークの違いを見てみよう！](https://qiita.com/masa08/items/a03ddee745a6213270c2)

## nodeのインストール
以下のサイトからnodeをインストールする。
https://nodejs.org/ja/download/

nodeに関しては、過去記事で一回インストール手順を解説しているので、わからない人は下記記事参考。
[Vue.js + Bootstrap4でポートフォリオサイトの雛形を作ろう！](https://qiita.com/masa08/items/3474d97a1283dfc275c9)

## npmを使ってライブラリのインストール
以下のコマンドを打って諸々のライブラリをインストールします。

```
$ npm install
```

## welcome.blade.phpの編集
resources/views/welcome.blade.phpを以下のように編集する。


```html
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>

        <!-- laravelmix style -->
        <meta name="csrf-token" content="{{ csrf_token() }}"> 
        <link rel="stylesheet" href="{{ mix('css/app.css') }}">
        <!-- Fonts -->
        <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet" type="text/css">
    </head>
    <body>
        <div id="app">
            <header-component></header-component>
            <example-component></example-component>
        </div>
        <!-- laravelmix-style -->
        <script src="{{ mix('js/app.js') }}"></script>
    </body>
</html>
```

## jsファイルの編集
resources/js/components下にHeaderComponent.vueを追加。中身は以下のように。

```html
<template>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <h1>This is header!</h1>
            </div>
        </div>
    </div>
</template>

<script>
</script>
```

その後に、resoueces/js/app.jsを編集。新規に作成したコンポーネントファイルを読み込む。

```js
require('./bootstrap');

window.Vue = require('vue');

Vue.component('example-component', require('./components/ExampleComponent.vue').default);
Vue.component('header-component', require('./components/HeaderComponent.vue').default);

const app = new Vue({
    el: '#app'
});
```

## npmを使ってコンパイル
ターミナルで以下のコマンドを実行。cssとjs関連のファイルをコンパイルする。

```
npm run dev
```

そのあとにlocalサーバーを立ち上げてみると以下のような画面になっているはず。
<img width="1147" alt="スクリーンショット 2019-01-04 18.50.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/124924/9a43a12a-900a-fe85-1967-9f234e39f15c.png">


## 最後に
一旦やったことをまとめましたが、まだよくわかっていない部分が多いので順次付け足していきたいです。

## 参考記事
[LaravelからVue.jsを使う最短レシピ
](https://qiita.com/fruitriin/items/e0f2c9aa035c3ff2c874)
TypeScriptのtsconfig.jsonをあれこれしてみた その１

# ぼやき
フロントエンドはカオスだなー
カオスだけどついていきたいなーと頑張っているけどやっぱりカオスだなー

React + webpack + TypeScriptであれこれしているんですが
`webpack.config.js`で数多のローダーを組み合わせたり
`tsconfig.json`の設定をどうにかしないといけなかったりと奔走しているうちに
ちょっとまずTypeScriptのtsconfigについて見てみようとなった次第です。


# 環境
- Mac OS Mojave v10.14.2
- node.js v10.9.0
- npm v6.2.0
- yarn v1.9.4
- Visual Studio Code v1.30.1

#　最低限の環境を準備

- とりあえず適当な作業ディレクトリを作ってそこに移動(以下、このディレクトリを`root`と表記)
- 以下のコマンドを実行

```shell
yarn init
yarn add -D typescript
```

rootの中はこうなってるはず。

```
root
 ┣━ node_modules
 ┣━ package.json
 ┗━ yarn.lock
```

# typescript使えるようになったかな？

以下のコマンドを打ってtypescript compilerのバージョンが表示されれば成功してる。

```shell
npx tsc -v
> Version 3.2.2
```

# 最低限のコードを書いて試してみる

`root`直下に`index.ts`を作成:

```index.ts
console.log("Hello World!");
```

`index.ts`をコンパイルする。

```shell
npx tsc index.ts
```

`root`直下に`index.js`が出来上がる。

```index.js
console.log("Hello World!");
```

JavaScriptで書けるコードしか書いてないので当たり前だが中身は何も変わらず。

コンパイルで出来た`index.js`を実行してみよう:

```shell
node index.js
> Hello World!
```

当然の結果ですね。

# ディレクトリ構成を変えたい。

こうしたい:

```
root
 ┣━ node_modules
 ┣━ src           ← typescriptのコードを入れるところ
 ┃   ┗━ index.ts
 ┣━ build         ← コンパイルした結果を入れるところ
 ┃   ┗━ index.js
 ┣━ package.json
 ┗━ yarn.lock
```

- `root/src`ディレクトリを作って`index.ts`をそこに移動する
- 以下のコマンドを実行する。

```shell
npx tsc ./src/index.ts --outDir ./build
```

- `--outDir`オプションを指定して出力先を指定。

まぁとりあえず現時点ではこれでよしとしよう。

# 外部ファイルを読み込みたい。

とりあえず`src/util.ts`を作る:

```util.ts
function hoge() {
  console.log("This is Util!");
}
```

`index.ts`で`util.ts`を読み込む:

```index.ts
import util from './util';
console.log("Hello World!");
```

コンパイルする:

```shell
npx tsc ./src/index.ts --outDir ./build
> src/index.ts:1:18 - error TS2306: File '/Users/nekonecode/work/lab/ts/src/util.ts' is not a module.
```

`util.js`は`module`じゃない！とおこです。
このモジュールってのが割とカオスってるなと、昔は思いました。(今もカオスではあると思う)


## util.tsをmoduleにする。

```util.ts
export function hoge() {
  console.log("This is Util!");
}
```

`export`をつけるだけです。
`export`は外で使えるようにする目印のようなもので、これを付けないと外から使えない。

再びコンパイルします:

```shell
npx tsc ./src/index.ts --outDir ./build
> src/index.ts:1:8 - error TS1192: Module '"/Users/nekonecode/work/lab/ts/src/util"' has no default export.
```

`default export`がねぇぞ！と再び怒っています。

これの解決策はいくつかございますが、今回は`index.ts`の方でどうにかしましょう。

## importの書き方 その１
```index.ts
import * as util from './util';
console.log("Hello World!");
```
`util.ts`を全て`import`し、それらを`util`という名前で取り扱うという書き方。

ついでなので`util.hoge()`を実行する処理も書いておきましょう。

```index.ts
import * as util from './util';
console.log("Hello World!");
util.hoge();
```

これで無事にコンパイルできました。

## コンパイルされた結果の`index.js`を実行してみる。

```shell
node ./build/index.js
> Hello World!
> This is Util!
```

いけました。


さて、`tsconfig.json`についてまだ触れていませんが
何やら長くなってしまったので続きはまた今度。

お疲れ様でした。

# 追記

[TypeScriptのtsconfig.jsonをあれこれしてみた　その２](https://qiita.com/Nekonecode/items/a6bf0464b2d66e9086f9)
iPad pro 256GB  + Apple Pencil を1年ぐらい悩んでついに買った、手足が自由になるんだ

- 外部デバイスは人間の手足の自由さである
- 思ったときにお絵かきができないという手足が自由に動かないもどかしさを感じていた
- iPad mini を指で書くのと iPad Pro Apple Pencil とは神と子供ぐらいの違いを感じた
- これでエンジニアリングの絵とかをばりばり書いていくんだ

I finally bought iPad pro 11 inch and Apple pencil 2nd generation 256GB and get free hand and legs

# Twitter

https://twitter.com/YumaInaura/status/1081121057619161089

![image](https://user-images.githubusercontent.com/13635059/50681874-4d311080-1050-11e9-9574-9f4c4dc321b5.png)

# Cost 150.000 yen

- just a little bit excpensivive
- i dont have a belief of really i will use 
- for only Apple pencil painting i spend money so expensive paper note

# 256GB

- i have a much 2TB of space in i cloud but wanna save local kindle books 
- i wanted to get perfectly FREE so space is valuable even it cost plus 15000 yen

# Cellar

- For Freedom
- Wi-fy only is too troublesome
- i will use second SIM OCN provider's






---

https://twitter.com/yumainaura

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
【scikit-learnメモ】 同じ入力で別の値を予測する複数モデルを同時に作る

# はじめに
入力値は同一で異なる値を予測するモデルを同時並行的に作りたい要件がありました。
scikit-learnのライブラリでこの要件を満たすモデルを作れることがわかったので、その手順のメモです。

# 問題設定
無理矢理感があるのですが、boston datasetを使い、target(=PRICE)の値だけでなく、CRIM(犯罪発生率)の値も予測したいと仮にします。
予測モデルはSVRを使います。
案の定、CRIMの予測値はメタメタになってしまいましたが、その点は大目に見て下さい。

# サンプルコード
以下に、コメント付きのサンプルコードを記載します。
動作確認はWatson Studio上のJupyter Notebookで行いました。

```py3
# データ準備

# 必要ライブラリのロード
import numpy as np
from sklearn.datasets import load_boston
import pandas as pd
from sklearn import preprocessing

# boston datasetの読み込み
boston = load_boston()

# 入力データをデータフレームに
df = pd.DataFrame(boston.data, columns=boston.feature_names)

# 正解データをpriceに
price = boston.target

# 入力データのうち、CRIMも正解データにするため、別変数に読み込む
crim = df['CRIM'].values

# 入力データから"CRIM"の列を落とす
df2 = df.drop('CRIM', axis=1)

# 入力データの正規化 (=X)
sc=preprocessing.StandardScaler()
sc.fit(df2)
X=sc.transform(df2)

# priceとcrimをつないで正解データとする (=y)
y = np.array([price, crim]).T

# モデル学習用データのサイズの確認
print(X.shape)
print(y.shape)

# 学習

# 必要ライブラリのロード
from sklearn.multioutput import MultiOutputRegressor
from sklearn.svm import SVR

# 多値予測モデルの生成
mor = MultiOutputRegressor(SVR(kernel='rbf', C=1e3, gamma=0.1))

# 学習
mor.fit(X, y)

# 予測の実施
p = mor.predict(X)

# 予測結果のサイズの確認
print(p.shape)
```

# (おまけ) モデルをWatson Machine Learning上に登録
今回は、このモデルをWatson Studio上で動かしたい要件があったので、モデルの登録も行いました。手順は基本的に[Watson Studioでscikit-learn機械学習モデルをWebサービス化する](https://qiita.com/makaishi2/items/38371d272d752b6e7647)と同じなのですが、せっかくなので一緒に記載しておきます。


```py3
# 認証情報の設定
wml_credentials={
  "apikey": "xxxx",
  "instance_id": "xxxx",
  "password": "xxxx",
  "url": "https://us-south.ml.cloud.ibm.com",
  "username": "xxxx"
}

# Watson ML clientオブジェクトの生成
from watson_machine_learning_client import WatsonMachineLearningAPIClient
client = WatsonMachineLearningAPIClient(wml_credentials)

# Watson ML にモデルの登録
published_model = client.repository.store_model(model=mor, meta_props={'name':'Multi Classifier Sample'}, \
training_data=X, training_target=y)
    
```
snapのcoreを含む全ての機能のアンインストール

スーパーユーザで作業します。

```
apt-get purge snap snapd
umount $(mount | grep snap | awk '{print $3}')
rm -rf /var/lib/snapd
rm -rf /var/snap
find /etc/systemd/system -name "*snap-*.mount" -delete
find /etc/systemd/system -name "snap.*.service" -delete
rm -rf /snap
```

以上。
google-drive-ocamlfuseが動かなくなったら

google-drive-ocamlfuseがdevice or resource busyを吐いて
動かなくなったので、色々試行錯誤をしていましたが、次の手順で動きました。

```
rm -rf ~user/.gdfuse
```
なんか設定ファイルがおかしくなってたようで、gdfuseの設定
ファイルを全部削除することによって動きました。
[rails] form_tag method: getでURL params を送る方法

1, URLにselectboxを使ってuserにparamsを送る
2, ついでにselectboxで選んだらすぐsubmitしたい。

```erb
[_filter.html.erb]

<%= form_tag request.path, method: :get do %>
  <%= hidden_field_tag :size, params[:size] %>
  <%= hidden_field_tag :view, params[:] %>
  <%= select_tag(:sort,
      options_for_select(@product_filter.sort_select_collection, 
      { selected: params[:sort] || 'newest' }), 
       class: 'select-drop', 
       onchange: 'this.form.submit();') 
  %>
<% end %>
```


controller側で、params[:size],params[:color]で受け取れる。
BlockWallet

こんにちは、私はグウェン([https://twitter.com/gwenskiesHere](https://twitter.com/gwenskiesHere))です。今日年の１２月２０日に、私たちはデモがありました。私はBlockWalletについて話しましたですから、これを話し合いましょう。

![Untitled presentation (1).png](https://qiita-image-store.s3.amazonaws.com/0/300937/e1a8f1d5-035a-9ff5-dbeb-3b7bf5619b51.png)

#BlockWalletについて
BlockWalletはブロックチェーンのサンプルです。対象者はブロックチェーンを知らない人やトークンを使ってみたい人です。このワレットはEthereum　ワレットです。Ethereum cryptocurrencyを使ったですからEthereumトークンを貰うことができます。このトークンはetherというです。でも、自分のトークンも作ることができます。この自分のトークンはERC223のトークンスタンダードを使いました。

*ERC223について、[リンク](https://qiita.com/gwenmerida/items/9b440d61264d118dae66)をクリックしてください。*

#使用されるツール
<img width="1029" alt="Screen Shot 2019-01-04 at 5.15.55 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/300937/f2dd389e-9fac-52e0-172e-551885a4fbb8.png">
この図は使った技術を示しました。react nativeでフロントエンドを作って、nodejsはethereumブロックチェーンに接続するためにwebjsに統合されました。
postmanはバックエンドのテストに使って、エクスポをフロントエンドのテストに使用しました。データベースとしてFirebaseが使用されしました。

#BlockWalletのできること

BlockWalletは自分のアカウントを作ります。IDを入力して,ログインをします。
QRコードで、他の人のウォレットに送金ことができます。グループも作ります。グループではグループ専用のトークンを作成できます。メンバーを追加して、送りあうことができます。

*BlockWalletのサムプルのビデオは[リンク](https://drive.google.com/open?id=19bHgHrc991hXqj8wC2K-Eq7WI6HulNqn)をクリックしてください。*
bat_バックアップ用バッチ(タイムスタンプ付き)


#1.概要
ファイルをバックアップするバッチファイル
ファイル名の後ろに日付時刻(秒まで)のタイムスタンプが付加される。
※バッチファイルの作成は初なので素人構文です。

#2.ソースコード

```
rem タイムスタンプ付きバックアップ用プログラムです。
::1.バックアップしたいファイルの直下にでのみ動作します。
::2.myFileNameにバックアップしたいファイル名(相対パス)を設定してください。
::コピーの際はファイル名に秒までのタイムスタンプが付加されます。
::3.BuckUpDirにバックアップ先のディレクトリ名を設定してください。
:: (存在しなければ作成されます。"にすると直下にバックアップされます")
::【備忘録】「date」や「time」の変数を使用する。ただし、ファイル名に使えない「/」が入っているため、文字抽出を行う」
:: 環境変数として参照する場合はそれぞれ「%date%」「%time%」

@echo off

::☆☆☆☆このファイル名を変更してください☆☆☆☆☆
set myFileName=test.txt
set BuckUpDir=BuckUp\
::☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆


:: batのフォルダをカレントにする
cd /d %~dp0

::今日の日付を取得
set date2=%date%

::date2から数字を抽出。「%date2:~0,4%」はdate2の1文字目以降から4文字を抽出する。
set date3=%date2:~0,4%%date2:~5,2%%date2:~8,2%

::timeから空白文字を0に置換
set time2=%time: =0%

::time2から秒までの数字を抽出
set time3=%time2:~0,2%%time2:~3,2%%time2:~6,2%

echo %time2%

call :GET_FILENAME %myFileName%
call :GET_FILEEXTEND %myFileName%

::タイムスタンプ用の文字列作成
set timestamp=%BuckUpDir%%GET_FILENAME_BUF%_%date3%_%time3%%GET_FILEEXTEND_BUF%

::Xコピーで実行。モードはファイル"F"。
echo F | XCOPY %myFileName% %timestamp%

::pause -> nul

::------------関数-------------------------
::ここから下の関数は実行後、「関数名_BUF」に値を代入する
::メインで実行後、バッファを使用すること


::拡張子を除いたファイル名を取得
:GET_FILENAME
set GET_FILENAME_BUF=%~n1
exit /b 0

::拡張子を取得
:GET_FILEEXTEND
set GET_FILEEXTEND_BUF=%~x1
exit /b 0
```
atcoder ABC111 C問題

ABC111　C問題の解法をメモ
方針は簡単にたつが、コーナーケースをしっかり対策しないとすぐにWAが出るので注意が必要

https://atcoder.jp/contests/abc111/tasks/arc103_a

#考え方
問題は、与えられた数列に対し偶奇で分け、その中で最頻数を見つけその数以外の数字についてカウントしていくものである。ここで偶奇の最頻数が同じだった時は、偶奇のどちらかを変えなければならないので、それぞれについて2番目に頻度の高いものも変数として持っておく。
Docker Registry構築メモ

## スペック
Ubuntu 16.04
CPU: 2コア
Memory: 4GB

## 構成
- 認証
  - htpasswdのファイルで管理
- フロント
  - 別のNginxでSSL終端させる
  - ここは省略。SSL終端させて、5000ポートにプロキシさせれば動く

## 導入手順
### Dockerの導入
```
sudo curl https://releases.rancher.com/install-docker/17.03.2.sh | sh
sudo gpasswd -a ubuntu docker
sudo systemctl restart docker
sudo curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo restart
```

### htpasswd生成
```
mkdir -p ./registry/auth
docker run --rm --entrypoint htpasswd registry:2 -Bbn <username> <password> > ./registry/auth/htpasswd
```

### Docker Compose
```docker-compose
version: '3'
services:
  registry:
    restart: always
    image: registry:2
    ports:
      - 5000:5000
    environment:
      REGISTRY_HTTP_SECRET: <適当な文字列>
      REGISTRY_AUTH: htpasswd
      REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
      REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
    volumes:
      - ./registry/data:/var/lib/registry
      - ./registry/auth:/auth
```

## ログイン
```
docker login <registryのURL>
```

## 参考
https://github.com/docker/distribution
【Go言語】個人的に1番良さげなDecoratorパターンの実装

# はじめに

Golangで実装するDecoratorパターンについて勉強した際、参考資料に載せてあるように多くの方法がありました。

**どんな実装が1番良いか模索した結果、個人的に↓で書いたコードが一番読みやすくて良いかなと思いました。**

# コード
今回実装したコードについて説明します。
**Decoratorパターンを使ってデフォルトのアバターをカスタマイズし、装備を着けて強化していくプログラムになっています。**

仮にDecoratorパターンを使わない場合、最初から装飾されたオブジェクトを用意しておいて生成する方法になると思いますが、
装備が増えた時に全パターン分用意することになるので、コード数がかなり多くなってしまいます。
なら装備を部品として用意してアバターに柔軟に着けていくのが一番良さそうです。

```golang:main.go
type Avatar struct {
	Name       string
	HP         int
	WeaponList []string
}

type CustomizerFunc func(*Avatar) *Avatar

func Custom(i *Avatar, customizerFuncs ...CustomizerFunc) {
	for _, customizerFunc := range customizerFuncs {
		i = customizerFunc(i)
	}
}

func Attach(weapon string, hp int) CustomizerFunc {
	return CustomizerFunc(func(i *Avatar) *Avatar {
		i.WeaponList = append(i.WeaponList, weapon)
		i.HP += hp
		return i
	})
}

func main() {
	// default Avatar
	avatar := &Avatar{Name: "久川善法", HP: 100}
	fmt.Printf("カスタマイズ前：%+v\n", avatar)

	// custom Avatar
	Custom(avatar, Attach("gun", 1), Attach("helmet", 10))
	fmt.Printf("カスタマイズ後：%+v", avatar)
}

// カスタマイズ前：&{Name:久川善法 HP:100 WeaponList:[]}
// カスタマイズ後：&{Name:久川善法 HP:111 WeaponList:[gun helmet]}
```

# コードの解説

### ・型定義
予約語である```type```を使って、既存の型や型リテラルに別名をつけることができます。
関数型の```CustomizerFunc型```を定義しました。
引数で```Avatar```を受け取り```Avatar```を返す関数です。

```golang
type CustomizerFunc func(*Avatar) *Avatar
```

### ・デコレータパターンの実装
上記で定義した```CustomizerFunc型```を複数受け取り、順番にその関数を実行しています。
```i = customizerFunc(i)```とあるので、```Avatar```を受け取って```Avatar```を返しています。

```golang
func Custom(i *Avatar, customizerFuncs ...CustomizerFunc) {
	for _, customizerFunc := range customizerFuncs {
		i = customizerFunc(i)
	}
}
```

**※余談**
```i = customizerFunc(i)```
この実装がわかりにくいかもしれないので、他の視点からも。

```golang
func main() {
    // 無名関数を定義しています。
	function := func(str string) string {
		return "*" + str + "*"
    }
    // 引数を渡して無名関数を実行しています。
	f := function("golang")
    fmt.Println(f)
}
// *golang*
```

### ・部品の用意
返り値は```CustomizerFunc```なので、```return CustomizerFunc()```を返しています。
```CustomizerFunc型```は```func(*Avatar) *Avatar```のエイリアスなので、functionを書きます。
そして引数で受け取った```Avatar```のHPやWeaponListに値を追加して返却しています。

```golang
func Attach(weapon string, hp int) CustomizerFunc {
	return CustomizerFunc(func(i *Avatar) *Avatar {
		i.WeaponList = append(i.WeaponList, weapon)
		i.HP += hp
		return i
	})
}
```

**・余談**
個人的に```return CustomizerFunc()```がわかりにくかったです。
簡単な例で同じ実装をすると以下のようになります。

```golang
type Number uint

func main() {
	num := Number(11)
	fmt.Println(num)
}
```

### ・最後にDecoratorを呼び出す

最後に```avatar```を第一引数に渡し、第二引数以降の```Attach```で装飾しています。

```golang
Custom(avatar, Attach("gun", 1), Attach("helmet", 10))
```


# 最後に

Function型のエイリアスを定義することがあまりないので、最初はコードを読むのに苦労しました。
簡単な例に置き換えてみるととてもわかりやすかったです。
個人的に実装してきたデザインパターンの中では一番好きなコードです。


# 参考資料
- https://gist.github.com/alehano/8785933
    - Golangっぽいです。
- https://github.com/monochromegane/go_design_pattern/blob/master/decorator/decorator.go
    - 書籍に書いてあるような書き方の印象
- https://github.com/alex-leonhardt/go-decorator-pattern
    - 9つのDecoratorパターンを紹介しています。すごい色々ある。
- https://gist.github.com/nightmouse/65cb8a01d274c4a6a53e
    - 個人的に一番参考にした記事です。
【個人開発】音楽番組のタイムテーブルから曲を見つけるサイトを作った！

[じぇい](https://twitter.com/jyouj__)です！あけましておめでとうございます。

2019年一発目のサービスをリリースしました！

[Caroling](https://caroling.herokuapp.com/)

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">音楽番組のプレイリストから音楽を見つけられるサービス&quot;Caroling&quot;をリリースしました！㊗️<br><br>YouTubeの公式チャンネルやLINE Musicのリンクも載せているのでそのまま閲覧可能<br><br>音楽の違法ダウンロードがなくなることを願ってつくりました！<br><br>拡散希望<a href="https://t.co/7MaeTXu0uB">https://t.co/7MaeTXu0uB</a> <a href="https://twitter.com/hashtag/%E3%83%97%E3%83%AC%E3%82%A4%E3%83%AA%E3%82%B9%E3%83%88%E3%81%8B%E3%82%89%E9%9F%B3%E6%A5%BD%E3%82%92?src=hash&amp;ref_src=twsrc%5Etfw">#プレイリストから音楽を</a></p>&mdash; じぇい👨‍💻 (@jyouj__) <a href="https://twitter.com/jyouj__/status/1080813481215971330?ref_src=twsrc%5Etfw">January 3, 2019</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# どんなサービス？
音楽番組のセットリストからあの曲もう一度聴きたいなー！という時に音楽を発見できるサービスです！

タイムテーブルになっており、横に公式YouTubeチャンネルやLINE Musicへのリンクも貼っているので、そのまま閲覧することができます。

音楽の違法ダウンロードや違法視聴が問題になっている中、そういったものが少しでもなくなることを願って作りました！

<img width="1300" alt="スクリーンショット 2019-01-04 17.30.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/252295/b0ff0001-008a-c26d-3b2d-ba021e9888f2.png">

<img width="1299" alt="スクリーンショット 2019-01-04 17.31.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/252295/c9d01dfe-2ac8-b4c9-d3fc-4e8c55496e55.png">

# 使った技術
### [Django](https://www.djangoproject.com/)
- 簡単にWebサービスが実装できるPythonのフルスタックフレームワーク
- 管理サイトをすごく活用しました！

### [MaterializeCSS](https://materializecss.com/)
- マテリアルデザインのサイトが作れるCSSフレームワーク
- card, table, buttonを使ってアクセントを出した

### [django-admin-sortable](https://github.com/alsoicode/django-admin-sortable)
- 手動でモデルの順番を管理サイトからいじれるライブラリ

### [FontAwesome](https://fontawesome.com/)
- ほんと驚くばかり！

# ちょっとした問題
YouTubeや配信サイトのリンクがない時、Noneとテンプレート上に表示されてしまって、かっこ悪いので

```html
{% if not song.link == None %}
<td><a href="{{ song.link }}">配信へ</a></td>
{% else %}
<td></td>
{% endif %}
```

このようにテンプレート上でif-else文を使って表示するかしないかを実装しました。もっとスマートなやり方があると思うんですが、うーむ。

# 最後に
今回はそんなに難しいことはしてないですね。uuidを初めて導入してみましたが、いいですね！

タイムテーブルや歌番組のデータが増えてきて、サイト自体のアクセスが増えてきたら、REST APIでも作って公開しようかな、と
思ってます。

いいね待ってまーすw
Rails5 jQueryでsubmitした時の、InvalidAuthenticityTokenエラーを解消する

## 発生した問題

jQuery を利用して、select ボックスを変更した際に、サブミットしたら `ActionController::InvalidAuthenticityToken` エラーが発生したのでその解決方法のメモ。

<img width="884" alt="スクリーンショット 2019-01-04 17.50.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/263973/7708e02a-ada9-d8e0-7219-add460c8fee5.png">


## 環境

```bash
$ rails -v
Rails 5.2.2

$ ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin18]
```

```ruby:Gemfile.lock
jquery-rails (4.3.3)
  rails-dom-testing (>= 1, < 3)
  railties (>= 4.2.0)
  thor (>= 0.14, < 2.0)
```

[bootstrap 4.2.1](https://getbootstrap.com/) を利用しています。

## 解決方法

```erb
<%= form_for @content, url: content_path(@content), html: {id: "edit_content_status"} do |form| %>
  <div class="form-group">
    <%= form.label :status %>
    <%= form.select :status, Content.status.keys, {}, :onchange => '$("#edit_content_status").submit();', class: "form-control" %>
  </div>
<% end %>
```

`authenticity_token` パラメータをPUT時に一緒に含めてあげればいいので、 [form_for](http://railsdoc.com/references/form_for) のオプションとして、 `authenticity_token: true` を設定してあげる。

```erb
<%= form_for @content, url: content_path(@content), html: {id: "edit_content_status"}, authenticity_token: true do |form| %>
  <div class="form-group">
    <%= form.label :status %>
    <%= form.select :status, Content.status.keys, {}, :onchange => '$("#edit_content_status").submit();', class: "form-control" %>
  </div>
<% end %>
```

すると、

```
Parameters: {"utf8"=>"✓", "authenticity_token"=>"L00Q20kOGwpkGAq6MI8DucZwtbCSsb4dkAz1ygZbOV+8ITLLaAoYSdi7w+khFr3TB04GaEPCSp0I9TLPrdbnWA==", "content"=>{"status"=>"published"}, "id"=>1}
```

といったように、 `"authenticity_token"` が iuput タグとして出力され、一緒に送信されるようになる。

## 補足情報

```js:app/assets/javascripts/application.js
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's
// vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//

//= require jquery
//= require jquery.turbolinks
//= require turbolinks
//= require rails-ujs
//= require select2
//= require_tree .
```

Content モデルの情報

```ruby:app/models/content.rb
# == Schema Information
#
# Table name: contents
#
#  id         :bigint(8)        not null, primary key
#  status     :boolean          default("draft"), not null
#

class Content < ApplicationRecord
  enum status: { draft: false, published: true }
...
end
```

rails-ujsとjquery-ujsは一緒に使うと、2回送信されたり、ブラウザの開発用コンソールに、アラートが表示されるので、jquery-ujsを使う方法は利用できませんでした。
VirtualBoxのcygwinへのインストール（未遂）

なんでも初めは無駄に苦労する。だからと言って始めなくなるのはダメなんだとわかってはいるけど。

[cygwin + vagrant + virtualbox 環境構築](https://qiita.com/kieaiaarh/items/8f5f9cd888f4ab8fbcb8)

cygwinで入力しようともdos2unixコマンドがないと言われる。
yumもapt-getも動かない。
コマンドってどうやって追加すりゃええねんと思ったら、
インストーラを叩き直すかapt-cygを使うらしい。

```
apt-cyg install dos2unix

MD5 sum did not match, exiting
```

動かないな？
[Cygwinのapt-cyg開発者が完全に開発終了を宣言](https://rcmdnk.com/blog/2017/01/31/computer-windows-cygwin/)
[Cygwinのapt-cygで”MD5 sum did not match”が出てエラーになる現象と対処法](http://nulltaba.com/computer/windows-management/apt-cyg-error-md5sum/)

時代の流れが速すぎておっさんついてけないよ・・・
仕方なくcygwinインストーラを保存して再実行。

ついでにWindows10初期セットアップの際に馬鹿正直に日本語で入力してしまい、
usersフォルダのパスが実名になっているのを直す。
[Windowsを英語表記のアカウントに変更する](https://nw.myds.me/gimp/change-jpn-account/)

```
$ dos2unix /cygdrive/c/HashiCorp/Vagrant/bin/vagrant
dos2unix: 一時出力ファイルを開くのに失敗しました: Permission denied
dos2unix: ファイル /cygdrive/c/HashiCorp/Vagrant/bin/vagrant 変換中に問題が発生しました。
```
なんでやねん。
ってインストールユーザとログインユーザが違うからか？
と思ってアンインストール＞再起動＞再インストール　でも同じ。

[Cygwinを管理者として実行するでした](http://take-web.com/brog/2015/02/16/post-6371/)
そんなオチかよ・・

```
$ dos2unix /cygdrive/c/HashiCorp/Vagrant/bin/vagrant
dos2unix: バイナリ文字 0x00 が 1 行目で見つかりました
dos2unix: バイナリファイル /cygdrive/c/HashiCorp/Vagrant/bin/vagrant をスキップしています
```
・・・これ成功してるとはとても思えないんだけど？

```
$ vagrant box add base https://files.vagrantup.com/lucid32.box
An error occurred while downloading the remote file. The error
message, if any, is reproduced below. Please fix this error and try
again.

Failed to connect to hashicorp-files.hashicorp.com port 443: Timed out
```
はいダメー
てか単純にlucid32.boxとかいうのが無いのでは。

```
$ vagrant box add base https://github.com/CommanderK5/packer-centos-template/releases/download/0.6.7/vagrant-centos-6.7.box
==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'base' (v0) for provider:
    box: Downloading: https://github.com/CommanderK5/packer-centos-template/releases/download/0.6.7/vagrant-centos-6.7.box
    box: Download redirected to host: github-production-release-asset-2e65be.s3.amazonaws.com
    box: Progress: 0% (Rate: 116k/s, Estimated time remaining: 3:15:47)
```
あ、なんか動いてるっぽい。拡張子が.boxになってればいけそう。
でもダウンロード環境が貧弱なので断念。

さて・・・明日から当面ネット環境がないんだがどうするかな。
ポケットWiFiでも借りようかな。
なんかこのダウンロード、ctrl-cしても止まんないんだけど。
ps見てもプロセス居ないし。linuxはほんと謎だな・・・先は長い。
別のデータベースからWordpressの投稿を取得してまとめて出力する

#やりたいこと
同一サーバー内にマルチドメインで作成した2つのWordpressサイト(サイトA,サイトB)のそれぞれの投稿記事をまとめて一カ所に投稿日順で出力したい。

##前提スキル
Wordpressサイトの構築は実務で3年弱の経験があるが、PHPやSQL発行は初心者。

##アプローチ
サイトA側でWordpressのwpdbクラスを使いつつ、サイトAとサイトBのクエリデータを結合した上で、それぞれの投稿をまとめて出力する。
feedを使う方法も検討しましたが、カスタムフィールドの取得や、ドメイン移管前という環境もあり断念しました。

##function.php
```php

/**
 * switch_blog 用に wp_upload_dir() の返り値を書き換え
 */
function _switch_blog_upload_dir( $upload_dir ) {
    $pattern = '/^(https?:\/\/[^\/]+)/';
    $replacement = home_url();
    $upload_dir['url'] = preg_replace( $pattern, $replacement, $upload_dir['url'] );
    $upload_dir['baseurl'] = preg_replace( $pattern, $replacement, $upload_dir['baseurl'] );
    return $upload_dir;
}

/**
 * サイトBに切り替え
 */
function switch_blog() {
    global $wpdb, $backup_wpdb;
    $backup_wpdb = $wpdb;
    $wpdb = new wpdb( 'データベースユーザー名', 'データベースパスワード', 'データベース名', 'データベースホスト名' );
    wp_set_wpdb_vars();
    wp_cache_init();
    add_filter( 'upload_dir', '_switch_blog_upload_dir', 10 );
}

/**
 * サイトAに設定を戻す
 * switch_blog した後は必ずこのメソッドでリセットが必要
 */
function restore_current_site() {
    global $wpdb, $backup_wpdb;
    $wpdb = $backup_wpdb;
    wp_cache_init();
    remove_filter( 'upload_dir', '_switch_blog_upload_dir', 10 );
}
```
functionコードは下記記事を参考にさせて頂きました。
https://2inc.org/blog/2015/10/23/5059/

##post.php
```php

<div class="other-project">
  <h2 class="other-project-title">Recently Project</h2>
<?php //サイトAのクエリを設定
$query = <<<SQL
    SELECT *,0 as flag
    FROM {$wpdb->posts}
    WHERE {$wpdb->posts}.post_status = 'publish'
    AND {$wpdb->posts}.post_type = 'post'
SQL;
switch_blog(); //サイトBに切り替え
$db_name = "サイトBのデータベース名";
$query .= <<<HERE //サイトBのクエリを結合
    UNION
    SELECT *,1 as flag
    FROM $db_name.{$wpdb->posts}
    WHERE $db_name.{$wpdb->posts}.post_type = 'post'
    AND $db_name.{$wpdb->posts}.post_status = 'publish'
    ORDER BY post_date DESC
HERE;
restore_current_site(); //サイトAに戻す
?>
<?php $posts = $wpdb->get_results($query); ?>
  <div class="prjslider">
  <?php
  foreach ($posts as $post): //ループ開始
    setup_postdata($post);

    if ($post->flag == 1) { //サイトA,Bを判定
      switch_blog(); //サイトBなら切り替え実行
    }

      get_template_part('loop', 'module');

      restore_current_site(); //サイトAに設定を戻す

  endforeach; //ループ終了
  wp_reset_postdata();
  ?>
  </div>
  <!-- /prjslider -->
</div>
<!-- /other-project -->
```

##まとめ
会社の先輩に助けてもらいつつ、何とかやりたい事はできました。
ですが、冗長なコードを書いている気がするのと、
そもそももっと手軽な方法があるのでは、と思っております。
優しい諸先輩方がいたら指摘いただけると幸いです。