OmniAICreator/Qiita-1.07M huggingface dataset:
Battalion 1944のサーバーをCentOS7で建てる

#タイトルの通りBattalion 1944のサーバーを建ててみる。
今流行り？のBattalion 1944のサーバーをVPSで構築。

##サーバースペック等
sakura VPS 8GBプラン
CentOS7
LinuxGSMを用いる

#構築手順
基本的にはLinuxGSM(https://linuxgsm.com/lgsm/bt1944server/) のページ通りやればよい。

###1. まずはyum周り

```
# yum install epel-release
# yum install mailx postfix curl wget bzip2 gzip unzip python binutils bc jq tmux glibc.i686 libstdc++ libstdc++.i686
```


###2. gccのアップデート

このまま構築しようとするとgccのバージョンが古くて起動しないので、gccのバージョンを新しめのやつにする。

https://www.server-memo.net/memo/gcc-install.html

この辺を参考にしてがんばってください。結構時間がかかるので、3回ぐらいはシコれる。終わったら**再起動**

```
# reboot
```

###3. LinuxGSMでサーバー建てていく

ユーザー追加とパスワード設定

```
# useradd -m bt1944server
# passwd bt1944server
# usermod -G wheel bt1944server
# su - bt1944server
```

LinuxGSMダウンロードとインストール

```
$ wget -O linuxgsm.sh https://linuxgsm.sh && chmod +x linuxgsm.sh && bash linuxgsm.sh bt1944server
$ ./bt1944server install
```

###4. ポート開放

デフォルトだと7777/UDP,7778/UDP,7779/**TCP**,7780/UDPを利用するようなので開放

```
$ sudo firewall-cmd --zone=public --add-port=7777/udp --permanent
$ sudo firewall-cmd --zone=public --add-port=7778/udp --permanent
$ sudo firewall-cmd --zone=public --add-port=7779/tcp --permanent
$ sudo firewall-cmd --zone=public --add-port=7780/udp --permanent
```


これで建ったよ💩


#追記

サーバー設定等書いておく

serverfiles/Linux/Battalion/Saved/Config/LinuxServer/bt1944server.ini を読み込むらしい。

```
vim serverfiles/Linux/Battalion/Saved/Config/LinuxServer/bt1944server.ini
```
OSXアップデートとGitの微妙な関係

OSXをアップデートすると毎回Gitが使えなくなる。


## 正しそうな作法

- OSXをアップデート
- Xcodeをアップデート
- Command line tools をアップデート

## 発生するエラー

- xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
    - 一般的には次のコマンドで解決する
        - xcode-select --install
- さらに 「このソフトウェアは、現在ソフトウェア・アップデート・サーバから入手できないため、インストールできません」 ダイアログが出る
    - この不親切極まりないエラーメッセージは、OSX,XcodeのVersionが一致していないのが原因の模様、おそらく Updateに新しいOSX用のXcodeがあるのでUpdateする。なければ手動でダウンロードしてインストール
    - OSXとXcodeのVersionを確認して、対応する Command line tools をダウンロードし、Installする。
    - ダンロードはこちらから(認証必要) https://developer.apple.com/download/more/

## 参考

- MacOSをMojaveにアップデートしたらgitコマンドが使えなくなった
    - https://qiita.com/pylori/items/3cfe6b34f9247603e42e
【PHP】２つの配列が全く同じであるかを比較する

(追記)
**コメントでいただいた方法だと、簡単に判定が可能でした！**

> php なら直接比較で良い気がします。

```php
$a = [0,1,2,3];
$b = [0,1,2,3];
var_export ($a === $b);
// true
```

・・・以降記載のような面倒な方法は回り道した記録として残しておきます。

----

array_diff を使います。

```php
$array1 = [1,2,3];
$array2 = [1,2,3];
$diff = array_diff($array1, $array2);
# var_dump($diff); → []
```
array_diffは第一引数の配列と以降の引数の配列を比較して、存在しなかった要素を返却します。
ですので、上記例だと

\$array2に1があるか
\$array2に2があるか
\$array2に3があるか

という順番で判定するわけです。
つまり、

```php
$array1 = [1,2,3];
$array2 = [1,2,3,4];
$diff = array_diff($array1, $array2);
# var_dump($diff); → []
```

上記の場合でも同じとなってしまうのです。
配列の要素数が同じであれば、array_diffで同じであるかどうかを判定できるので、

```php
/**
 * 同じ配列かチェックする
 * @param array $array1
 * @param array $array2
 * @return bool $flag
 */
function checkSameArray(array $array1, array $array2): bool
{
    $flag = false;
    // 要素数を判定
    if (count($array1) === count($array2)) {
        // array_diff で判定
        if (count(array_diff($array1, $array2)) === 0) {
            $flag = true;
        }
    }
    return $flag;
}

```

このように判定すると、配列がまったく同じものであるかどうか判定できます。
※わざわざ関数化しなくても、

```php
if (count($array1) === count($array2) && count(array_diff($array1, $array2)) === 0) 
```
と判定すればいいので、コードの長さや使いまわしなどを考慮して実装するといいでしょう。
【Clibor】GoogleIMEとかでyyyy-mm-dd形式を一発変換したい


#はじめに

GoogleIME（Google変換）にて「きょう」で変換すると

>
今日
きょう
2019/06/06
2019-06-06
2019年6月6日
平成31年6月6日

なんて出てきますね。

自分が使うのは「2019-06-06」の「yyyy-mm-dd」形式なのですが、毎度毎度入力＆スペースキーを連打して選ぶと10タイプくらいして面倒だったので、どうにかして一発変換出来ないか調べました。


#結論

無理！
けど出来た。

GoogleIMEでは2019-06-06現在、無理でした。

Clibor（クリボー？）というフリーソフトを使ったら出来ました。



#Clibor

Windows用フリーソフトです。

公式サイト
https://chigusa-web.com/clibor/


使い方丁寧に公式でまとめてくれるの凄い好感持てますね。



#インストール

https://www.vector.co.jp/soft/winnt/util/se472890.html

ツールバーにダウンロードマークっぽい下矢印が追加されたら成功。

デフォルトでCtrlを2回押したらコピーした履歴が出てくるはず。


#設定

ツールバーのアイコン右クリックから「設定」

「基本動作」ページ

「自動貼り付けを有効にする」をON

（ついでに「自動貼り付け時のWait」を50ミリ秒くらいにするのオススメ）


#定型文

設定を閉じてから。

ツールバーのアイコンを右クリック→「定型文の編集」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71795/783d288b-54af-7e63-cc7f-f7de0c87614a.png)

```
<$CLB_HDATE>yyyy-mm-dd</CLB_HDATE>
```

ホットキーは悩んだんですが、Ctrl + DとかだとChromeなどブラウザ側のショートカットキーと認識されちゃいますね……。

Shift + Dとかでも一応動きますが、使うことないであろうShift + 0にしておきました。

なにかオススメあったら教えて欲しいです。


#まとめ

これで無事に「Shift + 0」一発で日付が入力されます。

曜日も入れたり、時刻とかにも対応してるみたいなので色々定型文入れるのも良いかもですね。

https://chigusa-web.com/clibor/qa/
↑
日付フォーマットについて。引用
>
変換についてはDelphiという言語のFormatDateTimeで行います。
例えばyyyyで西暦4桁で表示されます。詳しくは「Delphi FormatDateTime」で検索してください。

あとは……、GoogleIMEのユーザー辞書だと改行入ったものとかは無理だし、そういう意味でも定型文かなり使えそうですね。

定型文それぞれにホットキー割り当てなきゃいけないってことでもないですし。

終わり
Failed dependencies:  soファイル見つからないって、よくある話

#よく遭遇する、dependenciesエラー

遭遇するたびに、どのパッケージをインストールすればいいんだ。。となる。

環境はCentOS７

```
[root@yuki yuki]# rpm -ivh '/home/yuki/Downloads/code-1.35.0-1559611476.el7.x86_64.rpm' 
error: Failed dependencies:
	libXss.so.1()(64bit) is needed by code-1.35.0-1559611476.el7.x86_64
```

が

誰が提供してくれんの？コマンドを使えば

```
[root@yuki yuki]#yum whatprovides */libXss.so.1

libXScrnSaver-1.2.2-6.1.el7.x86_64 : X.Org X11 libXss runtime library
Repo        : base
Matched from:
Filename    : /usr/lib64/libXss.so.1

```

が提供してくれるらしい。
libXScrnSaver

yum install libXScrnSaver  としてインストールすれば解決。
Webアクセシビリティ: 

2017年9月に開催された[Html5 Conference](http://events.html5j.org/conference/2017/9/)で発表されていた
[多様なユーザーニーズに応えるフロントエンドデザインパターン〜書籍「インクルーシブ HTML + CSS & JavaScript」より -HTML5 Confrence 2017-](https://www.youtube.com/watch?v=FOznWmVyk9I)

こちらとてもわかりやすかったです。
これを見ていて特になるほど！と思った内容をメモしておきます。

# 隠しテキストで説明
```html
<a href="xxx/xxx.html" class="call-top-action">
  今すぐ購入
</a>
```
`今すぐ購入`のようなボタンが続く場合だったり、対象の商品からdomが離れてしまっている場合、
スクリーンリーダーでは「何を」今すぐ購入なのかがわからない。

そんな時は、以下のように隠しテキストで補足説明を書いてあげよう。

```html
<a href="xxx/xxx.html" class="call-top-action">
  <span class="visuallt-hidden">
    スタンドにたたずむ裸の男を
  </span>
  今すぐ購入
</a>
```

# 数種類の要素を１つのリンクにすることへの問題点
よくあるタイトルや画像・ボタンなど全てがリンクになっているパターンです

```html
<a href="xxx/xxx.html" class="call-top-action">
  <h3>スタンドにたたずむ裸の男</h3>
  <img src="image.jpg" alt="スタンドにたたずむ裸の男の写真"/>
  <button>今すぐ購入</button>
</a>
```
デザイン(みため)としての問題もありますが、スクリーンリーダーに対する問題点が強いなと感じました

- スクリーンリーダーで中身が全部読まれてしまうため、リンクとして判断しずらい
    - リンク内の要素全て読まれた後に「リンク」と読まれる
- リンク一覧機能と相性が悪い

# 外部サイトとの連携を考える(SERP)
メタデータを設定しましょう。
サーチエンジン経由で使う人が使いやすいように。
また、外部サイトでも表示されやすいように。
[itemprop 属性](https://reference.hyper-text.org/html5/attribute/itemprop/)

# WAI-ARIAのライブリージョン
スクリーンリーダーで他の読み上げに割り込んで読んでくれる。
たとえばローディング中などに活躍します。

```html
<div aria-live="assertive" role="alert">
  XXを読み込み中。しばらくお待ちください
</div>
```
[初心者]gfortran (gcc version 8.3.0)でwrite文をコンパイルするとSegmentation faultになってしまう

ソースからビルドしたgfortranの挙動に不可解な点があったので記事にして残しておく．
多分自分が何か変なことをしてしまっているので何か分かったら追記する．

ビルドは『[gccをソースからビルド／インストールする](https://qiita.com/liveralmask/items/6ed4a98ebb3bf6b7f707)』を参考にさせていただいた．
ソースは上記のページにリンクしてあった筑波のミラーサイトから拝借．

具体的には以下のwrite文をコンパイルするとSegmentation faultが返ってくる．

```fortran:test.f90
program main
implicit none

write(*,'(a)') 'TESETSTESTSETSETSETSET'

end program
```

現在エラーを確認しているのはgcc version 8.3.0と8.2.0で，
反対にversion 4.4.7と6.5.0では問題なく動いた．動作はCentOS 6.9上で確認した．
他にもIntel Fortranを試したり，macOS 10.14上でHomebrew GCC 8.2.0のgfortranでも試したが問題なく動いた．

ビルドの段階で自分が何かおかしいことをしたのだろうと思うので，何か分かったら追記する予定．
現在自分はうまく動いたversion 6.5.0を使っている．
Rubyでsortとeachを組み合わせる

eventsというeventインスタンスの集合があったとします。

eventsに存在するeventのidを一覧表示させるためには以下のようにします。

```
$ events.each {|event| puts event.id }

12359
12138
7184
6872
13547
5582
```

表示されたidをソート順で確認したい場合は以下のようにします。


```
$ events.sort_by {|event| event.id }.each {|event| puts event.id }

5582
6872
7184
12138
12359
13547
```
[win10]Could not install packages due to an EnvironmentError: [Errno 2] No such file or directory

#原因について
同じエラーが発生した人の助けになればと思いこの記事を書きました。

```
>pip install tf-nightly-gpu-2.0-preview
```
pip installしているときに、以下のようなエラーが出ました。

```
Could not install packages due to an EnvironmentError: [Errno 2] No such file or directory: 'C:\\Users\\****\\AppData\\Local\\Temp\\pip-install-iwat19hr\\tf-nightly-gpu-2.0-preview\\tf_nightly_gpu_2.0_preview-2.0.0.dev20190605.data/purelib/tensorflow/include/tensorflow/include/external/eigen_archive/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h'
```

調べたところ、原因はパスが長すぎることらしいです。
win10はデフォルトでは260文字の制限があるため、これを解除する必要があります。

#対策
1. グループポリシーの編集を開く

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425255/62e60aaf-78bf-6c74-e8da-86d6e7dbeaeb.png)
2. コンピューターの構成 > 管理用テンプレート > システム > ファイルシステム をクリック

![970e2b21b92914473dbab1d2a89f7ae7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425255/7521d6c5-1d6e-275d-de2f-966d08530a50.png)

3. Win32の長いパスを有効にする をダブルクリック
4. 有効 をクリックして、画面下部の　OK ボタンをクリック
![369f65ba949361367cbe25f9441df5de.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425255/49e0f911-1d6b-c4c9-fb34-1befdcc9e0c9.png)

これでインストールができるようになるはずです。
(できない場合は他の方に聞いてください)

#参考リンク
https://github.com/tensorflow/tensorflow/issues/24886
https://blog.beachside.dev/entry/2017/07/25/183000
Flutterアップデート際にExpand-Archiveのエラーが発生Dartアップデートが失敗する件

##環境
- Windows 10 (1809)
- Flutter   
 - Flutter 1.5.4-hotfix.2 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 7a4c33425d (5 weeks ago) • 2019-04-29 11:05:24 -0700
Engine • revision 52c7a1e849
Tools • Dart 2.3.0 (build 2.3.0-dev.0.5 a1668566e5)

##事象
- Flutterのアップグレード際に下記のようなエラーメッセージが生じました。

```text
Expand-Archive : パラメーター名 'DestinationPath' に一致するパラメーターが見つか
りません。
発生場所 C:\flutter\bin\internal\update_dart_sdk.ps1:77 文字:32
+     Expand-Archive $dartSdkZip -DestinationPath $cachePath
+                                ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Expand-Archive]、ParentContai
    nsErrorRecordException
    + FullyQualifiedErrorId : NamedParameterNotFound,Pscx.Commands.IO.Compressio
   n.ExpandArchiveCommand

