OmniAICreator/Qiita-1.07M huggingface dataset:
自作のノベルゲームエンジンを作ってみた

# はじめに

この記事は、DxLib Advent Calendar 2018 の8日目の記事です

僕が代表を務めているゲームリンクスで使用することを目的に制作したノベルゲームエンジン「LINKS」について書きます

# つくったもの

これらをDxLibを使い作りましたー

[Novel.Game.Engine.LINKS(C版)](https://github.com/S-H-GAMELINKS/Novel.Game.Engine.LINKS)

[Novel.Game.Engine.LINKS.for.CPP(C++版)](https://github.com/S-H-GAMELINKS/Novel.Game.Engine.LINKS.for.CPP)

実際のデモは以下のような感じです


![links.gif](https://qiita-image-store.s3.amazonaws.com/0/191521/8a46a1a3-45d2-1be2-60c0-78fddeef7cad.gif)


C版LINKSに関してはyumetodoせんせーからのPull Requestなどを受けつつリファクタリングしてたり

C++版LINKSはそのあとにC++で実装しなおしてみたものになります。

# 実装のあれこれ

一応は、ノベルゲームのエンジンをうたっているので各種素材を読み込む処理を実装しています

```cpp

#include "ConstantExpressionVariable.hpp"
#include <vector>
#include <string>
#include <array>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <boost/filesystem.hpp>
#include <boost/range/iterator_range.hpp>

namespace fs = boost::filesystem;

namespace {

	//各素材ファイルパス取得
	const std::vector<std::string> AllFilePath(const std::string& Path) {

		std::vector<std::string> Container;

		const fs::path path(Path);

		for (const auto& p : boost::make_iterator_range(fs::recursive_directory_iterator(path), {})) {
			if (!fs::is_directory(p.path()))
				Container.emplace_back(std::move(Path + "/" + p.path().filename().string()));
		}

		return Container;
	}
}

//各種素材読込テンプレート関数
template <typename T, typename Func>
constexpr std::vector<T> MaterialLoad(std::vector<T> Material, const std::string& Path, Func&& Loader) noexcept {

	//サウンドデータの読み込み形式
	DxLib::SetCreateSoundDataType(DX_SOUNDDATATYPE_MEMPRESS);

	std::vector<std::string> Container = AllFilePath(Path);

	for (auto&& c : Container)
		Material.emplace_back(std::move(Loader(c.c_str())));

	return Material;
}
```

ちなみにこれはC++版LINKSでBoostを使って実装した部分になります

ファイルパスを渡し、その中にある全てのファイルへのパスを格納させています。
そのあとラムダ式:`Loader`で受け取ったパスを使い、各種素材を読み込むようにしています



# 今後

今後としては、もうちょい機能拡充を図るか高速化を図るかといったところかなぁと

あとは、LINKS使ってのフリーゲーム制作とかどんどんやっていきたいなと思います
R環境について

自分の備忘録もかねて置いておきます。

macOSをMojaveにアップデートしたら、Rの日本語設定をしなければいけなくなったので、変更用のコードです。

ターミナルで以下のコードを実行するとR環境で日本語が出るようになります。


`system("defaults write org.R-project.R force.LANG ja_JP.UTF-8")`


これを実行してから、Rを立ち上げなおすと日本語読み込み出力できます。
Rを開いたまま実行しても直らないので、Rを1回閉じないといけないです。
OSをアップデートしたら突然Rに不具合が起こって、少し焦りました。
Docker Composeを使ってサクッとNginxコンテナを起動する

## 前提・環境

・Windows10 Pro
・Docker for Windows（コマンドプロンプトで「docker --version」や「docker-compose --version」を打ってバージョン番号が表示されること）

## Docker Composeとは
Docker Composeとは、複数のコンテナを使うDockerアプリケーションを、定義・実行するツールです。開発中や運用時に複数のDockerコンテナを使うと管理が煩雑になりますが、Docker Composeを利用することで環境構築における構築手順を自動化することができたりするので、煩雑さを軽減することができます。

## NginxをDocker Hubから取得
以下のコマンドでDocker HubからNginxのイメージを取得します。

```
docker pull nginx:latest
```

次に以下のコマンドでnginxのイメージが取得できているかを確認します。

```
docker images   ※もしくはdocker images nginx
```

REPOSITORYにnginxが存在すればOKです。


## Dockerfileの作成

 
```Dockerfile
# base imgae（docker imagesコマンドで表示されたREPOSITORYを指定）
FROM  nginx:latest

# author
MAINTAINER  nagaoka

ADD default.conf /etc/nginx/conf.d

RUN echo "now building..."
```

## docker-compose.ymlの作成

```docker-compose.yml
version: '3'
services:
  nginx:            // ※1
    build: .        // ※2
    ports:
      - "8080:80"        // ※3
    volumes:
      - ./public:/usr/share/nginx/html        // ※4
```

※1任意の名前を指定
※2Dockerfileからコンテナ生成・起動する場合。Dockerfileを利用しない場合は、image: nginxと記述
※3「ホスト側のポート:コンテナ側のポート」の形式。ホスト側のブラウザ等でhttp://localhost:8080　とアクセスすると、コンテナ側の80ポートへフォワードされる
※4「ホスト側のディレクトリ:コンテナ側のディレクトリ」の形式。左記の例だと、docker-compose.ymlが配置されたディレクトリにあるpublicというディレクトリがコンテナ側の「/usr/share/nginx/html」にマウントされる

## コンテナ起動
以下のコマンドでnginxを起動します。

```
docker-compose up
```

以上です。

## 参考
http://docs.docker.jp/v1.12/compose/index.html
http://docs.docker.jp/v1.12/compose/compose-file.html#service-configuration-reference
git push -u origin branch_name を楽にする

## はじめに
この記事は[Linkbal Advent Calendar 2018](https://qiita.com/advent-calendar/2018/linkbal)の5日目の記事です。昨日は、私がリンクバルで一番プログラミングできると思っている方の[letをconstにできるケース（とlet使用禁止というルールについて）](https://qiita.com/laineus/items/5b8f51e8823c3f510f0e)という記事です。

どうも、水野（キンチキ）です。今回はgitについてちょっとしたことを書きます。

## git push -u origin branch_name がダルい
gitで新しくブランチ切り、最初にpushするときに `git push -u origin branch_name` と実行するじゃないですか？

これかなりめんどくさくないですか？ いちいちタイプ数が多いんですよ。プライベートならともかく、業務だと頻繁にブランチ切ることありますし。

これを毎回ブランチ切る度に打ってて嫌になったので楽にする関数を作りました。

## 楽にする関数
以下の関数を `.bashrc` や `.zshrc` に追加してください。関数名はお好きなもので。

```sh
function gpush-u() {
    BRANCH=$(git symbolic-ref --short HEAD | tr -d '\n') # カレントブランチ名を取得
    git push -u origin $BRANCH
}
```

この関数を定義しておけば、例えばブランチが `hogehoge` というとき、`gpush-u` と打つだけで `git push -u origin hogehoge` が実行されます。

`git symbolic-ref --short HEAD` はカレントブランチを出力しますが、改行が含まれているため `tr -d '\n'` で改行を消して変数に入れます。そしてそれを `git push -u origin` に続けているだけです。

それだけなのですが、個人的にめちゃくちゃ便利なので、ぜひ使ってみてください。

これはわざわざ関数にせずにaliasでもいいかもしれないです。私の書き方がいけないのか、aliasだと上手く動かないことがあったので関数にしたら常に動くようになりました。おそらく、シェル起動時にgitリポジトリ以外のディレクトリなので `git symbolic-ref --short HEAD | tr -d '\n'` が正常に動かなかったことが原因です。

## 【追記】 楽にするalias
コメント頂いた以下のコマンドならaliasでいけます。

```sh
# OK
alias gpush-u='git symbolic-ref --short HEAD | tr -d "\n" | xargs -I@ git push -u origin @'

# NG
alias gpush-u='git push -u origin `git symbolic-ref --short HEAD | tr -d "\n"`'
```

NGの方だと、バッククォートで囲われているところがコマンドを読み込んだ時（not `gpush-u` を実行した時）に評価されて `git symbolic-ref --short HEAD | tr -d "\n"` の部分が動かないのですね。

@YHiroyuki さんありがとうございます！

## おわりに
簡単なシェルスクリプトを作ったり、ちょっとしたシェルの設定をするだけでコマンドラインはかなり便利になったりします。面倒に感じることやなんとかしたいと感じることはきっと解決策があるので、ぜひ調べてみてください。

私のかなり拙い`.zshrc`ですが、他にもgitに関する関数など登録しているので、よろしければご覧ください！
[dotfiles/.zshrc at master · kinchiki/dotfiles](https://github.com/kinchiki/dotfiles/blob/master/.zshrc)

それではまた。
【YouTube】足立研 Javaプログラミング入門講座 -オブジェクト指向を理解する-【まとめ】

オブジェクト指向を復習するにあたって参考にした、慶應義塾大学の小野雅裕元助教授による[足立研セミナー](https://www.youtube.com/watch?v=KW5aafq8CGk&t=854s)がとてもわかりやすかったので要点を自分なりにまとめたいと思います。

##オブジェクト指向
**そもそもなぜオブジェクト指向が重要なのか？**
- 人気のプロジェクト言語はほとんどがオブジェクト指向の概念を取り入れているから
- 大きなプロジェクトや複数人でプロジェクトを動かすときにとても便利だから

####クラスとインスタンス
オブジェクト=全てのもの 
e.g.)僕の車、小野先生のネクタイ、新庄剛志の歯、りんご、便座

---------------------------
クラス=もののカテゴリー 
インスタンス=クラスの下に入るもの
e.g.)クラス=犬　インスタンス=チコちゃん（小野先生の犬）、白戸次郎、パトラッシュ
e.g.)クラス=人　インスタンス=小野雅裕、バラクオバマ、アホの坂田
<img width="522" alt="スクリーンショット 2018-12-05 22.27.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/301887/f665a798-1cae-0adb-b1c5-0d4f89ea382c.png">

####カプセル化
**アクセス修飾子**
- `public` 外部からでも参照可能
- `protected` 同一クラス、同一パッケージ、サブクラスからの参照可能
- `default` 同一クラス、同一パッケージからの参照可能
- `private` 同一クラスからの参照可能
つまり書き換えられたくない度合いによってアクセス修飾子を使い分けることが必要。
必要な情報を隠蔽し、メソッドを通してしか情報にアクセスさせないことを**カプセル化**と言います。

####クラスの継承
**クラスの階層構造**
スーパークラス 
  e.g.)
Animal

サブクラス 
 e.g.)
1. Dog
2. Cat

インスタンス
 e.g.)
