OmniAICreator/Qiita-1.07M huggingface dataset:
node.jsでjQueryを使ってスクレイピングする

### 要約
- `Node.js`でスクレイピングする
- `jQuery`を利用する
- `Promise`,`async/await`で同期処理にする。なお同期処理に悪戦苦闘した。難しい・・・

### 動機
- 自然言語の機械学習用データ集めのため、スクレイピングする必要があった。
- Pythonでばかりコーディングするのも芸がない。DOMを操作するんだから、jQueryを使ってやろう。
- Node.jsは前から興味があったけど、初めて触る。JSのお勉強がてらやってみるか。（※ワタクシのJavaScript知識は10年以上前で止まっていましたので。プロミス？なにそれ、消費者金融？って状態でした）

### やりたいこと
- とある、Webサイトの記事のURLを取得したい。
- Webサイトには一覧ページがあり、1ページに50件程度の記事一覧がある。ページはパラメータで変えられる（`https://hoge?page=2`のような形で）
- 記事一覧の各ページから、記事本文のURLと投稿日、記事タイトル等を取得する

### やったこと

#### 必要なライブラリのインストール
```bash
$ node -v # => v8.11.1
$ npm init
$ npm install jquery --save
$ npm install jsdom --asve
```
jqueryは趣旨のとおり。jsdomはjqueryをブラウザなしで利用するのに必要だった。

#### コーディング
ポイントは

- https.getは非同期で動作するので、（同期させたいなら）**`Promise`オブジェクトを返す関数**でラップしてやる(`get_entry_titles`)
- GETで取得したHTMLをそのままjqueryへ突っ込むと **windowがない** といってエラーになるで、jsdomを利用する
- 同期したいところを**`async/await`** を使う。

```javascript
const https = require("https"); //GETメソッドでリクエストするために
const util = require("util"); //format関数を利用するために
const jsdom = require("jsdom"); //jqueryをつかうために
const jquery = require("jquery"); //趣旨のとおり、DOM走査するために

// 記事一覧のページ
const URL = "https://hoge?page=%s";

// スクレイピングする処理（プロミスオブジェクトを返す) 
// 最近はfunctionで定義しないで、無名関数を変数に代入にするのがモダンなの？
function get_entry_titles(page){
	// プロミスをnewする
	return new Promise((resolve) => {
		// httpsリクエスト
		const req = https.get(util.format(URL,page), (res) =>{
			// このあたりは公式のドキュメント参考に
			var html = "";
			res.setEncoding('utf8');
			res.on('data',(chunk) => html += chunk);
			res.on('end',() => {

				// windowがないとjQueryが動かないそうで、以下の様にする模様
				const dom = new jsdom.JSDOM(html);
				const $ = (jquery)(dom.window);

				//スクレイプしたい処理をjQueryで記述
				$(".foo").each((index,element) =>{
					// スクレイプ結果を出力
					console.log(util.format(
						"%s\t%s\t%s"),
						page, //ページNo.
						$(element).find(".bar").attr("href"), //リンクURL
						$(element).find(".hoge").text()); //タイトル
				});
				//ここで処理完了なのでresolve。これにたどり着くのに悪戦苦闘した
				resolve();
			});
		});
		req.end();
	});
}

// メインのループ処理（ページ数文繰り返し) async関数にする
async function main(){
	// 1〜9ページ繰り返す
	for (var page=1; page < 10 ; page++){
		// awaitを付けて、１ページづづ同期する。じゃないとページ数だけが先にインクリメントされてしまう。
		await get_entry_titles(page);
	}
}

// 処理エントリ
main();
```

### 最後に
うむ、JavaScript、もう一度勉強しないと。10年の遅れをキャッチアップせねば。
なんとか動作はしたが、もっといいやり方とかがあるかもしれない。
画像をスクレイピングして保存までをPythonでやってみた[初心者向け]

##はじめに

興味本位でスクレイピングをやってみました。
めちゃくちゃ簡単なのでやってみて下さい。


##スクレイピング

スクレイピング用のメソッドを書きました。
至ってシンプルです。
HTTPステータスコードが200の時だけ取得データを返します。