Error: Unable to update Dart SDK. Retrying...

3 秒待っています。終了するには CTRL+C を押してください ...
```
##対策
- 「update_dart_sdk.ps1」を開いて、編集します。

```text
#Expand-Archive $dartSdkZip -DestinationPath $cachePath
#Flutterのキャッシュフォルダに移動する
 Push-Location -Path $cachePath 
#Dart-sdkのZipファイルを解凍する
 Expand-Archive $dartSdkZip
```
Android StudioでOpenCVを使う

# はじめに

AndroidStudioでOpenCVを導入する方法についてのメモです。
qiitaにもいくつか投稿がありますが、AndroidStudioのバージョンやOpenCVのバージョン等によって、
微妙に皆設定が違うようなので、ここでは自分が行った設定についてメモしておきます。

# 動作確認環境

* Windows 10 64bit
* Android Studio 3.4.1 (update前の3.2.1でも動作確認済） 
* OpenCV 4.1.0

Android Stduioはインストール済みであることが前提。

# OpenCVのダウンロード

下記どちらからでもダウンロード可。Android版を選択。

* https://github.com/opencv/opencv/releases
* https://opencv.org/releases/

ダウンロード後は解凍して、適当なところに配備。後でAndroid StudioからImport。

# 新規プロジェクトの作成

* メニューバーから File -> New -> New Project -> Empty Activity 
* Name, Packag name等は適宜設定。Languageは「Java」、Minimum API levelは「28」 にしました
    * ただ、28だと新しすぎるので、もう少し下げても良いかも。ちなみに15だと低すぎてエラー発生。
* Finishボタンを押したら、Buildが実行されしばらく待ちます
* Android端末をUSBでPCに接続して、右上の▶か、メニューバーからRun->Runを実行すると「Hello World」が表示されることを確認

# OpenCVの取り込み

* メニューバーから File -> New -> Import Module
* Source directoryには、上記で解凍したzipのパスからsdkフォルダを指定
* Module nameには、適宜わかりやすい名前をつける。ここでは「opencv」  
    (デフォルトでは「:sdk」になっているので、何のsdkか分かりづらい）


![opencv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92328/7204aae4-2b5c-1708-7987-2cc67d13ec28.png)

* Finishボタンを押す
* index構築でしばらく時間がかかるので終わるのを待つ

# モジュールの依存関係設定

* メニューバーから File -> Project Structure を選択
* 左側のメニューから Dependencies -> app 選択  (Android Studio 3.4.1では3.2系とUIが違った）
* 右上の + アイコンをクリックして 3: Module dependency を選択

![OpenCV_module_dependencies.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92328/52e8efe6-04c4-15ff-ec92-f44c3a68282e.png)

* 上記で設定したModule name (opencv)を選択してOK

![OpenCV_module_dependencies2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92328/61054ca7-f763-f326-026a-25bdb4559517.png)

* OKした後はこんな感じに追加される

![OpenCV_module_dependencies3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92328/ad9779ca-c7a3-3597-616a-6782dd33d7b0.png)


# その他の設定

OpenCVのバージョン3以下(?)で必要だったらしい下記対応はやらなくても動作

* jniLibsへのsoライブラリのコピー
* build.gradleのsdkのバージョン変更

 

# 動作確認

画面にOpenCVのバージョンを表示するサンプル

* 個人的にLinearLayoutが好きなので、そこにTextView追加

```xml:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

