OmniAICreator/Qiita-1.07M huggingface dataset:
Alfred plugin を作ってみた話

最近 alfred を導入してみました

結構便利な感じです！

便利さについては既に色々な方が書いているので、調べてください😳
[便利なalfred](https://qiita.com/search?utf8=%E2%9C%93&sort=stock&q=tag%3Aalfred)

そして今日有料版購入して欲しい機能があったので、今日作ってみました

できたのがこちら [github](https://github.com/eretica/alfred-open-as-html)

![aaa12335.gif](https://qiita-image-store.s3.amazonaws.com/0/131778/4865670d-78f7-04e2-0841-ff25e20f2c92.gif)

GIFの内容
・ alfred を開いて `html <button>Click Here</button>` 
・ Enter押すと引数のHTMLが既定のブラウザで出力される

作った目的としては、APIの中でエラーが出たときに返ってくるHTMLをぱぱっと表示したかっただけです

例 ) デバッグで帰ってきたHTMLのアレ
<img width="1522" alt="Screen Shot 2018-04-17 at 10.59.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/131778/a037995f-eace-9e81-0207-defc66b7a2e0.png">

↑をコピってをぱぱっと
![aaa1233.gif](https://qiita-image-store.s3.amazonaws.com/0/131778/d7d88592-1424-e0b1-016a-530a73bbd164.gif)

地味に役に立つ（気がする

仕事中に作りたくなって、帰宅中電車でわくわくして、いざやってみると簡単すぎて悲しくなりました

![Screen Shot 2018-04-16 at 23.17.52.png](https://qiita-image-store.s3.amazonaws.com/0/131778/3609eb1c-8c3f-30b4-ea82-fe92f7343baf.png)

GUIで流れ作って

![Screen Shot 2018-04-16 at 23.18.15.png](https://qiita-image-store.s3.amazonaws.com/0/131778/74cae903-1972-6869-1016-a81435b3a2ec.png)

今回はphpで処理書いて

![Screen Shot 2018-04-16 at 23.19.38.png](https://qiita-image-store.s3.amazonaws.com/0/131778/2b108194-9f0e-5576-2068-e1ab503be2dd.png)

指定のファイルを既定のブラウザで開く...

終わり・・・

GUIでちょちょっとやってスクリプトちょちょっと書くだけで終わりました

```php:書いたスクリプト
// 引数を受けとり
$query = "{query}";

// ファイルを出力
file_put_contents('/tmp/open_as_html.html', $query);
```

簡単すぎて逆に辛くなりました。

終わり(´；ω；｀) つ [Download できます](https://github.com/eretica/alfred-open-as-html/releases)
Githubで本名が公開されていてあたふたした件

#背景
RailsTutorialを今更ながら勉強し、個人開発にGit、Githubを導入しました。
#起きたこと
first commit を行い、意気揚々とGithubの画面を見るとそこには本名が。。。
committerとして漢字、フルネームで記載されていました。
慌ててリポジトリーを削除しようとするもまったく削除欄がわからずまたしてもあたふた。。。
#解決策
問題点としては2点あります。
■Gitのユーザ名に本名が登録されている件
Gitの初期設定を忘れていた模様。
忘れずやりましょう。
参考記事：https://qiita.com/428desmo/items/307e33ceff168966fa50

■Githubのリポジトリーが削除できない件
こちら「setting」下の方に「Danger Zone」と記載された箇所がありそこに削除用のボタンがありました。
よく確認しましょう（教訓）
参考記事：https://qiita.com/PlanetMeron/items/4d164eff7bff2243cf06

#終わりに
GithubにAWSのキーを公開して。。。みたいな記事はちらほら見ていたので自分も公開する情報には気をつけようと肝に命じていたが、まさか本名を公開していたとは笑
amp-social-shareでfacebookを使う場合のdata-param-app_idデフォルト値

# あらすじ
エンジニアとして働く傍ら、友達と映像制作なんかをしていると、
「Webサイト作ってよ。エンジニアなんでしょ？」という流れになりますよね。
![Green12_fax20141123134902_TP_V4.jpg](https://qiita-image-store.s3.amazonaws.com/0/27851/a721dabc-a40c-8f86-feb5-82e2391089b3.jpeg)

おーしやったろうじゃねぇか。
なになに？最近はAccelerated Mobile Pagesてのがあるんだって？
新しいモノには挑戦しないとな！

なんて始めるのがエンジニアですよね。

せっかくだしシェアボタンでも付けるかー。
コンポーネントもあるし、楽勝楽勝。


と考えていた僕ですが、甘っちょろかったです。

[data-param-app_id](https://www.ampproject.org/docs/reference/components/amp-social-share)？
[facebook for developers](https://developers.facebook.com/apps)の登録…？

えぇい、そんな仰々しいものでもない、ただのサイトなんだ！
ということでググった結果、デフォルト値がありました。
# 環境
[Firebase](https://firebase.google.com/?hl=ja)
# 結論
"145634995501895"を指定すれば良かった。

``` html:サンプルコード
<script async custom-element="amp-social-share" src="https://cdn.ampproject.org/v0/amp-social-share-0.1.js"></script>
・・・
</head>

<body>
・・・
<amp-social-share type="facebook" data-param-app_id=145634995501895></amp-social-share>
```
# サイト
Wild Campers Film Official Home Page
https://wild-campers-film.firebaseapp.com/
# 参考
AMPからFacebookへのシェア時に「Invalid App ID: 0」とエラーを吐く際の対応
https://notes.muo.jp/1702_amp-facebook-share.html
「yarn upgrade パッケージ」で引っかかったこと

現代的なプログラミングには欠かせないパッケージマネージャーですが、Bundlerと同じ感覚でyarnを使ったところ、ハマる例が出てしまいました。

# 失敗談

Bundlerで一気にアップデートしたら、必要ないパッケージまで上がってしまって困った、ということがあったので、yarnでも同様に`yarn upgrade some-package`のようにして、1つのパッケージだけバージョンを上げようとしました。

ところが、それを行ったあとにバンドル後のJavaScriptを見れば、一気に容量が膨れ上がっていました。確認してみると、内部で使っているパッケージの違うバージョン2つが取り込まれてしまっていたのでした。

## 事態の問題点

同じパッケージが複数入ってしまうと、当然容量は増えますし、それ以外にもルーターなど状態を持つパッケージが複数入ってしまうと、「ルーターA」と「ルーターB」で別の状態を持つ、なんてことになってしまって、正常動作しなくなります。

# 傾向と対策

Bundlerでは「同じパッケージは1つしか入れられない」のですが、Node.js環境ではパッケージをグローバルにさらさず、`require`や`import`でローカルな名前をつける形となるので、同じパッケージを複数インストールすることも可能なのです。これが逆に仇となったわけです。

そして、一部だけ`upgrade`すると、指定したパッケージの依存パッケージまでまとめて`upgrade`されるので、`upgrade`しないパッケージとの間でバージョン差が出てしまいます。yarnについては、「基本`yarn upgrade`で更新して、特定バージョンがまずい場合には`package.json`に明記する」という形にしたほうがいいかも知れません。
treeコマンドの罫線をタブにする (Linux, Mac, Windows対応)

# はじめに
treeコマンド結果の罫線を消したいことがあります。

```bash
$ tree ./directory0
./directory0
├── directory1
│   ├── directory2
│   │   ├── directory3
│   │   └── file3
│   └── file2
└── file1
```

そんな時に使えるfilterを書きました。
以下のように罫線が消えてタブでインデントされます。
Excel等に貼り付けて資料化するのに便利です。

``` bash
$ tree ./directory0 -J | ./filter.sh
./directory0/
        directory1/
                directory2/
                        directory3/
                        file3
                file2
        file1
```

以下リポジトリで公開しています。
https://github.com/loftkun/indent-filter-for-tree

# for Linux, Mac
## 前提条件
- jq
- python3.x

## Usage

```bash
git clone https://github.com/loftkun/indent-filter-for-tree.git
cd indent-filter-for-tree/linux
tree ../test/directory0 -J | ./filter.sh
```
## treeコマンドとの比較(再掲)
罫線が邪魔だが、、、

```bash
$ tree ./directory0
./directory0
├── directory1
│   ├── directory2
│   │   ├── directory3
│   │   └── file3
│   └── file2
└── file1
```

これならすっきり資料化できます。

```bash
$ tree ./directory0 -J | ./filter.sh
./directory0/
        directory1/
                directory2/
                        directory3/
                        file3
                file2
        file1
$
```

# for Windows
## 前提条件
- Windows Powershell

## Usage
filterを作成。IndentFilterと命名(filter.ps1を参照)。

```powershell
PS C:\test> filter IndentFilter {
% { $_ -replace "^(.*[+,\\\\]-.*)$","$&\" } |
% { $_ -replace "\|   " ,"`t" }  |
% { $_ -replace "\+---" ,"`t" }  |
% { $_ -replace "\\---" ,"`t" }  |
% { $_ -replace "    "  ,"`t" }  |
% { If ( $_ -notmatch "`t+$" ){$_} }
}
```

IndentFilterを使う

```powershell
tree /F /A TARGET_DIRECTORY | IndentFilter
```

## treeコマンドとの比較
罫線が邪魔だが、、、

```powershell
PS C:\test> tree .\directory0 /F /A
C:\TEST\DIRECTORY0
|   file1
|
\---directory1
    |   file2
    |
    \---directory2
        |   file3
        |
        \---directory3
PS C:\test>
```
これならすっきり資料化できます。

```powershell
PS C:\test> tree .\directory0 /F /A | IndentFilter
C:\TEST\DIRECTORY0
        file1
        directory1\
                file2
                directory2\
                        file3
                        directory3\
PS C:\test>
```
Vulkan のインストールと導入(windows VisualStudio 2017)


[目次に戻る](https://qiita.com/tositada_nakada/items/db0f01c1c8c2945f786b)

#はじめに
qiita初投稿で慣れていませんがよろしくお願いします。

##目的
Visual studioでVulkanを開発する環境をまとめる。

##実行環境
[OS] windows10
[GPU] Gtx 1080 & intel graphics 520

##Vulkanとは
・khronosの新しいAPI
・OpenGLが時代に合わなくなったから作られた。次世代のグラフィクスAPI

![ダウンロード (2).jpg](https://qiita-image-store.s3.amazonaws.com/0/251306/3b0b4284-1087-cb72-2604-b2c641083c53.jpeg)


#WindowsPCにインストール

###ご所有のPCパーツが対応しているバージョンを選びましょう

[intel グラフィクス対応API表](https://www.intel.co.jp/content/www/jp/ja/support/articles/000005524/graphics-drivers.html)
[Nvidia geforce グラフィクス対応表](https://developer.nvidia.com/vulkan-driver)
[AMD対応](https://www.amd.com/ja/technologies/vulkan)



##必要なもの
・visual stdio 2015以降 (2017推奨)
・グラフィクスドライバー
・cmake version 3.7以降
・python3 
・lunarG Vulkan SDK(自分のPCパーツに合わせて)lunarG vulkan sdk以下VulkanSDK と、表記します

これらのソフトを各自インストールします。

##visual stdioで開発
visual stdioの起動
新しいプロジェクト → c++ → コンソールアプリケーション
<img width="643" alt="スケッチ (6).png" src="https://qiita-image-store.s3.amazonaws.com/0/251306/2bbf4e3c-c714-6c6c-31eb-2ac005feeed1.png">
上のプロジェクトタブから、プロパティを選ぶ
<img width="555" alt="スケッチ (7).png" src="https://qiita-image-store.s3.amazonaws.com/0/251306/c94cfabf-1ea8-e2ec-9d4c-89df17634d01.png">
構成プロパティ →　VC++ディレクトリー → インクルードライブラリーにvulkanSDK/includeのアドレスを入れる。

構成プロパティ →　VC++ディレクトリー → ライブラリーディレクトリーにvulkanSDK/Binのアドレスを入れる。

<img width="549" alt="スケッチ (8).png" src="https://qiita-image-store.s3.amazonaws.com/0/251306/bb9b3788-0ab2-f8bb-cb00-e7f7c45979fd.png">
リンカー → 入力 → 追加の既存ファイルに「vulkanSDK/lib/vulkan-1.lib」を追加



以上が終われば、楽しくVulkanの開発がwindowsでできるようになります。
##終わりに
Vulkanが流行るか分からないけど。そろそろ勉強します。

## 連絡先

tweeter: [tositada_nakada](https://twitter.com/nakadasanda17)
mail: nakadasanda@outlook.com

## 寄付

paypal: [tositada_nakada](https://www.paypal.me/nakadasanda)
Amazon: [欲しいものリスト](http://amzn.asia/fGpGuJo)
【JavaScript】配列の書き方と定義してある配列の値（value）を取得するメソッド


# JavaScriptの配列

PHPばっか触ってると他の言語で配列をどーやって書くのかすぐ忘れます。
特にJavaScriptとか忘れる。すぐ忘れる。

# 配列のvalueを取得する処理

配列を書きつつ、引数で受け取った`key`に対応する`value`を取得するメソッドも書き記しておきます。
評価の値によって★の数を取得する処理とかこんなかんじですかね

```.js:star.js
/**
 * 評価値に対応するvalueを返す
 * @param key 評価値
 */
function stars(key)
{
    var stars = {
        '0' :'☆☆☆☆☆',
        '1' :'☆☆☆☆★',
        '2' :'☆☆☆★★',
        '3' :'☆☆★★★',
        '4' :'☆★★★★',
        '5' :'★★★★★',
    };

    return stars[key];
}
```

# おわり
- こんな書き方もできるみたいですね、てことで
- `var`より`const`のがいいのかしら:princess:？
アクセス元のIPアドレスで処理を分岐させる

# アクセス元によって処理を分岐させたい

たまにあると思われるので、メモ。
スニペット的にコピペして使おう。

## どんな場面？

アクセス元によって処理を分けたい時はまれによくあります。
例えば

* 深夜帯は公開側がメンテナンスになるけどその時間に表示の確認を行いたい。
* 自分のサイトに自分だけのバックドアを作成したい。
* 管理者専用のメニューを表示したい。

などなど

## 書き方

こんな感じに単純に。

```PHP
<?php
if($_SERVER['REMOTE_ADDR'] === "xxx.xxx.xxx.xxx"){
	//IPアドレスが一致した場合の処理
}else{
	//IPアドレスが一致しなかった場合の処理
}
```

これでOKですよ(^o^)
OnsenUIのons-lazy-repeatをリストの要素番号を取得する

# はじめに
OnsenUIのons-lazy-repeatを使ってons-listを表示させ、タップしたリストの要素番号を取得するプログラムをご紹介します。
今回は基本的なOnsenUIを使って実装していきます。
※Angular,React,Vueのフレームワークは使用しません。

# ons-lazy-repeat
このコンポーネント内で描画されるアイテムのDOM要素の読み込みは、画面に見えそうになった時まで自動的に遅延され、画面から見えなくなった場合にはその要素は動的にアンロードされます。このコンポーネントを使うことで、パフォーマンスを劣化させること無しに巨大な数の要素を描画できます。
![test.gif](https://qiita-image-store.s3.amazonaws.com/0/247084/e276ea8d-4a94-6435-334b-0044ef87dca6.gif)


コードや基本的な情報はOnsenUIのサイトに公開してあります。
https://ja.onsen.io/v2/api/js/ons-lazy-repeat.html

# コード
```html:index.html
<ons-list>
  <ons-lazy-repeat id="infinite-list"></ons-lazy-repeat>
</ons-list>
```
```javascript:app.js
ons.ready(function() {
  //infinite-listを取得
  var infiniteList = document.getElementById('infinite-list');

  infiniteList.delegate = {
    //repeatさせたいリストを作成 ※iはcountItemsでのデータ数
    createItemContent: function(i) {
      //dataは関数に渡したい値をいれてください
      return ons.createElement('<ons-list-item data="'+ i +' onclick="showIndex('+ i +')" tappable">Item '+ i +'</ons-list-item>');
    },
    countItems: function() {
      //データ数
      return 10000;
    }
  };

  infiniteList.refresh();
});

function showIndex(index){
  ons.notification.alert(index+'　がタップされました');
}
```

# 実行
![test.gif](https://qiita-image-store.s3.amazonaws.com/0/247084/ef1821e8-ee72-7727-cc30-0854321bcb75.gif)

# はまったこと
ons-list-itemの要素にdata="i"を加えないと引数が存在しないとエラーが出ました。

```javascript:app.js
createItemContent: function(i) {
  //dataは関数に渡したい値をいれてください
  return ons.createElement('<ons-list-item data="'+ i +' onclick="showIndex('+ i +')" tappable">Item '+ i +'</ons-list-item>');
}
```
※ただしオブジェクトを渡すことはできないみたいです。

# まとめ
今回はons-list-itemをタップしたときに値を関数に渡しましたがリストだけでなくさまざまなモノにも適用できるのでぜひ使ってみてください！！
※ただしオブジェクトを渡すことはできないみたいです。
プリントできる画像クラスを書いてみた

# まえおき

この時期は新入さんが入ってきてプログラミングを基礎から教える機会も多いですね．プログラミングの入口といえばやっぱり**Hello, World!**でしょうか．C#だとこんな感じですね．

```cs
System.Console.WriteLine("Hello, World!");
```

さて，プログラミングに不慣れな新人さんは怖いもの知らずにこんなコードも書いちゃいます．

```cs
System.Console.WriteLine(42);
```

いやいや文字列を渡さないと．．．と思いきや，しっかりと動いてくれますね．
C#のConsole.WriteLineはいろいろな**オーバーロード**が用意されています．上の例だとWriteLine(int value)が呼ばれます．

さて他のオーバーロードも見てみると，Write(object value)というのも用意されています．object型が渡せるということは何でもWriteLineできるということですね．ToStringメソッドの結果を標準出力に表示してくれます．

ここで，新人さんはこんなコードを書いちゃうかもしれません．

```cs
var bmp = new Bitmap("pronamachan.png");
System.Console.WriteLine(bmp);
```

実行結果はこんな感じです．

```console
> foo.exe
System.Drawing.Bitmap
```

これは，，，，:scream:
新人さんはこんな地味な結果を期待してはいなかったはず．何とかしないとプログラミングに興味をなくしてしまうかもしれません！

# ほんだい

前置きが長くなってしまいましたが，新人さんのモチベを下げないためにも，プリントできる画像クラスを書いてみました．

```cs
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Linq;

namespace PrintableBitmap
{
    class PrintableBitmap
    {
        public Bitmap Bitmap { private set; get; }
        public PrintableBitmap(string filename) => Bitmap = new Bitmap(filename);
        public override string ToString()
        {
            int w = Bitmap.Width;
            int h = (int)(Bitmap.Height * 0.42);
            int height = 64;
            int width = (int)(w / (float)h * height);
            var resizebmp = new Bitmap(Bitmap, width, height);
            var text = new StringBuilder((width + 1) * height);
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    var pxl = resizebmp.GetPixel(x, y);
                    text.Append(ToChar((byte)((pxl.R + pxl.B + pxl.G) / 3)));
                }
                text.Append('\n');
            }
            return text.ToString().TrimEnd('\n');
        }
        private char ToChar(byte pixel)
        {
            var table = new List<(byte p, char c)>
            {
                (249, ' '), (239, '`'), (233 , '.'), (217 , ','), (198 , '-'), (185, '~'), (173, '+'),
                (160, '<'), (147 , '>'), (134, 'o'), (109, '='), (83, '*'), (52, '%'), (13 , 'X'), (0, '@')
            };
            return table.SkipWhile(x => x.p > pixel).First().c;
        }
    }
}
```

クラスを作ってToStringメソッドを**オーバーライド**すればいいですね．いい感じに表示されるように高さを適当に縮めてサイズを決めて，RGBの平均値をとってグレースケールにしたあとASCII文字に変換してます．ちなみにBitmapクラスは`sealed`だったので継承せずにこんな感じで実装しています．あとC#は久しぶりに書いたのですが，C#7で導入されたタプルを使ってみました．便利ですね．

使ってみるとこんな感じです．

```cs
var bmp = new PrintableBitmap("pronamachan.png");
System.Console.WriteLine(bmp);
```

<img width="860" alt="image2.png" src="https://qiita-image-store.s3.amazonaws.com/0/45310/776b87df-f3d2-c06c-9579-d51d9fc7590f.png">

まずまずじゃないでしょうか．これなら新人さんも楽しくプログラミングを続けられるかもですね:muscle:
Storyboardを使わずにコードでレイアウトするときに使えるSourceEditorExtension

SwiftでStoryboardを使わずにコードだけで画面のレイアウトを書く際に、毎回おまじないのように書くコード（translatesAutoresizingMaskIntoConstraintsやNSLayoutConstraintなど）が多いので、コマンド一発である程度補完できるようになる、ちょっとだけ便利なSourceEditorExtensionを作ってみました。

https://github.com/shindyu/NSLayoutConstraintSourceEditorExtension

![output.gif](https://qiita-image-store.s3.amazonaws.com/0/130686/90935b35-8fd9-5a59-295c-5a126fb0d4ef.gif)



選択範囲にある変数に対して、translatesAutoresizingMaskIntoConstraints　と、 topAnchor, leftAnchor, rightAnchor, bottomAnchor　の制約を一括で書くことができます。ちなみに複数選択にも対応しています。

```swift

sampleView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
    sampleView.topAnchor.constraint(equalTo: <#targetView#>.topAnchor),
    sampleView.leftAnchor.constraint(equalTo: <#targetView#>.leftAnchor),
    sampleView.rightAnchor.constraint(equalTo: <#targetView#>.rightAnchor),
    sampleView.bottomAnchor.constraint(equalTo: <#targetView#>.bottomAnchor)
    ])
```

リポジトリからgit cloneしてarchive buildした中身を開くとxcode上で使えるようになるので、お好きなキーバインドを割り当てて使ってみてください。中身のコードは結構簡単なのでカスタムしてもいいと思います。よかったらgitのスターください。笑

https://github.com/shindyu/NSLayoutConstraintSourceEditorExtension
職務経歴書をGitHubで書いてみた

[職務経歴書をGitHubで管理しよう](https://qiita.com/okoysm/items/abcad0b4aefa585bc50b)をみて書きたくなったので[書いてみた](https://github.com/suzunoneseven/Curriculum-Vitae)
意外と思い出せないものがあって時間かかった。。。
本名書くのはちょっと怖い
もっと早く書いていれば資格とった日とか書けたのに。。。
日常用語と論文の表現


後輩に役を立つようにまとめして見た。

| 日常用語 | 論文用語 | 例 |
|:--------|:-----------|:---|
|こんな   |このような | このようなデータが数多く見られる |
| たくさんの | 数多く |数多くの問題が生じている |
|いろいろな | さまざまな| さまざまな見方がある |
|少し | わずか |僅かの誤差|
|全部の |全ての|全ての犬|
|よく言われる | いわゆる|これが、よくいわゆるインフレである|
|前に書いた |前述のように|前述のように、この点について|
|後で書く| 後に述べる|この点については後に述べる|
|たち|ら|田中らは|
|両方とも|ともに|男女ともに|
|どんな|どのような/いかなる|どのような方法|
|どれぐらい|如何に/どの程度|この問題が、如何に|
|どちらも|いずれも|AとBはいずれも..|
|だいたい|ほぼ|ほぼ全員|
|全然|全く|全く変化がなかった|
|とても|非常に|非常に高い|
|目立って|著しく|著しく低下|
|ずっと|遥かに|前年度より遥かに高い|
|だんだん|次第に/徐々に|徐々に低下した|
|一番|最も|最も高い|
|いつも|常に|常に改善の必要がある|
|もう|既に|既に指摘|
|まだ|いまだに|いまだに明らかにされていない|
|相変わらず|依然として|依然として続いている|
|たぶん|恐らく|恐らく今後も|
|する|行う|実験を行なった|
|使う|用いる|データを用いる|
|見せる|示す|結果を示す|
|違う|異なる|大きく異なっている|
|見つける|見出す|例に見つけられない|
|書く|述べた|以下に述べる　上で述べた|
FinTechキャッチアップ リンク集

※今後もっと追加していく予定

# ブロックチェーンとは

分散型ネットワーク。

### 参考
[ブロックチェーン - Wikipedia](https://ja.wikipedia.org/wiki/ブロックチェーン)
[5分でわかるブロックチェーンの基本的な仕組み - SlideShare](https://www.slideshare.net/cookle/5-58379474/)
[「ブロックチェーン」とは？今さら聞けない基礎知識を解説｜ferret [フェレット]](https://ferret-plus.com/7706)
[ブロックチェーンの仕組み 〜初心者のためのわかりやすい解説〜](http://gaiax-blockchain.com/blockchain-first-book)


# ブロックチェーン技術

[さまざまなブロックチェーン技術 - Qiita](https://qiita.com/akitoh/items/bebf1bf3d71d3e4b96b0)

# hyperledger

[Tutorial: Hyperledger Fabric v1.1 – Create a Development Business Network on zLinux - GitHub](https://github.com/CATechnologies/blockchain-tutorials/wiki/Tutorial:-Hyperledger-Fabric-v1.1-–-Create-a-Development-Business-Network-on-zLinux)
[Hyperledger Fabric Tutorial](http://hyperledger-fabric.readthedocs.io/en/master/)
Elasticsearch 6.2.3 で インストール済みプラグインのリストを確認する

Elasticsearch を使っていてどんなプラグインを入れたか確認したくなった際のコマンドになります。
内容としては以下のドキュメントから抜粋してまとめたものになります。
[Listing, Removing and Updating Installed Plugins](https://www.elastic.co/guide/en/elasticsearch/plugins/current/listing-removing-updating.html)

手元の環境は以下になります。

* Ubuntu 16.04 LTS
* Elasticsearch 6.2.3

次のように実行します。

```
$ sudo bin/elasticsearch-plugin list
```

プラグインがインストールされていれば以下のような結果になります。

```
analysis-icu
analysis-kuromoji
ingest-attachment
```

プラグインを削除したい場合は以下のように実行します。

```
$ sudo bin/elasticsearch-plugin remove ingest-attachment
$ sudo /etc/init.d/elasticsearch restart
```
Linux メモ


##mkdir option

```
#ディレクトリ下に一気に作成
mkdir -p dir1/dir2/dir3/
#delete
rm -ir dir/dir

#作成する時権限変更
mkdir -m 755 dir
```
##tar

```linux
#fileをアーカイブ　何のfileをアーカイブしているか
tar cf old1.tar file1 file2
less old1.tar

#dirに展開
tar xvf old2.tar -C dir

#dirをtar さらにgzip
tar cvzf old3.tar.gz dir

#dir下に解凍
tar xzvf old.tar.gz
```

##date

```
date '+%Y%m%d %H:%M'
```

crontabの命令ファイルにdate実行する時に、%の前に **¥** を挿入　

##grep

```
#大、小文字区別せず
grep -i error file
 
#keyword含まない
grep -v keyword file

#文頭に最初firstwordとotherword
grep -E '^firstword.*otherword' file
```

##sed 

```
#指定行
sed -n 6,8p file

#word行delete
sed /word/d file

#全てのword置換
sed 's/word/world/g' file
```

##sortとuniq

```
#重複順多い順に並ぶ　重複回数付き 前10行表示
sort file | unic -c | sort -rn | head -n 10
```

##other

```
#-i 間隔 -c 回数
ping -i 2 -c 10 IPadd

cut -c 6- file

#sh入力改行しない
echo -n 

#正規表現
echo -e "W¥nO¥nR¥nd"

tailf -f file &
kill %1

jobs
bg%1 kill%1

ps
kill -1

#ディレクトリのfree space
df -h
```

##入力が数値かcheck

```linux
if[-z $1];then
 echo please input argument ¥n
 exit1
elif[[!"$1"=~^[0~9]+$]];then
 echo please input narural number.
 exit2
fi
```
GitLabとIRCの連携 ( GitLab Integrations )

# はじめに
GitLabとIRC Gateway(irker)を連携させることで、リポジトリへのpushをトリガにcommit内容をIRCチャットに投稿できます。

SlackやMattermostなど今風チャットとの連携の影に隠れてあまり(全く)紹介されていないのと、
irkerの起動方法のドキュメントがない(&若干注意が必要な)ので本記事で紹介します。

動作確認バージョン
GitLab Community Edition 10.6.4
irker (SHA-1) dc0f65a7846a3922338e72d8c6140053fe914b54

参考ドキュメント
https://docs.gitlab.com/ee/user/project/integrations/irker.html

# IRC Gateway(irker)の起動
irkerはGitLabからのcommit&push通知を待ち受け、受信した通知をIRCサーバに送信するツールです。Pythonで実装されています。

```
# Ubuntu 17.10 にて動作確認
# 入手
git clone https://gitlab.com/esr/irker.git
cd ./irker/

# 起動
nohup ./irkerd -H 0.0.0.0 -n GitLab &
```
#### 設定の注意点
##### -Hオプション
GitLabとirkerdを同一ホストで動かす場合、-Hオプションは不要です。
(その場合irkerdはlocalhostから接続のみ受け付けます。)

<font color="OrangeRed">GitLabとirkerdを別ホスト(dockerも含む)で動かす場合、-Hオプションが必要です</font>(このへん早めに気づかないとハマるかも。。)。

##### -nオプション
-nはチャットに書き込む際のusernameです。
<font color="OrangeRed">他のユーザとusernameがとかぶるとチャット投稿に失敗しますので注意が必要です。</font>

##### チャットの文字コード
irkerdは文字コードutf-8でチャットを送信します。
そのため、お使いのクライアントソフトの文字コード設定と相違があると文字化けして表示されてしまいます。
<font color="OrangeRed">例えば[LimeChat](http://limechat.net/)のデフォルトの文字コードはiso-2022-jpですのでそのままですと文字化けします。</font>
クライアントソフト側の文字コードをutf-8にするか(チーム全体で統一が必要です)、以下のようにirkerdの送信処理の実装を書き換えて文字コードをクライアントソフトに合わせましょう。

```python
    def ship(self, string):
        "Ship a command to the server, appending CR/LF"
        try:
            #self.socket.send(string.encode('utf-8') + b'\r\n')
            self.socket.send(string.encode('iso-2022-jp') + b'\r\n')
            LOG.debug("TO: %s" % string)
        except socket.error:
            self.disconnect("Connection reset by peer.")
```
##### うまく動かないときは
-d オプションにdebugを指定すると詳細な動作ログを標準出力に出力しますのでヒントになるかもしれません。

# Integrationsの設定
GitLabのプロジェクト→Settings→Integrations→Irker (IRC gateway)を開きます。

以下は設定例です。
![irc.png](https://qiita-image-store.s3.amazonaws.com/0/21106/4e943a35-7b12-e8c0-e9e8-3c4c13c7ab8b.png)

# 投稿されたチャット内容
pushすると以下のようにチャットされました、しっかりと連携できてます。

```console
20:55 (GitLab) [test] loftkun pushed 1 new commit to master: http://mygithub.com/loftkun/test/compare/8d5a364e...76df7004
20:55 (GitLab) test/master 76df7004 loftkun (1 file): test commit
```

push内容に続けてcommitの内容が投稿されていました。
Mac OSXのコピーペーストをCtrl+C,Vに設定する方法

# Mac OSXのコピーペーストをCtrl+C,Vに設定する方法

> 追記：2019年8月28日
今は、`Ctrl+C,V`でコピペするのではなく、Mac本来の`command + c` `command + v`に戻しました。なぜか、それは、完全に全てのアプリを`Ctrl+C,V`で置き換えることができなかったからです。`command + c` `command + v` に慣れたほうが、長い目で見て、良いのかなと自分は思います。

mac osxだとコピーペーストのショートカットが`command + c` `command + v` なので、これをWindowsっぽく `Ctrl + C` `Ctrl + V` に変更する方法です。 

![keyboard.jpeg](https://qiita-image-store.s3.amazonaws.com/0/11224/1c21d883-6f8d-577e-874a-67d477ec8e64.jpeg)

## まず、`caps`キーを`ctrl`キーに変更

自分的には、ほとんど使用しない`caps`キーを`ctrl`キーに変更します。

![スクリーンショット 2018-04-17 21.01.08.png](https://qiita-image-store.s3.amazonaws.com/0/11224/906bac5f-cec1-8255-6801-1d9d92fa7bbd.png)

## キーボードショートカットを新規作成

`Ctrl + C` `Ctrl + V`用のキーボードショートカットを新たに作成します。

![スクリーンショット 2018-04-17 20.54.23.png](https://qiita-image-store.s3.amazonaws.com/0/11224/3e93f238-6f2e-1dc0-38df-f32845a29f47.png)

最終的には以下のようになります。

![スクリーンショット 2018-04-17 20.52.59.png](https://qiita-image-store.s3.amazonaws.com/0/11224/056cad1b-7d3d-405f-7de8-81a6bb79d608.png)

これで、Windowsっぽく`Ctrl + C` `Ctrl + V`ができるようになります。
PandasでSeries.dt()を使って日付を変換する方法


#はじめに

pandasで、日時データの粒度を変換する作業は少し面倒だったりします。
resampleなどを使う方法もありますが、indexに入ってないといけないのと、
Seriesを単純に変換したいだけの場合もあると思います。

そんなとき、Series.dt()を使うと便利です！

##日付の文字列の列に対してto_datetimeを適用

次のような日時データがあったとします。

```py

data = pd.read_csv(".../Downloads/sample.csv")
print(data)

#       date	   value
# 0 2016/5/1 0:03	 45
# 1 2017/9/1 0:04	 4
# 2 2016/3/1 0:06	 23
# 3 2018/4/1 0:06	 12
# 4 2017/7/12 0:06	 78
# 5 2018/1/12 0:07	 33
# 6 2018/2/1 0:10	 55
# 7 2018/3/1 0:12	 32
# 8 2018/4/1 0:13	 76

```

このデータのdateカラムに入っている日付は、何時何分まで入っていますね。
今回はこれを日付まで丸めます。

まずpandasは日付をデフォルトで読み込むと文字列型になるので、
この日付データを、to_datetimeメソッドを使ってdatetime型に変換してやる必要があります。

```py

#型の確認
data.dtypes

# date      object
# value    float64
# dtype: object

#to_datetime で日時型に変換
data['date'] = pd.to_datetime(data['date'])

#型の確認
data.dtypes

#date     datetime64[ns]
#value           float64
#dtype: object
#日付のカラムがdatetime64型になっている
```

##いざ変換！


Series.dt()メソッドを使って日時データを変換していきます。
先ほど見たようにdateカラムは、何時何分まで日時データが入っていますが、
これを日付までにして返すには、Series.dt.dateを使います。


```py

data['date'] = data['date'].dt.date
print(data)

#       date	value
# 0 2016/5/1	 45
# 1 2017/9/1 	 4
# 2 2016/3/1 	 23
# 3 2018/4/1 	 12
# 4 2017/7/12 	 78
# 5 2018/1/12 	 33
# 6 2018/2/1 	 55
# 7 2018/3/1 	 32
# 8 2018/4/1 	 76
```

ジャジャーン！日付まで丸まって、欲しい粒度のnumpy配列を返してくれます。

ちなみに、Series.dt.dayofweekを使うと、月曜日= 0、日曜日= 6にして返してくれます。

```python

data['date'] = data['date'].dt.dayofweek
print(data)

#     date	value
# 0   6.0	 45
# 1   4.0 	 4
# 2   1.0	 23
# 3   6.0 	 12
# 4   2.0 	 78
# 5   4.0 	 33
# 6   3.0 	 55
# 7   3.0 	 32
# 8   6.0 	 76

```

うまく変換できていますね。
他にもたくさんあります。以下でまとめてみました。



|Datetime Properties|内容|
|:---|:---:|
|Series.dt.date|datetime.dateオブジェクトのnumpy配列を返します|
|Series.dt.time|datetime.timeのnumpy配列を返します|
|Series.dt.year|日時の年|
|Series.dt.month|月は1月= 1、12月= 12|
|Series.dt.day|日時の日数|
|Series.dt.hour|日時の時間|
|Series.dt.minute|日時の分|
|Series.dt.second|日時の秒数|
|Series.dt.microsecond|マイクロ秒|
|Series.dt.nanosecond|ナノ秒|
|Series.dt.week|年の序数|
|Series.dt.weekofyear|今年の序数|
|Series.dt.dayofweek|月曜日= 0、日曜日= 6の曜日|
|Series.dt.weekday|Monday = 0、Sunday = 6の曜日|
|Series.dt.weekday_name|週の名前（例：金曜日）|
|Series.dt.dayofyear|年の順番の日|
|Series.dt.quarter|日付の四半期|
|Series.dt.is_month_start|月の最初の日かどうかを示す論理値|
|Series.dt.is_month_end|月の最終日|
|Series.dt.is_quarter_start|四半期の初めの日かどうかを示す論理値|
|Series.dt.is_quarter_end|四半期の最終日かどうかを示す論理値。|
|Series.dt.is_year_start|年の最初の日かどうかを示す論理値。|
|Series.dt.is_year_end|最後の年かどうかを示す論理値。|
|Series.dt.is_leap_year|日付がうるう年に属するかどうかを示す論理的|
|Series.dt.daysinmonth|月の日数|
|Series.dt.days_in_month|今月の日数|


公式ドキュメントはこちら[pandas.pydata.org](https://pandas.pydata.org/pandas-docs/stable/api.html#datetimelike-properties
)
Leverage Eloquent To Prepare Your URLs

[Laravel News](https://laravel-news.com/)には良記事が満載なので、備忘録の意味合いも込めて、記事を簡単にまとめていこうと思います（翻訳ではないです）。

# 元記事
投稿日: 2018/04/16
タイトル: Leverage Eloquent To Prepare Your URLs
URL: https://laravel-news.com/leverage-eloquent-to-prepare-your-urls

# まとめ

```php
<a href="{{ route('users.show', $user) }}">{{ $user->name }}</a>
```

というviewによくあるコードを

```php
<a href="{{ $user->url->show }}">{{ $user->name }}</a>
```

と、coolに書こうぜというものです。
中身はとても簡単で、routeを返すクラス(UrlPresenter)をUserモデルに持たせています。

# 感想

実装は簡単ですが、いろいろな箇所で出て来るrouteを呼び出しを簡潔に書けそうです。
Model生成時にUrlPresenterも自動生成できるようにしておけば、考えることが減りそうでよい。

# その他

調べている最中、[laracasts/Presenter](https://github.com/laracasts/Presenter)というのを見つけました。
今回の記事の$user->urlは[ミューテタ](https://laravel.com/docs/5.6/eloquent-mutators)を使っていますが、リファレンスでは$user->first_nameを大文字にして返す例が載っています。
こういった処理をUserモデルではせずに、Userモデルに持たせたPresenterで行うことで、ModelとView(Presenter)を分けています。
テキスト丸め込み、画像暗くするメモ

###テキスト丸め込みメモ

画像を暗くするときは、rgba(color,opacity)functionをbeforeで使う

```scss:SCSS
.text {
  overflow: hidden; //topics部分と2箇所かける
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mainVisual {
  background: url("sample.png") no-repeat center top/cover;
  border-bottom: 1px solid $color-aaaaaa;
  height: 220px;
  position: relative;

  &::before {
    background-color: rgba($color-000000,0.4);
    bottom: 0;
    content: " ";
    left: 0;
    position: absolute;
    right: 0;
    top: 0;
  }
}
```
あるAndroidアプリが応答できるURLスキームを調べる


手元にソースコードがない任意のAndroidアプリで、そのアプリが応答できるURLスキームを調べたいときがある。
以下の方法で調べることができる。

### 1. 対象のアプリのpackage nameを調べる

play storeのURLをみれば`id=`以降がpackage nameになっている。

https://play.google.com/store/apps/details?id=com.example.targetapp&hl=ja


### 2. 対象アプリのAPKを取得する

実機にインストール、adbでapkのパスを調べてadb pullするのが早い

```
adb shell pm list packages -f | grep com.example.targetapp
```

すると以下のような出力が得られる。

```
package:/data/app/com.example.targetapp-1/base.apk=com.example.targetapp-1
```

これをもとにadb pullする。

```
adb pull /data/app/com.example.targetapp-1/base.apk
```

### 3. intent-filterの内容を調べる

aaptをつかえばパッケージの詳細を調べることができる。aaptはSDK HOMEの `build-tools/{build tool version}` 以下にある。

```
aapt l -a base.apk
```

出力からintent-filterの項目を探して、応答しそうなURLをつくればよい。
たとえば、以下のようなintent-filterの場合、 `http://sugoiapp/some/interesting/path` に応答しそうだということがわかる。

```
        E: intent-filter (line=xxx)
          A: android:autoVerify(0x00...)=(type 0x12)0xffffffff
          E: action (line=xxx)
            A: android:name(0x00...)="android.intent.action.VIEW" (Raw: "android.intent.action.VIEW")
          E: category (line=xxx)
            A: android:name(0x00...)="android.intent.category.DEFAULT" (Raw: "android.intent.category.DEFAULT")
          E: category (line=xxx)
            A: android:name(0x00...)="android.intent.category.BROWSABLE" (Raw: "android.intent.category.BROWSABLE")
          E: data (line=xxx)
            A: android:scheme(0x00...)="http" (Raw: "http")
          E: data (line=xxx)
            A: android:scheme(0x00...)="https" (Raw: "https")
          E: data (line=xxx)
            A: android:host(0x00...)="sugoiapp" (Raw: "sugoiapp")
          E: data (line=xxx)
            A: android:pathPrefix(0x00...)="/some/interesting/path" (Raw: "/some/interesting/path")
```

### 4. 実際にintentを起動してみる

adbコマンドをつかえば、実際にそのURLスキームをintentとして起動することができる。

```
adb shell am start -a android.intent.action.VIEW -d http://sugoiapp/some/interesting/path
```

### 参考

* https://developer.android.com/guide/components/intents-filters.html
Vue.jsでグローバルな定数をコンポーネントで使いまわせるようにしたい


WEBサービス作るときに、定数で設定しておきたいものとかありますよね。

最近は、SPAでvuex使って実装してる事が多く、Storeに設定しておけばGettersでグローバルに参照できるのでvuexで良い気がしていたけれど、
vuexを使用していない場合の開発で定数を設定する方法がないかなーと思い、考えてみました。

完全にパッと思いついたので参考程度になれば幸いです。


## やりたいこと

※都道府県のセレクトボックスとかよく使うので`都道府県のenum`を用意してそれをグローバルに参照する

## Mixinを使ってみました

自分はざっとこんな感じのディレクトリ構造です。

```
frontend/
├── entry
│    ├── application.js
├── javascripts 
│    ├── store/
│    ├── components/
│    ├── viewModels/
│      ├── Signup.vue
│    ├── mixins/
│    ├── utils/
│    ├── filter/
```

### 1. 都道府県のenumを`mixins`ディレクトリに作成

```js:mixins/PrefsMixin.js

const _prefs = [
  { "id": '1', "name": '北海道' },
  { "id": '2', "name": '青森県' },
  { "id": '3', "name": '岩手県' },
  { "id": '4', "name": '宮城県' },
  { "id": '5', "name": '秋田県' },
  { "id": '6', "name": '山形県' },
  { "id": '7', "name": '福島県' },
  { "id": '8', "name": '茨城県' },
  { "id": '9', "name": '栃木県' },
  { "id": '10', "name": '群馬県' },
  { "id": '11', "name": '埼玉県' },
  { "id": '12', "name": '千葉県' },
  { "id": '13', "name": '東京都' },
  { "id": '14', "name": '神奈川県' },
  { "id": '15', "name": '新潟県' },
  { "id": '16', "name": '富山県' },
  { "id": '17', "name": '石川県' },
  { "id": '18', "name": '福井県' },
  { "id": '19', "name": '山梨県' },
  { "id": '20', "name": '長野県' },
  { "id": '21', "name": '岐阜県' },
  { "id": '22', "name": '静岡県' },
  { "id": '23', "name": '愛知県' },
  { "id": '24', "name": '三重県' },
  { "id": '25', "name": '滋賀県' },
  { "id": '26', "name": '京都府' },
  { "id": '27', "name": '大阪府' },
  { "id": '28', "name": '兵庫県' },
  { "id": '29', "name": '奈良県' },
  { "id": '30', "name": '和歌山県' },
  { "id": '31', "name": '鳥取県' },
  { "id": '32', "name": '島根県' },
  { "id": '33', "name": '岡山県' },
  { "id": '34', "name": '広島県' },
  { "id": '35', "name": '山口県' },
  { "id": '36', "name": '徳島県' },
  { "id": '37', "name": '香川県' },
  { "id": '38', "name": '愛媛県' },
  { "id": '39', "name": '高知県' },
  { "id": '40', "name": '福岡県' },
  { "id": '41', "name": '佐賀県' },
  { "id": '42', "name": '長崎県' },
  { "id": '43', "name": '熊本県' },
  { "id": '44', "name": '大分県' },
  { "id": '45', "name": '宮崎県' },
  { "id": '46', "name": '鹿児島県' },
  { "id": '47', "name": '沖縄県' }
]

export default {
  data () {
    return {
      prefs: _prefs,
    }
  }
}
```

### 2. コンポーネント側からmixinをimportして使用する

```js:viewModels/Signup.vue

  import prefs from '../mixins/PrefsMixin'

  export default {
    mixins: [ prefs ],
    data () {
      return {
      }
    }
  }
```

> mixinを読み込む → ``import prefs from '../mixins/PrefsMixin'``
mixinを継承します　→　``mixins: [ prefs ],``
※ コンポーネント内の`data () { }`で変数を宣言する必要はありません。


※1. mixinはコンポーネント自身が呼び出される前にフックがかかるので、コンポーネントよりも前にmixinの定数を読み込みます。
※2. もちろん、コンポーネント内で`prefs: []`みたいに変数として宣言するとprefsは`[]`になります。


## 終わりに

パッと思いついたがこれだったので、
もし他にもこんなやり方あるよー！これは駄目だよ。とかご意見あればぜひコメント頂ければと思います。
本格的なiOS開発でよく使うツール

# 本格的なiOSの開発に必要なツール類
個人開発ならXcode・Carthage・CocoaPodsがインストールされていれば十分だが、会社などチームで開発しようとすると、各種ツールのバージョン管理が必要となり、色々前提ツールが増えてくるのでまとめる
Xcodeは必要なバージョンをインストールしてあること前提

1. [Homebrew](https://brew.sh/index_ja)
    - macOS用パッケージマネージャー
    - 下記ツールをインストールするための前提
1. [rbenv](https://github.com/rbenv/rbenv)
    - rubyのバージョン管理ツール
    - Macにデフォルトで入っているRubyだと何かと不都合が多いので、このツールでバージョンを自由に切り替えたり、ディレクトリ毎にバージョンを指定したりできるようにする
    - :warning: よく上手くインストールできなくて引っかかる部分（後述）
1. [bundler](http://bundler.io/)
    - gemパッケージの管理ツール
    - CocoaPodsやfastlaneなどをこれでバージョン管理・インストールする
1. [Carthage](https://github.com/Carthage/Carthage)
    - ライブラリ管理ツール
1. [GitHubに対するssh接続](https://github.com/settings/keys)
    - fastlaneでCertificateを管理していたり、SSOを導入しているGitHubのOrganizationで作業をする時に必要
1. [mergepbx](https://github.com/simonwagner/mergepbx) (optional)
    - コンフリクトしやすい.xcodeprojをよしなにマージしてくれるツール
    - [XcodeGen](https://github.com/yonaskolb/XcodeGen)を使用するなら不要
1. SlackとかGitHubのアイコンを自分の推しに変える（最重要）
    - アニメでもアイドルでも何でもいいので自分の推しに変える
    - デフォルトアイコンだと誰だか見分けが付かない
 
個別のインストール方法は**rbenv以外**公式ページ通りやれば詰まるところはないはずなので割愛

# 構築時によく引っかかる所
## rbenv をインストールしたはずなのに ruby -v が期待したバージョンになってない
ターミナルで `which ruby` を叩いても `/Users/YOUR_USER/.rbenv/shims/ruby` など、rbenv配下のrubyを見ずに、Macにデフォルトでインストールされているrubyを見ているパターン
下記のようにインストールすれば解決可能

```sh
brew install rbenv
echo 'export RUBY_CONFIGURE_OPTS="--with-openssl-dir=$(brew --prefix openssl) --with-readline-dir=$(brew --prefix readline) $RUBY_CONFIGURE_OPTS"' >> ~/.bash_profile
echo 'if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi' >> ~/.bash_profile
source ~/.bash_profile
```

なおmacOS Catalinaからはターミナルがbashではなくzshになったので、macが最初からCatalinaだった場合は `.bash_profile` ではなく `.zshrc` になる点に注意

[参考](https://gist.github.com/satococoa/5830035)

## rbenv で必要なrubyバージョンをインストールしてるのに、bundlerの実行時にバージョンが違うと言われる
パスがrbenvでインストールしたrubyでなく、システムのrubyを見るようになってると思われる
（bundler自体もrbenvのほうではなくシステムのrubyにインストールされてしまっている）
上述の用にrbenvをインストールする ( or インストール済みの場合は `brew install rbenv` 以外を実行する） で直るはず
【tutorial】既存プロジェクトをGit管理に追加→Bitbucketにプッシュ（GitBash）

GitBash（Git For Windows）のインストールは↓の記事。
https://qiita.com/d778980/items/063e3d04fd6d2bf91abd

2018/04/17に実施。

１．既存プロジェクトをGit管理に追加。
https://qiita.com/d778980/items/5bf67fcde80de1830635

２．GitBashを起動。↓のコマンドで秘密鍵と公開鍵を作成。

```
mkdir ~/.ssh
cd ~/.ssh
ssh-keygen -t rsa -C 'メールアドレス'
```

３．何も考えずに Enter を3回。

```
Generating public/private rsa key pair.
Enter file in which to save the key:　→Enter1回目
Enter passphrase (empty for no passphrase):　→Enter2回目
Enter same passphrase again:　→Enter3回目
```

４．configファイルを作成。

```
touch config
chmod 700 config
```

５．configファイルを編集。

```
vim config
```

```
Host bitbucket.org
  HostName bitbucket.org
  IdentityFile ~/.ssh/id_rsa
  User git
  Port 22
  TCPKeepAlive yes
  IdentitiesOnly yes
```

６．↓のコマンドで公開鍵をクリップボードにコピー。

```
clip < ~/.ssh/id_rsa.pub
```

７．Bitbucketにログイン。「Bitbucket settings」をクリック。
![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/247425/42ba49a4-3a2b-e1f5-e860-08a0db43d924.jpeg)

８．「SSH鍵」をクリック。
![2.jpg](https://qiita-image-store.s3.amazonaws.com/0/247425/9a169794-d33c-d467-e6d7-22411a9d6afd.jpeg)

９．「鍵を追加」をクリック。
![3.jpg](https://qiita-image-store.s3.amazonaws.com/0/247425/74505950-0d12-8da7-a1f3-491c8baac0e4.jpeg)

１０．Labelを適当に入力してKeyに「６．」でコピーした値を貼り付け。「鍵を追加」をクリック。
![4.jpg](https://qiita-image-store.s3.amazonaws.com/0/247425/f8801238-b7b5-ddaa-e3b3-7273a5a44799.jpeg)

１１．リポジトリを作成。
![5.jpg](https://qiita-image-store.s3.amazonaws.com/0/247425/1aa286bd-9cdf-935a-02b6-d0cf4cfeab77.jpeg)

１２．リポジトリ名を入力。「Include a README?」を「No」に変更して「リポジトリの作成」をクリック。
![6.jpg](https://qiita-image-store.s3.amazonaws.com/0/247425/b6a71156-2d0e-64ca-ecf0-e200db4ee5f1.jpeg)

１３．GitBashを起動して、ローカルプロジェクトに移動。今回は「~/Desktop/project」

```
cd ~/Desktop/project
```

１４．↓のコマンドでリポジトリを紐づけして、プッシュ。

```
git remote add origin ssh://git@bitbucket.org:（アカウント名）/（プロジェクト名）.git
　例：git remote add origin ssh://git@bitbucket.org:d778980/project.git
git push -u origin master
```

終わり。
AWS S3のクライアントからPhoenix Channelに参加する方法

　Phoenixのchannelについてもクロスドメイン問題のような問題があるのか調べてみました。言い方を変えるとAWS S3のクライアントからPhoenix Channelに参加する方法を試してみました。

[Phoenix.Transports.WebSocket -HexDocs](https://hexdocs.pm/phoenix/Phoenix.Transports.WebSocket.html)
[Phoenix.Endpoint - HexDocs](https://hexdocs.pm/phoenix/Phoenix.Endpoint.html)


　結論から先に言えば、:check_originの設定を行うことで、channelへの接続元を制限できるようです。config/dev.exsのcheck_originの値がデフォルトでfalseになっていますが、これは制限なしにアクセスできることを意味しています。つまり設定変更なしに可能ということです。セキュリティを考慮して、明示的に許可するドメインを指定したい場合は以下のように設定します。ここではPoenixのポートは4009にしています。

```elixir:config/dev.exs
#
#  check_origin: false, #デフォルト<==これでもよい
  check_origin: ["http://www.mypress.jp:4009","http://elm-svg.s3-website-ap-northeast-1.amazonaws.com/"],
#
```


　過去記事「[Phoenix Channelで作る最先端Webアプリ - Reactチャット編　- Qiita](https://qiita.com/sand/items/e4940eaf83daa69d8a59)」においてチャットアプリを作成しました。この時のJavaScriptプログラムを、以下のようにsocketの接続先を明示するように変更して、AWS S3に持っていきます。


```react:Chat.js
#
        //this.socket = new Socket("/socket", {params:
        this.socket = new Socket("ws://www.mypress.jp:4009/socket", {params:
          {token: window.userToken}
        });
        this.socket.connect();
#
```

 reactのbundleファイル priv/static/js/app.js をawschat.jsとリネームして、以下のawschat.htmlとともにAWS S3にアップロードします。


```html:awschat.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>AWS Chat</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="awschat.js"></script>
  </body>
</html>
```


　AWS S3ではstatic hostingを有効にして、httpsではなく、httpでアクセスするようにします。httpsでアクセスすると、Poenix channelへのアクセスもSSLであることを要求され、エラーとなってしまいますので。これでAWS S3にあるReactクライアントからもPhoenix Channelに参加できるようになります。

　今回は以上で終わりです。
positon:absoluteのときに、横幅可変の要素を作る

absoluteがきいているときでも、可変の要素を作りたい
transformとcalcを使う

```scss:SCSS
.text {
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 29px; //文字中央寄せのため
  border: 1px solid white;
  border-radius: 5px;
  position: absolute;
  bottom: 14px;
  left: 50%; //要素を左半分に寄せる
  transform: translateX(-50%); //寄せた位置から、要素の中心を50%右に寄せる
  width: calc(100% - 16px);
  height: 29px;
}
```
Flask のサーバーの起動パターン

次のページを参考にしました。
[Flaskのデフォルトでは同時アクセスを処理できない](https://qiita.com/5zm/items/251be97d2800bf67b1c6)

基本パターン

```py
app.run(host='localhost', port=3000)
```

外部からアクセスできるようにする

```py
app.run(host='0.0.0.0', port=3000)
```

外部から複数の同時アクセスが出来るようにする

```py
app.run(host='0.0.0.0', port=3000, threaded=True)
```

確認したバージョン

```text
$ python --version
Python 3.6.4
```
疑似要素で棒線を上手に操る方法

##疑似要素で棒線を上手に操る方法をまとめた

###文字の間に縦線

```html:HTML

 <div class="notification-label">
  <span class="notification-date">2</span>
  <span class="notification-date">3</span>
 </div>

```


```scss:SCSS

.notification-label {
  align-self: center;
  display: flex;
}

.notification-date {
  display: inline-flex;

   &:first-child::after {
    content: "";
    height: 8px;
    width: 1px; //高さ8px横幅１ｐの棒線
    align-self: center;
    display: block;
    margin: 0 2px;
  }
}

```

###タブで選択されたものに下線がついている状態

```html:HTML

 <div class="tabs">
   <div class="tab is-active">A</div>           
   <div class="tab">B</div>
 </div>

```

```scss:SCSS
.Tabs {
  display: flex;
  font-size: 14px;
}

.Tab {
  background-color: gray;
  border-radius: 3px 3px 0 0;
  cursor: pointer;
  flex: 1;
  height: 40px;
  line-height: 45px; //文字垂直合わせ
  position: relative;
  text-align: center;

  &:not(:last-child) {
    margin-right: 4px; 
  }

  &.is-active {
    background: $color-ffffff;
    color: $color-000000;

    &::before {
      content: "";
      display: block;
      height: 2px;
      background: #05C3C8;
      position: absolute;
      bottom: 0;
      left: 10px;
      right: 10px;　
    }
  }
}
```
left,rightの位置を指定することで、その位置からの下線をひける

###クローズボタンをつくる


```html:HTML
<div class="closeBtn"></div>
```

```scss:SCSS
.closeBtn {
  height: 8px;
  position: relative;
  width: 8px;

  &::before,
  &::after {
    background: white;
    content: "";
    display: block;
    height: 10px;
    left: 50%;//擬似要素をdivの中心に寄せる
    position: absolute;
    top: -1px;
    width: 1px;
  }

  &::before {
    transform: rotateZ(45deg);
  }

  &::after {
    transform: rotateZ(-45deg);
  }
}
```



###リスト状になっているリンクの端にある矢印（矢印は画像のとき）

```scss:SCSS
.List {
  background-color: white;
  border-bottom: 1px solid #A1A1A1;
  display: flex;
  position: relative;

  &::after {
    content: "";
    background-image: url("arrow.png");
    background-repeat: no-repeat;
    background-size: cover;
    position: absolute;
    right: Xpx;
    top: Ypx;
  }
```
コンソール実行時にすぐに画面が閉じるときの対処法(C++)

# 動機
久々にC++を触る機会があり、デバッグの際に止まらずに終了してしまう、よくあるトラブルの対処法を忘れていたので、備忘録として記載しておきます。
追記：2018/04/18 14:19

# 環境
Visual Studio Community 2017

# 魔法の１行
以下の1行をストップしたい場所に入れ、stdio.hをインクルードするだけです。
(初歩的なプログラムの場合、returnの上に入れるのが普通です)

```hoge.cpp
getchar()
```
このコマンドは本来一文字読み取る関数ですが、一度入力待ちになり、何かキーを押すと再度動くので、擬似的なブレークポイントとして機能します。

# プログラム例
16進数で入力された数字を10進数で表示する簡単なコードです。

```main.cpp
#include <stdio.h>

int main() {
    int variable;
    variable = 0x12345678;

    printf("%d", variable);

    getchar(); // 一時停止
    return 0;

}
```
上手くいけば、以下のように表示され、何かキーを押すと終了するようになると思います。

```
305419896
```

# 追記：もう一つの魔法の１行(?)
別解として、以下があります。(y_itamoto様コメントありがとうございます。)

```hoge.cpp
system("pause");
```
これは１行で「続行するには…」を表示してくれる優秀ちゃんです。
ただ、正確には１行ではなく、

```hoge.cpp
#include <stdlib.h>
```
を先頭に追加する必要があります。
蛇足ですが、僕も最初にこれを発見したのですがエラーを吐いてしまい(その時インクルード部分のスペリングミスとは気づかなかった)、先程紹介した方法に行き着くことになりました。
多分コメントで指摘されるまで気づくことなかったかも…
# プログラム例 その２
```main.cpp
#include <stdio.h>
#include <stdlib.h>

int main() {
    int variable;
    variable = 0x12345678;

    printf("%d\n", variable);

    system("pause"); //一時停止
    return 0;

}
```
上述したプログラムと同じ動作をするはずです。

# 最後に
このコマンドを書いた後に、「別にブレークポイントでよくね？」って思った
CakePHP3でjsonを返すAPIをCakePHPの流儀に従って記述量少なく書きたい人生だった

素人の投稿なので間違っていたら教えてください。

# やりたいこと
```
wget http://xxx/api/apples.json
```

```json
{
  "apples": [
    "Tsugaru",
    "Fuji"
  ]
}
```

…を出来る限り短いコード量で作りたい。
CakePHPの流儀に従ったら短くなるはずだ。

## Note
いやいや、以下を返すべきだろ、などなどは本質的ではないので目をつぶってね。

```json
["Tsugaru", "Fuji"]
```

# routes.php
```php
Router::extensions(['json']);
Router::prefix('api', function ($routes) {
    $routes->resources('Apples');
});
```

resourcesはREST APIのインタフェースを作ってくれる。
今回の場合は `index` のみ許可すべきですが、本質的ではないので省略。

# controller
```php
namespace App\Controller\Api; // napmespaceとdirectoryは Api の配下
use Cake\Controller\Controller;

class ApplesController extends Controller
{
    public function initialize()
    {
        parent::initialize();
        $this->loadComponent('RequestHandler');
    }

    public function index($mode = null) {
        $this->viewBuilder()->setClassName('Json'); // .jsonなしでもOKにする
        $apples = ["Tsugaru", "Fuji"];
        $this->set([
            'apples' => $apples,
            '_serialize' => ['apples']
        ]);
    }
}
```

# JsonView を使う方法も (Thx to @juner)

`JsonView` を使うともっときれいにかけそうです。
https://book.cakephp.org/3/ja/views/json-and-xml-views.html#json

# Point (Thx to @nojimage )
- コントローラの置き場を Controller/Api/ApplesController にしたい
- コントローラのnamespaceを namespace App\Controller\Api; にしたい

といった場合は、[プレフィックスルーティング](https://book.cakephp.org/3.0/ja/development/routing.html#prefix-routing) を使用します。

# `["Tsugaru", "Fuji"]` だけを返したい。

```php
        $this->set([
            'apples' => $apples,
            '_serialize' => 'apples'
        ]);
```
Thanks to @tomcat0090 !
AWSCLIとS3を利用して、全ユーザーを保持したままサーバを移行する。

# やりたいこと
全ユーザーを保持したまま新サーバに移行したい。

# どうやってやるか
下記、1つのディレクトリ、5つファイルを、新サーバに移せば良い。
VPC、ElasticIPの関係なのか、scpコマンドで送受信できなかったので、S3を利用した。

- /home
- /etc/passwd
- /etc/shadow
- /etc/group
- /etc/gshadow
- /etc/ssh/ssh_config

# 手順
## ①旧サーバ → S3
### ファイル(ディレクトリ)を圧縮する
```
$ cd /home
$ sudo tar -zcvf home.tar.gz /home

$ cd /etc
$ sudo tar -zcvf etc.tar.gz passwd shadow group gshadow
```

#### (補足)tarコマンド オプション
-z：gzipで圧縮・展開
-c：アーカイブ作成
-v：詳細情報の表示
-f [ファイル名]：アーカイブファイル名を指定
-x：アーカイブ展開

### S3 IAMを設定する

### S3に接続できるように設定する

```
$ aws configure

aws_access_key_id = XXXXXXXXXX
aws_secret_access_key = XXXXXXXXXX
Default region name [None]: XXXXXXXXXX
Default output format [None]: XXXXXXXXXX
```

### S3に接続できるか確認する
```
$ aws s3 ls s3://s3-bucket-name/
```

### S3に圧縮したファイルをアップロードする
```
$ cd /home
$ aws s3 cp home.tar.gz s3://s3-bucket-name/

$ cd/etc
$ aws s3 cp etc.tar.gz s3://s3-bucket-name/
```

## ②S3 → 新サーバ
### 新サーバのインスタンスを立てる

### 新サーバでも上記同様に、S3に接続できるように設定する
```
$ aws s3 ls s3-bucket-name/
```

### S3から圧縮したファイルをダウンロードする
```
$ aws s3 cp s3://s3-bucket-name/home.tar.gz /home/izumiru/
$ aws s3 cp s3://s3-bucket-name/etc.tar.gz /home/izumiru/
```

### ファイルを展開する
```
$ cd /
$ tar -xvzf home.tar.gz
$ rm -rf home.tar.gz

$ cd /etc
$ tar -xvzf etc.tar.gz
$ rm -rf etc.tar.gz
```

### 旧サーバのElasticIPを外し、新サーバに付与する

### 新サーバにログインできれば移行完了
```
$ ssh -p 22 XXXXXXXXXX
```

# 起きた問題
ユーザーとグループの権限がおかしくなり、移行者のみログインできなくなった。
そのため、ログアウトする前に権限がどうなっているのか確認したり、
移行した人に自分の権限を変更してもらえるように設定していくなど、準備と対策が必要です。

# 参考リンク
- [CentOS 6のサーバーの全ユーザーを別のCentOS 7のサーバーに移行する方法](https://urashita.com/archives/2340)
wemos d1のピン配置

#概要
wemos d1のピン配置を調査。


#写真

![wemos_d1.jpg](https://qiita-image-store.s3.amazonaws.com/0/18104/570eaadf-b604-e24e-a231-3d6d0920aa08.jpeg)


#ピン配置
信号レベルは、3.3V

| uno      |    wamos    | GPIO |
|:-----------------|:------------------|-------:|
|SCL   | D15/SCL | 5|
|SDA　 | D14/SDA | 4|
|AREF  | NC|  |
|GND   | GND|  |
|D13　 | D13/SCK　  | 14|
|D12　 | D12/MISO　 | 12|
|D11　 | D11/MOSI　 | 13|
|D10　 | D10/SS　　 | 15|
|D9　　| TX1/D9/LED　　 | 2|
|D8　　| D8　　　   |  0|
|D7　　| D11/MOSI/D7　|13|
|D6　　| D12/MISO/D6　|12|
|D5　　| D13/SCK/D5　 |14|
|D4　　| D14/SDA/D4　 |4|
|D3　　| D15/SCL/D3　 |5|
|D2　　| D2　　　     |16|
|D1　　| TX->D1      |1|
|D0　　| RX<-D0      |3|
|A0　 | A0　　220K+100K　で分圧し、100K側でADCに接続|ADC0 |
|A1　 | NC| |
|A2　 | NC| |
|A3　 | NC| |
|A4　 | NC| |
|A5　 | NC| |
[Ubuntu]固まったアプリケーションをKillする方法

自分のための備忘録。
３ステップくらい必要な操作って忘れやすいよね。
bash script化するよりqiitaに投稿してメモる方が楽な気がして書いてみた。
1. `xwininfo`でアプリケーションのウィンドウをクリック　→　window id取得
2. `xprop -id [window id] _NET_WM_PID`　→　pidを取得
3. `kill -9 [pid]`　→　kill 完了
3Dモデル表現形式Colladaについて

# はじめに

3Dモデルの表現形式は非常に種類が多く、
使用できるアプリ、できること、できないことをはっきりさせておかないと大変です。
この記事では比較的多くのアプリケーションで使用でき、
表現能力もそこそこあるColladaについて紹介します。

# Colladaとは

- 3Dモデルを配布するためのフォーマットで、xmlで記述される．拡張子dae。
- 元々はPS3用に作られたものである。
- 対応ソフトが多く、Blenderでも生成できる。
- ロボット系だとROSのロボットモデルであるURDFのメッシュにも使われている。
- v1.5とv1.4で多少違いがあり、どちらか一方にしか対応してないケースもあるので注意。
- ちなみにテクスチャやボーンにも対応しています。

Khronosからファイルフォーマットの詳細についてダウンロードできます。
日本語版もあり。(ソニー製だから？)

https://www.khronos.org/collada/


## 最小セットの例は？

ドキュメントの最後にキューブの例が載っています。

https://www.khronos.org/files/collada_spec_1_5.pdf

https://www.khronos.org/files/collada_spec_1_4.pdf

のと、一度blenderで簡単なモデル(デフォルトキューブも可)を
エクスポートして、エディタで開くのが楽でしょう。


## どうやって読むの？

人間が読む場合を考えると、最低限xmlの知識が求められます。

公式のリファレンスカードにスキーマがわかりやすくまとめられています。

https://www.khronos.org/files/collada_reference_card_1_4.pdf

これと最小セットの例を照らし合わせると大体読めると思います。

### 最小セットから紐解いてみる

最小セットでは以下のような構造でデータを記述しています。

- `COLLADA`
    - `asset`
        - ファイルの属性など
    - `library_effects`
        - material用のeffect
    - `library_materials`
        - ここでmaterialにeffectを指定
    - `library_geometries`
        - `geometry`
            - この中で頂点、法線、面を指定する
    - `library_visual_scenes`
        - `visual_scene`
            - `node`ごとに座標系設定
              - `instance_geometry`で`geometry`をシーンに生成
    - `scene`
        - `instance_visual_scene`でシーンを生成

参照が複雑だったり設定の重複が多い印象です。

## プログラムで解釈する方法は？

ロボット系でよく使われるのはcollada-domでしょうか。

https://github.com/rdiankov/collada-dom

githubは軽量版で、フルサイズはsourceforgeにあります。

https://sourceforge.net/projects/collada-dom/

一方、pycolladaというpythonのライブラリもあります。

https://github.com/pycollada/pycollada


## hogehogeで作ったdaeがfugafugaで読めないんだけど？

はいきた。

ここがColladaにおいて問題になる点で、
BlenderですらColladaで許容される表現を完全にインポートできていません。

問題になりそうな例をいくつか挙げると、

### materialの指定がgeometryとbind_materialの双方で出来てしまう

最小セットの例でもわかりますが、
materialの指定できる箇所が二箇所あります。

- `library_geometry/geometry/polygons`
- `library_visual_scenes/instance_geometry/bind_material`

どちらかしか見てないソフトだと互換性が取れません。
blenderはそもそもmaterialの設定を上手く取れていない気がします。

### geometryの中で複数の形状情報が許容されている

geometryが複数の形状情報(polygonsなど)を持つことが許容されていますが、
この場合blenderでは問答無用でgeometry単位で一つの部品になります。
またbind_materialがgeometryのidを指定しているため、
各形状情報でmaterialの色分けをした場合うまくいかないことが予想されます。

## なんかこのdae壊れてない？

壊れてるかどうかをチェックしようと思うと、例えば次のようなことが考えられます。

- arrayで指定しているcountが正しいか
- urlを指定している場所でリンク切れがないか(bind_materialのtargetなど)

ちなみに、gazeboの場合bind_materialのtargetでリンク切れを起こすと静かに落ちます。

# おわりに

Colladaは表現能力はそこそこ高いのですが、
以下のような問題点が挙げられると思います。

- 表現の自由度は高いが、対応を謳うソフトがそれに対応できるとは限らない。
- 各言語で取り扱える標準のパーサがない。
Webアプリケーションにおいて404や500などのエラーページはどう作るのが良いか

## 概要

Webアプリケーションを開発する際、404や500などHTTPステータスコードに応じたエラー画面をサイト専用で用意することが多い。

エラーページなので、画面のレイアウトやコンテンツの構成は統一させて表示するメッセージだけ変えたいと考えるのが普通だと思うが、ログインやサイト共通のヘッダー、サイトのベースレイアウトなどが絡んでくると少し厄介になる。

結論からいくと、

* 最小コストで用意するなら
 * HTML1枚で完結させるようにした40X・500ページを返す

* ユーザーコミュニケーションを重視するなら
 * 通常UIに準拠してログイン状態等も考慮して、40Xページを返す
 * HTML1枚で完結させるようにした、500ページを返す

が良いと思う。


## 主要なHTTPステータスコード整理
### 404 Not Found

* ページが見つからない

| Webサーバ | ログイン状態 |
|:-:|:-:|:-:|
| 稼働中  | 判定可能  |

* cssや画像ファイルが閲覧可能
* ログイン用メニュー等も表示可能

### 403 Forbidden

* ページの閲覧権限がない

| Webサーバ | ログイン状態 |
|:-:|:-:|:-:|
| 稼働中  | 判定可能  |

* cssや画像ファイルが閲覧可能
* ログイン用メニュー等も表示可能

### その他の40X

基本

| Webサーバ | ログイン状態 |
|:-:|:-:|:-:|
| 稼働中  | 判定可能  |

になる（はず）。

参考：[HTTPステータスコード（クライアントエラー）](https://ja.wikipedia.org/wiki/HTTP%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89#4xx_Client_Error_%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%82%A8%E3%83%A9%E3%83%BC) 

### 500 Internal Server Error

* サーバ内部エラー
 * 想定外の問題が発生して適切なレスポンスを返せていない状態

#### アプリケーション内でエラーが発生した場合

| Webサーバ | ログイン状態 |
|:-:|:-:|:-:|
| 稼働中  | 判定不能  |

* cssや画像ファイルは閲覧可能
* ログイン用メニュー等は表示不能

#### アプリケーションが応答を返せない場合

| Webサーバ | ログイン状態 |
|:-:|:-:|:-:|
| 停止中  | 判定不能  |

* cssや画像ファイルが閲覧不能
* ログイン用メニュー等も表示不能

### 503 Service Unavailable

* サービス利用不可
 * メンテナンス中など

| Webサーバ | ログイン状態 |
|:-:|:-:|:-:|
| 停止中  | 判定不能  |

* cssや画像ファイルが閲覧不能
* ログイン用メニュー等も表示不能

### その他の50X

基本

| Webサーバ | ログイン状態 |
|:-:|:-:|:-:|
| 停止中  | 判定不能  |

になる（はず）。


参考：[HTTPステータスコード（サーバエラー）](https://ja.wikipedia.org/wiki/HTTP%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89#5xx_Server_Error_%E3%82%B5%E3%83%BC%E3%83%90%E3%82%A8%E3%83%A9%E3%83%BC) 



## どうつくればよいか

### 最小コストで用意するなら

* HTML1枚で完結させる
 * CSSはインライン or HTML内埋め込み
 * 画像はData URIスキームで埋め込み

### ユーザーコミュニケーションを重視するなら

#### 404、403、その他40X

* 通常UIをベースに、未ログイン時とログイン時で戻るボタン等も出し分けてつくる
 * ログイン中なら上部にメニュー出すなど

#### 500、その他50X

* HTML1枚で完結させる
 * CSSはインライン or HTML内埋め込み
 * 画像はData URIスキームで埋め込み