1-1. チコちゃん
1-2. 白戸次郎
1-3. パトラッシュ
2-1. ミーミ
2-2. ひこにゃん
2-3. ミャロメ
<img width="493" alt="スクリーンショット 2018-12-05 23.00.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/301887/bc7087fb-7718-0ec3-1c9a-09b4701664ca.png">

`class Dog`と`class Cat`のスーパークラスとして`class Animal`を宣言したいときは`extends`を用いて、

```
class Animal {
~~
}
class Dog extends Animal {
~~
}
class Cat extends Animal {
~~
}
```

とするとそれぞれのクラスが紐づけられます。

######なぜこのような階層構造が必要か
`class Animal`では以下のような特徴があるとします。
- 目が2つ
- 尻尾が1つ
- 足が4本
これらの情報は共通項としてサブクラスにも適応することができます。
しかし`class Dog`ではさらに`class Cat`にはない以下の特徴を追加するとします。
- 人懐っこい
- ワンッと鳴く
逆に`class Cat`には`class Dog`にはない以下の特徴を追加します。
- 高くジャンプする
- ニャーと鳴く

階層構造を持たせることでこのような共通項目とするものと独自の項目とするもので使い分け、扱いやすくすることが可能になります。

####ポリモーフィズムとオーバーライド
**ポリモーフィズム**とは一定の型を用意し、その型の中に入る引数によって異なる動作を実装する方法のことです。
上記の例を使えば、

```animal.java
class Animal {
~~
public abstract void poke (); //pokeの中身はabstractをつけることで空になっている
~~
}

```

```dog.java
class Dog {
~~
@Override //abstractをつけたスーパークラスの抽象メソッドをこちらのサブクラスで実装
public void poke (){
  makeSound(); //ワンッと鳴く
  say(); //何かしらメッセージを入れる
}
}
```


##まとめ
以上、今回は慶應義塾大学の小野雅裕元助教授による講義『足立研セミナー』を、YouTubeを参照しながらまとめました。
Backlogで正確な実績時間を集計する方法

Backlog API を利用して正確な実績時間集計をするツールを作成しました。

Backlog上の検索機能では課題の作成日の期間指定した場合でもその期間で実績時間が正しく集計することが出来ません。
例えば、①11月1日から11月30日まで実績時間と②12月1日から12月31日まで実績時間を集計しようとした場合、単純に課題の実績時間を合計した場合、①と②で重複する可能性があります。(ひとつの課題で①と②の期間にわたって対応した場合)

課題内のコメントを検索し、実績時間が入力された日時と実績時間から正しい実績時間を集計しています。

#### Source code
https://github.com/infinith4/BacklogApiProcessing

#### 使い方
以下に記載の通りです。
https://github.com/infinith4/BacklogApiProcessing/blob/master/README.md
Lambda Layer と X-Ray

# はじめに
AWS re:Invent 2018 でLambdaのLayer機能が発表されたのでどういう使い方をするかなーと考えてみました。
使い方についてはもういろんなサイトで公開されているので割愛。

今回は、分析時に便利なX-Rayの導入を簡素化させるためのLayerを用意してみました。

Lambdaのコードや設定は[ここ](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-layers.html/)を参考にしています。

# tl;dr
- Layerはパッケージを作るときに言語毎のルールがあるのでそれに従わないといけない
- Layerは/optに展開される
- あとは通常のライブラリの使い方と同じかんじ
- X-Rayやrequestsのライブラリを個別に入れる手間が少しだけはぶける。（既存のLambdaに手を加える必要はある。）

# やったこと

## 前提
- ALB、Lambdaは東京リージョンに作成
- Layerの言語はPython 3.6
- Layerを追加したいLambdaはすでに作成ずみ（Python 3.6)

## Layerのパッケージの作成
今回はX-Rayとrequestsを含めたLayerを作成する

```
$ mkdir python
$ touch python/layer.py
$ pip install requests -t python/
$ pip install aws-xray-sdk -t python/
```

layer.pyを編集する

```layer.py
from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core import patch_all

patch_all()
```

zipにしたらパッケージの準備完了

```
$ zip -r python.zip python/
```

## Layerの作成
```
$ aws lambda publish-layer-version --layer-name x-ray-layer --description "x-ray layer" --license-info "MIT" --content S3Bucket=xxxx,S3Key=python.zip --compatible-runtimes python3.6
```

## LambdaにLayerを追加
```
$ aws lambda update-function-configuration --function-name <function_name> --layers arn:aws:lambda:ap-northeast-1:<account_id>:layer:x-ray-layer:1
```

## LambdaのX-Rayを有効化
```
$ aws lambda update-function-configuration --function-name <function_name> --tracing-config '{"Mode": "Active"}'
```

これで、準備は完了。
あとはLayerを追加したLambdaに以下の一文を追加するとX-Rayでトレースが見られるようになる。

```
import layer
```

Layerを適用したLambdaのデプロイ用のパッケージは容量減るのですっきりした感じがする。
（実行時のモジュールサイズはへらない。）
OctoberCMS ViewBagの変数の有無のチェック方法

ViewBagの使用方法に落とし穴があったのでメモ。

## やりがちな誤った方法
例えばレイアウトテンプレートで、ある変数が設定されているときだけ、それを使用する、という記述がしたい場合、下記のように書きそうだが、これはNG。

```twig
{% if viewBag.canonical_url is not empty %}
	<link rel="canonical" href="{{ viewBag.canonical_url|app }}">
{% endif %}
```
なぜなら変数、この例では `canonical_url` は変数が存在しない場合に `empty` と判定されないからだ。未確認だが、おそらくマジックメソッドとして処理されるためだろう。

ちなみに、`is defined` でもダメだ。変数が存在しない場合に例外になってしまう。

```twig
{% if viewBag.canonical_url is defined %}
```

また、そもそも `viewBag` コンポーネントがレイアウトやページに設定されていないと、エラーになる。

## 正解
下記のように、 `viewBag` と変数の有無のチェックを `empty` チェックの前に入れてやれば良い。

```twig
{% if viewBag is defined and viewBag.__isset('canonical_url') and viewBag.canonical_url is not empty %}
	<link rel="canonical" href="{{ viewBag.canonical_url|app }}">
{% endif %}
```

なんともバグが混入しやすそうな仕様だ。早く改善したいもんだ。