```
     
```java:MainActivity.java
package com.example.myopencv;  // ★適宜自分のパッケージ名に変更

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

import org.opencv.android.OpenCVLoader;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView textView = findViewById(R.id.text1); 
        textView.setText(OpenCVLoader.OPENCV_VERSION);  // ★OpenCVのバージョンを設定
    }
}

```

* 今回は4.1.0を入れたので、画面には4.1.0が表示

---
さて、これからOpenCVをどう試すかな…
chromeの検証ツールから自動で入力項目を埋める

検証が思った以上に長引いてめんどいので作ったからメモ
jqueryを使って入力項目を埋める。
何回も新規登録でユーザを作成したりするときには便利かと。

使い方(chrome前提)は下記を自分のhtmlに合わせて修正し、検証のコンソールで実行。

入力項目
`$('input[name="name"]').val('名前だぞ');`
セレクトボックス
`$('select[name="establish_month"]').val(2);`
テキストエリア
`$('textarea[name="comment"]').val('コメントだぞ');`
チェックボックス
`$('input[name="agree"]').prop('checked', true);`
ラジオボタン
`$('input[name="xxxxxx"]:eq(1)').prop('checked', true);`


↑はnameを使ってますが、idを使って項目を指定する場合は
`$('input[name="name"]')→$("#ID名")`
になります。

その他はまたあったらここに追記していきます。
PHP7.3にimagick導入 簡単yumだけ

https://qiita.com/maimai-swap/items/6523e5ae9fd8414b29d8

それyumでできるよ！

imagickはバージョンで死ぬパターンあるらしいから事前に確認

```
yum install --disablerepo=* --enablerepo=remi,remi-php73 php-pecl-imagick

エラー: パッケージ: ImageMagick6-libs-6.9.10.48-1.el7.remi.x86_64 (remi)
```

```
yum install --enablerepo=remi,remi-php73 ImageMagick6-6.9.10.48

yum install --disablerepo=* --enablerepo=remi,remi-php73 php-imagick
```

世界はyumが支配した
Raspberry Pi と Docker でベクトルタイルのデモ・教育環境を作りたい

```
 _   _ _   _  __     __        _             
| | | | \ | | \ \   / /__  ___| |_ ___  _ __ 
| | | |  \| |  \ \ / / _ \/ __| __/ _ \| '__|
| |_| | |\  |   \ V /  __/ (__| || (_) | |   
 \___/|_| \_|    \_/ \___|\___|\__\___/|_|   
                                             
 _____ _ _        _____           _ _    _ _   
|_   _(_) | ___  |_   _|__   ___ | | | _(_) |_ 
  | | | | |/ _ \   | |/ _ \ / _ \| | |/ / | __|
  | | | | |  __/   | | (_) | (_) | |   <| | |_ 
  |_| |_|_|\___|   |_|\___/ \___/|_|_|\_\_|\__|

       Make the technology the easy part.
```

<img alt="クロスプロットフォームで国連ベクトルタイルツールキットを動かす" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102082/298dfeb4-7f74-d440-651c-94644bcb8476.png">
上図は、クロスプロットフォームで国連ベクトルタイルツールキットを動かすために Docker を活用している様子のイメージです。

# きっかけ
[国連ベクトルタイルツールキット](https://github.com/un-vector-tile-toolkit)を開発から配備に移す段階で、エンタープライズな配備先では一部のコンポーネントの導入に苦労することがありました。

また、ベクトルタイルの技術は最初の取り付きが難しく、情報技術のスキルがないとなかなか取り付きづらいのが実情です。

これらの課題への対応のため、Docker の使用を検討してきましたが、そもそも Docker が満足な速度で動く環境を手に入れることもそれほど容易ではありません。

そこで、数十ドルで手に入る Linux 環境として Raspberry Pi を捉え、国連ベクトルタイルツールキットを Docker 経由で Raspberry Pi で動作させることを考えました。これが実現すれば、イメージをコピーした MicroSD カードを配るだけで、国連ベクトルタイルツールキットのデモ環境および教育環境を提供できるようになるかもしれません。

# とりあえず試してみたこと
私は最近 Raspberry Pi 3 Model B+ を入手し、Raspbian を導入しました。

## Docker のインストール
docker と docker-compose を導入しました。当面、docker-compose を使うことはないと思いますが、将来にむけて念のため docker-compose も入れています。この作業については、@Aruneko さんが [Raspberry PiでLet's EncryptなNginx Proxyを作ろう](https://qiita.com/Aruneko/items/0a6c0dd0fe1b8ede6cba) で紹介されている、次の方法を使っています。（ありがとうございます。）

```console
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo apt install docker-compose
```

あとは、 arm32v7/node:latest あたりをベースにして、国連ベクトルタイルツールキットを適宜導入して、なんらか具体的な例をみてもらいに行きたいと思います。

# 直面した課題
## 直面した課題
ということで、とりあえず [doria](https://github.com/un-vector-tile-toolkit/doria) に Dockerfile を作ってビルドを試してみたのですが、どうしても build 中に問題が起こって終了してしまいます。

どうやら、Node の @mapbox/vt-composite をインストールするにあたって、 C++ の mapbox/mason が x86 用の clang 関係のものを使ってしまってエラーになるようです。

私の C/C++ コンパイリングスキルだと、この辺りはたちどころに解決できなさそうです。

## 対応方針
ベクトルタイルをサーブするときに composite するのは、更新頻度が異なる複数のタイルセットについて、配信時に複合させるようにしたほうが合理的である場合があると判断したからですが、そこに拘泥せず、**まずはできるだけシンプルなベクトルタイルサーバが、Raspberry Pi の上の Docker で動作することを実証する** ことを優先するべきだと考えました。

# koxinga の開発開始
ということで、doria をさらに単純化して、タイルセットの composite を行わないベクトルタイルサーバのバージョンを作ってみることにします。

このプロジェクトには koxinga という名前を割り当て、とりあえず[レポジトリ](https://github.com/un-vector-tile-toolkit/koxinga)と[ドキュメント](https://hackmd.io/@hfu/koxinga)の作成を開始しました。
画像の遅延ロードするときはbackground-imageも遅延ロードさせる

# 画像の遅延ロードするときはbackground-imageも遅延ロードさせる
Webページの速度改善において、画像を必要になってからダウンロードさせる遅延ロードは定石です。
[PageSpeedInsights](https://developers.google.com/speed/pagespeed/insights/)辺りでもしつこく指摘される点です。
各種フレームワークでプラグインなどの形で公開されているので、とりあえず入れているという方も多いかと思います。

しかし、この時``<img>``タグ部分しか遅延ロードさせないと意味がなかったり、逆効果になってしまう場合があります。

## CSSで指定するbackground-imageにも注意する
画像は``<img>``タグ以外にも、CSSのbackground-imageでもダウンロードされます。
これが指定された状態で、``<img>``タグ側に遅延ロードをかけると、
全てのbackground-imageで指定された画像がダウンロードされてから、
遅延ロード対象となった画像がダウンロードされることになります。

画面の下の方の背景画像のロードを待ってから、画面上部の通常の画像が表示されることになってしまうので、
通常の画像に遅延ロードをかけた意味がなくなってしまいます。

## 対策
単純に、背景画像も含めて遅延ロードさせれば解決します。

プラグインやフレームワークを選ぶ際には、背景画像の遅延ロードにも対応しているか気を配りましょう。
AWS の ALBでHTTPS化してEC2ではHTTPでWordpressを動かすときの設定

# AWS KUSANAGI
AWSにKUSANAGIパッケージがあるのでそれをインストールします。
https://kusanagi.tokyo/cloud/kusanagi-for-aws/

## KUSANAGIをHTTPで動かす（HTTPSにしない）
KUSANAGIのインストールで、

```
kusanagi init
```
したときに問い合わせでメールアドレスを、、、と聞かれたときに、メールアドレスを入力するとLet's EncryptでSSLが勝手に導入されてしまうので、メールアドレスを入力しないでEnterを２回入れればSSL設定を回避し、HTTPで起動できるようになります。


## ALB(Application Load Balancer)でHTTPS化
AWSでロードバランサを設定してそこに証明書を発行します。ロードバランサを使う場合は、証明書の費用はかかりません。
HTTPSをリッスンしてHTTPで動作しているEC2インスタンスに転送する感じで設定です。
HTTPも通しておかないとデフォルトでWordpressがhttpアクセスを強制しますので。忘れずに。

（暇があったらもっと詳しく書きます）


## Wordpressのリダイレクトループ

はい、これでOKとおもいきや、
管理画面に入って、wordpressの設定で、httpをhttpsにすると
リダイレクトループが発生して開けません。

.htaccessが邪魔してるので、通してあげます。

２行追加

```config:.htaccess
RewriteCond %{HTTP:X-Forwarded-Proto} !=https
RewriteRule ^/?(.*) https://%{HTTP_HOST}/$1 [R,L]
```

これで通常ページは見えるようになりますが、こんどは管理画面にも入れない。。。
HTTPSにしてるのにサーバーそのものはHTTPで動作してるので、HTTPSにリダイレクトしようとしてくれてますので、PHP設定で、嘘をついてあげます。$_SERVERや$_ENVでHTTPS通信してるよって。これをwordpressが参照してリダイレクトしようとするみたいなので。
これで管理画面にも入れるようになってよかったよかった。

```php:wp-config.php
$_SERVER['HTTPS'] = 'on';
$_ENV['HTTPS'] = 'on';
```


### ついでに、WordpressをFTP情報入れなくても直接アップデートやプラグインのインストールできるようになる設定をメモ

```php:wp-config.php
define('FS_METHOD', 'direct'); 
#define('FS_METHOD', 'ftpsockets');
#define('FTP_HOST', 'localhost');
#define('FTP_USER', 'kusanagi');
```

以上
PlayFab の サポートが変わりました！！

PlayFabのサポートに関して更新されたので翻訳してみました
原文は[こちら](https://blog.playfab.com/blog/playfab-support-overview)

### 概要
今までFormsで質疑応答だけではなく、ちゃんとサポートチームの方で対応するようになりましたよ
という話
Microsoftのサポートチームで対応できるようになったので、よりスピーディーにワールドワイドな対応が可能となりました
(ただしProfessionalプラン利用の必要あり)

### 問い合わせのやり方
ゲームマネージャ(PlayFabの管理画面)の「ヘルプ」→「問題を報告する」
から依頼することが可能
(私はEssentialなのでフォームがでてきませんが・・・)
![Playfab-help_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/7479fa25-bea7-7ac8-dc5c-2fb72d236418.png)

問い合わせはチケットとして管理され、今後問い合わせの履歴も見れるようにしていく予定とのこと

**一般サポート**
公式サイトのドキュメントとコミュニティのフォーラムがこれにあたります。
PlayFabとしては1営業日以内にすべての質問に回答できる体制をとることです
コミュニティフォーラムも活性化させるためにサポートも増員し、バグや新機能の提案などができる場所として維持していきます
またSlackも維持しPlayFabをどのように利用していくかを話し合える場としてこちらも維持していきます。
ただこれが正式なサポート要請の方法ではない点に関しては注意が必要

**技術以外のサポート**
ログインができない、請求書に関してなど技術的な質問でない場合は、[こちら](https://playfab.com/support/contact/)
技術的な質問をこちらに投げても無視されるそうなので注意です

**エンタープライズサポート**
エンタープライズ向けは今までと特に変わっておらず、ゲームマネージャからのチケット発行とSlackもしくはTeamsのプライベートチャンネルによる個別対応で引き続き行われます

**メールによるサポートは？**
ゲームマネージャ内のサポートチケット発行システムへの変更に伴いメールでの問い合わせサポートは廃止の予定です。
メールサポートのリンクは徐々に削除され、新しいサポートへのメールは自動返信が返ってくるようになります


有料・無料サポートとの明確な線引きと有料側の質の向上が行われているということのようです
pythonのインタプリタでカーソルが効かなくなった

## python2.7系でカーソルが効かなくなった

上を押しても変な文字が表示され、直前に実行されたコマンドが表示されなかった。

## 原因

いろいろ調べていると、readlineがエラーが出て読み込めていないのが原因の方が多かった。
実際に自分の環境で打ったコマンド結果

```
>>> import readline
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dlopen(/Users/xxx/Documents/env/lib/python2.7/lib-dynload/readline.so, 2): Library not loaded: /usr/local/opt/readline/lib/libreadline.7.dylib
  Referenced from: /Users/xxx/Documents/env/lib/python2.7/lib-dynload/readline.so
  Reason: image not found
```

## 対処
readline8があったが、readline7のほうの参照先がなかったのでそこにシンボリックリンクした。

```
ln -s /usr/local/opt/readline/lib/libreadline.dylib /usr/local/opt/readline/lib/libreadline.7.dylib
```

エラーは起きなくなった
カーソルも効くようになった。

```
>>> import readline
>>>
```
UITableViewやUICollectionViewをスクロールで閉じる

TableViewやCollectionViewでスクロールで一番上までいってたら（contentOffset.yがマイナスだったら）閉じたい場合がたまにある。
PanGestureを使って細やかにハンドリングした方が手触り感としては良くできるのだが若干手間ではある。
この方法だととてもシンプルに実装できたのでメモ。


```swift
// テーブルビュー

import UIKit

class TableViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    var dataSource: UITableViewDataSource!

    override func viewDidLoad() {
        super.viewDidLoad()
        configure()
    }

    func configure() {
        dataSource = UITableViewDataSource()
        tableView.dataSource = dataSource
        tableView.delegate = self
    }

}


