OmniAICreator/Qiita-1.07M huggingface dataset:
FormでPOST処理をしつつ画面遷移させない方法

いろいろ調べてみて、iframeを使う方法のみ上手くいったのでメモ。
参考：[Form Submit 後に画面遷移をさせない方法](http://tizio1976.blogspot.com/2015/02/form-submit.html)

formタグのtarget属性にiframeを指定。
formタグのtarget属性は送信結果をどのフレーム（ウィンドウ）に表示するのかを指定するもの。
https://www.tagindex.com/html_tag/form/form_target.html

```html:index.html
<form method="post" id="form" action="/api/upload" target="sendPhoto">
  <input type="file" capture="camera" accept="image/*" id="file-image">
  <button class="btn-send">送信</button>
</form>

<iframe name="sendPhoto" style="width:0px;height:0px;border:0px;"></iframe>
```

```javascript:script.js
const $form = $('#form')
$('.btn-send').on('click', evt => {
  $form.submit()
  $form[0].reset()
  return false
})
```

formタグのonsubmitイベントで`return false`したり、
submitボタンのclickイベントで`return false`したり、
submitボタンのclickイベントで`event.preventDefault()`したり。

これらは、ページ遷移してしまったり、一見するとAjax通信が成功しているように見えるが中身が送信されていなかったりした失敗例。
[学習用]初心者でもRails＋HerokuのPostgresqlをアップグレードして有償プランへ失敗しないで変更する手順

![postgresqlHeroku Data.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132580/d7ad2ad0-5825-3a49-6481-efe4e9885f69.jpeg)

Herokuのデータベースを有償版に帰る為、作業メモ。

アプリ名を　myapp　とします。
※適時自分のアプリ名に変えること。


# Herokuのデータベースをアップグレードするまでの流れ
## Herokuのデータベース先確認
```
$ heroku pg:info -a myapp
```

## Herokuをメンテナンスモードへ変更
```
$ heroku maintenance:on -a myapp
```

## 有償版のHerokuPostgresqlを追加
```
$ heroku addons:create heroku-postgresql:hobby-basic -a myapp
Creating heroku-postgresql:hobby-basic on ⬢ myapp... $9/month
Database has been created and is available
 ! This database is empty. If upgrading, you can transfer
 ! data from another database with pg:copy
Created postgresql-fluffy-12345 as HEROKU_POSTGRESQL_JADE_URL
Use heroku addons:docs heroku-postgresql to view documentation
```
Herokuの管理画面でも簡単に追加できます。
月9ドル課金される旨が表示されます。


## データをコピーする為、PostresをWaitしておく
```
$ heroku pg:wait
```

## 旧データベースから新データベースへコピー
```
$ heroku pg:copy DATABASE_URL HEROKU_POSTGRESQL_JADE_URL -a myapp
 ▸    WARNING: Destructive action
 ▸    This command will remove all data from JADE
 ▸    Data from DATABASE will then be transferred to JADE
 ▸    To proceed, type myapp or re-run this command with --confirm myapp

> myapp
# ここで続行するならアプリ名を入れろと言われるので　間違わずアプリ名を入れる

Starting copy of DATABASE to JADE... done
Copying... done
```

## 新データベースをディフォルト接続へに変更
```
$ heroku pg:promote HEROKU_POSTGRESQL_JADE_URL -a myapp
Ensuring an alternate alias for existing DATABASE_URL... HEROKU_POSTGRESQL_BLUE_URL
Promoting postgresql-fluffy-12345 to DATABASE_URL on ⬢ myapp... done
```

## Herokuのデータベース先の確認
```
$ heroku pg:info -a myapp
=== DATABASE_URL, HEROKU_POSTGRESQL_JADE_URL
Plan:                  Hobby-basic
Status:                Available
Connections:           0/20
PG Version:            11.2
Created:               2019-04-23 02:39 UTC
Data Size:             10.2 MB
Tables:                6
Rows:                  5445/10000000 (In compliance)
Fork/Follow:           Unsupported
Rollback:              Unsupported
Continuous Protection: Off
Add-on:                postgresql-fluffy-12345

=== HEROKU_POSTGRESQL_BLUE_URL
Plan:                  Hobby-dev
Status:                Available
Connections:           0/20
PG Version:            11.2
Created:               2019-04-23 01:40 UTC
Data Size:             10.3 MB
Tables:                6
Rows:                  5445/10000 (In compliance)
Fork/Follow:           Unsupported
Rollback:              Unsupported
Continuous Protection: Off
Add-on:                postgresql-defined-54321
```

## メンテナンスモードOFF
```
$ heroku maintenance:off -a myapp
Disabling maintenance mode for ⬢ myapp... done
```

これでHeroku無料版Postgresqlから有償版のPostgresqlへ変更できました。

無料版のPostgresqlは1万行まで
有償版のPostgresqlは1000万行まで保存可能です。
gnuplotで連番データから動画を作成する

**この記事を読むとできるようになること**
`gnuplotを使って，連番データファイルから，連番画像を保存せず一気にgif動画を作れるようになる`

動画の作り方については，一旦，連番画像を作成したのち，それらをつなげる方法をよく見かけます．
しかし，これでは二度手間ですし，画像ファイルがいっぱいになってしまい大変です．
ですので，データファイルから一気に動画を作ってみましょう．

- 環境
    - macOS Mojave 10.14.4
    - gnuplot 5.2.6

```gnuplot:gif.gp
#軸やラベルの設定など
...(省略)...

#最後の動画サイズはお好みで
set term gif enhanced animate optimize size 700, 480
set output ‘anime.gif’

#連番データファイルを次々に読み込んで描いていく
#do for[i=初めの番号:終わりの番号:読み飛ばす刻み]
do for[i=0:100:2]{
    filename = sprintf('0%03d.dat', i)
    #タイムステップを表示
    plot_title = sprintf('timestep=%d', i)
    set title plot_title
    #plot[ｘ軸の範囲][y軸の範囲]
    plot[0:1][0:1] filename u 1:2 w l
}

set out
reset
set term aqua
```

``do for`` 部分で，0000.datから0100.datを，1つ飛ばしで読み込んで繰り返し描画しています．
動画がカクカクしない程度に読み飛ばすと，gifファイルが重くなるのを防ぐことができます．
タイムステップも表示するようにしました．

`gif.gp`を実行すると`anime.gif`が作成されます．
sqlite3が消えない

#Sqlite3が消えない

herokuにアプリをプッシュしようとしたら

```
remote: ! Failed to install gems via Bundler. 
remote: ! Detected sqlite3 gem which is not supported on Heroku
```

とエラーが出る。

sqlite3がherokuではサポートされていない事が問題なようなので消してみる。。。
→と思ったらGemfileにはsqlite3は記載されていない！

でもGemのインストール結果を記すGemfile.lockにはsqlite3の記載が複数箇所ある。。。
困った。
bundle installをもう一度試しても、Gemfile.lockの方でsqlite３を消してみても変わらず。

しかし良く見てみると

```Gemfile.lock
mailcatcher
 ...
 sqlite3
 ...
```

との記載が。
どうやらmailcatcherをインストールする際にsqlite3も一緒にインストールされてしまうらしい。
mailcatcherはあくまでテスト用のGemなのでこれを削除してpushすると、エラーを吐かなかった。

でもこれって引っかかったのがたまたまテスト用のｇｅｍだからよかったけど、必要なものだったらどう対処すれば良いのかな
疲れていて犬か猫かすらわからなくなってしまったあなたへ…

人間、疲れがたまると犬や猫を見たときにそれが犬なのか猫なのか分からなくなってしまうことがあるかと思います。

昨今では、このような視覚情報の判定を機械に任せてしまおうというムーブメントが巻き起こっており、
我々は混乱した頭で正確な視覚情報を得たいときに機械を利用するという手段を得ているわけです。

さて、今回は犬か猫が分からないという問題が起きたときのために、機械に犬か猫を判定させるための学習モデルを作成してみたいと思います。

## CreateMLUI

Xcode10から利用できるようになったCreateMLを利用します。
この素晴らしいフレームワークは頭が疲れてプログラムが書けなくなってしまった人間でも、或いは、プログラムなど微塵も書けない人間ですら、簡単に利用出来る実に素晴らしいフレームワークです。

Xcodeを起動したら、「Get started with a playground」を選択し、macOSのSingleView projectを選択して適当なワークスペースにプロジェクトを作成します。
<img width="768" alt="スクリーンショット 2018-12-03 22.23.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/28406/e8b2bc13-757e-a206-6b9c-0ebe0dc34565.png">

__※macOSのSingleViewプロジェクト以外でプロジェクトを生成した場合、CreateMLが利用出来ないので注意が必要です。__

プロジェクトが起動したらエディターが表示されますので、以下のコードをエディターに貼り付けます。

```swift
import CreateMLUI

let builder = MLImageClassifierBuilder()
builder.showInLiveView()
```

コードを貼り付けたら"▶"のようなマークが行数の箇所にあるのでこれをクリックし、
右上にある○が２つ交わっているようなアイコンをクリックします。

そうすると、学習するためのUIが表示されます。
<img width="952" alt="スクリーンショット 2018-12-03 22.28.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/28406/7d31762e-399f-7187-d0d0-37df37f49962.png">


## 判定のための画像を収集する

Googleで適当に犬と猫の画像を集めてきます。
集めた画像は以下のようなフォルダ構成で分類しておきます。

```
TrainingData/
  Inu/
    犬の画像（１０枚以上）
　　　　　　　　　　　　・
　　　　　　　　　　　　・
　　　　　　　　　　　　・
  Neko/
    猫の画像（１０枚以上）
　　　　　　　　　　　　・
　　　　　　　　　　　　・
　　　　　　　　　　　　・
```

```
TestData/
  Inu/
    犬の画像（2枚以上）
　　　　　　　　　　　　・
　　　　　　　　　　　　・
　　　　　　　　　　　　・
  Neko/
    猫の画像（2枚以上）
　　　　　　　　　　　　・
　　　　　　　　　　　　・
　　　　　　　　　　　　・
```

`TrainingData`は学習用のデータで、`TestData`は学習結果をテストするためのデータです。

## 学習してみる

先程表示した学習するためのUIに"Drop Images To Begin Training"と書いてある箇所があるのでここに`TrainingData`フォルダをドラッグしすると学習が始まります。
<img width="955" alt="スクリーンショット 2018-12-03 22.35.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/28406/75087301-450e-b087-a1dd-8e5a17003d9d.png">

学習が終わると、UIに"Drop Images To Begin Testing"と書いてある箇所が増えるのでここに`TestData`をドロップして学習モデルのテストを行います。
<img width="948" alt="スクリーンショット 2018-12-03 22.40.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/28406/8001e9cb-11f0-87e8-0f14-96de2afc0115.png">

はい、このように結果が表示されました。

---

ということで、犬か猫かを判定する学習モデルを作ってみました。
この学習モデルはCoreMLフレームワークから利用出来るので簡単にアプリに自前の学習モデルを組み込むことが出来ます。

これでどんなに疲れていても犬や猫を間違える心配がありませんね！
いい時代になったものです…

尚、この投稿の内容はほぼAppleのドキュメントに記載されている内容の簡略版なので興味の湧いた人は本家ドキュメントを一読しましょう。
[Creating an Image Classifier Model](https://developer.apple.com/documentation/createml/creating_an_image_classifier_model)
nginxでTLS1.0が無効にならない

#結論
**複数サーバを設定している場合、一つのサーバだけ変更しても有効とならない**

#概要
##環境
CentOS7、nginx1.15.7

##概要
CentOS7とyumでインストールしたnginxを使用してリバースプロキシとして利用しています。
複数Siteを一台で運用するため、server_nameでおのおののSiteを記述しています。
SSLの設定もその中に記載していました。

```text:修正前
server {
       listen 443 ssl http2;
       server_name honban-site.example.com;
       ssl_protocols  TLSv1.0,TLS1.1,TLSv1.2;
       ssl_ciphers  HIGH:!aNULL:!MD5;
　　　　・・・省略
}
server {
       listen 443 ssl http2;
       server_name test-site.example.com;
       ssl_protocols  TLSv1.0,TLS1.1,TLSv1.2;
       ssl_ciphers  HIGH:!aNULL:!MD5;
　　　　・・・省略
}
```

さて、セキュリティ向上のため、TLS v1.0、v1.1は停止し、TLSv1.2のみとする設定のテストとして
test-site.example.com だけを下記のように変更しました。

```text:修正後
server {
       listen 443 ssl http2;
       server_name honban-site.example.com;
       ssl_protocols  TLSv1.0,TLS1.1,TLSv1.2;
       ssl_ciphers  HIGH:!aNULL:!MD5;
　　　　・・・省略
}
server {
       listen 443 ssl http2;
       server_name test-site.example.com;
       ssl_protocols  TLSv1.2;
       ssl_ciphers  HIGH:!aNULL:!MD5;
　　　　・・・省略
}
```


ssl_protocols  TLSv1.0,TLS1.1,TLSv1.2;　→　ssl_protocols  <font color="Red">TLSv1.2;</font>

さて、これでnginxをreloadし、SSL Server TESTサイトから確認をします。
![TLS-check.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394967/7ac3763c-5c15-b34f-f055-698b45fa4128.jpeg)

**が～～～ん、1.0,1.1ともYesですよ**
test-site.example.comの設定だけ変更しても望んだ結果とはなりませんでした。

##解決策
解決策をいろいろ探した（ぐっぐただけとも言う）けど、見つからなかった・・・

そうこうするうち、どこかのSite（すいません、思い出したらリンク張ります）で、ssl_protocolsはhttpセクションに書きましょうとの記事を見つけました。
その構成にするにはnginx自体を複数立ち上げないといけないな・・・　いっそ、別サーバを立ててしまおう。
ということで、おのおの別々のサーバにてリバースプロキシを構築しました。

そうすると、なにもなかったかのようにすんなりTLSv1.2のみとなりました。
これは推測に過ぎませんが、複数サーバでserverセクションにssl_protocolsを記載した場合、利用しているすべてのプロトコルに反応してしまうようです。
また、もとの記述で双方のserverのssl_protocolsをTLSv1.2のみにすることでもv1.0,v1.1は無効となりました。

これが正解かはわかりませんが、少なくともserver_nameで分離した定義のつもりでもssl_protocolsはすべて合わせたプロトコルに反応するので、サーバを分ける、あるいは別ポートでnginxを起動する等の対応でしのげることがわかりました。

***
2019/04/23 記載
PWA 用語メモ

PWA 関連の用語がこんがらがるので整理メモ。適時更新。
Cache 部分に関しては [Workbox](https://developers.google.com/web/tools/workbox/) のドキュメント参照してるので Workbox の仕様寄り。
考え方は PWA 共通の内容のはず。

# Cache 関連

## Precache

ServiceWorker のインストールと同時にキャッシュされる内容。PWAのコア部分（基本的に変更が無い or 変更頻度が少ないファイル）をキャッシュさせる。ここで指定されたファイル群はページで表示（取得リクエスト）されて無くても ServiceWorker のインストールと合わせてまるっとキャッシュされるっぽい。

有効期限は無し。Workbox の場合キャッシュファイルリストが更新されて不要なものが発生したらその時点で削除される（フルスクラッチで書いた場合は大元のキャッシュ名その物を変えれば消えるかと思ったけど消えなかったのでよくわからなかった）。

キャッシュさせるファイル群はフルスクラッチで書くとそもそも管理しきれない ＆ ServiceWorker 更新しても上記のように上手くキャッシュが更新されない現象に出会う頻度が高くなって何をやっているのかわからなくなる。Workbox はその部分をしれっとカバーしてくれるので便利ね、うふふってなる。

## RuntimeCache
リクエストに対するキャッシュコントロールを行える。RuntimeCache は差分検出と削除の仕組みが無いらしく、明示的に有効期限を設定したほうが良いらしい。[Workbox Strategies](https://developers.google.com/web/tools/workbox/modules/workbox-strategies#network_first_network_falling_back_to_cache) にイメージ図有り。RuntimeCache でハンドリングできる種類は以下。

### CacheFirst
キャッシュから優先して取得。キャッシュにまだなければネットワークから取得。最初 Precache との違いがよくわからなかったけどととりあえず明示的にリクエストしているかの違いと解釈。

### CacheOnly
キャッシュからのみ取得。

### NetworkFirst
ネットワークから優先して取得。ネットワークから取得に失敗した場合はキャッシュから取得。

### StaleWhileRevalidate
キャッシュから優先して取得しつつ、次回アクセス時に備えてバックグラウンドでネットワークから更新をフェッチしてキャッシュを更新。

## 参考

- [静的サイト向けWorkBoxレシピ](https://qiita.com/masato_makino/items/c85cb01d52632da42c03)
- [ServiceWorkerを簡単に書けるworkbox-swの使い方](https://qiita.com/nazonohito51/items/32b61cabdac8b24769bd)

キャッシュに関してはとりあえず以上。
キャッシュ処理だけでも色々考えること多くて WEB ページ作成もなんか複雑になってきたなぁと。

# Push 関連

[Firebase](https://firebase.google.com/?hl=ja) が使い易そう。もうちょい理解が進んだら整理。
iOSのターゲットバージョンを保護する

iOSのバージョンは、簡単に上げられる上に問題なく動作してしまう場合もあり、コードレビューでも人間の誤りを検知しにくいです。
ヒューマンエラーで重大な損害をもたらす割に、守るための方法がないなぁと思っていくつか方法を試しました。

# 実行時に保護する
この関数はAppDelegate.swiftのトップレベルに記述しています。

```swift:AppDelegate.swift
/// 意図しないミスでiOSのバージョンが変わってしまった場合は、実行時にアプリを強制終了させて検知できる。
/// - Attention : このターゲットは、iOS11.0が最低限バージョンになっているのが正しい
func protectDeploymentTarget() {
    guard __IPHONE_OS_VERSION_MIN_REQUIRED == __IPHONE_11_0 else {
        assertionFailure("Deployment target is wrong. you may miss operation or forget to fix above line.")
        return
    }
    print("No problem. You are right.")
}

```

# 1. `__IPHONE_OS_VERSION_MIN_REQUIRED` とは？
Deployment Targetを設定していると、コンパイラが、下限のiOSバージョンを設定してくれます。

# 2. `__IPHONE_11_0` とは？
`__IPHONE_OS_VERSION_MIN_REQUIRED` で取得できる値は、`Int32` の `110000` などの数値のため(iOS11の場合)、`__IPHONE_OS_VERSION_MIN_REQUIRED == 11` のような指定をすると常に実行に失敗します。などでシステム定義のバージョン数値を使います。

# ビルド時に保護する
ビルド時にターゲットバージョンを保護できます。こちらの方がより確実で、余計なソースをプロダクションコードに乗せなくせスマートです。

```sh:check.sh
if [ $IPHONEOS_DEPLOYMENT_TARGET != '11.0' ]; then
exit "iOS Deployment Target should be 11.0!"; exit 1
fi
```

こちら、 @lovee さんより教えていただきました！ありがとうございます！
ICP(IBM Cloud Private)のインストールに失敗したとき

## はじめに

ICPインストールしてみた系の素晴らしい記事ってたくさんあって、基本的にはそこ見て実施すれば問題ないはずです。
IBMの正式手順も結構わかりやすいですし。
[ICPのインストール(公式)](https://www.ibm.com/support/knowledgecenter/ja/SSBS6K_3.1.1/installing/install.html)

けど、何らかのミスでインストール失敗しちゃうことありますよね。

- やばい、ssh コピーの手順飛ばしてた！
- やばい、host IP間違えてた！
- やばい、loop backアドレスコメントアウトし忘れた！

などなど。
そーゆーとき、上記の記事を読み込み間違えを修正すると思うのですが、それでも失敗することがあります。


なぜなのか・・？


**失敗したときは一度アンインストールしてやり直す必要がある！！！**

インストールやり直しは時間がかかるので、この手順とばしちゃうと時間がもったいない、、気をつけましょう。

手順は以下です。
## ICPのアンインストール

1. インストールディレクトリー内のClusterディレクトリーに移動する

```
 cd /<installation_directory>/cluster
```
clusterディレクトリーはインストール時に作成されています。<br>
2. ICPをアンインストールする
 
```
 docker run -e LICENSE=accept --net=host \
   -t -v "$(pwd)":/installer/cluster \
   ibmcom/icp-inception:3.1.1 uninstall
```

icpのバージョンはインストール済みの内容に変えてください。
ここではCEエディションのバージョンv3.1.1をアンインストールしています。<br>
3. Dockerを再始動する

```
 service docker restart
```


[ICPのアンインストール（公式）](https://www.ibm.com/support/knowledgecenter/ja/SSBS6K_3.1.1/installing/uninstall_ce.html)

## まとめ
インストールに失敗したときは、一度アンインストールしてから再度チャレンジしましょう。
私はずっとアプリ開発を担当してきたので、こういう当たり前（なのか？）ことで躓く場面が多い。

アドバイスあればご指摘ください。
tmuxの初期設定

使用しているマシンを変更した際、tmuxの設定をし直す必要があり、confファイルを取っておかなかったことを後悔。備忘録として。

```
vi /path/to/.tmux.conf
```

**.tmux.conf**

```
# デフォルトのCtrl-bは使いづらいので、Ctrl-jに変更
unbind C-b
set-option -g prefix C-j
bind-key C-j send-prefix

# copy modeのコマンドキーバインドをemacsからviへ変更
set-option -g mode-keys vi
```

**tmux起動**

```
tmux /path/to/.tmux.conf
```
abemaビデオで、無料のみを表示するブックマークレットを、ものすごく雑に作る。

#### やりたいこと
- [abemaビデオ(アニメ)](https://abema.tv/video/genre/animation
)の下部にある一覧で『無料』のみを表示したい。
- 『無料のみ』のチェックボックスはあるけど、『一部無料』も表示されないようにしたい。
- 頑張らない。

#### 出来たもの

`javascript:document.querySelectorAll("#main > div > main > div > section > div > div > div").forEach(function(e){var muryo=e.querySelector("#main > div > main > div > section > div > div > div > a.com-m-TitleCard__link > div > div > span");if(muryo == null){e.parentNode.removeChild(e)}else if(muryo.innerText=='一部無料'){e.parentNode.removeChild(e)}});`

一応、登録用リンクも置いとこうと思ったけど、Qiitaの仕様上出来ないっぽい。
もし登録や動作確認したい人が居たら、↑をコピーして、ブックマークのURLに貼り付けてください。

##### 追記

使っていくうちに『無料』且つ『●新着エピソード』も消したくなったので、改修。

`javascript:document.querySelectorAll("#main > div > main > div > section > div > div > div").forEach(function(e){var muryo=e.querySelector("#main > div > main > div > section > div > div > div > a.com-m-TitleCard__link > div > div > span");if(muryo == null){e.parentNode.removeChild(e)}else if(muryo.innerText=='一部無料'){e.parentNode.removeChild(e)};console.log(e.querySelector('#main > div > main > div > section > div > div > div > a > span > span'));if(e.querySelector('#main > div > main > div > section > div > div > div > a > span > span')!=null){e.parentNode.removeChild(e);}});`


### やったこと
記憶ベース。使用環境/ブラウザはwindows10 home/chrome。デバッグや調査は省略。

1. https://abema.tv/video/genre/animation を開く。
2. 消したい要素を右クリックして検証。
3. 要素を選択した状態でデベロッパーツールが開かれる。
4. 目的の要素でなければ、目的の要素を探す。目的の要素であれば、右クリック→Copy→Copy JS Pathをクリック。
5. 以下の要素が取得できた。
`document.querySelector("#main > div > main > div > section.abm_c6b3d82d_b > div > div:nth-child(5) > div:nth-child(2)")`

6. querySelectorをquerySelectorAllに変更して、要素を特定しそうな要素を消す。
 `document.querySelectorAll("#main > div > main > div > section > div > div > div")`

7. デベロッパーツールのconsoleタブで、動作確認。取得成功。
8. forEachとquerySelectorで、目的の要素まで取得。中身確認。取得成功。
 なお、中身は`null` `<span>一部無料</span>` `<span>無料</span>` だった。
`document.querySelectorAll("#main > div > main > div > section > div > div > div").forEach(function(e){console.log(e.querySelector("#main > div > main > div > section > div > div > div > a.com-m-TitleCard__link > div > div > span"))})`

9. 中身が `null` の時にinnerTextが出来ないようなので、とりあえずifで分割して、要素を削除。
`document.querySelectorAll("#main > div > main > div > section > div > div > div").forEach(function(e){muryo=e.querySelector("#main > div > main > div > section > div > div > div > a.com-m-TitleCard__link > div > div > span");if(muryo == null){e.parentNode.removeChild(e)}else(console.log(e))})`

10. 残った消したい要素の `一部無料` だった時も、同様に削除する。
`document.querySelectorAll("#main > div > main > div > section > div > div > div").forEach(function(e){var muryo=e.querySelector("#main > div > main > div > section > div > div > div > a.com-m-TitleCard__link > div > div > span");if(muryo == null){e.parentNode.removeChild(e)}else if(muryo.innerText=='一部無料'){e.parentNode.removeChild(e)}});)`

11. `javascript:;` でブックマーク化して登録。完成。

#### 備考

- 消した後に『無料のみ』をチェックすると画面が真っ白になる。
Error: Unexpected key "NSMainNibFile~ipad" while parsing <dict/>

cordova build ios を実行するとエラーが発生。

```
Error: Unexpected key "NSMainNibFile~ipad" while parsing <dict/>
```

どうも cordova-ios のエラー？
[https://github.com/apache/cordova-ios/issues/572](https://github.com/apache/cordova-ios/issues/572)

plist ファイルで "NSMainNibFile~ipad" キーの値が誤って処理されていることが原因らしい。
そこで cordova-custom-config プラグインを使って該当のキーを書き換えて対処。

```
<platform name="ios">
    ...
    <custom-config-file mode="replace" parent="NSMainNibFile" target="*-Info.plist">
        <string />
    </custom-config-file>
    <custom-config-file mode="replace" parent="NSMainNibFile~ipad" target="*-Info.plist">
        <string />
    </custom-config-file>
</platform>
```

これだけでは修正が反映されないのでプラットフォームを作り直し。

```
cordova platform rm ios
cordova platform add ios
```

私の環境ではこれで修正されました。
備忘録：epubcheckが何をやっているのか解読してみた

#前回までのあらすじ
pythonでepubcheckなるモジュールを取り込んだはいいがexe化すると動かなかった。
https://qiita.com/blue_red_violet/items/af32f2f2caa5551aa350

##今回の施策：printで可視化だ！
人の書いたコードは何をやっているかが分からないので、まずエラーが出る箇所で何のデータを受け渡ししているのかを、先達の助言に従いprintで可視化してみた。

###そもそも何と格闘しているの？
epubcheckフォルダ内のchecker.py line 41にエラーが！
→上記が参照している同ファイル内line58にエラーが！
→上記が参照しているjsonフォルダ内の__init__.py line 348にエラーが！
→上記が参照している同フォルダ内のdecoder.py line 337にエラーが！
→上記が参照している同ファイル内line355にエラーが！

ということで、epubcheckモジュールとjsonモジュールにまたがってエラーが出ている。（そもそもepubcheckのchecker.pyを参照している元のファイル周りで出てるエラーは記載省略した）

##今回やってみたこと
__init__.py　line348は

```
return _default_decoder.decode(s)
```

なので、その直前に

```
print(_default_decoder.decode(s))
```
を突っ込んでみた。

###結果
出てきた出てきたjsonの中身が！
初っ端のmessagesに既に空のリストがあるんだが、これがそもそも「出せ！」とこちらで要求しているresult.messagesに該当しているのでは……？（仮にそうなら、そりゃ空だとエラー出すわ）

###副産物
epubcheckさんの働きぶりが細々分かった。

どうやらファイルごとに
・epubのopfファイル内で割り振ってあるid
・ディレクトリ＋ファイル名
・圧縮関係（圧縮時ファイル容量、非圧縮時ファイル容量、圧縮方式）※epubは一部ファイルを除きzipと同じように圧縮されている
・pythonで生成したリスト内で割り振られたid
・epubの表示周り（SpineだのLinearだのNavigationOrderだのfix型時のRendtionLayoutだのOrientationだのSpreadだの）
・他のファイルを参照しているかどうか(referencedItemsというリストを生成して、ファイル内から他ファイルを参照していたらリンク先がリストに吐き出される)

他にも、opfだけの処理も細々行っていた。省略可能なDCMES要素も混じっているので、空のリストもここで生じている。
・epubのファイル名
・epubcheckerのバージョン
・チェックした日時
・更新日
・epubcheckerの結果（チェックに要した時間含む）
・出版社
・タイトル
・クリエーター
・subject（ここが空だった）
・spine内要素の数
・リフローかフィックスか
・宣言してある使用言語は
・OrientationやSpreadは
・epubのバージョンは
・その他epubで使える要素を使っているかどうかあれこれ（列挙に疲れたので以下記載。伏せたい箇所はほにゃらら化しました）

```
{'messages': [], 'customMessageFileName': None, 'checker'
: {'path': 'ほにゃらら',
 'filename': 'ほにゃらら',
 'checkerVersion': '4.2.0-rc',
 'checkDate': '04-23-2019 09:57:22',
 'elapsedTime': 4341, 'nFatal': 0, 'nError': 0, 'nWarning': 0, 'nUsage': 0}, 'publication'
: {'publisher': 'ほにゃらら',
 'title': 'ほにゃらら',
 'creator': ['ほにゃらら'], 'date': '2019-04-23T00:00:00Z',
 'subject': [], 'description': None, 'rights': None, 'identifier': 'urn:uuid:ほにゃらら',
 'language': 'ja',
 'nSpines': 63, 'checkSum': 0, 'renditionLayout': 'reflowable',
 'renditionOrientation': 'auto',
 'renditionSpread': 'auto',
 'ePubVersion': '3.2',
 'isScripted': False, 'hasFixedFormat': False, 'isBackwardCompatible': False, 'hasAudio': False, 'hasVideo': False, 'charsCount': 63893, 'embeddedFonts': [], 'refFonts': ['serif-ja',
 'sans-serif-ja',
 'serif-ja-v',
 'sans-serif-ja-v'], 'hasEncryption': False, 'hasSignatures': False, 'contributors': []}, 

'items': [{'id': 'book-style',
 'fileName': 'item/style/book-style.css',
 'media_type': 'text/css',
 'compressedSize': 1378, 'uncompressedSize': 6207, 'compressionMethod': 'Deflated',
 'checkSum': '7594817bcbb9ba19f81dc4e68dddb203791691a4b36948985302a8f46247d',
 'isSpineItem': False, 'spineIndex': None, 'isLinear': False, 'navigationOrder': None, 'isHTML5': False, 'isFixedFormat': None, 'isScripted': False, 'scriptSrc': False, 'scriptTag': False, 'scriptInline': False, 'renditionLayout': None, 'renditionOrientation': None, 'renditionSpread': None, 'referencedItems': ['item/style/style-advance.css',
 'item/style/style-reset.css',
 'item/style/style-standard.css']},
```

##次はどうしよう
とりあえず冒頭のmessagesがどうやったら空にならなくなるのか調べるところからですね。
Javaのジェネリクス(備忘録)

### Mapの値にListを持つ
要求：
Mapの値がListで，かつこのListで管理するオブジェクトに`Child extends Parent`という関係がある．そして，各List<Child>のインスタンスが存在し，Listの中のオブジェクトをParentとして処理したい．

#### 問題点
ジェネリクスは共変じゃないので，以下ができない

```java
Map<Key, List<Parent>> map1;
Map<Key, List<Child>> map2;
map1 = map2;  // ここでコンパイルエラー
```

そこで，ワイルドカードを利用する．しかし，以下もNG

```java
Map<Key, List<? extends Parent>> map1;
Map<Key, List<Child>> map2;
map1 = map2; // ここでコンパイルエラー
```

これは，

```java
List<? extends Parent> list1;
List<Child> list2;
list1 = list2;
```
ができるのに，おかしいと思ってしまった．そして，以下が正解

```java
Map<Key, ? extends List<? extends Parent>> map1;
Map<Key, List<Child>> map2;
map1 = map2;
```

見て分かる通り，ワイルドカードを２回使わないといけなかった．
これを利用してメソッドを定義して実行してみた．

```java
  List<Integer> ilist = new ArrayList<Integer>();
  ilist.add(1);
  ilist.add(2);
  ilist.add(3);			
		
  Map<String, List<Integer>> imap = new HashMap<String, List<Integer>>();
  imap.put("1", ilist);
  doit(imap);

  public void doit(Map<String, ? extends List<? extends Number>> inmap) {
      for (String key : inmap.keySet()) {
          System.out.println("key = " + key);
          List<? extends Number> list = inmap.get(key);
          for (Number n : list) {
              System.out.println(n);
          }
      } 
  }
```

おまけ：

`List<Child>`から`List<Parent>`を値に持つMapを返すメソッド

その１

```java
public <V, K extends T, T> Map<V, List<? extends T>> convert(Map<V, List<K>> srcMap) {
    Map<V, List<? extends T>> dstMap = new HashMap<V, List<? extends T>>();
    for (V key : srcMap.keySet()) {
        dstMap.put(key, srcMap.get(key));
    }
    return dstMap;
}
```

その２

```java
public <V, K extends T, T> Map<V, List<T>> toUpper(Map<V, List<K>> srcMap) {
    Map<V, List<T>> dstMap = new HashMap<V, List<T>>();
    for (V key : srcMap.keySet()) {
	    List<T> tlist = new ArrayList<T>();
	    for (K val : srcMap.get(key)) {
		    tlist.add(val);
	    }
	    dstMap.put(key, tlist);
	}
	return dstMap;
}
```
おそらく「その２」のほうがよい．何故かと言うと，返り値の型が`Map<V, List<T>>`となるから．Effective Javaによると，「その１」のようにこのメソッドを実行側でワイルドカードを意識させる(e.g., `List<? extends T>`)ことは良くないとされるため(多分．．)

間違い等あればご指摘下さい.
【Unity】RenderTextuerからTextuer2DへしてからSpriteに変換

#前回記事にしたRenderTextuerからTextuer2Dの応用です。
https://qiita.com/tilyakuda/items/67fe8e787ab5e5679ddb

#前回公開したScript

```C#:CreateTexture.cs

     //このScriptはMainCameraにアタッチしてください

    public RenderTexture renderTexture;             //mainCameraにつけるRendertexture(アタッチしてね)
    public Texture2D kakunin;                       //ほんとに保存されているかの確認用
    Camera mainCamera;
	void Start ()
    {
        mainCamera = GetComponent<Camera>();
        kakunin = CreateTexture2D(renderTexture);
	}
	
    /// <summary>
    /// ここでTextur2Dに変換しているよ
    /// </summary>
    /// <param name="rt"></param>
    /// <returns></returns>
    Texture2D CreateTexture2D(RenderTexture rt)
    {
        //Texture2Dを作成
        Texture2D texture2D = new Texture2D(rt.width, rt.height, TextureFormat.ARGB32, false, false);

        //subCameraにRenderTextureを入れる
        mainCamera.targetTexture = rt;

        //手動でカメラをレンダリングします
        mainCamera.Render();


        RenderTexture.active = rt;
        texture2D.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
        texture2D.Apply();

        //元に戻す別のカメラを用意してそれをRenderTexter用にすれば下のコードはいらないです。
        mainCamera.targetTexture = null;
        RenderTexture.active = null;

        return texture2D;
    }

```
これにこちらの関数を追加します。

```C#:CreateSprite
	Sprite CreateSprite(Texture2D tex2D)
	{	
		Sprite sprite = Sprite.Create(tex2D,new Rect(0f,0f,tex2D.width,tex2D.height),new Vector2(0.5f,0.5f),100f);
		return sprite;
	}
```

#完成

```C#:kansei

	//このScriptはMainCameraにアタッチしてください

	public RenderTexture renderTexture;             //mainCameraにつけるRendertexture(アタッチしてね)
	public Texture2D kakunin;                       //ほんとに保存されているかの確認用
	public Sprite spriteTest;						//Sprite確認用
	Camera mainCamera;

	

	void Start()
	{
		mainCamera = GetComponent<Camera>();
		kakunin = CreateTexture2D(renderTexture);
		spriteTest = CreateSprite(kakunin);
	}

	/// <summary>
	/// ここでTextur2Dに変換しているよ
	/// </summary>
	/// <param name="rt"></param>
	/// <returns></returns>
	Texture2D CreateTexture2D(RenderTexture rt)
	{
		//Texture2Dを作成
		Texture2D texture2D = new Texture2D(rt.width, rt.height, TextureFormat.ARGB32, false, false);

		//subCameraにRenderTextureを入れる
		mainCamera.targetTexture = rt;

		//手動でカメラをレンダリングします
		mainCamera.Render();


		RenderTexture.active = rt;
		texture2D.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
		texture2D.Apply();

		//元に戻す別のカメラを用意してそれをRenderTexter用にすれば下のコードはいらないです。
		mainCamera.targetTexture = null;
		RenderTexture.active = null;

		return texture2D;
	}

	Sprite CreateSprite(Texture2D tex2D)
	{	
		Sprite sprite = Sprite.Create(tex2D,new Rect(0f,0f,tex2D.width,tex2D.height),new Vector2(0.5f,0.5f),100f);
		return sprite;
	}
}
```
Fast Stone Captureで拡大せずにWindows10のスクリーンショットを取る

※自分用の備忘録です

##利用環境
- Windows10　Pro　Ver.1803 (解像度　1920 x 1080)
- テキスト、アプリ、その他の項目のサイズを変更する　(125%)
- Fast Stone Capture(Ver. 5.3)

##困ったこと
スクリーンショットを取ると、画面が拡大して期待の画像が取得できない。
Windowsの拡大率を100%にすると、文字が小さすぎて読みにくい。

##解決方法
→Fast Stone Captureの設定で「高いDPI設定を上書きする」という設定をする

手順
1.**アプリの設定画面ではなく**、exeファイルのプロパティを開く

![2019-04-23_100043.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317739/0f036fd3-b5a9-4d75-3b7e-28a75a43ef53.png)

2.[プロパティ]の[互換性]タブ内[高DPI設定の変更]を押下

![2019-04-23_100107.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317739/65116c43-9bb5-e26d-6c85-a3a6ac946bee.png)

3.「高いDPIスケールの動作を上書きします」にチェックを入れる
![2019-04-23_100125.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317739/1ef2310d-69bd-643f-64e3-b628e1ff83b5.png)

4.アプリ再起動で改善
第１回　Raspberry Pi で監視カメラを作ろう！　～準備編～

Raspberry Piと専用のカメラモジュールを使用し、ONVIF対応の監視カメラを作成する[シリーズ記事](https://qiita.com/lis-hanzomon/items/cc1f7f316fbeb9579b28)です。
本記事は[リンク情報システム株式会社](https://www.lis.co.jp/)の有志が作成しています。

今回作成する監視カメラに必要な機材を紹介します。
いずれの機材もamazon等で、手軽に入手可能です。

## CPUボード
#### ・Raspberry Pi3 Model B
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399637/10701581-a72a-0134-b1bb-54c5ca7e8347.png)

Raspberry Pi3 Model B の性能

- Quad Core 1.2GHz Broadcom BCM2837 64bit CPU
- 1GB RAM
- BCM43438 wireless LAN and Bluetooth Low Energy (BLE) on board
- 40-pin extended GPIO
- 4 USB 2 ports
- 4 Pole stereo output and composite video port
- Full size HDMI
- CSI camera port for connecting a Raspberry Pi camera
- DSI display port for connecting a Raspberry Pi touchscreen display
- Micro SD port for loading your operating system and storing data
- Upgraded switched Micro USB power source up to 2.5A

参考元：[Raspberry Pi 3 Model B - Raspberry Pi](https://www.raspberrypi.org/products/raspberry-pi-3-model-b/)

## ストレージ
#### ・SDカード

OSのインストール用にSDカードを用意します。
録画ファイルの保存にも使用しますので、16GB～の容量が良いかと思います。
ちなみに、海外ではTFカードと呼ばれたりしています。英語の仕様書や海外のホームページを参照する際には、ご注意ください。

## カメラ
#### ・CAMERA MODULE V2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399637/80f441b7-a1dd-15e7-1e84-e46a49aaebbc.png)

CAMERA MODULE V2 の性能

- Sony IMX219 8-megapixel sensor
- 1080p30, 720p60 and VGA90 video modes

参考元：[Camera Module V2 - Raspberry Pi](https://www.raspberrypi.org/products/camera-module-v2/)

## カメラマウント
首振り機能用の部品になります。
首振り機能が不要であれば必要ありません。

#### ・カメラマウント A838
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399637/ba35b6d3-6b27-9f38-717e-3fe2135b5462.png)

#### ・デジタル マイクロ サーボ SG90 × 2個
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399637/d0816366-0f96-df4f-9501-b6b2f5d0a4ab.png)

#### ・Adafruit 16-Channel 12-bit PWM/Servo Driver - I2C interface - PCA9685
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399637/0fb82e81-6721-e03f-a85a-cbe8a79badfe.png)
サーボ制御には、GPIOを利用して自分で波形を出力することも可能ですが、波形の出力にはリアルタイム性が必要になり、安定性に不安が残るので、今回はI2C通信で制御できるコントローラ(PCA9685)を使用しています。

## 電源
本体、及びサーボ用の電源として2A以上の出力が望ましいと思います。
携帯用の充電器を流用するのが良いと思います。

例）エレコム　AC充電器(2ポート2.4A)　MPA-ACUEN000NWH 
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399637/7c1079a1-914b-230c-8f6b-7ae4c655d113.png)

## その他
キーボード、マウス、モニタ、HDMIケーブル、電源接続用のUSBケーブル等が必要になります。

---
[インデックス記事へ](https://qiita.com/lis-hanzomon/items/cc1f7f316fbeb9579b28)
[第２回記事へ](https://qiita.com/lis-hanzomon/items/91df20407d65322d0afb)

---
[リンク情報システム株式会社](https://www.lis.co.jp)では一緒に働く仲間を[随時募集](https://www.lis.co.jp/employ_top)しています！
また、お仕事のご依頼、ビジネスパートナー様も募集しております。[お気軽にご連絡](https://www.lis.co.jp/inquiry)ください。
Raspberry Piの固有ID


Raspberry Piの固有IDについて、調べた。

/proc/cpuinfoにあるので、catで表示する。

```
# cat /proc/cpuinfo
processor       : 0
model name      : ARMv7 Processor rev 4 (v7l)
BogoMIPS        : 38.40
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 4

processor       : 1
model name      : ARMv7 Processor rev 4 (v7l)
BogoMIPS        : 38.40
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 4

processor       : 2
model name      : ARMv7 Processor rev 4 (v7l)
BogoMIPS        : 38.40
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 4

processor       : 3
model name      : ARMv7 Processor rev 4 (v7l)
BogoMIPS        : 38.40
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 4

Hardware        : BCM2835
Revision        : a02082
Serial          : 00000000de876543
```

最後のSerialがシリアル番号になる。
スクリプトなどで使用する場合は、


```
# grep Serial /proc/cpuinfo|awk '{print $3}'

00000000de876543
```

で番号のみを取り出せばよい。


また、eth0のMACアドレスは、OSでベンダー番号（b8:27:eb）+シリアルで振っているようなので

```
# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.3  netmask 255.255.255.0  broadcast 192.168.1.255
        ether b8:27:eb:87:65:43  txqueuelen 1000  (イーサネット)
        RX packets 2194421  bytes 283335546 (270.2 MiB)
        RX errors 0  dropped 1632266  overruns 0  frame 0
        TX packets 116143  bytes 26260222 (25.0 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
```

のether部分も固有IDとなるかと思う。

これも

```
# ifconfig eth0|grep ether|awk '{print $2}'|sed "s/://g"
b827eb876543 
```

でhexのみを取り出す。

参考：
https://raspberrypi.akaneiro.jp/archives/413
http://boysenberrypi.hatenadiary.jp/entry/2014/03/29/222028
Serverless python requirementsのcachingを有効にしてビルド時間短縮

[Serverless Framework](https://serverless.com/) でrequirements.txtに記載したパッケージをインストールしLambdaに同梱してくれる便利プラグイン [serverless-python-requirements](https://github.com/UnitedIncome/serverless-python-requirements) 。便利だけど、ビルドのたびインストールが走ってしんどいなぁと思ってました。

が、キャッシュを利用できる設定がありました！


# キャッシュ利用設定

[README](https://github.com/UnitedIncome/serverless-python-requirements/blob/master/README.md) の *Extra Config Options > Caching* から引用

```
custom:
  pythonRequirements:
    useDownloadCache: true
    useStaticCache: true
```

customセクションのpythonRequirementsで有効にするキャッシュタイプをtrueにすることでキャッシュを有効にできます。デフォルトはfalse(=キャッシュ使わない)設定になってます。

詳細は[README](https://github.com/UnitedIncome/serverless-python-requirements/blob/master/README.md)参照
cacheLocationでキャッシュする場所も指定できるようです。

# キャッシュ利用結果

2回目以降はキャッシュが使われて、比較するとかなり早くビルドが終わりました。

```
Serverless: Using static cache of requirements found at /root/.cache/serverless-python-requirements/...
```

## 指定バージョンを変更した場合

requirements.txt内の
dnspython==1.15.0
を
dnspython==1.16.0
に変更して、もう一度ビルド&デプロイしてみたところ

```
Serverless: Installing requirements from /root/.cache/serverless-python-requirements/...
```

という感じでインストールが走り直しました。デプロイされたパッケージのdnspythonバージョンも1.16.0になっていました。


# 備考
キャッシュ設定は去年(2018)の9月ぐらいから使えるようになったぽい
https://github.com/UnitedIncome/serverless-python-requirements/pull/165
https://github.com/UnitedIncome/serverless-python-requirements/commit/137f8e1b1e10579a2b8db88a49c335329a3307dd#diff-04c6e90faac2675aa89e2176d2eec7d8
僕の嫌いなerror: failed to push some refs to 'git@github.com:hogehoge/hugahuga'

##いつものようにgithubにpushしようとした時のこと下のエラーが出ました。

```
$ git push origin master
To github.com:hoeghoge/hugahgua
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'git@github.com:hogehoge/hugahuga'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. Check out this branch and integrate the remote changes
hint: (e.g. 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```

このエラーにはよく出会っていたのでさっさとpullしてpushしようとしました。

```
$ git pull origin master
From github.com:hogehoge/hugahuga
 * branch            master     -> FETCH_HEAD
fatal: refusing to merge unrelated histories
```

？？？
よくわからないが、mergeできないぞって怒られた。

とりあえず、エラーをググるとヒストリーが繋がってないことを指摘されていたようだ。（そういえば、github側でsample.mdを作成していたので多分それですね）

オプション付けてpullすれば問題ないようなのでオプション付けてpullする。

```
$ git pull origin master --allow-unrelated-histories
From github.com:hogehoge/hugahuga
 * branch            master     -> FETCH_HEAD
Merge made by the 'recursive' strategy.
 README.md | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 README.md
```

お、mergeできた。

あとはお約束のadd〜pushの流れを実行

```
$ git add .
$ git commit -m "forst_commit"
On branch master
nothing to commit, working tree clean
$ git push origin master
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 4 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 29.64 KiB | 7.41 MiB/s, done.
Total 5 (delta 0), reused 0 (delta 0)
To github.com:hogehoge/hugahuga
   66edb0e..18fc410  master -> master
```

無事pushできました。
Craft CMS のルーティングをファイルで管理する

**Craft CMS で月別アーカイブのページを作成する | mersy note**
https://note.mersy418.com/article/craft-cms-monthly-archive

こちらのブログ記事で紹介されているルートの設定について、少し補足。

Craft CMS では管理画面の「設定 > ルート」で管理する以外に、`config/routes.php` に定義する形でもルートを設定できる。

リンク先にあわせて `archive/YYYY/MM` でアクセスすると、テンプレート `archive/_monthly` でレンダリングするのであれば

```php:config/routes.php
<?php
return [
    // 月別アーカイブ
    'archive/<year:\d{4}>/<month:\d{2}>' => ['template' => 'archive/_monthly'],
];
```

と定義すればよい。

ここで記述している `<year:\d{4}>` は4桁の数字を変数 `year` として受け取ることを意味するため、テンプレート内で

```twig
<h1>{{ year }}年{{ month }}月の記事一覧</h1>
```

のように利用できる。

管理画面から登録する方法だと数が多い場合に管理が煩雑になり、開発環境や本番環境など異なる環境に反映するための時間が必要になるため、状況に応じて使い分けると良い。

## 参考

**Craft 3 ドキュメント | ルーティング > URL ルールによる高度なルーティング**
https://docs.craftcms.com/v3/ja/routing.html#url-ルールによる高度なルーティング
デザイナーにデザインを依頼するときに意識するとよいこと

やりたい企画や訴求に関してデザインをおこしてもらう場合、スムーズに案件を進めるにはどうすればよいか、今までの経験から最低限やっておくとよさそうな項目をまとめました。
# 企画者側として依頼する場合

## 目的を明確化する

これは全ての職種・案件に対して共有の項目ですね。

何を伝えるためのデザインを作ってほしいのか、明確に説明する必要があります。

売上を取りたいのか、それともサービスの認知が目的なのか、コンバージョンがどこにあるかを明確にする必要があります。

## ターゲットの明確化

誰に向けたデザインにするかで、説明すべき範囲やしてほしいアクションが変わってきます。

## コンテンツの明確化

ここでいうコンテンツは、訴求できる材料を意味します。
デザインで盛り上げてほしいなどの要求は、訴求したいコンテンツの数や内容が充実している必要があります。

## シチュエーションの明確化

コミュニケーションがどの段階にいるかを明確にしておく必要があります。

ターゲットが明確化していても、次にしてほしいアクションが決まっていないとユーザーに対して何を説明すべきかがわからなくなってしまい、過不足のある情報になってしまいます。

## 「デザインでいい感じに」というワードは使わないこと

企画の中で一番伝えたいこと、その企画自体にどういう印象を持たせたいかなど、企画者の中ですでにイメージがある場合、きちんと言語化しデザイナーに伝える必要があります。そうでないと、デザインが出来上がったときに条件は合っているがイメージに相違があるという状態になってしまいます。

## 訴求文言が事実であることが断言できるか

デザインを起こす上で、訴求文言の言葉の使い方や表現により、事実よりも情報を誇張してしまったり、意図と異なる情報になってしまう可能性もあるため、訴求内容の条件はできるだけ具体的な情報を伝えておく必要があります。

# エンジニアとしてやりとりする場合

実現したいことに関して、デザインで吸収できる部分とシステムで吸収できる部分を明確にし、担当者同士でコミュニケーションを取ることが重要です。
NetBeansで構成の固定方法

NetBeansで構成の固定方法は
プロジェクトのプロパティ＞構成＞アクティブ化
で出来たっ

プロジェクトのプロパティ＞アクション＞構成
でどうにかしようとしていて迷っていました(^^ゞ
Swift：おっぱい関数をつまんでプルンとさせてみた．

# 概要

Swiftでキーフレームアニメーション実装の練習をしようと思い，[おっぱい関数選手権大会](https://youtu.be/sqcHd4tI99Y)にて準優勝に輝いた[@CHARTMANq](https://twitter.com/CHARTMANq?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor)さん作の[おっぱい関数](https://www.desmos.com/calculator/i05puaquwh)をつまんでプルンとさせてみました．

## できたもの
![oppai_demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/e33e9caa-d921-0844-6257-7605ac139963.gif)

[GitHubリポジトリ](https://github.com/Kyome22/Oppai)（自分のiPhoneでも動かしてみたい人向け）

# 実装の軽い説明

1. 基本，静止状態のOppaiCurveを描画して待機（パンジェスチャのイベント待ち）
2. ユーザのドラッグに応じて上下にOppaiCurveを歪ませる
3. ユーザが指を離したらアニメーションを開始（パンジェスチャーの解除：アニメーション中はジェスチャを受け付けない）
　- 減衰しながら揺れるように，OppaiCurveのキーフレームアニメーションを設定する
　-> 上にドラッグして離した場合は下方向に揺れ始めるようにし，その逆の場合は上に揺れ始めるようにする
4. アニメーションが終了したら，パンジェスチャを再登録

## キーフレームアニメーション
キーフレームアニメーションには`CAKeyframeAnimation`を使います．普通は`CAMediaTimingFunction`を使ってキーフレーム間を補間するのですが，今回はOppaiCurveが複雑な関数(実際にはベジェ曲線)だったため，パラパラ漫画のようなコマ送りアニメーションになるよう`CAMediaTimingFunction`を使わず，`CAKeyframeAnimation．calculationMode = .discrete`としました．

# 参考
- [おっぱい関数 by CHARTMAN](https://www.desmos.com/calculator/i05puaquwh)
- [CAKeyframeAnimationを使ってUIBezierPathをアニメーションさせる](https://qiita.com/naoyashiga/items/bd014f303c1b743638b8)
- [How to create custom easing function with Core Animation?](https://stackoverflow.com/questions/5161465/how-to-create-custom-easing-function-with-core-animation)

また，CHARTMANさんにTwitterで直接アドバイスをいただき，さらに[減衰振動](https://www.desmos.com/calculator/e1ue3nc9at)のデモまで作っていただきました（お優しい...

# 所感
CHARTMANさんのアドバイスもあり，比較的簡単におっぱい関数を揺らすことができたのですが，もっと柔軟にプルプルさせたかったというのが本音です．曲線の知識はほぼ高校3年までの二次曲線でストップしているので．自在に曲線をアニメーションさせるには，もう少し深く数学の勉強をする必要がありそうです．
kotlinのcollection入門

##collectionとは
collection: List/Set/Map
`collectionには読み取り専用(値が変更できない)と更新可(値が変更可)が存在する`

読み取り専用(値が変更できない): List/Set/Map
更新可(値が変更できる): MutableList/MutableSet/MutableMap

####基本的なcollectionの使い方

```kotlin
//初期化
val list = listOf(1, 2, 3)
val set = setOf(1, 2, 3)
val map = mapOf(1 to 10, 2 to 20, 3 to 30)
 
 
//値の更新はvalでも行えるため、基本的にvalで定義する
val mutableList = mutableListOf(1, 2, 3)
val mutableSet = mutableSetOf(1, 2, 3)
val mutableMap = mutableMapOf(1 to 10, 2 to 20, 3 to 30)
 
 
//値の追加
mutableList.add(4)
mutableSet.add(4)
mutableMap.put(4, 40) 
 
//値の削除
mutableList.remove(2)
mutableSet.remove(2)
mutableMap.remove(2)
mutableMap.remove(2, 20)
```

##よく使用する操作関数
###filter
```kotlin
val list = mutableListOf(1,2,3)
 
 
val arraySize = list.filter { it == 2 }.size
 
 
/*  filter内のitは配列の要素{1,2,3}を示している
        今回はlistの中から2に等しい要素をlist型で返す
        実行結果はarraySize = 1となる   */
```

###forEach/forEachIndexed
```kotlin
val list = mutableListOf(1,2,3)
 
list.forEach { element -> //{1,2,3}が順番に入ってくる
    Log.d("test", element.toString())
    //実行結果: 1, 2, 3
}
 
 
list.forEachIndexed { element, index ->
    Log.d("test", index.toString() + "番目：" +element.toString() )
    //実行結果：1番目：1, 2番目：2, 3番目：3
    //要素に対してindexを取得したい場合に使用する
}
```

###flatmap
```kotlin
val list = mutablelistOf(mutableListOf(1,2,3), mutableListOf(4,5,6))
//[[1,2,3],[4,5,6]]
 
val flatList = list.flatmap {num -> num}
 
//[1,2,3,4,5,6]
//ネストの深いList構造を平坦にしてくれる
```

###distinct
```kotlin
val list = mutableListOf(1,2,3,2,3)
 
val distinctList = list.distinct()
//実行結果：1
//重複している要素を削除してそれ以外の要素を残している
```

###take
```kotlin
val list = mutableListOf(1,2,3,4,5,6)
 
val takeList = list.take(3)
//実行結果：[1,2,3]
//takeで指定した数の分だけ先頭から要素を抜き出す
//後ろから抜き出したい場合はtakeLast
```
コンパイラのコード生成: 配列(カウンター方式)

# はじめに

このテキストは[「コンパイラのコード生成: 繰返し」](https://qiita.com/zacky1972/items/29c1cf24ec2361e2f179)の続きです。


# C言語プログラム例

下記のC言語プログラム例を見ていきましょう。

```c
int calc(int a[], int n) {
	int sum = 0;
	for(int i = 0; i < n; i++) {
		sum += a[i];
	}
	return sum;
}
```

# RISC-Vのアセンブリコード

次のようにコンパイルします。

```bash
riscv64-unknown-elf-gcc -S -O0 -march=rv32i -mabi=ilp32 -o sample.s sample.c
```

得られた RISC-V のアセンブリコードは次の通りです。

```
	.file	"sample.c"
	.option nopic
	.text
	.align	2
	.globl	calc
	.type	calc, @function
calc:
	addi	sp,sp,-48
	sw	s0,44(sp)
	addi	s0,sp,48
	sw	a0,-36(s0)
	sw	a1,-40(s0)
	sw	zero,-20(s0)
	sw	zero,-24(s0)
	j	.L2
.L3:
	lw	a5,-24(s0)
	slli	a5,a5,2
	lw	a4,-36(s0)
	add	a5,a4,a5
	lw	a5,0(a5)
	lw	a4,-20(s0)
	add	a5,a4,a5
	sw	a5,-20(s0)
	lw	a5,-24(s0)
	addi	a5,a5,1
	sw	a5,-24(s0)
.L2:
	lw	a4,-24(s0)
	lw	a5,-40(s0)
	blt	a4,a5,.L3
	lw	a5,-20(s0)
	mv	a0,a5
	lw	s0,44(sp)
	addi	sp,sp,48
	jr	ra
	.size	calc, .-calc
	.ident	"GCC: (GNU) 8.2.0"
```

# 演習問題

レジスタマップとメモリマップを作成してみましょう。

# コード生成: 配列の参照

配列を参照している部分は次の通りです。

```
	lw	a5,-24(s0)
	slli	a5,a5,2
	lw	a4,-36(s0)
	add	a5,a4,a5
	lw	a5,0(a5)
```

`-24(s0)` が `i` に相当し，`slli a5,a5,2` によって `i` を4倍にします。さらに `-36(s0)` が `a` すなわち配列 `a` の先頭アドレスになりますので，`add a5,a4,a5`によって `a + i * 4` すなわち `a[i]`のアドレスがレジスタ`a5`に入ります。

あとは `lw a5, 0(a5)` によって参照するというわけです。

# コード生成: 配列への書き込み

逆に書き込む場合は，配列の参照のコードの最後を `sw (格納したい値を入れたレジスタ), 0(a5)` という具合にストア命令に書き換えます。

# ポインタを使った場合

下記のコードは，同じ実行結果になるコードですが，配列の代わりにポインタを用いています。

```c
int calc(int *a, int n) {
	int sum = 0;
	for(int i = 0; i < n; i++) {
		sum += *a++;
	}
	return sum;
}
```

# RISC-Vのアセンブリコード例 (ポインタを用いた場合)

```
	.file	"samplep.c"
	.option nopic
	.text
	.align	2
	.globl	calc
	.type	calc, @function
calc:
	addi	sp,sp,-48
	sw	s0,44(sp)
	addi	s0,sp,48
	sw	a0,-36(s0)
	sw	a1,-40(s0)
	sw	zero,-20(s0)
	sw	zero,-24(s0)
	j	.L2
.L3:
	lw	a5,-36(s0)
	addi	a4,a5,4
	sw	a4,-36(s0)
	lw	a5,0(a5)
	lw	a4,-20(s0)
	add	a5,a4,a5
	sw	a5,-20(s0)
	lw	a5,-24(s0)
	addi	a5,a5,1
	sw	a5,-24(s0)
.L2:
	lw	a4,-24(s0)
	lw	a5,-40(s0)
	blt	a4,a5,.L3
	lw	a5,-20(s0)
	mv	a0,a5
	lw	s0,44(sp)
	addi	sp,sp,48
	jr	ra
	.size	calc, .-calc
	.ident	"GCC: (GNU) 8.2.0"
```

違いがわかりますか？ 配列版では，`slli` 命令がありますが，ポインタ版ではありません。

# 演習課題

配列版とポインタ版のロジックをよく見比べてみましょう。違いを説明してください。
vbsの作法 その27

#概要
vbsの作法調べてみた。
非同期、やってみた。

#サンプルコード


```
Sub Proc0
	ProcNumber = 1
	WshShell.Exec "wscript " & WScript.ScriptName & " " & ProcNumber
	WScript.Echo "Main"
End Sub

Sub Proc1
	WScript.Sleep 3000
	WScript.Echo "Sub"
End Sub

Dim ProcNumber
Dim WshShell

Set WshShell = CreateObject("WScript.Shell")
If WScript.Arguments.Count = 0 Then
	ProcNumber = 0
Else
	ProcNumber = CInt(WScript.Arguments(0))
End If
Select Case ProcNumber
Case 0
	Call Proc0
Case 1
	Call Proc1
Case Else
	WScript.Echo "err!"
End Select
WScript.Quit


```

以上。
Express on Docker

簡易APIサーバー作成メモ

```
vim index.js
```

```js:index.js

var express = require('express');
var app = express();

app.get('/', function (req, res) {
 res.json({key: "value"});
});

app.listen(3000, function () {
 console.log('listening on port 3000!');
});

```

```
docker run -itd --name express -v "$PWD":/app -w /app -p 8080:3000 node:8.9.4-alpine
docker exec -it express /bin/sh
npm init
npm install --save express
node index.js
```

- ブラウザからアクセスしてjsonのレスポンスを確認  

http://localhost:8080/
Laravelで検索機能とページネーションを同時につけたいとき


Laravelで検索機能をつけました。

Laravelでページネーションができるようにしました。


では、実際に検索して...

次のページへ移動しようとすると、、、

「あれ！検索結果がリセットされてしまった！！」


さて、こんな方に朗報です。

一発でカイゼンすることができます。

# 通常のページネーション

ビューではこのように書いている人が多いのではないでしょうか！

```
{{ $users->link() }}
```

いやあ、これだけでページネーションを作ってくれるLaravelさんすごい！！


# 検索結果を保持したままページネーションしたい！

検索結果を保持したままページネーションをするには、

```
{{ $users->appends(request()->input())->links() }}
```

こういう風に書き換えるだけでできるようになります！

お試しください！
s3_waitについて

s3_waitについて(部分意訳・要約)
https://docs.digdag.io/operators/s3_wait.html

## s3_waitとは
s3にファイルが置かれるのを待つdigdagオペレーター

## オペレーター表記
`s3_wait> `

### ポイント
- 環境変数の登録が前提条件
- ファイルが作成されてから演算子がそれを検出するのはラグがある
- 待機中はワークフローの実行は起動中のまま

## 環境変数
s3を利用するのでアクセスキーとシークレットキーは必須
前提として、下記のように登録・指定が必要

```
# 例
## ローカルで実行する場合
digdag secrets --local --set aws.access_key_id=''
digdag secrets --local --set aws.secret_access_key=''

## digdagサーバー上で実行する場合
digdag secrets --project --set aws.access_key_id=''
digdag secrets --project プロジェクト名 --set aws.secret_access_key=''
```

## embulk.ymlに変数展開
```
in:
  type: s3
  bucket: バケット名
  access_key_id: ${secret:aws.access_key_id}
  secret_access_key: ${secret:aws.secret_access_key}
  report_dir: 対象ファイルまでのパス or ディレクトリ
　・
　・
　・
```

## パラメータの設定方法
```
+タスク名:
  s3_wait>: バケットディレクトリ or ファイル
```

## 雑感
s3ファイル配置の遅延幅と、digdagの実行間隔によって使用すべきか否かは変わりそう
遅延幅が一時間くらいなら使用しても良さそうだが、それ以上だとずっとワークフローが起動中になってしまうので、digdagの実行間隔で解決した方が良さそう
vbsの作法 その26

#概要

vbsの作法調べてみた。
再帰、やってみた。

#サンプルコード

```
Function kaijyou(n)
	If n = 1 Then
		kaijyou = 1
	Else
		kaijyou = n * kaijyou(n - 1)
	End If
End Function

Dim answer
answer = kaijyou(5)
msgbox answer
```

以上。
vbsの作法 その25


#概要

vbsの作法調べてみた。
複素数、やってみた。

#サンプルコード


```
Sub c_add(c1_r, c1_i, c2_r, c2_i, c3_r, c3_i)
	c3_r = c1_r + c2_r
	c3_i = c1_i + c2_i
	msgbox c3_r
End Sub

Sub c_sub(c1_r, c1_i, c2_r, c2_i, c3_r, c3_i)
	c3_r = c1_r - c2_r
	c3_i = c1_i - c2_i
End Sub

Sub c_mul(c1_r, c1_i, c2_r, c2_i, c3_r, c3_i)
	c3_r = (c1_r * c2_r) - (c1_i * c2_i)
	c3_i = (c1_i * c2_r) + (c1_r * c2_i)
End Sub

Sub c_div(c1_r, c1_i, c2_r, c2_i, c3_r, c3_i)
	c3_r = ((c1_r * c2_r) + (c1_i * c2_i)) / ((c2_r * c2_r) + (c2_i * c2_i))
	c3_i = ((c1_i * c2_r) - (c1_r * c2_i)) / ((c2_r * c2_r) + (c2_i * c2_i))
End Sub

Const r1_r = 2
Const r1_i = 3
Const r2_r = 4
Const r2_i = 5
Dim r3_r
Dim r3_i
c_add r1_r, r1_i, r2_r, r2_i, r3_r, r3_i
msgbox "r1 + r2 = " & FormatNumber(r3_r, 2) & " + " & FormatNumber(r3_i, 2) & "i"
c_sub r1_r, r1_i, r2_r, r2_i, r3_r, r3_i
msgbox "r1 - r2 = " & FormatNumber(r3_r, 2) & " + " & FormatNumber(r3_i, 2) & "i"
c_mul r1_r, r1_i, r2_r, r2_i, r3_r, r3_i
msgbox "r1 * r2 = " & FormatNumber(r3_r, 2) & " + " & FormatNumber(r3_i, 2) & "i"
c_div r1_r, r1_i, r2_r, r2_i, r3_r, r3_i
msgbox "r1 / r2 = " & FormatNumber(r3_r, 2) & " + " & FormatNumber(r3_i, 2) & "i"


```

以上。
検索機能をつける時に便利なforループの書き方（Laravel）


今まではこのように書いていました。


```php

@if (!$users->isEmpty())
    @foreach($users as $user)
        <p>$user->id</p>
        <p>$user->name</p>
    @endforeach
@endif
```

※今、頭の中で思い描いたサンプルなので、実際にこのコードをコピペして動くかどうかはわかりません。



でも、こうやったらもっとシンプルでわかりやすいなあっていうのを見つけました！

それが`forelse`です。

```
@forelse ($users as $user)
    <p>$user->id</p>
    <p>$user->name</p>
@empty
    <p>表示する項目はありません</p>
@endforelse
```


これでみやすく、スッキリまとめることができました！

forelseすごいっ！！
Windows10 Homeで導入したdockerを最新にアップデートする方法

Windows10 Homeでdocker環境を構築するとdocker本体のパージョンアップの際にも少し手間がかかります。2019.4.23時点で成功した方法を記載します。

## 実行環境
- windows10 home
- docker 18.03.0-ce
- docker-machine 0.14.0
- docker-compose 1.20.1
- Kitematic 0.17.2
- VirtualBox 5.2.8

## 方法
https://github.com/docker/toolbox/releases の最新から DockerToolbox-[最新リリース日].exeをダウンロード
![win10home_docker_update1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75471/84d911a1-1038-995f-e9da-409d90769411.png)

実行し、一緒にアップデートする必要のないもののチェックを外して(Git For WindowsとVirtuialBoxは別途アプデしたい)next
![win10home_docker_update2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75471/70a781ff-c563-3af8-8274-13f3f5b62e31.png)

既にパスは通っている、docker-machineを使っているのでboot2dockerのアプデも不要、ということで次のチェックはすべて外してinstall
![win10home_docker_update3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75471/6e82ab85-4ffd-17a6-64a1-37cee880ac7c.png)

インストール完了したのでバージョン確認します

```shell
> docker -v
Docker version 18.09.3, build 774a1f4eee
```

成功していますね。dockerホストのboot2dockerバージョンも同期して上げましょう

```shell
> docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER     ERRORS
default   *        virtualbox   Running   tcp://192.168.99.100:2376           v18.09.3
> docker-machine upgrade default
Waiting for SSH to be available...
中略
Restarting docker...
> docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER     ERRORS
default   *        virtualbox   Running   tcp://192.168.99.100:2376           v18.09.5
```

以上の工程で現時点の最新として以下のバージョンアップをすることができました。

- docker 18.03.0-ce -> 18.09.3
- docker-machine 0.14.0 -> 0.16.1
- docker-compose 1.20.1 -> 1.23.2
- Kitematic 0.17.2 -> 0.17.6


## 補足
1. docker-machineバージョンアップに伴いdockerホストが動作しなくなるので、以下の方法でコンテナとイメージファイルのバックアップを取るのもよいと思います。
http://takaya030.hatenablog.com/entry/20160320/1458489260


2. ちなみにhttps://docs.docker.com/toolbox/overview/ で取得できるDockerToolbox.exeは少しだけバージョンが古くv18.03.0-ceのようです。

### 参考
http://takaya030.hatenablog.com/entry/2017/11/19/234004
https://qiita.com/idani/items/fb7681d79eeb48c05144