OmniAICreator/Qiita-1.07M huggingface dataset:
aws Kinesis Video Streams が WebRTCのサポートを開始

##awsがWebRTCのサポートを開始
https://aws.amazon.com/jp/about-aws/whats-new/2019/12/amazon-kinesis-video-streams-adds-support-for-real-time-two-way-media-streaming-with-webrtc/

WebRTCはWebブラウザでリアルタイムデータのやりとりが可能な技術で、主にSkypeのようなビデオ通話に利用されています。
Android/iOSでも利用が可能です。

ユースケースの「赤ちゃんの監視」が微笑ましい。
>Typical uses include interactive video and audio between a video doorbell or baby monitor and your mobile phone, video chat, and peer-to-peer media streaming

正しくはSTUN/TURNの提供のようです。
コンソール上にもチャネル作成の項目があります。
![Amazon_Kinesis_Video_Streams.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/af2618bb-ddf8-6df1-3fda-013d28c8fc29.png)

今まではaws+WebRTCの場合、Wowza等のミドルウェアをEC2上でセットアップして構築というイメージでしたが、数クリックで構築できるようになります。

##サンプルコードも公開されてます
https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-js/tree/master/examples

![スクリーンショット_0001-12-06_2_02_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/80eb1d1f-546c-ce19-062e-fffae01fabd8.png)

![スクリーンショット_0001-12-06_2_03_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/74936ddf-79be-4c33-00c1-1bd8348220ac.png)

https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-js#add-signaling-client-event-listeners
カメラ映像取得などはNativeなJavaScriptのAPIを利用するようです。

##オンラインドキュメント
https://docs.aws.amazon.com/ja_jp/kinesisvideostreams/latest/dg/API_Operations.html
このドキュメントで実装を進めるのは敷居が高そうです。やはりサンプルコード見ながら実装するのが最短かもしれません。WebRTCの基礎知識も必要になりそうです。

こちらにチュートリアルが記載されていました。
https://dev.classmethod.jp/cloud/aws/update-kinesis-video-streams-supports-webrtc/

##未調査（今後調査予定）
・1対Nのライブ配信系にはどの規模（同時接続数）に耐えうるか？
・録画方法
・冗長構成
・遠隔地とのビデオ通話での遅延

