OmniAICreator/Qiita-1.07M huggingface dataset:
IOS11.4で疑似要素を使って三角を作る時の注意点

cssの疑似要素にborderを使ってうまく三角ができなかったのでメモ。
高さを指定していないことが原因かな？

```html:index.html
<div class="arrow-wrap">
  <span class="arrow"></span>
</div>
```

```css:style.css
/*-- iosだとうまく表示されない --*/
.arrow:before {
    content: '';
    display: block;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    border: 4px solid transparent;
    border-top: 6px solid #fff;
    border-bottom: none;
    transition: .5s;
}

/*-- これだとうまく表示された --*/
.arrow:before {
    content: '';
    display: block;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 0;
    height: 0;
    border: 4px solid transparent;
    border-top: 6px solid #fff;
    border-bottom: none;
    transition: .5s;
}
```

検証がIOS11.4だったので、もしかしたら他のバージョンでも同じような現象が起きるかも。
Bashが壊れたときに対応した方法2018年8月

# やべぇ！Bashが壊れた！
.bash_profileでなにか変更し、sourceコマンドで再読込した際に、誤ってlsコマンドなどが使えなくなることがある。

```sh
Command 'ls' is available in '/bin/ls'
The command could not be located because '/bin' is not included in the PATH environment variable.
ls: command not found
```

そんなあなたにはこの、修復コマンドを送ります

```
export PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin
```
Amazon Game Tech Night #6 ~GameSparksハンズオン~ メモ

# AWSアップデート（ゲーム向け）

## Fortnite
ニューヨークのAWS Summitで開発者が登壇。

24アベイラビリティゾーン利用。
7つのクロスプラットフォーム。（PC,PS4,XBOX,Nintendo Switch…）
Kubernetesによる分析、機械学習、コンテナアプリケーションを利用している。

## その他、AWSでゲームに関するアップデート
* EKSがリリース。
* Fargateが東京リージョンで利用可能に。
* EFSが東京リージョンで利用可能に。
  フルマネージ型NFSサービス
  EC2からNFSマウントして利用する。
  NFSv4対応。
* r5,r5d,z1dインスタンスリリース
  d：ローカルストレージ搭載。
  z：CPU性能が良く、TurboBoost搭載最大4.0GHzで動作。CPUを多く使用するゲームのワークロードに向く。
* QuickSightが東京リージョンで利用可能に。
  S3に置いたファイルをAthenaなどを通してデータソースとして利用可能。
  機械学習を利用したアセットライブラリ構築。画像をAWS上にPUTすると自動タグ付け管理できる。

## 告知
* CEDEC2018にAWS登壇
  * GameSparksハンズオン
* AWS re:Invent 11月予定 ラスベガス
  * Supercell ログ基盤（代表作：Clash of Clans）
  * League of Legendsのグローバルアカウントシステムについて解説
  * Infinity Ward - Call of Duty
  * 低レイテンシーの世界規模のマルチプレイヤーゲーム

# GameSparks

## GameSparks概要
2017年にAmazonが買収したゲーム向けバックエンドサービス

### 主要なお客様
* スクウェア・エニックス
* バンダイナムコエンターテインメント
* NEXON
* UBISOFT
など

### ゲームに特化したサーバサイド機能を提供
* リーダーボード（ランキング）
* ガチャ（課金ガチャ・アイテムドロップ）
* ルーム
* チャット（リアルタイム・非リアルタイム）
* チーム（ギルド）
など

### マッチメイクのロビーを作るなら？
ルーム機能 ＋ リアルタイムチャット機能 のように複数の機能を組み合わせて実装可能。

### アナリティクス
SDKの実装やAPIでグラフィカルに表示可能。
MAU・DAUなど表示可能。
レイアウトも自由。

### 採用事例
* Hungry Shark UBISOFT
  https://www.ubisoft.com/en-gb/game/hungry-shark-world-console
* 7 Days to Die
  https://7daystodie.com/entrygate.html
* Disc Jam
* Hotwheels:Race Off
* Zlatan Legends

## ハンズオン概要
* アカウント作成
* Lab1-4
  * Lab1 リーダーボード（ランキング）
  * Lab2 マルチプレイヤー対戦
  * Lab3 ガチャ
  * Lab4 UIからテスト

### 今回作成するもの
* ユーザー
* リーダーボード（ランキング）
* マルチプレイヤー対戦
* アイテム（ガチャ用）
* ガチャ

### 補足事項
#### 現在は英語のみの提供だがチュートリアルドキュメントが充実している。
日本語訳中。

#### APIコール数のリミッターはあるか？
リーダー・ランキングボードだと100req/s。
必要ならばそれ以上も相談できる。

#### バルクインポートに対応しているか？
現在はJSONを作りAPIで1つずつ取り込むしかない。

#### 利用料金は？
評価・プロトタイピングは無料。
エンタープライズとインディーズで異なる。
費用はAWSに問い合わせること。
基本はMAUベースの課金。

#### GameSparks内にプログラムを実装するCLOUD CODEは、現在はコードの直接入力かzipインポートしかできない。
CodePipelineなどAWS内のサービスも対応していない。
TypeScript 3.0でredux-actionsのcreateActionみたいなものをつくる

# 前回までのあらすじ
https://qiita.com/terrierscript/items/b3f9dd95a4c7afe0b102

上記の記事に書いてたけどちょっと別物になってきたので記事わけた。

