OmniAICreator/Qiita-1.07M huggingface dataset:
Nuxt - Django 準備メモ

## この記事について

Nuxt と Django を Docker Compose で用意したときのメモ

## 開発環境

### 構成

- インフラ `Docker + Docker Compose`
- アーキテクチャ `Nuxt (フロント) + Django ( API ) + MySQL (データベース)`

### Nuxt の準備

1: `mkdir nuxt_django`
2: `cd nuxt_django`
3: `mkdir frontend`
4: `cd frontend`
5: `mkdir frontend`
6: `docker run --rm -it -v "$(pwd):/usr/src" node:8.11.1 bash`
7: `cd /usr/src/front`
8: `npm init`

- 入力はすべて空 ( Enter 連打 )

9: `npm install --save nuxt`

- インストール成功したら `Thanks for installing nuxt` が表示される
- 結構インストール失敗するので、失敗したら `rm -rf node_modules` を実行してから もう一度 `npm install --save nuxt`

10: **package.json** の **scripts** を以下に変更

```
"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "dev": "nuxt"
},
```

11: `mkdir pages`
12: **pages** ディレクトリに **index.vue** ファイルを作成し、以下の内容で保存

```
<template>
  <h1>Hello world!</h1>
</template>
```

13: `npm run dev`

- うまく行ったら `http://localhost:3000` が表示される

14: `control + C` キーで終了させて `exit` コマンドでコンテナを終了
15: `nuxt_django/fronted` ディレクトリに `Dockerfile` を作成し、以下の内容で保存

```
FROM node:8.11.1
RUN mkdir -p /usr/src/app
ENV HOME=/usr/src/app
WORKDIR $HOME
ADD . $HOME
WORKDIR $HOME/frontend
RUN npm install
```

### Django

1: `nuxt_django` ディレクトリ内で `mkdir backend`
2: `cd backend`
3: `docker run --rm -it -v "$(pwd):/usr/src" python:3.6 bash`
4: `cd /usr/src`
5: `pip install django djangorestframework djangorestframework-camel-case mysqlclient`
6: `pip freeze > requirements.txt`
7: `django-admin startproject backend`
8: `python backend/manage.py runserver`

- うまく行ったら `Starting development server at http://127.0.0.1:8000/` が表示される

9: `conrole + C` キーで終了させて `exit` コマンドでコンテナを終了
10: `nuxt_django/backend` ディレクトリに `Dockerfile` を作成し、以下の内容で保存

```
FROM python:3.6
ENV PYTHONUNBUFFERED 1
RUN mkdir -p /usr/src/app
ENV HOME=/usr/src/app
WORKDIR $HOME
ADD requirements.txt $HOME
RUN pip install -r requirements.txt
ADD . $HOME
```

### MySQL

1: `nuxt_django` ディレクトリ内で `mkdir db`
2: `db` ディレクトリ内で `custom.cnf` を作成し、以下の内容で保存

```
[mysqld]
character-set-server=utf8mb4
```

3: `db` ディレクトリ内で `Dockerfile` を作成し、以下の内容で保存

```
FROM mysql:5.7.19
ADD custom.cnf /etc/mysql/conf.d
```

### Docker Compose

1: `nuxt_django` ディレクトリに `docker-compose.yml` ファイルを作成し、以下の内容で保存

```
version: "3"
services:
  frontend:
    build: ./frontend
    volumes:
      - ./frontend:/usr/src/app
    environment:
      - HOST=0.0.0.0
    ports:
      - "3000:3000"
    command: npm run dev
  backend:
    build: ./backend
    volumes:
      - ./backend:/usr/src/app
    ports:
      - "8000:8000"
    command: python backend/manage.py runserver 0.0.0.0:8000
    links:
      - db:db
    tty: true
    stdin_open: true
  db:
    build: ./db
    volumes:
      - ./db/datadir:/var/lib/mysql
    expose:
      - "3306"
    environment:
      - MYSQL_ROOT_PASSWORD=dev_nuxt_django_pw
      - MYSQL_DATABASE=dev_nuxt_django_db
```

2: `docker-compose build`
3: `docker-compose up db`
4: `End of list of non-natively partitioned tables` の表示がされたら `control + C` キーで終了させる
5: `docker-compose up`
6: `http://localhost:3000` と `http://localhost:8000` が動いていたら OK
express & mongodb & mongooseの基本

#前提
 - MongoDB Serverがローカルで動作している前提
 - MongoDB ver 2
 - Mongoose ver 4.5.9
 

#MongoDB(ver2)インストール 
> npm install mongodb@2 --save

# MongoDB接続テスト

```javascript:connect_mongodb.js
const MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/Test', (err, db) => {
    if (err) {
        return console.log('Unable to connect to MongoDB server.');
    }
    console.log('Connected to MongoDB server');

    db.close()
});

```
>  node connect_mongodb.js

# mongoose インストール
> npm install mongoose@4.5.9 --save

# mongoose接続テスト
```javascript:db/mongoose.js
var mongoose = require("mongoose");

mongoose.Promise = global.Promise;
mongoose.connect(process.env.MONGODB_URI); //環境変数

module.exports = { mongoose };
```

```javascript:models/todo.js
var mongoose = require("mongoose");

var Todo = mongoose.model('Todo', {
    text: {
        type: String,
        required: true,
        minlength: 1,
        trim: true
    },
    completed: {
        type: Boolean,
        default: false
    },
    completedAt: {
        type: Number,
        default: null
    },
    _creator: {
        type: mongoose.Schema.Types.ObjectId,
        required: true
    }
});

module.exports = { Todo };
```


```javascript:mongoose-test.js
require('../config/config.js')
const { ObjectID } = require("mongodb")
const { mongoose } = require("../db/mongoose");
const { Todo } = require("../models/todo");

const userOneId = new ObjectID();

// careate todos[]
const todos = [{
    _id: new ObjectID(),
    text: 'First test tod',
    _creator: userOneId
}, {
    _id: new ObjectID(),
    text: 'Second test tod',
    completed: true,
    completedAt: 333,
    _creator: userOneId
}]
// remove all and Create todos[] and find
Todo.remove({}).then(() => {
    Todo.insertMany(todos).then(()=>{
        Todo.find({}).then((todos) => {
            console.log('Todos', todos);
        })
    })
});

```

> node .\mongoose-test.js

```console
Todos [ { _id: 5b614f87c3fbed2318feba17,
    text: 'First test tod',
    _creator: 5b614f87c3fbed2318feba16,
    completedAt: null,
    completed: false },
  { _id: 5b614f87c3fbed2318feba18,
    text: 'Second test tod',
    _creator: 5b614f87c3fbed2318feba16,
    completedAt: 333,
    completed: true } ]
```
【Laravel】静的メソッドと動的メソッドについて

#静的メソッド

`public static function`で定義されるメソッド。

self::メソッド名で呼び出す時に利用する。

#動的メソッド

`public function`で定義されるメソッド。

$変数->メソッド名で定義される。

#使い方

```sample.php
public static function foo()
{
    return 'hello';
}

public function bar()
{
    return 'world';
}
```

```SampleController.php
public function index()
{
    $sample = Sample::foo();

    $bar = new Sample;
    $sample = $bar->bar();
}
```
静的メソッドはクラスから呼び出す。
動的メソッドはインスタンスから呼びだす。
【Laravel】ルーティング時のパラメータ指定方法

#パラメータ指定方法

URLにIDが入る場合、`function (App\User $user)`で指定することができる。

```web.php
Route::get('profile/{user}', function (App\User $user) {
    //
});
```

#コントローラーに書く

一般的にはコントローラーに切り出します。

```UserController.php
public function edit(Request $request, User $user)
{
    //
}
```

これでidごとのuser編集画面に飛ぶことができます。

#user一覧ページは？

user一覧ページに`public function index(Request $request, User $user)`というミスをしました。
indexページは個別にidを取得することがないので、不要です。
indexメソッドでは個別の`$user`ではなく、`$users`を使うことが多いので、
`$users = User::all();`を記述すればOK

#storeは個別だよね？

store(Userの新規追加)は個別に追加するよね？という疑問。
`public function store(Request $request, User $user)`

これも単純な話なんだけど、これから新規追加する、つまり現時点ではuserはいないということなので、指定のしようがないということになる。

#判断基準は？

`User $user`をいつ使うべきかという判断基準は、urlに{user}があるかどうか。でいいと思う。
indexやstoreにパラメータはないし、editにはあるはず。

Railsだとurlにパラメータをつけずに`current_user`でログインしているuserを取得できたので、ちょっとごちゃまぜになっていた。

Laravelの場合、そういうルーティングはしないはず？なのでこの基準で問題ないはず。
クラスメソッドをやっと理解した

#クラスメソッドとは？