[StackOverflow](https://stackoverflow.com/questions/53223008)にもう少し詳しく書いてあるので参考までに。
Vue.js使いだして２年くらい経ったけど、使ったことないAPIを使ってみる「グローバル設定」(2/2)

[Vue.js使いだして２年くらい経ったけど、使ったことないAPIを使ってみる「グローバル設定」(1/2)](https://qiita.com/bolobob/items/b9f3abebba1feb18708c)の続き

### [ignoredElements](https://jp.vuejs.org/v2/api/#ignoredElements)

```vue
<template>
  <div id="app">
    <x-tabs>
      <x-tab>タブ1</x-tab>
    </x-tabs>
  </div>
</template>
```

上記のように`Web Components` の `Custom Elements` を使って独自の要素を定義した場合、

![スクリーンショット 2018-12-03 23.28.52.png](https://qiita-image-store.s3.amazonaws.com/0/19909/b77e3818-e558-3aeb-2643-5c7f89d8b9cc.png)

このような警告が出力される。
そこで、

```js
Vue.config.ignoredElements = [
  'x-tabs',
  'x-tab'
];
```
と設定すると警告が出力されなくなる。
これで`Web Components`も安心して使える。

### [keyCodes](https://jp.vuejs.org/v2/api/#keyCodes)

[キー修飾子](https://jp.vuejs.org/v2/guide/events.html#%E3%82%AD%E3%83%BC%E4%BF%AE%E9%A3%BE%E5%AD%90)なるものがあり、特定のキーコードだけに反応するキーボードーイベントが簡単に実装できる仕組みがある。
`enter`や`tab`など代表的なものはすでにエイリアスが用意されてるが、ほとんどキーコードに対しては用意されてない。
そこで`keyCodes`を使うことでエイリアスを設定できるようだ。

```js
Vue.config.keyCodes = {
  v: 86,
  f1: 112,
  // キャメルケースは動作しません
  mediaPlayPause: 179,
  // 代わりに、二重引用符でケバブケースを使用することができます
  "media-play-pause": 179,
  up: [38, 87]
}
```
といった設定をすると

```vue
<input type="text" @keyup.v="submit">
<input type="text" @keyup.f1="submit">
<input type="text" @keyup.media-play-pause="submit">
<input type="text" @keyup.up="submit">
```
といった書き方ができるようになる。

### [performance](https://jp.vuejs.org/v2/api/#performance)

```js
Vue.config.performance = true;
```
にして、`devtool`の`Performance`パネルを未設定のときと見比べたけど、何が違うのかよくわからなかった。

### [productionTip](https://jp.vuejs.org/v2/api/#productionTip)

> プロダクションのヒント

![スクリーンショット 2018-12-05 22.54.05.png](https://qiita-image-store.s3.amazonaws.com/0/19909/64ab18c2-3e40-548d-4e50-d208a467c09d.png)

これが

```js
Vue.config.productionTip = false;
```
にすると表示されなくなる。
[Elm]Browser.Navigation.Key生成できない問題

# 要約

`Browser.Navigation.Key`は自分で生成できなくてテストなどで困るので以下のような型を作ってます

```Types.elm
type WithKey m
    = WithKey Key m
```

以上です。ありがとうございました

# 問題提起

Elm0.19になって起動`Program`周りが整理されて[`Browser` package](https://package.elm-lang.org/packages/elm/browser/latest/Browser)に集約されました

この中の[`Brouwser.application`](https://package.elm-lang.org/packages/elm/browser/latest/Browser#application)ではルーティングを行う際、[`Key`](https://package.elm-lang.org/packages/elm/browser/latest/Browser-Navigation#Key)が必要になります

この`Key`型の値は`init`関数に渡されるのでそこでよしなに自分の`Model`に含めることになります

```Main.elm
type alias Model = { key : Browser.Navigation.Key, ... }

init : () -> Url -> Key -> ( Model, Cmd Msg )
init _ url key =
    ( { key = key
      , ...
      }
    , Cmd.none
    )
```

さて、何も問題はありませんね

## Modelを引数にとる関数のテストをしたい

あなたの手元にはModelを引数に取る関数があり、これをあなたはテストしたいはずです
updateの中身を切り出した関数とか、Page用のviewとかですね

```elm
update msg model =
    case msg of
        ComplicatedMsg data ->
            complicatedUpdate data model
        ...

view model =
    case route of
        ListRoute ->
            listView model
        ...
```

[わたしの場合はviewでKeyが問題になりました(コード)](https://github.com/miyamoen/elm-local-packages/blob/c8a020d81597a379a833474c8a7956422a55e64c/src/elm/Views/Pages/Packages.elm#L21)。わたしは自分で作った[Bibliopola](https://package.elm-lang.org/packages/miyamoen/bibliopola/latest/)というStorybook的なのでviewを見ながら開発してるのでModelが生成できないと使えなくなって困るんです

# 解決策1

問題を解決するのは難しいことではありません
引数に`Key`が入ってるとはいえ別に使ってるわけではないので適切に引数の型を狭めればいいです

```elm
type alias Model =
    { key : Key
    , ham : Ham
    , egg : Egg
    }

-- view : Model -> Html Msg
view : { a | ham :Ham, egg : Egg } -> Html Msg
view model =
    ...
```

こんな感じ。構造的部分型とかいうのかな、まあ詳しくないので呼び方はなんでもいいのですがこれでこのview関数をテストするのに`Key`は不要になりました

ついでにaliasしときましょう

```elm
type alias SubModel a =
    { a | ham : Ham, egg : Egg }

view : SubModel a -> Html Msg
view model =
    ...
```

よしこれでOkですね🎉

# 解決策2

`SubModel a`の型変数がうざい

解決策3も出てきますが型いじってるだけで大差ないのでお好きなものがあれば採用ください

アプリケーションの都合で型変数を持たされてしまった型を引数に取るのはなんかうざいのでちょっと逆転させます

```elm
type alias Model =
    { ham : Ham, egg : Egg }

type alias WithKey m =
    { m | key : Key }

view : Model -> Html Msg
view = ...

main : Program () (WithKey Model) Msg
main = ...
```

よしよしこれでProgramの都合は`Browser.application`が直接依存する関数だけにとどまるぞ🎉

# 解決策3

`Model`の詰め替えがつらい

`WithKey Model -> Model`の処理は自動でやってくれないので中身を取り出して詰め替えしないだめです。`Model`にフィールド増えたときも増やさないといけないです
まあめんどいです

とうことで今日仕事中に唐突に思いついたんですけどこれでどうでしょうか？

```elm
type WithKey m
    = WithKey Key m
```
これなら要素の詰め替えもしなくてよい

解決策2と比べて代わりにupdateの返り値を必ずWithKeyで包まなくてはならなくなったのですが、updateの内で対処するのは理にかなってるので今はこれでやってみてます

# おわり

[feldmanがこの件に関して対処するようです]
(https://github.com/elm-explorations/test/issues/24#issuecomment-444143745)

`Cmd`のテストとかできるようになるんですかねー、たのしみー
条件分岐をしないFizzBuzz

# 最近FizzBuzzをよく見かける季節になってきたので
おそらく高速なFizzBuzzを

```rb
def fizzbuzz(max)
  fb_count, rest = max.divmod 15
  last_fb = fb_count * 15
  r = 1.step(last_fb, 15).reduce(''){|memo, n|
    memo += <<~StrFizzBuzz
      #{n}
      #{n+1}
      Fizz
      #{n+3}
      Buzz
      Fizz
      #{n+6}
      #{n+7}
      Fizz
      Buzz
      #{n+10}
      Fizz
      #{n+12}
      #{n+13}
      FizzBuzz
    StrFizzBuzz
  }
  rest_start = last_fb + 1
  rest_array = Array.new(rest){|i| rest_start + i}
  3.step(rest, 3){|n| rest_array[n-1] = 'Fizz' }
  5.step(rest, 5){|n| rest_array[n-1] = 'Buzz' }
  r + rest_array.join("\n")
end

puts fizzbuzz(100)
```

# 工夫した点
- FizzBuzzは15要素ずつ変換する事ができるので一気に
- 後半の余り部分も`step`だけで乗り切る

# ベンチマークは
後でやる
QuickSort

QuickSortのプログラムを書いてみました。
再帰を使うと便利ですね。

クイックソートは、
1. データ列からPivotを選ぶ
2. Pivotより大きいものと小さいものに分ける
3. 分けたそれぞれを整列
というようにソートしていきます。

Pivotが、データ列の中央に位置するような場合は、ソートのなかで計算量が最も少ないアルゴリズムで、計算量はO(nlogn)で済みます。
Pivotが一番端に来るような場合はO(n^2)かかってしまいます。


```java:QuickSort.java
import java.util.*;
public class QuickSort {
    public static boolean debug = false;
    private static int partition(int[] a,int l,int r){
	if(debug)System.out.print("partition l="+l+", r="+r);
	int pivot = a[r];
	int i = l;
	int j = r-1;
	for (;;) {
	    while (a[i] < pivot) ++i;
	    while (i<j && a[j] >= pivot) --j;
	    if(debug) System.out.println("check i="+i+" ,j="+j+" ,pivot="+pivot);
	    if(i>=j) break;
	    if(debug) System.out.println("change i="+i+" ,j="+j);
	    int tmp = a[i];
	    a[i] = a[j];
	    a[j] = tmp;
	}
	int tmp = a[i];
	a[i] = a[r];
	a[r] = tmp;
	return i;
    }
    private static void quickSort(int[] a,int l,int r){
	if(l >= r) return;
	int v = partition(a,l,r);
	if(debug) System.out.println("l="+l+", r="+r+", v"+v+": "+toString(a));
	quickSort(a,l,v-1);
	quickSort(a,v+1,r);
    }
    public static void sort(int[] a){
	quickSort(a,0,a.length-1);
    }
    public static String toString(int[] a){
	StringBuffer sb = new StringBuffer();
	for (int i = 0; i < a.length; i++) sb.append(a[i]+" ");
	return sb.toString();
    }
    public static void main(String[] args) {
	if(args.length > 0 && args[0].equals("-d")) debug = true;
	Scanner sc = new Scanner(System.in);
	System.out.print("データの個数を入力してください ");
	int n = sc.nextInt();
	int[] a = new int[n];
	for (int i = 0; i < n; i++) a[i] = sc.nextInt();
	sort(a);
	System.out.println(toString(a));
    }
}
```
SelectionSort

SelectionSortのプログラムを書いてみました。

SelectionSort（選択ソート）は、小さいデータを見つけて、最初の位置の要素を入れ替えていきます。
それを繰り返していくので、n^2/2回の比較が必要になり、計算量はO(n^2)です。


```java:SelectionSort.java
import java.util.*;
public class SelectionSort {
    static boolean debug = false;
    public static void main(String[] args) {
	if (args.length > 0 && args[0].equals("-d")) debug = true;
	Scanner sc = new Scanner(System.in);
	System.out.print("データの個数を入力して下さい  ");
	int n = sc.nextInt();
	int[] a = new int[n];
	for (int i=0; i<n; i++) a[i] = sc.nextInt(); 
	sort(a);
	System.out.println(toString(a));
    }
    public static void sort(int[] a) {
	    for(int i = 0; i < a.length-1; i++) {
	    int k = i;
	    for(int j = i + 1; j < a.length; j++) {
		if(a[k] > a[j]) k = j;		
	    }
	    int tmp = a[i];
	    a[i] = a[k];
	    a[k] = tmp;
	    if(debug) { System.out.println("sorting: " + toString(a)); }
	}
    }
    public static String toString(int[] a) { 
        StringBuffer sb = new StringBuffer();
	for(int i = 0; i < a.length; i++) {
	    sb.append(a[i] + " ");
	}	
	return sb.toString();
    }
}
```
8946 Take#63

#問題

http://www.hackerschool.jp/hack/take63.php

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/87ece18d-fcac-633f-b42e-a3cec8a95412.png)

#解いてみた

- クリックしてみましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/c8662ea6-fc6d-01a4-736d-383af4fa3d3a.png)

- こんなページが開きました。
- 適当に文字を入れてログインしてみる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/29efafda-bdd8-faa0-f349-c2044c543627.png)

- ソースを見てみましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/18b8cf88-99a9-4b5b-a32e-63214f609c6c.png)

- 特に何もないですね。
- wiresharkで見てみましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/cd62eb61-a0d6-0c94-6148-62d6a9344f3c.png)

- 一瞬怪しげなページに飛んでいるものの302ですぐにほかのページに行ってた模様。
- ソース内の現在メンテナンス中ではない「管理ユーザ管理」ページは怪しいので、直接アクセスしてみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/473d4c10-fbd7-95cf-4a6f-aec08082e885.png)

- 認証エラー画面に遷移しました。
- URLも変わってしまっていたので、これもリダイレクトしているようです。
- さっきと同じようにwiresharkで見てみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/136997b5-d2c5-8f1a-72bf-13617d53c55c.png)

- ユーザのIDとパスワードが載ってますね。
    - adminとasfjinads213

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/ea751aa6-2d95-0b89-1af8-7078b4a2d6e0.png)

- んー、何か文字化けしてます。
- 表示する文字コードを変えるところがよくわからなかったので、wiresharkで。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/d09d87b4-5ff3-1e69-56c5-42aa4d5d4b77.png)