# もうちょっとなんとかしたかったこと
前回までのactionはボイラープレート多かったので、[redux-actions](https://github.com/redux-utilities/redux-actions)のcreateActionみたいなのがほしくなった。
本家のをそのまま使いたいところだが、payloadが`payload?`で定義されており若干今回のactionの付帯情報まで決定させたいということが出来なかった。

あと、TypeScript 3.0で出ていたTuple in Rest parameterの使い所じゃん！って思ってテンションがあがったので使いたかった。
ということで下記は3.0以上向けになるので注意

# コード

```ts

// Extraの部分を作成する関数。Tuple in Rest parameter大活躍！
type ExtraFunction<Arg extends any[], R> = (...args: Arg) => R
type ActionCreator<Arg extends any[], Action> = (...args: Arg) => Action

// 関数のoverload
export function createAppAction<A extends string>(
  type: A
): ActionCreator<any[], AppAction<A>>
export function createAppAction<A extends string, Arg extends any[], R>(
  type: A,
  fn: ExtraFunction<Arg, R>
): ActionCreator<Arg, AppAction<A, R>>

export function createAppAction(type, extraFunction?) {
  return (...args) => {
    if (extraFunction) {
      const extra = extraFunction(...args)
      return { type, ...extra }
    }
    return { type }
  }
}

```

利用側はこんな感じになる

```ts
const increment = createAppAction(ActionType.increment)
const decrement = createAppAction(ActionType.decrement)
const force = createAppAction(ActionType.force, (num: number) => {
  return {
    count: num
  }
})
```

また、このcreateAppActionの定義と[コメントいただいた](https://qiita.com/terrierscript/items/b3f9dd95a4c7afe0b102#comment-77f7521fdcec8ad716ad) `ReturnType`を駆使すると、更に楽ができる

```ts
// もとの定義
// type CounterAction =
//   | AppAction<ActionType.increment>
//   | AppAction<ActionType.decrement>
//   | AppAction<ActionType.force, { count: number }>

type CounterAction = ReturnType<
  typeof increment | typeof decrement | typeof force
>
```

気分が乗ってきたのでさらにactionをobjectでまとめてみるとこうなる

```ts
export type AppActionCreators<
  T extends { [key: string]: (...args) => any }
> = ReturnType<T[keyof T]>


export const counterActions = {
  increment: createAppAction(ActionType.increment),
  decrement: createAppAction(ActionType.decrement),
  force: createAppAction(ActionType.force, (num: number) => {
    return {
      count: num
    }
  })
}

type CounterAction = AppActionCreators<typeof counterActions>
```
capistrano3 でデプロイしようとした時に詰まった(bundle: No such file or directory) 

# はじめに
capistrano3を使ってデプロイしようとした時にエラーがでて詰まった話。

capistranoは3.10.1。CentOS6.10。

```shell
# cap --version
Capistrano Version: 3.10.1 (Rake Version: 12.3.0)
```
# エラー
`bundle exec cap staging deploy`を実行したら以下エラーが発生しました。

```shell
bundle stdout: Nothing written
bundle stderr: /usr/bin/env: bundle: No such file or directory
```

# 原因
上記エラーを私なりに解釈すると`bundle`コマンドが無い！らしい・、な、なるほど！原因は単純でデプロイ先のサーバで`bundle`コマンドが見つからないよ！ということです。ウーん、なぜみつからないの？

## bundleどこ
`bundle exec cap staging deploy`を実行している環境のbundle コマンドの所在を確認してみました。

```shell-session
# which bundle
/root/.rbenv/shims/bundle
```
u~n、なるほど！
まず、rootユーザにrbenvをインストールしています。rubyのバージョンを管理できるあれですね！そして`# gem install bundler`を実行してbundleコマンドをインストールしていました。よってrbenv配下の`/root/.rbenv/shims/bundle`に存在するわけですね。

## ちなみにgemコマンドどこ

rubyもrbenvで管理しているのでgemもそのrbenvの管理に置かれます。

```
which gem
/root/.rbenv/shims/gem
```

## どうすればよい

まとめるとデプロイ先のサーバでbundleコマンドを使えるようにするために、デプロイ先のサーバでも(同じ様に)rbenv環境を構築してcapistranoからそのrbenv配下のbundleコマンドを利用出来るようにすれば上手くいくはずです！
(またはrbenvを使わずともbundleコマンドを使えるようにすればよいと思いますが、例えばシステムにrubyを入れてパスを通すみたいな、ですが、rbenvがスマートなやり方なのでrbenvを使った方法にします。)

# 対応
## デプロイ先
デプロイユーザでrbenvを使う設定をいれてrubyを使えるようにして+ `gem install bundler` 

[rbenvの設定参考](https://jitaku-server.com/?p=245)

## ローカル環境
デプロイ先サーバのデプロイユーザでrbenvのbundleを使う設定。capistrano-rbenvを使う。

https://github.com/capistrano/rbenv

Gemfile

```rb
gem 'capistrano-rbenv'
```

Capfile

```rb
 require "capistrano/rbenv"
```

deploy.rb

```rb
set :rbenv_ruby_version, '2.5.1p57'
set :rbenv_path, '/home/deploy/.rbenv' #指定するとこのパスは以下のbundleが、指定しないと$HOME配下のbundleが実行された
set :bundle_path, './vendor/bundle'
set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} #{fetch(:rbenv_path)}/bin/rbenv exec"

```

実行結果

set: rbenv_pah ある場合

```shell
00:09 bundler:install
      01 RBENV_ROOT=/home/deploy/.rbenv RBENV_VERSION= /home/deploy/.rbenv/bin/rbenv exec bundle install --path ./vendor/bundle --without development test --deployment --quiet
```

set: rbenv_pah がない場合

```shell
00:08 bundler:install
      01 RBENV_ROOT=$HOME/.rbenv RBENV_VERSION= $HOME/.rbenv/bin/rbenv exec bundle install --path ./vendor/bundle --without development test --deployment --quiet
```

### 参考
[USAGE](https://jitaku-server.com/?p=245)

```rb
# Capfile
require 'capistrano/rbenv'


# config/deploy.rb
set :rbenv_type, :user # or :system, depends on your rbenv setup
set :rbenv_ruby, '2.4.2'

# in case you want to set ruby version from the file:
# set :rbenv_ruby, File.read('.ruby-version').strip

set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec"
set :rbenv_map_bins, %w{rake gem bundle ruby rails}
set :rbenv_roles, :all # default value
```
Windows10 × PyCharmで必要だった設定

私の環境がややこしいせいか、PyCharmの参照ライブラリのインストールに失敗。

**ややこしいポイント**

- ユーザー名が日本語で、Userの下に日本語でスペースができている
- msys2でpipを入れたりしている

# 文字コードが読み込めない
失敗したときのメッセージはこれ。↓

```
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position xx: ordinal not in range(128)
```


下記URLに従って、cp932に変更して対処

http://d.hatena.ne.jp/shu223/20111201/1328334689
https://qiita.com/chatrate/items/eb4b05cd1a6652529fd9
http://www.wakayama-u.ac.jp/~kazama/lab/python/i18n.html


# C#コンパイラが必要
**2018/8/17追記**
requirement.txtを`pip install`できない事象が発生。
コンソール上ではよくわからなかったが、PyCharm上で実行すると、次のもののインストールが必要だといわれた。

https://www.microsoft.com/en-us/download/details.aspx?id=44266

へぇ～。
Rails5のsystem testでheadless chromeを使っているときにJavaScriptのログを見る方法

以下のように追加のオプションを与えると見ることができます。

```ruby:test/application_system_test_case.rb
require "test_helper"

class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
  caps = Selenium::WebDriver::Remote::Capabilities.chrome(loggingPrefs: { browser: 'ALL' })
  driven_by :selenium, using: :headless_chrome, screen_size: [1920, 1080], options: { desired_capabilities: caps }
end
```

```ruby:test/system/something_test.rb
require "application_system_test_case.rb"

class SomethingTest < ApplicationSystemTestCase
  test "display javascript logging" do
    visit("/")
    click_button("Submit")
    pp page.driver.browser.manage.logs.get(:browser)
  end
end
```

ログを出力するようにすると、テストが少し遅くなるっぽいので必要なときだけ出すようにするのがよさそうです。

### 参考

* [javascript - Capture browser console logs with capybara - Stack Overflow](https://stackoverflow.com/questions/46278514/capture-browser-console-logs-with-capybara)
ただひたすらに画像を開くだけのImageViewerをC#で作った

# 画像を開くやつを作った
ただひたすらに画像を開き見るだけ
以下二つの起動パターンがある
・起動してからドラッグ＆ドロップ
・画像の起動アプリケーションに指定（ダブルクリックで開けるようになる）
## 理由

・win10フォトの動作が異常に重いときがある（画像サイズに関係ない）
・ていうか画像見たいだけなのでほかの機能いらない
・画像の取り扱い方法をいろいろ調べてた

### 学び
・コマンドライン引数というものを知る
・Image機能強い
・身近なソフトウェアの簡単な改善は自分ですぐできる

### 設定とか
・FormのAllowDropをTrueに
・controlSizeChanger()のthis.width,heightパラメータをいじれば
最小のウィンドウサイズを変えられる

```C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ImageViewer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            Console.WriteLine(System.Environment.CommandLine);

            string filepath;

            //コマンドライン引数を配列で取得する
            string[] cmds = System.Environment.GetCommandLineArgs();
            //コマンドライン引数を列挙する
            if(cmds.Length >= 2)
            {
                filepath = cmds[1];

                System.Drawing.Image img = System.Drawing.Image.FromFile(filepath);

                controlSizeChanger();

                pictureBox1.Image = img;
            }
        }

        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            this.pictureBox1.Width = this.Width;
            this.pictureBox1.Height = this.Height;

            this.panel1.Width = this.Width - 15;
            this.panel1.Height = this.Height - 37;
        }

        private void Form1_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.All;
        }

        private void Form1_DragDrop(object sender, DragEventArgs e)
        {
            if (!e.Data.GetDataPresent(DataFormats.FileDrop)) return;

            foreach(var filepath in (string[])e.Data.GetData(DataFormats.FileDrop))
            {
                System.Drawing.Image img = Image.FromFile(filepath);
                this.pictureBox1.Image = img;

                controlSizeChanger();
            }
        }

        private void controlSizeChanger()
        {
            this.Width = 700;
            this.Height = 800;

            this.pictureBox1.Width = this.Width;
            this.pictureBox1.Height = this.Height;

            this.panel1.Width = this.Width - 15;
            this.panel1.Height = this.Height - 37;
        }
    }
}

```
JavaScript の Promise は モナドではない

誰かの投稿にコメントしたけど、散逸するのももったいないので記事にした。

# TL;DR;
JavaScript の Promise は モナド則を満たさないのでモナドではない

# だから何？
Promise がモナドではなくても、別に困らない

関数型プログラミング指向の人で、モナドの恩恵を受けるような操作（例: 関数の lift ）が必要な場合、サードパーティ製の非同期モナドを使わないといけない(例: Folktale)

# モナド則を JavaScript で
モナド則を Haskell wiki から抜粋
>
**Left identity**: return a >>= f ≡ f a
**Right identity**: m >>= return ≡ m
**Associativity**: (m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)

JavaScript 用に書き直す。return は JavaScript では予約語なので `_return` としよう。演算子 >>= もJavaScript では定義されていないので `_bind` としよう。するとモナド則の JavaScript 版はこうなる

```monad-laws.js
// a は任意の型の定数, m はモナド
// f は b を受け取り モナド c を返す関数(b, c は任意の型)
// g は c を受け取り モナド d を返す関数(d は任意の型)
'Left identity:'; _bind(f, _return(a)) ≡ f(a)
'Right identity:'; _bind(_return, m) ≡ m
'Associativity:'; _bind(g, _bind(f, m)) ≡ _bind(x => _bind(g, f(x)), m)
``` 

# モナド則を満たさない Promise
Promise はモナドだよね、という主張をする人は、以下の想定をしている人が多い。

```promise-monad-mapping.js
const _return = x => Promise.resolve(x)
const _bind = (f, p) => p.then(f)
```

このようにマッピングすると確かにPromiseはモナド則を満たすケースが多いのだけれど、反例も山ほどある。

```LeftIdentityが成立しない反例.js
const a = Promise.resolve(1) // aは任意の型なので Promise Int にしてみる
const f = x => x.then(y => y) // 上記のように設定したので xはPromise。よってthenを持つ
_bind(f, _return(a)) // -> 左辺は type error
f(a) // -> 右辺は 1 でresolve される
```

上記の例では、_bind の実装であるところの then が a の型である Promise を引きはがしてしまったためにモナド則が成立しなかった。Promiseの入れ子をまとめて外すという JavaScript の仕様が原因であるといえる。

これは些細なコーナーケースか？いやそんなことはなくて、JavaScript では比較的よく起きるシチュエーションだ。Promise の入れ子をはずされて、Promise に詰めなおした、という経験をもつ人は多いだろう。

# Functor ですらない Promise
ついでなので、Promise が Functor ですらないことも示しておこう（察しがいい人にはもう自明だろう）。ファンクター則は JavaScript で以下のように書ける。

```functor-law.js
// a はファンクター
'Identity'; _map(a, x => x) ≡ a
'Composition'; _map(a, x => f(g(x))) ≡ _map(_map(a, f), g)
```

Promise が Functor であるという人は以下を念頭に入れているだろう。

```promise-functor-mapping.js
const _map = (p, f) => p.then(f);
```

反例はすぐに上がる。

```Compositionが成立しない反例.js
const a = Promise.resolve(1);
const f = x => x.then(y => y + 1);
const g = x => x.then(y => y * 2);
_map(a, x => f(g(x))) // 左辺: type error
_map(_map(a, f), g) // 右辺: type error
```

一方、Array は Functor である（考えてみてほしい）

```array-functor-mapping.js
const _map = (arr, f) => arr.map(f)
```

# まとめ
Promise は Monad でも Functor でもない

# 参考
- [Fantasy-land](https://github.com/fantasyland/fantasy-land): JS で関数型プログラミングする人は必見。functor則, monad則 などなどを JS のsyntax で規定 
- [No, Promise is not a monad](https://buzzdecafe.github.io/2018/04/10/no-promises-are-not-monads): 他にもあるだろうけど本稿と同じ趣旨のblog記事
マイクのゲイン

マイクで音を録音する場合、次のようなケースが考えられる。

* 電話のようにマイクの近くに音源がある場合
* オーケストラの演奏のような大音量の音源の場合
* 鳥のさえずりのような微弱な音源の場合

最初のケースを基準にすると、二番目のケースはゲインを下げなければ音が割れる。三番目のケースはゲインを上げないと、ノイズに消されてしまう。ただし大きな音は割れてしまう。

最近のスマートスピーカーは一番目と三番目の中間くらいに位置するのかもしれない。この場合マイクは指向性があり、また認識率を上げるためには話者の方向にマイクを向けるべきである。カメラで話者を認識してその方向にカメラを向けるスマートスピーカとかあったらよくないかな。

一番目と二番目は割れないようにピークが出ないように設定せするのですが、三番目は対象以外の音はピークになっても良いように設定します。

ゲインを下げるのは抵抗などの簡単な回路で可能だが、ゲインを上げるのはトランジスタや[オペアンプの回路](https://qiita.com/yamori813/items/737f54bbcc584df8791e)が必要になる。また集音フードを使うことでもゲインを上げることも可能だ。

コンデンサーマイクの微弱な信号をケーブルで引き廻すと、ノイズの影響が出やすいので、ケーブルは短めにするとかマイクの近くにプリアンプを入れるのが良いと思う。

人間の耳は本当によくできていて、いろいろなイコライジングをかけて聞き取っているので、マイクではいろいろうまくいかないことが多い。

マイクアンプにはコンプレッサー機能がついてるものがある。コンプレッサーとは実際のレンジよりも出力を狭くして音割れを防ぐ機能である。電話のような場合には有効だが、それ以外の場合は逆効果になることもある。

私は三番目のケースをいろいろ試してみたいと思っている。
Nuxt.jsで画像をバインディングする方法2018年8月

# Nuxt.jsで画像をバインディングするする方法
自分用のメモとして記す。

今回は、初期に入っている `src/assets/logo.png` を親コンポーネントから子コンポーネントに渡してみる。

## require方式→うまくいかなかった

検索すると、以下のようにrequireでpropsから渡ってきた画像を囲んで、返ってきた文字列を`<img :src="返ってきた文字列">`のやり方があった。
が、requireなんて関数ねえよって怒られた。

### 親
```src/pages/top.vue
<template>
  <div class="top">
    <MainVisual image_url="../../assets/logo.png">
  </div>
</template>

<script>
import MainVisual from '../commons/MainVisual'
export default {
  name: 'Top',
  components: {
    MainVisual
  }
}
</script>
```

### 子
```src/components/commons/MainVisual.vue
<template>
  <div>
    <img :src="src">
  </div>
</template>

<script>
export default {
  name: 'MainVisual',
  props: {
    image_url: String
  },
  data () {
    src: require(this.image_url)
  }
}
</script>
```

## import方式→うまくいった
解決策として、以下のように親コンポーネントで使用する画像をimportしておき、それを子コンポーネントに渡した。

### 親
```src/pages/top.vue
<template>
  <div class="top">
    <MainVisual :image_url="src">
  </div>
</template>

<script>
import MainVisual from '../commons/MainVisual'
import MainImage from '../../assets/logo.png'
export default {
  name: 'Top',
  components: {
    MainVisual
  },
  data () {
    return {
      src: MainImage
    }
  }
}
</script>
```

### 子
```src/components/commons/MainVisual.vue
<template>
  <div>
    <img :src="image_url">
  </div>
</template>

<script>
export default {
  name: 'MainVisual',
  props: {
    image_url: String
  }
}
</script>
```
MySQLに127.0.0.1で接続するとAccess denied for user 'root'@'localhost'となる時の対応

ホストをlocalhostで指定すると接続できるが、　127.0.0.1で指定すると接続できないときの解決方法です。
なお、コマンドの変数は以下のことを意味しています。

- $DB_USER: ユーザー名
- $DB_PW: パスワード
- $DB_NAME: DB名


## 現状の確認
以下のような状態になっているとします。


127.0.0.1だと接続できません

```
mysql -u$DB_USER -p$DB_PW -D$DB_NAME -h 127.0.0.1

ERROR 1698 (28000): Access denied for user 'root'@'localhost'
```

localhostと指定すると接続できます。

```
mysql -u$DB_USER -p$DB_PW -Disubata -h localhost

mysql>
```

mysqlのユーザーにはhost=127.0.0.1のユーザーがいません

```
mysql> SELECT user, host FROM mysql.user ORDER BY user, host;
+------------------+-----------+
| user             | host      |
+------------------+-----------+
| debian-sys-maint | localhost |
| isucon           | %         |
| isucon           | localhost |
| mysql.session    | localhost |
| mysql.sys        | localhost |
| root             | localhost |
+------------------+-----------+

```

## 解決方法

今回は2つの方法を紹介します。

### 方法1. 『127.0.0.1で接続できるようにする』
DNSを無効にすることでIPアドレスで接続できるようにします。そのためには`skip-name-resolve`をtrueに設定します。


```/etc/mysql/my.cnf 
[mysqld]
skip-name-resolve
```

設定が完了したらmysqlを再起動して設定を反映させます

```
sudo systemctl restart mysql
```

### 方法2. 『127.0.0.1のmysql.userを作成する』
mysqlでは`$DB_USER@localhost`と　`$DB_USER@127.0.0.1`は別ユーザーとして識別されます。
そのため、127.0.0.1で接続できるようにユーザー権限の付与をします。


```
# 権限付与
mysql > GRANT ALL ON *.* TO $DB_USER@'127.0.0.1' IDENTIFIED BY 'root' WITH GRANT OPTION;

# 確認
mysql > SHOW GRANTS for $DB_USER@'127.0.0.1';
+---------------------------------------------------------------------+
| Grants for $DB_USER@127.0.0.1                                       |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO $DB_USER@'127.0.0.1'WITH GRANT OPTION|
+---------------------------------------------------------------------+

# 有効化
mysql > FLUSH PRIVILEGES;
```

## さいごに
ツイッター(<a href="https://twitter.com/nishina555" target="_blank" rel="noopener">@nishina555</a>)やってます。フォローしてもらえるとうれしいです！
Raspberry PiでWi-Fiを無効にする

Raspberry Pi Zero Wで無線無効にする設定。(Wの意味がない・・・)

#設定
/boot/config.txt の最終行に以下を追記すればよい。#はコメント行。

```/boot/config.txt
#turn wifi and bluetooth off
dtoverlay=pi3-disable-wifi	
dtoverlay=pi3-disable-bt	
```
rebootして、ifconfigでwlan0が出てこないことを確認。

##設定内容
/boot/overlays/README を読むと設定一覧が記載されている。
起動時に、カーネルにこの設定を行うことで、ハードウエアの違い等を吸収するための仕組みとのこと。
以下、bt=bluetoothとWi-Fi部分の抜粋。Loadの内容をconfig.txtに記載すればよい。

```
/boot/overlays/README
Name:   pi3-disable-bt
Info:   Disable Pi3 Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15
        N.B. To disable the systemd service that initialises the modem so it
        doesn't use the UART, use 'sudo systemctl disable hciuart'.
Load:   dtoverlay=pi3-disable-bt
Params: <None>

Name:   pi3-disable-wifi
Info:   Disable Pi3 onboard WiFi
Load:   dtoverlay=pi3-disable-wifi
Params: <None>
```
Github Gist を使いやすくするTIPS


## TIP. ローカルから git push できるようにする

（裏技なのだろうか）

- レポジトリ名にユーザー名を含めない
- git プロトコルを使う

git clone の例

```
git clone git@gist.github.com:45460cb396c8c82b65efff6e7395cbf6
```

参照 [Github Gist にローカルから push する - Qiita](https://qiita.com/YumaInaura/items/b1377bb69947a5707fb0)

## TIP. ファイルをソートする

Gist は ファイル名を ASCII の順番で表示しているようなので、並べ替えたい場合はファイル名を考慮する。

( e.g `00_README.md` `01_example.rb` `02_example.py` )

## TIP. 画像をアップする

Gistのコメント欄はアップロード機能がある。
いったんこれを使って画像アップロードしておいて、生成されたマークダウンやURLを、Gist本体のファイルにも使えば良い。

![image](https://user-images.githubusercontent.com/13635059/43615828-7738781c-96f4-11e8-80e3-15b296039558.png)

## TIP. Gistをブラウザで簡単に開けるようにする

- URLだけを記録したファイルを作っておく。
- URL記録ファイルを読んで、コンソールからWebブラウザを開くコマンドを叩く。

ローカルやWebを行き来する時に便利。

```
echo https://gist.github.com/YumaInaura/45460cb396c8c82b65efff6e7395cbf6 > gist.url
```

(Mac OS の場合)

```
open -a "Google Chrome" $(cat gist.url)
```

このファイルも git 管理に含めておくと、後からも操作しやすいと思う。

## TIP. 複数のGistを1個のレポジトリでまとめて管理する

git submodule を使う。

参照: [Github Gist を1個のレポジトリでまとめて管理する ( git submodule を利用 ) - Qiita](https://qiita.com/YumaInaura/items/8088aae8df7ffac482b9)

## Gist

- [Make it easy to use Github Gist TIPS](https://gist.github.com/YumaInaura/45460cb396c8c82b65efff6e7395cbf6)








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Visual Studio CodeでC/C++実行環境を整える

Windows10にいれたVisual Studio Code上でC/C++をビルド、実行できるようにしたメモです。

Visual Studio Codeはインストール済みとする。

#MSYS2/MinGWをインストール
###1.MSYS2をインストール
gcc環境としてMSYS2(MinGW-w64)を使用する。
公式からインストーラーをダウンロードし、インストールする。
http://www.msys2.org/
msys2-x86_64-yyyymmdd.exeをダウンロード、すべてデフォルトのままインストールする。

###2.MinGWをインストール
インストール後、MSYS2のshellが立ち上がるので、アップデートと追加モジュールのインストールを行う。

```
pacman -Syuu
```
実行すると以下のワーニングが出て途中で止まってしまった。

```
警告: terminate MSYS2 without returning to shell and check for updates again
警告: for example close your terminal window instead of calling exit
```
再実行するように言われているので、いったん閉じて(ワーニング出るが無視)、
スタートメニューのMSYS2 64bitのMSYS2 MinGW 64-bitをクリックしてshellを起動。

```
pacman -Syuu
```

追加モジュールを入れる。上の2つだけ入れればいいもよう。makeは不要かもしれないが何となく入れた。

```
pacman -S base-devel
pacman -S mingw-w64-x86_64-toolchain
pacman -S mingw-w64-x86_64-make
```

###3.PATHの設定
環境変数のPATHに以下の2つを追加する。

```
C:\msys64\mingw64\bin
C:\msys64\usr\bin
```
エクスプローラでコンピュータを右クリックしてプロパティからシステムの詳細設定を開き、詳細設定タブで環境変数を表示する。

###4.設定の変更
32bit版は使用しないため、除外する。
`C:\msys64\etc`にあるpacman.confをテキストエディタで開き、以下の行をコメントアウトする。

```
[mingw32]
#Include = /etc/pacman.d/mirrorlist.mingw32
```

###5.動作確認
適当なフォルダに動作確認用のコードを作成する。

```hello.c
#include <stdio.h>

void main(void){
    printf("hello, world\n");
}
```

コマンドプロンプトを起動し、実行してみる。
![クリップボード.jpg](https://qiita-image-store.s3.amazonaws.com/0/276188/0c20ddab-8301-b7af-013c-3e62ecdabfa7.jpeg)
実行できたのでGCC環境とPATH設定は完了。

ちなみに、普通はCドライブだと思いますが、私は作業場所をDドライブにしています。
コマンドプロンプトで`D:`とだけ入力するとDドライブに移動可能です。("cd D:\" では移動できない)

#Visual Studio Codeの拡張設定
Visual Studio Codeの拡張機能を開き、C/C++と入力、一番上に出てくるMicrosoftの拡張機能をインストールする。
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/276188/cefd860f-ecf4-f23a-5ca7-28ddcc9558f9.jpeg)
これで、コード補完が可能になる。

PATHがつながっているので、Visual Studio Code側の設定は特に不要です。
コンソールから同じように実行可能。PowerShellを使用している場合は、hello.exeとしても実行できず、
`./hello.exe` とする必要があります。(よく読むと一番下に書いてあったけど、だいぶ嵌りました^^;)
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/276188/38449275-6c96-416f-9644-42777ac33b11.jpeg)

以上！

頑張ればステップ実行もできるようですが・・・そのうち調べようと思います。
まぁ無償版のVisual Studio使えばいいんじゃない？:sweat_smile:

2018/08/08 追記
MinGW-w64をWindowsで使う場合にはセキュリティに対する脆弱性があるとのこと。
以下を参考にしたほうがよさそうです。
[mingw-w64 が生成する実行ファイルにおいて ASLR が機能しない問題](https://jvn.jp/vu/JVNVU99390733/)

#参考
- [MSYS2/MinGW-w64 (64bit/32bit) インストール手順 メモ](https://gist.github.com/Hamayama/eb4b4824ada3ac71beee0c9bb5fa546d)
- [Visual Studio Codeの設定(C/C++編)](https://qiita.com/lunatea/items/0ff9cb103bc45a0f66b7)
- [Windows10の開発環境をMSYS2で再構築](https://qiita.com/azk0305/items/a546da060f3ab8d6a8bf)
VSCodeでerbファイルでもEmmet補完が効くようにする

# VSCodeのEmmet補完

VSCodeではHTMLファイルを開くと標準でEmmet補完が効くようになります。
例えば、`ul>li*5`と入力すると、Emmet Abbreviationと書かれた補完候補が表示され、これを選択すると以下のように展開されます。

```html
<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>
```

ところが、erbファイルを開いた時にはこれが効きません。

# erbでもEmmet補完する設定

VSCodeの設定に以下を追記します。
`files.associations`では、拡張子`.erb`を持つファイルをerbファイルとして定義します。
`emmet.includeLanguages`では、erbファイルにhtml形式のEmmet補完を適用するように設定します。
（html形式の補完の他に、css形式のEmmet補完が存在します。）

```
"files.associations": {
    "*.erb": "erb"
}
"emmet.includeLanguages": {
    "erb": "html"
}
```

これでerbファイルでもEmmet補完が効くようになったはずです。

# 参考

https://github.com/rubyide/vscode-ruby/issues/197
ターミナルで使用できる全コマンドを表示する方法は意外と簡単だった

「今のユーザーで使えるコマンドってどんなものがあるんだろう？」

とふと考えてしまったので試してみた。

## 結論: TABキーを2回叩く

使えるコマンドを表示するコマンド自体を最初は探していたけど、Linuxの補完機能で事足りた。

TABキーを2回叩くと、
`Display all 1852(ここは環境によって異なる) possibilities?(y or n)`
と聞かれるので`y`を押せば選択可能なコマンドが表示される。

![Screenshot 2018-08-03 07.57.05.png](https://qiita-image-store.s3.amazonaws.com/0/79990/4bbd10d7-bcb5-e5cd-d1b6-fdea3ba89a54.png)

もちろん補完なのでファイルやディレクトリもコマンド以外が入ってしまっているけれども、
コマンドだけを出す必要もなかったのでこれでよしとする。
FreeBSDのサウンドまわり

いろいろFreeBSDのサウンドまわりを調べていて、なんか変だなと思うことをまとめてみました。10.4Rか12CURRENTで確認してみました。

# 標準のディストリビューションに再生や録音のコマンドがない

再生や録音のコマンドが入ったwavplayやsoxなどのパッケージはありますが、/usr/binにはありません。Appleですらafplayというコマンドを10.5から用意していて、soundが標準で組み込まれているkernel configもあり、少なくとも再生コマンドを用意すべきだと思います。

# デバイスファイルがへん

USBオーディオデバイスを接続すると/dev/audioなどが作られるのですが、ls /devでは表示されません。なんでかな？

# 複数のUSBデバイスの区別がつかない

複数USBデバイスを接続した時にデバイス番号とデバイスの確認ができません。CoreAudioのようにUSBのデバイス名を使うのが良いのではないででしょうか。

```
% cat /dev/sndstat 
Installed devices:
pcm0: <USB audio> (play)
pcm1: <USB audio> (play/rec) default
pcm2: <USB audio> (play/rec)
```

# 勝手にふられるdefaultが変えられない

~~defaultはなんらかのロジックで設定されるようなのですが、これを変えることができません。数字の付いたデバイス名を直接指定するしかありません。soxのコマンドはdefaultしか扱えないのでとっても不便です。~~
hw.snd.default_unitで変えられるようです。

# mixerコマンドの一覧がわかりにくい

volやpcmなどは出力系でmicは入力系なんですが、同じように表示されてわかりにくい。またmicの初期値が0:0なのはなぜ？

```
% mixer
Mixer vol      is currently set to  75:75
Mixer bass     is currently set to  50:50
Mixer treble   is currently set to  50:50
Mixer pcm      is currently set to  75:75
Mixer mic      is currently set to   0:0
```

# kernel configのsoundとmoduleのsoundが同じで無い

kernel configのsoundはsoundだけを入れますが、moduleでsoundを指定するとsoundとすべてのsndモジュールを入れてしまいます。moduleではsound/soundとするとsoundだけになり、それぞれのドライバーはsound/driver/hogeと指定するようです。

# 起動時にUSBモジュールが認識されないことがある

10.4R/amd64で起動時にUSBモジュールを接続していると認識されないことがある。チップセットの問題かもしれないが。

# SNDCTL_DSP_SPEEDが設定値がへん

録音する時のioctlのSNDCTL_DSP_SPEEDで設定値がサンプリングレートの2倍を指定しないとデータがへんでした。amd64でもmipsでも同じでした。

# mipsの録音でpanic

12CURRENTでデバッグしたけどわからなかったので、Bugzilla入れました。

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=230370

# RT3050(mips)で録音した音がへん

サウンドの問題ではなくてSOC側のクロックの問題な気がします。

# 資料が少ない

公式のハンドブックはPCI時代の事が書かれていて、最近はUSBデバイスの方が多いので参考にならないところも多い。
API GatewayのBinaryMediaTypesを指定するとCloudFormationのStackの更新に失敗する

[docomo Developer support](https://dev.smt.docomo.ne.jp/)の[@akatsukaha](https://qiita.com/akatsukaha)です

API GatewayのリソースをCloudFormationで作成後に，BinaryMediaTypesを追加して更新すると何故か失敗するのでその記録を残します．

Templateを作成

```yaml:template_v1.yaml
AWSTemplateFormatVersion: '2010-09-09'

Resources:
  TestApi:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Description: 'Test API'
      Name: 'Test API'
      FailOnWarnings: true
      EndpointConfiguration:
        Types:
          - EDGE

  TestApiResource:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      RestApiId: !Ref TestApi
      ParentId: !GetAtt TestApi.RootResourceId
      PathPart: 'test'
```

Stackを作成する．
無事APIが作成されている．

![スクリーンショット 2018-07-27 13.33.03.png](https://qiita-image-store.s3.amazonaws.com/0/262328/32265d5b-1fd3-bc72-e03f-b56e44807ef3.png)

![スクリーンショット 2018-07-27 13.57.45.png](https://qiita-image-store.s3.amazonaws.com/0/262328/b9d88cbf-e871-ec75-8b0b-c3a45c3647d4.png)

続いて，BinaryMediaTypesをTemplateに追記してStackを更新してみる．

```yaml:template_v2.yaml
AWSTemplateFormatVersion: '2010-09-09'

Resources:
  TestApi:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Description: 'Test API'
      Name: 'Test API'
      FailOnWarnings: true
      BinaryMediaTypes: 
        - image/jpeg
      EndpointConfiguration:
        Types:
          - EDGE

  TestApiResource:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      RestApiId: !Ref TestApi
      ParentId: !GetAtt TestApi.RootResourceId
      PathPart: 'test'
```

何故か失敗する．

![スクリーンショット 2018-07-27 14.56.01.png](https://qiita-image-store.s3.amazonaws.com/0/262328/88106576-8f76-df41-d336-40c8b9b1702d.png)

ログ見ると`/binaryMediaTypes/image/jpeg`のパスのリソースを変更しようとしている？

```
Invalid patch path /binaryMediaTypes/image/jpeg (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID: 
```

もちろん反映されていない

![スクリーンショット 2018-07-27 14.56.46.png](https://qiita-image-store.s3.amazonaws.com/0/262328/c6db6bef-7ce5-5ef3-f3f8-9b1676560e75.png)

Stackを削除して，BinaryMediaTypesを追加した下記のTemplateを利用してStackをゼロから作成してみる．

```yaml
AWSTemplateFormatVersion: '2010-09-09'

Resources:
  TestApi:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Description: 'Test API'
      Name: 'Test API'
      FailOnWarnings: true
      BinaryMediaTypes: 
        - image/jpeg
      EndpointConfiguration:
        Types:
          - EDGE

  TestApiResource:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      RestApiId: !Ref TestApi
      ParentId: !GetAtt TestApi.RootResourceId
      PathPart: 'test'
```

サクッと作れた．

![スクリーンショット 2018-07-27 15.01.29.png](https://qiita-image-store.s3.amazonaws.com/0/262328/03cd184d-3266-578a-9761-003ee0a864ad.png)

![スクリーンショット 2018-07-27 15.01.46.png](https://qiita-image-store.s3.amazonaws.com/0/262328/d069ab42-c6f7-a5db-836e-7eead8cf21f8.png)

なぜかBinaryMediaTypesを指定すると更新ができない模様
【ATOM】ATOMの日本語エラーを直しました

## あれ？こんなエラーがなんで？

この前まで普通に使えてたのに。こんなエラーが。

`UnicodeEncodeError: 'ascii' codec can't encode characters`

パッケージのjapanese-menuはちゃんと作動して日本語表記になっている。
エンコードエラーを回避するために変更していた項目

~~~coffee
process.env.PYTHONIOENCODING = "utf-8";
~~~
~~~coffee
exports.Python =
  'Selection Based':
    command: 'python3'
    args: (context) -> ['-u', '-c', context.getCode()]

  'File Based':
    command: 'python3'
    args: ({filepath}) -> ['-u', filepath]
~~~
~~~coffee
runner:
    scopes:
      python: "python3"
~~~
これらも変更済み。
日本語出力について調べてると、だいたいこんなところでエラーがなくなるらしいけど直らない…

## 最近何したっけ？
こんな記事を発見。

http://www.o2-m.com/wordpress2/2017/08/21/atom-runnerでpythonプログラムを実行すると日本語表示がエラ/

前回のrunから新しくやったことは。
iTeam2の導入と、zshへの変更。ちょっと近い気がしてきた。
けど、ATOMとzshを関連させて書いてある記事は見つけられず。

## 悪の元凶を特定

上記の記事のようにターミナルで
~~~
mv ~/.zshrc ~/.zshrc.old
~~~
.zshrcのファイル名を他の名前に変更すると、atomのエンコードエラーがなくなった！！
けど、zshの設定も初期化されてるorz

## zsh の調査

あんまり理解できてないんですが、zsh の環境設定で[少し凝った.zshrc](https://gist.github.com/mollifier/4979906)のなかには、こんな一文が。

~~~coffee
# 環境変数
export LANG=ja_JP.UTF-8
~~~

## 解決しました
結果的には.zshrcに[少し凝った.zshrc](https://gist.github.com/mollifier/4979906)をほぼコピペしたんですが、無事にエンコードエラーから解放されました。

zsh 導入時にお約束的に記載が必要だったのかもしれませんが、そこまで出来てなかったツケが回ってきたようです。
名前付きPIPE + scriptコマンド + Python で base64結果をローカルに保存

## 目次

- TL;DR
- usage
- 仕組み
    - 名前付きPIPE
    - script コマンド
    - `snatch_base64.py` 機能
- 以上ですが、嘘かもしれない
- 参考文献

---

## GitHub

https://github.com/mandbjp/snatch_base64

---

## TL;DR
- なぜ作った？
    - 多段sshした先のファイルをscpで取ってくるのが大変だから、標準出力からファイルに落とせるようにした
- 以下のようなコマンドを叩くとMac内にファイルを保存する
    - `cat some_large_text.log | gzip | base64 -w0`
    - `cat some_archive.tar.gz | base64 -w0`

---

## usage

```shell:term1_ssh
> mkfifo -m 0777 fifo.pipe
> script -qF fifo.pipe
> 
```

```shell:term2_snatch_base64
> python snatch_base64.py

```

```shell:term1_ssh(cont.)
> ssh user@centos.somedomain.local
[centos]> cat some_large_text.log | gzip | base64 -w0
ASDF....==[centos]> 
> 
```

```shell:term2_snatch_base64(cont.)
start capture!!
gzip support
dumped!!
```
 
---


## 仕組み
---

### 名前付きPIPE
---

#### 名前付きPIPEって？

- 通常のPIPEは `|` で stdout -> stdin をつなぐ
- 名前付きPIPEは `mkfifo` で作られたファイル越しに stdout -> stdin をつなぐ


---

#### 名前付きPIPE 使い方

```shell:term1
> mkfifo -m 0777 my_fifo.pipe
> cat my_fifo.p
(ここで止まる)
```

```shell:term2
> echo "hello!" > my_fifo.pipe
> 
```

```shell:term1
> mkfifo -m 0777 my_fifo.pipe
> cat my_fifo.p
hello!
> 
```

---

#### 名前付きPIPE 特徴

- ターミナルが別でも伝搬可能
- 実行ユーザーが別でも伝搬可能 `-m 0777　オプション`
- 入出力が揃わないと開始しない
- 名前付きPIPEへの出力 (`term2`) が終了すると、 名前付きPIPEからの入力 (`term1`) も終了する

---

### script コマンド
---

#### script コマンド (Mac/FreeBSD系)

- stdin/stdout を記録してくれる
- `-F` : 名前付きPIPEへ出力する
- `-q` : 開始/終了メッセージを表示しない

---

#### script使い方 (ターミナルをミラー化)

```shell:term1
> mkfifo -m 0777 my_fifo.pipe
> cat my_fifo.pipe
（待つ）
```

```shell:term2
> script -qF my_fifo.pipe
> （ここで何かを入力する）
```

```shell:term1
> mkfifo -m 0777 my_fifo.pipe
> cat my_fifo.pipe
(全く同じ挙動がここで見える)
```

- ターミナルをリサイズして `vim` とかやると面白い

---

#### script 特徴

-  stdin/stdout 両方取れる
-  ただし、stdin/stdout の区別はできない

---

### `snatch_base64.py` の機能
---

#### `snatch_base64.py` がやってること

1. 名前付きPIPEをFileOpenする
-  → ユーザーの入力も、コマンドの結果も読み取れる
- 改行区切りで入力を判定する
- `(centos用) base64 -w0` の文字列が含まれるか
- `(mac用) base64 -i -` の文字列が含まれるか
- 含まれている場合、次の行をbase64入力として準備する
- 改行を見つけるまでメモリ上に貯め込む
- 改行されたら溜め込んだものを base64decode してファイル保存する

---

#### `snatch_base64.py` の強み

- ローカルのstdin/stdoutしか見ないため、多段のsshにも対応
- 先方サーバーにはツール等のインストールが不要
    - ただし base64コマンドが使えること
- `gzip` 検出で保存時にgz展開
- `cat` 検出でファイル名取得

---

## 以上ですが、間違ってるかもしれない

- 本書の内容は短い経験的なことで書いてます
- 正しくない情報が含まれてるかもしれません
- 間違ってたらごめんなさい

---

## reference
- [gzip base64 encode and decode string on both linux and windows - Stack OverFlow](https://stackoverflow.com/questions/42459909/gzip-base64-encode-and-decode-string-on-both-linux-and-windows)

---

## _End of Slide_
各層対応プロトコル

![](https://thinkit.co.jp/sites/default/files/styles/main_image_730x/public/main_images/5800_main_8.png?itok=23DSvTFH)

##TCP/IP階層モデル


|     | 名称                           | 役割                                             | プロトコル                                    |
|-----|--------------------------------|--------------------------------------------------|-----------------------------------------------|
| 4層 | アプリケーション層             | アプリケーション間のやり取り                     | HTTP、POP3、SMTP、FTP、DHCP, DNS, TFTP, IMAP4 |
| 3層 | トランスポート層               | プログラム間の通信、通信の制御                   | TCP、UDP                                      |
| 2層 | インターネット層               | インターネットワークでの通信                     | IP、IPsec                                     |
| 1層 | ネットワークインターフェイス層 | 同一ネットワーク上での通信、ハードウェア仕様など | Ethernet、PPPoE                               |


#### TCP/IP（Transmission Control Protocol/Internet Protocol）

>現在のインターネット通信およびイントラネット通信において最も利用されている通信プロトコルです。TCP/IPは複数のプロトコルからなりますが、中心的な役割を果たすのがTCPとIPであることから TCP/IP と呼ばれるようになりました。　※　IP通信で使用するプロトコル群（ IP, ICMP, TCP, UDP, HTTP, SMTP, SSH,TELNETなど）を総称してTCP/IPと呼びます。

##OSI参照モデル

|   | 名称                   | 役割                                                                                    | プロトコル                                                      |
|-------|----------------------|-----------------------------------------------------------------------------------------|-----------------------------------------------------------------|
| 7層 | アプリケーション層   | アプリケーション間でのデータのやり取りを規定する                                        | HTTP DHCP SMTP SNMP SMB FTP Telnet AFP X.500                    |
| 6層 | プレゼンテーション層 | データの表現方法を規定する                                                              | SMTP SNMP FTP Telnet AFP                                        |
| 5層 | セッション層         | セッションの手順を規定する                                                              | TLS NetBIOS NWLink DSI ADSP ZIP ASP PAP 名前付きパイプ          |
| 4層 | トランスポート層     | 各コンピュータ上で実行されている、2つのアプリケーション間での通信方法を規定する         | TCP UDP SCTP DCCP SPX NBF RTMP AURP NBP ATP AEP                 |
| 3層 | ネットワーク層       | ネットワーク上の2つのコンピュータ間での通信方法を規定する                               | IP ARP RARP ICMP IPX NetBEUI DDP AARP                           |
| 2層 | データリンク層       | 1つのネットワーク媒体に接続された複数のコンピュータの間でデータを伝送する方法を規定する | Ethernet トークンリング アークネット PPP フレームリレー         |
| 1層 | 物理層               | コンピュータのデータとネットワーク媒体上を流れる電気的な信号を変換する方法を規定する    | RS-232 RS-422 (EIA-422、TIA-422) 電話線・UTP ハブ リピータ 無線 |

>OSI参照モデル（OSIさんしょうモデル、英: OSI reference model）は、コンピュータの持つべき通信機能を階層構造に分割したモデルである。国際標準化機構(ISO)によって策定された。 OSI基本参照モデル、OSIモデルなどとも呼ばれ、通信機能（通信プロトコル）を7つの階層に分けて定義している。


##参考


* [TCP/IP 4階層モデルとは？ | Think IT（シンクイット）](https://thinkit.co.jp/story/2015/04/30/5800)
* [TCP/IPをはじめから](http://www.infraexpert.com/study/tcpip.html)
jQuery UIを使わずにドラッグドロップしてみる

現在受けてるNuxt.jsの授業の課題のひとつで『jQuery UIを使わずにドラッグドロップを実装する』というのがあって、一見難しい様でJavaScriptをしっかり使いこなせていればなんて事なく、普段使わないflagの使い方を知るすごくいい課題だったので、復習の為にまとめようと思いました。

ドラッグドロップのイベントを分解すると以下の３つになります。

① mousedown
要素をクリック

② mousemove
クリックしたままマウスを動かす＝ドラッグ

③ mouseup
クリック解除してドラッグ終了

[完成品はここにあります](http://eiciemm.sakura.ne.jp/dragdrop/)



まずは必要なグローバル変数などを用意。
movingはフラグです。

```
var elements = document.getElementById("red");
var x;
var y;
var moving = false;
```


<br>
<br>



```
elements.addEventListener("mousedown", function (e) {
　moving = true;
  x = e.pageX - this.offsetLeft;
  y = e.pageY - this.offsetTop;
}, false);
```
① mousedown
要素をクリックした時、movingをtrueにします。
これ自体には意味ありません。フラグの名の通り、旗で、目印です。後で役に立ちます。

そして、次の行で不思議な計算をします。これは百聞は一見にしかずで目でみた方がわかりやすいと思い、図にしました。

<img width="444" alt="01.png" src="https://qiita-image-store.s3.amazonaws.com/0/173182/c258c5fe-0938-6123-71e0-1643ba683456.png">

<img width="388" alt="02.png" src="https://qiita-image-store.s3.amazonaws.com/0/173182/6d551824-6448-0c53-1872-09ea9c3768a5.png">

なぜこの部分の値を求めておくのかは次のmousemoveでわかります。
<br>
<br>



```
window.addEventListener("mousemove", function (e) {
   if (moving == false) return

   elements.style.top = e.pageY - y + "px";
   elements.style.left = e.pageX - x + "px";

}, false);
```

② mousemove
マウスを動かしている時のイベントを検出するのですが、ここで最初に設定したフラグが役に立ちます。フラグがfalseの時（要素をクリックしてない時）はその下の処理は実行しません。こうしておかないとマウスの動きを常に検出してしまいます。

そして、マウスを動かしてカーソルの座標(pageX, Y)をそのままCSSに入れてもドラッグドロップは成立するのですが、そうするとドラッグし終わった時に要素の左上が矢印の位置にずれるのです。これはCSSのtop, left値が要素の左上のx, y座標だからです。

<img width="831" alt="03.png" src="https://qiita-image-store.s3.amazonaws.com/0/173182/7e2e58ca-932b-0e7a-4ac3-a5e0d25cca00.png">

これも百聞は一見にしかずだと思うので、別で用意しました。
[こちらをどうぞ](http://eiciemm.sakura.ne.jp/dragdrop/example)
<br>


もう一点ここでの注意点として、dom要素のelementsに対してではなく、windowにaddEventListenerを指定してます。これはdom要素のelementsに指定するとマウスの動きについてこれずに素早くドラッグすると要素が置いていかれてしまうバグが発生してしまうのを防ぐためです。
[これがそのサンプルです](http://eiciemm.sakura.ne.jp/dragdrop/example2)

<br>
<br>

```
elements.addEventListener("mouseup", function () {
  moving = false;
}, false);
```

③ mouseup
最後にマウスのボタンを離した時にドロップになります。ここでの処理はフラグをfalseに戻すだけ、これでmousemoveで行われてる計算は行われなくなり、要素の動きも止まります。


実際の開発の現場ではjQueryUI使うと思うけど、あえて使わずに書くというこの経験がコード力をあげていくと思いました。
tkinterのcanvasのevent時image書き換えで画像が表示されなかったからごり押しした

###要約：tkinterのcanvasのcreate_imageの画像データ(PhotoImage等)はglobal変数に持たせておけばとりあえずしのげる。
--------
本題
tkinerのeventのコールバックでcanvasの画像(create_imageしたやつ)を更新(ex:マウスクリックされたピクセルを赤く塗る等)するとき、

```python
#前略　import類
canvas = tkinter.Canvas("""オプションをだらだらと""")
PIL_Img = PIL.Image.open('foo.png')
#中略　(canvasに最初の画像を置いたりｳｲﾝﾄﾞｳｻｲｽﾞを云々～～
def callback(event):
     PIL_Img.putpixel((event.x,event.y), (255, 0, 0, 255))
     event.widget.itemconfigure(1,image = PIL.ImageTk.PhotoImage(PIL_Img) )
#　　　　　↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑▲このへんが問題▲↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

canvas.bind("<1>",callback)
#その他略
```
などとすると、画像が消える。どうやらコールバック内のみでしかPhotoImageの参照を持ってくれないらしい。create_ovalとかはちゃんと残るので逆に混乱する。なんでやねん。

個人的にかなり不本意だがグローバル変数に参照を持たせることでとりあえず解決した。

```python
#前略　import類
global img """←こいつに画像の参照を持たせる"""
#中略　(root = tkinter.Tk()云々～～
canvas = tkinter.Canvas('~~~~略~~~~')
PIL_Img = PIL.Image.open('mask.png')
#中略　(canvasに最初の画像を置いたりｳｲﾝﾄﾞｳｻｲｽﾞを云々～～
def callback(event):
     global img """←ここにもこう書かないと×"""
     PIL_Img.putpixel((event.x,event.y), (255, 0, 0, 255))
     img = PIL.ImageTk.PhotoImage(PIL_Img)
     event.widget.itemconfigure(tagOrId="foo",image = img)

canvas.bind("<1>",callback)
#後略　(root.mainloop()云々～～
```

----
解決のヒントになった記事
http://lrcgf.hatenablog.com/entry/2013/06/30/222918
tkinterの画像がどうのこうのについては
https://docs.python.jp/3/library/tkinter.html#bindings-and-events　の25.1.6.9にもその記載があった
グローバル変数については　https://qiita.com/msssgur/items/12992fc816e6adf32cff
を参考に
めっちゃハマった。つらみ。
Pipenv管理下のJupyter NotebookプロジェクトにRuby kernelをBundlerで入れる

グローバルな環境にPython, Pipenv, Ruby, Bundlerはインストール済みと仮定します。

動作確認済みのバージョンは以下

```shell-session
$ python --version
Python 3.6.2

$ pipenv --version                       
pipenv, version 2018.05.18

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

$ bundle -v
Bundler version 1.16.2
```
# プロジェクト開始
```shell
$ mkdir someProject
$ cd someProject
```

# Pythonパッケージインストール
```
$ pipenv install jupyter
```

# Rubyパッケージインストール
```
$ bundle init
```

```ruby:Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem 'cztop'
gem 'iruby'
gem 'rbczmq'

```
```
$ bundle install --path=vendor/bundle
```
- [参考] [rbczmq の幾つかのインストール方法 - Qiita](https://qiita.com/mrkn/items/78196ed59266f58dcb64)

# Jupyter NotebookにRuby kernelを登録
次のコマンドが唯一のポイントです。

```
$ pipenv run bundle exec iruby resister
```

`pipenv run`しないと`ipython`コマンドが見つからないと怒られます。

```shell-session:間違ったコマンド
$ bundle exec iruby resister

bundler: failed to load command: iruby (path/to/someProject/vendor/bundle/ruby/2.5.0/bin/iruby)
Errno::ENOENT: No such file or directory - ipython
```

# 設定ファイル変更
前述のコマンドで`~/.ipython`ディレクトリが作られますので、以下のようにファイルを変更します。

（`display_name`はお好みで変更可）

```json:~/.ipython/kernels/ruby/kernel.json
{
	"argv": [
		"pipenv",
        "run",
        "bundle",
        "exec",
        "iruby",
		"kernel",
		"{connection_file}"
	],
	"display_name": "Ruby 2.5.1",
	"language": "ruby"
}
```

# 実行
```
$ pipenv run jupyter notebook
```

`New▼`から`Ruby`が選べる！しあわせ！
sbtインストール

#sbtのインストール
scalaの勉強を始めるにあたってまずはビルドツールであるsbtをインストールした。
Mac OSの場合はHonebrewでインストールできた。
`$ brew install sbt`
バージョン確認は
`$ sbt --launcher-version`
`sbt launcher version 1.0.4`
でできた。
`$ sbt --version`だと

```

[info] Loading project definition from /Users/hisashi/sbt/project
[info] Loading settings for project sbt from build.sbt ...
[info] Set current project to sbt (in build file:/Users/hisashi/sbt/)
[error] Expected symbol
[error] Not a valid command: --
[error] Expected 'debug'
[error] Expected 'info'
[error] Expected 'warn'
[error] Expected 'error'
[error] Expected 'addPluginSbtFile'
[error] --version
[error]   ^

```
というエラーが出る。sbtのバージョンによってコマンドが違うらしい。

`$ sbt console`
で対話形式で実行できる。
https://dwango.github.io/scala_text/
を読みながら勉強していく。今後つまずいたところとかをまとめていきたい。
DB設計の考え方やポイントについて~超初級編~


## はじめに

この記事は、僕がメンターから教わったDB設計の考え方についてまとめたものになります。

## 設計に取り掛かる前の大前提
リリースまでに必要となるであろう、おおよその機能についての洗い出しがしっかり終わっていること。


## DB設計の考え方
1. column を細かく洗い出すより、table 同士の relation が明確になることのほうが大切
1. 最初からできるだけアルファベットでそのまま書く（カラム名を日本語にすると二度手間であるため）
1. ある程度拡張性も意識して設計することが必要
1. 正規化についての理解を深めておくこと

### 参考
https://qiita.com/naoqoo2/items/cdda5fe6f9935a03189d

### ファーストステップ
* 各テーブル同士の関連について、手書きで書いてみる
* 機能の洗い出しに不安があるなら、もう一度見直す
* テーブル同士の関係性が明確になったら、それぞれのテーブルに必要なカラムを書き出す


## レベル0:テーブル同士の関係性について考える

![新規ドキュメント 2018-08-03 00.52.20_1.jpg](https://qiita-image-store.s3.amazonaws.com/0/195539/38816d24-aa8e-acc0-d59d-cf6af119dc79.jpeg)

### ステップ1
まずは、各テーブルにどんなデータが保存されているかを、丸で囲って洗い出す。
(ここではカラム同士の関係性は考慮しない)

### ステップ2
丸で囲んだテーブル同士に、どんな関係性があるかを考える。

### ポイント
* テーブル同士の関係性が多対多である場合、中間テーブルを作る。
(railsの場合は、特徴のない中間テーブルを作成する場合、テーブル同士の名前をスネークケースで表示する。 eg:`article_tags`）
* テーブル名は必ず複数形になるので、手書きの際も必ず複数形で書くように意識する
Linuxコマンドのvmstatの使い方について

#▼vmstatの使い方について
先日検索用のSQLを流そうとしたら、「SQL実行時に、vmstatコマンドで念のため問題ないかは見ておいてね」と言われました。ただ、vmstatって名前知ってるけど使い方知らないです、、状態だったので、これを機会に簡単な使い方を調べようと思いましたので以下備忘録として記載します。

##◆そもそもvmstatって？
まずはググりました。
「vmstatは仮想メモリやCPU、ディスクI/Oの統計情報を表示するコマンド」
とのことですので、簡単い言えばシステムの情報を表示する、みたいです。

##◆実行して見た
とりあえず以下の環境で実行して見ました。
ローカル：maxOS High Sierra バージョン 10.13.4
リモート：CentOS release 6.9 (Final)

```shell

[shota@hostname ~]$ vmstat
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0  31008 169728 163352 223440    0    0     0     1    0    0  0  0 99  0  0
```
それぞれ順番に現在の"プロセス"、メモリー、スワップ、デバイス、割り込み、CPUの情報が表示されます。
また、○秒間隔で表示するといったこともできます。

```shell

[shota@hostname ~]$ vmstat 3
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0  31008 167432 163352 223448    0    0     0     1    0    0  0  0 99  0  0
 0  0  31008 167440 163352 223448    0    0     0    11  110  135  0  0 100  0  0
 0  0  31008 167440 163352 223448    0    0     0     4  112  133  0  0 100  0  0
 0  0  31008 167448 163352 223448    0    0     0     0  124  133  0  0 100  0  0
 0  0  31008 167448 163352 223448    0    0     0     4  115  136  0  0 100  0  0
```
上記のように、引数で数字を指定するとその指定した秒毎にシステム情報を出力してくれます。
それぞれの詳しい見方はよくわかってないですが、近いうちに調べます。
'.ssh/conig' を使わない多段SSHポートフォワーディング

#　はじめに
検証でたくさんのサーバに多段ポートフォワーディングしないと行けなくなったが、
多段sshのやり方を調べると '.ssh/conig'に設定を記載する方法ばかりヒットするのと
そもそも多段sshがなぜ可能なのか、といった中身の話の解説記事が見当たらなかったので調べた内容をここに記録する

## TL;DR
・運用とかでいろんなサーバ管理してる人
・でセキュリティポリシー厳しくて踏み台挟まないと行けない人
・加えてブラウザアクセスしたいけどポートフォワーディング経由じゃないと通信経路がそもそもないみたいなカッチカチな環境のお相手をしている人
・どちらかというとWindowsな人向け

## 時間が無い方へ

``` bash 
# stepsv ... 踏み台サーバのホスト名 or IP
# targetsv ... 接続したいサーバのホスト名 or IP
# -t 強制的に仮想端末(tty)作る

ssh.exe -t -l user -i private.key -L 10443:localhost:10443 stepsv "ssh -L 10443:targetsv:443 targetsv"

```

で `https://localhost:10443/` にブラウザアクセスするとめでたく `targetsv` の `443` ポートと通信できる。


## (適当な)解説
そもそもsshコマンドにはリモート先サーバのコマンドを実行する機能がある。
こんな感じ

``` batch
ssh -l user remotesv "ls -l"
```


そしてポートフォワーディングという機能
ポートフォワーディングは一つ上のリモート先コマンドの実行の応用みたいなもので、
リモート先でパケットを発砲しちゃう、という機能
もちろんReceiveしたパケットは手元の端末に戻してくれる。

簡単に言えばsshで張ったトンネルの中に自由なプロトコルを流すことができる
こんな感じ

``` batch
ssh -l user -L 443:localhost:443 remotesv 
```



上記コマンドはまず `remotesv` にsshして、**remotesv** から `localhost` の `443` 宛にパケットを発泡せよ、って意味のコマンド
なので remotesvの 443と通信できる。


で、この2つの機能を組み合わえて、
リモート先でさらにポートフォワーディングしたら数珠つなぎで更に先のサーバと通信できるんじゃね？って予感がする
絵にすると次のとおり。 `->` がポートフォワーディング

localpc(10443) -> (10443)stepsv(10443) -> (443)targetsv
 
そしてこの予感は正しい。


で出来上がったコマンドが

``` bash 
ssh.exe -t -l user -i private.key -L 10443:localhost:10443 stepsv "ssh -L 10443:targetsv:443 targetsv"

```

他所のブログで何段まで行けるか検証してないからわからない、とか書いてる人いますが、理屈は上記のとおりなので接続数に制限はない。
ワンライナーの文字数制限がコマンドプロンプトやらbashやらのシェルにあるなら、そっちの制限には書かるるかもね。

## バッチ化してみた

`portfoward_remotesv_443.bat`というファイルを用意して以下のコードを記述する。
このバッチファイルを実行するとファイル名に記載のサーバとポートに対してポートフォワーディングを張ってくれる

``` batch 
@echo off

echo %0
set FILENAME=%0

rem アンダーバー区切りでバッチファイル名を分割、接続先と接続先ポートを取得
FOR /F "tokens=2,3 delims=_." %%i in ('echo %0') do (
  set HOSTNAME=%%i
  set PORT=%%j
)

rem パラメタ出力
echo %HOSTNAME%
echo %PORT%
echo ssh.exe -t -l user -i private.key -L %PORT%:localhost:%PORT% targetsv "ssh -L %PORT%:%HOSTNAME%:%PORT% %HOSTNAME%"

ssh.exe -t -l user -i private.key -L %PORT%:localhost:%PORT% targetsv "ssh -L %PORT%:%HOSTNAME%:%PORT% %HOSTNAME%"

```

おわり。
Boostnoteでブロックコメントのシングルクォートが`&apos;`になって困った人向けの記事

## 背景

┗(^o^)┛BoostNoteを久しぶりに使ってみようかな。

（ ˘⊖˘）。o(待てよ、せっかくなら最新版のBoostNoteを使おう)

|最新版BoostNote| ┗(☋｀ )┓三

ブロックコメントのシングルクォートは`&apos;`に置き換えますね…( ◠‿◠ )☛ 

<img width="651" alt="スクリーンショット 2018-08-03 0.30.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/210923/0548baf4-6dc9-bc95-4747-a883a36e5a07.png">

▂▅▇█▓▒░(‘ω’)░▒▓█▇▅▂　うわあああああああああ


## 結論
 
- Boostnoteはセキュリティ的な理由で、サニタイズを行なっています
- サニタイズを無効にする方法
  - 日本語環境 : 設定 => インターフェース => サニタイズ => 安全でないHTMLタグの利用 を選択
  - 英語環境 : Preferences => Interface => Sanitization => Allow dangerous html tags を選択

<img width="1086" alt="スクリーンショット_2018-08-03_0_48_57-2.png" src="https://qiita-image-store.s3.amazonaws.com/0/210923/77cfc2ab-8483-b2fd-b373-9e2edebe0bac.png">

- 変更後 (想定通りの表示)  
  <img width="686" alt="スクリーンショット 2018-08-03 0.54.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/210923/7bf28bcd-7781-9ae6-e455-5d45873f0160.png">


## サニタイズする理由

BoostNoteの中ではElectronを用いて実装されており、
勿論、ファイルシステムやシェルにアクセスすることができます(XSSの危険性も含んでいる)

ゆえに、安直にサニタイズを止めるのは良くないのですが、
**絶対にLocalでしか使わない場合** などサニタイズしなくても良い場合もあります。

ただし、**Dropbox、OwnCloud、またはSkyDriveに置いて使用している場合**は
原則的にサニタイズを有効にして用いることをおすすめします。

### BoostNoteのサニタイズ関連のissue(一部)
- https://github.com/BoostIO/Boostnote/issues/1644
- https://github.com/BoostIO/Boostnote/issues/1672
- https://github.com/BoostIO/Boostnote/issues/2242

### BoostNoteのサニタイズ関連のPullRequest(一部)
- https://github.com/BoostIO/Boostnote/pull/1715
- https://github.com/BoostIO/Boostnote/pull/1634