クラスから直接呼び出すことのできるメソッドです。
クラスメソッドとインスタンスメソッドがあり、インスタンスメソッドはインスタンス（クラスを実現化したもの）を作成する必要があります。

#ちょっとインスタンスについて

インスタンス＝クラスを実現化したものって正直わかりにくいですよね。
なので、ここでインスタンスについて整理しておきます。
クラスをnewしたものらしいです。

参考：https://wa3.i-3-i.info/word1118.html

`$user = new User;`
と書いておけばUserクラスが実現化するってことですね。
ちなみにこの`$user`にはnameとかの情報が何も入っていません。
ここにインスタンスメソッドを使ったりして、情報を追加したり削除したり、保存してあげるわけです。


#では、クラスメソッドの書き方について

```Post.php
public static function getPostAttribute()
    {
        $post = self::orderBy('id', 'desc')->first();
        return $post->title;
    }
```

```PostController.php
public function index()
    {
        return view(
            'post' => Post::getPostAttribute();
        );
    }
```

これでPostクラスの一番初めのidのタイトルを取得できます。

#インスタンスメソッドにすると

```Post.php
public function getPostAttribute()
    {
        $post = $this:->orderBy('id', 'desc')->first();
        return $post->title;
    }
```

```PostController.php
public function index()
    {
        $post = new Post;
        return view(
            'post' = $post->getPostAttribute();
        );
    }
```

#両者の違い

メソッドについては書き方が違うだけで、それほど行数も変わらないし、どちらでも良さそうな感じです。
呼び出しの部分が大きく違うところです。
クラスメソッドは直接クラスから呼び出すので、`Post::get~`で呼び出せちゃいます。

対して、インスタンスメソッドは一度インスタンスを作成する必要があるので、
`$post = new Post;`という一文が多くなります。

じゃあクラスメソッドの方が記述量が減るしインスタンスメソッドなんて要らないじゃないかと思うかもしれません。

#インスタンスメソッドのメリット

インスタンスメソッドの方が柔軟です。
例えば、
`$post = new Post;`を`$post = self::orderBy('id', 'desc')`とします。
そうすると、メソッドの方は
`$post = $this->first();`になります。

orderByがコントローラーに移っただけ？
そうです。
これは他のアクションで利用する時のことを考えています。
indexアクションではdescでよかったかもしれませんが、他のページではascにしたい場合。
メソッドではなく、コントローラーで指定することでそれぞれ分けることができます。

あくまで一例ですが、クラスメソッドは全てのアクションで同じ動作をさせる場合に使う。
インスタンスメソッドはそれぞれのアクションで1部分だけを使いたい場合に使う。
といったイメージで使い分けると良いかと。
【Laravel】ソフトデリートしたモデルの取得

参考：https://readouble.com/laravel/5.3/ja/eloquent.html

#普通の削除方法

```Flight.php
$flight = App\Flight::find(1);

$flight->delete();
```

ここは問題ないですね。
id=1を削除したい時はfindでモデルを検索して、`delete()`で削除

#ソフトデリートとは

ソフトデリートは実際にDBからレコードを削除せずに、削除したように見せかける技です。
deleted_atカラムに日時を追加することで、検索できないようになります。
通常はnullにすることで表示対象になります。

#ソフトデリート方法

```Flight.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Flight extends Model
{
    use SoftDeletes;

    /**
     * 日付へキャストする属性
     *
     * @var array
     */
    protected $dates = ['deleted_at'];
}
```

参考からのコピペですが、これは必ず必要みたいです。


```create_table.~
Schema::table('flights', function ($table) {
    $table->softDeletes();
});
```

デリートカラムを追加します。

あとは通常のデリートと同じく`delete()`で削除するとソフトデリートできるらしい。
簡単！

#ソフトデリート済みモデルを取得したい

削除はしたけど過去の情報は残しておきたい。そんな時も大丈夫。

```
$flights = App\Flight::withTrashed()
                ->where('account_id', 1)
                ->get();
```

これでアカウントID=1の人の過去のフライト情報を取得することができるんですね。

`$flight->history()->withTrashed()->get();`

リレーションしていても使える

デリートされたモデルのみ取得

```
$flights = App\Flight::onlyTrashed()
                ->where('airline_id', 1)
                ->get();
```

#ソフトデリートの復活

ソフトデリートにする目的として復活させたいというのがあります。
削除したアカウントの情報を保持しておけば、再登録した時に途中から始めることができます。

`$flight->restore();`

これだけみたいです。

今回使いたかった機能はこれだけなのでこれ以上は書きませんが、参考URLにはもっと詳しく書いてあります。
【Laravel】リレーションしている数の検索

#状況

リレーション件数を検索にかけたい。
どういうことかというと、
`User->post()->count`があったとして、
ユーザごとに何件投稿したかが表示されるようになっている。
その件数を検索したい。

#問題

検索の時は`where`を使うもんだと思っていたのだが、
カラム検索ではないので使えないらしい。
`where('カラム', '検索ワード');`

countをカラムにしてしまおうと思った。
`selectRaw('count(*) as cnt')`とするとcntをカラムとして使えるっぽいので、

```
selectRaw('count(*) as cnt')
    ->where('cnt', '$request->xxx');
```

これをリレーション先で指定するから

```
whereHas('posts', function($query) use($q){
    $query->selectRaw('count(*) as cnt')
          ->where('cnt', '$request->xxx')
          ->groupBy('cnt');
});
```

これでもダメみたい。。
全てのPostの件数を取得するので、
User1->post = 3
User1->post = 10
User1->post = 30
とかだと、countで43になっちゃうのではないか。

あまり使ったことのないSQLの知識を使いながら奮闘しましたけど、できませんでした。

#hasメソッド？
hasメソッドを使えば簡単らしい。
`$query->has('posts', 'リクエスト');`
これだけです。

$queryごとにPostの件数を取得してリクエストと照らし合わせてくれる。
簡単すぎた。
Xfce タッチバッドのスクロール方向の設定

Xubuntu 18.04でのお話。
GUIのマウスの設定で変更できるかと思いきや、一部(GTK2+？)アプリケーションでのみ反映される。めっちゃ使いづらいの・・・

#Synclientを使う
現在の値の確認

```bash
synclient | grep ScrollDelta

#右辺が現在値
VertScrollDelta         = 119
HorizScrollDelta        = 119
```
垂直・水平方向の設定を変えたければ以下の通り値を反転させる。

```bash
synclient VertScrollDelta=-119 && synclient HorizScrollDelta=-119
```

パームリジェクションなど、他にもオプションがあるので調べてみよう。