- ということでadminとasfjinads213が答え。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/bcb90d3e-bf1c-b780-e9a9-7dba4b2ab401.png)
pandasでcsvファイルの下から数行を取り出す

上から10行だと

```python
data = pd.read_csv('file.csv', nrows=10)
```

で取り出せる。

下から10行だと少し大変。

```python
#最終行を取得する
lastRow = sum(1 for line in open('file.csv')) - 2
#最終行から10行の行数を求める。
pickRow = [lastRow - line for line in range(10)]
pickRow.reverse()
data = pd.read_csv('file.csv', skiprows=lambda x: x not in pickRows)
```
LaradockでLaravelの環境を構築する 

# 参照
https://qiita.com/rock619/items/62c2ab2252c405e26479

# Laradock
Laradockをインストールしていない人は以下を参照してください。
参照：https://qiita.com/Takuya-Hirata/items/4e8f44e57a04bf3029ed

# Laravel
<strong>workspaceに入る</strong>
```docker-compose up -d nginx mysql workspace phpmyadmin```
```docker-compose exec workspace bash```

<strong>Laravelをインストール</strong>
```composer create-project laravel/laravel myProject```
終わるまで少々時間がかかりますが、コーヒーでも飲んで待ちましょう。

<strong>インストールが終わったらworkspaceを抜ける</strong>
```exit```
```docker-compose stop```  * Dockerも一旦ストップ

<strong>.envを編集する</strong>
Laradockの.envの```APP_CODE_PATH_HOST=../```の部分を
```APP_CODE_PATH_HOST=../myProject```に変更する。

# 動作確認
```docker-compose up -d nginx mysql workspace phpmyadmin```
上記のコマンドを実行の上、http://localhost/ にアクセスする。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3135383236392f33383833646266372d306639352d373465342d313462612d3364373664656330346435652e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/321807/c20b2f81-5238-bc9e-6f7c-fd22dbea848c.png)
成功です。これで開発できます。MySQLとの接続は次で説明します。
シクシク素数列 Advent Calendar 2018 (Rust)

Rust で書いたよ

```rust
use std::io::stdin;

fn is_prime(n: u128) -> bool {
    if n <= 1 {
        return false;
    }
    for i in 2..n {
        if n % i == 0 {
            return false;
        }
    }
    true
}

fn is_4949(mut n: u128) -> bool {
    loop {
        if n == 0 {
            return false;
        }
        match n % 10 {
            4 | 9 => return true,
            _ => n /= 10,
        }
    }
}

fn solve_4949(n: usize) -> Vec<u128> {
    let mut ans = Vec::new();
    let mut i = 1;
    while ans.len() < n {
        if is_prime(i) && is_4949(i) {
            ans.push(i);
        }
        i += 1;
    }
    ans
}

fn main() {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    let n = buf.trim().parse().expect("fail parse as integer");
    let ans = solve_4949(n);
    println!(
        "{}",
        ans.iter()
            .map(|n| n.to_string())
            .collect::<Vec<String>>()
            .join(","),
    );
}

#[test]
fn test_prime() {
    assert_eq!(is_prime(0), false);
    assert_eq!(is_prime(1), false);
    assert_eq!(is_prime(2), true);
    assert_eq!(is_prime(57), false);
    assert_eq!(is_prime(97), true);
}

#[test]
fn test_4949() {
    assert_eq!(is_4949(0), false);
    assert_eq!(is_4949(1), false);
    assert_eq!(is_4949(4), true);
    assert_eq!(is_4949(9), true);
    assert_eq!(is_4949(87318112), false);
    assert_eq!(is_4949(987318112), true);
}
```

`cargo` で動かすよ

