OmniAICreator/Qiita-1.07M huggingface dataset:
メールサーバ構築・独自ドメインのメールアドレス作成(3/4)～サーバーと独自ドメインの紐付編～

##目標
最終目標　：メールサーバを立てて、独自ドメインのメールアドレスを作成する
今回の目標：サーバーと独自ドメインの紐付

##必要なものごと
1. サーバーリソース確保→ [前回の記事](https://qiita.com/pypypyo14/items/08cf3e3fa8cc4d9e254b)
2. 独自ドメイン取得　　→ [前回の記事](https://qiita.com/pypypyo14/items/b03f9ba32bdd94636adf)
3. **サーバーと独自ドメインの紐付**→今回はこれ
4. メールサーバのインストール・設定

##どこのDNSサーバを使おうか
ホントはドメインとる前に考えておいたほうがよかったです。（浅薄）
以下3つを候補に、どこのサービスをつかうか検討しました。

2018年2月現在

| 候補 | 説明 | 月額 |
|:-:|:-:|:-:|
| お名前.com  | ドメイン管理元  |  0円※ |
| AWS(Route53)  | サーバ稼働元  | [料金表] (https://aws.amazon.com/jp/route53/pricing/) |
| Hurricane Electric Hosted DNS  | フリーDNSサービス  | 0円  |

※ 有料の機能もあり

Route53は月額利用料がかかりますが、可用性100%をうたっていてすごい。
今回は個人の趣味で作るものなのでもし数日落ちたところでそんなダメージはないですし、
委譲作業は何かと手間がかかりそうなので お名前.comさんにしました。

## 登録方法
###管理メニューにアクセス
お名前.comさんのドメインナビにログインし
「ドメイン設定>ネームサーバの設定>DNS関連機能の設定>内部ドメイン一覧」から
対象ドメインを選択した上で「DNSレコード設定を利用する」を選択


###レコード登録

必要な情報を入れて追加をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/174283/d88ded39-e975-c933-6978-a032c72195ea.png)
- ホスト名　お好みで。
- TYPE　　 IPv4のグローバルIPアドレスとの紐づけであればAを選択。
- TTL　　　キャッシュに何秒情報を保持するか(長短でメリデメリあるようなので大人しくデフォルトの3600にしました）
- VALUE　　サーバのグローバルIP



![image.png](https://qiita-image-store.s3.amazonaws.com/0/174283/b8b7a1df-f4da-c7a7-745c-960a544a9fa5.png)
レコード登録作業と同じ画面の最下位のチェックボックスにチェック入れれば
どうやら必須らしいメールサーバーの変更もまとめてできちゃうらしいです。

ここまで入れたら、設定する 選択で完了！

＊＊＊
(2018/02/07 追記)
メールサーバを立てるなら、AレコードだけじゃなくてMXレコードの登録も必須でした…。
というわけで登録
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/174283/ec646216-ad95-ee81-511a-79de0e8ec635.png)
※ これで ～～@osji.net 宛てのメールがmail.osji.net に届くようになります。

## 確認方法
nslookupコマンドでホスト名を確認したら、登録したアドレスがでてくるよ！
登録から5分くらいしてからコマンド叩いたら秒で出てきました。
グローバルIPはまるで意味ありませんが申し訳程度に隠す。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/174283/bb5c5917-2bb3-45e0-e209-1bea1bde1d74.png)

SSHでも名前で接続できるようになりました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/174283/7a58c2d1-d5af-aa29-0d36-70f01170c81f.png)
javaからkotlinに移行するときに悩んだポイントまとめ

#Javaで書いたAndroidアプリのコードをkotlinで置き換えようとしたときのつまづいたポイントを羅列するだけ

開発環境
IDE : android studio
OS : mac

##勘違いしてたこと
- kotlin使えばnullポ発生しない


##1. HashMapをそのまま流用しようとしたら怒られた

下記のようなJavaのコードを用いることがあるが
kotlinではMapは読み取り専用となるらしい
そのため、変更可能なMutableMapを代わりに用いる。

``` hoge.java
Map map = HashMap<>
```

今まで読み取り専用で書いていなかったことが露見しますね

``` hoge.kt
MutableMap map = HashMap<>
```

## 2. 厳格なnullチェック
nullが入りそうなコードがあると逐一怒ってくれる
ので、そのコードの直前でnullチェックをしてあげるようにしてた

ただ、値がnullの時に例外を投げてくれる、エルビス演算子なるものが
あるらしく、if文を書く量が増えることは防げた

```before.kt
val hoge = func()
if(hoge!=null){
  hoge.fuga()
}
```


```after.kt
func()?.fuga() ?: throw Exception("アカン") 
```

?.ってのは、安全呼び出しといって
直前の式がnullだった場合に、nullを返すらしい
UIViewをキラッとさせる


[jQueryを使わずCSSのみで画像をキラッとさせる](https://www.trust5.jp/jquery-light/)のswift版です

#こんな感じ
![demo](https://media.giphy.com/media/l4pT1DOfTIacMlU7m/giphy.gif)

#ソース

キラッとするView

```swift:LightView
class LightView: UIView {
  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
  
  private weak var light:UIView?
  
  private var isStartAnimation:Bool = false
  
  private let rotate:CGAffineTransform = CGAffineTransform.init(rotationAngle:45*CGFloat.pi / 180.0)
  
  override var frame: CGRect{
    didSet{
      guard let light = self.light else { return }
      light.frame = CGRect(x:0, y:0, width: self.frame.width * 0.4, height: self.frame.height)
      light.center = CGPoint(x: 0, y: 0)
    }
  }
  
  override init(frame: CGRect = .zero) {
    super.init(frame: frame)
    self.layer.masksToBounds = true
    self.setup()
  }
  
  private func setup(){
    let v = UIView()
    v.backgroundColor = .white
    self.addSubview(v)
    self.light = v
  }
  
  private func resetAnimation(){
    self.light?.transform = rotate
    self.light?.alpha = 0
  }
  
  private func animateLight(){
    guard self.isStartAnimation else {
      self.resetAnimation()
      return
    }
    
    let delay:Double = 2 //ここを乱数にするとランダムな間隔で光る
    
    UIView.animate(withDuration: 0.2, delay: delay, options: UIViewAnimationOptions.curveEaseInOut, animations: {
      self.light?.transform = self.rotate.concatenating(CGAffineTransform.init(scaleX: 0, y: 0))
      self.light?.alpha = 0.5
    }) { (success) in
      UIView.animate(withDuration: 0.2, delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
        self.light?.transform = self.rotate.concatenating(CGAffineTransform.init(scaleX: 4, y: 4))
        self.light?.alpha = 1
      }) { (success) in
        UIView.animate(withDuration: 0.2, delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
          self.light?.transform = self.rotate.concatenating(CGAffineTransform.init(scaleX: 50, y: 50))
          self.light?.alpha = 0
        }) { (success) in
          UIView.animate(withDuration: 0.2, delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
            self.resetAnimation()
          }) { (success) in
            self.animateLight()
          }
        }
      }
    }
  }
  
  func startAnimation(){
    self.isStartAnimation = true
    self.animateLight()
  }
  
  func stopAnimation(){
    self.isStartAnimation = false
  }
}}
```


使う方

```swift:ViewController
import UIKit

class ViewController:UIViewController{
  
  override func viewDidLoad() {
    super.viewDidLoad()
    
    self.view.backgroundColor = .black
    
    let lightView = LightView()
    self.view.addSubview(lightView)
    lightView.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
    lightView.center = CGPoint(x: self.view.frame.width/2, y: self.view.frame.height/2)
    lightView.backgroundColor = .red
    
    lightView.startAnimation()
  } 
}
```
MATLABのFigureが画面外にPopupする問題の解決

# その場しのぎ
[ここの記事](https://qiita.com/rysk-t/items/e29463ddb5ccd12ae93e)の手法が参考になった。

僕の場合，Figureを表示すると画面外にFigureが出て来る問題をいつしか抱えていたのだが。


```matlab
set(0,'DefaultFigureWindowStyle','docked') 
```

とやって解決することが出来た。

MATLAB公式の質問にも似たような話がある。
https://jp.mathworks.com/matlabcentral/answers/67553-controlling-matlab-figure-pop-up-location


# 出現位置制御

以下のようにして私は現在図の出現位置を調整している。matlabのどこか深い所でディスプレイの座標を読み違えているんだろうけどこれは結構面倒だ。

```matlab
set(0, 'DefaultFigurePosition', [-1500 0  400 300]);
```
Ruby（Rails）でsjisのパスワード付きファイルをunzipする

Rubyでパスワード付きのzipファイルを解凍する案件があり色々しらべてみたが、解凍の情報って案外すくないので、最近の方法をまとめてみた。

まず、調べて出てくるのは以下の方法
①[rubyzip](https://github.com/rubyzip/rubyzip)
②[zipruby](https://github.com/fjg/zipruby)
③[archive-zip](https://github.com/javanthropus/archive-zip)
④外部コマンド　unar

【結論】
④unar外部コマンドを利用して一時ディレクトリに出力してから処理する。(エラ-処理は無視してます)

```ruby:app/models/concerns/unzip.rb
require 'tmpdir'

module Unzip
  extend ActiveSupport::Concern

  class_methods do
    def tmpzipfiles(path, password)
      Dir.mktmpdir do |dir|
        system("unar -f -o '#{dir}' -p '#{password}' '#{path}'")
        Dir.glob(File.join(dir, "**/*")){ |f| yield(f) }
      end
    end
  end
end
```

Railsでの使い方はモデル内で

```ruby:app/models/model.rb
include Unzip

def hoge 
  tmpzipfiles do |f|
    # f（一時ファイル名）に対する処理
  end
end
```

以下は色々試した経緯です。

どちらもgemで入れられるライブラリーだが、②[zipruby](https://github.com/fjg/zipruby)はどうやらオワコンらしい。
ってことで一番メジャーそうな①[rubyzip](https://github.com/rubyzip/rubyzip)を使ってみる。

Railsなので、

```ruby:Gemfile
gem 'rubyzip'
```

一時ディレクトリに解凍してブロック処理を行い、終わったら削除としたいので、
Dir::mktmpdirを利用

```ruby:app/models/concerns/unzip.rb
require 'zip'
require 'tmpdir'

module Unzip
  extend ActiveSupport::Concern

  class_methods do
    def tmpzipfiles(path, password)
      entrys = []
      decrypter = password.present? ? Zip::TraditionalDecrypter.new(password) : nil

      Zip::InputStream.open(path, 0, decrypter) do |input|
        # get_next_entryするとinputのoffset（ポインタ）が動く
        while (entry = input.get_next_entry)
          Dir.mktmpdir do |dir|
            save_path = File.join(dir, entry.name)
            File.open(save_path, "wb") {|wf| wf.puts(input.read) }
            yield(save_path)
          end
        end
      end
    end
  end
end
```
としたんだが、どうもSJISの1文字だけのファイル("0\n\r")が正しく解凍できない。
それに、このコードがどうも嫌だ。input.get_next_entryって！そんで取得したentryではなく、inputからreadするところが、とっても嫌なので却下！

次に③の[archive-zip](https://github.com/javanthropus/archive-zip)使ってみる。これは殆ど情報がないけど、シンプルが売りで使いやすそうですね。

```ruby:Gemfile
gem 'archive-zip'
```

```ruby:app/models/concerns/unzip.rb
require 'archive/zip'
require 'tmpdir'

module Unzip
  extend ActiveSupport::Concern

  class_methods do
    def tmpzipfiles(path, password)
      Dir.mktmpdir do |dir|
        Archive::Zip.extract(path, dir, password: password)
        Dir.glob(File.join(dir, "**/*")){ |f| yield(f)  }
      end
    end
  end
end
```


こっちは3バイトファイルも問題なし、しかもコードもシンプルになりました。
しかし、ZIPファイル内にSJISの日本語ファイルとかフォルダがあると文字化けしてしまいます。
dockerを使って簡単にER図を作ってみる


# SchemaSpyをdocker内で使ってER図を作る

## SchemaSpyとは

https://github.com/schemaspy/schemaspy

SchemaSpyとは、現在のSchemaを元にER図を作るライブラリです。
現在の最新バージョンは6.0.0 RC2です。

公式ドキュメントは以下にあります。
http://schemaspy.readthedocs.io/en/latest/

## docker内で使ってみる

SchemaSpyではJavaとGraphvizに依存していますので、ローカル環境にインストールする必要があるのですが、こういう場合は最近ではdockerコンテナ内で構築してしまうようにしています。
docker内に環境をまとめることで、どのマシンでもローカルの環境に依存することなく独立して構築することができるので他人に渡すときにもとても楽になります。

Dockerfileのリポジトリは以下に公開しています。
https://github.com/cimadai/schemaspy

また、Docker HubでAutomation buildを設定していますので、以下のリポジトリからpullすることができます。
https://hub.docker.com/r/cimadai/schemaspy/

## 使い方

データベース名がpostgres、ユーザー名がpostgres、パスワードは空、というデータベースの場合、以下のコマンドでER図を生成できます。

```
docker run --rm -it -e DB_HOST=<YOUR_DB_HOST> \
  -v /path/to/output:/output cimadai/schemaspy
```

上記を実行すると、`/path/to/output` 内に「postgres」というディレクトリが生成されており、その中にindex.htmlが生成されています。

下図のようなリレーション図などが自動生成されています。便利ですね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/104844/1974b83b-3338-36cf-ffb4-62f5c670e92c.png)

他にも生成されるものはありますので、公式サンプルを参照してください。
http://schemaspy.org/sample/index.html

## 別のデータベースを参照したい

| 環境変数名 | 初期値 | 概要 |
| :--- | :--- | :--- |
| JDBC_DRIVER_PATH | postgresql-42.2.1.jar | 対象とするDBに接続するためのjdbcライブラリ |
| DATABASE_TYPE | pgsql | 何のDBを参照するか。ora (Oracle)やmysql (MySQL)、db2などがあります。 |
| DB_HOST | localhost | 対象DBのホスト名(or IP Address) |
| DB_NAME | postgres | 対象DB名 |
| DB_USER | postgres | 対象DBのユーザー名 |
| DB_PASS | (empty) | 対象DBのパスワード |

## 参考にした記事
https://qiita.com/genzouw/items/23cd0119715403e6e110
UIWebViewDelegateを利用してJSの検知や実行を行う

#概要
UIWebViewDelegateを利用して特定のJSイベントを検知したり、JSコードを実行する方法を簡単に紹介します。

#手法
下記のように、shouldStartLoadWithメソッドでurlを調べることでJSイベントの検知を、webViewDidFinishLoadでwebView.stringByEvaluatingJavaScriptを呼ぶことでJSの実行を行うことができます。

```swift:UIWebViewDelegateを利用してJSの検知・実行を行う
class WebViewController: UIViewController, UIWebViewDelegate {
    @IBOutlet weak var webView: UIWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.webView.delegate = self
    }
    

    // MARK: - UIWebViewDelegate
    func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
        if let requestUrl = request.url, requestUrl.absoluteString.contains("YOUR_JS_CODE") {
            // JSコードを検知
        }
        
        return true
    }
    
    func webViewDidFinishLoad(_ webView: UIWebView) {
        // JSコードを作成・実行
        let jsCode = createJSCode()
        webView.stringByEvaluatingJavaScript(from: jsCode)
    }
}
```

#用例
例えば、下記のように"document.title"のコードを差し込むことでWebViewのタイトルを取得し、ネイティブのNavigation titleに挿入するといったことも可能になります。

```swift:WebViewのタイトルをJSで取得する
func webViewDidFinishLoad(_ webView: UIWebView) {
    self.navigationItem.title = webView.stringByEvaluatingJavaScript(from: "document.title")
}
```
webpack 4入門：PostCSS(AutoPrefixerやcssnano)を使う方法

この記事は加筆して「[最新版で学ぶwebpack 4入門 \- Autoprefixerを取り込む方法 \- ICS MEDIA](https://ics.media/entry/17376#postcss-autoprefixer)」に引っ越しました。

※Google検索等でこのページに辿り着いた方がリンク切れでは申し訳ないので、残しています。ご了承ください。
active storageの画像がリンク切れする

## 問題
`Rails 5.2.0.beta2`で開発中、何故か画像がリンク切れする。
コードはドキュメント通り書いている。画像も指定の場所に上がっている。

```ruby:app/views/accounts/show.html.slim
= image_tag url_for(@account.avatar)
```

## 原因
`route.rb` でのエラー処理の記述が問題だった。
`route.rb`の一番最後に、以下のように記述して、エラーページを表示していた。

```ruby:config/route.rb
Rails.application.routes.draw do
  ...
  get "*path", controller: 'application', action: 'error404', via: :all
end
```

ところが、ActiveStrageは画像のリンクを、以下のように見ているらしい。

```ruby:rails/activestorage/config/routes.rb
Rails.application.routes.draw do
  get "/rails/active_storage/blobs/:signed_id/*filename" => "active_storage/blobs#show", as: :rails_service_blob, internal: true
  ...
end
```
`project/config/route.rb`が`rails/activestorage/config/routes.rb`よりも先に呼ばれるので、画像を呼ぶ前に、エラーページの方を呼んでしまう。

## 解決方法

エラーハンドリングに関する別の問題(上記のrouteでの記述では、RoutingErrorをキャッチできない)の記事を参考にした。
それと同じ方法でエラー処理するようにしたら解決した。

以下のファイルを作成して、`route.rb`の記述を削除。サーバを再起動する。

```config/initilizers/exceptions_app.rb
Rails.application.configure do
  config.exceptions_app = ErrorsController.action(:show)
end
```

```app/controllers/error_controller.rb
class ErrorsController < ApplicationController

  skip_after_action :verify_authorized

  layout 'application'

  rescue_from StandardError, with: :error500
  rescue_from ActionController::RoutingError, with: :error404
  rescue_from ActiveRecord::RecordNotFound, with: :error404

  def error404(exception = nil)
    logger.info "Rendering 404 with exception: #{exception.message}" if exception
    render template: 'errors/error404', status: 404
  end

  def error500(exception = nil)
    logger.info "Rendering 500 with exception: #{exception.message}" if exception
    render template: 'errors/error500', status: 500
  end

  def show
   raise
  end
end
```

詳細は以下の参考のリンクから。

## 参考
* Railsの ActionController::RoutingError は ApplicationController での rescue_from で捕まえられない:
https://qiita.com/gaaamii/items/183a9a3091a1751d833a
* Railsアプリの例外ハンドリングとエラーページの表示についてまとめてみた:
https://qiita.com/upinetree/items/273ae574f1c021d24c37#exceptions_app%E3%81%AB%E3%82%88%E3%82%8B%E4%BE%8B%E5%A4%96%E6%8D%95%E6%8D%89
オフラインリアルタイムどう書く E21 の実装例

問題 : http://mtsmfm.github.io/2018/02/03/doukaku-e21.html
解答リンク集 : https://qiita.com/mtsmfm/items/b48952dee07784cce8f2

負けた。

帰宅した後でみなおして、テスト通した：

```ruby:ruby
def okay( revo0, ms, bc )
  revo = revo0.dup
  rpos = mpos = 0
  dead = [false]*ms.size
  expected = ms.map{ |x| x[1] }
  states = {}
  loop do
    s = [ bc, rpos, mpos, dead, revo ].inspect
    return false if states[ s ]
    states[s] = true
    if revo[rpos]
      revo[rpos]=false
      raise "zombie!" if dead[mpos]
      dead[mpos]=true
      bc-=1
      return dead == expected if bc==0
    else
      rpos = ( rpos+ms[mpos][0] ) % revo.size
    end
    loop do
      mpos = (mpos+1) % ms.size
      break unless dead[mpos]
    end
  end
end

def solve( src )
  members, srevo = src.split("/")
  rcount = srevo.to_i
  members = members.scan( /\[\d\]|\d/ ).map{ |x| x.size==3 ? [x[1].to_i,true] : [x.to_i, false]}
  bcount = members.count{ |x| x[1]}
  [*0...rcount].combination( bcount ).flat_map{ |s|
    revo = Array.new(rcount){ |x| s.include?(x) }
    if okay( revo, members, bcount )
      [revo.map{|x| x ? ?1: ?0 }.join]
    else
      []
    end
  }.join(",")
end

TESTS=<<TESTS.freeze
/*0*/ test("3[2]3/6", "000100");
/*1*/ test("21[3]/6", "000100");
/*2*/ test("12[3]/6", "000100");
/*29*/ test("[7][6][5]54[5]8[5]53[8]1/15", "010001110010001");
TESTS

$stdout.sync=true

TESTS.scan( /(\d+)\*\/\s*test\("([^\"]+)",\s*"([^\"]+)"\)/ ).to_a.drop(0).map{ |num, src, expected|
  actual = solve( src )
  okay = actual == expected
  p [ num, (okay ? "ok" : "**NG**" ), src, actual, expected ]
  okay
}.all?.tap{ |x| puts( x ? "okay" : "something wrong" ) }
```
実装戦略は 男装の状態を……いや、そうじゃなくて、弾倉の状態を全探索。

敗因は、ひとえに精進不足。反省。

実行すると、手元で 7秒ほどかかる。遅い。
Glacier Expressヤクの毛刈り(CloudFormation CLI tool) メモ (2018/02/03) (未整理)

- Glacier Expressのヤクの毛刈りとしてCloudFormation 用のCLI toolの作成を行う
- ただ、現状ではTool の作成どころか設計のための情報も足りず、検証段階と言える
- 今日の検証はStackのイベントの追跡
  - いままでの検証で
  - describe_stack_eventsで追跡できそうなことはわかったため、更に検証を進めた
- 結果としては順調に情報の取得ができた
- イベントは時系列(降順)で取得できる
- next_tokenで次の以降のイベントに限って取得できると考えたが、実際には"一定以上イベントが積み重なっている場合のPagerである"ことが判明したあまり使用することは想定されない
  - アウトプットが1MBを超えたときに使用する
  - カウント方法が分からないためなんとも言えないが1MBはレスポンスとしては非常に大きいため当面は対応する必要はないように感じる
- ただ、イベントすべてを取得するため、今回適用分以外も表示されると考えた方が良い
- client_request_tokenをeventの情報の要素に見つける、これなら今回適用分のみ判別することに使えるかもしれない
- 再度試行してみるも、client_request_tokenの値が空白(null or 空文字列)であった
- API Referenceを再度確認すると、どうもclient_request_token はcreate-stackを行う際に指定するようだ。
- 指定してみたところその文字列が表示された。
- さて、ではイベント取得の終了条件について考えてみることにする
- create, update, delete、それぞれを確認してみたところ、どの変更であったとしても最初と最後のイベントは論理IDはstack_nameと同じものとなっている
- そのため論理IDとステータスを見張れば終了がわかると考える
- 試行してみたところ概ね成功
  - ただし、削除の場合は失敗
    - どうも```DELETE_COMPLETE```はstack_nameが論理IDの場合はない模様
    - 終了はスタックが存在するかどうかで判断する必要があるらしい
  - あと実際にはstack_nameだけじゃなくてリソースタイプが```AWS::CloudFormation::Stack```であるかも条件に加えた方がいいと思われる
OSXのterminalで多言語をしゃべらせてみる

# 経緯
妻がフランス語を勉強しろとうるさい

　

ので，なんとかして勉強をしているフリをしてみることにした．
でも，そんなに時間を割いてる場合ではないので，あるものを使う．

# 基本動作の確認

> say -v Alex 'hello' 

こいつをcommand line appsに組み込むだけで，味気ないCUIが**AUI** (Audio User Interface，今作った，あるのかな？)に格上げ．．

> say -v '?'

で可能な声とか，言語の種類がわかるよ．

# 色んな声に色んなことばをしゃべらせたら

下のんをちょっと作ってみました．

``` ruby
require 'open3'

out, err, status = Open3.capture3("say -v '?' | grep US")
#out, err, status = Open3.capture3("say -v '?'")
out.split("\n").each do |line|
  name_lang, sentence = line.split("#")
  next unless m = name_lang.match(/(.+)\s+(\w+_\w+)/)
  name = m[1].sub!(/\s+$/,'')
  lang = m[2]
  printf("%s =%5s=%s\n", name,lang,sentence)
  sentence.gsub!("\'",'')
  system "say -v \'#{name}\' #{sentence}"
end
```
色々記事ありますが、これで大丈夫！OpenCVをwindows環境にgitbushでインストールする方法

## 背景
なにやらいろいろエラーがでたので、スッキリインストールできる方法をまとめました。

具体的に出たエラーは以下のようなものです。

```
opencv_python-3.4.0-cp37-cp37m-win_amd64.whl is not a supported wheel on this platform.
```

```
UnsatisfiableError: The following specifications were found to be in conflict:
  - opencv -> python 2.7*
  - python 3.6*
Use "conda info <package>" to see the dependencies for each package.
```

# OpenCVをwindows環境にインストールする方法

## まずはpythonのバージョンを調べる

`python -V`コマンドで調べることができます。

[![https://gyazo.com/bd9ef6963aa99a5946e3cf8eebff7ed3](https://i.gyazo.com/bd9ef6963aa99a5946e3cf8eebff7ed3.png)](https://gyazo.com/bd9ef6963aa99a5946e3cf8eebff7ed3)

私の場合は、python3.6で、64ビットらしい。

## 自分のpythonにあったOpenCVパッケージをダウンロード

以下のページに行ってください。
https://pypi.python.org/pypi/opencv-python

いろいろな`openCV`があります。
[![https://gyazo.com/7c4043e9fc885729302cc3ae2e87007a](https://i.gyazo.com/7c4043e9fc885729302cc3ae2e87007a.png)](https://gyazo.com/7c4043e9fc885729302cc3ae2e87007a)

`cp`の後ろの数字がpythonのバージョン、`.whl`の直前の数字がビットです。
なので、`python3.6`で`64ビット`場合は、**opencv_python-3.4.0.12-cp36-cp36m-win_amd64.whl (md5)**となります。

(`補足`)
`opencv_python-`の後ろの数字は`openCV`のバージョンなので気にしなくてOK

クリックしてダウンロードしましょう。

## インストール

まずは、ダウンロードしたファイルがあるディレクトリまで移動します。

```
$ cd ダウンロードしたファイルのpath
```

で、以下のコマンドを打ち込みます。

```
$ pip install opencv_python-3.4.0.12-cp36-cp36m-win_amd64.whl
```

`opencv_python-3.4.0.12-cp36-cp36m-win_amd64.whl`の部分はダウンロードしたファイル名にあわせてください。

バージョンやビットが自分のPythonにあっていないファイルだと下のようなエラーがでます。

```
opencv_python-3.4.0-cp37-cp37m-win_amd64.whl is not a supported wheel on this platform.
```
PHPでドメインのSSL証明書の期限日を取得する

### 結構古めの記事しかなかったので自分のコピペ用にメモ

```php
    /*
     * $domainからSSLの期限を取得
     */
    public static function getSSLDueDate($domain)
    {
        // 外部接続用のstream_contextを取得
        $stream_context = stream_context_create([
            'ssl' => [
                'capture_peer_cert'     => true
                // エラー回避用
                , 'verify_peer'         => false
                , 'verify_peer_name'    => false
            ]
        ]);
        // 外部接続
        $resource       = stream_socket_client(
            'ssl://' . $domain . ':443'
            , $err_no, $err_str, 5
            , STREAM_CLIENT_CONNECT, $stream_context
        );
        // ドメインの情報を取得
        $context        = stream_context_get_params($resource);
        $parsed         = openssl_x509_parse(
            $context['options']['ssl']['peer_certificate']
        );
        // SSL期限を返す
        return (strpos($parsed['subject']['CN'], $domain) !== false)
            ? date('Y-m-d', $parsed['validTo_time_t']) : null;
    }
```
Σ（シグマ）の計算をプログラミング（js）で実装する

#更新情報
2018.08.01 @foxwell さんの指摘事項を修正

#数式

```math
\sum_{i=0}^{n}i
```

ここで気にしないといけないのは3点です。

```
i=0, n ,i
```
※シグマは総和を表す記号なので実際計算時には必要ない。

##考え方
上記の式の場合iが0から始まりnまで繰り返す。
繰り返す課程でiを足していった合計が答えになる。

つまりnが確定すれば答えを求めることができるようになります。

#例1

```math
\sum_{i=0}^{5}i
```

##考え方
i=0から始まり5まで(n)繰り返す。

## 数式
```
0 + 1 + 2 + 3 + 4 + 5 = 15
```

## コード
```javascript

let sum = 0; //合計
let n = 5;
for (i = 0; i <= n; i++) {
	sum += i;
}

console.log(sum); //15
```

#例2

```math
\sum_{i=0}^{5}(2i+3)
```

##考え方
i=0から始まり5まで(n)繰り返す。
繰り返す過程で `(2i+3)` を足していく

## 数式
```
(2 * 0 + 3) + (2 * 1 + 3) + (2 * 2 + 3) + (2 * 3 + 3) + (2 * 4 + 3)  + (2 * 5 + 3) = 48
```

## コード
``` javascript
let sum = 0; //合計
let n = 5;
for (i = 0; i <= n; i++) {
	sum += (2 * i + 3);
}

console.log(sum); 
```
pandasで時系列データの作成

# pandasでの時系列データ作成
- pandasで，1日毎，5秒毎などの時系列データを作成するメモ。
- 作成は，``date_range``で行う。

## 開始と期間を指定
- ``periods``で期間を指定できる。
- デフォルトは日単位だが，``freq=``で指定できる。
- 例えば，``s``とすれば，1秒毎だが，``5s``では5秒毎となる。

```python
import pandas as pd

pd.date_range(start='2018-2-1', periods=10)  #開始と期間を指定

pd.date_range(start='2018-2-1', periods=10, freq='D') #開始と期間，単位を指定，1日
pd.date_range(start='2018-2-1', periods=10, freq='H') #開始と期間，単位を指定，1時間
pd.date_range(start='2018-2-1', periods=10, freq='min') #開始と期間，単位を指定，1分
pd.date_range(start='2018-2-1', periods=10, freq='s') #開始と期間，単位を指定，1秒
pd.date_range(start='2018-2-1', periods=10, freq='5s') #開始と期間，単位を指定，5秒

pd.date_range(start='2018-2-1', periods=10, freq='5ms') #開始と期間，単位を指定，5ミリ秒

pd.date_range(start='2018', periods=10, freq='Y') #開始と期間，単位を指定，１年
pd.date_range(start='2018-2', periods=10, freq='M') #開始と期間，単位を指定，１ヵ月
```

## 開始と終了を指定
- ``start``と``end``で開始と終了を指定できる。
- ``freq``で，単位を指定できる。

```python
pd.date_range(start='2018-2-1', end='2018-2-10') #開始と終了を指定

pd.date_range(start='2018-2-1', end='2018-2-2', freq='10s') #開始と終了，単位を指定，10秒
```
ローカル環境に Swagger のスタブサーバを立てる（Mac編）

今や RESTful API スキーマ定義のデファクトスタンダードとなった感のある [Swagger](https://swagger.io/)。ですが、どうにも今いちドキュメントが整備されてないのかわかりづらいのかで、やりたいことがあってもどんなツールがあってどれを選ぶべきか、それらの組み合わせや使い方がわからず困ることが個人的に多いです。

SPA の開発で、`swagger.yaml` からローカル環境にスタブサーバを立ててフロントエンドのテストに使いたかったのですが、これまたやり方がわからず色々調べてようやくできるようになったので、その備忘録を残しておきます。
なおこの記事は Mac ユーザーの方が対象で、すでに Homebrew と Node.js はインストールされているものとします。


## 1. スキーマ定義ファイルを用意
まずは Swagger のデモとして超有名な [Petstore API](http://petstore.swagger.io/) の YAML ファイルを落としてきましょう。

```sh
mkdir swagger-server
cd swagger-server
wget http://petstore.swagger.io/v2/swagger.yaml
```

このままだと、Swagger UI から「Try it out」で試したときに [petstore.swagger.io](petstore.swagger.io) を叩きに行ってしまうので、下記のように内容を書き換えておきます。

```diff:swagger.yaml
- host: "petstore.swagger.io"
+ host: "localhost:8081"
```


## 2. swagger-codegen をインストール

Homebrew でインストールします。すでに Java がインストールしてあるなら、2行目は不要です。

```sh
brew update
brew cask install java
brew install swagger-codegen
```


## 3. 環境を構築

```sh
swagger-codegen generate -i swagger.yaml -l nodejs-server
npm install
```

今回は `nodejs-server` を選びましたが、`swagger-codegen langs` で選択可能な言語・環境リストが表示されるので、別のものがよければそこから選んでください。


## 4. サーバを起動

```sh
node index.js
```

これで http://localhost:8081/docs/ にアクセスすると、Swagger UI 形式で PetStore のドキュメントが表示されます。
試しに `GET /pet/{petId}` のエントリポイントがスタブで動いているか確認のため、http://localhost:8081/v2/pet/1 を叩いてみましょう。以下のような JSON データが返ってくるはずです。

```json:GET　/pet/{petId}
{
  "photoUrls": [
    "photoUrls",
    "photoUrls"
  ],
  "name": "doggie",
  "id": 0,
  "category": {
    "name": "name",
    "id": 6
  },
  "tags": [
    {
      "name": "name",
      "id": 1
    },
    {
      "name": "name",
      "id": 1
    }
  ],
  "status": "available"
}
```


なお Swagger UI の「Try it out」からでも同様のことができるようになっています。
Chainerのextensions.PlotReportをログ表示に変更する

Chainerには`extensions.PlotReport()`という`extensions.LogReport`で出力されるログ結果を可視化してくれる機能がある。しかし、学習がある程度進むとlossもほとんど変化しなくなるので対数グラフで可視化したくなる。最近リリースされたchaineruiを利用するのも手だが、`extensions.PlotReport()`を少し変更するだけで対数グラフで出力できるようになる。

# 動作環境
- Ubuntu 16.04.3 LTS
- Python 3.5.2
- chainer 3.2

# グラフのイメージ

以下で説明する関数を他の`extensions`同様にimportして使用すれば以下のように対数グラフのPlotReportが生成される。

![log_plot.png](https://qiita-image-store.s3.amazonaws.com/0/227399/cb4168d9-3f3b-0b94-05a7-fc46217ae361.png)

# 対数グラフにする

## ソースコードの取得
まずは`extensions.PlotReport()`をchainerの[ソースコード](https://github.com/chainer/chainer/blob/master/chainer/training/extensions/plot_report.py)から持ってくる。

## ソースコードの改変

### 変更前

`def __call__(self, trainer)`の中間程度の以下を

```python3
f = plt.figure()
a = f.add_subplot(111)
a.set_xlabel(self._x_key)
if self._grid:
    a.grid()

for k in keys:
    xy = data[k]
    if len(xy) == 0:
        continue

    xy = numpy.array(xy)
    plt.yscale("log")
    a.plot(xy[:, 0], xy[:, 1], marker=self._marker, label=k)

if a.has_data():
    if self._postprocess is not None:
        self._postprocess(f, a, summary)
```

### 変更後

以下のように修正する（`# 追加`の部分）。最後の`annotate()`はお好みで。

```python3
f = plt.figure()
a = f.add_subplot(111)
a.set_xlabel(self._x_key)
if self._grid:
     a.grid(which='major', color='gray', linestyle=':')# 追加
     a.grid(which='minor', color='gray', linestyle=':')# 追加
    # a.grid()は削除

for k in keys:
    xy = data[k]
    if len(xy) == 0:
        continue

    xy = numpy.array(xy)
    plt.yscale("log")# 追加
    a.plot(xy[:, 0], xy[:, 1], marker=self._marker, label=k)

if a.has_data():
    if self._postprocess is not None:
        self._postprocess(f, a, summary)

    # 追加（validationの最新の値を表示）
    a.annotate('validation\n{0:8.6f}'.format(xy[-1, 1]),
               xy=(xy[-1]), xycoords='data',
               xytext=(-90, 75), textcoords='offset points',
               bbox=dict(boxstyle="round", fc="0.8"),
               arrowprops=dict(arrowstyle="->",
                               connectionstyle="arc,angleA=0,armA=50,rad=10"))

```

できれば標準で実装して欲しい（`PlotReport`で`flg`指定する感じ）けど、~~github初心者なので誰か代わりに報告してください~~

以上。
AWS Lambda から ElastiCache に接続する

## やりたいこと
- AWS Lambda から ElastiCache に接続する
- boto3 は get/set はできないらしいので他の方法を使う

## 必要な設定
- AWS Lambda, ElastiCache を同じVPCにあわせる

## redis (クラスターモードが無効) の場合

### EC2 にて [redis-py](https://github.com/andymccurdy/redis-py) をダウンロード
```bash
$ pip3 install redis -t ./
```
- 生成されるディレクトリを開発環境の　index.py と同じディレクトリにコピーする

### index.py 作成
```python3:index.py
import redis

def handler(event, context):

    r = redis.StrictRedis(host='****.****.0001.apne1.cache.amazonaws.com', port="6379", db=0)

    r.set("key1", "value1")
    print(r.get("key1"))

    return "OK"

```
または

```python3:index.py
import redis

def handler(event, context):

    pool = redis.ConnectionPool(host='****.****.0001.apne1.cache.amazonaws.com', port=6379, db=0)
    r = redis.StrictRedis(connection_pool=pool)

    r.set("key1", "value1")
    print(r.get("key1"))

    return "OK"

```

以上。

## redis (クラスターモードが有効) の場合

### EC2 にて [redis-py-cluster](https://github.com/Grokzen/redis-py-cluster) をダウンロード
```bash
$ pip3 install redis-py-cluster -t ./
```
- redis-py も依存してるので一緒にダウンロードされる
- 生成されるディレクトリを開発環境の　index.py と同じディレクトリにコピーする

### index.py 作成
```python3:index.py
from rediscluster import StrictRedisCluster

def handler(event, context):

    startup_nodes = [{"host": "****.****.clustercfg.apne1.cache.amazonaws.com", "port": "6379"}]
    rc = StrictRedisCluster(startup_nodes=startup_nodes, decode_responses=True, skip_full_coverage_check=True)

    rc.set("key1", "value")
    print(rc.get("key1"))

    return "OK"

```

- クラスターモードが無効の redis には繋がらないのでテスト環境などでは上記実装を切り替える

以上。
Ruby on Rails アプリをAWSにアップするまで

Webアプリ初心者がはじめてrailsアプリをAWSへアップするまでの作成日記
作成中のサイト
https://www.drink-app.club/

- ID:admin
- pass:test0108

https://github.com/katsun0921/drink-app-rb

# 参考サイト
@iwaseasahi さんのページを参照すればだいたいAWSへのアップはいける

- [初心者向け：AWS(EC2)にRailsのWebアプリをデプロイする方法 目次](https://qiita.com/iwaseasahi/items/d5f2ef3eac5e349a8f7d)

- [AWS：無料でSSL証明書を取得する方法](https://qiita.com/iwaseasahi/items/1687426add4124899fe3)

# はまったところ
## ruby2.5.0でやったらDeviseでSyntaxErrorとなった。
バグらしいので修正が必要だった

```
SyntaxError: /.../devise-3.5.5/app/controllers/devise/sessions_controller.rb:5: syntax error, unexpected '{', expecting keyword_end
...ter only: [:create, :destroy] { request.env["devise.skip_tim...
```

ここをコードを修正

```
prepend_before_filter only: [:create, :destroy] { request.env["devise.skip_timeout"] = true }
```

```
prepend_before_filter(only: [:create, :destroy]) { request.env["devise.skip_timeout"] = true }
```

## nginxでrestartが反映されない？

修正ファイルをgit hubからpull したら、反映されずというかDNSが切れた
なぜ？
どうやらnginxだとrestartではなくreloadだとうまくいく
http://abyssluke.hatenablog.com/entry/2015/12/11/203707

```
sudo nginx service reload
```

でうまくいかなかったらreload

```
sudo nginx -s reload
```


## develop環境だと画像が表示されるのに、producton環境だと画像が表示されなくなった？

ローカル環境でのvagrantだと画像は、表示されるのにAWSにアップしたら表示されない？
assets/images 配下に画像をおいていた

```
background: url(/assets/images/hoge.jpg)
```

この書き方だとパスの書き方が間違っていたっぽい

https://qiita.com/wadako111/items/03bc00d914e62243a511

このページを参考にして画像をpublicへ変更したら解決

```
/public/images/
```

に画像をおいて画像パスを変更

```
background: url(/images/images/hoge.jpg)
```

assetsにあるcssは変更したらプリコンパイルを忘れず

```
bundle exec rake assets:precompile RAILS_ENV=production
```
Laravel で migrate 実行時に seed も実行する

[Laravel5でmigration実行時に外部ファイルのsqlを実行する](https://qiita.com/esu_eichi/items/59107aa125c262e8a63f)という記事を書きましたがその派生です。
やることは同じですので、詳細はこちらを参照ください。

#migrateファイル
最後に以下の一行を足します。
`exec('php artisan db:seed --class=SeederFileName');`
###Artisan ファサードを使う
[@nunulk](https://qiita.com/nunulk)さんより指摘頂きました。上よりもこちらのほうがlaravelっぽくていいですね。
`Artisan::call('db:seed', ['--class' => 'SeederFileName']);`

###不整合をより減らすために
[@mpyw](https://qiita.com/mpyw)さんより指摘いただきました
`php artisan migrate:fresh --seed`
seed実行時はこちらのほうが実際に、より不整合を減らしながらデータ投入できます。
ただし、全テーブルdropするので、気をつけてください。


## 注意
これでseederは実行されますが、seederが失敗したときにエラーが出ません。注意してください。
確実に動くことが担保されているseederを使うか、実行後データが入っているかを確認してください。

自分はテーブルとseederのカラム名が違っていてデータが入っていませんでした。

###その他参考
[LaravelのSeeder単体で実行。](https://qiita.com/niiyz/items/c36191fc2c5d48e7e544)

以上です。
Google Driveから共有ファイルをダウンロードする

# 概要
Google Drive上で共有しているファイルを外部からダウンロードする必要がありました。下記にあるような先人の方々の情報を見るとダウンロードするために若干の手続きが必要で、毎回手動で行うには少し面倒と感じたことと、ダウンロード時にファイル名の取得も同時にできればと思い、CLIツールとして作成しました。自分用として作成したため機能は非常にシンプルです。Google Drive上でファイルを共有したときに表示されるURLを与えて、ダウンロードし、ファイルとして保存するだけです。共有ファイルのダウンロードのため、アクセストークンは不要です。1GBのファイルサイズでテストを行いダウンロードすることができましたが、それ以上については未確認です。プロジェクトファイル以外であれば共有されているファイルはダウンロードすることが可能でした。（今のところプロジェクトファイル以外でダウンロードできないファイルは認められません。）アクセストークンを使用すると、共有されたプロジェクトファイルもダウロードすることが可能ですが、このツールではできません。

### 参考
- [Direct download from Google Drive using Google Drive API
](https://stackoverflow.com/questions/20665881/direct-download-from-google-drive-using-google-drive-api)
- [wget/curl large file from google drive
](https://stackoverflow.com/questions/25010369/wget-curl-large-file-from-google-drive)
- [Create Direct Links to your Files on Google Drive](https://www.labnol.org/internet/direct-links-for-google-drive/28356/)
- [GoogleDriveからcurlでダウンロードする](https://qiita.com/netwing/items/f2a595389f39206235e8)
- [curlやwgetで公開済みGoogle Driveデータをダウンロードする](https://qiita.com/namakemono/items/c963e75e0af3f7eed732)

# インストール方法
go getあるいは[こちら](https://github.com/tanaikech/goodls/releases)からダウンロードして使用してください。

~~~
$ go get -u github.com/tanaikech/goodls
~~~

# 使い方
下記のデモンストレーションをご覧ください。基本はURLを与えるだけです。

![demo.gif](https://qiita-image-store.s3.amazonaws.com/0/133383/a43a6a43-d21c-7b3e-b222-c1fbaf369966.gif)

~~~
$ goodls -u [URL of shared file on Google Drive]
~~~

オプションは２つです。

- ``-e`` : ここに拡張子を与えるとGoogleDocsをダウンロードする際にファイル形式を選択することができます。
- ``-f`` : ここにファイル名を与えると、好きなファイル名で保存することができます。

また、``$ cat sample.txt | goodls``や``$ goodls < sample.txt``のような使い方も可能です。sample.txt内は1行ごとに個々のURLを配置してください。この機能はGitHubへ公開した際に要望があり付加しました。

詳細は[GitHub](https://github.com/tanaikech/goodls)をご覧ください。

この情報が何かのお役に立てましたら幸いです。
AIY Voice Kitでハマった事

AIY Voice KitはGoogle HomeやAmazon Alexaのようなボイスアシスタントを自作・カスタマイズできるGoogleのキットで、Raspberry Pi 3を持っていれば比較的安価にボイスアシスタントハードウェアを作ることができる。
年末には日本語対応も発表される等環境も充実しつつあるので年末年始休みの自分のオモチャとして買ってみた。

基本的には
[AIY Voice Kitの公式サイト(英語)](https://aiyprojects.withgoogle.com/voice#assembly-guide-2-assemble-the-hardware)に沿ってハードウェアを作成し、ソフトウェアをセットアップする
[Assistant SDK公式サイト(英語)](https://developers.google.com/assistant/sdk/guides/library/python/embed/install-sample)に沿ってSDKをセットアップする
なのだが日本語化についてはあまり詳しく書かれていないので下記サイトを参考にした。

https://kureuetan.com/web/iot/4677/
https://kureuetan.com/web/raspberrypi/4818/

スイッチサイエンスのサイトも参考になる
http://mag.switch-science.com/2017/12/20/aiy-projects-kit/

なんとかセットアップ終わり、下記コマンド実行するが何度やっても日本語化できず1ヶ月くらい経過…

~~~
(env)$ googlesamples-assistant-hotword --project_id my-dev-project --device_model_id my-model
~~~
最近やっとわかったのだが間違いは一点、project_idに文字通りプロジェクトIDを設定するのだがずっとプロジェクトの名前を指定していた…
Google Cloud Consoleで例えば「Test-Project」という名前でプロジェクトを作成すると、プロジェクトIDは例えば「test-project-123456789012」のように自動生成されるが、この数値付きの方をproject_idに設定しなければいけなかった。

これで成功するとgooglesamples-assistant-hotwordを実行した後に

~~~
Model XXXXX successfully registered
~~~
という文字列が出て、これで初めてAndroidのGoogle Assistantアプリの設定画面にモデル名が出てくるようになる。
出てくるようになってはじめて言語設定が変えられるようになる。

うまくいかなくても英語で動作してしまうしError的なものも出ないので全然気が付かず。

ちなみに一度registered成功するとproject_idオプションは指定しないでdevice_model_idのみの指定で動作するようになる。
Arduino Leonardoがシリアルポートに認識されないときの対処法

Arduino Leonardoを購入し使用しようとしたところ全くパソコンに認識されなかった。ドライバのインストールやリセットボタンやあらゆる対処法を行ってみたが、うんともすんとも言わなかった。しかしリセットボタンを”連打”することで認識された。もしいろいろ試してみて諦めかけていた自分のような人がいるならば最後の足掻きとしてやってみてもいいかもしれない。

追記)
認識はされたが認識された後すぐに切断されるという状況であった。これはプログラムが書き込まれる前に連打して書き込み直前に認識させることでなんとか書き込むことができた。これ以降は普通に認識、書き込みができている。
pySpherepts v0.3 > getFibonacciNodes()移植完了

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
```

### 関連

- [pySpherepts > on GitHub > 球面上の点: Icosahedral Nodesを取るNumpy+Scipy実装](https://qiita.com/7of9/items/3f81de6d1b2337ac6a9e)
- [pySpherepts > getHammersleyNodes()移植完了 > IcosNodesと比べて中心からの距離が小さい?](https://qiita.com/7of9/items/e5666dbb6a699c05f38f)

https://github.com/gradywright/spherepts
のNumpy+Scipy版を実装している。

### 追加機能

v0.3においてFibonacciNodesを取得する関数のNumpy実装を行った。

https://github.com/yasokada/pySpherepts_171126
https://github.com/yasokada/pySpherepts_171126/releases/tag/v0.3

- 追加ファイル
    - [sph2cart_180204.py](https://github.com/yasokada/pySpherepts_171126/blob/master/sph2cart_180204.py)
        - 座標変換(球->直交)
    - [getFibonacciNodes_180204.py](https://github.com/yasokada/pySpherepts_171126/blob/master/getFibonacciNodes_180204.py)

### 備考

現在走らせているIcosahedral Nodesによる計算が終了した時点で試験計算をしてみる予定。

Hammerslay NodesとIcosahedral Nodesの２つで同じNori(Number of orientations)では計算精度に目立つ差はないような気がする。
Fibonacci Nodesはどうか。
arduinoでターミナル その6

#概要

arduinoでターミナルやってみる。
２０字４行のLCDとps/2キーボードをつないで、シリアル端末を作ってみる。
テストの為、forthをarduinoに焼いてみた。

#写真
![for.jpg](https://qiita-image-store.s3.amazonaws.com/0/18104/eb14a484-0aef-a75b-d133-9c92fc80af89.jpeg)

#参考にしたページ
http://middleriver.chagasi.com/electronics/tforth.html

#サンプルプログラム（１から１０の和）

```
: wa 0 11 1 DO I + LOP . ;
```

以上。
個人開発者がサービスリリースに際してやることリスト

# このqiitaの目的

個人開発者がサービスをリリースするにあたって見落としがちなものをまとめるもの。他にもここ忘れているよ！というのがあったら教えてください。

# 法律周り

開発者はプログラミングの勉強はガツガツしたいけど法律は面倒という人も多いでしょう。（僕もです）最低限やっておいたほうがいいよというのをまとめときました。

## 利用規約作成

個人的には開発者は利用規約の役割を覚えておいたほうが自分の身を守れる。利用規約をちゃんと制定することでサイトで何かが起こった際に自分に降りかかる責任を制限する事ができる。例えば掲示板サイトで援交など行われていたり、騙された人が出てときもその利用規約に運営元は投稿内容を管理していないので責任取れないと一言入れるか入れないかで大分変わってくる。

もちろん問題が起こった場合に対応するのは当たり前なんですが自由な投稿サイトを作ると100%投稿をコントロールするのは個人開発者だと余計難しいのでちゃんと責任を制限しておいたほうがいいです。

https://www.fuhyo-bengoshicafe.com/bengoshicafe-260.html

プロバイダ責任制限法は覚えておくと便利。

## プライバシーポリシー作成

逆にユーザーを安心させるために作っておいたほうがいいのがプライバシーポリシー。プライバシーポリシーは基本的には下記について提示するもの。

* 利用目的
* 第三者提供
* 保有個人データに関する事項

なのでリテラシーの高い人がこれがないとこのサイトは情報を勝手に第３者に渡しているかもとかtweetして炎上する可能性がある。

## copyrightをつける

webサービスで作ったロゴやデザインの著作権の持ち主を明示するもの。一番下あたりにcopyright〜〜〜の文言を追加すればok。

# サーバ周り

## バックアップが取れるようにすると安心

なにか問題が起こった時用にバックアップを取っておこう。

## サーバ選び-herokuにするかAWSにするか-

個人的には最初はherokuで始めるのがいいかなと思っている。というのもawsだと料金に上限がつけられないのでdos攻撃などされたときに怖いなあと。なれている人は最初からawsでもいいのかもしれない。

# 絶対にないと困りそうな機能

## 削除、編集機能

投稿する機能は頑張って作るんだけど編集機能や削除機能はおざなりになりがち。ちゃんと作っておこう。

## DBを直接いじれるようにしておこう

編集機能などがうまく動かない、またプロバイダ責任制限法でユーザーから削除を依頼された投稿に対応するためにDBを直接いじれるようにしておくのは大切。

## 問い合わせ機能

tayoriなどで簡単に設置しても良さそう。LINE@を載せておくのもいいと思う。メールでの問い合わせは前時代的な気もする。

https://tayori.com/

# 個人開発者の人情報交換しましょう

個人開発者同士だからこその悩みやノウハウを共有できるといいなあと考えています。近々コミュニティを作りたいと思っているので気になる人はtwitterで気軽にご連絡ください。

https://twitter.com/you8802
NanoPi-NEO2用　kernel build (linaro gccで）

# 概要
buildrootを使えば、kernel,rootfilesystem,bootloaderとシステムに必要なものは一気につくることができます。私の場合、kernel modulesを使わないシステムづくりをしていますので、kernelやbootloaderだけは別にツールチェーンを使ってビルドして、buildrootでつくったrootfilesystemと組み合わせる、なんてこともやります。今回は、linaro gccを使ってkernel buildをした手順をメモしておきます。

## linaro gccの入手
https://releases.linaro.org/components/toolchain/binaries/latest/aarch64-linux-gnu/
から

gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu.tar.xz

をダウンロードして適当なディレクトリに展開しておきます。

## kernelの入手
http://wiki.friendlyarm.com/wiki/index.php/Mainline_U-boot_and_Linux
から
NanoPi-NEO2のdownloadリンクをたどり

linux_4.14.0_20171212.tar.gz

をダウンロードして適当なディレクトリに展開しておきます。

## patchをあてる
kernelのソースは/home/linux/、patchは/home/patch/にあるものとします。

```
$ cd ~/linux
$ cat ../patch/patch-4.14.15 | patch -p1
$ cat ../patch/patch-4.14.15-rt13.patch | patch -p1
```
## 最適化オプションの設定
パパリウスさんに教えてもらったのですが、kernelに対するNanoPi-NEO2用の最適化オプションの設定はkernelソースのmakefileを直接編集することにより行います。

/linux/Makefileの編集内容

```
KBUILD_CFLAGS	+= -O2 $(call cc-disable-warning,maybe-uninitialized,)
else
KBUILD_CFLAGS   += -O3 -pipe -ftree-vectorize <---追加

endif
```

/linux/arch/arm64/Makefileの編集内容

```
KBUILD_CFLAGS	+= $(call cc-option,-mabi=lp64)
KBUILD_AFLAGS	+= $(call cc-option,-mabi=lp64)
KBUILD_CFLAGS += -march=armv8-a+fp+simd <---追加
KBUILD_CFLAGS += -mtune=cortex-a53　　　 <---追加
KBUILD_CFLAGS += -mcpu=cortex-a53+fp+simd　<---追加
```

## makeする
linaro gccは/home/gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu/にあるものとします。

```
$ make sunxi_arm64_defconfig ARCH=arm64 CROSS_COMPILE=/home/gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
$ make menuconfig ARCH=arm64 CROSS_COMPILE=/home/gcc-linaro-7.2.1-2017.11-x86_64_aarch-linux-gnu/bin/aarch64-linux-gnu-
$ make ARCH=arm64 CROSS_COMPILE=/home/gcc-linaro-7.2.1-2017.11-x86_64_aarch-linux-gnu/bin/aarch64-linux-gnu- Image dtbs -j4
```
数値計算 > 偶数から奇数へ > Ceilを使わない方法でPython実装してみる (正の偶数にのみ対応) | 元の実装の意図: 引数が偶数でも奇数でも対応

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
```

### 擬似コード

```
Num = CEIL((Num - 1) / 2)
XS = [0] * (2 * Num + 1)
```

偶数のNumを元に奇数のサイズのXSを定義したいようだ。
CEIL()を使う理由が分からなかった。

コードの下の方で以下があった。

```
for i = -Num to Num   # Numまでを含めたループ
    ...
```

このループのために冒頭のNumをCEIL()で取得しているようだ。

### 別案

Ceilを使わない方法をPythonで書いてみる。

Nloopの計算は二通り考えた。Pythonであれば後者が簡潔に記載できる。
(後者: [floor division](https://qiita.com/7of9/items/8c3a11f0bced8d8d0581))

ceil()がある言語ではceil()を使う方がいいかもしれない。ただし、最初にceil()を使うのではなく、ループ変数計算用にceil()を使う方が読みすいと思う。

```test_odd2even_loop_180204.py

# tested on Python 3.5.2

Neven = 8

Nodd = Neven - 1
# 1. for non-Pythonic language
Nloop = (int)((Nodd - 1) / 2) + 1
# 2. for Python
Nloop = Nodd // 2 + 1

for idx in range(-Nloop, Nloop+1):  # +1: range() does not include end point
    print(idx)

```

```txt:run
$ python3 test_odd2even_loop_180204.py 
-4
-3
-2
-1
0
1
2
3
4
```

こういうループはSpherical Harmonicsのorder, degreeの計算でよく目にする。

### code修正

最初にCEIL()で処理しているので、下記が正解だろうか。

```test_odd2even_loop_180204.py

# tested on Python 3.5.2

Neven = 8

Nodd = Neven + 1
# 1. for non-Pythonic language
Nloop = (int)((Nodd - 1) / 2)
# 2. for Python
Nloop = Nodd // 2

for idx in range(-Nloop, Nloop+1):  # +1: range() does not include end point
    print(idx)

```

元の擬似コード実装では、最初にCEIL()を使うことで引数が奇数でも偶数でも対応する、という意図がある気がしてきた。
Juliaで二次元版合意形成と適用例

# 内容
- グラフラプラシアン$L$を利用すると、状態変数が収束する形の合意形成が可能
    - 参考: <a href='https://qiita.com/taki__taki__/items/ec03d316dccf2b7f377d' target='_blank'>Juliaでグラフラプラシアンを用いた合意形成を計算する - Qiita</a>
- 1次元だと1つの値に合意形成された
- 2次元に拡張すると、$x$ 軸方向と $y$ 軸方向で合意形成され、$N$個のペア $(x_i, y_i)$ が合意形成されるはず
- 実際に確認してみる

# 下準備
- $N$個の状態変数 $(x_i, y_i)$ を乱数で生成するスクリプトを用意
    - CircleSimというモジュールにしておいた（機能が貧弱だけど）
    - ファイル置き場: https://github.com/cocomoff/TIL/blob/master/julia/sim/circlesim.jl

- 実装している機能
    - 以下の操作を$N$点分繰り返して、乱数位置を作成
        - $\theta$を$[0, 2\pi]$の範囲から選択
            - 実装上は$\Delta\theta$を受け取って、$0:\Delta\theta:2\pi$ からサンプリングする
        - 位置がだいたい円上になるように、$[R_{min}, R_{max}]$の範囲から選択
            - 実装上は$\theta$と同じく$\Delta r$の刻み幅でサンプリングする
    - 2点 $(i, j)$ がしきい値$T$以下の位置にある場合、無向グラフの辺を置く

- 使ってみるとこういう感じになる

```julia
using CircleSim
N = 50
T = 3.0
points = generate(N)
edges = getedges(points, T=T)
circleplotedges(points, edges)
```

- 生成される図の例

![sim0.png](https://qiita-image-store.s3.amazonaws.com/0/7181/0e160504-c9ea-7a4c-2d6e-2e933f072c92.png)

- 作図機能は本当はアニメーションGIFが描けるようにしたかったけど、PyPlotでやるのが面倒な気がした（未調査）ので、アニメーションGIFの実装は諦めた


# X軸、Y軸に関した合意形成結果
- 事前に試した例題と同様に、合意形成される

- X軸

![sim_loc_x のコピー.png](https://qiita-image-store.s3.amazonaws.com/0/7181/fd76f058-c806-1210-d256-6d5541e09d47.png)

- Y軸

![sim_loc_ｙ のコピー.png](https://qiita-image-store.s3.amazonaws.com/0/7181/691ef28e-0c68-5d8b-7d30-24b3e595aa99.png)

# 二次元プロット
- 最初のうち30ステップ程度から適当に選んできた収束様子は次のようになる
- ここはアニメーションが作りたかった。。。 :cry:

- 最初の5ステップ

![sim1.png](https://qiita-image-store.s3.amazonaws.com/0/7181/164d218b-3e2e-15d0-5358-da6ac66bc59a.png) ![sim2.png](https://qiita-image-store.s3.amazonaws.com/0/7181/a59efc2f-41c7-3377-140b-1aa186228ddb.png) ![sim3.png](https://qiita-image-store.s3.amazonaws.com/0/7181/b027b45a-b582-1501-8fdb-3e59d20591f1.png) ![sim4.png](https://qiita-image-store.s3.amazonaws.com/0/7181/590c30e4-d1d0-8500-4911-b8728b8128de.png) ![sim5.png](https://qiita-image-store.s3.amazonaws.com/0/7181/a7991df5-669f-9ffb-aff2-052b63413c71.png)

- ３０ステップ後（だいたい集まってきている）

![sim30.png](https://qiita-image-store.s3.amazonaws.com/0/7181/5640cf7b-6cbf-4fbc-cf30-42d12ef817ff.png)

# コード

```julia
using CircleSim
N = 50
T = 3.0
points = generate(N)
edges = getedges(points, T=T)

# make (N, 2) matrix
xy = zeros(N, 2)
for i in 1:N
    p = points[i]
    xy[i, 1] = p.x
    xy[i, 2] = p.y
end

# adjacency matrix, graph laplacian
A = zeros(N, N)
for i = 1:N, j in edges[i]
    A[i, j] = 1
    A[j, i] = 1
end
D = diagm(squeeze(sum(A, 2), 2))
Δ = maximum(D)
L = D - A

# simulation for both X (xy[:, 1]) and Y (xy[:, 2])
Δt = 0.05
tf = 10
xx = []
yy = []
for t in 0:Δt:tf
    push!(xx, xy[:, 1])
    push!(yy, xy[:, 2])
    Δx = -L*xy[:, 1]
    Δy = -L*xy[:, 2]
    xy[:, 1] += Δx * Δt
    xy[:, 2] += Δy * Δt
end
```
buildrootでつくるNanoPi-NEO2用upnpレンダラー　(build option)

# 概要
buildrootでupnpレンダラーをつくるときに、やったほうがいいことの一つに

**「NanoPi-NEO2に最適化したビルド」**

があります。
symphonic-mpdのパパリウスさんもおっしゃられてますが、最適化ビルドをしたほうが音がよくなるというのは実際に体験してみて私も感じています。
私がやっていることについて書いておきます。

## 最適化オプション
gcc 7.Xのドキュメントとにらめっこしながら実際に設定している（ビルドが通る）NanoPi-NEO2用のビルドオプションは以下の通りです。詳しい人からみればこれいらないんじゃない？みたいな部分もあると思いますが。

```
CFLAGS="-O3 -pipe -ftree-vectorize -march=armv8-a+fp+simd -mtune=cortex-a53 -mcpu=cortex-a53+fp+simd -mabi=lp64"
CXXFLAGS="${CFLAGS}"
```


## 最適化ビルドする対象
音楽再生に関係があると思われるもので最適化オプションでビルドしているものは以下のとおりです。

```
alsa-lib alsa-utils audiofile flac libcurl libmad mpd libupnp libupnpp upmpdcli
```

## buildrootでの最適化ビルドオプションの記載例
buildrootでは各パッケージのビルド手順は/buildroot/package/の中にあります。例えばalsa-libなら、/buildroot/package/alsa-lib/alsa-lib.mkです。このファイルを以下のように編集しています。

```
ALSA_LIB_CONF_OPTS = --disable-ipv6 \
CFLAGS="-O3 -pipe -ftree-vectorize -march=armv8-a+fp+simd -mtune=cortex-a53 \
-mcpu=cortex-a53+fp+simd -mabi=lp64" \
CXXFLAGS="${CFLAGS}"
```
xmonadを使ってみる

# 参考にしたもの
http://blog.blueblack.net/item_422.html


# xmonadって何？
タイル型のウィンドウマネージャー
私はFedora26で動かしてます。


# インストール

```
sudo dnf install -y xmonad
```


# 設定ファイルを作成

```
cat <<EOF > ~/.xmonad/xmonad.hs

# http://code.haskell.org/xmonad/man/xmonad.hs
# とかも参考にして書き込む

EOF
```

# キーマップ　＆　入力

## キーボード配列を日本語にする

```
setxkbmap -layout jp
```

## ibus-mozcのデーモンを起動する

```
ibus-daemon --xim &
```

## ibusの設定

```
ibus-setup
```

## CapslockをCtrlにする

```
setxkbmap -option ctrl:nocaps
```

# 画面の輝度

## インストール

```
sudo dnf install -y xbacklight
```

```
sudo cat <<EOF > /etc/X11/xorg.conf
Section "Device"
Identifier  "Card0"
Driver      "intel"
Option      "Backlight"  "NAME OF THE FOLDER"
EndSection
EOF
```


```
mod-shift-return  : ターミナルを起動
mod-p             : dmenuを起動(キーワードランチャ)
mod-shift-p       : gmrunを起動(キーワードランチャ)
mod-shift-c       : フォーカスウィンドウを閉じる
mod-space         : レイアウトアルゴリズムを変更する(縦分割→横分割→フル)
mod-shift-space   : レイアウトアルゴリズムをデフォルトに戻す
mod-n             : フォーカスウィンドウを正しいサイズに戻す
mod-tab/shift-tab : ウィンドウフォーカスを移動
mod-j/k           : ウィンドウフォーカスを移動
mod-m             : マスターウィンドウへフォーカスを移動
mod-return        : フォーカスウィンドウをマスターパネルとスワップ
mod-shift-j/k     : フォーカスウィンドウを隣りのウィンドウとスワップ
mod-h/l           : マスターパネルのサイズ比率を狭める/広げる
mod-t             : フローティングウィンドウをタイルに戻す
mod-,/.           : マスターエリアのウィンドウ数を増やす/減らす
mod-b             : ステータスバーのギャップをトグルする
mod-shift-q       : Xmonadを終了
mod-q             : Xmonadを再起動
mod-1~9           : ワークスペースを切り替え
mod-shift-1~9     : フォーカスウィンドウを指定ワークスペースへ移動
mod-w/e/r         : スクリーンを切り替え(1, 2, 3)
mod-shift-w/e/r   : フォーカスウィンドウを指定スクリーンへ移動(1, 2, 3)
mod-button1       : ウィンドウのフローティングと移動
mod-button2       : フローティングウィンドウを最前面に移動
mod-button3       : フローティングウィンドウのリサイズ
```set
MATLAB > B(:) > flatten in a row major order | reshape()

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
```

### code

```matlab
>> A = 1:10

A =

     1     2     3     4     5     6     7     8     9    10

>> B = reshape(A, [5,2])

B =

     1     6
     2     7
     3     8
     4     9
     5    10

>> C = B(:)

C =

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
```

### B(:)

`B(:)`の意味は何か?

https://jp.mathworks.com/matlabcentral/answers/54172-how-to-flatten-a-matrix-in-row-major-order

行方向へのflattenの意味のようだ。

リンク先のコード掲示の下にコメントで注意書きはある。


### 関連

- [Reshape array](https://jp.mathworks.com/help/matlab/ref/reshape.html?lang=en)
Jupyter notebook で DataFrame 等を比べて簡易に単体テスト書いて仕様を保証したい

概要
=====

Jupyter notebook で DataFrame 等を比べて簡易に単体テスト書いて仕様を保証したいという、ニッチなニーズに答えてみたところ、悪くない利用感になったので公開してみます。

単体テストのコアコード
=================

```py
import pandas as pd
def _assert(actual, expected, message=''):
    if isinstance(actual, (pd.DataFrame, pd.Series)):
        actual = json.dumps(actual.T.to_dict(), ensure_ascii=False)
    if type(expected) != str:
        expected = json.dumps(expected, ensure_ascii=False)
    if actual != expected:
        raise Exception(f"Assert Error!! {message}\nactual:   {actual}\nexpected: {expected}\n")
```

これだけ。

使い方
=======

```py
actual = your_method()
_assert(actual, {"1": {"A": 1.0}, "2": {"A": 2.0}, "3": {"A": 3.0}}, 'DFが一致してるか')

print('test ok')
```

- このように期待するDF(DataFrame)の中身をdictで指定できます。
- また、dictはレコードの順に書く方が直感的なので（通常to_doctすると列方向になりますが）レコード方向で比べるようにしてあります。
- これで問題なければ `test ok` が表示され、NGならエラーになります。
- エラーは json 化された文字列が出力されます。

```:エラーの例
Exception: Assert Error!! DFが一致してるか
actual:   {"1":{"A":1.0},"2":{"A":1.0},"3":{"A":3.0}}
expected: {"1":{"A":1.0},"2":{"A":2.0},"3":{"A":3.0}}
```

もちろん、スタックとレースも出ます。

- 引数 actual / expected にはシリーズや文字列でも使えます。
arduinoでターミナル その5

#概要

arduinoでターミナルやってみる。
２０字４行のLCDとps/2キーボードをつないで、シリアル端末を作ってみる。
テストの為、basicをarduinoに焼いてみた。

#写真
![base.jpg](https://qiita-image-store.s3.amazonaws.com/0/18104/bed1753b-987f-ef05-d638-ee9922671c50.jpeg)


#参考にしたページ

https://github.com/rutles/ttbasic_arduino

#サンプルプログラム（１から１０の和）

```
10 a=1
20 b=0
30 b=b+a
40 a=a+1
50 if a < 11 goto 30
60 print "souwa="
70 print b
```

以上。
Win+Vagrant環境でマウントしたJS(CSS)ファイルが正常に反映されない時の対処法

## Win + Vagrant + CentOS + Apache の仮想環境で、HostOS側のファイル編集がなぜかうまく反映されずにハマったのでメモ。


### httpd.conf の EnableSendfile 設定を off にしてあげるとなおった。


```
# sudo vi /etc/httpd/conf/httpd.conf

EnableSendfile on
↓
EnableSendfile off

$ sudo systemctl restart httpd

```