extension TableViewController: UITableViewDelegate {
}

extension TableViewController: UIScrollViewDelegate {

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let contentOffsetY = scrollView.contentOffset.y + view.safeAreaInsets.top // StatusBar, NavigationBarの高さを足してオフセットを0に
        let threshold: CGFloat = -60.0 // どの程度マイナス方向にスクロールしたらdismissするか
        if contentOffsetY < threshold {
            dismiss(animated: true, completion: nil)
        }
    }

}
```


```swift
// コレクションビュー

import UIKit

class CollectionViewController: UIViewController {

    @IBOutlet weak var collectionView: UICollectionView!
    var dataSource: UICollectionViewDataSource!

    override func viewDidLoad() {
        super.viewDidLoad()
        configure()
    }

    func configure() {
        dataSource = UICollectionViewDataSource()
        collectionView.dataSource = dataSource
        collectionView.delegate = self
    }

}


extension CollectionViewController: UICollectionViewDelegate {
}

extension CollectionViewController: UIScrollViewDelegate {

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let contentOffsetY = scrollView.contentOffset.y + view.safeAreaInsets.top // StatusBar, NavigationBarの高さを足してオフセットを0に
        let threshold: CGFloat = -60.0 // どの程度マイナス方向にスクロールしたらdismissするか
        if contentOffsetY < threshold {
            dismiss(animated: true, completion: nil)
        }
    }

}
```
Ubuntuでキーボードがus配列に変わってしまう問題を解決

# 全てはDefaultが悪かった

Ubuntuにログインする度に何故か日本語入力ができなくなる今日この頃。

原因は何なのか？と色々調べていたら、遂に原因が判明。

mozc.xmlのキーボードレイアウトがDefaultだったのだ！！！

# 解決策
以下のコマンドを実行する

`sudo vim /usr/share/ibus/component/mozc.xml`

```
<component>
  <version>2.20.2673.102+dfsg-2</version>
  <name>com.google.IBus.Mozc</name>
  <license>New BSD</license>
  <exec>/usr/lib/ibus-mozc/ibus-engine-mozc --ibus</exec>
  <textdomain>ibus-mozc</textdomain>
  <author>Google Inc.</author>
  <homepage>https://github.com/google/mozc</homepage>
  <description>Mozc Component</description>
<engines>
<engine>
  <description>Mozc (Japanese Input Method)</description>
  <language>ja</language>
  <symbol>&#x3042;</symbol>
  <rank>80</rank>
  <icon_prop_key>InputMode</icon_prop_key>
  <icon>/usr/share/ibus-mozc/product_icon.png</icon>
  <setup>/usr/lib/mozc/mozc_tool --mode=config_dialog</setup>
  <layout>default</layout>
  <name>mozc-jp</name>
  <longname>Mozc</longname>
