OmniAICreator/Qiita-1.07M huggingface dataset:
agora.io SignalingSDKで複数のChannelにログインする方法

#概要
agora.io SignalingSDK(iOS/Android)のver1.4.0から複数のインスタンス生成が可能になりました。
これにより、複数のChannelにログインする事が可能です。

**※Signaling SDK は、サポート終了しております。後継サービスとして、[RTM (Real-time Messaging) SDK] (https://docs.agora.io/en/Real-time-Messaging/product_rtm?platform=All%20Platforms) が提供されております。RTM SDK は、Signaling SDK に比べ、 安定性や信頼性が向上しております。**

#サンプルコード
インスタンス生成部分について抜粋して記載します。

##iOS
```swift
if isFirstInstance == true {
  agoraSignalKit = AgoraAPI.getInstanceWithoutMedia(KeyCenter.AppId)
} else {
  agoraSignalKitSub = AgoraAPI.createSigInstance(KeyCenter.AppId)
}
```

##Android
```java
signal = AgoraAPIOnlySignal.getInstance(application, agoraAppId)
signal2 = AgoraAPIOnlySignal.createInstance(application, agoraAppId)
```


#最後に
[**agora.ioに関するお問い合わせはこちらから**](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=e598a9ed4d451ee51b93)
[<img width="912" alt="スクリーンショット 0001-08-15 13.41.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/5d815376-9b89-08fa-9434-6fa7e8e67bcf.png">](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=e598a9ed4d451ee51b93)
仮想でActive Directory練習環境を構築してみたので　メモ



新しいserver2019も出たことなので、せっかくなのでいままで食わず嫌いだったインフラをちょっと勉強してみる

こういうのは現実でテスト環境作るのが、物理的に大変なので仮想でやってみることにした

すると大変,
主は仮想でのネット構造などなにもわからないので、IP面での連携ですごく苦労したので、ここに記しときます。

まず、Windows Serverの立ち位置を把握することに苦労しました。

Windows ServerはDNSになり、IPv4の設定のところの優先DNSにWindows ServerのIPを書くとうまくいくみたい

あと、仮想ネットに関してはブリッジにしないとフォレストドメインにぶら下げるPCが繋がらないみたい

あとは以下省略

![natipng.png](https://qiita-image-store.s3.amazonaws.com/0/310991/abab3935-d96b-b3f8-8ba2-35baef8c189c.png)

Windows server 2019 管理するPC
Windows 10pro       管理されるPC
【GitHub】Pull Request をする際に作業毎にRequestを出したい

##やりたいこと
Pull Requestをする時に、作業ごとにRequestを出したい。
例）
ログインページと新規登録ページを作り、別々にPull Requestを出したい。。
だけどRequestを二つ出してしまうと、なぜかRequestが一つのところにまとまってしまう。

##原因
Branchを一つにしてしまっているから。


##解決方法
Branchを作業毎に分ける。

##やり方
###①`git branch`で新たにbranchを作成する。

```terminal
$ git branch login_button
```

###②`git checkout ブランチ名`で作成したブランチに移動

```terminal
$ git checkout login_button
```

※上記は`git checkout -b login_button`とすることでブランチを作成しその後移動させることができる。


###③`git status`で変えたいファイルを確認する。

```terminal
        modified:   app/views/sessions/new.html.erb
        modified:   app/views/users/new.html.erb
```

###④`git add ファイル名`でstagingするファイルを指定
まずはログインページ（sessions/new)を指定する。

```terminal
$ git add app/views/sessions/new.html.erb
```

`git status`で現状を確認すると一つのファイルだけstagingされている

```terminal
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   app/views/sessions/new.html.erb

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   app/views/users/new.html.erb
```

###⑤コミット名を決めてgitにコミット

```terminal
$ git commit -m 'modified login button'
```

###⑥`git push origin login_button`としてリモートリポジトリにpush

```terminal
$ git push origin login_button
```

この時`git push origin login_button:自分のつけたい名前`とすることでリモートリポジトリにpushすると、リモートリポジトリには`自分のつけたい名前`が反映される。

####この後GitHub上でPull Requestをすると下のようになる。

<img width="1046" alt="Screen Shot 2019-01-23 at 16.48.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/312088/67405f9e-ba38-181a-5df4-7cd2e4d7de87.png">

###⑦branchの名前を`signin_button`として①~⑥を繰り返す。

###⑧Pull Requestが作業毎に出来る

<img width="1024" alt="Screen Shot 2019-01-23 at 16.57.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/312088/23316c6a-554b-3b10-0719-450159cc1b04.png">

##結論
Pull Requestを出すときはBranchを分けることによって、作業毎にRequestを出すことができる。
【Golang】ポインタの基礎をアドレス演算子を使っみ触ってみた

ここ数日、いろいろと挙動を確認しながらGolangのポインタを勉強しています。

ブログや本などを色々読み漁っていましたが、アドレス演算子を触っいる時、少ししっくりきた部分があったので備忘録として残しておこうと思います。<br>

基礎中の基礎で、かなりシンプルな内容です。

## アドレス演算子

アドレス演算子とは、変数の格納アドレスを確認することができる演算子です。<br>


```golang
var i int
i = 5

fmt.Println(i)  // => 5

fmt.Println(&i) // => 0xc000014078
```
`&i`で出力すると変数 i の格納アドレスのみが出力されました。
&を付けると格納アドレスだけ表示されます。

次はpに代入

```golang
var i int
i = 5
p := &i

fmt.Println(p)  // => 0xc000014078
```

当たり前のようですが、　変数`p`も格納アドレスだけ寄越してきました。
これは格納アドレスを`p`に渡しているから、こう表現されるのでしょう。

それぞれの変数の中身(型、アドレス)がどうなっているのか確認してみました

```golang
var i int
i = 5
p := &i

fmt.Printf("type=%T, address=%p, int=%d\n", i, i)
// => type=int, address=%!p(int=5)

fmt.Printf("type=%T, address=%p, int=%d\n", &i, &i)
// => type=*int, address=0xc000098000

fmt.Printf("type=%T, address=%p, int=%d\n", p, p)
// => type=*int, address=0xc000098000
```

アドレス演算子`&`を付けると型も特殊な\*int型になります。
型が違うのでint型と\*int型は計算はできません。

```golang
var i int
i = 5
p := &i

q := p + 5
// invalid operation: p + 5 (mismatched types *int and int)

```



肝心のpの値を利用したいときには変数に`*`を付けます

```golang
var i int
i = 5
p := &i

fmt.Println(*p)  // => 5
```

処理を行うときにも忘れずに。

```golang
var i int
i = 5
p := &i

q := *p + 5

fmt.Println(q) // => 10
```


ポインタはGo言語で重要な概念で、構造体を利用する際に必ず利用します。
構造体は他言語でいうクラスみたいなものですが、値型と参照型と言う点で性質が違います。
BigDecimalの罠    〜doubleから変換はvalueOf使え〜

腹立ったので記事化。

BigDecimalという、不動小数点を扱うときに精密に計算する際に利用することを推奨されるクラスがあります。
んで、これのインスタンス化のときにDouble使うとズレることがある、という話。

## 背景

一種の会計ソフトのレシート出力を作っていて、
`111.11` 円を８つ、つまり `888.88` を出力しようとすると
なぜか `888.87...` になってしまって怒り狂っていた

## 原因

BigDecimalのインスタンス化のときにdoubleを利用すると、
その時点で正確な値にはならない場合があるようです

追記：
エライ人たちにご指摘いただき、潜ってみたら書いてた ^q^
`0.1` とかをdoubleで渡すと、正確な不動小数点表現（64bit表現）に変換されてしまい　`0.100...551..`とかになるらしい

```
    /**
     * Constructs a new {@code BigDecimal} instance from the 64bit double
     * {@code val}. The constructed big decimal is equivalent to the given
     * double. For example, {@code new BigDecimal(0.1)} is equal to {@code
     * 0.1000000000000000055511151231257827021181583404541015625}. This happens
     * as {@code 0.1} cannot be represented exactly in binary.
     * <p>
     * To generate a big decimal instance which is equivalent to {@code 0.1} use
     * the {@code BigDecimal(String)} constructor.
     *
     * @param val
     *            double value to be converted to a {@code BigDecimal} instance.
     * @throws NumberFormatException
     *             if {@code val} is infinity or not a number.
     */
    public BigDecimal(double val) {
```

## 例

```Kotlin
import java.math.BigDecimal

fun main(args: Array<String>) {
    val seed = 888.88
    val fromDouble = BigDecimal(seed)
    val fromValueOf = BigDecimal.valueOf(seed)
    println("from double  -> $fromDouble")
    println("from valueOf -> $fromValueOf")
}
```

```
from double  -> 888.8799999999999954525264911353588104248046875
from valueOf -> 888.88
```

## 解決策

~~Stringにしてインスタンス化のときに渡してやると、ズレずにできました。よかったよかった。~~
`BigDecimal.valueOf(double)` とすると正確にdoubleから変換できるようです。
（@blhsrwznrghfzpr さん、ご指摘ありがとうございました！）

みんなちゃんとドキュメント読もう (　^ω^)
【一年生の頃の私へつづる言葉⑤】teraterm使用時は、自動ログインマクロだけでも作っておいて。

・今となっては、当然のごとく使用していることを、ただ手紙としてしたためるだけの記事の第五弾。
・今回もひたすら「過去との対話」という、人生謳歌芸に酔いしれよう。
・このような奇行によって大量の手紙が届く過去の私よ、「人生とはそのようなものだ。」
・よし。今回も入社後、知っておけばよかったことを書こう。

## teratermマクロについて
### ＜当時＞
- 「概要」・・・入社後に実際に触りだすまで、teratermの名前と概要しか知らなかった。操作方法は全く分からず状態。   
→それまでサーバーいじりの経験が皆無だったため、マクロの存在自体の認知は遅かった。 
- 「マクロ作成」・・・存在自体しらなかったため、作成方法も当然意味不明状態。  
→teraterm自体の概要や操作方法の学習や習得に力を注いでしまう。
  
→操作方法の習得に加え、本番いじりの緊張も相まって、あいにくの容量満杯状態。
→にもかかわらず、極度の負担を招く接続をマクロで行わず、手作業で行うという「自己障害」。

### ＜現在＞
概要や作成方法を学び、自動ログインマクロをネット写経にて作成。
→簡単操作・負担軽減・不備一掃を達成できた。

- ***概要***  
    - teratermのマクロ言語を用いた実行プログラム。  
    →ログインやサーバー操作の自動化が可能になる。

- ***簡単な作成手順***
    - 1. テキストファイルを作成。（メモ帳でもなんでもいい。）
    - 2. そこにマクロ処理を記述。
    - 3. 名前をつけて保存で、拡張子を「.ttl」にする。
    - 4. 保存後、右クリックで、「プログラムから開く」「既定のプログラム選択」で「ttpmacro.exe」と紐づける。  
    - 5. 接続確認後、次回以降ダブルクリックのみで接続できるようになれば、完了。

- ***簡単なサンプルバッチ***
- ①teraterm自動ログイン（パスワード認証）
    - そのままメモ帳に書いてOK。
    - 下記サーバー情報
        - IPアドレス : 「111.222.333.444」
        - ポート番号 : 「22」
        - ユーザー名 : 「test」
        - パスワード : 「test1234」
        - ※SSHバージョン : 「2」
    - 下記のコードをコピー。

```
; 接続情報
HOSTADDR = '111.222.333.444
USERNAME = 'test'
PASSWORD = 'test1234'

; 接続処理
COMMAND = HOSTADDR
strconcat COMMAND ':22 /ssh /2 /auth=password /user='
strconcat COMMAND USERNAME
strconcat COMMAND ' /passwd='
strconcat COMMAND PASSWORD
connect COMMAND
end
```

- ②teraterm自動ログイン（公開鍵認証）  
※公開鍵の保存は、「pemファイルを使用」
    - そのままメモ帳に書いてOK。
    - 下記サーバー情報
        - ※IPアドレス : 「111.222.333.444」
        - ポート番号 : 「22」
        - ユーザー名 : 「test」
        - パスワード : 「test1234」
        - 鍵補完ファイル : 「C:\test\aaaaaa.pem」
        - SSHバージョン : 「2」
    - 下記のコードをコピー。

```
; 接続情報
HOSTADDR = '111.222.333.444'
USERNAME = 'test'
PASSWORD = 'test1234'
KEY_FILE = 'C:\test\aaaaaa.pem'

; 接続処理
COMMAND = HOSTADDR
strconcat COMMAND ':22 /ssh /2 /auth=publickey /user='
strconcat COMMAND USERNAME
strconcat COMMAND ' /passwd='
strconcat COMMAND PASSWORD
strconcat COMMAND ' /keyfile='
strconcat COMMAND KEY_FILE
connect COMMAND
end
```
        
### ＜過去の私へ送る言葉＞
- <font color = "tomato">本番接接続の負担は、尋常ではないかで、こういうところからから軽減していこう。</font>
- <font color = "tomato">間違っても、しっかりと落ち着いて焦らないでね。</font>

## まとめ
- 今回は、teratermマクロということで、圧迫・負担・安堵等が、急速循環していたころを思い出しながら、記事を書く。
- この「Orangeごっこ」は、もしも論の連続ということもあるので、早期の「並行世界への移動」実現を切に願う。
- 整理してみると、「私のサーバーの知識が弱すぎる」ということもあるので、時を見計らって学んでいこう。
Google Tech Dev Guideの問題を解いてみた

#はじめに
研修でGoogle Tech Dev Guideの問題を解いていたので、
自分なりに考えたことをメモとして残します。
[今回解いた問題](https://techdevguide.withgoogle.com/paths/foundational/subnumbers-problem-string-return-sum/#!)

#問題
問題文を抜粋すると
>Given a string, return the sum of the numbers appearing in the string, ignoring all other characters. A number is a series of 1 or more digit chars in a row. (Note: Character.isDigit(char) tests if a char is one of the chars '0', '1', .. '9'. Integer.parseInt(string) converts a string to an int.)

とのこと。
要約すると、「受け取った文字列から数値のみを取り出しを加算する」といった内容です。
文章のみだと分かりづらいと思うのですが、
下記のような出力になればいいみたいです（sumNumbersメソッドを実装する）
>sumNumbers("abc123xyz") → 123
sumNumbers("aa11b33") → 44
sumNumbers("7 11") → 18

↑を見ていただくと分かるかと思うのですが、
数値の間に文字列または空白があった場合は、それぞれの数値を加算する必要があります。

#さっそく解いてみた
まずは、文字列中に含まれるかもしれない要素を洗い出しました。

 + 文字列
 + 数値
 + 空白

上記を踏まえ、今回は下記のようなアプローチをとりました。
　1.数値以外の要素を全て空白に変換
　2.空白区切りで配列に格納
　3.配列の中で空の要素以外を全て加算

最終的に下記のようなコードになりました。

```java:sample.java
class Test1{
  public static void main(String args[]){
    // 動作確認用
    System.out.println(sumNumbers("abc123xyz"));
    System.out.println(sumNumbers("aa11b33"));
    System.out.println(sumNumbers("7 11"));
  }
  public static int sumNumbers(String str) {
    // 1.数字以外をすべて半角スペースに変換
    String buf = str.replaceAll("[^0-9]", " ");
    // 2.空白区切りで配列に格納
    String list[] = buf.split(" ");
    int sum = 0;

    // 3.配列の中で空の要素以外を全て加算
    for(int i = 0; i < list.length; i++){
      if (!(list[i].isEmpty())){
        sum = sum + Integer.parseInt(list[i]);
      }
    }
    return sum;
  }
}

```
「もっとこうした方がいい！」等ありましたら、ぜひご指摘をいただければと思います！

#おまけ
普段はRubyで書いているので、Rubyでも解いてみました。

```ruby:sample.rb
def sumNumbers(str)
  str.gsub(/[^0-9]/," ")
     .split(" ")
     .compact
     .reject(&:empty?)
     .sum{|v| v.to_i}
end
#動作確認用
puts sumNumbers("abc123xyz")
puts sumNumbers("aa11b33")
puts sumNumbers("7 11")

```
rubyだとメソッドチェーンを使って書けるので楽しいですよね！
Bitnamiに複数バージョンのredmineにアクセス

初心者のメモ

例：
C:\Bitnami下に
redmine-3.3.1-0  Port:44
redmine-4.0.1-0  Port:88
がインストールされた場合、各バージョンのredmineにアクセス方法

localhost:44/redmine
localhost:88/redmine
vue.js axios laravel で ajax したら なんとぱっくり Error: Network Error at createError

まじでおまんちょですよ。
外部ドメイン、まぁ通称クロスドメインAJAXしようと思ったら以下のエラーが。

```

Error: Network Error
    at createError (app.js?id=fa47fccde137f8c8325f:2218)
    at XMLHttpRequest.handleError (app.js?id=fa47fccde137f8c8325f:1761)

```

おいおい、json取得できーへんのかい！
ということで 1時間大ハマリ。

結論から言えば,


```/js/bootstrap.js35行目らへん

if (token) {
    // window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
    window.axios.defaults.headers.common = {
        'Accept':'application/json',
        'Content-Type':'application/json'
    };
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}




```


というふうに書き直せば、取得できるようになる。
BUSCO用 tblastn の不具合　ソースインストールで解決

# busco
最近、次世代シーケンスでのゲノムデータから遺伝子の予測には必須になりつつあるbuscoですが、使えるようになるための設定が結構難しいのです。
# tblastn
他もいろいろつまったのですが、一番手間取ったのがblastでした。
最初　Anaconda でblastをインストールして、tblastnをaugustusが呼び出すようにしていたのですが、
1　CPU コアしか使えませんとのエラーが出て
Googleで検索したら、1cpu設定で実行すれば解決との記事が
それで実行したところ1ヶ月以上かかってもbuscoが終わらない。
#　結局blastをソースからコンパイル
それで、NCBIからblast　2.81のソースをもらってコンパイルしたところ、順調にマルチコアで動くようになりました。
ただし、blastのコンパイルには1時間以上かかって大変でした。
# 結論
ツールでエラーが出たときには、ソースからコンパイルしましょう。
TextViewの文字制限を簡易的に実装する

#はじめに
・textViewに文字を入力する際に文字制限をかけ、文字を超過した場合にkeybordが閉じるという挙動になります。
・超過後、再フォーカスした時にkeybordが閉じてしまうことを防ぐためにバックスペースの検知イベントを行います。

#ViewControllerでの記述
textViewのdelegateメソッドでとりあえずコードを記述

```swift:ViewController.swift
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        let char = text.cString(using: String.Encoding.utf8)!
        let isBackSpace = strcmp(char, "\\b")

        if textView.text.count >= 3 {
            if (isBackSpace == -92) {
                //backspaceAction...
                return true
            } else {
                self.view.endEditing()
                return false
            }
        }
        
        return true
    }
```

###.cString()のメモ
cString()はswiftでのString型をchar型にエンコードして変数を扱うためのメソッドだと思います（？）。調べたところswiftには改行(\n)の様な特殊文字はバックスペースキーにはないため、バックスペースキーを押すとnilが返され検知することができなくなります。そのため、C言語にある特殊文字を利用し、エンコードして値を付加することでキーを検知できるようにする為だそうです。

###.strcmp()のメモ
.strcmp()はStringCompareの略で、その名の通り２つの値を比較するためのメソッドです。上のコードの例では変数charと"\\b"バックスペースの特殊文字を比較しています。

###-92の意味とは
これは簡単にいうと確実にバックスペースキーを押したことを検知するための値です。swiftのバックスペースキーをC言語のcharにエンコードすると[0]という10進数の値が取得できます。それに対して"\\b"は[92]という値が取得できます。
つまりバックスペースキーを押した時"0"と"92"を比較した時の差が-92という意味です。

#最後に
文字コードらへんの事も理解していかないと簡潔なコードが書けないと実感した。ちゃんと勉強しよう。。
終わり。
InterfaceBuilderにてUILabelのUIFont.TextStyleを指定する方法

## やりたいこと

以下のUILabelと同じものをXibで再現。


```swift:View.swift
let label = UILabel()
label.font = UIFont.preferredFont(forTextStyle: .headline)
```

同じフォントサイズや太さになるように見える範囲で安易にカスタムして済ませても、端末の設定で文字サイズ変更したときなどに挙動変わってくるのが想像ついてしまう。
Xib上の見た目は諦めておとなしくソースコードで指定してでも条件を同じにしたいところ。

## 発見

Label > Font > Font にいらっしゃった。
.xcodeprojファイルのパラメータみたいに検索効くと見つけやすいのだけどなぁ・・・

![スクリーンショット 2019-01-23 16.04.00.png](https://qiita-image-store.s3.amazonaws.com/0/113982/0d7ce447-8dfc-fa06-4bbb-73746286cbd6.png)
![スクリーンショット 2019-01-23 16.04.21.png](https://qiita-image-store.s3.amazonaws.com/0/113982/56258867-6f78-a793-48c2-6899285604e9.png)
【Bigquery】文字列型の日付を0埋めした形でいい感じに日付型に変換する方法

とあるテーブルの日付を入れるカラムに

`2015/2/19`　
こういうやつとか
`2015/05/03`
こういう形式で日付（文字列型）が入っちゃってるときに、いい感じに、
`2015/02/19`　

みたいに変換する方法です。


```sql
SELECT
    PARSE_DATE('%Y/%m/%d', '2018/5/1') AS _date
```



これで、
`2018-05-01`
という日付がDATE型で返ってくるのであとはよしなに色々できます。
社内プロキシのせいでdocker pullが途中で止まってしまうからプライベートレジストリを使ってみた

# はじめに

`docker pull` でイメージをダウンロードするも、なぜか途中で止まってしまい、最後までイメージをダウンロードできない。そんな症状に悩まされていました。

原因は社内プロキシが色々と制限をしているせいでした。社内プロキシは、~~社外との通信を制限してくる嫌なやつ~~セキュリティリスクからPCを守ってくれる良いやつですね！（世知辛い）

幸いにも、社内ネットワーク内に Private Docker Registy があり、そこを利用しても良いとのことだったので、そこへの登録手順を忘れない内にメモします。

Private Registryの構築方法はこちらをご覧ください。

- [プライベートなDockerレジストリサーバーをコンテナで立てる](https://qiita.com/rsakao/items/617f54579278173d3c20)



以降、説明のため、公式のNode.jsのDockerイメージを入手する場合で書きます。



# 社外PCでイメージを入手する

まず、社外PC（社内プロキシ影響下にないPC）でDockerイメージを入手します。（え？そんなPCない？がんばれ！！）

```bash
# Docker Hub（パブリックなレジストリ）からイメージをダウンロードする
docker pull library/node:10.15.0

# イメージをtarファイルに書きだす
docker save library/node:10.15.0 > ./image.tar
```

この `image.tar` を社内PCにコピーします。（ネットワークがつながってないからUSBメモリで転送？世知辛いのじゃー）



# 社内PCにイメージを取り込む

次に、社内PC（社内プロキシ影響下にあるPC）にDockerイメージを取り込みます。

```bash
# tarファイルからイメージを読み込む
docker load < ./image.tar

# イメージ一覧を表示して確認
docker images
```

以降の作業はすべて社内PCで行います。



# Private Registryへイメージを登録する

次に、社内にあるPrivate Docker RegistryへDockerイメージを登録します。説明のため、Private Registryのアドレスとポートは `xxx.xxx.xxx.xxx:xxxx` とします。

```bash
# イメージの名前を変更する
docker tag library/node:10.15.0 xxx.xxx.xxx.xxx:xxxx/library/node:10.15.0

# Peivate Registryにpushする（Proxy配下環境）
docker push xxx.xxx.xxx.xxx:xxxx/library/node:10.15.0
```

ここで、 `http: server gave HTTP response to HTTPS client` というエラーが、私の環境では発生しました。調べたところ、PC側のdockerの設定に `insecure registries` というものがあり、そこに `xxx.xxx.xxx.xxx:xxxx` を追加する必要があるそうです。

詳細はこちらをご覧ください。

- [Docker for WindowsでhttpなDokcer registryからイメージをpullしたい](https://yoshinorin.net/2018/03/17/docker-for-windows-private-docker-registory-http/)

これでプライベートレジストリへの登録ができました。



# Private Registryからイメージを入手する

以下のように書くだけです。

```bash
# Peivate Registryからイメージをダウンロードする
docker pull xxx.xxx.xxx.xxx:xxxx/library/node:10.15.0
```

同僚のPC（社内PC）で試したところ、うまくイメージをダウンロードできました。



# Dockerfileでイメージをpullする

Dockerfileも同じです。

```dockerfile
# Peivate Registryからイメージをダウンロードする
FROM xxx.xxx.xxx.xxx:xxxx/library/node:10.15.0
```



# さいごに

以下のサイトを参考にさせていただきました。ありがとうございました。

- [プライベートなDockerレジストリサーバーをコンテナで立てる](https://qiita.com/rsakao/items/617f54579278173d3c20)
- [Docker for WindowsでhttpなDokcer registryからイメージをpullしたい](https://yoshinorin.net/2018/03/17/docker-for-windows-private-docker-registory-http/)
DataBindingでクラスが見つからない時の対応法

#DataBindingでクラスが見つからない時

ビルド時に　`シンボルが見つかりません`　というエラーが表示されます。

#対応方法

##名前が衝突していないかを確認する

詳細なルールを把握していないのですが、DataBindingで生成されるコード内のクラスの名前が重複しているとエラーが出てしまいます。

`com.xxx.xxx.a.User` と　`com.xxx.xxx.b.User` のようにパッケージ名が異なっても、クラス名が同じ場合はエラーになります。


##クリーンビルド
おなじみの。

##Invalidate Cache/Restart
キャッシュ削除して AndroidStudio を再起動します。

##PCの再起動
嘘かと思うかもしれませんがこれでなおりました。

##AndroidStudioの再インストール
最終手段な気がします。


以上です。これでもダメなら DataBinding のバグの可能性があるのでIssue トラッカーを漁るしかないかと。
Servletで接続元IPチェック

環境変数「ALLOW_IP_ADDRESS_RANGES」に許可するアドレス範囲を定義しておく
「1.1.1.1-1.1.1.1, 1.1.1.10-1.1.1.11」形式
チェックを行わない場合は設定しないこと

接続元IPはrequest.getRemoteAddr()で取得しているが、必要に応じてX-Forwarded-Forヘッダから取得する
Herokuではrequest.getRemoteAddr()で取得可能 - https://help.heroku.com/FIX647OC/why-can-t-i-access-the-x-forwarded-for-header-in-my-java-spring-app

```java
private static final String ALLOW_IP_ADDRESS_RANGES = System.getenv("ALLOW_IP_ADDRESS_RANGES");
```
```java
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class IpAddressFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        if (ALLOW_IP_ADDRESS_RANGES != null && !ALLOW_IP_ADDRESS_RANGES.isEmpty()) {
            String remoteIpAddress = formatIpAddress(getRemoteIpAddress((HttpServletRequest) request));

            String[] allowIpAddressRanges = ALLOW_IP_ADDRESS_RANGES.split(",");
            boolean allowed = false;
            for (String allowIpAddressRange : allowIpAddressRanges) {
                String[] allowIpAddressRangeSplit = allowIpAddressRange.trim().split("-");
                String allowIpAddressLow = formatIpAddress(allowIpAddressRangeSplit[0]);
                String allowIpAddressHigh = formatIpAddress(allowIpAddressRangeSplit[1]);

                if (remoteIpAddress.compareTo(allowIpAddressLow) < 0 || 0 < remoteIpAddress.compareTo(allowIpAddressHigh)) {
                    log.trace("remote ip address {} is not in range({}-{})", remoteIpAddress, allowIpAddressLow, allowIpAddressHigh);
                } else {
                    log.trace("remote ip address {} is in range({}-{})", remoteIpAddress, allowIpAddressLow, allowIpAddressHigh);
                    allowed = true;
                    break;
                }
            }

            if (!allowed) {
                log.info("remote ip address {} is not included in environment variable {}", remoteIpAddress, ALLOW_IP_ADDRESS_RANGES);
                ((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN);
                    return;
            }
        } else {
            log.trace("environment variable {} not set", ALLOW_IP_ADDRESS_RANGES);
        }

        chain.doFilter(request, response);
    }

    private String getRemoteIpAddress(HttpServletRequest request) {
        String remoteIpAddress;
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty()) {
            remoteIpAddress = xForwardedFor.split(",")[0].trim();
        } else {
            remoteIpAddress = request.getRemoteAddr();
        }
        return remoteIpAddress;
    }

    private String formatIpAddress(String ipAddress) {
        String[] nums = ipAddress.split("\\.");
        StringBuilder stringBuilder = new StringBuilder();
        for (String num : nums) {
            if (stringBuilder.length() > 0) {
                stringBuilder.append('.');
            }
            stringBuilder.append(String.format("%03d", Integer.parseInt(num)));
        }
        return stringBuilder.toString();
    }
}
```
Dataclips 概要(Heroku)

# Dataclips とは
Heroku Postgres にリクエストするクエリーを保存し、CSV,JSON,xlsファイルにエクスポートする機能。
# 利用用途
リレーショナルデータベース(Heroku Postgres)に保存されている(最新)情報を、特別なツール無しに、SQL 構文をしらない非開発者でも収集できるようにする Heroku の機能。
# 利用までの流れ
1. 開発者がデータを収集するための SQL 文（クエリー)を作成、Dataclips として保存
2. Dataclips の URL を、情報入手したいユーザーに共有
3. 入手したURLに .csv , .json , .xls を追加することで、各形式のファイルを https (https://dataclips.heroku.com ではじまるURL)でダウンロード可能

# 注意点


- 1分以上データが古くなった場合、クエリーが再実行される
- 10分以上かかるクエリーは実行されず、キャンセルされる
- Heroku Postgres の場合、Standard 以上であれば、参照可能なユーザーを データベースにアクセス可能な、Heroku アカウント保持者に制限可能（元々のURLは推測しにくい文字列なので、URLが漏洩しない限り、Standard 以下でも安全に運用可能)
- 戻り値としての最大レコード数は 10万行


# その他利用方法
利用ツール(クライアント)が Google Spreadsheet の場合、IMPORTDATA 関数でデータを埋め込む事が可能。
**その場合、Google Spreadsheet のデータ更新頻度が1時間毎なので、Postgres 上のデータを更新してもすぐに Google Spreadsheet に反映されない場合あり。**

# 出典
[Sharing Query Results with Dataclips](https://devcenter.heroku.com/articles/dataclips)
【Google for jobs】Googleの新サービスを触ってみた【Googleしごと検索】

# 前提

* ろくに検証してないので、注意。責任は持たないです！
　→ご指摘等ありましたらコメントいただけると幸いです。

* 以下詳しく扱ってる記事がありました。これを先に読んでおくといいかも
 
https://hcm-jinjer.com/media/contents/c-contents-googleforjobs-180117/

# Google for Jobsって何？

![google.png](https://qiita-image-store.s3.amazonaws.com/0/146205/6fed2d04-d7df-046f-4903-51120a4bcf21.png)

Google for Jobsとは、「求人」や「転職」などの求人情報を検索する際、
検索ページの上部に求人情報が表示されるサービス。
アメリカでは2017年6月20日にリリースされている。
日本では2019/1/23に正式リリース。

自社ホームページの求人情報をgoogleに登録して使えば、タダで求人ができるよ！

## 表示例

![2.png](https://qiita-image-store.s3.amazonaws.com/0/146205/73f81326-0b7f-261e-88ee-75e676ac935e.png)

上記画像は、地域名＋SEで検索した例。
関連職種や、どういった仕事をしていくか、募集元の会社などが記載されている。
気に入った求人を保存も可能であり、関連の会社をクリックすることで業務内容の閲覧も可能。

## googleトレンドで確認してみた

![asas.png](https://qiita-image-store.s3.amazonaws.com/0/146205/0f9de3cc-d96d-0762-66d0-c7bf53516dbd.png)

Googleトレンドで確認した結果。
直近7日間のプレビューで一番検索数が伸びている。

## どうやって設定するの？

参考：
https://developers.google.com/search/docs/data-types/job-posting?hl=ja



* googleBotがクロールできることを確認
* Botのクロールの頻度を上げる
* https://developers.google.com/search/docs/data-types/job-posting?hl=ja#guidelines に準拠していることを確認する。
* 次項にある、jsonを変更し自社の求人ページに貼り付ける。
* https://search.google.com/structured-data/testing-tool?hl=ja でテストを行う。
* 準備が完了したらサイトマップ送ればおｋ

## json例

Google For Jobsで定義された最小のフィールドのみ定義しています。
もっと細かい情報を乗せたい場合はhttps://schema.org/JobPosting へ。
プロパティいっぱいあります。


```js:sample.json
<script type="application/ld+json">
{
"@context": "http://schema.org", //固定
  "@type": "JobPosting", //固定
  "datePosted": "2019-01-23", //最初の投稿日
  "description": "【急募】刺身にたんぽぽを乗せる仕事！<br />【詳細】刺身にたんぽぽを乗せる仕事です。ニートでもできますのでまずはご応募を。", //仕事内容の説明
  "hiringOrganization":{
    "@type": "Organization", //固定
    "name": "株式会社XXX", //会社名
    "sameAs": "http://www.hogehoge.com" //会社URL
  },
  "jobLocation": {
    "@type": "Place", //固定
    "address": { //もっと詳細にするなら https://schema.org/Place を参考に。求人の質が上がります。
      "@type": "PostalAddress", //PostalAddress固定がいい？
      "addressLocality": "XX区XX", //場所
      "addressRegion": "東京都", //地域
      "postalCode": "123-4567" //郵便番号
    }
  },
  "title": "【たんぽぽラー】時給700円", //職務の名称(非常に簡略な概要)
  "validThrough": "2020-01-23T00:00", //求人の有効期限。期限がないなら定義しない
  // 以下お好みで
  "employmentType": ["part-time"], //雇用形態
  "baseSalary": {
    "@type": "MonetaryAmount",
    "currency": "JPY", //日本ならこれ。BTCとかぶっ飛んだのでも対応してる…
    "value": {
      "@type": "QuantitativeValue",
      "value": 700, // 給与額
      "unitText": "HOUR" //月 or 時
    },
    "url": "http://www.hogehoge.com" //会社URL
  }
}
</script>

```
ちなみにこれでテストしてみるとこんな感じで出る。

![image1.png](https://qiita-image-store.s3.amazonaws.com/0/146205/f99fbcec-03bb-b76d-ad75-3542fea52541.png)

![image1.png](https://qiita-image-store.s3.amazonaws.com/0/146205/214b48c3-8cf5-7ea6-7695-80a3c78d7528.png)

構造化ツールでしか検証をしていないのでURLの部分がsupport.google.comになっているが、おそらくurl(会社URL)の値に代わってくれるはず。

## 最後に

会社でやって公開をしたわけではなく、検証レベルなので
情報が甘い個所などが何点かあると思います。
違っている箇所等ありましたら、コメント欄にてご指摘ください。

あと刺身の上にタンポポ乗せる仕事は募集してませんので、その点にもご注意を！
Cloud FunctionsのlogをstackdriverにjsonPayloadで送りたい

Cloud Functionsは実行ログをstackdriverに自動的に集めてくれるので大変に便利だが、
`console.log` を利用するとjs objectを渡してもstackdriverのrecordの本文が`textPayload` になってしまう。
これをなんとかしてjsonPayloadとしてログ送信したい。

# tl;dr

[@google-cloud/logging](https://www.npmjs.com/package/@google-cloud/logging) で自前でlogger instanceを作って送信する。

## そもそもなんでそんなことしたいのか

**できる限り楽して、URL query paramをBQに保存したかったから。**

`stackdriver > BQ` にexportしたときに`json payload`の場合は勝手にcolumn作ってくれて便利

# console.logを使った場合

まずは一番シンプルなcloud functions

~~~js
/**
 * Responds to any HTTP request.
 *
 * @param {!express:Request} req HTTP request context.
 * @param {!express:Response} res HTTP response context.
 */
exports.helloWorld = (req, res) => {

  //この書き方だとstackdriverのrecordがtextPayloadになる
  console.log(req.query);
  res.status(200).send(message);
};
~~~

上記のfunctionsを以下のようなqueryで実行

`https://${TRIGGER_URL}/functions-1?hoge=fuga&foo=bar`

stackdriverのrecordは以下のようにtextPayloadの文字列として保存される

~~~
textPayload:  "{ hoge: 'fuga', foo: 'bar', mes: 'mesbody' }"  
~~~

## 自前loggerを使う場合

以下のようにlogger instanceを自前で作ってやるとjsonPayloadで入る。よかったよかった

~~~js
const {Logging} = require('@google-cloud/logging');
const logging = new Logging(process.env.GCLOUD_PROJECT);
const log = logging.log('jsonpayload-log');

const LogMetadata = {
  resource: {
    type: 'cloud_function',
    labels: {
      function_name: process.env.FUNCTION_NAME ,
      project: process.env.GCLOUD_PROJECT,
      region: process.env.FUNCTION_REGION
    },
  },
};

/**
 * Responds to any HTTP request.
 *
 * @param {!express:Request} req HTTP request context.
 * @param {!express:Response} res HTTP response context.
 */
exports.helloWorld = (req, res) => {
  const entry = log.entry(LogMetadata, req.query);
  log.write(entry);
};

~~~
SSH通信、公開鍵認証方式とパスワード認証方式


### 公開鍵認証方式とパスワード認証方式の違い

- 公開鍵認証方式:パスワードを求められずそのままアクセスできる
- パスワード認証方式:パスワードを求められる

### VMの作成 
- 前提
    - VagrantでVirtual Box上にVMを立てた

    
```ruby:Vagrantfile

Vagrant.configure(2) do |config|
　　config.vm.define "controller" do |node|
        node.vm.box = "bento/centos-7.2"
        node.vm.hostname = "controller"
        node.vm.network :private_network, ip: "192.168.100.10"
        node.vm.network :forwarded_port, id: "ssh", guest: 22, host: 2250        
  end
end

```
### 接続方式の差異を確認

作成したVMにsshアクセス

```shell:パスワード認証方式
$ ssh root@localhost -p 2250
root@localhost's password:
```
パスワードを求められる。
一方keypairを取得してVMに送りつけると

```shell:公開鍵認証方式
$ ssh-keygen -t rsa
・
・
[何も入力せずにEnter　->　Pairが生成される]
・
・

$ ssh-copy-id root@localhost -p 2250
・
・
root@localhost's password:

Number of key(s) added:
・
・


$ ssh root@localhost -p 2250
Last login: Wed Jan 23 05:59:25 2019 from 10.0.2.2
[root@controller ~]#

```

鍵を送りつけるときにパスワードは求められるものの、その後はVMにssh接続する際にパスワードを求められなくなった。
HerokuのDynoは1日1回再起動される

https://devcenter.heroku.com/articles/dynos#restarting

Dynoは健康のために毎日最低1回再起動される
周期は24時間(プラス最大216分のランダム分、複数Dynoが同時に落ちないように)

その際、
DynoのアプリケーションプロセスにSIGTERMが送信される
ローカルファイルシステムへの変更は削除される
ログに「heroku[web.1]: Cycling」が出力される
 
 
SIGTERMがアプリケーションプロセス(Tomcat等)に送られて30秒以内に
新しいrequestの受け付けを中止して現在のrequest処理を終了させ、プロセスを終了する必要がある
(TomcatにとってSIGTERMはgraceful shtdownなので処理中のリクエストは最後まで処理される)
30秒経っても残っているプロセスにはSIGKILLが送られ即時終了させられる

手動再起動はheroku ps:restartコマンドで
DB2エラー（SQLCODE=-20249） 対処方法

# DB2のバージョンをダウングレードさせた際に発生するエラーの対処
## 前提条件
 - フルバックアップをとっていること
 - バージョン 11.1.3 ⇒ 11.1.2 にした際の検証

## エラー内容 ①
    Caused by: org.quartz.impl.jdbcjobstore.LockException: Failure obtaining db row lock: DB2 SQL Error: SQLCODE=-20249, SQLSTATE=     , SQLERRMC=NULLID.SYSSH200, DRIVER=3.72.44 [See nested exception: com.ibm.db2.jcc.am.SqlException: DB2 SQL Error: SQLCODE=-20249, SQLSTATE=     , SQLERRMC=NULLID.SYSSH200, DRIVER=3.72.44]

## 実行コマンド

```sh
# DB接続
$ db2 connect to <DB名>
# 対象のパッケージを削除
$db2 drop package NULLID.SYSSH200
# 再バインドする
$ db2 bind /opt/ibm/db2/V11.1/bnd/@db2cli.lst blocking all grant public CLIPKG 3
LINE    MESSAGES FOR db2cli.lst
SQL0061W  バインド・プログラムが処理中です。
SQL0091N  バインドが、エラー "0" と 警告 "0"
            で終了しました。
```

## エラー内容 ① 解決後のエラー内容 ②
    Caused by: org.quartz.impl.jdbcjobstore.LockException: Failure obtaining db row lock: DB2 SQL Error: SQLCODE=-551, SQLSTATE=42501, SQLERRMC=UEDB;EXECUTE;NULLID.SYSSH200, DRIVER=3.72.44 [See nested exception: com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-551, SQLSTATE=42501, SQLERRMC=UEDB;EXECUTE;NULLID.SYSSH200, DRIVER=3.72.44]

```sh
$ db2 grant execute on package NULLID.SYSSH200 to PUBLIC
// 再バインド
$ db2 bind /opt/ibm/db2/V11.1/bnd/@db2cli.lst blocking all grant public CLIPKG 3
```

## 参考URL
 - [エラー内容概要](https://www-01.ibm.com/support/docview.wss?uid=swg21115245)
 - [実行コマンド1](https://www.ibm.com/support/knowledgecenter/en/SSEPGG_11.1.0/com.ibm.db2.luw.apdv.cli.doc/doc/r0007866.html)
 - [確認コマンド1](https://www.ibm.com/support/knowledgecenter/en/SSEPGG_11.1.0/com.ibm.db2.luw.sql.rtn.doc/doc/r0053626.html)
 - [実行/確認 コマンド2](https://www-01.ibm.com/support/docview.wss?uid=swg21993468)
PowerShellでGET-ADUserするときのメモ

##最初にやるのはmoduleのインポート
AD上でやらない場合は、機能の追加で画像のものを追加します。
![get-aduser1.png](https://qiita-image-store.s3.amazonaws.com/0/220924/800476f8-6473-155b-f556-505e674a4019.png)
画像は2016サーバーです。Windows10等のクライアントPCは管理ツールを入れてください。

powershellを起動して、最初の一回だけ、
Import-Module ActiveDirectory
を実行します。

##Get-ADUserの実行
get-aduser -filter {objectClass -eq "user"} -searchbase "OU=ActiveUsers,DC=hogehoge,DC=jp" -properties *
このように検索します。-properties *としておくと、
AccountExpirationDate
accountExpires
AccountLockoutTime
AccountNotDelegated
・・・・・・
・・・・・・
・・・・・・
UserPrincipalName
uSNChanged
uSNCreated
whenChanged
whenCreated
ずらーっとリストが出てくるので、パイプしてselectで必要な項目を取り出します。
それをexport-csvにパイプでさらに渡せばcsvファイルになります。

get-aduser -filter {objectClass -eq "user"} -searchbase "OU=ActiveUsers,DC=hogehoge,DC=jp" -properties * | select CanonicalName,CN,Created,DisplayName,Enabled,GivenName,LastLogonDate,mail,Name,PasswordLastSet,SamAccountName,sn,Surname,UserPrincipalName | export-csv -encoding default userlist.csv

この様に書いたファイルをuserlist.ps1とか名前を付けてpowershellで実行すれば、毎回、最新のcsvになります。
filterの書き方やsearchbaseの書き方は[本家のサンプル](https://docs.microsoft.com/en-us/powershell/module/addsadministration/get-aduser?view=win10-ps)見てください。

ざっとメモです。
【Laravel】 viewファイルのキャッシュが更新されない時に確認するべき項目[docker]

# php5.5から導入された `revalidate_freq` が0になっているか
php5.5で導入された OPcache `revalidate_freq` の設定を確認しましょう。

> [公式ドキュメント]
> 更新のためにスクリプトのタイムスタンプをチェックする頻度。（秒単位） 0 にすると、OPcache は、リクエストごとに更新をチェックします。
http://php.net/manual/ja/opcache.configuration.php

つまり更新をかける頻度をphp側が設定しています。

## php.ini の設定ファイルを書き換える
`php.ini` がどこにあるか確認しましょう

オススメの検索方法（本番サーバでやると負荷かかるのでやめましょう）

全ディレクトリから `revalidate_freq` の文字列を含むファイル一覧を表示してくれます。
`grep revalidate_freq -rl /`


```zsh:私はここにありました
/usr/local/etc/php/conf.d/overrides.ini
```

```ini:/usr/local/etc/php/conf.d/overrides.ini
upload_max_filesize = 100M
post_max_size = 108M
short_open_tag = On
fastcgi.logging = 1
opcache.enable=1
opcache.revalidate_freq=0
opcache.validate_timestamps=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=0 #60秒から0に変更
opcache.fast_shutdown=1
xdebug.remote_enable=1
```
Windows10＋Laravel/Homesteadでvue.js(Laravel-MIX)の環境を作る

マジで苦労しました。残念なことに1ヵ月以上は時間を浪費しました。
しばらく放置していましたが[Vue.js/Nuxt.js meetup #2](https://vuekansai.connpass.com/event/112900/) に参加してモチベーション回復してなんとか解決。
できてしまえばどうってことない話ですが、誰かのお役に立てれば幸いです。

よくわかってなくて周りに聞ける人もいないとこうなるんだよ！って記事です。

Windows10 Homeの人向けです。

# Laravelを準備

vagrantなので[こういう記事](https://qiita.com/ricoirico/items/9745160bcf9983fa30ad)を参考にLaravelのプロジェクトを作成、とっても簡単。
この状態で既にVue.js（Laravel MIX）が準備されているらしい。

# Vagrant環境でnpm installが失敗する件

作成したLaravelプロジェクトのディレクトリで`npm install`とするだけでwebpackやらvue.jsが使えるようになりますよと言われたのですが`npm install`でエラーになりまくりです。

解決方法の選択肢がいろいろあって悩まされたのですが、共有フォルダ内にある`node_modules`フォルダにシンボリックリンクが張れない問題を回避する方法でやってみました。
↓
http://jjtake.hatenablog.jp/entry/2017/10/22/004650

`mount --bind`を使って共有フォルダ外に`node_modules`フォルダをマウントしています。マウントの永続化はvagrantfileのプロビジョニングで起動時にコマンド実行。

これで無事npmインストールは完了しました。

# ローカルサーバー（webpack-dev-server）ってなに？

これが本当によくわかりませんでした。
Webサーバーみたいなものが動いているんだろうけど、本当に動いているのかどうか確認することもできないし（ドキュメントルートがどこなのか知らない）そもそもアクセス方法もわからない。

ブラウザ開いて`localhost:8080`でOKとか言われても仮想マシン上で動いてるのにlocalhostでアクセスできないし。

* どこに置いたソースが表示されているかわからない
* ローカルサーバーの設定方法がわからない
* アクセス方法がわからない
* そもそもちゃんと起動しているのかわからない

vagrantだからダメなのか、Laravelがダメなのか、npmのインストールがダメなのか、webpackがだめなのか？？

あれこれ考えましたが問題の切り分け方法もわからず進展のない日々が続いたのは辛かったです。
なんせ設定を変更して試そうにもどのファイルを変更したらいいのかという知識すら持ち合わせていなかったので、、

# とりあえずこれで動いた

**・仮想マシン上のローカルサーバーにはポート転送でアクセスする**

vagrantの機能でポート転送することができます。

```
config.vm.network "forwarded_port", guest: 8080, host: 8080
```

vagrantfileに追記したら仮想マシンのローカルサーバーにアクセスできました。

**・webpack-dev-serverの設定を変更する**

ようやくわかったのですが`webpack.mix.js`でmixオブジェクトに設定してやるとデフォルトを上書きしてくれるみたいです。

```webpack.mix.js
mix.webpackConfig({
    devServer: {
        disableHostCheck: true,
        host: '0.0.0.0',
        port: 8080,
    },
    watchOptions: {
        poll: 2000,
        ignored: /node_modules/
    }
});
```
重要なのは`watchOptions`です、これを設定しておかないとソースの変更を検知してくれず自動的に更新してくれません。

# おわりに

これで念願のvue.jsの開発に着手できるようになりました。
この方法が正しいのかどうかわかりませんしDockerとか使えたら状況は違っていたかも知れません。何はともあれvue.jsのサンプルコードとか試せるようになったので大満足です。

もうほぼほぼ諦めていたんです、かなりの時間を費やしながら解決できず凹んでましたし。

[Vue.js/Nuxt.js meetup #2](https://vuekansai.connpass.com/event/112900/)に参加してよかったです。みなさんVue.jsでわいわい楽しそうだったのでライフが回復しました！ありがとう～
JenkinsのSlack通知にgit logの情報を出力する (Groovyスクリプト編)

Jenkinsのデプロイ完了をSlackに通知している方も多いと思います。

今回は、その通知メッセージにgit logの内容を出力する方法を紹介します。
といっても、単にコマンド実行結果を出力する方法なんですが。

Groovyスクリプトで、

```Groovy
def output = sh returnStdout: true, script: 'git log --stat -1'
```
とすると、コマンドの実行結果がoutputに保存されます。
これを、Slackへの出力メッセージに追加するだけです。
RasPiでOVOから音出してみた。

#はじめに
[OVO](https://www.jdsound.co.jp/products/ovo/)というスピーカーがあります。
usb一本だけで、高音質、強力低音、爆音ていう。
RaspberryPiで流せるかなと試してみました。
今回はRasPiZeroHWで試しました。

#結論
特に書くこともなく、usb挿せばOVOと認識され（電源はraspiのみ）
mp3しかなかったので

```
sudo apt-get install mpg321
```
でmpg321インスコして
**OVOのローカルボリュームに設定して、ボリュームを最低にして（超重要）**

```
mpg321 -a hw:1,0 XXX.mp3
```
で、すんなり再生されました。音量は3ぐらいから聞こえ始めて4で小さめ、それ以上は踏み入ってません。

#注意（ネタじゃないです）
最初に音鳴らないなぁ、とローカル音量にした瞬間、超爆音が鳴って雷が落ちたかと。
これは本当に注意。
Servletでファイル名からMimeTypeを判別

```
String mimeType = request.getServletContext().getMimeType(downloadFileName);
if (mimeType == null) {
    mimeType = ContentType.APPLICATION_OCTET_STREAM.toString(); ★
    log.warn("can't get mime-type for {}. default={}", downloadFileName, mimeType);
}
```

★：org.apache.http.entity.ContentTypeがimportできないなら"application/octet-stream"で十分
Pingを基礎から理解しよう3~ルーティング

今はPingを通してネットワークの基本的な部分を学習しています。

[前回の記事](https://qiita.com/tekondo/items/f835040c96d70ddb59d5)
ではIPパケットがどのように構成されているのかを確認しました。

今回の記事では実際にIPパケットが送信された時にどんな流れでパケットが運ばれているのかについて調べていきます！

## IPアドレスとルーティングテーブル
通信するためには宛先のIPアドレスを知っている必要がありました。

IPアドレスとは、ネットワーク上で割り当てられている住所のようなものです。

IPアドレスが一意に割り当てられているために届けたいものを届けたい場所に届けることができます。

しかしパケットを届けたいところに届ける場合、いくつものルーター、ホストを経由して送信されます。


こんな感じ
![スクリーンショット 2019-01-22 16.45.57.png](https://qiita-image-store.s3.amazonaws.com/0/231063/dc643a9e-f33f-416a-770c-c104eb9c765c.png)
引用元：[マスタリングTCP/IP](https://www.amazon.co.jp/%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%AA%E3%83%B3%E3%82%B0TCP-IP-%E5%85%A5%E9%96%80%E7%B7%A8-%E7%AC%AC5%E7%89%88-%E7%AB%B9%E4%B8%8B/dp/4274068765/ref=p)


ここで大事なのはアドレスをみて**どのルーターを経由する**のかを判断しなければならないということです。

ここで使用されているのが経路制御表（ルーティングテーブル）です。
これはIPアドレスと次に送るべきルーターが記載されています。
経路制御表の例をあげると

| IPアドレス       |       ルーター |
|:-----------------|------------------:|
| 192.168.0.0             |          ルーターA |
| 192.168.1.0             |          ルーターB |
| 192.168.2.0             |          ルーターC |

このような形でアドレスと次に送るべきルーター情報が記載されています。

これを元にルーターは送られてきたパケットをどのルーターに送るのかを判断します。

## 実際に経路制御表をみてみよう
イメージはだいたい掴めたと思うので自分のパソコンの経路制御表がどうなっているのかをみてみましょう。

macの人であれば

```
netstat -r
```
で自分のルーティングテーブルを表示することができます。

```
➜ netstat -r
Routing tables

Internet:
Destination        Gateway            Flags        Refs      Use   Netif Expire
default            10.16.255.254      UGSc          164        0     en0
10.16/16           link#5             UCS             0        0     en0      !
10.16.172.142/32   link#5             UCS             0        0     en0      !
10.16.255.254/32   link#5             UCS             1        0     en0      !
10.16.255.254      0:a0:c9:48:1:1     UHLWIir        99       16     en0    643
127                localhost          UCS             0        0     lo0
localhost          localhost          UH             10    33236     lo0
```

こんな感じで表示されました。
Destinationが目的地でGateWayが経由するホスト、ルーターを示しています。

ここで大事なのはdefaultと呼ばれる目的地です。
大抵のアクセスはここに飛ばされることがわかります。

各項目の詳細については
https://www.ibm.com/support/knowledgecenter/ja/POWER7/p7hcg/netstat.htm
こちらをご覧ください。


### Wifiオフにしてみると
```
➜ netstat -r
Routing tables

Internet:
Destination        Gateway            Flags        Refs      Use   Netif Expire
127                localhost          UCS             0        0     lo0
localhost          localhost          UH             11    33340     lo0
169.254            link#12            UCS             1        0     en3      !
169.254.92.48/32   link#12            UCS             1        0     en3      !
224.0.0/4          link#12            UmCS            1        0     en3      !
224.0.0.251        1:0:5e:0:0:fb      UHmLWI          0        0     en3
255.255.255.255/32 link#12            UCS             0        0     en3      !
```

ここでWiFiをオフにしてみましょう。
経路がかなり変わったのがわかると思います。

接続するWiFiが変更されるとグローバルIPアドレスも変わるように接続しているアドレスが変更されているのでテーブルも変更されることが確認できます。



### link〇〇ってなに？
表をみているとlink#5とかが見受けられると思います。これはルーターを経由せず自力で通信する場合に記述されます。


## まとめ
パケットが送信されてからルーティングテーブルをどんどん経由して行ってどんなルートを通るのかがだいたいイメージできたかと思います！

今回ほとんどPing関係ないですね、、、
C++ Builder XE4 > 45個のボタンを持つフォーム。ボタンを押したら名前をTMemoに表示

```txt:動作環境
C++ Builder XE4
```


### 処理概要

- 45個のTButtonを用意
- 各ボタンを押した時、その名前をTMemoに表示する

### イベント設定

Button1を配置する。
オブジェクトインスペクタの「イベント」タブにて、「OnClick」をButtonXClick_generalという名前にする。
ButtonXClick_generalは以下の実装を行う。
実装後、Button1をコピーして、45個のButtonをフォームに配置する。


![2019-01-23_14h34_42.png](https://qiita-image-store.s3.amazonaws.com/0/32870/3e1da976-490d-3af1-0651-7dbbded64161.png)


### 実装

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	Memo1->Lines->Clear();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonXClick_general(TObject *Sender)
{
	TButton *btnPtr = (TButton *)Sender;
	Memo1->Lines->Add(btnPtr->Name);
}
//---------------------------------------------------------------------------
```

### フォームデザイン

![2019-01-23_14h32_31.png](https://qiita-image-store.s3.amazonaws.com/0/32870/bef4b484-097f-c090-8e72-7eef4df5d5fc.png)

### 実行例


![2019-01-23_14h33_09.png](https://qiita-image-store.s3.amazonaws.com/0/32870/8676a269-b9fe-00c7-eb4b-67d1a2a94935.png)

### 作成の理由

マウス自動クリックのソフトを実装し、そのテストに使う。

- [auto click the mouse](http://www.delphigroups.info/2/2/223069.html)
    - Delphi実装例
        - フォーカスがクリック先のソフトに移る
        - 自分のソフトにフォーカスを戻す処理で失敗したりする
Salesforce SOSL ORDER BY例

```
FIND {避難 AND 学*} IN ALL FIELDS RETURNING Case(Id, CreatedDate ORDER BY Name DESC NULLS last)
```
「避難」という単語を含む、かつ「学」から始まる単語を全フィールド(ってどれだよ)中いずれかに含むCaseのId・CreatedDateを返す
結果はNameでソート、その際NULLは最後
Unityでゲーム画面を作っていこう！その0　諸々確認

##何を作りたいか##
ラングリッサーシリーズのようなシミュレーションゲーム
（ファイアーエムブレムとは違う）

##自分の前提条件##
Unity初触り
プログラムはweb系ならいける
現場でソシャゲの開発、保守経験はある
音楽はDTMで作れる
絵は描けないから恐らくコミpo!で作る

##作成手順##
どういう順序で作ればいいかな～と考えているのですが、
・画面に画像貼り付けてボタンを作ってまずは画面遷移を作る
・飽きたらDBに繋げて装備品とかアイテムとか魔法、職業等をINSERTし、とりあえずショップ画面を作ってみる
・それも飽きたら魔法の説明画面とか作る
・上記を飽きたら別の作業を繰り返す
・DB周りが出揃ったら戦闘画面（マス目の画面）を作る
・戦闘シーンを作る
・その他作る　今は大雑把

という感じで行きたいと思います。
休日も仕事してる感じなのでのろのろペースです。


コンパイル言語（厳密にはそうではないけど）は初めてなので、わからないことだらけですが
マイペースに作っていきたいと思います。
一年で3ステージくらいまで作れれば上出来かな～と思ってます。
html入門1~書式など~

##書式##
とりあえず下

```html
<タグ名　属性="属性値">コンテンツ</終了タグ>

<p class="hogehoge">hogehoge</p>
```

最初の\<>が開始タグで\</>が終了タグと申します.

##階層関係##
階層関係を理解していないと勉強するときお困りになるのでメモメモ

###親子###
パパママに子供が包まれている感じの関係です.
下の通りです.

```html
<親要素>コンテンツ<子タグ>コンテンツ</子タグ></親要素>

<p>お山の<strong>翁</strong>ありにけり</P>
```

###子孫###

```html
<祖先要素>
         <子要素><子孫要素></子孫要素></子要素>
</祖先要素>

<div>
     <p>永谷園の</p>
     <p>麻婆<strong>春雨</storong></p>
</div>
```

上の例で言うとdivはstorongにとっての祖先要素です逆にstorongはdivから見ると子孫要素です.
ややこしや~

###兄弟###

同じ親要素をもつ要素同士を兄弟要素っていうらしいです.
ご覧ください

```html
<親要素>
       <子要素1></子要素1>
       <子要素2></子要素2>
</親要素>
```
子要素1と2が兄弟です.

##インライン要素とブロックレベル要素##

###インライン要素###
インライン要素 < a >、< span >、< button >、< input >、< img >など 　
インライン要素は横方向に配置される。 
親要素の幅(もしくはページ幅)に到達すると改行され,また行の先頭から追加されていく。

###ブロックレベル要素###
ブロックレベル要素 < h1 >、< p >、< div >、< ol >、< ul >など
矩形としての領域を確保し,縦方向に追加されていく。

###注意点###
ページをレイアウトするときは,まずブロックレベル要素を使って大まかなレイアウトを整え,その中にインライン素 を流し込んでいく。
また,インライン要素とブロックレベル要素を混同しないようにする。
インライン要素に高さを指定しても無視されるし,ブロックレベル要素に高さを指定するとむ



とりあえずこんなところで失礼します.
convnet.jsで7セグメントLED

#概要

convnet.jsで7セグメントLED、学習してみた。

#写真

![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/W/8/l/W8lG.jpg?t=1548217326)

#モデルを作って、教師データを学習する。
dataset

```
var data = [
    [0, 0, 0, 0],
    [1, 0, 0, 0], 
    [0, 1, 0, 0],
    [1, 1, 0, 0], 
    [0, 0, 1, 0],
    [1, 0, 1, 0],
    [0, 1, 1, 0],
    [1, 1, 1, 0],
    [0, 0, 0, 1], 
    [1, 0, 0, 1]];
var labels = [
    [1, 1, 0, 1, 1, 1, 1], 
    [1, 1, 1, 1, 1, 1, 1],
    [0, 1, 0, 0, 1, 1, 1],
    [1, 1, 1, 1, 1, 0, 1],
    [1, 1, 0, 1, 1, 0, 1],
    [1, 1, 0, 0, 1, 1, 0], 
    [1, 0, 0, 1, 1, 1, 1], 
    [1, 0, 1, 1, 0, 1, 1],
    [0, 0, 0, 0, 1, 1, 0], 
    [0, 1, 1, 1, 1, 1, 1]];
```

model 

```
net.makeLayers([{
    type: 'input', 
    out_sx: 1,
    out_sy: 1,
    out_depth: 4
}, {
    type: 'fc', 
    num_neurons: 20,
    activation: 'relu'        
}, {
    type: 'regression',
    num_neurons: 7
}]);
```

モデルは、入力4、出力7、全結合20、reluの回帰。
オプチマイザーは、sgd
学習は、1000回

#成果物

http://jsdo.it/ohisama1/W8lG/

以上。
Ktorアプリの warをweb.xml無しで作成する。

##前置き
とあるアプリケーションの作成でKotlinを使うことにしました。で、WebのサービスAPIを作成するためのフレームワークについて、KotlinはJVM言語だからJAX-RSとか定評のあるJavaのフレームワークも使えたのでしょうけど、折角なのでKotlinのフレームワークのKtorに挑戦することにしてみました。

Webアプリケーションをtomcatなどにデプロイするにはwarファイルにすると便利なので、それについて調べたところ、[公式にその方法があったりはする](https://ktor.io/servers/deploy/packing/war.html)のですが、そこではweb.xmlをつかってKtorのサーブレットを登録する方法が示されています。

しかし今どきServlet3.0以上だと思うし、何よりxmlが煩わしいのでweb.xmlを使わないようにしてみました。

##方針
基本的な方針は単純で、web.xmlで登録するサーブレット`io.ktor.server.servlet.ServletApplicationEngine`を継承したサーブレットを作成してそこにサーブレット登録用のアノテーションを付加することを考えます。

##設定項目
公式のweb.xmlで設定されているのは次の通り。

* サーブレットコンテキストへ名前`io.ktor.ktor.config`、値`application.conf`
* サーブレットの登録、名前は`KtorServlet`、サーブレットは`io.ktor.server.servlet.ServletApplicationEngine`
* async supported
* マルチパート設定
 * `max-file-size`が304857600
 * max-request-sizeが304857600
 * file-size-thresholdが0
* サーブレットの入り口が`"/"`

以上をアノテーションで設定します。

##サーブレット
上記のうち、コンテキストパラメーター以外は次のようにサーブレットで実現できます。

```
import io.ktor.server.servlet.ServletApplicationEngine
import javax.servlet.annotation.MultipartConfig
import javax.servlet.annotation.WebServlet

@WebServlet(name = "KtorServlet", value = ["/"], asyncSupported = true)
@MultipartConfig(fileSizeThreshold = 0, maxFileSize = 304857600, maxRequestSize = 304857600)
class KtorEntryServlet: ServletApplicationEngine() {
}
```
ただしサーブレットコンテキストについてはサーブレット作成前に予め設定しておく必要があるので、こちらはServletContainerInitializerを作成して設定します。コードは次の通り。

```
import javax.servlet.ServletContainerInitializer
import javax.servlet.ServletContext

class KtorServletContainerInitializer: ServletContainerInitializer {
    override fun onStartup(c: MutableSet<Class<*>>?, ctx: ServletContext?) {
        ctx!!.setInitParameter("io.ktor.ktor.config", "application.conf")
    }
}
```

なんか安直な方法ですが、これでとりあえず動作しているみたいです(ファイルアップロードは検証していませんが)。

あと何か初期設定をしたいばあいはこちらで行えば良さそうですね。
参照した式だけ番号を表示する

ちょっとしたメモ

$\rm\LaTeX$ で参照した式だけ番号を表示したい。

#showonlyrefs
参照した式だけ番号を表示するには、 `mathtools` パッケージを使います。
プリアンブルに

```latex
documentclass{jsarticle}
\usepackage{amsmath} % amsmath も必要
\usepackage{mathtools}
\mathtoolsset{showonlyrefs} % 参照した式のみ番号を表示
...
\begin{document}
...
```

のように書けば、参照した式のみ右端に番号が表示されます。（`showonlyrefs` は `showonlyrefs=true` と書いても良い。）

**例**

```latex
\begin{align}
a & = b \label{ab} \\
c & = d \label{cd} \\
e & = f \label{ef}
\end{align}
式 \eqref{cd} によると...
```

```math
\begin{align}
a & = b \label{ab} \\
c & = d &&& (1)\label{cd} \\
e & = f \label{ef} 
\end{align}
```
$\text{式(1)によると...}$

**注意**

- `\ref` ではなく `\eqref` を使う必要があります。（**超重要**）[^1]
- `\eqref{label}` で $(1)$ のように括弧付きで式番号が表示されます。

[^1]: これを伝えるために書いた記事です。
React-routerメモ

## React-routerのメモ
### 1　インストール
- npm install --save react-router-dom

### 2 コンポーネント作成
```javascript

import React from "react";
import ReactDOM from "react-dom";
//pagesディレクトリを作ってhome,aboutを作成する
import Home from "./pages/home";
import About from "./pages/about";
import {BroweserRouter, Switch, Route} from 'react-router-dom'
import "./styles.css";

function App() {
  return (
    <div className="App">
　　　　　　　　　　//作ったコンポーネントを呼び出す
      <Home />
      <About />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

```

### 3 コンポーネントのルート先を設定
- react-router-domを使う

```javascript

import React from "react";
import ReactDOM from "react-dom";
import Home from "./pages/home";
import About from "./pages/about";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import "./styles.css";

function App() {
  return (
    <div className="App">
      <BrowserRouter>
        <Switch>
          <Route path="/" component={Home} exact />
         //urlで/aboutにするとこちらのコンポーネントが表示される
          <Route path="/about" component={About} exact />
        </Switch>
      </BrowserRouter>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

```

### 4 Linkを使う

```javascript

import React from "react";

const Header = props => {
  return (
    <nav>
      //通常のhtml風だとここがaタグになるが、これだと画面遷移をしても更新されてしまう
　　　　　　　　　　　//そこでaタグではなくLinkというものを使う
      <a href="/">Home</a>
      <a href="/about">About</a>
    </nav>
  );
};

export default Header;

//↓置き換えるとこう

import React from "react";
import {Link} from 'react-router-dom'
const Header = props => {
  return (
    <nav>
      //Linkを使って上のaタグをこのように変える
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
    </nav>
  );
};

export default Header;
```

## 補足　アクティブリンクをつけたい場合

```javascript

import React from "react";
//NavLinkに変更して使うことで見ているページにactiveを付与できる
import { NavLink } from "react-router-dom";
const Header = props => {
  return (
    <nav>
      <NavLink to="/" exact>
        Home
      </NavLink>
      <NavLink to="/about" exact>
        About
      </NavLink>
    </nav>
  );
};

export default Header;


```

```css
nav a.active {
  color: red;
}

```
とかにしてあげるとこれでアクティブのスタイルを変更できたりする

## メモまとめ
繰り返しやることでやはり定着されるものだと感じつつ、他のもの触ったりしてたらちょっと忘れてたりするので
ドキュメントチェックはかかせないですなぁぁ
修学旅行にインフルで行けないので10分ごとに行きたいツイートをする

#背景
修学旅行前日にインフルエンザになりました
行けなくてあまりにも悔しいので10分ごとに「修学旅行行きたい」ツイートするようにしました
#プログラム
```python
from twython import Twython,TwythonError 
import datetime
import time
#twitterの認証情報を入力 
CONSUMER_KEY = "XXXXXXXXXXXXXXXXXXXXXX"
CONSUMER_SECRET = 'XXXXXXXXXXXXXXXXXXXXXX' 
ACCESS_KEY = 'XXXXXXXXXXXXXXXXXXXXXX' 
ACCESS_SECRET = 'XXXXXXXXXXXXXXXXXXXXXX' 
api = Twython(CONSUMER_KEY,CONSUMER_SECRET,ACCESS_KEY,ACCESS_SECRET) 
print('Auth Done!')

while True:
    #日時取得（重複ツイートを避けるためにツイートに日時の情報をstrで入れる）
    now = datetime.datetime.now()
    api.update_status(status='修学旅行行きたい\n' + str(now))
    print(now)
    time.sleep(600)#〜秒ごとに繰り返す
```
#実行
10分ごとでやったらTL埋め尽くして申し訳なかったので1時間ごとに変更しました
<img width="768" alt="IMG_2136.png" src="https://qiita-image-store.s3.amazonaws.com/0/263501/3ecdcede-e0a9-be6e-f6ad-6d806ac18b4c.png">
https://twitter.com/nya3_neko2/status/1088082093437902848
#おわりに
修学旅行行きたい
pythonのdatetimeで年月日をフォーマットに落とす

```python
import datetime
now=datetime.datetime.now()
print('{0:%Y/%m/%d/%H:%M:%S}'.format(now))
```
>'2019/01/23/13:17:04'


##追記：3.6以上はf-stringsが使える
@shiracamusさんにコメントで頂きました。ありがとうございます！

```python
import datetime
now = datetime.datetime.now()
print(f'{now:%Y/%m/%d/%H:%M:%S}')
```

>2019/01/23/13:32:41


###参考
* [Pythonで現在の日時を取得して指定のフォーマットの文字列に変換する](https://tonari-it.com/python-datetime-now/)

* [【Python】色々なprintフォーマットの出力方法 – %s, .format(), f-strings]
(https://code-graffiti.com/print-format-with-string-in-python/)