##類似サービス（SDK）
このaws+WebRTCの類似のサービスとしては既存の下記SDK等があります。
先行してリリースされているサービスのほうが機能面や実績では安心感がありそうです。
・SkyWay
・Twilio
・OpenTok
・[agora.io](https://hubs.ly/H0kB1_n0)

##最後に
[**agora.ioに関するお問い合わせはこちらから**](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=f46ea1c04695afc87ae7)
[<img width="912" alt="スクリーンショット 0001-08-15 13.41.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/5d815376-9b89-08fa-9434-6fa7e8e67bcf.png">](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=f46ea1c04695afc87ae7)
オーバーロード

初学者ですが、個人的な勉強のためまとめました

##オーバーロード

・オーバーロードは「メソッドの多重継承」とも呼ばれ、同名のメソッドを複数宣言できる機能のこと
・**名前が同じかつ引数（引数の数、型、順番）が異ならないと使えない**
・JVMは、実行するメソッドをを読み込むとき、メソッドだけで判断するのではなく、**シグニチャ（メソッド名と引数のセット）**で見分けるので、同名のメソッドを複数宣言できる
React環境構築 Linux mint

# VMのLinux mint上にReact環境を構築する

自宅PCのVM上に開発環境を構築する自分用の手順書です。
※　2019/12/13更新

# 環境
- OS:Linux mint 19.2
- VM:Oracle VM VirtualBox 6.0.14

# apt update & upgrade

```sh
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo reboot
```

# npm インストール

```sh
$ sudo apt-get install npm -y
$ npm -v
6.12.1
```

#nodejs インストール

npmを使って最新版のnodejsをインストールします。

```sh
$ sudo npm install n -g
$ sudo n stable
$ node -v
v12.13.1
```

# yarn インストール

※npmのみでも実行可能であるが、参考にしたサイトではyarn推奨

```sh
$ sudo npm install yarn -g
```

# ~~create-react-app　インストール~~
※バージョン変更により、テンプレートが作成出来ない不具合が発生する可能性があるためインストールはしない方がいいです。

こちらは飛ばして次の項目へ進んでください。

```sh
$ sudo npm install create-react-app -g
$ create-react-app --version
3.2.0
```

#React アプリ作成
以下の3つのどれかを実行して下さい。

```sh
$ npx create-react-app my-app
$ npm init react-app my-app
$ yarn create react-app my-app
```

Hello Worldを表示するため /src/idenx.jsを書き換える

```src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

-ReactDOM.render(<App />, document.getElementById('root'));
+var element = React.createElement('h1', { className: 'greeting' }, 'Hello, world!');
+ReactDOM.render(element, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
serviceWorker.unregister();

```

# TCP/3000番ポートを開放する

```sh
$ sudo ufw allow 3000
$ shutdown -h now
```

※ポート開放後にVirtualBoxのポートフォワーディングを設定するため一度シャットダウンする

VirtulBoxマネージャー画面から使用しているVMを選択し
設定 -> ネットワーク(NAT) -> 高度(D) -> ポートフォワーディング(P)
ルールを追加し以下のように設定する

|  名前  | プロトコル | ホストIP | ホストポート | ゲストIP | ゲストポート |
| :---: | :-------: | :-----: | :---------: | :------: | :--------:  |
| Rule1 | TCP | | 3000 | | 3000 |

# Hello World表示

create-react-appで作成したフォルダに移動してnpm or yarnでstart

```sh
$ cd my-app
$ npm start
or
$ yarn start
```

ブラウザから`http://localhost:3000/`にアクセス

# 参考サイト
https://jitaku.work/it/react/
https://qiita.com/y_ohr/items/8afd0852b24356059f2b

# 追記（2019/12/13）

```sh
$ sudo npm install create-react-app -g
```
上記で`create-react-app`をインストールしている方は、バージョンが変わりテンプレートのインストールが出来なくなる可能性があります。
`create-react-app --version`で確認し、3.3.0よりも古いバージョンはテンプレートが作成されません。

以下のコマンドを実行してアンインストールして下さい。

```sh
$ npm uninstall -g create-react-app
$ which create-react-app
/usr/local/bin/create-react-app
sudo rm -rf /usr/local/bin/create-react-app
```

以下の3つのどれかを実行して下さい。

```sh
$ npx create-react-app my-app
$ npm init react-app my-app
$ yarn create react-app my-app
```
Ubuntu起動時のエラーはブータブルUSBの抜差しで解決するかもしれないって話（自己責任で。。。）

## TL;DR  
USBメモリからUbuntuが起動できなかった際、偶々起動中にUSBを抜差ししたら起動成功してしまったので、
困ったら一度試してみてもいいかもよという話。（自己責任でお願いします）
自分の記録＋私同様にUbuntu入れてみたい、な人の助けに少しでもなったら幸福至極。
![HP-windows.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182297/1597056c-106a-4a26-7eef-71f5a9034266.jpeg)
これが、
![HP-Ubuntu.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182297/aea71219-2fc6-87ae-3635-d221305e273d.jpeg)
こうなる。

## 環境  
- Windows8.1マシン(HP 14-r229TU スタンダードモデル)
- Ubuntu Desktop 18.04.3 LTS
- USBメモリ(HIDISC USB 2.0 フラッシュドライブ 8GB 白 キャップ式 HDUF122C8G2)

## 作業記録
### 準備~起動
1. 何も考えずヤマダ電機さんで最安だったUSBメモリを調達（金欠マン）
2. [jp.ubuntu.com](https://jp.ubuntu.com/download)からisoダウンロード
3. [Ubuntuのチュートリアル](https://tutorials.ubuntu.com/tutorial/tutorial-create-a-usb-stick-on-windows#0)を参考にブータブルUSB作成
4. [Ubuntuのチュートリアル](https://tutorials.ubuntu.com/tutorial/try-ubuntu-before-you-install#2)と[こちら](https://mogi2fruits.net/blog/os-software/windows/3467/)を参考にBIOSのBoot順序を設定
5. Ubuntu起動（できない）
Boot optionからTry Ubuntu without installingを選択して起動、も失敗。  
真っ黒画面に`initramfs`プロンプトを表示して、色鮮やかなGUIの姿は見れず。
![IMG_0259.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182297/a94276e7-91a7-d065-0ea6-31a0946f9921.jpeg)

### エラーその１`BusyBox v1.27.2`
とりあえず目についたエラーメッセージでググる。
[こちら](https://qiita.com/takanemu/items/911f1943ecaf764e973d)を参考させて頂き`fsck`を叩いてみる（脳死）
Ubuntu起動（できない）
コマンドを理解せず、何となく引数を変えただけなので当然うまくいかず。
少しメッセージを広めに見て次の挑戦に。

### エラーその２`No init found`
`init`が見つからんのやなってことで、強い味方`ls`を使って`init`コマンドをさがす。
`/`直下にあるやんけってことで`/init`を試してみる、が・・・・駄目っ・・・・！
`/init`壊れてんちゃうかって思い込みで、メディアの再作成したり迷走を始めたところで、
改めてメッセージとにらめっこ。

### エラーその３`device descriptor read/64, error -110` `Unable to find a medium containing a live file system` `unable to enumerate usb device`
**なんだかUSBデバイスが怪しそうなメッセージ。てか、ずっと同じメッセージ吐かれてない？？！！**
最上部（上画像で見切れてしまってる）に上記メッセージたちが出力されてることに気づく。
ask ubuntuなどを見ていたらBIOSの設定でUSB3.0 Configuration in Pre-OSなる項目があるらしい。
何も考えず調達したUSBメモリが3.0でなく、2.0だったことも思い出し、これだ！と意気揚々と設定。
いざUbuntu起動!!!???（できなあ゛あ゛あ゛あ゛あ゛
どうしてだよお゛お゛お゛、USB3.0と2.0の設定が決め手だと思ったのになんでだよお゛お゛お゛お゛お゛。
その後もWindowsの高速起動設定を外したり、セキュアブートdisabledにしたり、
現役のWindowsマシン使ってブータブルUSB壊れてないか検証したり、
現役マシンのBIOS設定が分からなくて結局検証に時間取られたりして、諦めかける。
無職にUbuntuは過ぎた代物だったんだ。。。

### 決着は突然
かれこれ作業開始から3時間経った頃、半ば事故的な感じで**起動中にUSB抜いて差しなおしたらなぜか起動**。。
理由は不明だが、抜き差しを3回試して3回起動成功、その後差しっぱなしで1回起動失敗を確認。。
少しもやっとしてますが、何はともあれ動作が重くてイライラさせられたウザカワWindowsマシンはもういません。
ちょっとスマートになったUbuntuちゃんに転生しました。~~（物理的にはちょい重のまま）~~
JIS配列->MacのUS配列を模したキーボード配列に設定できたのも個人的にうれしいです。(AutoHotKey不要！）

## 終わりに
- **GB,SFCの裏技みたいな方法でなぜか解決してしまった**~~（ワザップもの）~~  
- 仕事や本番環境と違って気軽にBIOSの設定触ったり、コマンド叩けてなんやかんや楽しかった。  
私のような（ガチで）何も分からない勢はとりあえず古いPC持ってきてLinux入れようとしてみるだけでも、
BIOS周りもLinux、USBのこともわからないことだらけで、色々これから勉強できるぞって気持ちになるかもしれません。（無知の知）

### 後記
作業しながら空いたタイミングにMacでメモ取ってたのですが、離席したタイミングでHyperくんが再起動、
メモ丸々吹っ飛んだのはUbuntuインストール過程のどのエラーよりも私のメンタルを削っていきました。
雑多なメモを~~更に雑多に~~書き直す機会をくれたんだねありがとう！
最後に、拙い内容と文章だったかと思いますが、最後まで読んでいただいた方がいたら誠にありがとうございます。
MacのSafariでApple Pay支払いボタン押下後、iPhoneで決済完了する際に気を付けること

#条件（日本で使用する場合）
・macOS 10.12.6以降
・Safari 11.1以降
・iPhone の「設定」>「Wallet と Apple Pay」で「Mac での支払いを許可」がオンになっている
・iPhone とMac のiCloud アカウントが同じである
・**Mac と iPhone の Bluetooth がオンになっていること**

**Mac と iPhone の Bluetooth がオンになっていること**
**Mac と iPhone の Bluetooth がオンになっていること**

[Apple Pay on the Web](https://developer.apple.com/documentation/apple_pay_on_the_web) にも書いていないので注意が必要です。。
PHP7.4の新機能、FFIでGoを使ってみた

# PHP7.4がリリースされた
今回のアップデートも目まぐるしい機能が多く追加されました
機能の紹介は既にあるたくさんの記事にお任せするとして、個人的に気になっていた新機能 FFIを試してみます

# FFIとは
`Foreign Function Interface` の略でPHPで別の言語を動かせる機能です
Cなどで実装した共有ライブラリを読み込んで、利用することができます
メリットとしては実行速度が速くなることが大きいかと思われます

# FFIでGoを利用する
本題です
Goを利用するにはGoで共有ライブラリを実装する必要があります

## 何故Goを利用するのか
Cより簡単だから

## Goで共有ライブラリを作るには
- packageをmainにする
- main関数が必要
- exportする関数に `//export [function name]` のコメントを書く
- ビルド時は `-buildmode=c-shared` を付ける

今回はフィボナッチ数を計算するプログラムを用意しました
再帰を使っていて数が大きくなるほど計算に時間がかかるサンプルです

```go
package main

import "C"

//export calcFibonacci
func calcFibonacci(i uint) uint {
    if i < 2 {
        return i
    }

    return calcFibonacci(i - 1) + calcFibonacci(i - 2)
}

func main() {}
```

## ビルド
説明通り `-buildmode=c-shared` を付けてビルドします
出力ファイル名は、Windowsの場合は `*.dll` 、macOSでは `*.dylib` 、Linuxでは `*.so` でしょうか
今回はmacOSを使っているので、 `fibonacci.dylib` というファイル名を指定しました

ビルドを済ませると指定したファイル名のバイナリと同じ名前の `*.h` ファイルが生成されているはずです
このヘッダーファイルを用いることで他のプログラムから利用することができます
(今回はこのヘッダーファイルを利用しない方法で説明します)

## PHPからFFIでGoを利用する
準備が整ったのでいよいよFFIを利用します

cdef関数を利用します
一つ目の引数にC形式での関数定義
二つ目の引数に共有ライブラリへのパスを指定します

```php
$ffi = FFI::cdef(
    'extern unsigned int calcFibonacci(unsigned int p0);',
    '[PATH]/fibonacci.dylib'
);
```

あとはこのように呼び出すことができます

```php
echo($ffi->calcFibonacci(10)); // 55
```

以上がFFIからGoを利用する方法です
では、続いてどれだけ実行速度に差が出るか比較してみます

# FFIでPHPはどれだけ速くなるか

以下のような検証用プログラムを作成しました
FFIとPHPそれぞれでフィボナッチ数列を40番目まで求めるプログラムです
実行はCLIから行いました

```php
const COUNT = 40;

$ffi = FFI::cdef(
    'extern unsigned int calcFibonacci(unsigned int p0);',
    '[PATH]/fibonacci.dylib'
);

// 比較対象のPHP実装サンプル
function calcFibonacci(int $i): int {
    if ($i < 2) {
        return $i;
    }

    return calcFibonacci($i - 1) + calcFibonacci($i - 2);
}

// Go(FFI)実装の実行速度計測
$startTime = microtime(true);
for($i = 1; $i <= COUNT; $i++) {
    $ffi->calcFibonacci($i);
}
$time = microtime(true) - $startTime;
echo "Go(FFI): {$time} 秒\n";

// PHP実装の実行速度計測
$startTime = microtime(true);
for($i = 1; $i <= COUNT; $i++) {
    calcFibonacci($i);
}
$time = microtime(true) - $startTime;
echo "PHP: {$time} 秒\n";
```

## 結果
```
Go(FFI): 1.5760109424591 秒
PHP: 33.616943836212 秒
```

かなり大きな差が出ていると思います
PHPで重い処理を行う場合に、FFIはかなり強みになると感じました
static

初学者ですが、個人的な勉強のためにまとめてみました

##**静的である**
**ロード後**、クラスファイルの内容はstaticなものは**static領域**というメモリ領域に、それ以外は**ヒープ領域**に配置される
static領域に配置された**クラス変数**、**クラスメソッド**はそのクラス内で１つという位置付け。そのクラスからいくつインスタンスを生成してもインスタンスごとにメンバ変数、メソッドが割り当てられることはなく、一つのデータしか作成されない。したがって、**すべてのインスタンスで同じ値を共有**するので**インスタンスを作らなくても使える**

　**※ロード**・・・クラスファイルを読み込むこと

　**※クラス変数、クラスメソッド**・・・static修飾子が付与されたものを**クラス変数**、**クラスメソッド**、static修飾子が付与されていないものを**インスタンス変数**、**インスタンスメソッド**と呼ぶ


##staticのアクセス

staticなメンバはインスタンスの有無関係なしに使えるが、staticではないメンバは、インスタンスがないと使えない
このルールのため、staticメソッドは**staticで修飾されたもの以外にはアクセスできない**

###staticフィールド

・アクセスする方法は以下の2つ
　①**クラス名.フィールド名**
　②インスタンス作成後に**変数名.フィールド名**

・初期化する方法は以下の2つ
　①宣言時に値を設定する
　②**staticイニシャライザ**で値を設定する

　**※staticイニシャライザ**
　・static修飾子が付与されたものだけがロード時に一度だけ実行されるブロック
　・あるクラスをインスタンス化する前や、メインメソッドよりも前に呼び出し実行したい処理を記述

###staticメソッド（クラスメソッド）
・staticメソッドはそのクラスに属し、インスタンスの状態に関係なく指定された処理を行うので、汎用的に使われる処理を実装するのによく使われる

・アクセス方法
　①呼び出し
　**クラス名.メソッド名（引数、．．．）**
　②関数型インターフェースのメソッド参照
　**クラス名::メソッド名（引数、．．．）**
【色即是空】Excelで悟る、空白判定の不条理【空即是色】

##概要
Excelの空白セルの判定でハマッたが、般若心経をヒントに悟りに至る。


##要件
とある管理表にて、枝番をつける・つけないを特定のセルの数値から判定する関数を作る。

- 数値セル(B列)が空白、半角ハイフン、0、1だったら、表示セル(C列)に「経典」と表示する。
- 数値セルが2以上だったら、「経典_2」のように枝番をつける。
- 数値セルには、他のExcelファイルからデータをコピーして値貼り付けする。

要件から、表示セルに以下の関数を記入。
`="経典"&IF(B3="-","",IF(B3>=2,"_"&B3,""))`
数値セルが空白の場合、「2以上」の判定はFALSEになるため、表示セルは「経典」になる想定。


###処理の流れ（Before）
>対象が半角ハイフンか？　**YES**→　経典
>**NO**
>↓
>対象が2以上か？　**YES**→　経典_数字
>**NO** （空白セルは、2以上ではないので**NO**になる）
>↓
>経典




##事象
**数値セルが空白なのに、「経典_」と表示**されてしまう。

![excel2-1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464218/52f44945-9173-74bf-79d5-542701656a22.png)



##原因（検証は後述）
数値セルに貼り付けるコピー元のセル(X1セルとする)が、さらに他のセル(Y1セルとする)を参照しており、`=Y1&""`となっていたため。
元ファイルにおいて、Y1セルが空白(未入力)のとき、それを参照するX1セルも空白にしたいが、`=Y1`だと0が表示されて美しくないので、`&""`をつけて、空白表示にしていると思われる。


結論から言うと、**0表示回避のための`&""`が原因**だった。
`&""`によって作られた空白セルは、 「空白であり、空白でない」と判定される。
`&""`セルをコピー・値貼り付けして作った直後の空白セルも、「空白であり、空白でない」状態になる。こちらは、F2→Enterすれば「空白である」の状態になる。


##検証方法
空白を値貼り付けした直後の状態がどう扱われているかを検証。空白の調査のための関数は、Office公式サポートページからコピペした。
**Officeサポート：IFを使用してセルが空白かどうかを確認する**
https://support.office.com/ja-jp/article/if-%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%82%BB%E3%83%AB%E3%81%8C%E7%A9%BA%E7%99%BD%E3%81%8B%E3%81%A9%E3%81%86%E3%81%8B%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B-dff4eda1-6187-4b83-b7f6-4c3c0a1e2188

また、空白でないと判定された場合は、2以上かを判定している。ここで2以上と判定されると/_2のように枝番が付加されるので、これも検証。


##検証結果
C8、C9、C12にて、ふたつの検証関数で差異があり、「空白であり、空白でない」という状態に。般若心経でよく知られた、**色即是空 空即是色**そのものである。
また、これら3つと、半角ハイフンが「2以上」と判定された。
![excel2-2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464218/98d16687-e127-6dcc-e7a1-e82e3f79278a.png)


##対応
まずは、**現世の不条理「空白であり、空白でない」を受け容れる**べし。きっとExcelの仕様。

さて、元ファイルは自分の管理外のファイルなので、編集できない。自分の管理しているファイルの中で解決策を考える必要がある。

検証したとおり、当初使っていた「2以上であるか」の判定、Officeサポートに記載されている「ISBLANK関数がTRUEか」 の判定では、`&""`による空白を正しく判定できない。**空白であるかの判定としては「対象が`=""`か」が適切**であり、これを明示的に判定する必要がある。

そこで、ひとつめのIF関数に**`=""`かどうかの判定を追加**した。IF関数のネストだとゴチャつくので、最近はOR関数推し。
Before：`="経典"&IF(B3="-","",IF(B3>=2,"_"&B3,""))`
**↓**
After：`="経典"&IF(OR(B3="",B3="-"),"",IF(B3>=2,"_"&B3,""))`

これで想定通りの処理になることを確認。
![excel2-3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464218/7ecb93ad-67e2-1d33-4fcc-8a097d06aaac.png)

###処理の流れ（After）
>対象が空白（""）あるいは半角ハイフンか？　**YES**→　経典
>**NO**
>↓
>対象が2以上か？　**YES**→　経典_数字
>**NO**
>↓
>経典

##教訓
- `&""`による空白セルは不条理を生み出すと知り、扱いに注意する。空白として確実に処理するには、明示的に判定する必要がある。
- たとえOffice公式サポートの記載であっても、検証は必要。
- Qiitaには「仏教」タグがある。

##余談
元ファイルを修正できるなら、参照先のセルが空白の場合はハイフンを表示させるのもアリかも。
X1：`=IF(Y1="","-",Y1)`
プロセスとジョブについて調べた

プロセスとジョブについて無知だったので少し調べてみた

## プロセスとは
プロセスとは、メモリ上で実行状態にあるプログラム

それぞれのプロセスにはプロセスIDという一意のIDが振られ、これによって適切にプロセスを管理することができる。プロセスIDはプロセスが終了するまで変化しない。

プロセスには、ファイルのオーナーと同様に実行ユーザーが設定されており、他人のプロセスを操作することはできない。

プロセスが新しく作られる場合には、既に存在しているプロセスから、別のプロセスが作成される。元となるプロセスを親プロセス、作成されるプロセスを子プロセスと呼ぶ。具体例としてlsコマンドを実行すると、親プロセスはシェル、子プロセスがlsコマンドのプロセスになる。

Linuxではログイン中のユーザーが実行しているプロセス以外にも、Linuxシステム自体を管理するプロセスが初めから動いている。これらの多くはスーパーユーザの権限で実行されている

## psコマンド
現在動作しているプロセスを表示するコマンド。オプションなしで実行すると、現在のターミナルで実行しているプロセスだけが表示される。

実行例

```
PID TTY           TIME CMD
89124 ttys000    0:00.05 /Applications/iTerm.app/Contents/MacOS/iTerm2 --server <= Itermのプロセス
89126 ttys000    0:00.32 -zsh <= zsh関連
88296 ttys001    0:01.40 /usr/local/bin/zsh -l <= zsh関連
```

* PID: プロセスID
* CMD: 実行されているコマンド
* TTY: 実行されているターミナル

### psコマンドのオプション
psコマンドの一例を紹介

#### xオプション
現在のユーザが実行している全てのプロセスを表示する

#### aオプション
自分のプロセスだけでなく、システムで動いている全てのプロセスを表示するためには、xオプションに加えてaオプションを追加する

#### uオプション
ＣＰＵやメモリの使用率なども表示する

### よく使うオプション

psコマンドを実行する際に、頻繁に利用する機械のあるオプションの組み合わせ
#### ux オプション
psコマンドを実行したユーザの全てのプロセスを、詳細情報を合わせて表示
する
#### aux オプション
全てのユーザのプロセスを、詳細情報を合わせて表示する

## ジョブとは
シェルから見たときの処理の単位をジョブと呼ぶ(プロセスはカーネルから見たときの処理の単位)。シェルのコマンドラインに入力した１行が１つのジョブになる

実行例
`history | grep git`

* 作成されるプロセスは`hisotry`と`grep git`で2つ
* 作成されるジョブは`history | grep git`で１つ

プロセスはシステム全体で一意のプロセスIDを持つが、ジョブはシェルごとにジョブ番号を持つ。つまり、複数のターミナルを複数開き、複数のシェルを同時に利用している場合、ジョブ番号は重複する。

### jobsコマンド
現在のジョブ一覧を表示するコマンド

### ジョブの状態
#### フォアグラウンド
ユーザが対話的に操作しながら処理が実行されている状態
##### fgコマンド
ジョブをフォアグラウンドで実行するコマンド

#### バックグラウンド
ユーザが対話的に操作せずに処理が実行されている状態
##### bgコマンド
処理をバックグランドにするコマンド

#### 停止
処理を一時的に中断している状態
##### Ctrl + z
処理を一時的に停止させる

### ジョブの状態遷移のまとめ
* フォアグラウンド　=> 停止 : Ctrl + z
* バックグラウンド　=> フォアグラウンド : fgコマンド
* 停止 => フォアグラウンド : fgコマンド
* 停止　=> バックグラウンド : bgコマンド

## killコマンド
プロセスやバックグラウンドのジョブを終了させるために使われるコマンド。正確には「シグナルを送信する」コマンド。シグナルとはプロセスに送信される信号。

シグナルの種類によって「終了」「停止」「再起動」などの様々な振る舞いをする。実行中のプロセスに対してシグナルを送ることで、プロセス間で通信を行うことができる。

### killコマンドで送るシグナル
killコマンドで送信するシグナルの種類は`kill -<シグナル名>`で指定することができる。シグナル名を省略すると、デフォルト値としてTERMというシグナルを送信する。つまり、以下の２つのコマンドは同じ意味になる。

`kill 100`
`kill =TERM 100`

TERMはterminate、つまり終了を意味する。

また、シグナルにはシグナル番号がついており、オプションをシグナル番号で指定することができる。TERMのシグナル番号は15番となっており、`kill -15 100`も上のコマンドと同じ意味になる。

シグナルの種類は`kill -l`で確認することができる

```
$ kill -l
HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM URG STOP TSTP CONT CHLD TTIN TTOU IO XCPU XFSZ VTALRM PROF WINCH INFO USR1 USR2
```

フォアグラウンドのジョブに対してのCtrl + zはTSTP(停止)、Ctrl + cはINT(終了)というシグナルを送信する。
3分でわかるエディタ戦争物語

# エディタ戦争って？
> エディタ戦争(Editor War)とは、プログラミングを行う人々(特にハッカー文化に属する人々)の間で続いている、どのテキストエディタが一番よいかというテーマの論争を指す。　-wikipediaより抜粋

プログラマにとってエディタは手足、エディタは家族、エディタは生命です。どんなエディタを使うか、そしてそれをいかに使いこなすかがプログラマのステータス(自己満足)と言えるでしょう。

これはそんなエディタをめぐり、長らく続く戦争の記録です。

# エディタの歴史
## ラインエディタ時代
遥か太古、エンジニアはコマンドによってテキストを編集していました。この頃は世は全て事もなし、人々の心は安泰に包まれていたともいなかったとも言われています。とにかく、大きな争いは起こりませんでした。
ラインエディタではUnixのed系が有名です。

## スクリーンエディタ
その後、ファイルの内容を画面に表示しながら編集することができるスクリーンエディタが登場しました。そして1970年代には**vi**と**Emacs**という二つのエディタが生まれ、現代まで続くエディタ戦争の火種となりました。
### vi
1976年にビル・ジョイ氏により開発されました。ラインエディタのexを先祖に持ち、コマンド等に根強く残っています。
viの特徴は以下の通りです

- モード：
viにはコマンド、挿入、ビジュアルなど多数のモードがあり、これらを切り替えながら編集します。
- コマンド：コマンドモードでは文字列の挿入、削除、置換等を多数のコマンドを組み合わせて行います。
- 軽量：viは他のエディタと比べてコンパクトです。

現在はvimという後継が広く普及しており、Unix系OSには大抵の場合このどちらかが標準で入っています。
### Emacs
Emacsはviの少し前から同時期にMITで開発が始まりました。

- コマンド：Emacsにはモードが存在せず、コマンドは修飾キー(Ctrlなど)と他のキーの組み合わせで入力されます。
- 対応言語：多くの言語(C++等メジャーな言語からウィキペディアページの編集モードまで)がサポートされています。
- カスタマイズ：Lispでエディタをカスタムできる他、拡張機能を入れればwebブラウザやメールまで使えます。

こちらも多くの人に広まりましたが、処理系が乱立した結果viほどのまとまりはないです。
##エディタ戦争開戦
そのうちvi派とEmacs派は、お互いを批判し始めました。

### vi派の主張
 
- viはUNIX系OSには必ず含まれる。
- Emacsはカスタムしすぎて他の環境になった時使いづらいが、viはそうでもない。
- Emacsは十得ナイフであり、機能の多さのせいでリソースを使いすぎる。
- 「Emacsは優れたOSだが、優れたエディタだけが足りない。」
- viは修飾キーが無いから腱鞘炎にならない。

### Emacs派の主張

- viよりコマンドが豊富で、しかもモードに煩わされない。
- Lispにより容易に拡張できる。
- Emacsは多くのニーズに応えられる。

その後Emacs教会ができたりviカルトができたりして、エディタ界はこの二派で大別されました。
これにより情勢は安定されたかのように見えましたが...
## エディタ戦国時代
vi(とその後継であるvim)もEmacsも、CUI上で使われることが普通でした。
しかしグラフィカルのウィンドウを持つOSが普及し、今やデスクトップ用途のほぼ全てでGUIが使われています。エディタも例外ではなく、GUI上で動作するものが台頭するようになりました。
最近では以下の3つがメジャーといえます。
### Atom
GitHub開発。テーマは*"A hackable text editor for the 21st Century"*
macOS、Windows、Linux等で動作し、パッケージをインストールすることで機能をカスタマイズできる。
### Sublime Text
プロプライエタリ(商用)のエディタ。Pythonで開発されているらしい。
macOS、Windows、Linux等で動作し、ファイル検索等プロジェクト管理に強い(らしい)。
### Visual Studio Code
Microsoft開発。同社のIDEであるVisual Studioのテキストエディタ部分。
macOS、Windows、Linux等で動作し、結構早い。

# 現状
プログラミングという行為がコマンドラインで行われるとは限らないのは、今や常識となりました。
しかしvi(,m)やEmacsを未だ愛用する人も多く、vimは現在でも1位か2位の人気を誇ります。
これらの背景には、単純に好き・CUIはどんな環境でも使える・コンパイラやgit等ツールの使用がCUIからの方がやりやすい等の理由があります。
最早エディタ戦争は、作業環境におけるGUC派とGUI派の代理戦争となったのです(???)

# 感想
vimは慣れるまで苦労したが、コマンドで編集できるのは結構楽だし面白い。まだまだ訓練の余地はあるし、使えば使うほど手に馴染むエディタだ。
AtomやVS Codeなどはプロジェクト管理やwebサービスとの連携においては最早IDEとの境界も曖昧なくらい高機能だが、テキスト入力についてはコマンドは排除されショートカットくらいしかない。それってnanoと変わらなくね？
という老害っぽいことを以前話したら、友達に「Atomにも操作をvimっぽくするパッケージあるよ」と言われた。諸行無常。
Cgo を使って C 言語で書かれた関数をテストする

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

Cgo を使うと C 言語で書かれた関数を定義したり呼び出したりできます。これを使って、 C 言語で書かれた関数をデバッグしてみます。


# 背景

組込開発 (C 言語) において、 AES を用いた処理があり検算が面倒だった。 Go だと自分の中ではサクッと書けるので、 C 言語で作ったものを Go で検算するようにしてみたら快適だったので共有しようと考えた。

# Cgo とは

> Cgo enables the creation of Go packages that call C code. 
> https://golang.org/cmd/cgo/


# Cgo の簡単なサンプル

Go では `import "C"` の直前のコメントに C 言語ソースを書くことで、手軽に C 言語ソースと接続することができます。
直前に、というのがポイントで、 `import "C"` の上に空行を挟むと動かないので注意。

```go
package main

/*
int max(int x, int y) {
	return x < y ? y : x;
}
*/
import "C"

import (
	"fmt"
)

func main() {
	num := C.int(1)
	ret := C.max(num, 2)

	fmt.Println("max(1, 2) => ", ret)
	fmt.Printf("type(ret) : %T\n", ret)

	i := int(ret)
	fmt.Printf("type(i) : %T\n", i)
}
```

C で書かれた max という関数は、 Go の世界からは `C.max` という名前でコールすることが可能です。

この時点で実行すると以下のような結果になります。
戻り値は見慣れない型 `main._Ctype_int` になっていますが、 `int` 型にキャストして受け取れば問題ないです。

```
$ go build && go-cgo.exe
max(1, 2) =>  2
type(ret) : main._Ctype_int
type(i) : int
```

このような形でシンプルな C ソースは Go から簡単に使う事が出来ます。
また、 Go の関数を C からも使うことができるので、興味がある人は以下を読むと良いです。
struct を使うケースや `char *` と Go の`string` の変換なども書かれています。

https://golang.org/cmd/cgo/

# C で書かれた max 関数をテストする

上で作成した `C.max()` をテストしようとして以下のようなソースを書いたとしてもそのままでは実行できません。

```go
package main

import "testing"

func TestCgoMax(t *testing.T) {
	if g, e := 3, C.max(2, 3); g != e {
		t.Errorf("got %d, want %d", g, e)
	}
}
```

実際に実行すると以下のようになります。

```
$ go test -v
# github.com/sago35/go-cgo [github.com/sago35/go-cgo.test]
.\main_test.go:6:16: undefined: C
FAIL    github.com/sago35/go-cgo [build failed]
```

`undefined: C` と出るので、テストコード内に `import "C"` 等を書いても以下のように怒られます。 Cgo はテストコード内では使えないようです。

```
$ go test -v
can't load package: package github.com/sago35/go-cgo: use of cgo in test C:\Users\takasago.masaaki\dev\src\github.com\sago35\go-cgo\main_test.go not supported
```

ということで、 Go で wrap してみましょう。テストコード側も、新しく作った `cgoMax() ` を呼ぶようにしてみます。

```go
package main

/*
int max(int x, int y) {
	return x < y ? y : x;
}
*/
import "C"

import (
	"fmt"
)

func cgoMax(x, y int) int {
	cx := C.int(x)
	cy := C.int(y)
	ret := C.max(cx, cy)
	return int(ret)
}
```

```go
package main

import "testing"

func TestCgoMax(t *testing.T) {
	if g, e := 3, cgoMax(2, 3); g != e {
		t.Errorf("got %d, want %d", g, e)
	}
}
```

実行してみると、うまくテストできるようになりました。

```
$ go test -v
=== RUN   TestCgoMax
--- PASS: TestCgoMax (0.00s)
PASS
ok      github.com/sago35/go-cgo        0.070s
```

# まとめ

C 言語で書かれたもののテストを Go で行うことができました。
Go でライブラリを書いていると、できるだけ pure Go で書こうと思ったりしちゃうわけですが、 Cgo もとても便利なので使えるようになっておくとよさそう。
Delphiで「大石泉すき」を標準出力する

この記事は [「大石泉すき」アドベントカレンダー](https://qiita.com/advent-calendar/2019/ohishi-izumi-suki) 6日目の記事となります。
6日目は、GUIアプリケーションの開発環境であるDelphiであえて標準出力してみます。

## 概要
以下のような方を対象にした内容になります。

* 大石泉P
* 大石泉に興味がある人
* Delphiでプログラミングを始めたいと思っている人

記事内のコードは以下の環境で実行しています。

```
OS: Windows 10
Delphiバージョン: 10.3 Community Edition
```

## Delphiについて
かつてWindows用のデスクトップアプリケーション開発で勇名を馳せたGUI開発環境＆言語です。
幾多の変遷を経て、現在ではAndroid、iOSのアプリ開発も行えるようになっています。
そして、制限はあるものの無料で利用することもできます。
無料版は [Delphi 10.3 Community Edition](https://www.embarcadero.com/jp/products/delphi/starter) からダウンロードできるので是非お試しあれ。

## Delphiで標準出力
### プロジェクト設定
Delphiを起動したら `ファイル > 新規作成 > コンソールアプリケーション` でコンソールアプリケーションの雛型を作成します。

![Delphi_プロジェクト設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106217/2166dc9f-57f2-dd46-ddbc-dcc839947bf2.png)

`プロジェクト > オプション` メニューからビルド設定を変更します。
初期状態では `プロジェクトルート/Win32/Debug` ディレクトリ以下にEXEが出力されます。
ここでは分かりやすくするためにプロジェクトルート以下に出力されるように変更しています。

![Delphi_出力先設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106217/79a59876-362d-699b-564c-0a01d8ca0da5.png)

プロジェクトの基本設定を終えたら、標準出力の実装です。
プロジェクトファイル(拡張子が `dproj` )に実装します。
プロジェクトファイルは他の言語のmain関数のようなものととらえてください。

`Writeln` 命令に引数で文字列を渡せば標準出力に文字列の内容が出力されます。
`Ctrl + F9` でコンパイルしてEXEを出力します。

```pascal
program BitPerformer;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

begin
  Writeln('大石泉すき');
end.
```

プロジェクトのルートディレクトリ直下にEXEファイルが出力されます。
コマンドプロンプトにて `dir` コマンドで確認してください。

![EXE出力.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106217/dfae5110-bcbe-6ddd-b81d-c7356d6283ac.png)

EXEファイル名を入力すると `大石泉すき` と出力されます。

![出力.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106217/f0bf3d5a-e7c1-c91b-4b21-ca9eb755b768.png)

### 引数で指定した回数だけ出力する
このままでは面白味がないし、 **ビット・パフォーマー** とは言えないので少しコードを追加します。
コマンドラインアプリケーションと言えば引数での挙動の変化が醍醐味なので引数で指定した回数だけ出力するように変更します。

```pascal
program BitPerformer;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

var
  n, i: Integer;

begin
  if ParamCount >= 1 then begin
    n := StrToIntDef(ParamStr(1), 1);
    if n > 5 then begin
      n := 5;
    end;
  end else begin
    n := 1;
  end;

  for i := 1 to n do begin
    Writeln('大石泉すき');
  end;
end.
```

1～5の値を指定するとその回数分だけ、6以上の値を指定した場合は5回、引数が無い、または数値以外の文字列を指定した場合は1回だけ出力するという実装です。
Delphiの言語仕様を知っている人は少ないと思うので以下にポイントとなるワードの解説を記しました。

```
ParamCount: 引数の数
ParamStr: 引数を格納したリスト(インデックス0はアプリケーション名になる)
StrToIntDef: 渡された文字列を整数に変換する、変換できない場合は指定した値を返す
```

以下が実行結果になります。

![複数回出力.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106217/1a028608-a632-847a-4a3d-28d9f2f26ae1.png)
Node.jsでBASIC認証.

# Node.jsでBASIC認証

Node.jsでexpressを使ったWebサーバでBASIC認証を導入する場合の実装方法について紹介します．
本記事上では，パスワードを暗号化・ハッシュ化せずにソースコード上に記載しております．セキュリティ上望ましくない点にご注意ください．

# BASIC認証の導入
expressでBASIC認証を導入するには[express-basic-auth](https://www.npmjs.com/package/express-basic-auth)を使用します．下記がそのサンプルコードです．

```javascript
const express = require("express")
const basicAuth = require("express-basic-auth")

// 正解のユーザ名とパスワード
const correctUserName = "hiroyky"
const correctPassword = "password"

const app = express();
app.use(basicAuth({
    challenge: true,
    unauthorizedResponse: () => {
        return "Unauthorized" // 認証失敗時に表示するメッセージ
    },
    authorizer(username, password) => {
        const userMatch = basicAuth.safeCompare(username, correctUserName)
        const passMatch = basicAuth.safeCompare(password, correctPassword)

        return userMatch & passMatch
    }
}))
```

``basicAuth``をexpressのミドルウェアとして登録しています．引数のオブジェクト中の``authorizer``に認証用関数を書きます．戻り値がtrueの場合，認証OK，falseなら否認です．

このとき注意したいのが公式ドキュメントにもあるように下記の記載です．内容としては以下の実装を推奨しています．素直に従っておきましょう．

- 比較に``===``や``==``といった演算子を用いない，``safeComapre``関数によって比較する
- ``return userMatch & passMatch``のように論理演算によって値を出力する

> When using your own authorizer, make sure not to use standard string comparison (== / ===) when comparing user input with secret credentials, as that would make you vulnerable against timing attacks. Use the provided safeCompare function instead - always provide the user input as its first argument. Also make sure to use bitwise logic operators (| and &) instead of the standard ones (|| and &&) for the same reason, as the standard ones use shortcuts.

これで，ひとまずBASIC認証を導入することができました．
Maplat CoreでAPIから地図表示を切り替える

Maplat Advent Calendar 5日目は、Maplat CoreでAPIから地図表示を切り替える方法です。

今日の動くものはここで確認できます。 => [CodeSandBox Maplat Advent Calendar day 5](https://codesandbox.io/s/maplat-advent-calendar-day5-u2lio)

まずは、地図を切り替えるボタンを追加するために、`html`と`css`に少し手を入れましょう。

```index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Maplat Advent Calendar Day5</title>
    <link rel="stylesheet" href="app.css" />
  </head>
  <body>
    <div class="mainview">
      <div id="map_div"></div>
    </div>
    <div class="button">
      <button id="gsi">GSI</button>
      <button id="osm">OSM</button>
      <button id="ojo">御城図</button>
      <button id="aki">秋元</button>
    </div>
  </body>
  <script src="app.js"></script>
</html>
```

```app.css
.mainview {
  position: absolute;
  top: 5%;
  bottom: 5%;
  left: 5%;
  right: 5%;
}
.button {
  position: absolute;
  top: 95%;
  bottom: 0%;
  left: 5%;
  right: 5%;
}
```

うーん、「私は`css`苦手でござい」というのがひしひしと伝わる`css`ですね。
やってることは、地図領域の真下にボタン4つ並べているだけです。

続いて、せっかく地図を切り替えるのですから、地図の数も少し増やして、2つから4つにしてみましょう。

```apps/maplat_ac_day5.json
{
  "home_position": [139.5321, 36.249302],
  "default_zoom": 17,
  "start_from": "tatebayashi_ojozu",
  "sources": [
    {
      "mapID": "tatebayashi_ojozu",
      "setting_file": "https://s.maplat.jp/r/tatebayashimap/maps/tatebayashi_ojozu.json"
    },
    {
      "mapID": "tatebayashi_castle_akimoto",
      "setting_file": "https://s.maplat.jp/r/tatebayashimap/maps/tatebayashi_castle_akimoto.json"
    },
    "osm",
    "gsi"
  ]
}
```
ご覧の通り、`tatebayashi_castle_akimoto`と`gsi`の2つの地図設定が`sources`に追加されています。
`tatebayashi_castle_akimoto`は、[ぷらっと館林](https://s.maplat.jp/r/tatebayashimap/)でやはり定義されている、秋元家支配時代の館林城の絵図です。
今日もやはり、地図自体の設定ファイルの詳細説明は後日に回します。
`gsi`は、`osm`同様設定がプリセットされているベース地図で、地理院地図を表しています。

この4つの地図の間で、表示を切り替えてみましょう。
`Javascript`ロジックはこのような感じになります。

```app.js
import "@maplat/core/dist/maplat_core.css";
import { MaplatApp } from "@maplat/core";

var option = {
  appid: "maplat_ac_day5"
};

var app = new MaplatApp(option);
app.waitReady.then(function() {
  document.getElementById("gsi").addEventListener("click", function(e) {
    app.changeMap("gsi");
  });
  document.getElementById("osm").addEventListener("click", function(e) {
    app.changeMap("osm");
  });
  document.getElementById("ojo").addEventListener("click", function(e) {
    app.changeMap("tatebayashi_ojozu");
  });
  document.getElementById("aki").addEventListener("click", function(e) {
    app.changeMap("tatebayashi_castle_akimoto");
  });
});
```
`app.waitReady`でMaplatアプリが動作レディになるのを待った後、各ボタンに`click`イベントハンドラが与えられ、そのコールバックの中で`app.changeMap({mapid});`のAPIが呼ばれています。
これにより、以下のように API経由での地図切り替えが実現されます。
![タイトルなし.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10108/677b438d-cdff-9edb-8229-6060c17d8854.gif)
ちょっと、アプリっぽくなってきましたね！

明日は、いよいよマーカーでも表示させてみたいと思います。
Hangouts Chatの雨通知botを爆速で作る

@murs313 さんの[Slackの雨通知botを爆速で作る【メッ●●】](https://qiita.com/murs13/items/abc2b124d53e2ed54a02)を読み、
早速同じ物を作ろうと思いましたが、弊社はSlackが使えませんでした。

というわけで**Hangouts Chat版**雨通知botを作ってみました。
GASだと真似しすぎで作っててつまらないのでPythonとcronで実装してみました。

※ なおHangouts ChatはG Suiteでのみ使用でき、個人のGoogleアカウントでは現在使用できません。

# つくったもの
テストで送信してみたものがこちら。
実際は時間を合わせて17:00に送信されるように設定しています。
![IMG_0068.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342105/da93ccdf-2a24-c9dc-4b94-eb48a3689152.jpeg)
Hangouts ChatはMarkdownっぽい記法が使えるのが良いですね。
（画像では強調表示がうまいこといってませんが……）

# つかったもの
- **CentOS 8**  
  cronで定期実行します。
- **Python 3.6.8**  
- **Hangouts Chat の incoming webhook**
- **[livedoorお天気API](http://weather.livedoor.com/weather_hacks/webservice)**

# Hangouts ChatへのPOST
Hangouts Chat は incoming webhook が使用できます。
@iitenkida7 さんの [[超簡単]Hangouts Chat の incoming webhooks を使ってAPIから簡単にメッセージを投稿する](https://qiita.com/iitenkida7/items/3c8f9f8f6ee1e809558d)を参考にさせて頂きました。

# Pythonのソースコード
```python:weather.py
import requests

weather_url = 'http://weather.livedoor.com/forecast/webservice/json/v1?city=130010' # Tokyo
resp = requests.get(weather_url)
data = resp.json()

# 一部ぼかしていますがコピペでおk
webhook_url = "https://chat.googleapis.com/v1/spaces/HOGEHOGE/messages?key={YOUR_KEY}&token={YOUR_TOKEN}" 

tomorrow_weather = data['forecasts'][1]
telop = tomorrow_weather['telop']
max_temp = tomorrow_weather['temperature']['max']
min_temp = tomorrow_weather['temperature']['min']
image = tomorrow_weather['image']['url']

text = ''
text += '明日の天気は'
text += '*' + telop + '*'
text += 'です。\n'
# なぜかmaxとminが時々取得できない
if max_temp is not None:
    text += '最高気温'
    text += max_temp.get('celsius')
    text += '℃'
if min_temp is not None:
    text += '/最低気温'
    text += min_temp.get('celsius')
    text += '℃\n'
text += image

content = {"text": text}
response = requests.post(webhook_url, json=content)
```

# cronの設定
cronの設定は[こちら](https://eng-entrance.com/linux-command-crontab)が参考になると思います。

cronの設定を行うには```crontab -e```を叩きましょう。

```sh
$ crontab -e
```

するとVimで設定ファイルが開くので、実行する時間と実行するコマンドを入力しましょう。
今回はホームディレクトリ直下に置いたという設定です。

```vim
0 17 * * * python3 ~/weather.py
```

ファイルを保存してVimを閉じた時に```crontab: installing new crontab```と表示されれば設定完了です。

動作確認する場合は、再度```crontab -e```を開き、

```vim
*/1 * * * * python3 ~/weather.py
```

のように記述すれば1分おきにコマンドが実行されるようになります。

# 感想
参考にさせていただいたリンクたちがわかりやすかったので特に詰まることなく設定できました。
これで私も雨の日の前日にPCを持って帰るのを忘れずに済みます。

……まぁ弊社は先日リモート禁止の御触れがでちゃったんですけど。
fluentd の record_transformer でログにプライベートIPを含める

## 概要
fluentdを利用して複数のEC2インスタンスからCloudWatch Logsにログを転送する際にプライベートIPを含めたいケースがあり、fluentdの標準Filterプラグインで実現しました

## record_transformer でログにプライベートIPを含める

### record_transformer
record_transformerは標準のFilterプラグインで、条件に一致したログへのフィールドの追加や編集ができます

- https://docs.fluentd.org/filter/record_transformer

### プライベートIPアドレスの取得
フィールドの追加時に値としてRubyの式展開を含めた文字列を指定することが可能です
下記のようにプライベートIPの取得を行い、フィールドの追加を行うことができます

```conf
<filter foo.bar>
  @type record_transformer
  <record>
    private_ip "#{(Socket.ip_address_list.find do |addr_info| addr_info.ipv4_private? end).ip_address}"
  </record>
</filter>
```
ffmpegを用いてyoutubeからダウンロードしてきた動画を連結

# はじめに
ちょっと諸事情でYouTubeの動画をダウンロードして、一つに連結しなければならなかったのでffmpegを使って作業をすることにしました。
# 準備
YouTubeをダウンロードするためにYouTube-dlをダウンロードします。
(Linux,OS X)用

```shell
$ sudo curl -L https://yt-dl.org/downloads/latest/youtube-dl -o /usr/local/bin/youtube-dl

$ sudo chmod a+rx /usr/local/bin/youtube-dl
```

もし curl がなければ

```shell
$ sudo wget https://yt-dl.org/downloads/latest/youtube-dl -O /usr/local/bin/youtube-dl

$ sudo chmod a+rx /usr/local/bin/youtube-dl
```

一応インストールできたと思います。

Macの場合ですと

```shell
$ brew install youtube-dl
```
でもインストールできます。

YouTubeは仕様の変更が度々ありますので youtube-dl は最新にしておいたほうがいいです。以下のコードで最新に更新することができます。

```shell
$ sudo youtube-dl -U
```

ここまでで、YouTubeをダウンロードすることはできるようになりました。

次に ffmpeg の準備です。
ubuntuへのインストールは簡単です。

```shell
$ sudo apt update
$ sudo apt -y upgrade
$ sudo apt install ffmpeg
```

Mac の場合は以下のようにしたらできます。

```shell
$ brew install ffmpeg
```

ここらで一応準備は簡単にですが終了です。
ちなみに Windows は。。。悟ってください。

# コード
YouTubeのダウンロードがまずは必要ですよね？

```shell
$ youtube-dl "YouTubeのURL" -f "フォーマット"
```
今回は、mp4でダウンロードするので、

```shell
$ youtube-dl "YouTubeのURL" -f mp4
```
でオッケーです。
他にもオプションなどとてもたくさんありますが今回は必要ないのでググってください。

次に、ffmpeg の使い方について説明します。ここから本題ですね。
ffmpeg で動画を連結ってググると以下のコマンドが出てきます。

```shell
$ ffmpeg -f concat -i "input.file" -c copy "output file"
```

ここでinput fileを一つのファイルで管理するのが便利ですね。（最新のバージョンはこの方法でしかできないとかできるとか。。)

input.file の中身を以下のように作ります。

```shell:input.file
file input_1.mp4
file input_2.mp4
file input_3.mp4
        |
        |
file input_N.mp4
```

ここまでできたらさっきのコードが以下のように変わる。

```shell
$ ffmpeg -f concat -I input.file -c copy output.mp4
```
ここまでで出来ると思いきや、まぁできません。途中から音楽だけ流れて動画が
フリーズしたりだとか。

この原因は、いろいろあるっぽいので、ffmpeg が大好き先輩に聞くと、動画形式を統一してみたら？ということで助けてもらいました。

ということで、youtubeからダウンロードしてきた動画の形式を強制的に揃えます。

```shell
$ ffmpeg -I input_1.mp4 -b:v 1M -r 30 -c:a aac -c:v h264 input_1_1.mp4
```

これでそれぞれのデータの形式を強制的に揃えました。ざきほど作ったinput.file
も編集します。

```input.file
file input_1_1.mp4
file input_2_1.mp4
file input_3_1.mp4
        |
        |
file input_N_1.mp4
```
ここまでの準備をしたら先ほどと同じように以下のコードを実行してください。

```shell
$ ffmpeg -f concat -I input.file -c copy output.mp4
```

もしこれでもうまくいかないようでしたら、-c copy を抜いてあげることで
うまくいくと思います。

```shell
$ ffmpeg -f concat -I input.file output.mp4
```

# おわりに
今回はYouTubeから動画をダウンロードして動画の連結をしましたが、著作権などには気をつけてください。 
DVDに焼くなり煮るなりして、車のカーナビで見るのもありですね。自分専用のDVDを作ることができます。isoを作るのはググればすぐ出てくると思います。
では、今回は以上で。
イベントリスナのキュー投入とジョブの実行単位について

この記事は [Laravel Advent Calendar 2019](https://qiita.com/advent-calendar/2019/laravel) 6日目の記事です :coffee: 


イベントの発行、イベントリスナのキュー投入、投入したジョブの実行、といった機能が Laravelでは提供されていますが、キューに積まれるジョブの実行単位を間違え、失敗してしまったことが最近あったので、本記事ではあらためてイベント・ジョブ・キューについて書いてみようと思います :pencil: 


## 1. イベント・リスナーとは

- 何かしらの動作や変更が発生した際に発信される処理のこと

- イベントが発生し検出されると、リスナーと呼ばれるイベントに対応する処理が実行されるようになっている
- リスナーの処理は、キュー(Queue)に積んで非同期で実行することができる
- ドキュメント :book:   [イベント 6\.x Laravel](https://readouble.com/laravel/6.x/ja/events.html) 

## 2. ジョブ(Job)・キュー(Queue)とは 

- キューは待ち行列のこと。非同期で処理を実行するときの処理待ちの処理のリスト

- 処理の実行単位のことをジョブという

- ドキュメント :book: [キュー 6\.x Laravel](https://readouble.com/laravel/6.x/ja/queues.html)


## 3. ワーカー(Worker)  

- Queue(キュー)に積まれたジョブ(Job)は、非同期で順次処理されていくが、その時に非同期でジョブを実行してくれるプログラムのことをワーカー(Worker)という

- ジョブの実行が失敗した場合のリトライ処理などもワーカー(Worker)がやってくれる


## 4. 失敗したこと :pensive:


- サービス利用全ユーザーにメールを送信したい場合、以下のようなコードを書いていた
- ワーカー(Worker)は最大試行回数を10回としていて、失敗しても最大10回リトライされるようになっていた

- イベントの発行（`event`ヘルパにイベントのインスタンスを渡すとイベントを発行することができる）

```php
    /**
     * メール通知
     * @param $notification
     */
    private function triggerEvent($notification)
    {
        // メール送信用にEvent登録する
        event(new Notification($notification));
        return;
    }
```

- リスナーの処理

```php
class UserEventSubscriber implements ShouldQueue
{
    public function subscribe(Dispatcher $dispatcher)
    {
    }

    public function handle(Notification $event)
    {
        $event->send();
    }
}
```

- `$event->send()` の処理

```php
    public function send(): void
    {
        // ユーザーを全取得
        $users = User::all();

        // メール通知
        foreach ($users as $user) {
            \Mail::to($user->email)->queue(new EventMail($this->notification));
        }
    }
```

-  上記コード例の問題点は、1人でもメール送信に失敗したユーザーが存在した場合、リトライされ成功した残りのユーザーに対しても、再通知されるようになっていたこと :cold_sweat:  

- キューに積まれていく、イベントリスナの処理の中で、キューに積まれていくメール送信の処理があり、失敗した時のリトライする単位を、送信に失敗したメール単位だと勘違いしてしまっていた

- 正しくは、イベントで呼び出されたリスナ単位でキューに積まれるのが正しかったです


> リスナがイベントのために呼び出されると、Laravelのキューシステムを使い、イベントデスパッチャーにより自動的にキューへ投入されます




## まとめ

- イベント、ジョブ(Job)、キュー(Queue)の仕組みは、コード自体の変更箇所以外に、インフラ、ワーカー（Worker）の設定などを正しく認識していないと、ちょっとした勘違いで大きなミスになってしまうと思った :pray: 
- すごく初歩的なところで失敗したことと、ドキュメントに書いてあるようなことをそのまま紹介してしいる記事になってしまったのですが、イベント、ジョブ(Job)、キュー(Queue)の仕組みについて勉強になったのはよかった :pencil: 
- 次はこの仕組みを提供してるLaravelのコードを自体を読んで、どういう仕組みで動いてるか理解できるようにしたい :muscle: 


## 参考

- [キュー 6\.x Laravel](https://readouble.com/laravel/6.x/ja/queues.html)
- [イベント 6\.x Laravel](https://readouble.com/laravel/6.x/ja/events.html)
アンドロイドエンジニアが不足しているという噂について調べてみた

<h2>概要</h2>
<p>最近アンドロイド開発におけるエンジニアが不足しているという話をよく聞く様になった。特にkotlinエンジニアはグーグルがkotlinファーストを掲げるなど需要がかなり高まってると言われている。しかし、swiftの様に今まで人気がなかったことや、Javaで開発していたことが多かったためkotlinで開発ができるエンジニアの供給が追いついていないのが現状である。売り手市場といわれるAndroidエンジニアのについて、その真相を調査した。</p>
<h2>現状の分析</h2>
<p>まず、エンジニアの単価をiOSとAndroidで比較してみようと思う。</p>
<h4>アンドロイドエンジニアの単価</h4>
<h5>フリーランスエンジニア運営事務局の調べによると、下記の様になっている。</h5>
<p>Android経験1年未満 25万円～30万円/月(週5常駐案件の相場単価)</p>
<p>Android経験1年 　　30万円～45万円/月(週5常駐案件の相場単価)</p>
<p>Android経験2年 　　40万円～55万円/月(週5常駐案件の相場単価)</p>
<p>Android経験3年 　　 50万円～65万円/月(週5常駐案件の相場単価)</p>
<p>Android経験4年 　　 55万円～75万円/月(週5常駐案件の相場単価)</p>
<p>Android経験5年以上 65万円～85万円/月(週5常駐案件の相場単価)</p>
<h4>iOSエンジニアの単価</h4>
<h5>フリーランスエンジニア運営事務局の調べによると、下記の様になっている。</h5>
<p>iOS経験1年未満 30万円～40万円/月(週5常駐案件の相場単価)</P>
<p>iOS経験1年 　　　 45万円～50万円/月(週5常駐案件の相場単価)</P>
<p>iOS経験2年 　　　 55万円～60万円/月(週5常駐案件の相場単価)</P>
<p>iOS経験3年 　　　 65万円～70万円/月(週5常駐案件の相場単価)</P>
<p>iOS経験4年 　　　75万円～90万円/月(週5常駐案件の相場単価)</P>
<p>iOS経験5年以上 85万円～100+万円/月(週5常駐案件の相場単価)</P>
<p></p>
<p>あれ、、iOSの方が単価は高いな。。。
しかし、このデータではkotlinとjavaなど言語が混同している可能性があるため次は言語別で比較したいと思う。
</p>
<h2>言語別年収ランキング</h2>
<p>大手転職サイトのビズリーチによると「プログラミング言語年収ランキング」によると下記の様になる。（2018年の集計結果）</p>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274030/c98d5288-1189-c331-d7a9-9f68b918c4b9.jpeg">
</img>
<p>
Kotlinが４位、swiftが８位となっており先ほどとは真逆の結果となっている。Javaがランキング外となっていることからJavaでのアンドロイド開発のニーズが減り、kotlinでのAndroid開発のニーズが高まっているのだと思われる。
</p>
<p>
ちなみに2016年のランキングではswiftは9位、kotlinはランキング圏外となっている。kotlinの人気はここ最近で急上昇したものなのかもしれない。
参考：https://jp.stanby.com/media/programming_ranking
</p>
<h2>結論</h2>
<p>OS別、言語別の単価の分類を考えると、kotlinを用いたAndroidアプリの開発の需要が高まっていると考えられる。</p>
<p>また、単価の安いAndroid搭載のスマホがアフリカなどの途上国で伸びていることなど大きなプラス要因がある。Androidエンジニアの需要は今後も高いままだろう。</p>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274030/9181ee60-d2d6-2b1a-7ca0-0b9e19b2f38f.jpeg"></img>
<p>参考：https://www.statista.com/chart/9628/smartphone-platform-market-share-forecast</p>
Mediumの斜め上をいく求人

[MediumのLocal Storageの記事](https://medium.com/@onejohi/offline-web-apps-using-local-storage-and-service-workers-5d40467117b9)を読んでいたら試したくなって、おもむろにChrome DevToolsを開いてみました。

```
CTRL + SHIFT + I
```

すると、Mediumの求人広告を目にするのでした。

```plaintext
-+++++=        .+++++=
.+@@@@@+       #@@@@*:
  .@@@@@=     *@@@@@  
   @+@@@@-   =#@@@@@  
   @ +@@@@: :% @@@@@  
   @  *@@@@-%: @@@@@  
   @   *@@@@-  @@@@@  
  -@-   #@@+  :@@@@@: 
-#@@@#-  ##  =@@@@@@@=
.......      .........

main.59bf7827.chunk.js:1 We're hiring! https://medium.com/jobs-at-medium/work-at-medium-959d1a85284e
```

果たして、Mediumはジョークとしてコード中にこの一行を入れたのか、応募してきたエンジニアを本気で採用するつもりでいるのかわかりませんが、非常に面白いですね。
第二種電気工事士試験を受けた話①



僕は明日12/7(土)、第二種電気工事士試験の二次試験、実技試験に行ってきます。(受かりてぇ)
こういうのを書くのは初めてなのでお手柔らかに。軽くになりますがよろしく

## そもそも電気工事士って？

電気工事士とは！電気工事をするための資格である！

はいこの話終了！とはならんけどまぁ一言で言うならこう。電気工事にも色々あって、資格によってできる範囲が変わる。

第二種電気工事士を持ってるとできること
一般電気工作物を扱える。一般電気工作物ってのは、600V以下で受電して同一構内で使用するもの。工事の例としては、
・家のコンセントを弄る~~(受ける友達で勝手に弄ったことあるってやつ何人もいるけど)~~
・スーパーの明かりの配線
・家の配電盤の配線
みたいな。

第一種なら二種の範囲に加えて自家用電気工作物（最大500ｋW 未満の需要設備）を扱える。（うち、ネオン工事、非常用予備電源発電装置工事を除く）例えば
ビルの配電盤の配線
鉄道の架線の工事
みたいな。二種の上位互換。

ネオン工事、非常用予備電源発電装置工事に関しては特殊電気工事資格者っていうまた別の資格が必要。

##　筆記試験と実技試験について
電気工事士は一次の筆記試験と二次の実技試験に分かれてて、僕は今筆記が合格している状態。ちなみにこの試験、わりと簡単。


~~**合格率が筆記で55~60%、実技でおよそ70%とか楽勝っしょwwwww**~~

ちなみに100点中60点で合格ですが僕は筆記が64点。あぶねぇ。勉強不足が露呈してますねハイ。まぁ知識問題が8割くらいなんでちゃんと勉強しないと普通に落ちる。ただ、過去問とかなり問題が類似したのが毎年出るのでそれをちゃんとやってれば問題ないという印象。要するにちゃんと勉強しよう。そうすれば筆記は受かる。

で、問題なのは実技試験。合格率70％であっても電気工事士という資格を取ろうという時には必ずぶち当たるであろう最大の課題、それは

**工具と練習用の部材をそろえること。**

ざっと調べた限り、Amazonで出てきたのは工具一式だいたい1万円、練習用のケーブルとかコンセント、スイッチetc...のセットが1万５千円くらい。たかい。
とはいえ、これを読んでいる酔狂な方々は高専生であろう。(そうじゃない人はごめんなさい)電気系の学科があれば工具は先生方に頼めば貸し出してくれると思うので是非活用しよう。弊学では練習用の部材も用意してもらえるので助かっている。(他高専も用意してくれてるところもあるんじゃないだろうか)
工具と部材が用意出来たらあとは公表問題の13問をやるだけ。この詳しい話は②以降で。


今回は時間ぎりぎりでやっつけで書いた文章だけども次はもうちょい真面目に書くのでよろしく！では②でまた会おう！

にしてもやっつけとはいえ多少は書いたつもりだったのに読み直すとめちゃ短い...
ShellScript Bash for文の書き方

# 目的

- ShellScript Bashにて指定回数処理を繰り返すfor文の書き方をまとめる

# 書き方の例

- 下記に指定回数処理を繰り返すfor文の例を記載する。
- `((i=0; i<指定の回数; i++))`は`((iは0から始まる; この回数に達したら処理は終了; 一回の処理ごとにiに1を足す))`ということである

```bash
#!/bin/bash

for ((i=0; i<指定の回数; i++)); do
  指定回数繰り返したい処理
done
```

# より具体的な書き方の例

- 下記に期待値の出力を記載する。

```
*
**
***
****
*****
```

- 下記に前述の期待値の出力を行う処理を記載する。

```bash
#!/bin/bash

FOO_1="*"
FOO_2="*"
for ((i=0; i<5; i++)); do
  echo "${FOO_1}"
  FOO_1="${FOO_1}""${FOO_2}"
done
```
C言語でメモリを確保する

今回はC言語です。

#メモリとは
メモリというのは資源です。
記憶するための領域で、沢山あると沢山記憶ができます。
よくあるPCのメモリは一時的に記憶しておくための機構であり、
長期保存がしたければ、そういう機構に記憶を依頼しないといけません。

#何を作ったか。
C言語のmallocとreallocをラップして自分には使いやすい構造にしてみました。

#苦労話。
reallocのコードを書いているときmallocのコードをコピペしてはまって、メモリースマッシュをしてしまいました。
メモリースマッシュは破壊の予兆になるのでやめましょう。

#lisence
copyright 2019 Yakitori.
MitLisence.

#Code
```c:MemoryAllocator.h
#pragma once
#include <stddef.h>
#include <stdbool.h>

typedef struct Memory_ {
	void* Memory;
	size_t ElementSize;
	size_t Length;
} Memory;

Memory MemoryAllocate(size_t N, size_t SizeOfElement);
Memory MemoryReAllocate(Memory* Mem, size_t N);
bool MemoryFree(Memory*);
```
```c:MemoryAllocator.c
#include <stdlib.h>
#include <memory.h>
#include "MemoryAllocator.h"

Memory MemoryAllocate(size_t N,size_t SizeOfElement ) {
	Memory M = { NULL,0 ,0};

	M.Memory = malloc(N*SizeOfElement);

	if (M.Memory != NULL) {	
		memset(M.Memory, 0, N*SizeOfElement);
		M.Length = N;
		M.ElementSize = SizeOfElement;
	}

	return M;
}

Memory MemoryReAllocate(Memory* Mem,size_t N) {
	void *p = realloc(Mem->Memory,N*Mem->ElementSize);

	if (p != NULL) {	
		//if (p != Mem->Memory) { free(Mem->Memory); }//this is safe??
		Mem->Memory = p;
		Mem->Length = N;
	}

	return *Mem;
}

bool MemoryFree(Memory* In) {
	free(In->Memory);

	In->Memory = NULL;
	In->Length = 0;
	In->ElementSize = 0;
	return true;
}
```
```c:main.c
#include "MemoryAllocator.h"
//#include <crtdbg.h>//ms env only.

int main() {
	//_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF| _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_LEAK_CHECK_DF);

	Memory M = MemoryAllocate(16 ,sizeof(int));
	Memory B = MemoryReAllocate(&M, 32);
	MemoryFree(&B);

	//_CrtDumpMemoryLeaks();//ms only.

	return 0;
}
```
rails routesのdirect resolveメモ

# 概要
## direct routing
アプリ外のルーティングをroutes.rbで表現できるようになった事で、
アプリ内外問わず、ルーティングをroutes.rbに集約できるようなった。 

## resolve routing
動的に変わるurl_helper
モデルに応じたポリモーフィックなURL生成のルールを再定義できるようになった。

# 使い方

## direct routing

```ruby:config/routes.rb
direct :outside do
  { controller: '', action: '' }
  'https://outside.com'
end


# >> outside_url
# => "https://outside.com"

direct :homepage do
  "http://www.rubyonrails.org"
end

# >> homepage_url
# => "http://www.rubyonrails.org"
```

## resolve routing

```ruby:config/routes.rb
resource :basket
 
resolve("Basket") { [:basket] }
```

```
<%= form_for @basket do |form| %>
  <!-- basket form -->
<% end %>
```

# 背景
https://github.com/rails/rails/issues/22512

# ドキュメント

## direct routing
https://railsguides.jp/routing.html#%E3%83%80%E3%82%A4%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AB%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%EF%BC%88direct-routes%EF%BC%89

## resolve routing
https://railsguides.jp/routing.html#resolve%E3%82%92%E4%BD%BF%E3%81%86

# 実装
https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/CustomUrls.html
さぁ、サイトを下からグイッっとパンしてサイトのロゴがドーン！する新しいjQueryプラグインを考えてみた

サイトのロゴはそのサイトを表す重要なものです。ただレイアウト的にはサイトの上部にちょこんとあるぐらいで、いろいろなサイトを見慣れてる人は スルーしているかもしれません。しかしせっかく作ったんだから見てほしい！そのニーズに答えたのがこのプラグインです。
デモ

どのようなものかこちらのデモをご覧ください。確認ブラウザはこの記事を書いた当時のIE・Firefox・Chromeの最新版です。

<a href="http://webdrawer.net/sample/js/standup/index.html" target="_blank">standup.jsのデモ</a>

これでバッチリ、サイトのロゴがアピール出来ましたね。

## 使い方

以下のライブラリを読み込みます。

```html
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.transform.js"></script>　
<script type="text/javascript" src="standup.js"></script>
```

このあとにJavaScriptが起動するように以下の記述をします。

```javascript
<script type="text/javascript">
$(function(){
  $('body').standup();
});
</script>
```

最終的なソースはこちら

```html
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.transform.js"></script>
<script type="text/javascript" src="standup.js"></script>
<script type="text/javascript">
$(function(){
  $('body').standup();
});
</script>
```

## HTML
HTMLではドーン！と表示したいサイトのロゴにid="titleLogo"を指定します。

## CSS

サイトのロゴ（#titleLogo）にwidthを指定して下さい。width:100%;だとその要素の真中にドーンします。※オプションでドーンする場所の調整ができます。

```css
#titleLogo {
  width: 200px;
}
```

これで上記のデモのような動きになります。


## オプション

オプションを設定することで、ドーンの位置を変えたり大きさを変えることができます。

```html
<script type="text/javascript">
$(function(){
  $('body').standup({
    id : '#titleLogo', //サイトのロゴのidをtitleLogo以外にしたい場合にここの記述。idとあるけど、classでも可。
    scale : 3, //ドーンする拡大値。ロゴの大きさによるが2～4ぐらいが適当。
    left : false, //widthが広い場合に、trueにするとその要素の左端にドーンするようの設定。
    right : false, //widthが広い場合に、trueにするとその要素の右端にドーンするようの設定。
    adjust : 0 //上記の左右端にドーンすると要素の端が画面中央にくるので位置微調整用の項目。左に100px動かすならなら「-100」。右に100px動かす場合は「100」と入れる。
  });
});
</script>
```

## 左寄せのデモ

```html
<script type="text/javascript">
$(function(){
  $('body').standup({
    left : true,
    adjust : -100
  });
});
</script>
```

<a href="http://webdrawer.net/sample/js/standup/index2.html" target="_blank">左寄せのデモ</a>

## 右寄せのデモ

```html
<script type="text/javascript">
$(function(){
  $('body').standup({
    right : true,
    adjust : 100
  });
});
</script>
```

<a href="http://webdrawer.net/sample/js/standup/index3.html" target="_blank">右寄せのデモ</a>

## 元ネタ

お気づきのかたも多いと思いますが、元ネタは<a href="https://www.nicovideo.jp/watch/1453188748" target="_blank">こちらのアニメのOP</a>になります。

転載元の記事
<a href="http://webdrawer.net/javascript/standup.html" target="_blank">さぁ、サイトを下からグイッっとパンしてサイトのロゴがドーン！する新しいjQueryプラグインを考えてみた</a>
three.jsでぺグソリティアをつくる

## 概要
旅先のカフェに手作りのペグソリティアが置いてあったのですが、攻略できなかったのでthree.jsで作ることにしました。
three.jsを使ったのは作品例が綺麗だったからで、特に意味はありません。
むしろ普通に作るときは使わないほうが楽です。

## ペグソリティア
盤上の杭（ペグ）を一つを残して取り除くゲーム。
ペグは以下のルールで動かすことができます(wikiより)。

- 駒が縦横に並んでいてかつその隣に駒がないとき、駒は他の駒を飛び越えることが出来る。
- 飛び越えられた駒は盤から取り除く。

今回はドイツスタイルのペグソリティアを作ります。

## three.js
https://threejs.org/

3Dアニメーションを手軽に作れるライブラリです。
カメラと光源クラスを用いて物体からの光の反射を表現したりします。

マウスでのオブジェクト操作には raycasterクラス を使います。
このクラスを使うと、カメラとクリックした点を結ぶ線分上にある物体を取得することができます。
今回は色を変えるのに使っています。

## 作ったもの（gifです）
![movie-min.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240492/162a48ae-063f-6a48-f1c3-0a6a59c9bb14.gif)

緑の玉がペグ、赤い玉がペグが取り除かれた位置を表します。
コードはこちら。手っ取り早くVue.jsでつくりました。
https://github.com/dshintani404/peg_solitaire
## 感想
「飛び越えられたペグ」はマウスクリックしないので、どうやってオブジェクトを取得するか考えました。
クリックされた2点の中点にマウスを配置して、クリックしたことにする、という雑な手段をとりました。
Assimpでファイルパスに日本語が含まれるファイルも読み込めるようにしてみた

趣味で作っている自作ゲームエンジン(もどき)がある程度組めたのでAssimp(ver 5.0.0)を導入してモデルを色々読み込んで遊んでいて、
ふとPMXモデルも読み込めたよな？と思いニコニ立体から適当にダウンロードして読み込ませたところ"Unable to load this asset ~~"といったエラーが発生するではないですか。
幸いAssimpはコード触りたい放題拡張し放題なのでパスに日本語が含まれている場合でもファイルを読み込めるよう改造してみました。
(何らかの意図があって現状のコードになっているはずなのでコードをイジる際は自己責任でどうぞ)

## やったこと
とりあえずニコニコ動画ランキングで目についたMMD動画で使われていた[アンジュカトリーナ](https://3d.nicovideo.jp/works/td63794)モデルをassimp_viewerで拝めるようにはしました。
(面倒だったのでファイル名に日本語を含むテクスチャの読み込み部分は修正していませんが)
![Open Asset Import Library _ Viewer  [C__Users_nest_4869_Downloads_こんにゃく式アンジュ・カトリーナver1_こんにゃく式アンジュ・カトリーナver1_アンジュ・カトリーナ(頭身高め).pmx] 2019_12_06 0_06_37 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546387/282b0fc2-3691-07ec-136d-718441517279.png)
~~シェーダのせいでびっくりするほどモデルの見栄えが悪い..~~

## 肝心の変更箇所
assimp-5.0.0/code/Common/DefaultIOSystem.cppのExists、Open関数内の処理を下記のようにfopenに統一します。

```c++:DefaultIOSystem.cpp
// 83行目あたり

// ------------------------------------------------------------------------------------------------
// Tests for the existence of a file at the given path.
bool DefaultIOSystem::Exists(const char* pFile) const
{
    FILE* file = ::fopen(pFile, "rb");
    if (!file) return false;
    ::fclose(file);
    return true;
}

// ------------------------------------------------------------------------------------------------
// Open a new file with a given path.
IOStream* DefaultIOSystem::Open(const char* strFile, const char* strMode)
{
    ai_assert(strFile != nullptr);
    ai_assert(strMode != nullptr);
    
    FILE* file;
    file = ::fopen(strFile, strMode);
    if (!file) return nullptr;

    return new DefaultIOStream(file, strFile);
}

```

以上です、はい。

なぜわざわざWIN32ではコンパイル分岐でfopenの使用を避けるのかが自分では理解できない...