</engine>
</engines>
</component>
```

下から6行目に存在する

`<layout>default</layout>`

を

`<layout>jp</layout>`

に修正する！！！以上！！！




# 参考文献
[Ubuntu 18.04 LTSでibus-mozcのキーボード配列が日本語にならない問題と解決方法](https://medium.com/@mshr_h/ubuntu-18-04-lts%E3%81%A7ibus-mozc%E3%81%AE%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E9%85%8D%E5%88%97%E3%81%8C%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%AB%E3%81%AA%E3%82%89%E3%81%AA%E3%81%84%E5%95%8F%E9%A1%8C%E3%81%A8%E8%A7%A3%E6%B1%BA%E6%96%B9%E6%B3%95-a66ed8de21bb)
Windows版Excelの数式バーから、見づらいビットマップフォントを駆逐する。その方法

# 概要

Excelの初期状態では、数式バーのフォントが「ＭＳ Ｐゴシック」であり、数式バーの表示に埋め込みビットマップフォントが使われてしまう。ClearTypeが市民権を得た現在のWindowsにおいて、ビットマップフォントが出現すると強い違和感がある。そのため、Excelの数式バーのフォントを別のフォントに変更する。

# 手順

1. メニューバーから「ファイル」 -「オプション」を選択し、「Excelのオプション」ウィンドウを開く
2. 「基本設定」タブの「新しいブックの作成時」セクションにある、「次を既定フォントとして使用」のフォントを変更する
3. Excelを再起動する

# Tips

* 「Excelのオプション」ウィンドウは、アクティブなExcel上で[Alt+f]→[t]とキーを押していけば、マウスを使うことなく開くことができる
* 自分が編集したExcelファイルを他の人が開くことを考えた場合、互換性を考え、既定フォントは以下のいずれかから選ぶことが望ましい
  * 游ゴシック
  * メイリオ
HTTPでリクエスト受けてコマンド実行->レスポンスで結果を返す

[こちらの記事](https://qiita.com/mjusui/items/bce4566ffdb54ba7039a)で紹介したツールの機能紹介です


普段ドキュメントはいっさい信用しない(実機に勝る情報ソースはない、ゆえにドキュメント作成もしない)インフラエンジニアの私ですが、よくプログラマの方から、インフラの設定がどうなっているか、ログがどこにあるかなどの質問を受け、その都度サーバにログインして確認したりしています

何度も使うようなコマンドはコード化して、個人用のリポジトリで管理しているのですが、もう聞かれるたびにコマンド一発打つのさえ面倒になってきて**「HTTPでリクエスト受けてコマンド実行->レスポンスで結果を返す」**みたいなことできないかと考えて機能を実装してみました


```endpoint.js
const Submarine = require('Submarine');

const Tutrial = class extends Submarine {
  query(){
    return {
      hostname: 'hostname -s',
      ip_addrs: String.raw`
        ip -o -f inet a \
          |awk '{print $4}'
      `,
      logs: String.raw`
        ls -lha /var/log/syslog* \
          | head -30
      `,
      tail: String.raw`
        sudo tail -6 /var/log/syslog
      `
    };
  }


}


const tut=new Tutrial({
  conn: 'ssh',
  host: server,
});

const endpoint=tut.communicate({
  pathname: '/logs/syslog'
});
```

こんな感じで定義しておいて

```
$ curl localhost:30117/logs/syslog
```

で`query`の戻り値に定義した4つのコマンドの実行結果をJSON形式で取得できます。コマンド結果が複数行にわたるときは、結果は配列で返されます。他のクラスを`new`して`communicate`関数に別の`pathname`を渡して呼び出せば、複数のエンドポイントを作ることもできます。

ここでは私の検証環境にあわせて`syslog`の情報を取得していますが、なんのログでもステータスでも、こうして公開しておけば「好きなときに勝手にたたいてね」と言うことができます


ログくらいいくらでもツールあるんだからブラウザで見られるようにしとけよ、と思うんですが、本格的にログ基盤を作るとなると結構な時間もコストもかかってしまうので、ありもので済ませようということで
成長する人ってどんな人？

#成長する人ってどんな人？
成長って自分で認識することが難しいですがどのようにお考えでしょうか？
それを考えるべく、まず新入社員として入社される方の心理状態を共有します。

##新人が質問する心理状態に関して考える
新人は何でこの作業が必要なのか等々無限に質問があります。
故に『この先輩にきいていいのかな？』とはどの新人でも感じる事でしょう。

精神が強く抵抗のない方であれば勝手に質問してくるかもしれませんが、大抵は質問する事に不安を感じる方が多いので気遣ってあげましょう。

それ故新人だけではなく上司も重要であると考えますが、成長が早くなるだろうなと感じる方の特徴は下記3点かと思います。

##①質問量が多い
新人の時は質問する事自体ハードルが高いものだと思います。
そこで、自分自身でどんどん疑問点を見つけて質問することは非常によい事だと考えます。（上司が聞きやすい状況を作るのも大事ですが。。）

アウトプットが多いと理解が深くなってきている証拠ですので、どんどん学んだことはアウトプットする習慣を新人、上司でつくりましょう。

##②気遣いが出来るコミュニケーション
ビジネスマナーがわからない、敬語が不安…という方は多いと思います。
これは、本やWeb上の情報をいくら収集しても、知識だけでは正直まかなえません。
知識があっても、今までの習慣やコミュニケーションのクセはふとしたときに出てしまうものです。

そのため、自分が考える10倍丁寧にコミュニケーション行い、
気遣いをする習慣をクセ付けしていくことが必要になります。

例えばですが。
・さんか様で迷ったら様で呼んでおく
・質問をするときはどんなにヒマそうでも必ず「今お時間よろしいですか？」と聞く
・お礼/謝罪を必ずする

など。実践したり周りの方を見習って必要だと感じる事はパクりましょう！

##③マメにメモをする
どんなことでもそうですが、自分が教えている時うなずきながら
メモをとってもらっている姿を見ると嬉しいですよね＾＾

ただ、そのままメモを取っても仕方ないので『単語としてわからないこと』や『気づき』をメモとして取ってググるなり後で聞くなりした方が効率的です。

以上、自分も当時出来ていなく、今だから言えるような内容になっています。
シンプルですが中々難しいと思いますが、気づきが1つでもあれば嬉しいです！
スライス

##スライス
```go
func main() {
	n := []int{1, 2, 3, 4, 5, 6}
	fmt.Println(n)      //[1 2 3 4 5 6]
	fmt.Println(n[2])   //3
	fmt.Println(n[2:4]) //[3 4]
	fmt.Println(n[2:])  //[3 4 5 6]
	fmt.Println(n[:2])  //[1 2]
	fmt.Println(n[2:3]) //[3]
	fmt.Println(n[:])   //[1 2 3 4 5 6]

	n[2] = 1234
	fmt.Println(n) //[1 2 1234 4 5 6]

	//入れ子構造(スライスの中にスライス)
	var board = [][]int{
		[]int{0, 1, 2},
		[]int{3, 4, 5},
		[]int{6, 7, 8},
	}
	fmt.Println(board) //[[0 1 2] [3 4 5] [6 7 8]]

	n = append(n, 100, 200, 300, 400)
	fmt.Println(n) //[1 2 1234 4 5 6 100 200 300 400]
}
```
##スライスのmakeとcap

```go
func main() {
	n := make([]int, 3, 5)
	fmt.Printf("len=%d cap=%d value=%v\n", len(n), cap(n), n) //len=3 cap=5 value=[0 0 0]
	n = append(n, 0, 0)
	fmt.Printf("len=%d cap=%d value=%v\n", len(n), cap(n), n) //len=5 cap=5 value=[0 0 0 0 0]
	n = append(n, 1, 2, 3, 4, 5)
	fmt.Printf("len=%d cap=%d value=%v\n", len(n), cap(n), n) //len=11 cap=12 value=[0 0 0 0 0 1 2 3 4 5]

	a := make([]int, 3)                                        //引数1つだけとると長さとキャパシティが3
	fmt.Printf("leng=%d cap=%d value=%v\n", len(a), cap(a), a) //leng=3 cap=3 value=[0 0 0]

	b := make([]int, 0)                                       //0のスライスをメモリに確保
	var c []int                                               //メモリ確保しないnil
	fmt.Printf("len=%d cap=%d value=%v\n", len(b), cap(b), b) //len=0 cap=0 value=[]
	fmt.Printf("len=%d cap=%d value=%v\n", len(c), cap(c), c) //len=0 cap=0 value=[]

	c = make([]int, 5)
	for i := 0; i < 5; i++ {
		c = append(c, i)
		fmt.Println(c)
	}
	fmt.Println(c)
	//結果
	// [0 0 0 0 0 0]
	// [0 0 0 0 0 0 1]
	// [0 0 0 0 0 0 1 2]
	// [0 0 0 0 0 0 1 2 3]
	// [0 0 0 0 0 0 1 2 3 4]
	// [0 0 0 0 0 0 1 2 3 4]

	c = make([]int, 0, 5)
	for i := 0; i < 5; i++ {
		c = append(c, i)
		fmt.Println(c)
	}
	fmt.Println(c)
	//結果
	// [0]
	// [0 1]
	// [0 1 2]
	// [0 1 2 3]
	// [0 1 2 3 4]
	// [0 1 2 3 4]
}
```
Golangでゴルーチンを触ってみる　第二弾

###第一弾###
[第一弾](https://qiita.com/besood/items/450c39404ddec4b68936)
こちらはgoroutineをちょっとだけ触った記事

##登場人物##
+ **func goroutine1()**　　前の記事に仲間外れにされた人物
+ __func goroutine2()__　　なぜか悪者にされた人物
+ __func main()__　　　　　こいつが本当の悪者
+ __var wg := ??__　　　　　今回の主役

```golang:goroutine.go
package main

import (
	"time"
	"fmt"
	"sync"
)

func goroutine1(wg *sync.WaitGroup){
	for i:=0;i<5;i++ {
		time.Sleep(100*time.Millisecond);
		fmt.Println("goroutine");
	}
	wg.Done()
}

func goroutine2(){
	for i:=0;i<5;i++ {
		time.Sleep(time.Millisecond);
		fmt.Println("now");
	}
}