[Arich wiki-Synaptics タッチパッド](https://wiki.archlinux.jp/index.php/Synaptics_%E3%82%BF%E3%83%83%E3%83%81%E3%83%91%E3%83%83%E3%83%89)
エクスプローラ上で新規フォルダを作成するショートカットキー

備忘録として残します。

ウィンドウズのエクスプローラ上でフォルダを作るとき、右クリック新規作成が面倒。
実はそれ、ショートカットキーあります。
不覚ながら私も最近知りました。

`Ctrl ＋ Shift + N`

上記のコマンドでフォルダを作成。

コピペとかと違い3つのキーがショートカットキーとなっているが、無いよりましです。

コピペと同じくらい必須のショートカットキーだと思うので、エンジニアでなくても、事務職でパソコンがっつりのOLの方でも重宝すると思います。

他にも”パソコンを使う人であればコピペばりに超必須だというショートカットキー”をご存知の方は共有していただければ幸いです。
Remote Desktop for Macでバックスラッシュを入力する

## 問題点

2018/8/1時点、Microsoft Remote Desktop(Version 10.2.0)でバックスラッシュにあたる`0x5C`を入力することができず、代わりにUnicodeの`0xC2A5`が入力されてしまいます。これをどうにかしたい。

Mac上だと`option + ¥`で入力できたり、Google日本語入力の設定で変えたりできるので特に困っていません。

## 回避策

Mac側でKaribinerを使って回避する手段が公開されています。

- [MacからWindowsへリモートデスクトップ接続したとき、バックスラッシュを使えるようにする](https://qiita.com/KNaito/items/174404ea42470d00c063)

手軽にwindows側でなんとかできないかな、と¥キーを押されたらバックスラッシュが押されたことにするプログラムを作りました。

- [stkchp/noyen - GitHub](https://github.com/stkchp/noyen)

接続先のWindows PC側で起動すれば、起動中は`0xC2A5`ではなく`0x5C`が入力されるようになります。


## 所感

そんなに頻繁に接続しない、Mac側にアプリを入れるまでのことじゃないという際に使えるかなと。

前接続を試した際は日本語キーボードで入力できず、記号の入力時に死んでいたんですが、いつの間にかJISキーボードで認識されるようになっています。長い間放置されていたフィードバックがおそらく届いたのでしょう。この問題もフィードバックしておけばいつの日にか修正されるかもしれません。

- [Remote Desktop for Mac - UserVoice](https://remotedesktop.uservoice.com/forums/287834-remote-desktop-for-mac)


また、UWPアプリでキーレイアウトが異なる問題はmicrosoftから回避策が提示されています。今後のupdateで解消されることを期待します。

- [Windows 10 RS4 へのリモート デスクトップ接続時に、UWP アプリへの入力時のみキーボード配列が異なる事象について](https://blogs.technet.microsoft.com/askcorejp/2018/06/08/rs4-rdp-keyboardlayout/)
transposeで入れ替え

Pythonの組み込み関数の１つであるtranspose
引数にaxisを指定することで，入れかえが可能です．

```py
In:
test = np.array([[1,2],[3,4]])
test.transpose(1,0)

Out:
array([[1, 3],
       [2, 4]])
```

transpose()を使う意味がなくなりますが，`test.transpose(0,1)`は`test`と等しくなります．

```py
In:
test = np.array([[1,2],[3,4]])
test.transpose(0,1)

Out: 
array([[1, 2],
       [3, 4]])
```
JTF2018の資料まとめ

#JTF2018の私的資料リンク集

https://docs.google.com/spreadsheets/d/1DybeTW4B2baPvl1xOiLgLYqDlVoW0-Jfa3hJ-CW6A9A/edit?usp=sharing

・更新して頂いても大丈夫です
・既に良いまとめ資料があれば教えていただけると嬉しいです
・こういうこと（共同編集・公開）をするときの良いツールはないですかね・・・？
Ubuntuを入れなおした私が、人権を取り戻すまで

結構雑ですが、自分がパソコンに求める最低限の設定をまとめてみました.
自分向けの備忘録なので、なにかミスってるかもしれません.

---
> イカしたエディタがはいること.  
capslockがctrlになること.  
これらによって、その箱は初めてパソコンとなる.  

---
## 最低限の人権
```
$ LANG=C xdg-user-dirs-gtk-update
$ sudo apt-get install vim
$ sudo apt-get install git
$ gsettings set org.gnome.desktop.input-sources xkb-options "['ctrl:nocaps']"
$ sudo apt-get install tmux
$ git config --global alias.graph 'log --graph --oneline --decorate=full -20 --date=short --format="%C(yellow)%h%C(reset) %C(magenta)[%ad]%C(reset)%C(auto)%d%C(reset) %s %C(cyan)@%an%C(reset)"'
```
---
## .bashrcに人権を付与する
```
# neovimへの移行
#alias vi=nvim
#alias vim=nvim

# kill caps
setxkbmap -option ctrl:nocaps

# my neovim setting
alias vimfile='cd ~/.config/nvim'

# for tmux
alias tmux="TERM=screen-256color-bce tmux"
#alias tmux="TERM=xterm-color256 tmux"
alias tmux="tmux -2"
#export TERM=xterm-color256

# ros
source ~/catkin_ws/devel/setup.bash
source /opt/ros/kinetic/setup.bash

alias cm="cd ~/catkin_ws && catkin_make"
```
あと、
```
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
```
のとこの`\W`を`\w`に書き直します  

---
## エディタに人権を付与する
さいつよエディタであるneovimをいれる.
手前味噌だけども、[筆者の設定](`https://github.com/OkanoShogo0903/vim-setting`)パクってneovim環境つくるのオススメ.
WinFormsのINotifyPropertyChangedを使ってみる

初投稿してみた　ありふれた情報です

BindingSourceを使用してnumericUpDownコントロールのValueにViewModelクラスをバインド、
ValueChangedイベントのタイミングで入力値を使用して、描画内容更新を実装したかったのですが、
ValueChangedイベントハンドラ内でViewModel参照しても値が更新されてねぇ！ってなったので、
値が変更されたら教えて～と思ってINotifyPropertyChanged使いました。（ながい

# INotifyPropertyChanged

VM側からUIに変更通知を行いたいときにこのインターフェースを使用する。

https://msdn.microsoft.com/ja-jp/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx

# 使い方

INotifyProperChangedを継承したViewModelクラスを作成する。
PropertyChangedイベントを忘れずに実装する。

```cs:PersonViewModel.cs
	public class PersonViewModel : INotifyPropertyChanged
	{
		private Person _person;

		public event PropertyChangedEventHandler PropertyChanged

		public string Name
		{
			get { return _person.Name; }
			set { _person.Name = value; }
		}

		public int Age
		{
			get { return _person.Age; }
			set { _person.Age = value; }
		}
	}
```

UI側のBindingSourceにVMを設定する。
適当にPropertyChangedイベントにハンドラを設定する。

```cs:MainForm.cs
	public partial class MainForm : Form
	{
		private MainViewModel _vm;

		public MainForm()
		{
			InitializeComponent();
			
			_vm = new PersonViewModel();

			bindingSource.DataSource = _vm;

			_vm.PropertyChanged += VmOnPropertyChanged;
		}
    }
```

これだけだとVMが変更されてもイベントは上がってきません。
VM側で値が変更されたときにイベントを上げてあげる必要があるのです。
（めんどくさい）

イベント上げてくれるようにPersonViewModelを変更する。
※_person null かもよ！って言われたのでさり気なくコンストラクタで初期化してます。

```cs:PersonViewModel.cs
	public class PersonViewModel : INotifyPropertyChanged
	{
		private Person _person;

		public event PropertyChangedEventHandler PropertyChanged;

		public PersonViewModel( Person person )
		{
			_person = person;
		}

		public string Name
		{
			get { return _person.Name; }
			set
			{
				if( _person.Name == value )
					return;

				_person.Name = value;
				NotifyPropertyChanged();
			}
		}

		public int Age
		{
			get { return _person.Age; }
			set
			{
				if( _person.Age == value )
					return;

				_person.Age = value;
				NotifyPropertyChanged();
			}
		}

		private void NotifyPropertyChanged( [CallerMemberName] string propertyName = "" )
		{
			PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( propertyName ) );
		}
	}
```

参考
https://blog.okazuki.jp/entry/2015/05/09/124333
https://qiita.com/ledsun/items/6f4ef754e5ae2507e531
I2C > C > CRC-8-CCITT計算 > どの部分に対するCRCを計算するのか

```txt:動作環境
とある32bit組込み環境
とあるセンサー(I2C通信)
```

### 問題

- [C > CRC-8-CCITTを計算 > I2C通信用のCRC](https://qiita.com/7of9/items/267c85c889a7add31f7e)

において、I2C通信のCRC計算は実装した。

一方で、そのCRC計算にはどの範囲の通信内容を渡せばいいのか?

### 確認した事項

以下の通信がある。

- Start
- Write Header: 0xC2
- Cmd MSB: 0x45
- Cmd LSB: 0x00
- XXX MSB: 0x00 (XXXは任意の設定項目名)
- XXX LSB: 0x02
- CRC: 0xE3
- Stop

上記に関して、XXXのMSBとLSBに対するCRC計算の結果が0xE3となった。

他のコマンドに関してもCRCの直前の2つ(MSBとLSB)に対するCRC値計算で整合するようだ。
C > CRC-8-CCITTを計算 > I2C通信用のCRC

```txt:動作環境
ideone C (gcc 6.3)
```

### 概要

I2C通信のCRC(CRC-8-CCITT)を計算する。

- Name: CRC-8
- Protected Data: read data
- Width: 8bits
- Polynomial 0x31 ($x^8 + x^5 + x^4 + 1$)
- Initialization: 0xFF
- Reflect Input: false
- Reflect Output: false
- Final XOR: 0x00
- Example: CRC(0xBEEF) = 0x92

### 参考

- [CRC8の計算](https://blog.goo.ne.jp/masaki_goo_2006/e/69f286d90e6140e6e8c021e43a11c815) @ プログラミングのメモ帳

情報感謝です。

### 実装 > ideone

上記の実装をI2C通信用のCRC-8-CCITTに変更したのが以下。

https://ideone.com/9FStVk

```c
#include <stdio.h>
#include <stdint.h>
#include <limits.h> // CHAR_BIT 
 
#define MSB_CRCS (0x31) // x8 + x5 + x4 + 1
 
static uint8_t calcCRC8CCITT(char *buff, size_t size)
{
    uint8_t crc8;
 
    for(crc8 = 0xFF; size != 0; size--) {
        crc8 ^= *buff++;
 
        for(int idx=0; idx < CHAR_BIT; idx++) {
            if (crc8 & 0x80) {
                crc8 <<=1;
                crc8 ^= MSB_CRCS;
            } else {
                crc8 <<=1;
            }
        }
    }
    return crc8;
}
 
int main(void) {
    uint8_t data[] = { 0xBE, 0xEF };
    uint8_t crc;
 
    crc = calcCRC8CCITT(data, 2);
    printf("0x%x\n", crc);
 
    return 0;
}
 
```

```txt:run
0x92
```

冒頭のExampleの通りになった。


### 関連

- [CRC（巡回冗長検査）で適正なデータ通信を実現](http://www.analog.com/jp/analog-dialogue/articles/cyclic-redundancy-and-correct-data-communications.html) @ Analog Dialogue

### 実装 > 組込み用Cファイル

実装中のソフトで使えるようにcファイル実装した。

単体動作時にはDEBUG_RUN マクロをアンコメントする。

```crc8ccitt_180801.c
#include <stdio.h>
#include <stdint.h>
#include <limits.h> // CHAR_BIT 
#include <stdbool.h>

#define MSB_CRCS (0x31) // x8 + x5 + x4 + 1

//#define DEBUG_RUN // use main() for debug

/*
 * v0.1 Aug. 01, 2018
 *   - add [DEBUG_RUN] macro
 *   - add main()
 *   - add Test_calcCRC8CCITT()
 *   - add calcCRC8CCITT()
 */

// Acknowledgement: 
// https://blog.goo.ne.jp/masaki_goo_2006/e/69f286d90e6140e6e8c021e43a11c815

/*
- Name: CRC-8
- Protected Data: read data
- Width: 8bits
- Polynomial 0x31 ($x^8 + x^5 + x^4 + 1$)
- Initialization: 0xFF
- Reflect Input: false
- Reflect Output: false
- Final XOR: 0x00
- Example: CRC(0xBEEF) = 0x92
 */

uint8_t calcCRC8CCITT(char *buff, size_t size)
{
    uint8_t crc8;
    int idx;

    for(crc8 = 0xFF; size != 0; size--) {
        crc8 ^= *buff++;

        for(idx=0; idx < CHAR_BIT; idx++) {
            if (crc8 & 0x80) {
                crc8 <<=1;
                crc8 ^= MSB_CRCS;
            } else {
                crc8 <<=1;
            }
        }
    }
    return crc8;
}

static bool Test_calcCRC8CCITT(void)
{
    uint8_t data[] = { 0xBE, 0xEF };
    uint8_t crc;

    crc = calcCRC8CCITT(data, 2);
    printf("0x%x\n", crc);	

    return (crc == 0x92);
}

#ifdef DEBUG_RUN
int main(void) 
{
	if (Test_calcCRC8CCITT()) {
		printf("Test: pass\n");
	} else {
		printf("Test: fail\n");
	}
    return 0;
}
#endif
```

```crc8ccitt_180801.h
#ifndef CRC8_CCITT_H
#define CRC8_CCITT_H

uint8_t calcCRC8CCITT(char *buff, size_t size);

#endif
```

stdint.hを使わない環境を考慮した方がいいかもしれない。
【Vue.js】Vue CLI 3.0でハッシュ名を付けずにproductionビルドする

Vue CLI 3.0になってVue.jsもより開発しやすくなりましたね。
UIでビルドも楽になって手放せないのですが、
困ったのが production で生成されるチャンクハッシュ名付きファイル名です。
キャッシュされないようにつけるらしいですが、
複数のhtmlから起動させたい場合等、開発条件によっては困るし、
ソース中で、動的にパス名を参照するところはrequire()を付ける必要あるので
デバッグにいらぬ時間を浪費します。

そこで、vue.config.js にハッシュ名を付けないように設定しました。
使う際には、UIのOutput Directoryは空にしておいて下さい。

```vue.config.js
const MiniCssExtractPlugin=require('mini-css-extract-plugin')

module.exports = {
  baseUrl: '',
  lintOnSave : true,
  productionSourceMap: process.env.NODE_ENV === 'production'? false :true,
  outputDir:process.env.NODE_ENV === 'production'? 'release' :'debug',
  pages:{
    index:{
      entry: './src/main.js',      //メインとなるJSファイル
      template: 'public/index.html',     //ソースとなるhtmlファイル名
      filename: 'app.html'      //出力するhtmlファイル名

    }
  },
  chainWebpack: config => {
      
    if (process.env.NODE_ENV === 'production'){

      //チャンクファイルを生成しないようにする
      config.optimization.delete('splitChunks')

      //メインJSファイル名にハッシュ値をつけない
      config.output
        .filename('[name].js')
       

      //imagesに置く画像ファイル名にハッシュ値をつけない
      config.module
        .rule('images')
        .test(/\.(png|jpe?g|gif|webp)(\?.*)?$/)
        .use('url-loader')
        .loader('url-loader')
        .options({
          limit: 4096,
          name: 'img/[name].[ext]'
        })

      //svgのファイル名にハッシュ値をつけない
      config.module
        .rule('svg')
        .test(/\.(svg)(\?.*)?$/)
        .use('file-loader')
        .loader('file-loader')
        .options({
          name: 'img/[name].[ext]'
        })

      //mediaに置くメディアファイル名にハッシュ値をつけない
      config.module
        .rule('media')
        .test(/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/)
        .use('url-loader')
        .loader('url-loader')
        .options({
          limit: 4096,
          name: 'media/[name].[ext]'
        })

      //fontsに置くフォントファイル名にハッシュ値をつけない
      config.module
        .rule('fonts')
        .test(/\.(woff2?|eot|ttf|otf)(\?.*)?$/)
        .use('url-loader')
        .loader('url-loader')
        .options({
          limit: 4096,
          name: 'fonts/[name].[ext]'
        })
            

            
      //CSSファイル名にハッシュ値をつけない
    config.plugin('extract-css')
        .use(MiniCssExtractPlugin, [{
          filename:'[name].css',
          chunkFilename:''
        }])

     //起動用htmlのminify設定を指定する
    config.plugin('html-index')
        .tap(args => {
          args[0].minify= {
            removeComments: false,
            collapseWhitespace: false,
            removeAttributeQuotes: false,
            collapseBooleanAttributes: false,
            removeScriptTypeAttributes: false
          };
          return args
        })



    }
  },
  configureWebpack:config => {
  }

}
```


そのうち、UIのオプションでチェックひとつでON/OFFできるようになるといいですね。
MPIプログラムからMPIプログラムをstd::systemで呼び出すと問題を起こす

# はじめに

これは[MPI Advent Calendar 2017](https://adventar.org/calendars/2548)の7日目の記事です。「[この辺でもう遠慮しようと思います](https://qiita.com/kaityo256/items/59a12abc48883bfefd62)」とか書いた気がしますがあれは嘘です。

並列コードを書くまでもない自明並列、いわゆる「バカパラ」をしたいときが結構あります。例えば大量のデータを処理したい、多数のフレームのレンダリングをしたい、などです。こんな要望に例えば「バルクジョブ」という形でシステム側で対応してくれているサイトもありますが、単純並列の場合は、MPIのラッパーを書いて、実行したいプログラムを`std::system`で呼び出す、ということをよくやります。

しかし、この子プロセスとして呼び出されるコードが、普通のシリアルプログラムではなく、MPIがリンクされた並列コードだと問題を起こすため、それについて紹介します。サンプルコードは

https://github.com/kaityo256/mpisystem

に置いておきます。

# サンプルコード

まず、親プロセス側(呼び出し側)としてこんなコードを書きます。

```a.cpp
#include <cstdio>
#include <cstdlib>
#include <mpi.h>

int main(int argc, char **argv) {
  MPI_Init(&argc, &argv);
  std::system("./b.out");
  MPI_Finalize();
}
```

単に`std::system`で`b.out`を実行するだけのコードです。

子プロセス側(呼び出され側)としてこんなコードを書いてみます。

```b.cpp
#include <cstdio>
#include <mpi.h>

int main(int argc, char **argv) {
  MPI_Init(&argc, &argv);
  printf("Hello World\n");
  MPI_Finalize();
}
```

何もせず、"Hello World"と表示するだけのコードです。ただし`MPI_Init`と`MPI_Finalize`は呼び出します。

さて、これをコンパイル、実行します。以下はMac上のOpen MPIの場合です。

```shell
$ mpicxx a.cpp -o a.out 
$ mpicxx b.cpp -o b.out
$ mpiexec -np 2 ./a.out
Hello World
Hello World # ← ここでプログラム実行が止まり、正常終了しない
```

一応コードは実行できますが、最後で止まってしまいます。ここでCtrl+Cを押すとSIGSEGVを吐いて異常終了します。

別サイトでIntel MPIで実行してみると、やはり実行はできますが最後に

```
===================================================================================
=   BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
=   PID XXXX RUNNING AT hostname
=   EXIT CODE: 13
=   CLEANING UP REMAINING PROCESSES
=   YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
===================================================================================
```

みたいなエラーを吐いて死にます。

# まとめ

MPIプログラムからstd::systemを使って子プロセスを大量に実行する、というのはよくやっていたのですが、子プロセスとしてMPIプログラムを実行すると異常終了する、というのは知らなかったのでシェアしてみました。よく考えると、MPIを多段実行していることになり、MPI_Finalizeがおかしくなるのはわかる気がしますが、実際そう言われるまでは気が付きませんでした。
ClangSharpPInvokeGeneratorを使ってみた

# ClangSharpPInvokeGeneratorって?

Microsoftの.Net用Clangバインディング[Microsoft/ClangSharp](https://github.com/Microsoft/ClangSharp)の
サンプル 兼 libclang.dllのP/Invokeのコードの自動生成用のプログラムです。

ClangSharpPInvokeGeneratorはlibclang.dllだけでなく、
一般のネイティブDLL呼び出しのためのP/Invokeのコードの生成もできそうなのですが、
ググっても日本語の情報が出てこなかったので試しに使ってみました。

# 準備

## LLVMのセットアップ

[LLVM Download Page](http://releases.llvm.org/download.html)から
`Pre-Built Binaries: Clang for Windows (64-bit)`を
ダウンロード & 展開 & パスを通す

## .Net Coreのセットアップ

※ 現時点での最新版は2.1
[.NET Core 2.1 downloads](https://www.microsoft.com/net/download/dotnet-core/2.1)から
`.NET Core Binaries: x64`を
ダウンロード & 展開 & パスを通す

## ClangSharpPInvokeGeneratorのビルド

```
git clone https://github.com/Microsoft/ClangSharp
cd ClangSharp/ClangSharpPInvokeGenerator
donet publish -c Release -r win-x64
```

# 実行

##ネイティブDLLサンプル
```c++:hello.h
#ifndef __HELLO__
#define __HELLO__

#ifdef DLL_EXPORT
#define DECLSPEC __declspec(dllexport)
#else
#define DECLSPEC __declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C" {
#endif
  DECLSPEC void CallMe(char* name, char* resp);
#ifdef __cplusplus
}
#endif

#endif
```

```c++:hello.cpp
#define DLL_EXPORT
#include "hello.h"

#include <stdio.h>

void CallMe(char* name, char* resp) {
    snprintf(resp, 260, "Hello %s!", name);
    return;
}
```

## ラッパーの生成

```shell
ClangSharpPInvokeGenerator --n Native --m Hello --o Generated.cs --l hello.dll --f hello.h
```

### 生成物

```cs:Generated.cs
namespace Native
{
    using System;
    using System.Runtime.InteropServices;

    public static partial class Hello
    {
        private const string libraryPath = "hello.dll";

        [DllImport(libraryPath, EntryPoint = "CallMe", CallingConvention = CallingConvention.Cdecl)]
        public static extern void CallMe(IntPtr @name, IntPtr @resp);

    }
}
```

### 呼び出しサンプル

```cs:Program.cs
using System;
using System.Runtime.InteropServices;
using Native;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var name = "World";
            var namePtr = Marshal.StringToHGlobalAnsi(name);

            string resp = "";
            var respPtr = Marshal.StringToHGlobalAnsi(resp);

            // 呼び出し
            Hello.CallMe(namePtr, respPtr);

            resp = Marshal.PtrToStringAnsi(respPtr);

            Console.WriteLine(resp);
            Console.Read();

            Marshal.FreeHGlobal(namePtr);
            Marshal.FreeHGlobal(respPtr);
        }
    }
}
```

とりあえず、文字列の受け渡しができることは確認できました。
構造体の受け渡し等は試してませんが、libclang.dllで使ってるくらいなので大丈夫でしょう、きっと。
Office365 Flow -> Yammerに投稿する

# はじめに
[Amazon Dash Button + Raspberry Pi + Office365で社員が幸せになれる](https://qiita.com/tsumasakky/items/1d84999c1369fabd0234)で
AmazonDashButton -> Dasher -> Office365 Flow -> Yammerに投稿
ということをしたく、Flowのセットアップ手順メモ

# Flowの作成

1. 「一から作成」を選択します。
![img1.png](https://qiita-image-store.s3.amazonaws.com/0/147118/e4d533fe-d826-6690-4399-720356b04d04.png)
2. 検索欄で"http"を入力し、「要求 - HTTP要求の受信時」を選択します。
![img2.png](https://qiita-image-store.s3.amazonaws.com/0/147118/d580eae6-c104-b866-87e7-5f17e4e104b3.png)
3. 「詳細オプションを表示」し、「method」で「GET」を選択します。
その後、「新しいステップ」を選択します。
![img4.png](https://qiita-image-store.s3.amazonaws.com/0/147118/96ddaf1a-5d23-1ed7-50b5-7105234df340.png)
4. 検索欄で"yammer"を入力し、「Yammer - 投稿メッセージ」を選択します。
![img5.png](https://qiita-image-store.s3.amazonaws.com/0/147118/5ba128f9-8376-d4fe-a431-69d977a455be.png)
5. 「グループID」、「メッセージテキスト」、「ネットワークID」を入力し、「保存」します。
![img6.png](https://qiita-image-store.s3.amazonaws.com/0/147118/00a506b4-f6b4-3844-5c27-adfca5e21ecc.png)
6. 保存を行うと要求先URLが表示されます。これを控えておき、Dasherのフック先URLに指定します。
![img7.png](https://qiita-image-store.s3.amazonaws.com/0/147118/4080382a-77cc-4032-8693-0774b64e8ce0.png)

# 感想
めちゃくちゃ簡単です。
Officeのリソースを使用するとなると3分クッキングなので、ちょっとした社内ツールの作成にはうってつけですね！
(備忘録)[Python + tkinter] tk.PhotoImage でエラーが出る

備忘録。
下記ソースのtk.PhotoImageで画像を読み込む際、
image "pyimage2" doesn't exist
というエラーが出た。
読み込む画像の枚数によっては"pyimage3"とかになるみたい。

```wrong.py
import tkinter as tk
import tkinter.ttk as ttk
from tkinter import PhotoImage

root = tk.Tk()
root.title(u"TITLE")

img = "img.png"
img1 = tk.PhotoImage(file=img)        #ここ
label1 = ttk.Label(root,image=img1)
label1.grid(row=0,column=0)

root.mainloop()
```
調べた結果、tk.PhotoImageの引数としてmasterを指定する必要があって、その画像を表示するwidgetが格納される、rootなりframeなりを master=root のように明示すると解決した。

NG： img1 = tk.PhotoImage(file=img)
OK： img1 = tk.PhotoImage(file=img,master=root)

```collect.py
import tkinter as tk
import tkinter.ttk as ttk
from tkinter import PhotoImage

root = tk.Tk()
root.title(u"TITLE")

img = "img.png"
img1 = tk.PhotoImage(file=img,master=root) #ここ
label1 = ttk.Label(root,image=img1)
label1.grid(row=0,column=0)

root.mainloop()
```
CRC-16 (Modbus) > Modbus の16ビットCRCを計算 @ On-line CRC calculation and free library

```txt:動作環境
Windows 10 Pro (64bit) バージョン 1803 (April 2018 Update)
Google Chrome バージョン: 67.0.3396.99（Official Build） （64 ビット）
```

### 概要

とあるセンサーのInterface Descriptionに記載のModbusのCRC(16ビット)をオンラインツールで計算してみる。

### 手順

- [CRC-16 > 色々あるようだ | On-line CRC calculation and free library](https://qiita.com/7of9/items/79db45461513029f4ac1)

にて紹介した[ 
On-line CRC calculation and free library](https://www.lammertbies.nl/comm/info/crc-calculation.html)
を使う。

某Interface Descriptionには下記の記載がある。
| 0x61 | 0x06 | 0x00 | 0x38 | 0x03 | 0xE8 |
これに対してCRCのLSBとMSBは以下とある。
| 0x01 | 0x19 |

以下のようにする。

1. Input typeをHexにする
2. Calculate CRCの左側のテキストボックスに以下を入力
3. Calculate CRCボタンを押す

上の表の「CRC-16 (Modbus)」に0x1901と出て、Interface Descriptionの記載と整合する。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/69f4d2fd-3bc5-3c6f-def4-401ace7ecd00.png)
[Python] iniファイルに変数を埋め込む方法

## 概要
以下の2つを、SafeConfigParserを使って実現します。

1. [iniファイルに変数を埋め込む方法](#iniファイルに変数を埋め込む方法)
1. [iniファイルを動的に生成する](#iniファイルを動的に生成する)

## iniファイルに変数を埋め込む方法
### iniファイルを作成
以下のいずれかの書式で作成。
`%(変数名)`の形式で変数を実装する。

```lang:sample.ini
[general]
name: my_name
base_dir: /home/myhome/exp

exe_dir: %(base_dir)s/bin
```

```ini:sample.ini
[general]
name=my_name
base_dir=/home/myhome/exp

exe_dir=%(base_dir)s/bin
```

### コードを作成

```py:sample.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import configparser

config = configparser.SafeConfigParser()
config.read('sample.ini')
value = config.get('general', 'exe_dir')

print(value)
```

### 実行

```shell-session
$ python sample.py
/home/myhome/exp/bin
```

## iniファイルを動的に生成する
以下の方法でiniファイルを動的に生成することで、環境変数やその他の処理を自由に行うことができる。
ここでは、環境変数`ENV`に値を設定して、それを用いてiniファイルを生成してみる。

### 環境変数のセット

```shell-session
$ export ENV=development
```

### iniファイルを生成するスクリプトの作成

```py:generate.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import ConfigParser
import os

config = ConfigParser.RawConfigParser()

section1 = 'general'
config.add_section(section1)
config.set(section1, 'env', os.environ.get('ENV'))
config.set(section1, 'name', 'myname')
config.set(section1, 'base_dir', '/home/myhome/exp')
config.set(section1, 'exe_dir', '%(base_dir)s/bin')
config.set(section1, 'hostname', '%(env).hostname')

with open('sample.ini', 'wb') as configfile:
    config.write(configfile)
```

このコードを実行すると、以下のiniファイルが生成される。
環境変数によって、`env`の値を変えることができる。

```ini:sample.ini
[general]
env = development
name = myname
base_dir = /home/myhome/exp
exe_dir = %(base_dir)s/bin
hostname = %(env).hostname
```

## 参考
- https://stackoverflow.com/questions/4999190/how-to-use-variables-already-defined-in-configparser
- https://docs.python.org/ja/2.7/library/configparser.html#examples
[180801]Gitlab の Merge Request から学ぶ

# [Fix bug with Wiki pages encoding](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/20906/diffs)
MR とは直接関係ないけど、こういう block をとる `before_action` はあまり見ない。
このくらいなら method にするまでもないって感じかな。

アクションごとに設定するものとか権限が違ってくると `before_action` がこんな感じになっていくのよく見る。
好みが出てくるポイントだと思う。

```diff
  before_action :authorize_read_wiki!
  before_action :authorize_create_wiki!, only: [:edit, :create, :history]
  before_action :authorize_admin_wiki!, only: :destroy
  before_action :load_project_wiki
+ before_action :load_page, only: [:show, :edit, :update, :history, :destroy]
+ before_action :valid_encoding?, only: [:show, :edit, :update], if: :load_page
+ before_action only: [:edit, :update], unless: :valid_encoding? do
+   redirect_to(project_wiki_path(@project, @page))
+ end
```

# その他
ちゃんと理解しようと思うとそれなりにコードとかモデルの関連とかを知る必要がある。

以下の3つは面白そうだけど、それなりに読み込みが必要そうなので、一旦メモしておく :pencil:

- [Add path of project and group milestones](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/20890/diffs)
- [Add user authentication activity metrics](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/20668/diffs)
- [Delete todos when users loses target read permissions](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/20665/diffs)
DjangoのImageKitを使うときはHerokuとAmazon S3に注意しよう。

<h1>はじめに</h1>
Djangoには便利なライブラリがたくさんあります。
ImageKitも、その１つで画像を自動的にリサイズしたり編集してくれます。

Djangoのmodels.pyに下記のように書いてあげるだけの簡単操作です。

```python:models.py
class Data(models.Model):

    image = models.ImageField(upload_to='/path/',
                              default="path/to/image/.jpg")
    middle = ImageSpecField(source='image',
                            processors=[ResizeToFill(1600, 1200)],
                            format="JPEG",
                            options={'quality': 100}
                            )
    small = ImageSpecField(source='image',
                           processors=[ResizeToFill(640, 480)],
                           format="JPEG",
                           options={'quality': 100}
                           )
```

余談ですがdefautl画像の設定をしておくのが吉です。htmlでレンダリングした際に画像が無ければエラーが出ることがあります。自分の環境ではローカルでは発生しなかったのですが実際にデプロイした際にエラーが出たのでdefault画像を設定しました。

HTMLファイルのテンプレートには

```html:index.html
{% for image in images %}
<img src="{{ image.small.url }}" >
{% endfor %}
```
と記載すると画像が表示されます。

Viewはこんな風にテンプレートに渡してあげます。流れを示しているだけなので適宜置き換えたり処理を追加してください。

```python:views.py
from .models import Data

def view(request):
  
    data = Data.objects.all()

    return render(request, 'index.html',
                  {'images' : data
                   })
```

これだけの処理でリサイズされた画像が簡単に表示できちゃいます。
HTMLタグにリンクタグつけるだけでサムネイル画像にもなりますし、使い勝手はいいです。


<h1>問題発生</h1>
Webサービスを作っている際に、そろそろデプロイしようと思ってHerokuをプラットフォームとして選択しました。
Herokuを使うのは初めてでしたが、簡単に公開できて感動しました！
しかし画像をアップロードしてもちょっとすると画像が消えている...

調べてみるとどうやらHerokuは画像やらのストレージとしては機能しないらしいので画像だけはAmazon S3などの他のファイルサーバから配信するのが普通だそうで。

配信方法については<a href="https://orangain.hatenablog.com/entry/django-heroku-s3-part1">こちら</a>などを参考にさせて頂きました。

ここまではすんなり行きましたが

>I/O operation on closed file

とエラーが発生。
どうやらAWSを使う際にライブラリのboto3を用いているのですが、それとの相性が悪いらしい。
この問題はimagekitの<a href="https://github.com/matthewwithanm/django-imagekit/issues/391">issue</a>でも議論されており

```python
class CustomS3Boto3Storage(S3Boto3Storage)

```
カスタムクラスを作成することで回避することが可能となっています。
全てソースコード載せるのは憚られたので上のissueを見てください。


<h1>まとめ</h1>
DjangoのImageKitを使うときはHerokuとAmazon S3に注意しよう。（２回目）
Railsアプリ作成の最初の準備（cloud9）①

:princess_tone1:「教師用Railsアプリ」①（$rails new~）

アプリのコンテストに出ます！
2月に勉強を始めて、まだ半年の超初心者ですが、
夏休みを使って、自分のレベルアップのために挑戦しようと思います。

今日（$ rails new）から完成までの記録を、できるだけ残していきたいと思います。


＊したこと

１）Rubyのバージョンチェック

```shell-session
 $ ruby -v  
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-linux]
```
２）gem rails　バージョン5.1.1　インストール

```shell-session
 $ gem install rails -v 5.1.1 
```

３）プロジェクト[lessonplan]の作成

```shell-session
 $ rails new lessonplan -d postgresql 
```

４）cloud9の設定  「template0」を追記

```yaml:config/detabase.yml
 default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see Rails configuration guide
  # http://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  template: template0　　←ここを追記
```

５）yarn経由でjquery,Bootstrapインストール
まず、[lessonplan]ディレクトリに移動

```shell-session
 $ cd lessonplan 
```

```shell-session
 $ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
 OK
```
```shell-session
 $ echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
deb https://dl.yarnpkg.com/debian/ stable main
```

```shell-session
 $ sudo apt-get update && sudo apt-get install yarn
・・・（省略）・・・
Unpacking yarn (1.9.2-1) ...
Setting up yarn (1.9.2-1) ...
```
⇒インストール開始（しばらくかかる）

```shell-session
 $ yarn add jquery
yarn add v1.9.2
info No lockfile found.
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ jquery@3.3.1
info All dependencies
└─ jquery@3.3.1
```
```shell-session
 $ yarn add bootstrap@3
yarn add v1.9.2
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ bootstrap@3.3.7
info All dependencies
└─ bootstrap@3.3.7
Done in 0.95s.
```
jsとcssに追記

```app/assets/javascripts/application.js
・・・（省略）・・・
//= require rails-ujs
//= require turbolinks
//= require jquery/dist/jquery.js　　←ここを追記
//= require bootstrap/dist/js/bootstrap.min　　←ここを追記　
//= require_tree .
```

```app/assets/stylesheets/application.css
/*
・・・（省略）・・・
 *
 *= require bootstrap/dist/css/bootstrap.min　　←ここを追記
 *= require_tree .
 *= require_self
 */
```
開発環境
Ruby   2.4.0
Rails -v 5.1.1
jQuery  3.3.1
Bootstrap 3.3.7


とりあえず、下準備その１はここまで。
ジム行って、走ってから、続きを。
Docker for Mac を使用していて「An HTTP request took too long to complete.」が出た

# 結論(直った方法)
Docker for Macを再起動する
おわり

## 発生
- OS:High Sierra (Version 10.13.6)
- Docker for Mac　(Version 18.06.0-ce-mac70)　を使用
- `docker-compose ほげほげ` を実行したときにエラーに遭遇

## エラー内容
```
ERROR: An HTTP request took too long to complete. Retry with --verbose to obtain debug information.
If you encounter this issue regularly because of slow network conditions, consider setting COMPOSE_HTTP_TIMEOUT to a higher value (current value: 60).
```

# おわりに
エラー文でぐぐって調べても解決方法がよくわからず、30分位悪戦苦闘していました。
ですが、解決法を模索している間に見つけた[こちら](https://github.com/docker/compose/issues/5620)をみると、どうやらDocker for Macが原因みたいな事が書かれていたので、試しに再起動したら普通に直りました。

再起動で直るなんてアホらしいなあとちょっと思ってしまったので、反省を込めた備忘録として書いておきます。
csvやtsvをmarkdownに変換する

# 参考文献
[CSVテキストをMarkdown形式のテーブルに変換するツールをつくった · THINKING MEGANE](https://blog.monochromegane.com/blog/2015/05/17/csv-to-markdown-table/)

# 導入

この文字列をコピーして試してください
1,2,3
a,b,c
d,e,f

```
# git cloneでもお好きに
ghq get https://github.com/monochromegane/mdt.git
cd /Users/ryuchan00/src/github.com/monochromegane/mdt
# パスを通った場所へコピー
cp mdt /usr/local/bin
pbpaste | mdt
| 1   | 2   | 3   |
| --- | --- | --- |
| a   | b   | c   |
| d   | e   | f   |

```
PhpStorm上でLaravel Mixプロジェクトのブレークポイントを使ったデバッグ


[RubyMine上でRails Webpackerプロジェクトのブレークポイントを使ったデバッグ](https://qiita.com/daiki7nohe/items/22ce8954510d4c295b6a)  で行なったようにLaravelプロジェクトでも同じようにモダンなJSフレームワークをブレークポイントを使ってデバッグしようと思います。



手順的にはRubyMineとRails Webpackerと同じで、Laravel mixではsourcemapをビルド時に生成する設定が必要です。



webpack.mix.jsを以下のように編集します。

```javascript
.
.
.
if (!mix.inProduction()) {
  mix.sourceMaps();
}
```



あとは、[RubyMine上でRails Webpackerプロジェクトのブレークポイントを使ったデバッグ](https://qiita.com/daiki7nohe/items/22ce8954510d4c295b6a)  と同じで、JetBrainsのブラウザ拡張のインストールやJavaScript Debugの設定を行なって起動するとブレークポイントが使えるようになります。
ブラウザバック時に画面遷移させずモーダルだけ消す対応

すごくピンポイントな内容ですが
とあるWebサービス(スマホ)の案件にて
**「モーダル表示時に、ユーザがブラウザバックしてしまうのを禁止したい、もしくはブラウザバックしてもモーダルが消えるだけで遷移しないようにしたい」**という要望がありいろいろ調査したので備忘録。

##仕組み
結論から言うと、ブラウザバックを実行した！というイベントは取れない。
なのでブラウザバック自体をdisableみたいな事は出来ない。
なので、ブラウザバック実行時に発生するイベントを取得可能なので、そちらで対応するやり方が一般的っぽい。

どうやら履歴というのは、ブラウザのHistoryというスタックの仕組みで動いている。
そのHistoryさんのAPI(下記参考サイト参照)は、追加(push)や変更(replace)は出来るようだが、取り出し(pop)や削除(delete)は出来ない模様。

[[Syncer] History](https://lab.syncer.jp/Web/API_Interface/Reference/IDL/History/)

そしてブラウザバックが実行された際に、Historyからpopする際のイベントが取れる。
それがよく「ブラウザバック禁止」とかでぐぐると出てくる下記サンプルのようなソースの概要のようだ。
```
window.addEventListener("popstate", function() {
  // ごにょごにょ
});
```

##safariのスワイプでのブラウザバックにハマる(失敗したやり方)

```
// ①遷移時にhistoryへ履歴を追加
history.pushState(null, null, null);

// popのイベント時(ブラウザバック時)に
window.addEventListener("popstate", function() {
    // 呼ばれたタイミングで①で追加した履歴が読まれている模様( = 現在のページへ遷移)

    // ②このままだと①が消化されている状態なので
    // 2回目以降のブラウザバック用にこのタイミングでもう1個追加する
    history.pushState(null, null, null);
    
    // ③モーダルを閉じる処理
    // ごにょごにょ

    // ④モーダルが開いてなかった場合はそのまま前画面へ遷移させたいが
    // ②で1個追加しているので2個分バックさせる
    (!modal_flg) && history.go(-2);
});
```
※書きながら思ったのだが④の後ろに②持ってきて、④でhistory.go(-1)ってしても良いような。でもそんなにやる事変わらないからまぁいっかと思ったり。

このやり方で概ね良い感じに動く。

が、スマホ実機端末のsafariには画面左端からスワイプでブラウザバック出来、しかも(脱獄しない限り)禁止出来ないという凶悪な機能がある。

前画面をA
現在の画面(モーダルを開いている画面)をB

とすると、モーダルからスワイプをしようとした際にチラ見えする画面がAになり、さらにシュッと実際にスワイプでのブラウザバックを実行すると、一瞬Aが表示されてからBに戻ってくる、という挙動になる。

前述のようにこのスワイプは禁止出来ない。
詰んだ＼(^o^)／

##解決策
とあるサイトを見ていたときにインスパイアされて解決した。
そう、パクろうとしたけどフロント側のフレームワーク違うしコードも難読化されててきつかったから渋々挙動を分析して苦戦しながらも実装したとかそういう事ではなく、あくまでもインスピレーションを受けただけなのだ。

やった事は3つ
①現在の画面にページ内遷移情報を付与
②モーダル表示時にpushstateで現在の画面URLに別の遷移情報を付与
③popstateの処理ではモーダルを閉じる処理だけ

元の画面URLが「https://xxx.com/list」だとすると
①遷移時のURLを「https://xxx.com/list#aaa」にして
②モーダル表示時にpushstate(null,null,"https://xxx.com/list#bbb")で履歴追加
という感じになる。
③も

```
// popのイベント時(ブラウザバック時)に
window.addEventListener("popstate", function() {
    // モーダルを閉じる処理
    // ごにょごにょ
});
```
これだけ。

なんだか狐につままれたような感じだが…
同一URLではリロードが走ってしまうが、ページ内遷移にする事でリロードも無し。
スワイプ時にチラ見えする画面もモーダル元の画面になっている。
よし。
[MATLAB] MEX関数の作成方法

# はじめに

MEX関数とは、MEXファイルに定義されたC/C++/Fortranで書かれた関数のことで、主にプログラムの高速化のために用いられます。通常のMATLAB関数と同様にMEX関数を読み込んで実行することができます。

以前、MEXファイルを作成したことがあったので、備忘録に残しておきます。
以下ではC++の場合のみ解説します。

# MEXファイルのC/C++用API

MEXファイルは必ず以下の形式を取ります。

```cpp:mexcpp.cpp
#include <mex.h>
/* ... */

// nlhs = 戻り値の数
// plhs = 戻り値へのポインタの配列
// nrhs = 引数の数
// prhs = 引数へのポインタの配列
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[]){
  /* ... */ 
}
```

上に示すMEXプログラムをビルドすると`mexcpp`というMEX関数が作られ、MATLABスクリプト内で

```m
<戻り値> = mexcpp(<引数>)
```

と使用することができます。ファイル内の`mexFunction`ではなく、MEXファイル名がMEX関数名となることに注意しましょう。

`mexFunction`内では、まず引数・戻り値の数と型を確認します。

```cpp:引数の数を確認
// 引数の数が１つかどうか確認
if (nrhs != 1) {
  mexErrMsgIdAndTxt("MATLAB:test:mexcpp:nrhs",
                    "Only one input argument required.");
}
```

```cpp:引数の型を確認
// 第一引数の型がdoubleかどうか確認
if (!mxIsDouble(prhs[0])) {
  mexErrMsgIdAndTxt("MATLAB:test:mexcpp:prhs",
                    "Input argument must be double.");
}
```

戻り値の数および型も同様に検証します。引数および戻り値の型を検証する関数は
[MathWorks Documentation: C行列ライブラリAPI - データの検証](https://jp.mathworks.com/help/matlab/validate-data.html)
にまとめられています。

次に与えられた引数および戻り値へアクセスします。第一引数にdouble型のスカラーが、第二引数にdouble型の行列が与えられたとすると、以下のようにアクセスすることができます。

```cpp:引数へアクセス
// 第一引数
double value = mxGetScalar(prhs[0]);

// 第二引数
// 配列の先頭へのポインタ
double* data = mxGetPr(prhs[1]);

// 第二引数の行・列数を得る
size_t rows = mxGetM(prhs[1]);
size_t cols = mxGetN(prhs[1]);
```

MATLABクラスのオブジェクトを渡してそのデータメンバーにアクセスすることも可能です。（`mxGetProperty`を使う）

データへアクセス（読み込み・書き込み）するための関数は
[MathWorks Documentation: C行列ライブラリAPI - データへのアクセス](https://jp.mathworks.com/help/matlab/access-data.html)
にまとめられています。

あとは得られたデータを使って戻り値を計算するだけです。
配列を扱う場合は、得られた生ポインタを適当なラッパークラスでラップしてから使用しましょう。（線形代数の計算を行うなら[`Eigen::Map`](https://eigen.tuxfamily.org/dox/group__TutorialMapClass.html)を使うと便利です。単なる配列なら[`gsl::span`](https://github.com/Microsoft/GSL)でよいでしょう。）

MEXファイルができたら[`mex`](https://jp.mathworks.com/help/matlab/ref/mex.html)コマンドを使ってMEX関数をビルドします。

# 参考リンク

- MathWorks Documentation
  - [MEXファイルの概要](https://jp.mathworks.com/help/matlab/matlab_external/introducing-mex-files.html)
  - [MEXファイルのビルド要件](https://jp.mathworks.com/help/matlab/matlab_external/what-you-need-to-build-mex-files.html)
  - [C行列ライブラリAPI](https://jp.mathworks.com/help/matlab/cc-mx-matrix-library.html)
  - [C++MEXファイルの作成](https://jp.mathworks.com/help/matlab/matlab_external/creating-c-mex-files.html)
  - [C++コンパイラの選択](https://jp.mathworks.com/help/matlab/matlab_external/choose-c-or-c-compilers.html)
  - [既定のコンパイラの変更](https://jp.mathworks.com/help/matlab/matlab_external/changing-default-compiler.html)
  - [MEXファイルのソースコードファイルの表](https://jp.mathworks.com/help/matlab/matlab_external/table-of-mex-file-source-code-files.html)
Mixed Reality Toolkit - Unityのサンプル「SharingWithUNET」をUnity Editorのデバッグ実行で確認する。

# 個人でHoloLensでシェアリングアプリを作るとき困るんです
もうお察しかもしれませんが、HoloLensでシェアリングのアプリを作るときに最大の問題は「HoloLensが複数台必要になること」です。過去色々方法は模索していたんですが最も有力なものとしてHoloLensエミュレーターを利用する方法です。過去SharingService（Mixed Reality Toolkitが提供するサーバを立てて利用するシェアリングのシステム）の場合ではあるのですが、この方法で複数台のHoloLensでの動きを確認していました。HoloLens実機１台でシェアリングアプリのデバックするには以下の組み合わせで疑似的な２デバイス状態を作る形になると思います。

1. HoloLens Emulator&HoloLens実機でシェアリング
2. Unity Editorを使ってPC&HoloLens実機でシェアリング
3. PCのWindows Mixed Realityデバイス & Hololens実機でシェアリング 

この中で特に「2. Unity Editorを使ってPC&HoloLens実機でシェアリング」はデバッグ時の情報も確認できる＆手軽に実現できるのでいいと思います。
ということで、今回はMixed Reality Toolkit - Unityのサンプル「SharingWithUNET」をUnity Editorのデバッグ実行で確認したいと思います。

## SharingWithUNETはそのままではUnity Editorのデバッグはできない。
実はそういうトラップがあったります。MRTKについているこのサンプルをUnity Editor上で実行してもUNETでいう「ホスト」や「クライアント」になれません。これはUnity Editorの場合は「ホストのIPアドレスがランダム」という実装になっているのでMRTKのサンプルをベースにUNETを使うとデバッグ時に困ります。
ということで少し見直して問題を解消しシェアリングアプリ開発を楽にしましょう。

## 修正方法

まずは、開発環境ですが以下の形となります。

### 開発環境
* Windows 10 Pro Spring 2018 Update
* Unity 2017.2.1p2
* [HoloToolkit-Unity-2017.4.0.0.unitypackage](https://github.com/Microsoft/MixedRealityToolkit-Unity/releases/tag/2017.2.1.4)
* [HoloToolkit-Unity-Examples-2017.2.1.4.unitypackage](https://github.com/Microsoft/MixedRealityToolkit-Unity/releases/tag/2017.2.1.4)

### 修正箇所
修正するコードは「NetworkDiscoveryWithAnchor.cs」です。
修正箇所は以下の3個所になります。

* Awakeメソッド
* InitAsServerメソッド
* StartHostingメソッド

#### Awakeメソッドの修正
AwakeメソッドではUnity Editor上で動かす際にIPアドレスを「"Editor"+ランダム値」で設定します。まずはここを正しいIPアドレスに変更しましょう。
プロパティを用意してもいいのですが、ここは手っ取り早くハードコーディングで。

```csharp:NetworkDiscoveryWithAnchor.cs
        private void Awake()
        {
#if !UNITY_EDITOR && UNITY_WSA
            // Find our local IP
            foreach (HostName hostName in NetworkInformation.GetHostNames())
            {
                if (hostName.DisplayName.Split(".".ToCharArray()).Length == 4)
                {
                    Debug.Log("Local IP " + hostName.DisplayName);
                    LocalIp = hostName.DisplayName;
                    break;
                }
            }
#else
            LocalIp = "XXX.YYY.ZZZ.XXX";//ここを端末のIPアドレスにする。
#endif
```

#### InitAsServerメソッドとStartHostingメソッド

これらのメソッドは実際にホストとしてサービスを立ち上げるために利用するメソッドなのですが、Unity Editorでの実行時は意図的にIPアドレスの指定を行っていません。
これは先ほどのAwakeメソッドでダミーのIPアドレスを与えている空だと思います。
ここはUnity Editorのみで実行が除外されている部分を修正します。
修正箇所は各メソッド最初にある以下の記述から「#if !UNITY_EDITOR && UNITY_WSA」と「#endif」を削除します。

```csharp:NetworkDiscoveryWithAnchor.cs


private IEnumerator InitAsServer()
{
    Debug.Log("Acting as host");
    NetworkManager.singleton.serverBindToIP = true;
    NetworkManager.singleton.serverBindAddress = LocalIp;
  ・
  ・
}


public void StartHosting(string SessionName)
{
    StopListening();

    NetworkManager.singleton.serverBindToIP = true;
    NetworkManager.singleton.serverBindAddress = LocalIp;
　・
　・
 }
```

### HoloLensにデプロイして実行

アプリが完成したらHoloLensにデプロイします。
その状態からUnity Editorをデバックで実行しホストとして実行します。その後HoloLensで同じアプリを起動するとデバッグ中の端末が一覧に表示されるので、選択して参加することでシェアリングが可能です。
[備忘録]Unity Editor上でUNETのデバッグをするときに立ちはだかるFire Wallをなんとなする（Windows Defenderの時）

# なぜかうまくつながらないと思ったら
UNETでうまくつながらないといえば使ったことある人にとってはあるあるだと思うのですが、遭遇すると解決に手間取って「ああ！もういい！」って投げてしまいそうになります。そんなあるある例としては以下のようなものでないでしょうか。

* ホストになった端末が見えない
* ホストは見えて参加もできるが、アプリが通信していない

同一ネットワークに参加していても発生する場合はたいていFire Wallがポートをふさいでいるというのがよくある話です。

## UNETのポート関連
UNETが使うポートについてはいくつかあります。

* NeworkManagerが通信に使用するポート（１つ）
* MatchMaker用のポート(1つ)
* NetworkDiscoveryが通信に使用するポート（1つ)

NetworkDiscoveryは状況に応じて使用の有無があります。（ホストを自動検索する場合等）よってこのポートをFire Wall上で開けてあげれば通信は可能です。

## 対象のFire Wall
私は環境上Windows DefenderのFire Wallに阻まれるのでここの設定をUNETが通るように設定変更を行います。
ポイントはUnity Editorのポートの解放状況です。どうもUnityはインストール時点で下記のように「受信の規則」の中でpublicネットワークに向けての通信はデフォルトでブロックしています。これが影響していてエディタ上ではつながらないことが多いんですね。
ということで「Unity 2017.2.1p2 Editor」の設定を「ブロック」ではなく「許可」に変更してあげれば解決します。変更するEditorについては使用しているUnityのバージョンを見てください。

![image](https://qiita-image-store.s3.amazonaws.com/0/152548/06002310-119d-d214-d006-a54ee7c288ea.png)

## 念のため
UNETでの検証が終わったらもとに戻しておきましょう。