```sh
$ cargo test
   Compiling qiita4949 v0.1.0 (./qiita4949)
    Finished dev [unoptimized + debuginfo] target(s) in 1.33s
     Running target/debug/deps/qiita4949-5b899812a8ccb542

running 2 tests
test test_4949 ... ok
test test_prime ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

$ cargo build --release 
   Compiling qiita4949 v0.1.0 (./qiita4949)
    Finished release [optimized] target(s) in 0.47s
$ echo 9 | ./target/release/qiita4949 
19,29,41,43,47,59,79,89,97
$ echo 100 | ./target/release/qiita4949
19,29,41,43,47,59,79,89,97,109,139,149,179,191,193,197,199,229,239,241,269,293,347,349,359,379,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,509,541,547,569,593,599,619,641,643,647,659,691,709,719,739,743,769,797,809,829,839,859,907,911,919,929,937,941,947,953,967,971,977,983,991,997,1009,1019,1039,1049,1069,1091,1093,1097,1109,1129,1193,1229,1249,1259,1279,1289,1291,1297,1319
```

```sh
$ echo 10000 | time ./target/release/qiita4949 > /dev/null
       20.19 real        20.16 user         0.01 sys
```
遅い :cry:
（アルゴリズムが悪い）
8946 Take#51

#問題

http://www.hackerschool.jp/hack/take51.php

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/8ce6e2ed-89e3-712d-6926-8dd31b57bb0f.png)

#解いてみた

- 指定されたリンクをクリックしてみましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/5be8c42a-68d2-cd21-5e14-4ab5c8496eaf.png)

- と表示されました。
- google翻訳使います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/f0d119ba-8046-0a30-10a8-8b6a6f020072.png)

- フランス語で「アクセス不可」という意味らしいです。
- wiresharkで見てみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/f62000da-7e17-8fec-a140-7324c8f10d31.png)

- 特に変わったところはないですね。
- アクセスが無効ということはこっちのIPアドレスを見ているということでしょうか。
- となるとフランス語に合わせて、フランスのIPからアクセスすれば。。。
- Tor Browser使って何回か画面更新したらいろんな国になってできそう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/aaafed37-6419-a63e-2032-a2f67fbd20cb.png)

- ということで答えはoPHj6yK4LL53K6mpです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/a105fd82-2350-6026-12fc-f4e8584dcc25.png)
Pepperの足元にあるセンサーのカバーが取れたときの対処法