func main(){
	var wg sync.WaitGroup
	wg.Add(1)
	go goroutine1(&wg);
	goroutine2();
	wg.Wait()
}
```
今日の主役　**sync.WaitGroup** さんです
彼が２つのfuncの間を取り持ってくれます。
ここだけの話*sync*って同期って意味らしいですよ・・・

###解説？###


+ wgを**WaitGroupというstruct**で宣言します。
+ wg.Add()にブロックするgoroutineの数を指定します。
+ それをgoroutine1に投げ飛ばします。
+ すると・・・**wg.Wait()**が早く**wg.Done()**かえってこねぇかなーと
  mainでずっと待っててくれます。
+ **func goroutine1**のループが終わると
+ **wg.Done()**が返ってくるので終了ということになります。


###次回予告###
未定　　たぶんchannel


**最初にdefer wg.Done()でもいいのかなって思った**
Junitでカバレッジを取得する

今回はJunitでカバレッジを取得する方法を書き連ねていきます。
とはいってもEclEmmaを導入するだけです。

1.まずはeclipseを起動し、「ヘルプ」→「Eclipseマーケットプレース」を選択します。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/7b7f79ec-a54e-5461-b1bb-62a29defff26.png)

2.Eclipseマーケットプレースのウィンドウが開くので、検索欄にEclEmmaと入力し、「Go」ボタンを押下してください。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/3bcf3154-6f65-21dd-2606-bf371a972e23.png)

3.検索結果にEclEmmaが表示されるので、「インストール」ボタンを押下してインストールします。
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/9d79e223-bd2a-0fee-89c6-4b0ceeeece6b.png)

4.利用規約が出てくるので、内容を確認して同意のラジオボタンを選択し、「完了」ボタンを押下してください。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/ef408625-30e1-bc20-e52d-bdc5d851dca2.png)

5.インストールが完了すると、再起動するかどうか尋ねられるので「はい」を押下して再起動を実行してください。
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/1b3b80ba-86e3-5853-b91b-ceb3a21c77fc.png)

6.さっそく実行してみます。
テストクラスを右クリックすると「カバレッジ」という項目が追加されているので、「カバレッジ」→「Junitテスト」を選択してJunitを実行します。
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/6a61e57a-91f1-6708-f452-d9fcebb7f36c.png)

7.Junitの実行結果が表示されているのと同じ場所に新たに「カバレッジ」というタブが開かれます。
テスト対象クラスの何割が実行されたかが可視化されます。
![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/019631cd-eb8c-4307-9ba4-33969acdc9c3.png)

8.ちなみに、クラスの方もこんな感じで色が付きます。
![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306544/a1cfa562-2553-5a8d-06f0-5a1d000395c6.png)
よい見積もりと計画づくりとは


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257568/37d61c35-e123-b1ff-7526-6489328aa884.png)

こちらを読んで

## 目的
見積もりと計画づくりの重要性を理解するため

## 見積もりとは
作業の**規模の大きさ**

見積もった時間内に作業が完了する確率のこと

## 計画づくりとは
計画をつくる**プロセス**、活動

- 計画ではない

- 計画とは
  - ドキュメントや図表であり、**ある時点のスナップショットを記録したもの**

### 計画づくりの問題
チームやステークホルダーが**コミットメントと捉えてしまうこと**

- バラ色のロードマップで何もリリースできない
- 不確実性を踏まえていないものは計画ではない
- **プロジェクトがアジャイルであるのに、見積もりと計画づくりがアジャイルでないのはありえない**

### 短絡的な間違い
アジャイルだから計画しない

## やること
- ストーリーカードを書く
- 優先順位をつける
- どのリリースに含めるか決める
- イテレーション計画づくりで必要なだけ詳細化する

## なぜ見積もりや計画づくりが必要なのか ?
大別すると2つ

- 期日やスケジュールを決めるため
- 「なにをつくるべきか ?」への問いに答えるため

### ポイント
- インクリメンタル
  - 答えをゴールへと少しずつ近づけていくこと
- イテレーティブ
  - 繰り返すこと 

## よい見積もりと計画づくりとは
5つの特徴を持ったプロセスのこと

- リスクを軽減する
- 不確実性を減らす
- 意思決定を支援する
- 信頼を確立する
- 情報を伝達する

### リスクを軽減する
リスクによって**取り止めではなく、許容範囲内に収められる幅をもたせられる見積もりが存在する**こと

### 不確実性を減らす
作る**プロダクトそのものを間違えない**ような仕組みであること

最初に立てた計画は不確実であることを前提とし、過程で得たプロダクトとプロジェクトに関する新しく得た知識をもとに、計画に反映可能なこと

### 意思決定を支援する
**見積もり**と**計画**があること

見積もりと計画がないのに意思決定をしないこと

### 信頼を確立する
フィーチャーを安定して頻繁に提供し続けること

フィーチャーの優先順位やトレードオフの**意思決定をするために見積もりが存在する**こと

- フィーチャーとは
  - 機能や特徴、性能、見た目などの「売り文句」の総称
  - ざっくりレベルの機能

### 情報を伝達する
計画が期待と**可能性を伝えるもの**であること

期間だけになっていないこと

## 書籍情報
Mike Cohn (著), 安井 力  (翻訳), 角谷 信太郎  (翻訳)
アジャイルな見積りと計画づくり ～価値あるソフトウェアを育てる概念と技法
https://amzn.to/30CRfjU

## 雑感
具体的な手法と合わせて考え方のポイントを押さえる
Jetson NanoでFCNを使ったセマンティックセグメンテーション

# はじめに

VGG16による画像識別で対象物を分離することが重要であることが分かった。そこでJetson Nano上でセマンティックセグメンテーションを実験してみる。

# FCNとは

Fully Convolutional Networksの略でセマンティックセグメンテーションと呼ばれる画像内の意味のある物体を画素単位で分割する技術の一つ。論文は下記。

https://arxiv.org/abs/1411.4038

VGG16等の画像識別では(畳み込み層 + プーリング層) x N個 + 全結合層という形を取っているが、最後の全結合の部分まで畳み込み層になっている。なるほど、Fullyとは全結合を表すFullyではなく、下まで全部畳み込みということか。これを行うことで効率的にヒートマップが作れるとのこと。

# 方針

きっと誰かがソースコードを書いているに違いないということで、chainer + FCNのキーワードで見つけたgithubのソースコードを用いる。今回用いるのは下記のソースコード。論文を読むだけでは詳細実装が良く分からないことがあるが、ソースコードがあると理解の進みが早くなる。本当にありがたい。

- https://github.com/wkentaro/fcn


# 準備

基本的なセットアップは「[Jetson Nanoの実験環境のまとめ](https://qiita.com/yamamo-to/items/fc8b91062cb4e115c600)」に従っている。
~/Documents/FCNというディレクトリ以下で作業を行う。

```bash:ターミナル
yamamo-to@jetson-nano:~$ mkdir ~/Documents/FCN
yamamo-to@jetson-nano:~$ cd ~/Documents/FCN
yamamo-to@jetson-nano:~/Documents/FCN$ pipenv --three
```

demoを動かすために`scikit-image`が必要になるため必要なパッケージをインストールする。

```bash:ターミナル
yamamo-to@jetson-nano:~/Documents/FCN$ sudo apt install libfreetype6-dev libblas-dev liblapack-dev libatlas-base-dev gfortran
```

下記のPipfileを~/Documents/FCN以下に置く。

```:Pipfile
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
cupy = "*"
chainer = "*"
chainercv = "*"
matplotlib = "*"
numpy = "*"
scipy = "*"
scikit-learn = "*"
scikit-image = "*"
gdown = "*"
tqdm = "*"
pandas = "*"
PyYAML = "*"
cython = "*"

