OmniAICreator/Qiita-1.07M huggingface dataset:
Heroku操作 CLI

コマンドラインインターフェースから`Heroku`操作時に主に使用しそうなコマンド簡易まとめメモ。

>
[Heroku CLI 簡単リファレンス](https://qiita.com/histori/items/3ce08a2926c22c63626b)
[Herokuでよく使うコマンドまとめ](http://vdeep.net/heroku-commands)

# コマンド
```zsh:基本
# 作成したアプリ一覧の表示
heroku list
# アプリケーションの情報を見る
heroku apps:info

# アプリケーションに対してコマンドを使う
heroku run コマンド
# アプリ名を指定してコマンド実行
heroku run コマンド --app アプリ名
```
```zsh
# プロセスを見る
heroku ps
```

#### 環境変数などの設定

```zsh
# 環境変数の確認
heroku config
# 環境変数の追加  heroku config:set 環境変数名=セットしたい値
heroku config:set PASS=word

# 環境変数 削除  heroku config:unset 環境変数名
heroku config:unset PASS

# タイムソーンを日本時間に変更
heroku config:add TZ=Asia/Tokyo
```

#### **ログ**の確認

```zsh
# ログを見る
heroku logs
# リアルタイムでログ表示  heroku logs --tail もしくは
heroku logs -t
```
```zsh:アプリ実行関連
# アプリを開く　（アプリのプロジェクトディレクトリ内で）
heroku open

# アプリ名指定して開く
heroku open --app アプリ名
```
#### **メンテナンスモード**

```rb
# メンテナンスモードにする
heroku maintenance:on
# メンテナンスモード解除
heroku maintenance:off
```
#### PostgreSQL
```swift
## PostgreSQLのDB閲覧
# ログイン
heroku pg:psql
```
```zsh:ログイン中はPostgreSQLコマンド操作
# データベース一覧を表示
\l

# テーブル一覧を表示
\d
# テーブルカラムの一覧表示 \d table_name
\d users

# ユーザの一覧を表示
\du

# データ閲覧時、コマンド入力に戻る
q
# ログアウト
\q
```
>
[PostgreSQLとMySQLの基本的なコマンドを比較](https://qiita.com/pugiemonn/items/75870ece3c8476bcb1c8)
[【MySQL, SQL】データベースを扱う基本SQL一覧](https://qiita.com/knife0125/items/bb095a85d1a5d3c8f706)

```zsh:DBのマイグレーション
heroku run rake db:migrate
#heroku run bundle exec rake db:migrate
```

```zsh:プロセス操作と再起動
# 指定したプロセスを停止する
heroku ps:stop <process name>
# 指定したプロセスを再起動する
heroku restart <process name>
# 再起動する
heroku restart
```
```zsh:railsコンソール実行
heroku run rails c
```
#### ロールバック操作
```zsh
## デプロイ時（heroku push master）のリビジョン一覧表示
heroku releases

#v7  Deploy 6b3c375e   ~~ #
#v6  Deploy 014c0bee  ~~ #
#デプロイ履歴が表示される

## 直前のデプロイ状態に戻す  heroku releases:rollback もしくは
heroku rollback

## 指定したデプロイ状態に戻す  heroku releases:rollback バージョン
# heroku releases:rollback v5 もしくは
heroku rollback v5
```
#### デプロイ

```zsh:
git push heroku master

#内容変更後の更新時は事前に「git add .」 「git commit」などを忘れずに
```
#### アドオン
`※ アドオン利用にはクレジットカードの登録が必要`

```zsh
# アドオン確認
heroku addons
# アドオン追加
heroku addons:create アドオン名
```
####アプリの削除

```zsh:Heroku上のアプリ、リモートリポジトリ設定を合わせて削除

#削除
heroku apps:destroy --app アプリ名
#アプリ名を再入力すると削除完了

#確認なしで1発で削除
heroku apps:destroy --app アプリ名 --confirm アプリ名
```

#### その他
```zsh:Herokuで実行しているアプリケーションのRubyバージョンを表示
heroku run "ruby -v"
```
>
[Specifying a Ruby Version | Heroku Dev Center](https://devcenter.heroku.com/articles/ruby-versions)

#参考
>[【herokuコマンド】createからdestroyまで](https://qiita.com/chihiro/items/5c3ff400f6cb99deb945)
[Heroku コマンド・設定 メモメモ](https://qiita.com/pugiemonn/items/0e69b7a29a384b356e65)
[Herokuの環境変数を確認／追加／変更／削除する方法](http://chomast.com/study/web/heroku-environment-variables.html)
[Herokuで前のデプロイした状態に戻す。](https://qiita.com/kimihito_/items/9608f2e94608c9359ad3)
[foreman で アプリケーションを動かす。](https://qiita.com/7kaji/items/6a59977d2ad85604e7fd)
Unity C# クラス構造が分からなくなるので、基本のクラスをまとめてみた

# はじめに

Unityを触る機会ができたのですが、基底クラスがいまいち把握できていないので、**Unityでよく登場するクラスをまとめてみました**。

# 基本のクラスたち

## `Object`

**Unity独自の基底クラス**として`UnityEngine.Object`が用意されています。
ここで`==` `!=`のオーバーロードが行われていて、独特のFake Nullな判定が定義されています。

```csharp:UnityEngine.Object
    public class Object { }
```

### `GameObject`, `Component`

恐らく自分が一番理解できていない部分です。
`GameObject`が`Component`(個々の部品)の塊のようなイメージでいいんですかね？
色々と違いはありますが、**共通するメソッドやプロパティが多い**のがこの2クラス。

```csharp:UnityEngine.GameObject
    public sealed class GameObject : Object { }
```

```csharp:UnityEngine.Component
    public class Component : Object { }
```

### `MonoBehaviour`

Unity上でスクリプト作成するとこのクラスを基底としたクラスのコードが生成されます。
**エディタ上でScriptとして扱われる**ものはこのクラスを継承していないといけない、というのが自分の理解。

```csharp:UnityEngine.MonoBehaviour
    public class MonoBehaviour : Behaviour { }
    public class Behaviour : Component { }
```

### `Transform`

ここから少し細かいクラスですが、オブジェクトの座標的な情報を扱う`Transform`クラスも`Component`です。

```csharp:UnityEngine.Transform
    public class Transform : Component, IEnumerable { }
```

## `Scene`

`Scene`は何故か構造体ですね。
部品というのには大きいので、`Component`を継承していないのは分かるのですが、何故構造体なんでしょう？

```csharp:UnityEngine.SceneManagement.Scene
    public struct Scene { }
```

## `Coroutine`

これもUnityを触ってギャップを感じる`Coroutine`クラス。
`YieldInstruction`というクラスを介して独自の継承階層です。

```csharp:UnityEngine.Coroutine
    public sealed class Coroutine : YieldInstruction { }
    public class YieldInstruction { }
```

## 継承階層

ということで、ここまで挙げたクラスの継承階層を簡単に示してみるとこんな感じ。

- **`Object`**
    - **`GameObject`** _(sealed)_
    - **`Component`**
        - **`Transform`**
        - `Behaviour`
            - **`MonoBehaviour`**
- **`Scene`** _(struct)_
- `YieldInstruction`
    - **`Coroutine`** _(sealed)_

# おわりに

初歩的な内容ですが、**基底クラスが`UnityEngine.Object`のものとそうでないものがある**ので、その違いは覚えておくと役に立ちそうです。
Windows ファイル名に同じ文字列を含んだファイル数によって処理を変える

#どうでもいい背景
[AKB48 53rdシングル 世界選抜総選挙 × SHOWROOM](https://www.showroom-live.com/event/akb48_sousenkyo_53rd) が開催されて
トップアイドルのAKB48グループの子たちが50カウントや1時間ごとのリセットを駆使して
泥臭い戦いを繰り広げている昨今、みなさんいかがお過ごしでしょうか。

[ショールーム録画っち](http://www.skypower.xyz/showroom_rokugatch.html) という神ソフトのおかげで
ひたすらにflvファイルが蓄積していく日々、その処理にお困りじゃありませんか？
手動でポチポチ整理するのに疲れたので、その処理を少し楽にするバッチを作りました。
~~[akbグループ映像倉庫](https://akb48group-eizo.jp/)に登録すればいいじゃんという話もあるけど、
AKB48G以外のアイドルの配信も見たいですしおすし~~

#やりたいこと
下記、現在やっている整理作業フローのうち1.2.の判断を自動化する

1. 録画フォルダに出力されたファイルを、ファイル名でソートする
![hozondata.PNG](https://qiita-image-store.s3.amazonaws.com/0/149787/58826c23-be12-7bc1-7c5a-55cc9662168f.png)

2.【配信ID】【配信日時】順に並ぶので、同じ配信ID・配信日のデータ数を確認する
　　a. 同じ配信日のデータが1つの場合
　　　　処理済みとして完了フォルダに保管する。
　　
　　b. 同じ配信日のデータが2つ以上の場合
　　　　　※途中で配信が切れたりするとデータが別れる
　　　　[Andys-FLV-Joiner](http://www.videohelp.com/software/Andys-FLV-Joiner)で目視しながらポチポチ結合する
　　　　　※解像度が混ざっている場合、結合するとおかしくなるので目視して適宜判断する

#結果
```cmd:check.bat
@echo off
cd /d %~dp0

rem チェック後に格納するディレクトリを指定
set OK_DIR="J:\Video\SHOWROOM\01"
set NG_DIR="J:\Video\SHOWROOM\02"

rem 作業変数
set TARGET_DIR=%OK_DIR%
set /a CNT=0
setlocal enabledelayedexpansion

rem 処理開始
for %%F in (%*) do (
for /f "DELIMS=日" %%A in ("%%~nF") do set NAME=%%A
rem 【配信ID】【配信日】で区切って抽出開始
set /a CNT=0
for %%G in ("!NAME!*") do set /a CNT=CNT+1

if not !CNT! equ 0 (
rem 1件以上対象ファイルが有る場合、移動処理を実行する
set TARGET_DIR=%OK_DIR%

if !CNT! gtr 1 (
rem 2件以上ある場合NG_DIRに格納
set TARGET_DIR=%NG_DIR%
) 
for %%G in ("!NAME!*") do (
move "%%G" !TARGET_DIR!
)

)
 
)
pause;
```
このバッチファイルに整理したいファイルをまとめて選択してドラッグ＆ドロップでOK

#参考
[.bat（バッチファイル）のifコマンド解説。](https://qiita.com/sawa_tsuka/items/8edf3d3d33a0ae86cb5c)
[.bat（バッチファイル）のforコマンド解説。](https://qiita.com/sawa_tsuka/items/67be34bab1fdf3fb87f9)
joins雑メモ


#joins

**用途** 隣接しているモデルの属性で絞り込みを行うとき。
**具体例** あるブログのポストでホゲ君だけがコメントしているポストだけ集めたい。
**条件** コメントのデータは扱わない。


**SQL文(クエリ)**

```
Post.joins(:comments).each do |post| post.comments.each do |comment| end end 
```



```
 SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"

 Comments Load (0.5ms)  SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = ?  [["post_id", 1]]                            

 Comments Load (0.5ms)  SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = ?  [["post_id", 1]]                            

:
:
:
```

コメントがあるポスト取得。
しかしコメントは毎回クエリを実行している。(N+1は解決していない。)

**参考**
http://blog.scoutapp.com/articles/2017/01/24/activerecord-includes-vs-joins-vs-preload-vs-eager_load-when-and-where

https://dev.classmethod.jp/server-side/activerecord-join/
DeepLearningモデルDCGANでアイドルの顔画像を生成してみた



# はじめに
最近、欅坂46にハマり推しメンが増えてきました．そこでDeeplearningを使い自分の推しメンを学習させ最強の推しメンの画像を生成しようと考えました．

# 開発環境
* macOS High Sierra 10.13.5
* python 3.6

# データセットを作る
## 1. アイドルの画像を集める
Deeplearningのモデル学習させるためには大量のデータが必要です．そこで[こちら](http://karaage.hatenadiary.jp/entry/2017/08/23/073000)のサイトを参考にしてアイドルの画像をネットから集めました．ターミナルでこちらを実行すれば画像をスクレイピングできます．

```
$ pip3 install bs4
$ python3 collect.py "ここに好きなアイドルの名前"
```
指定したフォルダに画像が保存されます．
<img width="486" alt="スクリーンショット 2018-06-09 15.14.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/256520/3c505241-6cc1-90f2-60e4-6646181fec2b.png">

## 2. 集めた画像から顔を切り出す
今回はアイドルの顔画像を生成したいため集めた画像から顔だけを切り出します．[こちら](https://ai-coordinator.jp/opencv_face)を参考にopencvを使い顔画像を切り出しました．ターミナルでこちらを実行すれば切り出しできます．

```
$ brew install opencv
$ python3 crop.py
```
このような感じで顔画像が切り出されます．顔画像ではないものも切り出されるため人力で削除しましょう．
<img width="515" alt="スクリーンショット 2018-06-09 15.11.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/256520/ab8993be-0b4e-d065-af1f-76aa8b313f61.png">

## 3. 画像サイズを揃える
ネットワークに入力するには画像のサイズが同じではないといけません．そのため以下のコードで画像をリサイズします．

```resize.py

import os
import glob
from PIL import Image

files = glob.glob('リサイズしたい画像があるディレクトリ名/*.jpg')
a = 0
for f in files:
    a = a+1
    img = Image.open(f)
    img_resize = img.resize((70, 70))
    ftitle, fext = os.path.splitext(f)
    img_resize.save('リサイズ後の画像を保存するディレクトリ名/' + str(a) + '_(70)' + fext)
```

# DCGANとは
DCGANはGANのモデルの一つです．GANとはGenerator（生成器）とDiscriminator（識別器）の２つのネットワークで構成されています．Generatorは訓練データに似たデータを生成します．一方、Discriminatorは入力されたデータが　Generatorによって生成されたデータか本物のデータかを識別します．

この関係は紙幣の偽造者と警察の関係によく例えられます。偽造者は本物の紙幣とできるだけ似ている偽造紙幣を造ります。警察は本物の紙幣と偽造紙幣を見分けようとします。

次第に警察の能力が上がり、本物の紙幣と偽造紙幣をうまく見分けられるようになったとします。すると偽造者は偽造紙幣を使えなくなってしまうため、更に本物に近い偽造紙幣を造るようになります。警察は本物と偽造紙幣を見分けられるようにさらに改善し…という風に繰り返していくと、最終的には偽造者は本物と区別が付かない偽造紙幣を製造できるようになるでしょう。

GANではこれと同じ仕組みで、generatorとdiscriminatorの学習が進んでいきます。最終的には、generatorは訓練データと同じようなデータを生成できるようになることが期待されます。このような状態では、訓練データと生成データを見分けることができなくなるため、discriminatorの正答率は50%になります。

![gan.png](https://qiita-image-store.s3.amazonaws.com/0/256520/70b868b3-c75f-28f0-5191-1909f16bd340.png "GANの概念図")


以上のことは[こちら](https://elix-tech.github.io/ja/2017/02/06/gan.html)のサイトに書いています．詳しいことが知りたい方はサイトを見てください．


# KerasでDCGANのコードを書く
今回は簡単にDeeplearningのモデルが書けるKerasというフレームワークを使います．以下のコマンドで簡単にインストールできます．

```
$ pip3 install tensorflow
$ pip3 install keras
```

実装したコードは[GitHub](https://github.com/NakaokaRei/Idol_GAN.git)に載せています．


# 生成された画像
![IMG_9438.PNG](https://qiita-image-store.s3.amazonaws.com/0/256520/62938bb1-4d38-8dfd-df96-24baf0964ff4.png)

怖いです．それに同じ画像が多く出力されています．他の方の記事を見るともっと綺麗で可愛い女の子を出力できていました．おそらくチューニングがうまくできていない、訓練画像の枚数が足りていないなどの問題があると考えています．うまく出来たらまた更新します．

#追記 2018/7/25
[こちら](https://github.com/carpedm20/DCGAN-tensorflow)のソースコードを使い顔画像生成したところ綺麗な顔画像が生成されました．



![train_07_0016.png](https://qiita-image-store.s3.amazonaws.com/0/256520/0a774a22-55e3-c238-d38b-febc29ba71d3.png)

同じデータセットを使ったため自分のコードでうまく生成できなかったのはデータせセットのせいではないみたいです．
JetBrains IDEでVagrant上のMongoDBを設定する

# Introduction

なかった（と思う）ので

私の環境はMacですが，Windowsでも何でも同様の手順でいけるかと思います．

# Results

こんな感じで見れるよ

![スクリーンショット 2018-06-09 15.54.48.png](https://qiita-image-store.s3.amazonaws.com/0/97131/341f6ecd-5e2a-2cbe-687d-59599b037765.png)

# How to

## Install a mongo plugin

- [Mongo Plugin](https://plugins.jetbrains.com/plugin/7141-mongo-plugin) をインストール，IDE再起動で有効化

![スクリーンショット 2018-06-09 15.57.12.png](https://qiita-image-store.s3.amazonaws.com/0/97131/4a8058d5-c495-20a3-bdab-268225692ecd.png)

- IDE の View から `Tool Buttons`を有効化し， __Mongo Explorer__ を選択 

![スクリーンショット 2018-06-09 15.58.30.png](https://qiita-image-store.s3.amazonaws.com/0/97131/317fe62a-0560-fde4-e853-32480ff2e742.png)

- スパナと歯車のやつ押す

![スクリーンショット 2018-06-09 16.00.24.png](https://qiita-image-store.s3.amazonaws.com/0/97131/6f56b82a-da85-01bd-8dc2-fed196ce9a86.png)

- vagrant上で `$ which mongo`とかやってmongo DBのPathを確認， その後 __Servers__ の__+__ を押して新規設定を作成する．

設定は以下の通り

|項目名|備考|
|:--|:--|
|General|MongoDB　のポート番号を変えてなければ変更する必要無し|
|Authentication|Mongo DB にユーザネームとか設定してる人向け（?）． 今回はスルー|
|SSH|vagrant ユーザはここを設定します．|

また，`Label` はわかりやすい名前にしましょう．私は __Vagrant MongoDB__ としました．

### SSH Config

|項目名|値|備考|
|:--|:--|:--|
|Proxy host|192.168.33.10|値変えてる人はそちらへ変更|
|Port|22|同上|
|Proxy user|vagrant|同上|
|Proxy password|vagrant|同上|

![スクリーンショット 2018-06-09 16.05.05.png](https://qiita-image-store.s3.amazonaws.com/0/97131/ff0410aa-a2d7-4e72-d669-6a11f936c74e.png)

- Test Connection して成功したらOK

# Conclusion

IDEって痒いところに手が届くからいいですね
ただし，重くなりがちなのでしっかりメモリを割り当てましょう

# References

- [Mongo Plugin](https://plugins.jetbrains.com/plugin/7141-mongo-plugin)
- [WebStorm から MongoDB へ接続してみる](https://qiita.com/hkusu/items/df90808d672a6baefc91)
クラスとインスタンスがなんとなくわかったのでメモ

#プログラミング初心者の敵　クラスとインスタンス
プログラミングを学んで一年半経ちますが、今までよくわからずここまで来ていました。
とにかく初心者からしたら全くわからない！w
いろんな本を見ると、車とかロボットとかたい焼きとか使ってますが、ごめんなさいよくわからないです。
ただ、自分がクラスとかインスタンスがよくわからない状態から、どうやって今ちょろっと理解しているのか、自分の頭の中をメモります。
ちなみに自分はRPGが好きなので、その例えでとりあえず腑に落ちています。今回もその例えで書きます。
こういう例えもあるんだなくらいで読んでいただき、ご理解の一助になれば幸いです。
違っているところがありましたら、どんどんください。
すぐに直します！！

#クラスは職業、インスタンスはその職業特有の能力を手に入れた実際の人
みなさんドラクエやFFはやったことありますか？
今は少ないですが、昔はゲーム内で職業というものが用意されていて、自分のパーティーにいる人を好きな職業に就かせるみたいなシステムがありました。
例えば、仲間になった時は戦士だったけど、後でジョブチェンジして魔法使いにしたり、もっと強くなったら竜騎士にしたり。。。
職業が変わると、覚える技や、呪文魔法が変わります。
戦士だった時は回復魔法は使えなかったけど、魔法使いになったらそれが使えるようになったりするんです。
何が言いたいかというと、
戦士という職業は一つしかありませんが、実際に戦士になっている人はゲームの世界にはたくさんいますよね？
例えば、自分のパーティー全て、戦士にした時。
パーティーが４人としたら戦士になっている人は、４人いますが戦士という職業は１つしかありません。
クラスは戦士という職業が持つステータス値、インスタンスはそのステータス値を獲得した人間一人ひとりです。

#じゃあコードで書いてみよう
自分はruby勉強中なので、rubyで書きます。

```ruby.rb
class Knight

 def greeting
  puts "hello world" 
 end

end
```
これはクラスです。つまり、戦士になるとこういうことができるようになりますっていう一覧です。
この場合はgreetingメソッドを使えるようになる。という感じです。
技の一つだと考えてくれればいいですかね。

では次に、そのステータスを持った実際の戦士を作ります。

```ruby.rb
Hassan = Knight.new

Yangasu = Knight.new

Arena =Knight.new

```

このようにすると、戦士（Knightclass）の力を受け継いだ３人の戦士が出来上がります。
つまり彼らは、greetingメソッドという技を使えます。
この実際の戦士(Hassan,Yangasu,Arena)がインスタンスです。

```ruby.rb
Hassan.greeting #=> "hello world"

Yangasu.greeting #=> "hello world" 

Arena.greeting #=> "hello world"
```

#インスタンス変数とローカル変数
今回勉強していて衝撃だったのは、インスタンス変数はインスタンスを入れるための変数ではないということです。
Railsから入ってしまうと、どうしても@がつく変数はインスタンスを入れなければならないという固定観念を持ってしまいますが、そんなことはありません。

ではインスタンス変数とはなんなのか。これは他のメソッドでも利用できる変数ですよ〜という意味です。

逆に、ローカル変数は特定のオブジェクトやメソッド内のみでしか使えない変数です。
これもまたコードで。

```ruby.rb

class Witch

 def initialize(skill)
   @skill = skill 　#この@skillがインスタンス変数
 end

 def call
   p "#{@skill}の呪文が使えます" 
 end

end

witch = Witch.new("炎系")　#このwitchがローカル変数
witch.call  #実行結果　"炎系の呪文が使えます"

```

上では新しく魔法使いのクラスとインスタンスを作ってみました。

Witchがクラスで、そのインスタンスがwitchですね。
initializeはインスタンスが作成されたタイミング、つまりWitch.newされた時に実行されるメソッドです。
ここで注目いただきたいのは@skillというインスタンス変数とwitchというローカル変数ですね。
Witchのインスタンスが入っているのは、witchであり、@witchではないのです。
つまり、絶対にインスタンス変数に入れなければならないという決まりはありません。

しかし、@skillはインスタンス変数です。別にインスタンスが入っているわけではないですが。。。。
これはintializeメソッドで作成した@skillをcallメソッドでも利用したいからです。
そうしなければ炎系という言葉を表示できません。
earthを叩く　その3

#概要
google earthをcom apiから叩く。
serialで、gpsのnmeaを読んで、現在地をearthで、表示するやつ。

#環境

windows vista
earth 6.2

#サンプルコード


```
forRead = 1
Set fso = CreateObject("Scripting.FileSystemObject")
sf = fso.getParentFolderName(WScript.ScriptFullName)
Set comObj = fso.OpenTextFile("COM5:9600,N,8,1", forRead)
WScript.Sleep(500)
c = 0
Do While comObj.AtEndOfStream <> True
	line = comObj.ReadLine
	nmea = split(line, ",")
	If (nmea(0) = "$GPGGA") Then
		If nmea(2) <> "" Then 
			c = c + 1
			If c > 3 Then Exit Do
		End If
	End If
	WScript.Sleep(200)
Loop
slat = cdbl(nmea(2))
slon = cdbl(nmea(4))
ilat = Fix(slat / 100)
ilon = Fix(slon / 100)
slat = slat - ilat * 100
slon = slon - ilon * 100
slat = slat / 60
slon = slon / 60
lat = ilat + slat
lon = ilon + slon
comObj.Close
Dim objGE
Set objGE = WScript.CreateObject("GoogleEarth.ApplicationGE")
While (objGE.IsInitialized = 0)
	WScript.Sleep 1000
Wend
Dim oCamera
Set oCamera = objGE.GetCamera(0)
oCamera.FocusPointLongitude = lon
oCamera.FocusPointLatitude = lat
oCamera.FocusPointAltitude = 0.0
oCamera.Range = 300
oCamera.Tilt = 0
oCamera.Azimuth = 0
objGE.SetCamera oCamera, 0.5

```


以上。
【CakePHP2】axiosのPOST送信のデータを取得する

フロントをVue.js、サーバサイドをCakePHP2で作っていてaxiosでPOST送信したときに、CakePHP2でうまく取得できなくて躓いたのでメモ。

# 普通に送信する（だめな例）

```js:sample.vue
axios.post( '/sample.php', {
    test: '送信データだよ',
} )
.then( ( res ) => {
    //送信完了
} );
```

このときに、CakePHP側で

```php:sample.php
$test = $this->request->data('test');
debug($test);
```

ってやったら　`null`　になってしまった。
調べてみたら、axiosのPOST送信はbodyにJSON形式でデータを送信するらしいので、PHPの`$_POST`だと取得できないらしい。

# 対策

## （対策その1）CakePHPのドキュメントにかいてありました。

axios側は普通に

```js:sample.vue
axios.post( '/sample.php', {
    test: '送信データだよ',
} )
.then( ( res ) => {
    //送信完了
} );
```

CakePHP２で取得方法が以下になります。

```php:sample.php
$data = $this->request->input('json_decode');

debug($data->test);//オブジェクトで取得されます
```
これで取得できました。
注意点としては、取得データがオブジェクト形式となること。個人的にはそのほうが好きなんですが、なんかCakePHP2って、こういうのを連想配列にいれちゃう感じがしてて、すこし戸惑いがありました。
とはいえ、おそらくこれがベストな方法かと思います。

##（対策その2）axios側で送信方法を工夫する
axios側で、POSTをapplication/x-www-form-urlencodedの形式（いつものPOSTのやつ）で送信するようにできます。
こちらだと、受ける側のPHPでは、いつもの方法で取得できます。

(axios側のスクリプト）

```js:sample.vue
let formdata = new URLSearchParams(); //クエリパラメータ作成用のクラス
formdata.append('test','送信データだよ'); //クエリを追加

axios.post( '/sample.php', formdata)
.then( ( res ) => {
    //送信完了
} );

```
この方法で送信すれば

```php:sample.php
$test = $this->request->data('test');
```

これでデータを取得できます。
ただ、複雑なデータを送信するときなどは、js側での処理がちょっと面倒になりがちで、axios（というかvue.jsとか）を使っている旨みがなくなりそう。
フロント側しかいじれないような局面では有効かも。


## （対策その3）PHPで生のJSONを取得
cakePHPとか関係なく、PHPでPOST送信されてきたJSONデータを直接取得する方法です。
axios側の送信は普通ので行けます。

```js:sample.vue
axios.post( '/sample.php', {
    test: '送信データだよ',
} )
.then( ( res ) => {
    //送信完了
} );
```
PHP側で取得する処理

```php:sample.php
$request_body = file_get_contents('php://input'); //送信されてきたbodyを取得(JSON形式）
$data = json_decode($request_body,true); // デコード

debug($data['test']); //当たり前だけど連想配列です。
```
とくにこの方法を選択する意味はないかもですが、CakePHP以外でも使えるので、覚えておきたいなと思って。
あと、`json_decode()`するんで当たり前ですが `$_POST`とかで取得したときみたいに連想配列で取得できます。



以上、自分は最初POSTを取得できないことに焦って、３番目の方法でずっとやってたんですが、あとから調べたらいろいろ良い方法があって後悔したので、メモ代わりに書いておきます。


# 参考

https://book.cakephp.org/2.0/ja/controllers/request-response.html#xml-json
https://github.com/axios/axios#using-applicationx-www-form-urlencoded-format
https://qiita.com/amamamaou/items/b6cb39739bba4abf4544
【Jenkins備忘録】Python自動テスト環境構築②テストコード準備編

・Python3.6.0をインストールしたところからスタート。

### テストコードの準備
・Pythonのユニットテストには標準で用意されているunittestフレームワークを使用する。
　詳しい使い方は、本家サイト(https://docs.python.org/dev/library/unittest.html) で確認  
  
テスト対象コード

```python:calc.py
# -*- coding: UTF-8 -*-


class Calculator(object):

    # 加算
    def add(self, num1, num2):
        return num1 + num2

    # 減算
    def sub(self, num1, num2):
        return num1 - num2

    # 乗算
    def mul(self, num1, num2):
        return num1 * num2

    # 除算
    def div(self, num1, num2):
        return num1 // num2

```


テストコード

```python:test_calc.py
# -*- coding: UTF-8 -*-

import unittest
from calc import Calculator


class Test_Calc_add(unittest.TestCase):

    # 加算テスト
    def test_add(self):
        print('Test add(self, num1, num2) ')
        calc = Calculator()
        result = calc.add(10, 20)

        self.assertEqual(result, 30, 'Match expected value')

    # 減算テスト
    def test_sub(self):
        print('Test sub(self, num1, num2) ')
        calc = Calculator()
        result = calc.sub(20, 6)

        self.assertEqual(result, 14, 'Match expected value')

    # 乗算テスト
    def test_mul(self):
        print('Test mul(self, num1, num2) ')
        calc = Calculator()
        result = calc.mul(3, 6)

        self.assertEqual(result, 18, 'Match expected value')

    # 除算テスト
    def test_div(self):
        print('Test div(self, num1, num2) ')
        calc = Calculator()
        result = calc.div(20, 5)

        self.assertEqual(result, 4, 'Match expected value')


if __name__ == '__main__':
    unittest.main()

```

### テストコードの実行
・calc.pyとtest_calc.pyを同じディレクトリ内に配置後、
　以下のコードを端末で入力するとテストが実行される。

```sh
$ python test_calc.py

Test add(self, num1, num2) 
.Test div(self, num1, num2) 
.Test mul(self, num1, num2) 
.Test sub(self, num1, num2) 
.
----------------------------------------------------------------------
Ran 4 tests in 0.000s

OK
```
High Sierra にて crontab の編集エディターを nano から vim に変更する方法について

# 概要

Ruby にてスクレイピングを定期的に実施したいと考えたため、cron をセットしようとしました。
crontab -e にて編集しようとすると、見慣れない nano エディタが起動して、非常にわかりずらい。
それで vim をエディターにしたいと思いました。

# 方法

下記の設定することで実現できました。

## bashrc/zshrc

How to specify nano or vim as editor for crontab file
https://www.garron.me/en/bits/specify-editor-crontab-file.html

How to save and exit crontab -e?
https://serverfault.com/questions/308085/how-to-save-and-exit-crontab-e

```.sh
export VISUAL=vim;
# 不要?　nano が editor になって後述の vimrc の設定が不要になる気がしていましたが、そうでもないみたいです。
export EDITOR=nano;
```

## vimrc 2018/6/16 追記

vimrc に下記を追加します。

```.vimrc
set backupskip=/private/tmp/*
```

[設定はこのページ](http://d.hatena.ne.jp/yuyarin/20100225/1267084794
) を参考にさせていただきました。
詳細は [このページ](https://rcmdnk.com/blog/2014/06/19/computer-mac/#crontab--e%E3%81%A7%E3%81%AE%E7%B7%A8%E9%9B%86 "crontab -eでの編集") に記載されていました。


> 原因としては上にある様に、本来crontabがコピーしてきたものが Vimによって名前を変えられ、同じ名前のものとし> て新しいファイルを作るので、 所有者などのファイルのプロパティが変わってしまい正しく処理出来なくなります。

vim で :help crontab でヘルプを見ると、vim のバックアップ機能により crontab のコピーが作成されるとオリジナルが廃棄されるが、 private/tmp に、crontab.xxxxxx が保存されるが、crontab のシンボリックリンクにあるオーナー情報などと食い違ってしまう、というような説明になっているようでした。

>	When a copy is made, the original file is truncated and then filled
	with the new text.  This means that protection bits, owner and
	symbolic links of the original file are unmodified.  The backup file
	however, is a new file, owned by the user who edited the file.  The
	group of the backup is set to the group of the original file.  If this
	fails, the protection bits for the group are made the same as for
	others.

それを避けるために、/private/tmp 配下のバックアップは作りませんよ、、と。
どうもありがとうございました！
テキストによる作図のすすめ -PlantUML-

Qiita初投稿です。
本稿ではPlantUMLの使い方についての詳しい説明はあまりしてません。
PlantUML/テキストによる作図をすると何がうれしいかという話を書いてます。

#はじめに

ソフトウェア開発の業務で設計書を書く際、
図を書く方は少なくないと思います。
私もその1人です。
私の場合、特に多いのがシーケンス図です。
基本的な作り方は以下のいずれか。

* Officeソフトで頑張る。
* astah* Community版を使う。

最も多いパターンは後者でした。
しかし、これがなかなか大変です。

* 矢印やメモ、ブロックの位置が均等に揃えられない。
* 修正箇所が分かり辛いのでレビューし辛い。
* 改修や設計修正でシーケンスが間に1つ増えるのはよくあること。
* ワードやエクセルに張り付けるので、作った画像が長いと分割しないといけない。
* astah* communityは7.0から商用で利用不可に。

…など、なかなか面倒です。
論文や説明資料で使うような1回限りの図であれば、
それほど不便はないのですが、何度も修正するのは大変です。
まして業務で使う場合、前回の修正者と今回の修正者が同じである限らないので。

## DSLによる作図

はじめに「テキストで作図する」と耳にした際、
私はGUIプログラミングやHTML/CSSのようなものを想像しました。
しかし、更に聞くとDSL(ドメイン固有言語)という特定の用途に特化した言語を使ったものだと分かりました。

はじめに知ったはblockdiag(http://blockdiag.com/ja/) で、
その流れでseqdiagについて調べました。
しかし、簡単な図を書くには良いのですが、
業務で使うにはできることが少なすぎました。
そこで、いろいろ調べた結果、最も用途に合ったものがPlantUMLでした。

#PlantUMLとは

PlantUMLはいろいろな図を書くことができるDSLとその処理系のことです。
とりあえず試してみたい方は公式ページ(http://plantuml.com/) の
オンラインジェネレータにDSLを書けば試せます。

```
@startuml

佐藤 -> 鈴木 : 依頼

鈴木 -> 田中 : 任せた

note left: 移譲

田中 -> 田中 : 作業

田中 --> 鈴木 : 結果

鈴木 --> 佐藤 : 結果

@enduml
```

![hoge.png](https://qiita-image-store.s3.amazonaws.com/0/263164/6267c207-d0ba-ebda-ba55-ae91fdf5a259.png)

また、PlantUMLは実行形式がjarファイルなので、
Java(JRE)が入ってればダウンロードするだけで実行できます。

```user$ java -jar plantuml.jar hoge.txt```

そのため、導入は非常に簡単です。
以下、PlantUMLのメリット・デメリット。

**PlantUMLのメリット**

* Javaが入っていれば動く。
* 多様な図の作成に使用できる。
* 日本語が使える。
* 一般的な記法(例えばシーケンス図の場合、分岐や反復、並列など)は一通りできる。
* アイコンや矢印などの種類が多い。
* 改ページができるため、別に画像を分割する必要がない(シーケンス図の話)。
* ライセンスはGPLなので、商用利用可能。
* 公式ページの情報量が多い。

**PlantUMLのデメリット**

* 記法が非常に多いので真面目に全部暗記するのはほぼ無理です。
* 自由記入可能なOfficeやastahに比べると制限があります。
(例えばシーケンス図で同じタイミングでシーケンスを書くといったことはできないので、表現には工夫が必要でした)

## おまけ

私は試していませんが、EclipseやIntelliJ、Atomなどを使えば、
テキストを書きながら図のプレビューが見れるとかなんとか…。
また、アドオンを入れるとGoogle DocsやRedmine、LatexなどでもPlantUMLを使用できるようです。

# 最後に

以下、テキストで作図をする場合のメリット・デメリットです。

**テキストによる作図のメリット**

* 作成・修正・流用(コピペ)が簡単。
* PCパワーが不要。
* diffで修正差分の比較ができる(diffに限った話ではないです)。
* grepで検索ができる(grepに限った話ではないです)。
* 今後の展望ですが、DSLからアプリやインフラの設定の雛形を作成する未来があるかもと勝手に思ってます。

**テキストによる作図のデメリット**

* CUIなのでGUIと違って覚える必要がある。 ~~(Officeやastahも大概多い)~~
* できることは提供された機能のみ。

---

# 関連記事

* [PlantUML シーケンス図で便利だと思った機能・使い方](https://qiita.com/yhornisse/items/b5ff87e63125828b52c1)  
* [PlantUMLで見ためを変更
](https://qiita.com/yhornisse/items/a1f85c876e1cadaaf348)
ssh接続でUNPROTECTED PRIVATE KEY FILE!できなかったときの対処

サーバーを作り直したりしていると、ssh で繋ごうとしたときに下記の警告が出た。

```
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
```

仰々しいが、同じ接続先なのに中身が違うよーってことだと警告しているのだと理解したい。

身に覚えがあるのであれば、

```
ssh-keygen -R ホスト名
```

として消すことができる。
これが、うまくいかなくとも、手動で、~/.ssh/known_hosts でホスト名が書かれている行を削除すれば接続できるようになる。
【Swift】VIPER導入のススメ

# 前段
* MVCから脱却したくてMVPを勉強し、実際に導入してみた
    * https://qiita.com/hicka04/items/25be38a90fdde29c97c2
* そこで以下の学びがあった
    * テスト書けそうで実は書けないコードになっていなかった。(勉強不足)
    * ModelとPresenterのどちらに書くべきかをちゃんと決めていなかったので、  
      FatPresenterやFatModelを作り出してしまった
    * 画面遷移処理をPresenter→Viewにお願いする必要があり、  
      画面の更新処理と混在して見通しが悪くなった

# そこでVIPER!
## VIPERって?
[こちらの記事](https://qiita.com/hicka04/items/09534b5daffec33b2bec)にまとめましたので、詳しくはそちらを参照ください

## 導入してよかったと思うポイント
* 単一責任の原則をとっており、どこにどの処理を書くべきかが定められている  
  →実装するときに**処理をどこに書くかで迷わなくなった**
* Routerがいい仕事している
    * Routerを見れば依存関係がわかる
    * DIの方法が確立しているので**テストをかけるコードになった**
    * Viewが画面の更新処理だけに集中できるようになり、**コードの見通しがよくなった**

``` Swift:Routerのサンプル
protocol HogeWireframe: class {

    // HogeViewから遷移したい画面をここに書く
    func showFugaView()
}

class HogeRouter {

    // HogeViewControllerが必要なのでイニシャライザで受け取る
    weak var viewController: UIViewController?

    private init(viewController: UIViewController) {
        self.viewController = viewController
    }

    // DI 定型文
    static func assembleModule() -> UIViewController {
        let view = HogeViewController()
        let interactor = HogeInteractor()
        let router = HogeRouter(viewController: view)
        let presenter = HogePresenter(view: view, interactor: interactor, router: router)

        view.presenter = presenter
        interactor.output = presenter

        return view
    }
}

extension HogeRouter: HogeWireframe {

   // 画面遷移の処理
   // 遷移先のDIは遷移先のRouterにお願いする
   func showFugaView() {
       let fugaView = FugaRouter.assembleModule()
       // イニシャライザで受け取ったviewControllerはここで使う
       viewController?.navigationController?.pushViewController(fugaView, animated: true)
   }
}
```

学びをすべて解消できた!!

# 導入までにやったこと
## まずはお勉強
VIPERに関する記事やらコードをみてお勉強

* [iOS Project Architecture : Using VIPER [和訳]](https://qiita.com/YKEI_mrn/items/67735d8ebc9a83fffd29)
* [ぼくのやっているVIPER(のようなもの)](https://qiita.com/Yaruki00/items/d350709678ff0aec93cc)
* [iOSなフレームワークViperのススメ](https://speakerdeck.com/hirothings/iosnahuremuwakuviperfalsesusume)

## 実際に書いてみる
* 書くときに迷わないのと、Routerのいい仕事してる感が感じ取れたら、VIPERの魅力に気付けた証拠
* ※書いてるとわかるが、毎回同じようなコードを書く必要がある。1つの画面を作るだけでも5つのファイルを作る必要がある…。

## コード自動生成ツールを導入
* [Generamba](https://github.com/rambler-digital-solutions/Generamba) (ジェネラムバ?)
    * インストール方法などはこちらの記事を参考にした  
      [iOS開発で VIPER / Clean Architecture を使うなら、ファイル自動生成の Generamba もどうぞ](https://qiita.com/YKEI_mrn/items/d1f79ceddf6e009fdcd0)
* デフォルトのテンプレートが使いづらかったので、テンプレートも自作してみた
    * https://github.com/hicka04/generamba-templates
    * テンプレートの書き方はこちらの記事を参考にした  
      [【iOS】GenerambaのテンプレートエンジンLiquidの書き方](https://qiita.com/tmyk110/items/de8f2aee315b47040c5e)

## 満を持して会社のコードに適用&布教
* 勉強してても最初は書き慣れておらずコーディングに時間がかかるので、その旨をチームの人に行っておくのが大事だった。
* アーキテクチャのミニ勉強会を開催して、VIPERの布教活動
    * 書く人だけじゃなく、**コードレビューをしてくれる人**も巻き込んだ
    * [モバイルアプリアーキテクチャ勉強会](https://qiita.com/star__hoshi/items/f28095542f56a1b05e34)の記事を上から順番に説明しつつ、VIPERを含めたいろんなアーキテクチャの勉強をした

# 最後に
* VIPERの特徴
    * 単一責任で処理を書く場所が決まっている
    * RouterのおかげでDIと画面遷移の仕組みが確立している
    * 生成するファイルが多いので、自動生成ツールで解決
* 前段のように同じ悩みを持っている人は導入を検討してもらいたい
    * Routerだけでも導入するとよい
* **VIPERは最高**
std::arrayを使って多元配列を作成する (C++11)

# この記事について

C++11で定義されたstd::arrayを使って多元配列を記述する方法について説明します。

# 多元配列の記述方法

以下のように記述することで、多元配列を表現できます。

```c++
#include <array>

// int[2][3]の場合
std::array< std::array<int, 3>, 2 > mat2x3 = {0,1,2, 3,4,5};

// []を使ってアクセスできます
std::cout << mat2x3[1][1]; // 4
mat2x3[0][1] = 10;         // 1 -> 10に置き換え
```


# テンプレートによる型定義

上記のままでは定義方法が煩雑なため、テンプレートを使った型定義により利便性を向上させます。

```c++:MultiDimensionalArray.h
/**
 * @file  MultiDimensionalArray.h
 * @brief 多元配列を作成しやすくするためのテンプレートクラス
 */
#ifndef MYLIBRARY_MULTI_DIMENSIONAL_ARRAY_H___
#define MYLIBRARY_MULTI_DIMENSIONAL_ARRAY_H___

//-------------------------------------------------------
// includes
//-------------------------------------------------------
#include <iostream>
#include <array>

//-------------------------------------------------------
// namespace
//-------------------------------------------------------
namespace mylibrary{

//-------------------------------------------------------
// public classes
//-------------------------------------------------------

// テンプレートの可変引数を利用して、<Type,2,3>や<Type,2,3,4>などを定義できるようにします
// <Type,2,3>  ：Type[2][3]
// <Type,2,3,4>：Type[2][3][4]
// となります。
template <class T, std::size_t N, std::size_t... M>
struct MultiDimensionalArrayType
{
    // arrayのネスト部分の型定義
    // MultiDimensionalArrayType<Type, N, M,・・・>::typeで
    // std::array< std::array< std::array< Type,・・・>, M > N >を表現できます
    using nested = typename MultiDimensionalArrayType<T, M...>::type;
    using type   = std::array<nested, N>;
};


template <class T, std::size_t N>
struct MultiDimensionalArrayType<T, N>
{
    using type = std::array<T,N>;
};


// MultiDimensionalArrayType<Type, N, M,・・・>::typeの「type」を書かなくてもよいように
// 型名を置き換えます。利用者側はMultiDimensionalArrayを使います
template <class T, std::size_t N, std::size_t... M>
using MultiDimensionalArray = typename MultiDimensionalArrayType<T, N, M...>::type;

}       // namespace
#endif  // include guard
```

MultiDimensionalArrayを使うことで、わかりやすく多元配列を定義できます。定義後の変数の使い方はstd::arrayと同様で、[]によるアクセスが可能です

```c++:main.cpp
#include "MultiDimensionalArray.h"

int main(){
    mylibrary::MultiDimensionalArray<float,2,3> mat2x3;

    std::cout << mat2x3[1][1];
    mat2x3[0][1] = 10;
    return 0;
}

```

# 補足

boostを使える環境であれば、boost::multi_arrayで同様に多元配列を扱うことができます。

boost::multi_array
https://www.boost.org/doc/libs/1_63_0/libs/multi_array/doc/user.html
[Swift4] UserDefaultsとKeychainを綺麗に管理する！

# はじめに
UserDefaultsとKeychainは各所から参照される存在であり、その責務を一点に集中させたいと考えました。
そこで、<font color="ORANGE">**シングルトンの「Service構造体」**</font>を生成し、<font color="RED">**Subscripts**</font>・<font color="ORANGE">**ジェネリクス**</font>・<font color="ORANGE">Enum</font>を使ってまとめました。[^1]

なお、[KeychainAccess](https://github.com/kishikawakatsumi/KeychainAccess)という有名なライブラリを使っています。

# こう使えるようにした！
```swift
 let sessionID = S.getKeychain(.SessionID)
 
 let isFirstLaunch: Bool? = S.getUserDefaults(.isFirstLaunch)
```
いいかんじ〜

# 実装
```Service.swift
import Foundation
import KeychainAccess

let S: Service.Type = Service.self

let SERVICE_NAME = "com.example.sensuikan1973"

struct Service {
    private init(){}
    static let keychain = Keychain(service: SERVICE_NAME)
    static let userDefaults = UserDefaults.standard
}

// MARK: Keychain
enum Keychain_Keys: String {
    case SessionID = "SessionID"
}

extension Service {
    static func getKeychain(_ key: Keychain_Keys) -> String? {
        return keychain[key.rawValue]
    }
    
    static func setKeychain(_ key: Keychain_Keys, _ value: String?) {
        keychain[key.rawValue] = value
    }
}

// MARK: UserDefaults
enum UserDefaults_Keys: String {
    case isFirstLaunch = "isFirstLaunch"
}

extension Service {
    static func setDefaultUserDefaults() {
        userDefaults.register(defaults: [UserDefaults_Keys.isFirstLaunch.rawValue: true])
    }
    
    static func setUserDefaults<T>(_ key: UserDefaults_Keys, _ value: T) {
        userDefaults[key] = value
    }
    
    static func getUserDefaults<T: Any>(_ key: UserDefaults_Keys) -> T? {
        return userDefaults[key]
    }
    
    static func removeUserDefaults(_ key: UserDefaults_Keys) {
        userDefaults.remove(key)
    }
}
```

```UserDefaults+subscript.swift
extension UserDefaults {
    subscript<T: Any>(key: UserDefaults_Keys) -> T? {
        get {
            let value = object(forKey: key.rawValue)
            return value as? T
        }
        set {
            guard let newValue = newValue else {
                removeObject(forKey: key.rawValue)
                return
            }
            set(newValue, forKey: key.rawValue)
        }
    }
    
    func remove(_ key: UserDefaults_Keys) {
        removeObject(forKey: key.rawValue)
    }
}
```


# 参考
- [Swift4でUserDefaultsを簡単に扱う](http://tech.unifa-e.com/entry/2018/01/09/143231)
- [[Swift]ProtocolとEnumでSwiftライクな一元管理で綺麗なコードを書く工夫](https://qiita.com/H_Crane/items/15b93a4403a10426627a#userdefaults) : チェーンで参照する書き方について。本稿とは異なるアプローチです。

[^1]: [Swift 4.2 Subscripts](https://docs.swift.org/swift-book/LanguageGuide/Subscripts.html)
MLMultiArrayの初期化

# 初期値は保証されない

こんなふうにイニシャライズする。

```
let input = try! MLMultiArray(shape: [3, 100, 100], dataType: .double)
```

何度か確認してみて0で初期化されてるっぽい、と騙されたら駄目。
時折↓こんな値が入っている。

```
  [0] = 0
  [1] = 4.2481962465896993E+180
  [2] = 0
  [3] = 3.991904287573309E+252
  [4] = 4.71049340390293E+257
  [5] = 1.9485307275297634E-153
  [6] = 6.0134700169917274E-154
  [7] = 0.0000000000000000000000000000000000000000000000000000000035248571487052602
  [8] = 6.0134700169916227E-154
  [9] = 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080177859870554834
  [10] = 2.5827657058487438E-144
  [11] = 1.1459827119906385E-259
  [12] = 4.134823634245056E+193
以下略
```

0で初期化したい場合はちゃんと0を入れましょうね、という事でした。

# おまけ

ちなみにMLMultiArrayをflattenしてDouble型の1次元配列にする拡張をデバッグでよく使ってる。

```
extension MLMultiArray {
    public func doubleArray() -> [Double] {
        if self.count == 0 {
            return [Double]()
        }
        let ptr = self.dataPointer.bindMemory(to: Double.self, capacity: self.count)
        return Array(UnsafeBufferPointer(start: ptr, count: self.count))
    }
}
```

# おまけ2
【追記】
割と大きいサイズのMLMultiArrayのすべてに0を愚直に代入するのは駄目だろうと思って色々やり方を模索した結果、

```
extension MLMultiArray {
    public func doubleArray() -> [Double] {
        【略】
    }

    public func zeroInit() {
        let ptr = self.dataPointer.bindMemory(to: Double.self, capacity: self.count)
        let ptr_buf = UnsafeMutableBufferPointer.init(start: ptr, count: self.count)
        let zeros = repeatElement(Double(0.0), count: self.count)
        _ = ptr_buf.initialize(from: zeros)
    }
}
```

こうなった。

サイズ分の0の配列を定義して領域確保するよりもRepeated型（他のプログラミング言語的にいうイテレータ？）で渡す方が節約されてそうという印象。（実際は確証はないですが…）
ただしサイズの情報を持った `UnsafeMutable「Buffer」Pointer` でないとRepeatedを渡して値を初期化できないのでそのような型変換をしています。

※ 厳密にはUnsafeMutablePointerでもできますが、DeprecatedでSwift4.0で削除されるっぽいです。
WebページにシンプルなSlack投稿ボタンをつくる

#社内配布のWebサービスで、フィードバックが欲しい...
アンケートとるのもあれなので、いいねボタンを埋め込もうと思います。

#Likeボタンを適当な場所に仕込む
ヘッダーバーの横が空いてたので、そこにボタンを入れました。
<img width="187" alt="スクリーンショット 2018-06-09 13.49.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/242744/e929287e-e5bc-c208-8a98-caa992c50171.png">

##コード

```html:html

<button class="mdl-button mdl-js-button mdl-button--icon" onclick="sendLikeToSlack()">
    <i class="material-icons">thumb_up</i>
</button>
```
ボタンにonclickイベントをつけます。(Material Design Liteを用いてます。)

```js:js

function sendLikeToSlack() {
    let xmlhttp = new XMLHttpRequest();
    //自分のwebhook URLを取得して、以下に代入
    let webhook_url = 'https://hooks.slack.com/services/******/******/******';
    let myJSONStr = '{"username": "ゆーざー" ,"text":"いいね",  "icon_emoji": ":heartpulse:"}';
    xmlhttp.open('POST', webhook_url, false);
    xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xmlhttp.send(myJSONStr);
}
```

slackのwebhook_URLにXMLHttpRequest()でPOSTします。
webhook_URLの取得は多くの記事がありますが、
https://qiita.com/vmmhypervisor/items/18c99624a84df8b31008
などを参考にしました。

#押してもらう
ポチっ
<img width="261" alt="スクリーンショット 2018-06-09 13.40.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/242744/383917d6-6d0f-ccdc-89d0-37f0c68c98ff.png">


#Slackに届いた！
<img width="582" alt="スクリーンショット 2018-06-09 13.56.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/242744/71a46a06-1950-3e34-81f6-fec7875d4ad6.png">

#終わりに
**これ、ちょっとしたフォームを作れば、Slackにメッセージを送るようにできますね。**
メールフォームみたいにシンプルに、slack投稿フォームをコピペで埋め込むことができるわけです。

いわゆるMVP(Minimum Viable Product)に使うことで、高速な仮説検証を回せそう...


　

######以前のslackの関係の記事
https://qiita.com/maatumoDev/items/f9497d5b37757db1b276
KeyboardObserverでTextFieldをずらす

KeyboardObserver_RxSwiftをpodで入れてこんな漢字

```swift

    private var keyboardObserver = KeyboardObserver()

        keyboardObserver.willHide { (event) in
                UIView.animate(withDuration: 0.5, animations: {
                    self.view.transform = CGAffineTransform.identity
                })
            }.didHide { (event) in
            }.willShow { (event) in
                let moveDistance = 100
                UIView.animate(withDuration: 0.5, animations: {
                    let transform = CGAffineTransform(translationX: 0, y: CGFloat(-(moveDistance)))
                    self.view.transform = transform
                })
            }.didShow { (eevnt) in
```
【Jenkins備忘録】Python自動テスト環境構築①Python準備編

・Ubuntu16.04のインストールが完了したところからスタート

### マシンスペック & OS

| OS  | Linux Ubuntu 16.04 64bit |
|---  |---                       |
| CPU | Core2 Duo                |
| RAM | 4GB                      |
| ROM | 80GB                     |

### Python3.6のインストール

```sh

# とりあえずアップデート  
$ sudo apt-get update
# gitをインストール  
$ sudo apt-get install git  

# Pythonのビルドに必要なライブラリをインストール  
$ sudo apt-get install build-essential libncursesw5-dev libgdbm-dev libc6-dev zlib1g-dev libsqlite3-dev tk-dev libssl-dev openssl libbz2-dev libreadline-dev
```

### pyenvのセットアップ

```sh
$ git clone https://github.com/yyuu/pyenv.git ~/.pyenv
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.profile
$ echo 'eval "$(pyenv init -)"' >> ~/.profile
$ source ~/.profile
```

### Python3.6.0をインストール
・pyenvでインストール。

```sh

$ pyenv install 3.6.0
```

### Python3.6.0をデフォルトに設定
・Ubuntu16.04のデフォルトPythonのバージョンは2.7なので、
　以下のコマンドを実行してインストールしたPython3.6.0バージョンを切り替える。

```sh

# 変更前確認  
$ python --version

# Python3.6.0をglobalに設定  
$ pyenv global 3.6.0

# version確認 
$ python --version
```
macbook pro でzipファイルにパスワードを掛ける方法

どうやらmacでは専用のアプリをインストール必要がないらしい。
#ファイルを圧縮する
圧縮したいファイルまたはフォルダをFinderから右クリック→["選択したフォルダ名またはファイル名"を圧縮]をクリックする。
#terminalでpasswordを掛ける
1. spotlight検索で`terminal`と検索して起動する。
2. `zipcloak "ファイル名"`でEnter（この時Finderから圧縮したzipファイルをドラッグ&ドロップすると簡単）
3. Enter password: と表示されるので任意のpasswordを入力する（入力した文字は見えない）
4. Verify　password:と表示されるので再度同じpasswordを入力すする（入力した文字は見えない）

思ったよりも簡単だったなー
Ubuntu Rails5 nokogiri 1.8.2 インストール エラー時の解決メモ

こんなエラー

```console
Installing nokogiri 1.8.2 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /var/lib/gems/2.5.0/gems/nokogiri-1.8.2/ext/nokogiri
/usr/bin/ruby2.5 -r ./siteconf20180609-8585-1wf897h.rb extconf.rb
mkmf.rb can't find header files for ruby at /usr/lib/ruby/include/ruby.h

extconf failed, exit code 1

Gem files will remain installed in /var/lib/gems/2.5.0/gems/nokogiri-1.8.2 for inspection.
Results logged to /var/lib/gems/2.5.0/extensions/x86_64-linux/2.5.0/nokogiri-1.8.2/gem_make.out

An error occurred while installing nokogiri (1.8.2), and Bundler cannot continue.
Make sure that `gem install nokogiri -v '1.8.2' --source 'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  rails was resolved to 5.1.4, which depends on
    actioncable was resolved to 5.1.4, which depends on
      actionpack was resolved to 5.1.4, which depends on
        actionview was resolved to 5.1.4, which depends on
          rails-dom-testing was resolved to 2.0.3, which depends on
            nokogiri

```

ググった。
https://stackoverflow.com/questions/49692252/installing-nokogiri-1-8-2-for-metaslpoit


下記でコマンドで実行後、再びインストールで成功しました。


```console
 sudo apt-get install build-essential liblzma-dev patch ruby-dev zlib1g-dev
```
これらがインストールされていなかったため、エラーになった。

```console
libgmp-dev libgmpxx4ldbl liblzma-dev ruby-dev ruby2.5-dev ruby2.5-doc
```

###TODO
インストールできなかった原因のパッケージを調べる
動的計画法でナップザック問題を解く

[Javaプログラマのためのアルゴリズムとデータ構造](https://www.amazon.co.jp/Java%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0-%E8%BF%91%E8%97%A4-%E5%98%89%E9%9B%AA/dp/4797326603)を参考にしています。
ソースコードは[GitHub](https://github.com/be-kan/knapsack_with_dynamic_programming)にあげています。

```java
import java.util.*;

public class Knapsack {
  int[] size;
  int[] value;
  int N;

  // ナップザック問題を表すオブジェクト
  public Knapsack(int[] size, int[] value) {
    if (size.length != value.length) {
      throw new IllegalArgumentException("'size'と'value'の要素数が一致していません");
    }

    this.N = size.length;
    this.size = (int[])size.clone();
    this.value = (int[])value.clone();
  }

  
  // 大きさmのナップザックに色々入れていく
  public void solve(int m) {
    int[] total = new int[m+1];
    int[] choice = new int[m+1];
    Arrays.fill(choice, -1);
    int repackTotal;
    System.out.printf("ナップザックの大きさは%d%n", m);

    // 品物を１つずつ入れて、ボトムアップ的に最大価値を求める
    for (int i = 0; i < N; i++) {

      // 品物iを一箇所ずつ入れていく
      for (int j = size[i]; j <= m; j++) {
        repackTotal = total[j - size[i]] + value[i];
        if (repackTotal > total[j]) {
          total[j] = repackTotal;
          choice[j] = i;
        }
      }

      System.out.printf("i = %d%n", i);
      System.out.printf("total = ");
      for (int j = 0; j <= m; j++) {
        System.out.printf("%4d", total[j]);
      }
      System.out.printf("%nchoice = ");
      for (int j = 0; j <= m; j++) {
        System.out.printf("%4d", choice[j]);
      }
      System.out.printf("\n");
    }

    for (int i = m; choice[i] >= 0; i -= size[choice[i]]) {
      System.out.printf("品物 %d (価値 %d) を詰め込む %n", choice[i], value[choice[i]]);
    }
    System.out.printf("価値の合計 = %d%n", total[m]);
  }


  public static void abort(String message) {
    System.err.printf("起動法: java Knapsack 大きさ%n");
    System.err.printf("%s%n", message);
    System.exit(1);
  }


  public static void main(String args[]) {
    Knapsack knapsack = new Knapsack(
      new int[] {2, 3, 5, 7, 9},
      new int[] {2, 4, 7, 11, 14}
    );

    int size = 0;
    if (args.length != 1) {
      abort("パラメータの個数が違います。");
    }
    try {
      size = Integer.parseInt(args[0]);
    } catch (NumberFormatException e) {
      abort("大きさには正の整数を指定してください");
    }
    if (size <= 0) {
      abort("大きさには正の整数を指定してください");
    }

    knapsack.solve(size);
  }
}

```
SkyWay Android SDKを使って多人数配信をやってみる！

# はじめに

- この資料は[Android Bazaar and Conference 2018 Spring 大LT祭り](https://abc.android-group.jp/2018s/app/#lt)の発表資料です。

---

# 自己紹介

- なかゆうすけ
- Twitter: [@Tukimikage](https://twitter.com/Tukimikage)

---

# WebRTCご存知ですか？

---

# ![image.png](https://qiita-image-store.s3.amazonaws.com/0/6651/4eade2f5-a189-f427-089e-24c2675593e5.png)

WebRTC = **W**eb **R**eal **T**ime **C**ommunication

IETFとW3Cにより標準化されている、リアルタイムコミュニケーションの標準技術です。

---

# SkyWayご存知ですか？

---

# ![image.png](https://qiita-image-store.s3.amazonaws.com/0/6651/cff72532-07c8-ebee-7c0d-80d8e08e125e.png)

- 自社のAndroid/iOSアプリやWebアプリに、WebRTCの音声・ビデオ通話機能を簡単に組込むことが出来る、プラットフォームサービス

- 無料ですぐに利用可能

- 詳しくは [SkyWay公式サイト - 開発者](https://webrtc.ecl.ntt.com/developer.html)

---

# 今日やること

---

# SkyWayのSFUを使って多人数配信

---

# デモのイメージ

---

![image.png](https://qiita-image-store.s3.amazonaws.com/0/6651/099e6671-0054-d272-6835-8660b0a4f4ba.png)

---

# SFUとはなにか

![image.png](https://qiita-image-store.s3.amazonaws.com/0/6651/9020e1d7-517d-8cb3-9040-2f56fb6e9007.png)

- WebRTCを使って多人数接続を実現する仕組みの一つ
- メディアのアップロードの数を1本に押さえられるのでクライアントの負荷が軽い
- 今日はこのSFUを使って**1:多の配信**を行います

---

# Android/PC Chromeでデモにご協力下さい！

---

# Let's access

## Android Camera

以下のソースコードをダウンロードの上、APIキーを書き換えてビルド実行して下さい。
room nameは `abc` です。
https://github.com/yusuke84/abc2018lt/tree/master/android_camera

## Web Camera **※2020.07.08追加**

以下にアクセスしてjoinして下さい。
room nameは `abc` です。
https://yusuke84.github.io/abc2018lt/web_camera/

## Web Viewer

以下にアクセスして視聴ボタンをクリックして下さい。
https://yusuke84.github.io/abc2018lt/web_viewer/public/

---

# ソースコード

- https://github.com/yusuke84/abc2018lt
  - android_camera : 配信用Androidアプリ
      - [SkyWay公式サンプル](https://github.com/skyway/skyway-android-sdk/tree/master/examples/sfu-videochat)を改造して利用
          - 映像を受信する必要がないため、UIと`Room.RoomEventEnum.STREAM`イベント発火時の処理を修正
  - web_camera : 配信用Webアプリ **※2020.07.08追加**
      - [SkyWay公式サンプル](https://github.com/skyway/skyway-js-sdk/tree/master/examples/room)を改造して利用
          - 映像を受信する必要がないため、UIと関連処理を修正
  - web_viewer : 視聴用Webアプリ
      - JavaScriptのコード160行ぐらいで実装可能

---

# 最後に

- **2020.07.08追加**
  - 以下のワークアラウンドは不要となりました。
  - 尚、デモ用で実装を省略している関係で、以下の制約があります
      - 必ず「配信用Androidアプリ」または「配信用Webアプリ」で配信を開始してから、視聴用Webアプリにアクセスしてください（順序性あり）
      - 配信者は必ず1人にしてください（複数人の配信には対応していません）。
  
- ~~このデモではSkyWayの現在（2018.06.09）の制約上、以下ワークアラウンドを2つ利用しています~~
    1. ~~[受信のみモード☓SFUモードのワークアラウンド](https://qiita.com/yusuke84/items/13fab1d0f97c466e4d4b#skyway%E3%82%92%E9%85%8D%E4%BF%A1%E3%81%AB%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88%E3%81%AE%E3%83%86%E3%82%A3%E3%83%83%E3%83%97%E3%82%B9)~~
    2. ~~必ず配信用アプリで配信を開始してから、視聴用ウェブにアクセスしてください（順序性あり）~~

---

# ご清聴ありがとうございました！
[R]st_readで日本語のshpを読み込むときの設定

忘れるのでメモ。

日本語を含むshpファイルをsfパッケージで読み込むと文字化けするので
ENCODINGのオプションをつける


```r 

shp <- sf::st_read("import.shp",options = "ENCODING=CP932")

```

文字列をfactorにしたい場合は

```r

shp <- sf::st_read("import.shp",options = "ENCODING=CP932", stringsAsFactors=TRUE)

```
Debian 8 (jessie) から 9 (stretch) にアップグレードしたらApacheが起動しなくなったのでなんとかした

# Debianのアップグレード方法

この辺を見ながら頑張る。

- https://www.debian.org/releases/stable/amd64/release-notes/ch-upgrading.html
- https://mov.vc/posts/11

自動更新予定のパッケージを上手く止められなかったんですが、今回の原因はそれではなさそう。
~~MySQLとかがjessie用のままなので後日どうにかする（とりあえず動く）。~~→別の不具合でインスタンスにログインできなくなったので結局stretchのディスクで作り直した…。

# Apache2が起動しない

```
$ sudo service apache2 start
Job for apache2.service failed because the control process exited with error code.
See "systemctl status apache2.service" and "journalctl -xe" for details.
```

MySQLは動くのに何故なんだ～。

## 1. 再インストールしてみる

ログを見てもよく解らなかったのでとりあえず。
結論から言うと上手くいかなかった。

- 参考：[Debian 完全にApache2をアンインストールし、再インストールする](https://viewse.blogspot.com/2011/02/debian-apache2.html)

`apt-get remove --purge [packages]` でapache関連を全部消す。
**設定ファイルも消えるので /etc/apache2 をホームディレクトリ等にバックアップしておく。**

## 2. 設定ファイルを調べる

アップグレード（または再インストール）に伴い新しく設定ファイルが必要になったが、作成されていなかったらしい。

- 参考：[VPSのApacheが動いてなかった件 → 解決](http://esf.hateblo.jp/entry/2015/10/28/155203)

`apachectl configtest` で設定ファイルのシンタックスエラーが見つけられます。
上記記事とは違うファイルが無いと怒られていたようです。
指定の場所に空のファイルを作って無事解決しました。
Link

# **ファイルリンク**について


--- 
- シンボリックリンク  
ファイル名を参照しているよ。  
Windowsでいうショートカットファイル。   
実態消えたら使えないよ。

---
- ハードリンク  
ファイルのiノード(ID)を参照しているよ。  
  他のディスクにファイルを置けないよ。  
実態消えてもパーティションにハードリンクが全部残って入れば使えるよ。

---

- コピー　：ファイルの実態を複製。リンクパスは通っていないよ。  

---
【IIS】Webサイトで突然認証ダイアログが表示されるようになった問題(共有が原因)

# はじめに
開発中のWebサイトにアクセスしたら、突然認証ダイアログが表示されるようになってしまった。
前日の終業間近に「[2018 年 5 月の更新プログラム適用によるリモート デスクトップ接続への影響](https://blogs.technet.microsoft.com/askcorejp/2018/05/02/2018-05-rollup-credssp-rdp/)」の件でWindows Server 2016にパッチをあてたこともあり、これが原因かも知れないとパッチをアンインストールしたものの、結果は変わらず。

ネットで調べて、IISのアプリケーションプールのIDを「Local System」から「Network Service」、「ApplicationPoolIdentity」、「Local Service」とかに変更してみた。
変更したことにより認証ダイアログは表示されなくなったが、逆に内部サーバーエラーとなり余計に訳が分らなくなった。

# 元の状態に戻す
サーバーは仮想環境で構築されており、たまたまメンテナンス関係で月曜日のバックアップが残っていたため、月曜日の状態に戻してもらった。
戻った状態で試してみると、認証ダイアログが表示されなくなっていたのでパッチを適用したことで何か起きたのかと思った次第です。

当日までの作業状態に戻すためにファイルやデータベースの変化点をコピーして、最後に共有フォルダを設定した後にWebサイトにアクセスしたら認証ダイアログが再度表示されるようになった。

# 原因
共有フォルダを設定したのが原因でした。(そういえば朝礼後に共有フォルダの設定をしたな・・・)
Webサイトのwwwrootフォルダには初期状態でアクセス許可に「IIS_IUSRS」や「IUSRS」が付くようになっています。今回はその親フォルダ(一般的にはinetpub、今回はEドライブの専用フォルダ)を共有しました。

親フォルダを共有した際に下図のように確認画面が表示されたが、この時にはアクセス許可の違いに気が付いていないため、そのまま「設定の変更」ボタンをクリックしました。
![ネットワークアクセス.png](https://qiita-image-store.s3.amazonaws.com/0/14053/a5537adb-bfc4-319a-a2dc-46eb43561c79.png)

そもそも「以下の表示されているフォルダーは以前に共有されていました。」では分からない、共有しようとしているところで、以前に共有されていましたって書いてあれば別に問題ないと思うわけですよ。

親フォルダのアクセス許可が反映されたことで、wwwrootフォルダから「IIS_IUSRS」や「IUSRS」が削除されてしまいました。

# 対応
wwwrootフォルダに「IIS_IUSRS」や「IUSRS」などのアクセス許可を付け直した。

# 最後に
Webサイトの設定変更する際に、いつもリモートデスクトップ接続した画面内で設定変更していたのですが、今回テスト作業でお手伝いする人が付き、テストで頻繁に設定変更するため、利便性を考えて共有フォルダ化したのです。

今回、原因のアクセス許可が削除されていたことに気が付かなくて何だかんだで半日潰してしまいました。

認証ダイアログが表示されるのではなく最初から内部サーバーエラーなら直ぐにアクセス許可に気がついたのか、まー調べ方が違ったかも知れないな。
トラブルが発生したときに別のトラブルが出てくると冷静になりにくい。冷静な時なら変化点により原因にすぐ辿りつくのにさ。