Pepperの足元にあるアレがいつの間にか取れていることってありませんか？
輸送中に外れることがあるようで、箱から取り出したときにポロッと落ちたりしているアレです。
特に見たことがない人はブラウザの戻るボタン押していただいて構いません。。
![IMG_20181205_185324.jpg](https://qiita-image-store.s3.amazonaws.com/0/321505/cb6afdae-745b-5f5f-74ea-6a7b88c3b8f6.jpeg)
コレです。

なんだこれ、と思うかもしれませんが、足元のレーザーセンサーのカバーです。
付け方がわからないと、質問を受けたので書いてみます。
Pepperは寝かして作業した方がやりやすいです。
<img width="1430" alt="“”_2018-12-05_22_11_04.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/321505/965406b4-8b11-59d4-6824-79d9605cd05c.jpeg">
まず画像のカバーを外します。
こことここのあたりに爪があります。
<img width="1429" alt="“”_2018-12-05_22_11_33.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/321505/33990591-325d-6817-07b6-c0625ef1585e.jpeg">
1つ目の爪はこの方向に力を入れて、浮き上がらせるようにすると外れます。
<img width="1411" alt="“”_2018-12-05_22_12_04.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/321505/aadc7a08-c4a0-f0b4-65cb-59992e9d8914.jpeg">
2つ目の爪も同じ方向に力を入れると外れます。
<img width="1219" alt="“”_2018-12-05_22_12_44.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/321505/b9daa489-4c8b-d6a9-ddf5-a5c76a09ac0d.jpeg">
画像のように、中に爪でひっかかっているので気をつけて外してください。
<img width="1370" alt="“”_2018-12-05_22_13_17.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/321505/e7d005a1-dc99-eba6-e5ff-c2c9ebb0725a.jpeg">
反対側も同様に行います。
<img width="1666" alt="“”_2018-12-05_22_13_43.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/321505/8f202cd5-61d8-50de-0a88-ff5db7115761.jpeg">
この状態だとまだうまくはめることが出来ません。真ん中の爪が引っかかっているからです。
<img width="1672" alt="“”_2018-12-05_22_14_16.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/321505/1dc0466f-a821-1737-6412-876597fd77ca.jpeg">
ここも画像の方向に浮き上がらせるように力を入れると外れます。
これで取れたパーツを入れる準備完了です。
<img width="1487" alt="“”_2018-12-05_22_14_59.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/321505/b4d7168c-a673-e608-dbb5-853ba0a849f3.jpeg">
センサーの位置に合わせて、爪の部分をもとに戻してパーツをはめます。
<img width="1532" alt="“”_2018-12-05_22_16_38.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/321505/6774dcba-9e49-18e5-799d-27ca010d6b4c.jpeg">
これで完了です。
あとは両側のカバーをもとに戻して完了です。
ARKitで位置情報を共有するためのモデルをCodableで作成する

昨日の[ARKitで空間共有して端末間通信する方法22選](https://qiita.com/k-boy/items/e9adf3e4b64be9ed4635)で、端末間でデータを送受信するのに使うのはCodableがベストだと書きました。

今日は具体的にそのCodableの使い方を紹介したいと思います。

# Codableとは

Swift4から使えるJSONのエンコードとデコードが簡単にできるSwift標準ライブラリです。めちゃ簡単に使えます。

以下はJSONパーサーのパフォーマンス比較表です。**Decodable**のJSONをデコードするのにかかる時間は比較的短いことが分かります。これで標準なんだから使わない手はないですね。(Codableの型は`Decodable & Encodable`)

![json](https://raw.githubusercontent.com/bwhiteley/JSONShootout/master/images/performance.png)
[^1]

- 参考: [Swift4 Codableがすごすぎた件](https://qiita.com/UJIPOID/items/2c436a80f1167f7bcac0)

# 基本Entity

それではARKitの位置共有で使うための基本データをCodableに準拠させてどう作っていくのか紹介します。

## Vector3Entity

位置座標x, y, zやオイラーアングルはSCNVector3で表されるのでそれに対応するEntityを作ります。

```swift
struct Vector3Entity: Codable {
    let x: Float
    let y: Float
    let z: Float
}
```

## Vector4Entity

4*4行列の要素や、rotationのSCNVector4に対応するために、対応するEntityを作ります。

```swift
struct Vector4Entity: Codable {
    let x: Float
    let y: Float
    let z: Float
    let w: Float
}
```

# 実践的なEntity

## PlayerEntity

例えばデバイス間で各自のデバイス位置を共有したいとき、以下のようなPlayerEntityを作って座標(position)と向き(eulerAngles)を共有します。

```swift
struct PlayerEntity: Codable {
    let position: Vector3Entity
    let eulerAngles: Vector3Entity
}
```

## TransformEntity

4*4行列を送受信するためのEntityを作ります。このtransformはデバイス間で座標合わせをするときに必要なことが多いです。(参考: [ARKitで空間共有して端末間通信する方法22選](https://qiita.com/k-boy/items/e9adf3e4b64be9ed4635))

```swift
struct TransformEntity: Codable {
    let column0: Vector4Entity
    let column1: Vector4Entity
    let column2: Vector4Entity
    let column3: Vector4Entity
}
```

# ARKitにおける位置情報共有の例

## 送信する側

例えばARSCNViewDelegateの`renderer(:updateAtTime`は毎フレームごとに呼ばれるので、ここでカメラの位置を取得して毎フレームごとに相手に送信することができます。（毎フレームごとに送るべきかは置いといて）

```swift
// MARK: - <#ARSCNViewDelegate#>
extension CameraViewController: ARSCNViewDelegate {
    func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
        guard let camera = sceneView.pointOfView else {
            return
        }
        // TODO: PlayerEntityのイニシャライザ作っとく
        let entity = PlayerEntity(position: camera.position,
                                  eulerAngles: camera.eulerAngles)
        let data: Data = try! JSONEncoder().encode(entity)

        // TODO: dataを送る
        
    }
    
```

## 受信する側

repositoryというクラスに相手からデータを受け取ったときに発火するonEventというクラスを用意したとして、以下のようにそのobjectをparseすることができます。

```swift
repository.onEvent { object in
    guard let data = object as? Data else {
        return
    }
    
    do {
        let decoder: JSONDecoder = JSONDecoder()
        let entity: PlayerEntity = try decoder.decode(PlayerEntity.self, from: data)
        // これを使って相手のデバイスを空間上で再現する
        let position = entity.position
        let eulerAngles = entity.eulerAngles
    } catch {
        
    }
}
```

# まとめ

以上のようなパターンでデバイス間で位置情報を共有することができます。位置情報アプリを作りたい方の参考になれば幸いです。

[^1]: https://github.com/bwhiteley/JSONShootout
君たちはCインタプリタを知っているか？

#むかしむかし、DOSで動くCインタプリタがありました

その名も`C-terp`。
探してみたらありました。
[ここ](http://www.softwarepreservation.org/projects/interactive_c/cterp/cterp/)です。

なんと、ダウンロードできるところも発見しました。[ここ](http://vetusware.com/download/C-Terp%20v3.02%20v3.02/?id=7970)です。

うーむ。でも、DOS環境がない。Windows10の環境でも動くのかなぁ。
RubyMineを感動的にする便利なショートカットとキーマップを紹介

![Alt text](https://i.gyazo.com/1f3de4b14367b8fd4ca0ce833e234dea.png)


JetBrainのIDEであるRubyMineですが、ショートカットを設定することで圧倒的に便利になります。個人的におすすめのショートカットとキーマップを紹介します。

まだRubymineをインストールしていない方は[こちら](https://pleiades.io/help/ruby/install-and-set-up-product.html)から。


# ショートカットの設定方法（keymapの設定）
RubyMineの`preferences`を開きメニューからKeymapを選択します。この画面でショートカットを設定していきます。

![Alt text](https://i.gyazo.com/ae03984666a1a5ca0bef315d6397eecb.png)


# 画面を縦に分割：Split Vertically
画面を縦に分割<br>

- おすすめkeymap :  `shift + command + v`

![Alt text](https://i.gyazo.com/b681369dd28be796ebbf7aa514bda884.gif)

# 画面を横に分割：Split Horizontally

- おすすめkeymap :  `shift + command + h`

![Alt text](https://i.gyazo.com/c26b87ae904f119c90ffe88ccb79c88f.gif)


# 分割した画面間の移動：Goto Next Splitter、Goto Previous Splitter
分割後の画面を行き来することができるようになります。

- おすすめkeymap :  `shift + command + j`、`shift + command + k`

![Alt text](https://i.gyazo.com/5c9e6e34e8bc853a129764cfdb7c5f7e.gif)



# コードジャンプ：Jump to Source
ソースに移動することができます。デフォルトでは`command + click`ですが、とても良く使うのでショートカットを設定しておくと非常に便利です。

- おすすめkeymap :  `F2`

![Alt text](https://i.gyazo.com/3387d6179bd9676b18c1102cdcb4f6cf.gif)


# 前の画面に戻る：Back
こちらもよく行う動作なので、絶対に設定しておきたいショートカットです。

- おすすめkeymap: `alt + command + ←`

![Alt text](https://i.gyazo.com/987960b9c800c3d21d5d0042dcefe1d9.gif)



# 拡張・縮小選択：Extend Selection ・ Shrink Selection
特定の範囲の選択を一発ですることができるようになります。単語やセンテンスをコピーすることが多い時に非常に役立ちます。

- おすすめkeymap: `shift + command + ↑`、`shift + command + ↓`

![Alt text](https://i.gyazo.com/d85631b83d10da56661ada2fe18e7838.gif)



# プロジェクト・ディレクトリ全体検索
プロジェクト全体や特定のディレクトリ以下など指定をして検索を実行することができます。

- おすすめkeymap: `shift + command + f`

![Alt text](https://i.gyazo.com/277df6d262e931b7a41cf1c2b5d8861a.gif)


# コード整形：Reformat Code
コードを整形してくれます。

- おすすめkeymap: `alt + command + l`

![Alt text](https://i.gyazo.com/dd1ea9e97648f7f57c0fa9e9e59b65c1.gif)




# model・controller・viewにジャンプする：Switch to Model、Controller、View
命名規則通りに作成されている場合に、model、controller、viewを行き来することができます

- おすすめkeymap(model): `control + m`
- おすすめkeymap(controller): `control + c`
- おすすめkeymap(view): `control + v`

![Alt text](https://i.gyazo.com/b20f9f5134ac891889cf5fb8d13b4cbb.gif)



# 左右のタブを移動する：Select Previous Tab・Select Next Tab
ソースファイルの左右のタブを移動することができます。こちらかなり使うことが多いショートカットです。また、キーマップの割り当てとしては、Chromeのショートカットと合わせているので、普段から使い慣れていくことができます！

- おすすめkeymap(previous tab):`shift + command + [`
- おすすめkeymap(next tab):`shift + command + ]`

![Alt text](https://i.gyazo.com/2def6c6dbd5c6981d6dfcec9c4cd5bfe.gif)

# ファイル名検索

- keymap： shiftを2回



# おすすめのショートカット教えて下さい

この他にみなさんが使っているショートカットでおすすめのものがあれば教えてください！
Raspberry PiとArduino UnoのUSBシリアル通信

# 概要
Raspberry PiとArduinoのUSBシリアル通信をしました。

Raspberry Pi側はPythonとC++の２通りで作成しました。
またProcessingも作成しましたが、こちらはUbuntuでしか確認していません。

内容は、Raspberry Pi/Ubuntuから文字列を送信し、Arduinoでは受信した文字列に文字を加えて送り返す、というものです。

# 環境
- Arduino
    - Arduino Uno  
    - Arduino 1.8.9
- Raspberry Pi
    - Raspberry Pi 3 Model B++
    - Raspbian 9.3
    - GCC 6.3.0
    - cmake 3.7.2
    - Python 3.5
- PC
    - Ubuntu 16.04
    - Processing 3.3.7
- その他
    - Raspberry Pi/UbuntuとArduinoはUSBケーブルで接続

# プログラム
ソースコードと使い方は[GitHub](https://github.com/hiro-han/sandbox)にあります。
Clingをコンパイルしてみた

#Clingをコンパイルしてみたよ（備忘録）

##環境その１

- Windows10
- WSL
- Ubuntu

##環境その１におけるコンパイル手順

###（１）UbuntuをWindows10にインストール

- 「Windowsの機能の有効化または無効化」をクリック。
- 「Windows Subsystem for Linux」をチェックしてOKボタンを押し、一旦Windows10を再起動する。
- Microsoft StoreからUbuntuをインストールする。

###（２）apt-getのアップデート
```
sudo apt-get update
```

###（３）Pythonのインストール
（Python3は既にインストールされているが、CMakeでPythonが無いと怒られたので、）
最低限のPythonをインストールしておいた。

```
sudo apt-get install python-minimal
```

###（４）CMakeのインストール

```
sudo apt-get install cmake
```

###（５）clone.shの実行

CERNの[ここ](https://root.cern.ch/cling-build-instructions)から、[build script](https://raw.github.com/karies/cling-all-in-one/master/clone.sh)をクリックしてclone.shをダウンロードする。
でもって、次のコマンドを入力する。

```
　　chmod +x clone.sh
　　./clone.sh
```
あとはじっと待つだけ。
おしまい。

#【おまけ】環境その２　MacOS High Sierra


- MacOS High Sierra

##環境その２におけるコンパイル手順

###（１）clone.shを実行しただけで問題なく動作した。
おしまい。

---
ごめんなさい。誤りを一部訂正しました。
【誤】sudu
【正】sudo
スクロールバーのデザインをいろいろ弄って遊んでみる。

# tl;dr
+ 味気ないスクロールバーをcssでデザインして遊ぶ。 :pencil2:  :pick:

## 百聞は一見に如かず。

<p data-height="500" data-theme-id="dark" data-slug-hash="QJRepq" data-default-tab="html,result" data-user="lemon2003" data-pen-title="Scrollbar Design Test" class="codepen">See the Pen <a href="https://codepen.io/lemon2003/pen/QJRepq/">Scrollbar Design Test</a> by lemon2003 (<a href="https://codepen.io/lemon2003">@lemon2003</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

グラデとかの使い方間違ってる？ 
~~ダｓｓｓｓっさ。~~ :scream: :scream_cat: :sob:

## 解説
### `::-webkit-scrollbar`
`width` で縦スクロールバーの幅、
`height` で横スクロールバーの高さを指定できる。

### `::-webkit-scrollbar-track`
スクロールバー全体のスタイルを指定する。

### `::-webkit-scrollbar-thumb`
*thumb* は **親指** :thumbsup: 。

スクロールするときにマウス(カーソル)でつかむところ。

### 参考
+ [Webkit独自拡張でスクロールバーのデザインを変更する ｜ DevelopersIO](https://dev.classmethod.jp/client-side/webkit-scrollbar-design/)
+ [スクロールバーをデザインする ::-webkit-scrollbar に関しての覚え書き | Unformed Building](http://unformedbuilding.com/articles/learn-about-webkit-scrollbar/)

### 最後に & お願い
`-webkit` とついているように、chromeなどでのみ動きます。
~~firefoxもなんかいろいろ弄ればできるっぽいけど、今回は割愛。（書き足すかも？）~~

#### 追記 at:2019/01/05
*Firefox 64* (2018/12/11 released) より、プレフィックスなしでのサポートになっています。
[Can I use... Support tables for HTML5, CSS3, etc](https://caniuse.com/#feat=css-scrollbar)

コメントありがとうございます！: [コメントより](#comment-63160cb3364c8588e728)

---

こんなこともできるよっていう風にいろいろcss弄ったけど、センスのないものしかできなかったので、
いいデザインができたら、こんなのどう？っていう感じでコメントしていただければ幸いです！ (完全に丸投げ。)
wxPythonを使った画面遷移

#環境
・Windows10
・Python 3.6.7
・wxPython 4.0.3


#概要
wxPythonを使って複数の画面をたくさんのWindowを生成せずに複数画面を作成するのが目的です。
frameのルートの要素にBoxSizerを追加して画面遷移が発生するたびに各要素を削除してsizerに追加しなおすという形式で画面遷移しました。



#ソースコード
```Python3:screen_transition.py
import wx

class mainFrame(wx.Frame):
	def __init__(self):
		super().__init__(None, wx.ID_ANY, 'Testapp', size=(900,500), style=wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN)

		self.CreateStatusBar()
		self.SetStatusText('Testapp')
		self.GetStatusBar().SetBackgroundColour(None)

		self.sizer = wx.BoxSizer(wx.VERTICAL)
		self.SetSizer(self.sizer)

		self.set_screen(Panel_1)


	def set_screen(self,panel):
		self.sizer.Clear(False)
		self.DestroyChildren()

		self.now_panel=panel(self)
		self.sizer.Add(self.now_panel,1,wx.EXPAND)
		self.sizer.Layout()



class Panel_1(wx.Panel):
	def __init__(self, parent):
		super().__init__(parent, wx.ID_ANY)
		self.parent=parent

		title_text = wx.StaticText(self, wx.ID_ANY, 'タイトル', style=wx.TE_CENTER)
		font_Title = wx.Font(24, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
		title_text.SetFont(font_Title)

		start_button = wx.Button(self, wx.ID_ANY, 'スタート')
		start_button.Bind(wx.EVT_BUTTON, self.click_start_button)

		layout = wx.BoxSizer(wx.VERTICAL)

		layout.Add(title_text, flag=wx.ALIGN_CENTER)
		layout.Add(start_button, flag=wx.ALIGN_CENTER)

		self.SetSizer(layout)

	def click_start_button(self, event):
		self.parent.set_screen(Panel_2)


class Panel_2(wx.Panel):
	def __init__(self, parent):
		super().__init__(parent, wx.ID_ANY)
		self.parent=parent

		title_text = wx.StaticText(self, wx.ID_ANY, '遷移後画面', style=wx.TE_CENTER)
		font_Title = wx.Font(24, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
		title_text.SetFont(font_Title)

		start_button = wx.Button(self, wx.ID_ANY, 'スタートに戻る')
		start_button.Bind(wx.EVT_BUTTON, self.click_start_button)

		layout = wx.BoxSizer(wx.VERTICAL)

		layout.Add(title_text, flag=wx.ALIGN_CENTER)
		layout.Add(start_button, flag=wx.ALIGN_CENTER)

		self.SetSizer(layout)

	def click_start_button(self, event):
		self.parent.set_screen(Panel_1)

if __name__ == '__main__':

	application = wx.App()
	frame = mainFrame()
	frame.Show()
	application.MainLoop()

```
【ざっくり理解する】AWSによるサーバーレスアーキテクチャ

# 概要
サーバーレスアーキテクチャを理解したかったので、「[AWSによるサーバーレスアーキテクチャ](https://www.amazon.co.jp/AWS%E3%81%AB%E3%82%88%E3%82%8B%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%83%AC%E3%82%B9%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3-%E9%95%B7%E5%B0%BE-%E9%AB%98%E5%BC%98-ebook/dp/B079VL58FG/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=&sr=)を読んだ。
「サーバーレスアーキテクチャとはどういうものか」がざっくり理解できたので、概要レベルでまとめる。

## サーバーレスアーキテクチャとは
サーバーレス≠サーバーがない
サーバーレス=サーバー管理が不要

サーバーレスアーキテクチャとは、プロビジョニングやメンテナンスが必要なく、スケーラビリティも確保されているアーキテクチャのこと。
ただし、厳密な定義はない。

## AWS + Firebaseでの具体例
![Serverless Diagram.png](https://qiita-image-store.s3.amazonaws.com/0/233620/1a11db22-fbf7-2f58-fb2d-0aedc2176153.png)

フロントエンドが直接サービス、データベースにアクセスする。一部のサービスはAPIGatewayを介してコンピュートサービス関数(AWS Lambda)の背後に隠し、この関数の中で追加的にセキュリティ関連の操作や正当性チェックを行う必要がある。

## FaaSについて
FaaSはサーバーレスアーキテクチャの根幹をなす技術。

Faas = Function as a Service
Function、つまり関数を実行できる環境のこと。開発者はコードを書くだけで実行することができる。
特徴

* コードは、イベントがトリガーとなり実行される(イベントドリブン方式)
* コードはコンテナ上で実行され、実行後破棄される
* 料金は使った分だけなため、サーバーを立ち上げている時間請求されるIaasよりもコスト削減が期待できる
AWSでは、AWS LambdaがFaasに該当するサービス。


## サーバーレスアーキテクチャの原則
* オンデマンドでコードを実行するために、（サーバーではなく）コンピューティングサービスを使う
* 目的が１つでステートレスな関数を書く
* プッシュベースのイベント駆動パイプラインを設計する  
例) 動画をアップロードすると、違う形式に変換し保存するサービス  
動画のアップロード  
→トランスコードジョブの作成(AWS Lambda)  
→動画のトランスコード(Amazon Elastic Transcoder)  
→トランスコード済みの動画の保存(Amazon S3)
* サードパーティサービスを活用する
* より厚く、より強力なフロントエンドを作る(SPA)

## メリット・デメリット
### メリット
* プロビジョニングやメンテナンスなどのサーバー管理が不用
* 低コスト(EC2など他のクラウドサービスと比較して)
* 開発時間短縮
* 実装がシンプル、コード量減る可能性がある
* スケーラブルで柔軟、並列処理が得意

### デメリット
* レイテンシーに厳しい制約のあるAPIには向かない
* ベンダーロックイン
* パブリッククラウドが提供できる水準よりも高いパフォーマンス、信頼性が求めらえるミッションクリティカルサービスに向かない
* サービス分散化による、リモート呼び出し、ネットワーク越しのエラー処理、レイテンシーの増加
* OSのカスタマイズやその下のインスタンスの調整はできない
ヤマハRTX830 の設定

既存のルータをヤマハRTX830と置き換えることにした。

設定はWeb GUIとコマンドで行う方法がある。
Web GUIでは設定できないパラメータ(DHCPの割当予約)があるためコマンドによる設定を行う。

## 1. telnetで接続
192.168.100.1にtelnet接続する。

```
RTX830 Rev.15.02.01 (Thu Jun 22 16:17:56 2017)
Copyright (c) 1994-2017 Yamaha Corporation. All Rights Reserved.
To display the software copyright statement, use 'show copyright' command.
AA:BB:CC:DD:EE:FF, AA:BB:CC:DD:EE:FF
Memory 256Mbytes, 2LAN
> 
```

## 2. ユーザー変更
以下のコマンドを実行し、管理ユーザにスイッチする。

`administrator`

```
> 
> adadministrator 
Password: 
# 
```

## 3. LANポート1のIPアドレス変更
既存のルータとRTX830を置き換えるにあたってデフォルトゲートウェイのアドレスを合わせたいため、以下のコマンドを実行しルータのIPアドレスを変更する。

`ip lan1 address 192.168.10.1/24`

```
> 
> ip lan1 address 192.168.10.1/24

```

実行するとルータのIPアドレスが変更され、telnet通信が切断される。
前回のセッションがタイムアウトするまでしばらく時間を置いてから192.168.10.1に再度telnetする。


## 4. DHCPの設定
DHCPの割当範囲を100から開始させて、予約 & 空きはいつでも使える状態にしておきたかったが、設定がよくわからなかった。

今回は以下のように設定した。

範囲 | 用途
:---: | :---:
192.168.10.1-192.168.10.99 | 予約 & 空き 
192.168.10.100-192.168.10.199 | クライアント割り当て


administratorでログインした状態で以下を実行する。

```
dhcp service server
dhcp server rfc2131 compliant except remain-silent
dhcp scope 1 192.168.10.1-192.168.10.199/24 except 192.168.10.8-192.168.10.99

dhcp scope lease type 1 bind-priority
dhcp scope bind 1 192.168.10.2 ethernet AA:BB:CC:DD:EE:FF
dhcp scope bind 1 192.168.10.3 ethernet AA:BB:CC:DD:EE:FF
```

設定を保存する。

```
save
```

## 余談
公式サイトの手順に沿ってDHCPを`bind-only`で設定したらアドレスが割り当てできなくてあれってなった。

参考 : 
[http://www.rtpro.yamaha.co.jp/RT/docs/dhcp-auth/index.html:title]
Vim 保存時のタイポで']'が作られてしまうことを防ぐ

# はじめに

この記事は[Vim Advent Calendar 2018](https://qiita.com/advent-calendar/2018/vim) 6日目の記事です。

私はタイプミスが多いです。
よくやらかしてしまうのが、ファイル保存時の`:w`を`:w]`とタイポしてしまい、
カレントディレクトリに`]`という不要なファイルを作ってしまうことです。

色々試したり、教えてもらったりして`]`を作らない(個人的には)ベストな方法に
辿りついたので備忘録もかねて以下に記載していきます。
(~~タイプミスをなくせという批判は無視~~)

## 1. autocmdを使う

Vimにはモード変更や、ファイルオープンなどのイベントをフックし、自動でコマンドを実行する仕組みが存在します。
以下ではファイル保存前(`BufWritePre`イベント発生後)にファイル名をチェックし、
不適切なファイル名(`]`)であればファイル保存を無効にしています。

``` vim

augroup vimrc_augroup
  " expand('<amatch>:t') でファイル名
  autocmd!
  autocmd BufWritePre * if expand('<amatch>:t') == ']' | throw "oops!!" | endif
augroup END

```

一見するとうまくいっているように見えるかもしれませんが、
`throw "oops!!"`という部分が綺麗ではありません。

現状のVimでは自動コマンドの停止(今回で言うところのファイル保存無効化)を行う術がないようで、
ワークアラウンドとして、throwを使い例外を投げて無理やり処理を止めていますが、
throwした後も以下のようなエラーメッセージが表示され、とても美しくありません
![20181205-203458.png](https://qiita-image-store.s3.amazonaws.com/0/60509/957bf7a9-8583-8098-57ee-347dba897eac.png)
もっと綺麗な方法がないか調べてみましたが、
ググったりヘルプを見てみても別の方法が全く分からなかったので、
VimのSlackで質問してみたところ、以下2つの方法を教えていただきました。

## 2. tyru/stoptypofile.vim を使う

実は自分が解決したい問題にドンピシャなプラグイン[tyru/stoptypofile.vim](https://github.com/tyru/stoptypofile.vim/commits/master)が既に存在しました。

このプラグインでは`:w]`だけでなく、`:w hogehoge]`等保存時のファイル名の末尾に特定のキーワードが付いた場合、
その名前で保存してよいかを確認してれます。
![20181205-214112.png](https://qiita-image-store.s3.amazonaws.com/0/60509/f362b868-38c2-7f09-8f4b-445749bfcb7c.png)
デフォルトでは`[]/`という3つのキーワードを使ってチェックしていますが、
`g:stoptypofile_autocmd_chars`の設定を変えることで任意のキーワードに変更することできます。

また、特定のプラグインでは特別なバッファ名(例: [qfreplace], fugitive://, etc..)
を使用しているケースがありますが、チェック対象から除外したい文字列は`g:stoptypofile#ignore_pattern`に指定しておくことができます。(正規表現で指定可能)

不便だと感じたことは大抵誰かが解決ずみですね。素晴らしい世の中。
私は以下に記載するもう1つの方法で問題を解決したのでこちらのプラグインを使っているわけではないのですが、
stoptypofile.vimを使えばかなり柔軟にタイポを検出できるので、お勧めです。

## 3. 短縮入力(Abbreviations)をタイポ制御に使う

結論から記載すると、以下をvimrcで設定するだけで解決することができます。

``` vim
cnoreabbrev w] w
```
とっても簡単ですね。私はこれを自分のvimrcに記載しています。

ちょっとだけ説明すると、Vimには短縮入力を行う機能が備わっています。

``` vim
" '#in'入力後に非キーワード文字(<Space>, <CR>等)を押すと '#include' に展開する設定
inoreabbrev <buffer> #in #include
```

この短縮機能をつかってコマンドラインモードでの`w]`を`w`に展開しているだけです。
もし`:w]`とタイポしてしまってもちゃんと`:w`に展開してくれるので、意図した通りにファイルを保存することができます。

# 最後に

``` vim
augroup vimrc_augroup
  autocmd!
  autocmd BufWritePre * if expand('<amatch>:t') == ']' | throw "oops!!" | endif
augroup END
" ↓
cnoreabbrev w] w
```

修正前よりも修正後のほうが綺麗に短く記載することができました。
満足。
MacでOSイメージをSDカードに焼く

## はじめに
- Raspberry Piで使うためSDカードにOSイメージを書き込もうと思ったのですが手順を忘れかけていました
- そう頻繁にやる作業でもないので次回も忘れるであろうと思い手順を書いておくべきだと思いました
- 環境はMacです


## ディスクを特定する

- SDカードを指す前にdiskutilコマンドを実行する

```bash
$ diskutil list
/dev/disk0 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *500.3 GB   disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:                 Apple_APFS Container disk1         371.0 GB   disk0s2
   3:                  Apple_HFS BOOTCAMP                128.3 GB   disk0s3

/dev/disk1 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +371.0 GB   disk1
                                 Physical Store disk0s2
   1:                APFS Volume Macintosh HD            119.7 GB   disk1s1
   2:                APFS Volume Preboot                 43.9 MB    disk1s2
   3:                APFS Volume Recovery                1.0 GB     disk1s3
   4:                APFS Volume VM                      3.2 GB     disk1s4
```


- SDカード指して再度diskutilコマンドを実行

```bash

$ diskutil list
/dev/disk0 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *500.3 GB   disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:                 Apple_APFS Container disk1         371.0 GB   disk0s2
   3:                  Apple_HFS BOOTCAMP                128.3 GB   disk0s3

/dev/disk1 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +371.0 GB   disk1
                                 Physical Store disk0s2
   1:                APFS Volume Macintosh HD            119.7 GB   disk1s1
   2:                APFS Volume Preboot                 43.9 MB    disk1s2
   3:                APFS Volume Recovery                1.0 GB     disk1s3
   4:                APFS Volume VM                      3.2 GB     disk1s4

/dev/disk2 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *15.5 GB    disk2
   1:             Windows_FAT_32 boot                    43.5 MB    disk2s1
   2:                      Linux                         15.4 GB    disk2s2
```

- 新たに表示されたディスクが対象のSDカードです
  - このケースではdisk2ですね


## ディスクのアンマウント
```
diskutil unmountDisk /dev/disk2
```

## OSイメージ書き込み

- ddコマンドでイメージを書きます
  - Macを含むBSD系のOSではrを頭につけるとシーケンシャルアクセスになるようなのでrdisk2のように指定しましょう
      - disk2とするとランダムアクセスになり非常に遅くなります
      - 試しにとあるイメージを書き込んでみたら処理時間が6倍もかかってしまいました
- ハイスペックな端末の場合はBSの値を大きくすると処理時間が早くなるかもしれません

### imgファイルの場合
```bash
sudo dd if=xxxxxxxx.img of=/dev/rdisk2 bs=16m
```

### xzファイルの場合
```bash
xzcat xxxxxxxx.img.xz | sudo dd of=/dev/rdisk2 bs=16m
```

### gzファイルの場合
```bash
gunzip -c xxxxxxxx.img.gz | sudo dd of=/dev/rdisk2 bs=16m
```