[requires]
python_version = "3.6"
```

必要なパッケージをインストールする。以下のコマンドは時間が掛かるので寝る前に実施するのが吉。

```bash:ターミナル
yamamo-to@jetson-nano:~/Documents/FCN$ pipenv install
```

githubからソースコードをダウンロードしインストールする[^1]。

[^1]: pipenv install -r requirements.txtでインストールすると途中で失敗する。

```bash:ターミナル
yamamo-to@jetson-nano:~/Documents/FCN$ git clone https://github.com/wkentaro/fcn
yamamo-to@jetson-nano:~/Documents/FCN$ cd fcn
yamamo-to@jetson-nano:~/Documents/FCN$ pipenv install fcn
```

結果用のディレクトリを作成する。

```bash:ターミナル
yamamo-to@jetson-nano:~/Documents/FCN$ mkdir result
```

# FCNの実行

いつもの`boss.jpg`を入力に使う。実行すると重みをダウンロードし始める。それを除けば30秒ほどで終了する。

```bash:ターミナル
yamamo-to@jetson-nano:~/Documents/FCN/fcn$ pipenv run python3 ./scripts/fcn_infer.py --img-files boss.jpg --gpu 0 -o result
```

先ほど作成したresultディレクトリの中に`boss.jpg`というファイルができている。結果は下記の通り。

![boss_fcn.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252224/6e9bfda8-c6fe-85d5-f806-3a97b299e2b9.jpeg)

おぉ、確かに分離されている。これが4年前の技術か・・・。先は長い。

# 参考文献
- https://arxiv.org/abs/1411.4038
- https://github.com/wkentaro/fcn
- https://www.mathgram.xyz/entry/chainer/fcn
- http://seiya-kumada.blogspot.com/2016/03/fully-convolutional-networks-chainer.html
配列

##配列の基本

```go
func main() {
	var a [2]int
	a[0] = 100
	a[1] = 200
	fmt.Println(a)

	/*
	var b [2]int = [2]int{100, 200}
	b = append(b, 300) //appendで配列をリサイズできない
	fmt.Println(b)
	*/

	//スライス
	var c []int = []int{100, 200}
	c = append(c, 300)
	fmt.Println(c)
}
```

配列はリサイズできない。スライスはできる。

>【参考】
現役シリコンバレーエンジニアが教えるGo入門(https://www.udemy.com/share/100BhMB0obeFpbTX4=/)
【Swift】TableViewControllerの基本


#必ず必要になる3つのデリゲートメソッド

####セクションの数を決める

```.swift
override func numberOfSections(in tableView: UITableView) -> Int {
 
        return 1
}
```

####1つのセクションあたりのセルの数を決める

```.swift
override func tableView(_ tableView: UITableView, numberOfRowsInSection 
section: Int) -> Int {
       return 1
}
```

#### セルを作る

```.swift
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

     // Configure the cell…

    return cell
}
```


## セルがタップされたときに勝手に呼ばれるメソッド

```.swift
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    
        //pushで画面遷移
    self.navigationController!.pushViewController(self.storyboard!.
    instantiateViewController(withIdentifier: "IDを自分で設定する") , animated: true)
}
```

##値を渡しながら画面遷移をする方法 

#### 画面遷移

```.swift
let 変数名: 画面遷移先の画面の名前 = self.storyboard?.instantiateViewController(withIdentifier: "StoryboardのID") as! 画面遷移先の画面の名前

変数名が持つ.変数 = 渡したいものが入った変数

self.navigationController?.pushViewController(画面遷移先の変数, animated: true)
 
```

#####当てはめてみる

```.swift
let viewController2: ViewController2 = self.storyboard?.instantiateViewController(withIdentifier: "next") as! ViewController2
        
viewController2.count = box

self.navigationController?.pushViewController(viewController2, animated: true)

```

## アプリ内にデータを保存する方法

#####考え方
- アプリ内にデータを保存することができる
- アプリを端末から消去しない限り半永久的に残り続ける
- 入力途中のものや､メモの保存などに役立つ
- 保存したデータは取り出す事ができる(以下2つが保存方法)
    - 保存する物に鍵(キー値)をつけて保存する
    - 鍵(キー値)の名前は自由につけてOK

####①UserDefaults(アプリ内)へ保存する

```.swift
UserDefaults.standard.set(保存したいもの, forKey: キー値(鍵))
```

####②保存されたものを取り出す方法
```.swift
if UserDefaults.standard.object(forKey:キー値) != nil{
            
            変数 = UserDefaults.standard.object(forKey:キー値) 
}
```

もし、キー値の中身が空でないなら、
箱の中にキー値で保存されているものを入れる。

##最後に
今回はTableViewControllerの基本についてまとめてみました｡
現在TableViewアプリを作成中で､データの受け渡しについて悩んだので､
同じ悩みを持ってる方々の参考になってくれれば嬉しいです｡

以上
ESP8266 RTC memoryを使う

RTC memory はESP8266 の真骨頂、DeepSleep Mode で値を保持してくれるメモリーです。
以前、[ESP8266 RTCMemory] (https://qiita.com/YumeYakata/items/c8db045c48dc3ebd0b24)を記載しましたが、ここではプログラムを紹介します。

「RTC Memoryは４バイトアライメント。でるあるから 128(=512/4) のアドレスで使うことができる。」とありますので、128 個のunsigned int のバッファーを準備します。

### loop で読み書きしてみる

RTC Memory を使うには、user_interface.hをinclude します。


```
/* ---------------------------------------- */
/* for DEBUG */
/* ---------------------------------------- */

#define USE_SERIAL Serial

#define _DEBUG 1
#if _DEBUG
#define DBG(...) { USE_SERIAL.print(__VA_ARGS__); }
#define DBGLED(...) { digitalWrite(__VA_ARGS__); }
#else
#define DBG(...)
#define DBGLED(...)
#endif /* _DBG */

/* ---------------------------------------- */
/* for RTC Memory */
/* ---------------------------------------- */
extern "C"{
    #include "user_interface.h"
}

#define RTCMEMORYSTART  64
#define RTCMEMORYLEN    128

unsigned int rtcBuffer[RTCMEMORYLEN]={0};

// setupでrtcBufferをクリアし、RTC memoryに書き込みます。

void setup() {
  USE_SERIAL.begin(9600);
  for(int i=0; i<RTCMEMORYLEN; i++) rtcBuffer[i]=0;
  system_rtc_mem_write(RTCMEMORYSTART,rtcBuffer,RTCMEMORYLEN*4);
}

// loop でRTC memory を読み出し、先頭rtcBuffer[0]と最後、rtcBuffer[RTCMEMORYLEN-1]を編集し、RTC memoryへ書き込みます。

void loop() {
  // put your main code here, to run repeatedly:
  system_rtc_mem_read(RTCMEMORYSTART,rtcBuffer,RTCMEMORYLEN*4);
  rtcBuffer[0]=rtcBuffer[0]+2;
  rtcBuffer[RTCMEMORYLEN-1]=rtcBuffer[RTCMEMORYLEN-1]+3;
  USE_SERIAL.println(String(rtcBuffer[0]) + ":" + String(rtcBuffer[RTCMEMORYLEN-1]));
  system_rtc_mem_write(RTCMEMORYSTART,rtcBuffer,RTCMEMORYLEN*4);
  delay(2000);
}

```
### Deep Sleep Modeで読み書きしてみる

下のプログラムはSetup の最後で、Deep Sleep Mode に入り、２秒後にリセットがかかります。
このプログラムを動作させるときはIO0 をHighにしておく必要があります。リセットがかかった時、IO0 をLowだと書き込みモードになってしまいます。

```
void setup() {
  USE_SERIAL.begin(9600);
  delay(100);
  
  system_rtc_mem_read(RTCMEMORYSTART,rtcBuffer,RTCMEMORYLEN*4);
  rtcBuffer[0]=rtcBuffer[0]+2;
  rtcBuffer[RTCMEMORYLEN-1]=rtcBuffer[RTCMEMORYLEN-1]+3;
  USE_SERIAL.println(String(rtcBuffer[0]) + ":" + String(rtcBuffer[RTCMEMORYLEN-1]));
  system_rtc_mem_write(RTCMEMORYSTART,rtcBuffer,RTCMEMORYLEN*4);

  ESP.deepSleep(2e6);   //2 Minitus
  delay(100);
}
```
[Git] rebaseとmergeってどう使い分ければいいの

##git rebase と git merge の違い
commitの履歴の残り方が異なる

###mergeの場合
commitの履歴を残せる

- 長所
    - コンフリクトの解消
- 短所　
    - 履歴が複雑になってしまう可能性がある

###rebaseの場合
commitの履歴が一直線になり履歴を綺麗に保つことができる([fast-forward](https://qiita.com/vsanna/items/451b42f886c599a16a55))

- 長所
    - コンフリクトの解消が大変
- 短所　
    - 履歴が綺麗に保てる



**◎rebaseで気をつけるべきこと**
 github等にpushしたコミットをrebaseしてはいけない
　　Lローカルとリモートの内容に矛盾が生じてしまうから




##git rebase と git merge どっちを使うべきか
###状況によって使い分ける
#####pushしていないローカルの変更の場合
→rebase
#####pushした場合
→merge
#####コンフリクトしそうな場合
→merge

##今後、付け加えたり修正していく予定
文献『Machine learning for embedded deep dive』を読む

#目的
表題の文献

Machine learning for embedded deep dive
　Presented By
　Andy Luo Sr. Product Marketing Manager 
　2018-10-0

は、
XILINX DEVELOPER FORUMのサイト
（ https://www.xilinx.com/products/design-tools/developer-forum/silicon-valley/access-content.html )
から、アクセス（ダウンロード）できる。

別の記事にも同じようなことを書いたが、
ディープラーニングのモデルの処理量を知りたい場合がある。
処理量としては、G-Ops等で示されているのが、扱いやすい。
処理量が記載された文書やサイトは沢山あるが、どれが、語弊のない数値が書かれているか、判断つかないときがある。
少し、情報を集めたいと考えました。

　:memo:まず、この文献は、沢山の情報があり、以下の方に役立つと思う。

　　　・ディープラーニングのモデルの処理量（GOPSなど）を知りたい人



#物体検出の処理量

下記の図より、物体検出の処理量が、まず、わかる。
（縦軸の条件が書かれていません、探しても、、、zu9とかでしょうか？）

(出典：　https://www.xilinx.com/content/dam/xilinx/imgs/developer-forum/2018-silicon-valley/Edge-Machine-Learning-for-Embedded-Deep-Dive.pdf　)

<img width="718" alt="gop_xilinx.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/3df16919-aced-26d0-0c2b-f818fb750eca.png">


グラフの数字を表にすると、以下のとおり。

|model|Gop|備考|
|:---:|:---:|:---:|
|Inception v1|3.2||
|Tiny Yolov3|5.6||
|Tiny Yolov2|7||
|ResNet50|7.7||
|VGG16|30||
|Yolov2|36||
|Yolov3|65||
|SSD|117||

prunedした場合の数値も示されている。


(出典：　https://www.xilinx.com/content/dam/xilinx/imgs/developer-forum/2018-silicon-valley/Edge-Machine-Learning-for-Embedded-Deep-Dive.pdf　)

<img width="714" alt="performance2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/4a4ddf1f-2c0a-f08b-4f48-548b617345bb.png">


#DPU Scalability
この情報も知りたかった。

(出典: )

<img width="715" alt="dpu.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/6df66684-8862-dd4d-410e-84a2d3dcb8b8.png">

#まとめ
この文献は、情報がよく集約されていると思う。

#関連（本人）

[DNNのモデル毎の処理量(GOP)をまとめる](https://qiita.com/enoughspacefor/items/83a9eac69f6209daf424)

[良書 「GPUを支える技術　超並列ハードウェアの快進撃[技術基礎]」を読む](https://qiita.com/enoughspacefor/items/31e9461b6a07b484b643)

[文献『From Model to FPGA: Software-Hardware Co-Design for Efficient Neural Network Acceleration』を読む](https://qiita.com/enoughspacefor/items/7de477dc3c1a50d36f2e)

[文献『AN ANALYSIS OF DEEP NEURAL NETWORK MODELS FOR PRACTICAL APPLICATIONS』を読む。](https://qiita.com/enoughspacefor/items/ea5a3225c6c54c469326)

#今後
適宜、情報を足します。
コメントなどあれば、お願いします。:candy:
Amazon Elasticsearch Service で kibana からのアクセスを制限したい

最近AWS入門しました。

## Elasticsearch Service 付属の Kibana を使うとPUTやらDELETEを制限できない？

AmazonさんのElasticsearchデフォルトでは色々と融通が効かないらしく、調べてもEC2に設定済み Kibana を乗っけるようなやつしか見つからなかった。

## セキュリティポリシーで制限できるのでは？

と、先輩にアドバイスをいただいた。
そして次のURLを投げてくださった。

https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/es-ac.html

基本的にこれを参考にした。

### 試行1: "es:ESHttpGet" のみ許可

ダメでござった。Discoverを見ようとした段階で読み込めない。
読み込める状態( `"es:ESHttp*"` )にしてChromeでネットワークを見てみると、POSTしてる先がいくつか。

```
/_plugin/kibana/elasticsearch/_msearch?rest_total_hits_as_int=true&ignore_throttled=true`
/_plugin/kibana/api/saved_objects/_bulk_get
```