※HTTPステータスコードが分からない方へ
[参考]
[HTTPステータスコードとは？種類とそれぞれの役割について](https://digital-marketing.jp/seo/http-status-code/)


```python:sample.py
import requests

def download_data(url):
    response = requests.get(url)
    if response.status_code == 200:
        return response.content
    else:
        print('ダウンロードに失敗しました\nステータスコード：', response.status_code)
```


##保存

保存用のメソッドを書きました。
こちらも同様に至ってシンプルです。
保存に失敗した時を想定して、try-except構文を使用して例外処理を実施してます。

```python:sample.py
import traceback

def save_file(data, file_name):
    try:
        with open(file_name, 'wb') as f:
            f.write(data)
    except:
        print('データの保存に失敗しました')
        traceback.print_exc()
```


##実際に取得してみよう


スクレイピング用メソッドに取得したい画像のURLを渡して、保存用メソッドに取得したデータと、保存用ファイル名を渡してあげて、スクリプトを実行してみましょう。

```python:sample.py
data = download_data('画像パス')
save_file(data, 'ファイル名')
```

`[取得、保存]`に成功していれば、画面には何も表示されないはずです。
失敗している場合は、エラーメッセージが出力されます。

```
$ python sample.py
```

エラーメッセージが出ていなければ成功しているはずなので、確認してみましょう。

```
$ find ファイル名
ファイル名
```

対象のファイルが見つかれば、成功です。


##まとめ

興味本位で始めた割に、案外簡単に出来た事が少し感動しました。
今後やりたい事としては、機械学習を使用して類似の画像を取得してくる、みたいな事をやりたいと思っています。

##おまけ
Twitterやってます！外部のエンジニアの方ともどんどん繋がりたいと考えていますので、是非フォローして頂ければと思います！[@Tatsuo96](https://twitter.com/Tatsuo96)
p.s.今年の2月までは溶接職人でした。ガッツ系エンジニアとしてやらせて頂いております。
いてつく波動を作る【ツクールMV】


Twitterでネタを見たので作成。
いてつく波動に代表される対象のバフ・デバフその他を解除するスキルは設定が面倒です。
攻撃力などの上下動の無効化は、「強化の解除」で行えますが問題はステートです。

マホカンタやらバイキルトやらをまとめて削除するのは大変です。
以下のような設定にした「いてつく波動ステート」を作成すると、いい感じに動いてくれます。

![2018-10-28.png](https://qiita-image-store.s3.amazonaws.com/0/92869/3c03c68b-bab8-d99f-543e-ace45fe08d82.png)

こうすることで、いてつく波動が発生したときに強化系ステートをステート無効化で剥がしつつ、いてつく波動も自身の効果によって除外されます。
また、いてつく波動が効かない敵だとか、確率でいてつく波動などといったものも作れるようになります。

ただ、いてつく波動は管理番号を後ろの方にしてください。
そうしないと、一部解除されないステートが出てきます。
github.com から error: GH008: Your push referenced at least 1 unknown Git LFS object: と言われているときは.lfsconfigが足りていない

git.lfs で他のサーバー指定してるときは `.lfsconfig` に入れとかないといけない。
無いのに push されてない blob が commit delta に入っているとエラーになる。

```
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
remote: error: GH008: Your push referenced at least 1 unknown Git LFS object:
remote:     bed775e3c3adc73c253aedfd7648043e691bcb25e319478312f138c5022a17b2
remote: Try to push them with 'git lfs push --all'.
```
nuxt-fontawesomeを使って Nuxt.jsへFont Awesome 5を導入する

結局[nuxt-fontawesomeのReadme](https://www.npmjs.com/package/nuxt-fontawesome)を見て解決したのですが、日本語の記事は見つからなかったりちょっと苦労もしたりだったので、（備忘録も兼ねて）記録
#前提
Nuxt.jsのプロジェクトにFontAwesome 5の導入が必要になった背景はこの投稿と同じ状況です。
https://qiita.com/_rema_lp/items/137f0de9e039a464e7db
以下引用：
>CSSフレームワークに Bulma を使おうとしたところ、公式ドキュメントが FontAwesome 5 対応になってしました。
>Nuxt.js 用の FontAwesome パッケージとして @nuxtjs/font-awesome がありますが、こちらはまだ FontAwesome 4 にしか対応していないため他の導入方法を探しました。

`@nuxtjs/font-awesome`を使う代わりに、上記の投稿では`@fortawesome/fontawesome-free-webfonts`を導入しています。

今回私の環境では`nuxt-fontawesome`を導入してみたので、その方法と結果を記します。

#Version
Nuxt.js: v2.0.0
@nuxtjs/bulma: v1.2.0
nuxt-fontawesome: v0.3.0

#方法
[nuxt-fontawesomeのReadme](https://www.npmjs.com/package/nuxt-fontawesome)の通りにやっていけば出来ました。

##導入
まずnpmで下記のコマンドを叩き、依存性を追加します。

```bash
$ npm i nuxt-fontawesome
$ npm i @fortawesome/fontawesome-svg-core @fortawesome/vue-fontawesome
$ npm i @fortawesome/free-solid-svg-icons
```

そうしたら`nuxt.config.js`を開き、`modules`に`nuxt-fontawesome`を追加します。
`@nuxtjs/bulma`が既に追加されているので、このように追記しました。

```js:nuxt.config.js
module.exports = {
 modules: [
    '@nuxtjs/bulma',
    'nuxt-fontawesome' //ここに追記
  ],

  ...

//この部分を追記
 fontawesome: {
    imports: [
      {
        set: '@fortawesome/free-solid-svg-icons',
        icons: ['fas']
      }
    ]
  }
}
```
module以下に追加する部分は二通りの書き方があるようですが、こちらの短い記述で大丈夫でした。
[Readme](https://www.npmjs.com/package/nuxt-fontawesome)を読むと結構追記する量が多く見えますが、よく見るとコメントで`//OR like this`と書いてあるので1行で大丈夫みたいです。

以上で導入はOKです。
`npm run dev`で既に起動している場合は一旦停止して再度起動すると変更が適用されます（そのことを知らず、少し悩みました）

##実装
template以下に`<font-awesome-icon icon="dollar-sign"/>`と書くだけでアイコンが表示されます


```vue
<template>
    <div>
        <font-awesome-icon icon="dollar-sign"  style="font-size: 30px"/> //styleを指定することも可能
        <font-awesome-icon :icon="['fas', 'adjust']"  /> //こっちの書き方でもOK
    </div>
</template>
```

`npm run dev`で確認してみると、右下の赤矢印で示したボタン左端のようにiconが追加されていることが確認できます
![doll.png](https://qiita-image-store.s3.amazonaws.com/0/301118/e42177e5-92c9-8ae8-7762-311eb93ddd75.png)

##詰まった点
- nuxt.config.jsを編集したら変更が適用されるのは再度`npm run dev`したタイミング
- 公式のUsageには`@fortawesome/pro-regular-svg-icons`も追加するよう書かれているけど、`@fortawesome/free-solid-svg-icons`だけでOK
pathlib　マイチートシート

OSコマンドとpathlibの対比を整理する。

```
from pathlib import Path
from stat import filemode
from shutil import rmtree

p_new_file = Path('./new_file.txt')
p = Path('.')

```

| OSコマンド  | pathlib |
| ------------- | ------------- |
| touch  | p_new_file.touch()  |
| rm  | p_new_file.unlink()  |
|chmod  755 | p_new_file.chmod(0o755)   # 8進数で指定|
|ls -la  # 権限確認 |filemode( p_new_file.stat().st_mode) |
|ls -la  # owner確認 |p_new_file.owner()|
|ls -la  # group確認 |p_new_file.group()|
|ls -la  # 存在確認 |p_new_file.exists() |
|ls -la  # ファイル確認 |p_new_file.id_file() |
|ls -la  # ディレクトリ確認 |p_new_file.is_dir() |
|ls -lF (grep -v \\) # ファイルだけ | [x for x in p.iterdir() if x.is_file()]  # ファイル一覧|
|ls -lF (grep  \\) # ディレクトリだけ| [x for x in p.iterdir() if x.is_dir()]  # ディレクトリ一覧|
|pwd |p.cwd()|
|mkdir|p.mkdir()|
|mkdir -p|p.mkdir(parents=True)|
| rm -fr  |rmtree(p)|

固有の話

|やりたいこと  | pathlib |
| ------------- | ------------- |
| 絶対パス変換  | p_new_file.resolve() |
|パス連結  | p_new_file / 'sub_dir' / 'file2.txt |
|ファイル名  | p_new_file.name |
|絶対パスか判定  | p_new_file.is_absolute() |
|親ディレクトリ|p_new_file.resolve().parent|
|拡張子取得|p_new_file.resolve().suffix|
|同じディレクトリに別名ファイルを作る|p_new_file.with_name('file_new.txt')|
|パターン検索|p.glob('**/*.txt')|
|ファイル削除　内包 | [p.unlink() for p in p_temp.glob('**/*') if re.search('\d+\.txt', str(p)) and p.is_file()]|
|ファイルのopen|with p_new_file.open(mode='w') as f:|
|ファイルの読み込み # ファイルのopenの後で|f.read()  # ファイル全体を文字列として読み込み<br /> f.readlines() # ファイル全体をリストとして読み込み<br />  f.readline() # ファイルを一行づつ読み込み|
[pandas] read_csv のオプションだけで、時系列データとして扱いやすいデータフレームを作成する

この記事では、pandas の read_csv のオプションだけで、時系列データとして扱いやすいデータフレームを作成する方法を示します。Jupyter Notebook 上で作業していることを前提にします。

### 結論

気象庁が公開している csv を、以下のオプション指定で読み込みます。

```python
df = pd.read_csv('data.csv',
            encoding='SHIFT-JIS',                      # 文字コードを指定
            skiprows=6,                                # 読み飛ばす先頭行数を指定
            usecols=[0, 1, 4, 7],                      # どの列を読み込むかを指定
            names=['date', 'average', 'high', 'low'],  # カラム名を設定
            parse_dates=['date'],                      # datetime で読み込むカラムを指定
            index_col=['date'])                        # インデックスにするカラムを指定
```

すると、以下のようにインデックスが [DatetimeIndex](https://pandas.pydata.org/pandas-docs/version/0.23.4/generated/pandas.DatetimeIndex.html) となったデータフレームが作られます。

![データフレーム](https://qiita-image-store.s3.amazonaws.com/0/48133/035849b0-45fd-5b7d-9d66-4de7b0c7c870.png)

以下は解説です。

### データソースの CSV

気象庁が公開している気象データを使用します。
https://www.data.jma.go.jp/gmd/risk/obsdl/index.php

地点を東京、項目を日平均気温、日最高気温、日最低気温、期間は過去 5 年分としてダウンロードします。

![気象庁ダウンロードページ](https://qiita-image-store.s3.amazonaws.com/0/48133/9c631d1e-c492-3b09-a3d4-70dfa1bc1353.png)

### オプション指定なして　read_csv を使用した場合

まず、パッケージをインポートします。

```python
import pandas as pd
```

文字コードの指定だけした状態で read_csv で CSV ファイルを読み込みます。

```python
df = pd.read_csv('data.csv', encoding='SHIFT-JIS')
```

すると以下のようなデータフレームが作られました。ここから加工することもできますが、read_csv 時に綺麗な状態で取り込めるといいですよね。

![データフレーム](https://qiita-image-store.s3.amazonaws.com/0/48133/91857ccd-3eb5-2789-f7c5-543b2856b555.png)

### オプションを指定して read_csv を使用する

上記の結論に書いた内容と重複しますが、[read_csv](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html) のオプションを活用して、時系列データを扱いやすくするようにデータフレームを読み込みます。

```python
df = pd.read_csv('data.csv',
            encoding='SHIFT-JIS',                      # 文字コードを指定
            skiprows=6,                                # 読み飛ばす先頭行数を指定
            usecols=[0, 1, 4, 7],                      # どの列を読み込むかを指定
            names=['date', 'average', 'high', 'low'],  # カラム名を設定
            parse_dates=['date'],                      # datetime で読み込むカラムを指定
            index_col=['date'])                        # インデックスにするカラムを指定
```

すると、次のようなデータフレームが作られます。

![データフレーム](https://qiita-image-store.s3.amazonaws.com/0/48133/035849b0-45fd-5b7d-9d66-4de7b0c7c870.png)

この状態だとインデックスが [DatetimeIndex](https://pandas.pydata.org/pandas-docs/version/0.23.4/generated/pandas.DatetimeIndex.html) になっていますので、日時を指定した操作がしやすいです。例として、2017 年の日平均気温の折れ線グラフを描画する場合は、以下のように書きます。

```python
%matplotlib inline
df.loc['2017'].plot(y='average', figsize=(15, 5))
```

![折れ線グラフ](https://qiita-image-store.s3.amazonaws.com/0/48133/df209aa9-b059-f3e4-df1e-14a29e9eba8b.png)


# 参考

[pandas: read_csv](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html)
[気象庁: 過去の気象データ・ダウンロード](https://www.data.jma.go.jp/gmd/risk/obsdl/index.php)
AnsibleでLEMPなWordPressを構築する（Debian 9.5ベース）

# 概要

* GCEの無料枠ありインスタンス `f1-micro` でWordPressを動かしたい
* `f1-micro` がDebian 9.5だったので、Dockerのdebian:9.5ベースのコンテナでWordPressが動くようなansible playbookを書いてみる

# バージョン情報

* Ansible 2.7.0
* Debian 9.5
* MariaDB 10.1.26
* nginx 1.10.3
* PHP 7.0.30
* （ホスト）Mac 10.13.6, Docker for Mac 18.06.1

# 成果物

https://github.com/t-morisawa/wordpress-debian

[ansible-examples](https://github.com/ansible/ansible-examples)ではRHELベースでのplaybookしかなかった。Debian向けのPlaybookについては[現在PRが出ているが](https://github.com/ansible/ansible-examples/pull/179)マージされていない。 PRのコードを動かしたところいくつか動かなかった点があったので修正したのが上記のコード。

# ハマった点

## nginx, php-fpmが起動しない

以下のようなハンドラを定義したもののserviceモジュールがnginxを起動してくれず。

```
- name: restart nginx
  service: name=nginx state=restarted enabled=yes
```

非推奨な方法だがcommandを利用して起動するようにした。

```
- name: restart nginx
  command: service nginx restart
```

php-fpmについても同様。

```
- name: restart php-fpm
  command: service php7.0-fpm start
```

参考文献
https://stackoverflow.com/questions/30162528/ansible-service-restart-failed


# 今後の課題

* HTTPS化の設定
* GCEではDockerコンテナをデプロイする形で動かすことができるので、Dockerで構築する方法と比べてより便利な方法を本番で採用したい。
Logic Appsを定時実行させる

#概要
今取り組んでいるプロジェクトで、
Logic Appsを毎朝7時30分に実行する必要があって、
その設定の備忘録。


#Logic Appsの作成

1. まずは「すべてのサービス」を選び、検索窓に「Logic Apps」と入力。
2. 「ロジック アプリ」を選択。
![LogicApps作成1.PNG](https://qiita-image-store.s3.amazonaws.com/0/146789/2c35b060-8a01-56a7-d723-17244d63f24f.png)

3. 以下のような画面になるので、「＋追加」をクリック。
![LogicApps作成2.PNG](https://qiita-image-store.s3.amazonaws.com/0/146789/e30ffabf-08eb-b67c-6f19-0ffa4ec68194.png)

4. ロジックアプリの作成に必要な設定値をセットし、「作成」をクリック。
![LogicApps作成3.PNG](https://qiita-image-store.s3.amazonaws.com/0/146789/061e6415-051d-372d-f6e9-98b8dd1b5f9d.png)

5. 作成が完了すると、以下のような画面に。
![LogicApps作成4.PNG](https://qiita-image-store.s3.amazonaws.com/0/146789/15b61dad-6b89-644c-7232-c933acd5cee7.png)

6. 左側の開発ツールの下にある「ロジック アプリ デザイナー」をクリック。
7. 下にスクロールし、「空のロジック アプリ」をクリック。
![LogicApps作成5.PNG](https://qiita-image-store.s3.amazonaws.com/0/146789/86333645-4f45-4db6-ba6a-95b61a7ccab7.png)

#定時実行するトリガーの設定
1. 検索窓に「スケジュール」と入力し、表示された時計アイコンの「スケジュール」をクリック。
![一日に一回実行1.PNG](https://qiita-image-store.s3.amazonaws.com/0/146789/a7b6c8a5-b603-a80b-6fdb-1b36c5bcc6d3.png)


2. 以下のような画面が表示されるので、「繰り返し」をクリック
![一日に一回実行2.PNG](https://qiita-image-store.s3.amazonaws.com/0/146789/8fd1ac13-27cb-e964-63ee-1114da4d8970.png)

3. 繰り返しの設定をしていきます。ここでは一日に一回実行したいので、間隔を「1」、頻度を「日」に設定し、詳細オプションをクリックします。
![一日に一回実行3.PNG](https://qiita-image-store.s3.amazonaws.com/0/146789/30a4e9be-1ac9-b1d0-f5fe-308010778d81.png)

4. 開始時刻を設定します。毎朝日本時間の7時30分に実行したいので、以下のように設定します。
・タイムゾーン：(UTC+09:00) 大阪、札幌、東京
・設定時刻（時間）：7
・設定時刻（分）：30

![一日に一回実行4.PNG](https://qiita-image-store.s3.amazonaws.com/0/146789/2e806b52-d24b-2c32-ecbb-46271e63af1e.png)

プレビューに「毎日の7:30に実行する」と表示が出て、わかりやすいですね！

トリガーの設定は以上です。
実行したいアクションを設定後、
Logic Apps デザイナーの上部にある「保存」アイコンをクリック。
そのあと、「実行」アイコンをクリックして、動作させてみてください。
PythonでGUI 

#環境
ubuntu LTS 18.04
Python 3.7.0

#事前準備

Terminalから`pip install PyQt5`を実行

#コード内容

```Python:Python
import sys
from PyQt5 import QtWidgets as qt

if __name__ == '__main__':
    app = qt.QApplication(sys.argv)

    windows = qt.QWidget()
    windows.show()

    sys.exit(app.exec_())
```

#実行結果![Screenshot from 2018-10-28 21-04-39.png](https://qiita-image-store.s3.amazonaws.com/0/287072/241ea117-4e42-be2c-073b-289475d8ab73.png)
CSSだけでハロウィン気分の404ページ作った

前回アンパンマンをCSSでお絵描きしました。
<a href="https://qiita.com/deren2525/items/3e6e606a8864a6c62ede" target=”_blank”>CSSだけでお絵描き（CodePen） </a>

今までCSSアニメーションをあまり使ったことがなく、使ってみたかったので
勉強がてら、CodePenで1つ作ってみました。
今回も記録用です。

## ハロウィン気分の404

CSSで404ページを作りました。画像は使用してないです。
ページがないのはいたずらされたってことにすればいいじゃない...というコンセプトで
※スマホで見るとひどいのでオススメしないです( ；∀；)...
<p data-height="574" data-theme-id="0" data-slug-hash="zmbErV" data-default-tab="result" data-user="deren2525" data-pen-title="CSS 404page Halloween" class="codepen">See the Pen <a href="https://codepen.io/deren2525/pen/zmbErV/">CSS 404page Halloween</a> by Deren (<a href="https://codepen.io/deren2525">@deren2525</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## CSSアニメーションを使用したところ

今回4つのモジュールにアニメーションを加えました。
全部シンプルです。

- [コウモリ](#コウモリ)
- [おばけ](#おばけ)
- [館の窓](#館の窓)
- [墓](#墓)

以下、アニメーション部分のみ抜粋したものを書きます。

### コウモリ

コウモリの動きです。上下移動をループしています。

```style.scss
.bat {
  animation: bat 5s linear infinite alternate;
}

// コウモリの動き
@keyframes bat {
  0% {
    transform: translateY(0);
  }

  100% {
    transform: translateY(-30px);
  }
}
```

以下、コウモリの羽の動きです。少し回転をつけました。
右の羽と左の羽で分けています。

```style.scss

.bat {
  &__right-wing { // 右の羽
  animation: bat 5s linear infinite alternate;
  }
  &__right-wing { // 左の羽
  animation: bat 5s linear infinite alternate;
  }  
}

// 右の羽
@keyframes bat-right-wing {
  0% {
    transform: rotateZ(0);
  }

  100% {
    transform: rotateZ(-20deg);
  }
}

// 左の羽
@keyframes bat-left-wing {
  0% {
    transform: rotateZ(0);
  }

  100% {
    transform: rotateZ(20deg);
  }
}
```
### おばけ

右左を行ったり来たりしています。ある程度進んだら折り返します。
びみょーーに上にも上がっています。わずかですが

```style.scss
//おばけの動き
.ghost {
  animation: ghost 20s linear infinite;
}

@keyframes ghost {
  0% {
    transform: translateX(0) rotateY(0);
  }
  45% {
    transform: translateX(190px) translateY(20px) rotateY(0);
  }
  50% {
    transform: translateX(200px) translateY(10px) rotateY(180deg);
  }
  95% { 
    transform: translateX(10px) translateY(10px) rotateY(180deg);
  }
  100% {
    transform: translateX(0) rotateY(0);
  }
}

```

### 館の窓

館の窓の色が微妙に変わるようにしています。

```style.scss
$BG_WINDOW: #F6E833;
$BG_WINDOW_MODIFY: #F0DB90;

// 窓の色
.house {
  &__window {
    animation: window 3s linear infinite;
  }
}

@keyframes window {
  0% {
    background-color: $BG_WINDOW;
  }

  100% {
    background-color: $BG_WINDOW_MODIFY;
  }
}
```
### 墓
ゆらゆら揺らしました。3つの墓がバラバラに揺れるようにそれぞれに時間を変えています。

```style.scss
.grave {
  animation: grave 3s linear 3s infinite; // 大きい墓
  &--mini {
    animation: grave 2s linear 3s infinite; // 小さい墓
    &:nth-of-type(2) {
      animation: grave 3.5s linear 3s infinite; // 小さい墓2つ目
    }
  }
}

@keyframes grave {
  0% {
    transform: rotateZ(0);
  }
  
  25% {
    transform: rotateZ(10deg);
  }
  
  50% {
    transform: rotateZ(0);
  }
   
  100% {
    transform: rotateZ(0);
  }
}
```

## 所感

シンプルなアニメーションですが、シンプルでもなんか動いていると嬉しくなっちゃいますね。次は複雑なものにもチャレンジしたいです。

1日で作ったわりにはなかなかの出来で満足したのですが、ハロウィンはもうすぐ終わりますね。短い命。少し悲しい。
次はクリスマスでしょうか

## 追記(2018/11/01)
ハロウィンおわっちゃった！！！！
[Lightning Network] Lightning Charge のインストール

Ubuntu 16.04 を使用する。

Lightning Charge とは、clightning を REST API にするツール。
基本的に[公式](https://github.com/ElementsProject/lightning-charge)のとおりに入れれば入る。

### Bitcoin および clightning(cln) のインストール

[こちら](https://qiita.com/jiyu/items/7130ddb49e532ac96ff0)で解説しました。

### nodejs と npm のインストール

```
sudo apt update
sudo apt install curl
curl -sL https://deb.nodesource.com/setup_8.x | sudo bash -
sudo apt install nodejs
node -v # バージョンが表示されれば成功
npm -v # バージョンが表示されれば成功
```
Lightning Charge は node のバージョンが新しすぎると動かないので、バージョンを簡単に変更できるように`n`を入れておく。

```
sudo npm i -g n
sudo su - # rootにならないと n が効かない
n 8.9.0 # とりあえずこのバージョンでは動いた
```

### Lightning Charge のインストール

npm でやるとエラーが出るので、yarnで入れる

```
sudo npm i -g yarn
sudo yarn global add lightning-charge
```

早速起動。以下に注意する。

 - 9112番ポートを開放するのを忘れずに
 - "midori" が API アクセスの為のシークレットトークンとなるため、適当な文字列に置き換える
 - ~/.lightning を lightning-dir に指定して lightningd を立ち上げた前提
 - charge.db は ~/.lightning/charge.db に配置することにした
 - --host を 0.0.0.0 にすると、外部からのアクセスも受け入れるようになる

```
charged --api-token midori --ln-path ~/.lightning --db-path ./charge.db --port 9112 --host 0.0.0.0
```

サーバ内部から叩いてみる。

```
curl http://api-token:midori@localhost:9112/info
```

結果が返ってくれば成功。
外部から叩く場合は、`localhost`をIPアドレスに置き換えればよい。

```
curl http://api-token:midori@testnet.cln.green:9112/info
```

こうすると以下が返ってくる。

```
{"id":"031201e62297a420a3878d0d8b7c4206553d354097da1a9e7c34158303d9223569","alias":"HAPPYBAGEL","color":"031201","address":[],"binding":[{"type":"ipv6","address":"::","port":9735},{"type":"ipv4","address":"0.0.0.0","port":9735}],"version":"v0.6.2-4-gaab9155","blockheight":493441,"network":"testnet","msatoshi_fees_collected":0}
```
uWSGI の簡単な使い方

Arch Linux でのインストール

```bash
sudo pacman -S uwsgi
sudo pacman -S uwsgi-plugin-python
```

```py:foobar.py
# -*- coding: utf-8 -*-
#
#	foobar.py
#
#						Oct/18/2018
# 
# ------------------------------------------------------------------
def application(env, start_response):
	start_response('200 OK', [('Content-Type','text/html')])
	rvalue = b"<h2>Hello World</h2>"
	rvalue += b"<blockquote>"
	rvalue += b"\tTest<p />"
	rvalue += b"</blockquote>"
	rvalue += b"\tOct/28/2018 PM 20:36<p />"
	return rvalue
# ------------------------------------------------------------------
```

サーバーの起動

```bash
uwsgi --plugin http,python --http :9090 --wsgi-file foobar.py
```

クライアントで http://localhost:9090/ にアクセス
![uwsgi_oct28.png](https://qiita-image-store.s3.amazonaws.com/0/179446/ed70f892-238d-79d1-9f71-10b41364a474.png)

確認した環境

```text
$ uname -a
Linux iwata 4.18.16-arch1-1-ARCH #1 SMP PREEMPT Sat Oct 20 22:06:45 UTC 2018 x86_64 GNU/Linux
[uchida@iwata uwsgi]$ python --version
Python 3.7.1
[uchida@iwata uwsgi]$ uwsgi --version
2.0.17.1
```
QEMUでRaspberry Pi 64bit + リアルタイムOS(TOPPERS/FMP)をエミュレートする

<img src="https://qiita-image-store.s3.amazonaws.com/0/176334/0dfe6938-0602-9359-b3a8-13ab7fde7de9.jpeg" width=60%>

# QEMUでリアルタイムOSを動かす

以下のRaspberry Pi 3 AArch64モード + TOPPERS/FMPカーネルの環境をQEMUでエミュレートする．
https://qiita.com/toshinaga/items/672c41a1f390922d5bae
実機レスの動作，検証が可能になる．

## 必要な機材

 - Linux PCのみ  
ビルド，および動作に使用する．  
VirtualBox + Ubuntu 16.04上を使用した．

## 開発環境の構築

 - コンパイラ
以下からフリーのARMv8 AArch64用コンパイラを入手する．
https://www.linaro.org/downloads/
Versionは`gcc-linaro-6.3.1-2017.02-xxx_aarch64-elf`を使用した．
xxxはPC環境によって適切なものを選択する．
ダウンロードして適当な場所に展開したら以下にpathに通す．
`<解凍したディレクトリ>/gcc-linaro-6.3.1-2017.02-xxx_aarch64-elf/bin`

 - コンフィギュレータ
以下からコンフィギュレータを入手する．
https://www.toppers.jp/cfg-download.html


 - QEMU
以下を実行してQEMUをインストールして，`~/opt/qemu/bin`にpathを通す．

```shell-session
git clone git://git.qemu.org/qemu.git
cd qemu
# git checkout stable-2.12  # 2018/10/26時点の最新stableにはUART割込みにバグがありmasterを使用する
git submodule init
git submodule update --recursive
cd ..
mkdir qemu_build
cd qemu_build
../qemu/configure --prefix=~/opt/qemu --target-list=aarch64-softmmu
make
make install
```
## ビルド

リポジトリを取得してfmpをビルドする．

```shell-session
git clone https://github.com/YujiToshinaga/RPi64Toppers.git
cd RPi64Toppers/fmp
mkdir -p cfg/cfg
mv <コンフィギュレータを解凍したディレクトリ>/cfg cfg/cfg
chmod 755 cfg/cfg/cfg
mkdir build
cd build
perl ../configure -T rpi_arm64_gcc
make fmp
```

## 起動

ビルドしたfmpを引数に指定して以下を実行する．

```shell-session
qemu-system-aarch64 -M raspi3 -m 256 -serial null -serial mon:stdio -kernel fmp -nographic -smp 4
```

QEMUを終了するには Ctrl-a, x を実行する．

## GDB（デバッガ）を用いた起動

GDBからQEMUに接続することで、GDBのコマンドによるステップ実行やブレーク，QEMUのコマンドによるレジスタの中身の参照などのデバッグが可能になる．

ターミナルを開き，QEMUを起動する．

```shell-session
qemu-system-aarch64 -M raspi3 -m 256 -serial null -serial mon:stdio -S -gdb tcp::1234 -nographic -smp 4
```

さらに別のターミナルを開き，GDBを実行してFMPを実行する．

```shell-session
aarch64-elf-gdb fmp
(gdb) target remote localhost:1234
(gdb) load
(gdb) monitor system_reset
(gdb) continue
```
Typescript基礎まとめ

## はじめに

これは、現在の案件でTypescriptを使用しているため、今まで学習してきたことを簡単にまとめた記事になります。

## typescriptで指定できる型

* number: 数値型
* string: 文字列型
* boolean: 真偽型
* symbol: シンボル型
* any: 任意の型
* オブジェクト型

number/string/boolean/symbol型は、標準で利用できるという意味で、Primitive Type(プリミティブ型or基本型)と呼ばれる。

型推論により、Typescriptは変数宣言で型指定が省略されている場合でも、型チェックを行う。

ただし、型・初期値ともに省略すると、変数はすべてany型になる。どんな型も受け入れてしまうので、原則letを使うときは初期値は省略しない方がいい。

```typescript
let data;
data = 10.5;
// toFiexdは引数に与えた
console.log(data.toFixed(0));
=> 11

data = 'hoge';
// charAtは引数に与えた数の位置にある文字列を返す。１
console.log(data.charAt(0));
=> h
```

#### charAt
https://www.ajaxtower.jp/js/string_class/index9.html
#### toFixed
https://www.ajaxtower.jp/js/number_class/index5.html

## 型アサーション

互換性のある型である場合、<型名>という記述を変数やリテラル前付与することで、型を明示的に変換してくれる。

```typescript
function show(result: string) {
    return`結果は結果は${result}です`;
}

console.log(show(100));
// 渡しているのはnumber型だが、string型に変換している
console.log(show(<any>100));
// asでも同様。
console.log(show('100' as any));
```

## 配列の定義方法
配列の目印として[](ブラケット)を使って、次のように定義する。

#### 例
```typescript
let hoge: string[] = ['fuga', 'mogo'];
```

#### [構文]
```typescript
let name: type[] = initial
```
name: 定義する配列名
type: 配列のデータ型
initial: 配列の初期値

typeについては、エイリアスとして次のように定義することもできる。

```typescript
let name: Array<type>
```

これはジェネリック記法と呼ばれるもので、Rubyでいうとこの%記法的な立ち位置。

ただ、基本的には`type[]`のほうがわかりやすい。

なお、空配列を定義する際は、次のように行うほうが` new Array` するよりもわかりやすくて、シンプル。

```typescript
let data: number[] = [];
```

## 連想配列
いわゆるハッシュ。

#### [構文]
```typescript
let name: { [index: i_type]: v_type] } = initial
```


name: ハッシュ名
i_type: インデックスのデータ型
v_type: 値のデータ型
initial: オブジェクトリテラルの初期値
index: インデックスを表す予約語(これは固定)


ハッシュへのアクセス方法は2種類ある。

1.  プロパティ構文
.(ドット)でアクセスする方法
`console.log(data.hoge)`

1. ブラケット構文
ブラケットでアクセスする方法
`console.log(data['hoge'])`

ちなみに、何度も同じハッシュを使うのであれば、名前付きの型(interfaceを使用)を定義することもできる。

```typescript
interface StringMap {
  [index: string]: string;
}

let object: StringMap = {
  'hoge': 'ほげ',
 'fuga': 'ふが',
 'bar': 'ばあ';
}
```
VirtualBox上のCentOS7にdockerでPHP+Apache環境を構築

## はじめに
ローカル環境にVirtualBoxを使用して開発環境を構築する作業の２回目です。
[前回](https://qiita.com/spaciba_h_t/items/e9dac4de27c7d44c5be6)はDBサーバを構築しました。
今回はWEBサーバを構築します。phpinfoを表示します。
構成はPHP + Apache を想定しています。

## 作業環境
- MacOS X Yosemite 10.10.5 

## 1.phpinfoを用意

今回はまずphpinfoを表示できる環境を構築します。
phpinfo.phpを用意します。

```
# vim phpinfo.php
```
```phpinfo.php
<?php
phpinfo();
?>
```

## 2.Dockerfileの作成
Apache + php をインストールするDockerfileの作成を行います。
DockerFikeでは、Apache モジュールが同梱された PHP コンテナイメージをベースとして使用。
先ほど作成したphpinfo.phpコンテナイメージに同梱するよう COPY を使ってphpinfo.phpをコンテナに含めるようにしています。

```
# vim Dockerfile
```
```
FROM php:apache
COPY ./phpinfo.php /var/www/html/
```

## 3.Dockerイメージを作成
docker build コマンドを使って、新たな自前 Docker イメージを作成します。
dockerfileと同じディレクトリで実行します。

```
# docker build -t web-server .
```

以下のようなメッセージが表示されて、Dockerイメージがされます。

```
Sending build context to Docker daemon 15.36 kB
Step 1/2 : FROM php:apache
Trying to pull repository docker.io/library/php ... 
apache: Pulling from docker.io/library/php
802b00ed6f79: Already exists 
59f5a5a895f8: Pull complete 
6898b2dbcfeb: Extracting [==============================================>    ] 62.39 MB/67.43 MB
8e0903aaa47e: Download complete 
2961af1e196a: Download complete 
71f7016f79a0: Download complete 
5e1a48e5719c: Download complete 
7ae5291984f3: Download complete 
725b65166f31: Download complete 
e90b121f9520: Download complete 

Digest: sha256:13f2eba8db9eb40f4a4f38a43716518513991d70698da28d56069ad9119abfab
Status: Downloaded newer image for docker.io/php:apache
 ---> a7d68dad7584
Step 2/2 : COPY ./phpinfo.php /var/www/html/
 ---> f24ea4de6996
Removing intermediate container eb8dcdd70b1e
Successfully built f24ea4de6996
```

## 4.Dockerイメージの確認
Dockerイマージが作成されたか確認します。

```
# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
web-server           latest              f24ea4de6996        13 seconds ago      378 MB
```

## 5.Dockerイメージの起動
作成したDockerイメージを起動します。

```
docker run --name phpinfo -p 80:80 -d web-server
```

## 6.アクセス確認
起動ができたら、ブラウザから起動したイメージのphpinfoにアクセスしてみます。
アクセスできたら、成功です。

http://【VirtualBox IPアドレス】/phpinfo.php

***

ここまででWebサーバも構築することができました。
次回は、DBサーバ＋WEBサーバ＋PHPアプリまでを実施するところまでを
まとめたいと思います。

## 参考URL
https://qiita.com/kumatch/items/7ea3bd4f87237980a399
https://qiita.com/nagi244/items/a13bf66d9eb6780ebcef
Picture-in-Picture on WebRTCが実現できるのか試してみた

# この記事はなに？
Chrome 70からデフォルトで有効になったらしいPicture-in-Picture（以降PinPと呼ぶ）がWebRTC MediaStreamでも実現できるのか調査&試してみたまとめ記事。


# そもそもPinPってなに?
ひとつの画面の隅などに小さく別の画面の表示領域を設け、両方の画面を同時に表示させておけるようにする表示法のこと。
スマホでYouTube動画を見たあとに戻ると右下に動画ウィンドウができると思うが、あれ。video要素に対してPinP機能が使える。

# 調査した内容

##  PinPの背景
- 2016/09にsafari9.0(macOS sierra)で実装されたよ
https://developer.apple.com/library/archive/releasenotes/General/WhatsNewInSafari/Articles/Safari_9_0.html

- その6ヶ月後にAndroid8.0のリリース時にChrome for Androidで実装されたよ
https://developer.android.com/about/versions/oreo/android-8.0#opip

- Chrome for DesktopでM68から実験的に実装されたよ
https://twitter.com/KevinCTofel/status/996040615648485376

- 2018/10/19にM70でデフォルトでPinP有効になったと報告
https://plus.google.com/+FrancoisBeaufort/posts/CmhhqTpbC1b

- **(!!) Media Streamに対応したとの報告あり**
https://chromium-review.googlesource.com/c/chromium/src/+/1196515



## PinP on WebRTCのブラウザ対応調査

WICGが以下でPinP APIを提案している。標準化に向けて頑張っている。
https://wicg.github.io/picture-in-picture


[SkyWay P2P-videochatのサンプルアプリ](https://github.com/skyway/skyway-js-sdk/tree/master/examples/p2p-videochat)にPinP機能を付け加えてPinP on WebRTCが対応しているかブラウザ検証してみた。（書いたコードは省略。index.htmlとscript.jsを[ここ](https://wicg.github.io/picture-in-picture/#example-add-custom-pip-button)と全く同じコードを追加した）


- :x: FF62, FF63
PinP APIに対応していない。(`documenｔ.pictureInPictureEnabled = false`)

- :x:[（注）](https://qiita.com/monmee/items/b1ab558fb024a3b035c1#%E6%B3%A8) Safari12
PinP APIに対応していない。(`document.pictureInPictureEnabled = false`)
しかし、実際PinP on WebRTCは実現可能。詳しくは[（注）](https://qiita.com/monmee/items/b1ab558fb024a3b035c1#%E6%B3%A8)で後述。

- :x: M70
`NotSupportedError` が出力されておりフォーマット未対応で使えない。

- :o: M71
デフォルトでは`The use of VideoLayer for video Picture-in-Picture is not supported` と出力され使えない。
しかし、 chrome://flags/#enable-surfaces-for-videos から`Enable the use of SurfaceLayer objects for videos.` をEnabledにするとPinP on WebRTCが実現できる。
- :o: M72
デフォルトで対応しており実現可能である。

### （注）
後から試してみたが、SafariはWICG提供のAPIには対応していないがSafari APIを使うとPinP on WebRTCは実現できる。
https://developer.apple.com/library/archive/releasenotes/General/WhatsNewInSafari/Articles/Safari_9_0.html


## ちょっと試してみた
SkyWayが提供している [SkyWay Conference](https://conf.webrtc.ecl.ntt.com/) の開発版をちょっといじって動作を試してみた。
以下はM72で試してみたときの図。メインスクリーン一番右上のメニューをクリックするとPinPモードに入れる。
<img width="1394" alt="スクリーンショット 2018-10-27 11.07.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/148447/e951e392-f0ff-cf6a-4387-b9f8d5582b71.png">

# おわりに

ざっくりまとめると、ブラウザアプリやそのバージョンにもよるが、WebRTC MediaStreamでもPicture-in-Picture機能は使える。

今後やりたいことは、PinPウィンドウ内のカスタマイズ。
例えば今回サンプルで使ったSkyWay Conferenceだと接続相手の名前表示とか、他の接続相手にウィンドウを切り替えるなどのメニューを作るとか。
（PinPウィンドウのカスタマイズ方法についてまでは未リサーチなので、もし知見がある方がいらっしゃればぜひご教授お願いします。）
nullは型を明示する

```Tips0031
class Tips0031 {
  public void someMethod() {

    // 代入文やメソッドを呼出す時に、単にnullと書いただけでは分かりにくいので、型を明示するとよい。
    // 次のような場合には、わざわざ明示する必要はない。
    String str = null;
    //
    // しかし変数宣言と代入文が離れている時には、明示した方がよい。
    //
    // 他の処理
    //
    str = (String)null;
    //
    // またメソッドを呼び出すときには
    otherMethod(null);
    // 上記よりも、下のようにした方がよい
    otherMethod((String)null);
    //
  }
  //
  private void otherMethod(String str) {
    // 何らかの処理
  }
}
```
LXD上でDockerを動かす方法

## 2018/11/27 追記
Dockerサービスの起動に失敗する場合は、以下を参照ください。
https://qiita.com/tabimoba/items/4f7af774145c0dbd70d9

## 1.コンテナの作成
dockerプロファイルはLXD 2.14より削除されました。

- https://discuss.linuxcontainers.org/t/lxd-2-14-has-been-released/157
-  https://github.com/lxc/lxd/issues/3615

Google等で検索すると、dockerプロファイルを指定した手順が検索結果に引っかかりますが、上記理由によりdockerプロファイルを指定した手順はエラーになります。このため、今後は以下の手順で進めていきます。

LXDコンテナでDockerを動作させる際は、以下の通りオプションを付加して、コンテナを作成します。
※ ```-c security.privileged=true``` （特権コンテナとしてLXDコンテナを動作させる）は作成されるDockerコンテナによっては正常に動作しない場合があるため、ここでは付加しています。

### Ubuntu 18.04

```
# lxc launch ubuntu:18.04 <LXDコンテナ名> -c security.nesting=true -c security.privileged=true
```

### Ubuntu 16.04
ディストリビューションの標準パッケージで提供されるLXDを使用する場合は、従来通りdockerプロファイルを指定した手順で対応します。（下記参照）

- https://qiita.com/m-shibata/items/c4dedc6055d2e6093c63

LXD 2.14およびそれ以降を利用している場合は、次のコマンドを実行します。

```
# lxc launch ubuntu:16.04 <LXDコンテナ名> -c security.nesting=true -c security.privileged=true
```

## 2.Docker CEのインストール
https://docs.docker.com/install/linux/docker-ce/ubuntu/ を参考にインストールを進めます。（LXDコンテナに入っている状態で以下のコマンドを実行します）

```
$ sudo apt-get remove docker docker-engine docker.io
$ sudo apt-get update
$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce
```

## 3.DockerコンテナをLXDコンテナ上で作成する
LXDコンテナへ入り、Dockerでhello-worldを実行してみます。（hello-worldというDockerイメージからDockerコンテナを作成して、実行してみます）

```
$ lxc exec <LXDコンテナ名> /bin/bash
# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
d1725b59e92d: Pull complete
Digest: sha256:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
```
Unity Admob バナー広告表示スクリプト/リンクまとめ

###注意
手順ややり方は詳しく書いていないです。
詳しく知りたい方は[Get Started | Google AdMob > Mobile Ads SDK > Unity](https://developers.google.com/admob/unity/start)を参考に進めていってください。
また、このコードはバナー広告を表示させます。
他の種類の広告は[Interstitial](https://developers.google.com/admob/unity/interstitial)や[Rewarded video](https://developers.google.com/admob/unity/rewarded-video)を参考にしてください。

---
###プラグイン
[Google Mobile Ads Unity Plugin](https://github.com/googleads/googleads-mobile-unity/releases/tag/v3.15.1)から**GoogleMobileAds.unitypackage**をダウンロード＆インポート。

---

###スクリプト
空のオブジェクトを作成しそれにアタッチする。
Main Cameraじゃできないという報告もあった気がする...

IDはAdMobのコンソール画面から取得してくる必要がある。

```c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GoogleMobileAds.Api;

public class AdMob : MonoBehaviour
{
    private BannerView bannerView;
    public void Start()
    {
        string appId = "ca-app-pub-XXXXXXXXXXXXXXXX~XXXXXXXXXX";
        MobileAds.Initialize(appId);
        this.RequestBanner();
    }

    private void RequestBanner()
    {
        string adUnitId = "ca-app-pub-XXXXXXXXXXXXXXXX/XXXXXXXXXX";
        bannerView = new BannerView(adUnitId, AdSize.Banner, AdPosition.Bottom);
        AdRequest request = new AdRequest.Builder().Build();
        bannerView.LoadAd(request);
        bannerView.Show();
    }
}
```
広告サイズを変更するには[こちら](https://developers.google.com/admob/unity/banner#optional_custom_ad_sizes)を参照。

---
###XML
プラグインの中に含まれている**AndroidManifest.xml** (パス：Assets/Plugins/Android/GoogleMobileAdsPlugin)を編集する必要がある。
(プラットフォームがiPhoneの場合はこの作業は必要ない。)

**AndroidManifest.xml**

```
<manifest>
    <application>
        <!-- Sample AdMob App ID: ca-app-pub-XXXXXXXXXXXXXXXX~XXXXXXXXXX -->
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="[SAMPLE_ADMOB_APP_ID]"/>
    </application>
</manifest>
```

**ca-app-pub-XXXXXXXXXXXXXXXX~XXXXXXXXXX**には自分のアプリIDを当てはめる。
Windows Subsystem for Linux(WSL)にPuTTYでアクセスする

## 経緯
`Windows Subsystem for Linux`で、`Ubuntu`を使っていますが非常に便利です。
WSLを導入してしばらくはコマンドプロンプト(cmd)でやっていましたが、いかんせんコピペがうまくできない！
マウスを使えばできないこともないけど、どうやっても`キーボードだけでコピペができる方法がわかりませんでした`。
他は許せるけどこれだけが不満…

そこで、普段使用しているPuTTYからWSLにsshアクセスしてみることにしました。

## 小話
ちなみに`WSL`は以下のような別名もあり、ググるときは両方共検索してみたほうがいいかもです。

- Windows Subsystem for Linux(WSL)
- Bash on Windows(BoW)

## 手順
### 元々入っている sshサーバーを削除
なぜか元々入っているsshサーバーだとうまくいかない…。原因はわからないけど思考停止して削除しちゃいます。

```shell-session
$ sudo apt-get remove openssh-server
```

### 新規でsshサーバーをインストール
```shell-session
$ sudo apt-get install openssh-server
```

### sshd_configを編集
ここは個人の自由ですが、少しセキュリティ関連の設定をします。

```shell-session
$ sudo vim /etc/ssh/sshd_config
```

以下は私がとりあえず気にしている項目です。

```bash
# rootログインを拒否
PermitRootLogin no

# パスワード認証を拒否
PasswordAuthentication no

# 空パスワードを拒否
PermitEmptyPasswords no
```

### sshサーバーを再起動
```shell-session
$ sudo /etc/init.d/ssh restart
```
うまくいかない場合は以下のコマンドも試してみます。

```shell-session
$ sudo service ssh --full-restart
```

### PuTTYにてアクセス
PuTTYで、`localhost:22`で接続してみてください。
WindowsからWSLにアクセスできるようになったと思います。

これでいつも使っているPuTTYでWSLが扱えます！
Autohotkey プログラムを起動&最小化&アクティブを一つの関数で行う。

- ホットキーでプログラムのフルパスを渡すと
- 起動されていれば、
  - プログラムをアクテイブにする。
  -  すでに、アクテイブなら最小化する。
- 起動されていなければ、起動する。


```
#1::RunActivateMinimize("notepad.exe")
#2::RunActivateMinimize("notepad.exe", "test.txt")

RunActivateMinimize(exePass, exeOption="") {
  SplitPath, exePass, exeName
	Process, Exist, %exeName%
    Sleep, 200
	If (ErrorLevel != 0)
    IfWinNotActive, ahk_pid %ErrorLevel%
  		WinActivate, ahk_pid %ErrorLevel%
    else
      WinMinimize, ahk_pid %ErrorLevel%
    else
      Run, %exePass% %exeOption%
}
```
### 更新
* 2018/11/07 起動オプションを渡せるようにした。

### トラブル
* ~~テスト時に同じホットキーを連打したら、アクテイブと最小化を繰り返すはずが、最小化されたままになる。~~ **解決:途中で `` Sleep `` を入れたら連打しても動い た。**
学生の時に知っておくべきだったと後悔したCのライブラリいろは

社会人1年目の時、仕事でC言語を使っていて、はじめて共有ライブラリの存在を理解した。
学生の時からC言語を触っていたが、ライブラリを作ったのはそれが初めてだった。
そのときに感じた疑問をふと思い出したので、つれづれなるままに記事にしてみる。

# まえがき
昔々、学生だった頃に「〇〇関数を使って〜するプログラムを作れ」というC言語の課題が出たことを思い出した。
詳細は忘れたが、ざっくり言うと

- 課題1：〜を〜する`kadai1()`関数を作れ
- 課題2：`kadai1()`関数を使って〜するプログラムを作れ

みたいな内容だった。
要するに「課題1」ができないと「課題2」は絶対にできない仕組みなわけだ。

課題の難易度はそれほど高くなく、授業内容を理解していれば難なく解けるレベルだったが、なぜか大学側から`kadai1()`関数の実装がオブジェクトファイルになって提供されていた。
たぶん、課題1が解けない学生のための救済措置だったのだと思う。
課題2の注釈に「課題1が解けない場合は`gcc -o kadai2 kadai2.c kadai1.o` でコンパイルして課題2に取り組め」みたいな記述があった気がする。

そんな些細な記憶が、今になって疑問になった。

これって、要するに`kadai1()`関数のソースコードは隠蔽して、動作だけ保証する何かを提供する行為だから、`*.so`とか`*.a`みたいなライブラリ提供にするのが一般的なんじゃないか、と。

# オブジェクトファイルとライブラリ
ライブラリはオブジェクトファイルをまとめたもの。そう自分は思っている。
ただ、ライブラリは動的だったり静的だったり共有だったり、と種類があって、用途に応じてメモリロードされるタイミングに違いをもたせられる、という認識だ。

先ほどの課題2の例で言うと、`kadai1`関数が使えればいいだけで、メモリロードのタイミングを意識する必要はないので`kadai1.o`でも`kadai1.so`でも`kadai1.a`でも問題ない。
しかし、世の中に公開するプログラムを作るなら、その提供形態はライブラリが一般的だ。オブジェクトファイルを剥き出しで提供しているソフトウェアは少ないだろう。
Javaでいうなら、`.jar`で提供することはあっても、`.class`で提供することは稀ということだ。

# でもライブラリパスを知らないとつまずく
ライブラリで提供するのが一般的、というはそうかもしれない。
だが、課題をこなす上で必要な「コンパイル」と「動作確認」の行為においては、オブジェクトファイルのままのほうが楽なのだ。
たとえば、`*.so`で提供した場合は

```
$ gcc -o kadai2 kadai2.c kadai1.so
$ ./kadai2
./kadai2: error while loading shared libraries: kadai1.so: cannot open shared object file: No such file or directory
```
こんな感じで「コンパイルは通るのに実行できない」という状況に陥り、`LD_LIBRARY_PATH`の存在を知らないと解決できない **課題の目的以外の環境問題** でつまずく学生が多発するだろう。

また、`gcc`の`-l`や`-L`オプションの存在も無視できない。
例えば「`math.h`を使いたければ`-lm`オプションをつける」ことは当時の私も知っていたが、その実態が`libm.so`を参照していて、そこにライブラリパスが通っているから、という理屈を知っているわけではなく「おまじない」として習慣化しているに過ぎなかった。
ライブラリ名も`kadai1.so`ではなく`libkadai1.so`にしないといけない、などという理由も必要になってくる。

課題1が解けない学生のための救済措置なのに、そんなことを強いていては本末転倒、というのが大学側の判断だったのだろう。


# ライブラリの使い方を知るタイミング
OpenCVやOpenGLなどの著名なライブラリを学生時代から触っていて、ライブラリの使い方や自作、提供方法を知っている人もいるかもしれない。
だが、自分の場合は会社に入ってからだった。
たまたまそういう機会に恵まれなかっただけかもしれないが、おそらく知らずに学生を卒業してしまうほうが多数派ではないかと思う。

会社に入ってから勉強すればいい。
それもそうだ。学生のうちは巨大なプログラムの保守について話しても実感が得られないだろう。
だが、自分の場合は運が悪いのか、とても苦労した。

というのも、1行修正しただけのソースコードを全プラットフォームに対してmake実行すると、数時間ビルドが終わらないような巨大なプログラムをいきなり任されたからだ。
そんなプログラムを例に初めてライブラリのいろはを勉強しようと思っても、Makefileのニッチな記述方法やメンテされていないシェルスクリプトの読解など、別のことが邪魔をして、
「だから、このソースのここをブレークポイントで止めるには`gcc`の`-g`をどこにつけばいいの？」を解読するだけでめちゃくちゃ苦労した。
**`-g`** この2バイトの文字をつけるだけでなんでこんな苦労するんだって思った。

# 結言
そういうこともあり、ライブラリの知識をもっと身近な手段で知る機会はないものか。学生の時にできれば知る機会が欲しいものだ、と感じた。
環境構築までの記事をまとめてみる

## はじめに
最近、開発環境とかデプロイ、リリース環境が
よく変わるのでこんな感じ↓のことを妄想してる今日この頃
![env(1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269640/26b114ea-11a4-2d5d-a0cb-ba375d2354d7.png)

## 現状
こんな感じ↓
![env(1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269640/5fd3d189-9b6a-19d0-5edb-f42c82759a87.png)

### Docker関連
| No | 記事一覧 |
|:---|:---|
| 004 |[Docker で alpine を使ってみた](https://qiita.com/osugizmo/items/6bc8290ec581b2053f2f) |
| 006 |[Docker で ubuntu18.04 を使ってみた](https://qiita.com/osugizmo/items/93868760864f7bb932a0) |
| 007 |[Docker Volume についてまとめてみた](https://qiita.com/osugizmo/items/a952ca6439e648d4cdaa) |

### AWS関連
| No | 記事一覧 |
|:---|:---|
| 001 |[AWS EC2でデスクトップ環境をつくる ～ Ubuntu Server 18.04 LTS GNOME編～](https://qiita.com/osugizmo/items/21578272ae2db05ab001)|

### Windows関連
| No | 記事一覧 |
|:---|:---|
| 002 | [Windows10 で Hyper-V を有効にする方法(PowerShell)](https://qiita.com/osugizmo/items/cac4b3170f42edd39dcb) |
| 003 | [Windows で Docker環境をつくる](https://qiita.com/osugizmo/items/81cc3581e8b40189c470) |
| 005 | [[失敗] WindowsでSSH環境を作る ～OpenSSH編～](https://qiita.com/osugizmo/items/70d35d1b098d6aec2b9b) |

### Misc関連
| No | 記事一覧 |
|:---|:---|
| 008 | [ポータブルなXubuntu環境を作ってみる 〜インストール編 〜](https://qiita.com/osugizmo/items/7c3e0a368aa42a746514) |
予約語_「すごいErlangゆかいに学ぼう！」_#03

# 予約語
- after
- and
- andalso
- band
- begin
- bnot
- bor
- bsl
- bsr
- bxor
- case
- catch
- cond
- div
- end
- fun
- if
- let
- not
- of
- or
- orelse
- query
- receive
- rem
- try
- when
- xor
変数・アトム_「すごいErlangゆかいに学ぼう！」_#02

# 変数
```erlang
One = 1. %% 1が変数Oneに代入された
One = 2. %% エラー。代入は一度まで
One = 1. %% 左辺の代入済の値と右辺の値が同じなら、スルーしてくれる
54 = 53 + 1. %% 証拠にこちらもスルー
54 = 54 + 1. %% エラー
two = 2. %% エラー。Erlangでは変数は大文字で始まる。小文字から始まるものはアトム。
```

# アトム
```erlang
atom. %% atomというアトム
atom_boy. %% アンダーバー使える
atom@example. %% @も使えるのね
atom = 'atom'. %% エラー起こらない。等価とみなすようだ
atom = "atom". %% エラー
```
【Unity】AdMobでバナー広告を表示する

AdMobで広告を表示しようとしたら
`'GoogleMobileAds/GoogleMobileAds.h' file not found`
でハマったので未来の自分に向けて流れを書き残しておく

# UnityにAdMobを導入
[Google Mobile Ads Unity Plugin](https://github.com/googleads/googleads-mobile-unity/releases)をダウンロードし、Unityに入れる
UnityPackageでOK

こんな感じのスクリプトを書いて、空のオブジェクトに貼ってあげる

```c#:AdMobManager
using System.Collections;
using System.Collections.Generic;
using GoogleMobileAds.Api;
using UnityEngine;

public class AdMobManager : MonoBehaviour {

	public static BannerView bannerView;
	private AdRequest request;

	void Start () {
		string appId = "xxx";
		MobileAds.Initialize (appId);
		RequestBanner ();
	}

	public void RequestBanner () {
		string adUnitId = "xxx";
		bannerView = new BannerView (adUnitId, AdSize.Banner, AdPosition.Bottom);
		request = new AdRequest
			.Builder ()
			.AddTestDevice (AdRequest.TestDeviceSimulator)
			.Build ();

		bannerView.LoadAd (request);
	}
}
```

バナー広告を表示したいときは、`AdMobManager.bannerView.Show();`
非表示にしたいときは、`AdMobManager.bannerView.Hide();`
をそれぞれ叩く

`AdPosition.Bottom`の部分を`AdPosition.Top`にすると上付き広告になったりする
今回は下に表示したかったのでBottomを採用

`.AddTestDevice (AdRequest.TestDeviceSimulator)`を書かないとシュミレータで表示されない


# AdMobに登録
よしなに[AdMob](https://apps.admob.com/)から登録して、
アプリを追加、広告ユニットの追加をする
文字を追っていけばそんなに詰まるところはないはず

アプリ->広告ユニットの設定->実装手順
をクリックすると、アプリIDと広告IDがまとめて確認できるので、
先程作ったスクリプトのIDの部分にコピペする

<img width="1002" alt="スクリーンショット 2018-10-28 18.44.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/130191/ac8384e9-49d9-95e0-95ed-93a29b8b5ac6.png">


アプリIDは数字の間に~が付いているもので、広告ユニットIDは/がついている

# Xcodeでビルド
[Google Mobile Ads SDK](https://developers.google.com/admob/ios/download) からSDKをダウンロードし、
GoogleMobileAds.frameworkをXcodeのプロジェクト（UnityでiOS向けにビルドしたもの）に追加する

`Add Files to “project”`をしろって言ってるサイトが多いけど見つけられなかった……~~（どこやねん）~~

ボタンから入れなくても、赤枠あたりの位置にドラッグ&ドロップしてあげれば入る
入れる際の確認ウィンドウで`Copy items if needed`にチェックを入れるのをお忘れなく！
チェック入れないとよくないことが起こるらしい

<img width="1133" alt="スクリーンショット 2018-10-28 18.21.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/130191/e991a27f-ac9a-1c84-57e0-48a30869c825.png">

入れることが出来れば準備完了！
問題なくビルド出来るはず！

~~ちなみにビルドは出来たけど広告は全然でない
調べてみると、なかなか提供されない場合もあるらしいので気長に待ってみる~~
`.AddTestDevice (xxx)`でデバイスIDを追加しないと出ないらしい

# おまけ

Addしたけどまたエラーが出た
`fatal error: error in backend: IO failure on output stream: No space left on device
Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang failed with exit code 1`

PCの容量がないよってエラーだった
使ってないデータ色々消したらビルドできるようになりました！
Template Methodパターン [C#]

## Template Methodパターンとは
Template Method パターンの目的は、ある処理のおおまかなアルゴリズムをあらかじめ決めておいて、  
そのアルゴリズムの具体的な設計をサブクラスに任せることである。そのため、システムのフレームワークを構築するための手段としてよく活用される。  

抽象メソッドとは、実装を持たず、メソッドの意味（規約）だけを定義したメソッドです。 抽象メソッドの実装は基底クラスでは行わず、派生クラスで行います。  
また、抽象クラスとは、 インスタンスを生成出来ないクラスのことで、 継承して使うことを前提としたクラスのことです。  

## サンプル例
小型トラック(2tトラック)と大型トラック(10tトラック)を作ろうとしたとき、特定の順序ですべて作成してほしい場合に役立ちます。
サンプルコードでは、以下の順序でトラックを作成します。

(1) パーツを購入する
(2) パーツを加工する
(3) 組み立てる
(4) 塗装する


## クラス図
抽象クラスは、TemplateMethodMakeCarクラスです。サブクラス(BigTrackクラス、SmallTrackクラス)に具体的な設計を任せます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/293729/318a4e25-e9b5-3bb0-b8b1-6317e54db50e.png)


## コード

``` cpp
using System;

namespace TemplateMethodOriginal
{
    class Program
    {
        static void Main(string[] args)
        {
            BigTrack BigTrack = new BigTrack();
            BigTrack.createMakeCar();

            SmallTrack SmallTrack = new SmallTrack();
            SmallTrack.createMakeCar();


            // 実行が一瞬で終わって確認できないので、キーの入力を待ちます
            Console.ReadLine();
        }
    }
    public abstract class TemplateMethodMakeCar
    {
        protected abstract void BuyParts();
        protected abstract void MakeParts();
        protected abstract void Assemble();
        protected abstract void PaintBody();

        public void createMakeCar()
        {
            BuyParts();
            MakeParts();
            Assemble();
            PaintBody();
        }
    }

    public class BigTrack : TemplateMethodMakeCar
    {
        override protected void BuyParts()
        {
            Console.WriteLine("大型トラックの部品を購入する");
        }

        override protected void MakeParts()
        {
            Console.WriteLine("大型トラックの部品を加工する");
        }
        override protected void Assemble()
        {
            Console.WriteLine("大型トラックの組み立てる");
        }
        override protected void PaintBody()
        {
            Console.WriteLine("大型トラックの塗装する");
        }
    }

    public class SmallTrack : TemplateMethodMakeCar
    {
        override protected void BuyParts()
        {
            Console.WriteLine("小型トラックの部品を購入する");
        }

        override protected void MakeParts()
        {
            Console.WriteLine("小型トラックの部品を加工する");
        }
        override protected void Assemble()
        {
            Console.WriteLine("小型トラックの組み立てる");
        }
        override protected void PaintBody()
        {
            Console.WriteLine("小型トラックの塗装する");
        }
    }
}

```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/293729/9d879b9f-6cb8-6d0c-db21-119974a327b6.png)
abc 100

C

```
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<list>
using namespace std;
using ll = long long;
const int INF = 1e8;
int N;
vector<int>c;
int main() {
	int N;
	int a;
	cin >> N;
	int ans = 0;
	for (int i = 0; i < N; ++i) {
		cin >> a;
		while (a % 2 == 0) {
			ans++;
			a /= 2;
		}
	}
	cout << ans << endl;
	return 0;
}
```
いや、３の意味なくね
Creating a Windows's window

###### Windowsのウィンドウを作成するための小さな詩。

ブラウザでWin32 APIの関数を検索してMSDNを参照すること。

WinMain関数を定義してその中に、
RegisterClassEx関数でウィンドウクラスを登録し、
CreateWindowEx関数でウィンドウを作成し、
ShowWindow関数でウィンドウを表示し、
GetMessage関数、TranslateMessage関数、DispatchMessage関数によるメッセージループを記述する。

WindowProc関数はコールバックの代表名。
WM_DESTROYメッセージではPostQuitMessage関数を呼び出す。
WM_PAINTメッセージの中に描画コードを書く。
それ以外の時はDefWindowProc関数の戻り値を返す。

> この詩はWhat's a Creelさんのyoutube動画を参考にしています。
> MSDN内にこのようなコンテンツもあります。
> [Get Started with Win32 and C++](https://docs.microsoft.com/en-us/windows/desktop/learnwin32/learn-to-program-for-windows)
GARMIN  vívoactive® J HR でワンタイムパスワードを表示出来る様にした話

自分が忘れそうなのでメモ。
そしてコレがQiita初投稿。

最近手に入れたGARMINさんでOTP表示できたら、ケータイ触らなくて楽だなぁと思ったら、
ちょうどいいアプリあったのでその設定方法。

# OTPのkeyの取得方法
## Google 二段階認証
* 「Googleアカウント」->「Googleへのログイン」->「二段階認証プロセス」
* OTPを登録したいアカウントでログイン
* 「認証システムアプリ」を選択
* 自分のスマホに合わせて選択
* 「認証システムの設定」でQRコードが表示されるが、「スキャンできない場合」を選択
* 「メールアドレスとこのキーを入力します。」の下に書かれているものがOTPのkey

## Yahoo! JAPAN ワンタイムパスワード
* アプリから「ワンタイムパスワード設定」を開く
* ワンタイムパスワードを登録したいIDでログイン
* 「設定の開始」で「アプリ」を開く
* ２の「アプリの設定」にある「自動設定がうまくいかない場合（手動で設定）」を開く
* 「登録コード」に記載されているコードがkey

# ワンタイムパスワードのアプリを入れて登録する
* OTP Authenticatorをインストール（vívoactive® J HR用）
    * https://apps.garmin.com/ja-JP/apps/c601e351-9fa8-4303-aead-441251559064
* type（認証方法）は自分が使いたいOTPに合わせる
    * (上のOTPだと`TimeBasedProvider`になるかと。)
* nameに任意の名前を入れる
* keyに上記で取得したkeyをスペース無しで入れる
* 終わり


# 感想
OTPにkeyなんてあったんだ。。。というとこから始まったので、ちょっと理解が進んだ気がする。
気がする。
アプリ側からの指示どおりにやると、簡単に登録できて、よくわかんないまま使っちゃってたので
触りだけでも裏側を知れて良かったかなと。