つまりkibanaへのPOSTを通す必要がある思われるので、試行2へ。

### 試行2: `/_plugin/kibana/*` 以下だけ全メソッド許可したい


```json:効きません
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<id>:role/Cognito_myappmovieAuth_Role"
      },
      "Action": "es:ESHttp*",
      "Resource": "arn:aws:es:us-west-2:<id>:domain/movies/_plugin/*"
    },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<id>:role/Cognito_myappmovieAuth_Role"
      },
      "Action": "es:ESHttpGet",
      "Resource": "arn:aws:es:us-west-2:<id>:domain/movies/*"
    }
  ]
}
```

無理でござった。Discoverを読み込めない同じ症状。
https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/es-ac.html#es-ac-types-resource

↑これだとindexをリソースに指定することはできるようだけど、 `_plugin` とかいうただのパスはダメなのでしょうか。

いろいろムラムラしつつここで `"Effect": "Deny"` にたどり着く。
上のリンク先の少しスクロールしたところにめっちゃ普通に書いてあるやん。

### 試行3: 守りたい index

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<id>:role/Cognito_myappmovieAuth_Role"
      },
      "Action": "es:ESHttp*",
      "Resource": "arn:aws:es:us-west-2:<id>:domain/movies/*"
    },
    {
      "Effect": "Deny",
      "Principal": {
        "AWS": "arn:aws:iam::<id>:role/Cognito_myappmovieAuth_Role"
      },
      "Action": [
        "es:ESHttpPost",
        "es:ESHttpPut",
        "es:ESHttpDelete"
      ],
      "Resource": "arn:aws:es:us-west-2:<id>:domain/movies/kibana_sample_data_ecommerce*"
    }
  ]
}
```

Discoverは見たところ普通に使えるのだった。
この状態で Dev Tools を開き、

```
DELETE kibana_sample_data_ecommerce
```

```json
{
  "Message": "User: arn:aws:sts::<id>:assumed-role/Cognito_myappmovieAuth_Role/CognitoIdentityCredentials is not authorized to perform: es:ESHttpDelete with an explicit deny"
}
```

良い感じ。
一方、

```
PUT test
```

```json
{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "test"
}
```

```
DELETE test
```

```json
{
  "acknowledged" : true
}
```

ほーん。
最初から PUT を Allow しなければ良いだけでは？（試してない）

## 願望

kibanaに対してだけメソッド開放したい。
mmap と free と ps と cgroup

とある python ライブラリが [mmap(2)](https://linuxjm.osdn.jp/html/LDP_man-pages/man2/mmap.2.html) を使ってファイルを `MAP_SHARED | MAP_POPULATE` flags 付きでメモリに読み込んでいたので、その時 Linux メモリ管理系ツールではどういう挙動になるかチラ裏。

## mmap お試しコード

```c:mmap-sample.c
#include <fcntl.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>

int main() {
    int fd = open("abc.txt", O_RDONLY, (int)0400);
    off_t size = lseek(fd, 0, SEEK_END);
    printf("start\n");
    char* addr = mmap(NULL, size, PROT_READ, MAP_SHARED | MAP_POPULATE, fd, 0);
    printf("end\n");
    sleep(100);
    return 0;
}
```

Linux 環境で

```
$ gcc mmap-sample.c
$ dd if=/dev/zero of=abc.txt bs=5M count=1024
$ ./a.out
start
[しばし待つ]
end
$ ./a.out
start
[すぐ終わる]
end
```

# free

mmap でファイルをメモリに読み込んだわけだが、buff/cache のサイズが 5G 増えた。

```
$ free -m
              total        used        free      shared  buff/cache   available
Mem:          61399         348       55745           0        5305       60453
Swap:             0           0           0
```

２回目の実行が早かったのは buff/cache にすでにメモリが載っていたから。cache を消したい場合は次のようにして drop cache する。

```
$ echo 3 | sudo tee /proc/sys/vm/drop_caches
```

## ps

RSSに5GBが含まれている。つまり ps の RSS は buff/cache として確保したメモリも含んでいる。

cache から追い出されたら VSZ はそのままで、RSS は小さくなるはず(未確認

```
$ ps au
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
sonots   15592  4.7  8.3 5247396 5242312 pts/12 S+  18:08   0:00 ./a.out
```

`top` で見た時の RES 列も同様に 5GB を含んでいる


## cgroup

cgroup 内の現在のメモリ使用量を示す `memory.usage_in_bytes` について。

1. cgroup A で mmap
2. そのあと cgroup B で mmap

したとする。k8s でいうと、同一ノードで pod A と pod B が立ち上がったような状況。

1 の cgroup A の `memory.usage_in_bytes` は mmap したメモリ使用量を含む。
2 の cgroup B では、直前に cgroup A で mmap しておりノードの buffer/cache にキャッシュが載っているのでそれが再利用される。cgroup B の `memory.usage_in_bytes` には mmap したメモリ使用量が**含まれない。**

First touch の原則というものがあるらしい。

> Shared pages are accounted on the basis of the first touch approach. The cgroup that first touches a page is accounted for the page. 

ref. https://serverfault.com/questions/903432/page-cache-usage-listed-in-cgroups-memory-stat-file


## total memory を超えて別ファイルを mmap しようとした場合

buffer/cache から前の mmap が追い出されて、新しいファイルが buffer/cache に載る。

## つまり

mmap が使われていると、2回目から起動が早くなったり、メモリを大量に確保しているのに cgroup の limit に引っかからなかったりするということ。
JSの関数内でIF文がうまく使えない

htmlとCSSを一か月ほど独学で学びJSを勉強し始めて一日目なのですが
関数内でIF文がうまく機能しません
エラーが出るわけでもないのですがtrue判定が出なくて困っています。
条件は
i=0
i-1<0
i === 0
と試してみましたがわかりません
疑問解決と後々エラーを見直せるようにQiitaへ投稿したいと考えました。

const choosing =()=>{
  let i = Math.round(Math.random()＊(listone.length-1));
  wone.textContent = listone[i];
  if(i == 0){
    wtwo.textContent[0]
  }else{
    let d = Math.round(Math.random()＊(listtwo.length-1));
    wtwo.textContent = listtwo[d]
  };
};