OmniAICreator/Qiita-1.07M huggingface dataset:
UnityのTest Runnerでusingが効かなかった

# Test Runnerでusingが効かなかった

Unityでユニットテストを書くなら、公式の **Test Rnner** がよいと聞いたので、試したところ、テストコード内の `using` でエラーが発生しました。

LeapMotionのSDKを利用したコードだったので、 `using Leap` を指定したのですが、ご覧の通り赤い波線が表示されました。

![TestCode2.png](https://qiita-image-store.s3.amazonaws.com/0/221845/f7bea01b-a686-3d29-c9c0-29057dfd1360.png)

カーソルを合わせると、ポップアップで警告文が表示されました。

![TestCode.png](https://qiita-image-store.s3.amazonaws.com/0/221845/f792bba6-cb38-ac7d-321b-fabd2ab928ad.png)

```
型または名前空間の名前 'Leap' が見つかりませんでした（using ディレクティブまたはアセンブリ参照が指定されていることを確認してください）。
```

と書かれています。

テストコードではない通常のコードからは `Leap` が参照できているのに、なぜかテストコードからは参照できていないようです。


# 開発環境

以下の環境で試しました。

- Windows 10 64bit
- Unity 2018.2.21f1

# `Leap` の Assembly Definition が必要だった

原因を調査したところ、こちらの記事を見つけました。
[Unity 2018.1でTest Runnerの使い方が変わっていた話](http://ntgame.wpblog.jp/2018/05/22/post-1679/)

Assembly Definition が必要ということが書かれています。私の環境も、まさに、これが原因でした。


# LeapMotion.asmdef を作る

LeapMotionのフォルダで右クリック → **Create** → **Assenbly Definition** を選択すると、 `NewAssembly` という名前で入力待機状態になったので、 `LeapMotion` と入力したところ、 `LeapMotion.asmdef` というファイルが生成されました。


# LeapMotion.asmdef をテストコード側から参照する

これをテストコード側のasmdefファイルから参照するようにします。

私の環境の場合、PlayModeテスト用に `PlayMode.asmdef` というファイルを作っていたので、Unity内でそれを選択し、 **Inspector** → **References** の右下の **+** → **None (Assembly Definition Asset)** の右の **〇** → リストの中から `LeapMotion` を選択することで、参照設定ができました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/221845/413f0c00-a41b-31f4-b23f-7d3febe59858.png)

これでテストコードの `using Leap` のエラーが解消されました。


# 補足：Enable playmode tests for all assemblies

PlayModeでテストしようとすると色々なエラーが出ました。
私の環境では、 `Enable playmode tests for all assemblies` の設定をしたら、解消されました。

この設定に関しては、こちらの記事が丁寧でわかりやすかったので、詳しくはご参照ください。
[Unity TestRunner（PlayMode）のアセンブリ参照問題](https://qiita.com/karinharp/items/e8b7843a01a850b5c657)


# さいごに
ユニットテストをしたいだけなのに、 **Assembly Definition** という設定が必要なのは、~~JavaのJUnitやRubyのminitestとかと比べると面倒~~大変だと感じました。
ただ、Assemblyを定義することで、ビルドの高速化等も可能になるようです。せっかくなので勉強していこうと思います。

# 2019/03/26追記
テストコードのC#ファイルを `Editor` という名称のフォルダの配下に設置すれば、 Assembly Definition をしなくても、 **Edit Mode** で Test Runner を利用できることがわかりました。
ただ、 **Play Mode** の場合、Assembly Definitionは必要そうです。
php-master-changes 2019-03-22

この日は AST の行番号管理の修正、重複コードをまとめる/削除する等のリファクタリング、新しいカスタムオブジェクトシリアライゼーションの実装、ReflectionClass::getMethods() に null を渡すと空配列を返す問題の修正、mysqli が unbuffered クエリでメモリリークする問題の修正、テストの微修正があった！

# 2019-03-22
## nikic: Switch to bison location tracking
- https://github.com/php/php-src/commit/e528762c1c59bc0bd0bd6d78246c14269630cf0f
- [7.4~]
- コンパイラで、AST の行番号管理を [bison の location tracking](https://www.gnu.org/software/bison/manual/html_node/Tracking-Locations.html) へ移行
- zend_ast_loc というのへ情報を詰めてる

## rjhdby: Deduplicate code in zend_builtin_functions.c
- https://github.com/php/php-src/commit/5456a6ea92243d6028ea2012407dbef557113215
- [7.4~]
- 重複コードをまとめるリファクタリング、class_exists() / interface_exists() / trait_exists() とか get_declared_classes() / get_declared_interfaces() とか

## rjhdby: Make zend_hash_sort() return void
- https://github.com/php/php-src/commit/e86cdce549c9e81847584d2caa2dff7f89eac682
- success しか返さない zend_hash_sort() を void にして呼び出し側のチェックも削除

## nikic: Remove HAVE_PCRE/HAVE_BUNDLED_PCRE checks
- https://github.com/php/php-src/commit/e7e2056d1a993a01c9d57fb2261066855d282d8f
- [7.4~]
- PCRE は常にあるので散在する HAVE_PCRE/HAVE_BUNDLED_PCRE のチェックを削除

## nikic: Implement new custom object serialization mechanism
- https://github.com/php/php-src/commit/d373c11e710b525feb6373629e3d1ebffef2dd5b
- [7.4~]
- [PHP RFC: New custom object serialization mechanism](https://wiki.php.net/rfc/custom_object_serialization) の実装

## nikic: Fixed bug [#77772](https://bugs.php.net/bug.php?id=77772)
- https://github.com/php/php-src/commit/da35fa2cb8d454c8e797067e28e647030a5fe5df
- [7.2~]
- ext/reflection で、[ReflectionClass::getMethods()](http://php.net/manual/ja/reflectionclass.getmethods.php) に null を渡しても意味のある動作をしない（空配列を返す）問題の修正
- 任意引数なので null だと渡さないのと同じ扱いか、と思いきや 0 扱いになる
- 元の挙動に意味ないんで BC 気にしないでスッと直しちゃうね、らしい

## nikic: Fixed bug [#77773](https://bugs.php.net/bug.php?id=77773)
- https://github.com/php/php-src/commit/30ddfd49edbd8066cc0a18a557e3de30c2397d12
- [7.3~]
- ext/mysqli で、unbuffered クエリでメモリリークする問題の修正
- [#77308](https://bugs.php.net/bug.php?id=77308) からの話

## remicollet: ensure pcre.jit=1 for these tests
- https://github.com/php/php-src/commit/2e9dccef78d169be9a4a37c813e0b5d624bd5ac7
- [7.2~]
- PCRE JIT 有効が前提のテストで、INI セクション使って pcre.jit=1 を保証するよう修正

## remicollet: ensure pcre.jit=1 for this test
- https://github.com/php/php-src/commit/e68fd40e22e695e17d94da24a1c0ca0087a61898
- [7.3~]
- ↑と同様
【Unity】3Dオブジェクトにスクリプトをコンポーネントとして追加した際、エラーが発生した件

## 経緯
Unityの3DオブジェクトにScriptコンポーネントを追加しようとした際、エラーが発生し追加できなかった。

## エラー情報
以下のポップアップが発生した。
<img width="418" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/120715/b537b616-fa2f-2bcf-8226-aa788d241213.png">

> Can't add script
> Can't add script component 'Controller' because the script class cannot be found. Make sure that there are no compile errors and that the file name and class name match.

## 原因
Unity管理のファイル名とプログラムのクラス名が違った。

「右クリック → Create → C# Script」でファイルを作成した際にファイル名を間違えた。
そのためUnity側で再度リネームを行なったが、この時クラス名は修正してくれいないようだ。

【エラー発生状態】
ファイル名：Controller.cs
クラス名：`public class Controllor : MonoBehaviour`

【正しい状態】
ファイル名：Controller.cs
クラス名：`public class Controller : MonoBehaviour`

是非自動で修正を反映して欲しいところ。

## 結論
UnityでScriptのファイル名を変更する際は、クラス名との整合性に気をつけよう。
プログラム開発では当たり前だが、Unityを使っていると少し感覚が違ってくるため。
Arch Linuxで恋声を使う

##はじまるまえに
どうも！初投稿の黒川音緒(ねお)といいます！自分用のメモのような記事を書いていきます。よろしくおねがいします！  

#はじめに
Archで恋声を動かしてかわいくなりたいと思ってる人が全世界に5000兆人居ると思ったので、書いてみました！
基本的にそのまま動きますがいろいろあったので書きました。(初心者なだけ)

## やりかた
まずWineをいれます  

```
# pacman -S wine
```
次に恋声の公開ページからzipを落としてきます
[ここらへん(http://koigoemoe.g2.xrea.com/koigoe/koigoe.html)](http://koigoemoe.g2.xrea.com/koigoe/koigoe.html)

どこかに展開して動かします  

```
$ unzip koigoe.zip
$ wine "koigoe(x86).exe"
```
![2019-03-24-011057_755x412_scrot.png](https://qiita-image-store.s3.amazonaws.com/0/383715/caf5e06a-ea54-701a-fb60-e4e96d8d64c8.png)

おわり！
##トラブルシューちんぐ(?)
ここでちゃんと動くイケメンのような環境をwine構築していないのは私だけだと思いますが、とりあえずマイクや出力デバイスがきちんと表示されませんでした。  
### その１
Wineにalsaのレジストリキーを追加してあげないとだめみたいです。[ここらへん参照](https://wiki.archlinux.jp/index.php/Wine#.E3.82.B5.E3.82.A6.E3.83.B3.E3.83.89)
(64bit、32bitうんぬん書いてあるけど書かないと動かなかった(きがする))

```
$ regedit
```
して、`HKEY_CURRENT_USER > Software > Wine > Drivers`内に文字列のキー、名前:`Audio`、データ:`alsa`を追加してあげます。
![2019-03-24-011802_1072x616_scrot.png](https://qiita-image-store.s3.amazonaws.com/0/383715/b07697c0-8c7a-5ed6-0928-12cf0670a361.png)

### その2
その1してもデバイスでない＞＜　再生できない＞＜ みたいなことがある場合、  

```
$ aplay -l
$ arecord -l
```
とかしてきちんとデバイスが認識できているか確認しましょう。
できてないけど、

```
$ lsusb (-vとか)
```
するとなんやら認識はしてるみたい！とかの場合、ALSAとかを再起動、コンピューターを再起動してあげると認識する場合があります。(これに1時間ぐらいハマっちゃった情弱がここ)

##おわりに
![2019-03-24-012927_755x412_scrot.png](https://qiita-image-store.s3.amazonaws.com/0/383715/05626b46-927f-f903-3ab3-4df06a252917.png)
楽しい恋声Archライフを！
おわりです。閲覧ありがとうございます(\*^_^*)
Yubikey 5のPIVで遊ぶ ( SSH鍵生成&保管 )

# Yubikey 5のPIVで遊ぶ ( SSH鍵生成&保管 )

Yubikeyには、PIVという規格/機能が備わっています。これを使って、SSH秘密鍵を生成したり、認証情報を保管したり、署名することができるので、今回はそれで遊びます。

# PIV とは

PIVは、Personal Identity Verificationの略で、アメリカ連邦政府で使われているスマートカードの規格です。
連邦職員が所持している身分証明カードは、このPIV規格に沿ったICチップが入っており、自分の身分を証明するために使用します。

Yubikeyがあれば、PIV対応のハード/ソフトで認証に使用したりすることができます。
ただ、日本でPIV認証に対応した場所はありません。
なので、今回はPIVにあるRSA/ECC鍵を生成して保管する機能を使って、SSH秘密鍵保管庫としてYubiukeyで遊んでみようと思います。

**要するに「内部で秘密鍵を保管してくれて、ファイルや文字列をぶん投げると署名して返してくれるUSBデバイス」です。**

# YubikeyのPIV

- PIV機能に対応したYubikeyは、Yubikey 4,5,NEOです。また、NEOはECC鍵に対応しておらず、RSA鍵しか使えません。

- USB接続だけではなく、NFCでも使用できます。

- YubikeyのPIVには、9a 9c 9d 9eの計4つの「スロット」があります。
つまり、4つの秘密鍵を保管することができます。

- 既にある秘密鍵をYubikeyに保管させることもできますが、Yubikey内で秘密鍵を生成し、公開鍵だけ出力することで、一切秘密鍵を外に持ち出せないようにすることもできます。
そちらのほうが安全なので、今回は後者を使います。

- 対応するアルゴリズムは RSA 1024, RSA 2048, ECC secp256r1 です。

- YubikeyのPIV鍵は、PINコードで保護されており、PINコードを入力しないとYubikeyに物理的にアクセスできても使うことはできません。

- 9a 9c 9d 9eの各スロットは、もともとは利用目的があるため、微妙にPINコードの管理が異なります。
 9aと9dは、認証に使うため（パソコンにセットするとか）に作られたため、一度PINコードを入力するとUSB接続が切れるまで使えます。
 9cはファイルのデジタル署名に使うため、署名するたびにPINコードが必要になります。
 9eは、建物の入館時のドアロックの解除などに使うため、PINコードが必要ありません。
**まーーー我々は連邦職員じゃないので、好きなスロット使えば良いですね。**

- 実はスロットは9a 9c 9d 9e以外にも82 83 84 ... 95まで20個あります。ここには、9a 9c 9d 9eに以前登録していた鍵が保存されています。
 つまり、間違えて、使ってるスロットの鍵を上書きしちゃっても、順次以前使っていた鍵がこのスロットにスライドされて来るのでなんとかなります。

# ツールのインストール

```console
$ sudo pacman  -S yubikey-manager opensc ccid
```

# 鍵の生成

```console
$ ykman piv generate-key -a RSA2048 9a pubkey.pem
$ ykman piv generate-certificate -s "SSH Key" 9a pubkey.pem
```

スロット9aに、RSA2048bitの鍵を生成します。公開鍵はpubkey.pemという名前でカレントディレクトリに生成されます。
また、２つ目のコマンドで、SSHに使用する情報の生成やスロットへの名前付をしています。

# sshクライアントの設定

`.ssh/config`に、以下のようにホスト情報を追記します。
IdentityをPKCS11Providerに置き換えて使えます。

```
Host hoge.com
  User fuga
  PKCS11Provider /usr/lib/opensc-pkcs11.so
```

これで、sshするときにPINコードが尋ねられます。
YubikeyのデフォルトPINコードは`123456`です。

# 公開鍵の変換

Yubikeyの公開鍵を、sshが使える形式に変換します。

```console
$ ssh-keygen -i -m PKCS8 -f pubkey.pem > pubkey.txt
```

pubkey.txtの中には、見覚えのある文字列（公開鍵）があるので、ssh先の`.ssh/authorized_keys`に貼り付けましょう。

# おまけ
## PINコードの変更

デフォルトのPINコードは`123456`で脆弱なため、変更しましょう。
変更するコマンドは以下です。

```console
$ ykman piv change-pin
```

## PINコードブロックの解除

PINコードの入力を3回以上間違えると、PINコードがブロックされ、PIV機能が使えなくなります。
PUKコードを使うことで、PINコードを新しものに変更できます。

```console
$ ykman piv unblock-pin
```

デフォルトのPUKコードは`12345678`です。（デフォルトのPINコードの末尾に78を追加）

## PUKコードの変更

```console
$ ykman piv unblock-pin
```

## PIVリセット

PINコードもPUKコードも忘れてしまった場合、YubikeyのPIV機能をすべてリセットすることができます。
もちろん、保管してある鍵はすべて消去されます。

```console
$ ykman piv reset
```

## マネジメントキー

マネジメントキーは、鍵の生成やインポートに使います。

デフォルトのマネジメントキーは`010203040506070801020304050607080102030405060708`です。

自分はマネジメントキーは変更する必要はないと思いますが、変更したい人は`ykman piv change-management-key`で変更できます。

# まとめ

これで、ssh鍵を物理的に安全に保つことができるようになりました。新しいマシンを触る度に鍵を生成してgithubに公開鍵を登録するよりかは、よっぽど便利なので、ぜひ使っていきたいですね。

# 参考
https://orebibou.com/2019/03/macos%E3%81%A7ssh-agent%E3%81%AByubikey%E3%81%AE%E9%8D%B5%E3%82%92%E7%99%BB%E9%8C%B2%E3%81%99%E3%82%8Bopensc%E7%B5%8C%E7%94%B1/
https://developers.yubico.com/PIV/Guides/SSH_with_PIV_and_PKCS11.html
https://wiki.archlinux.org/index.php/YubiKey#CCID_Smartcard
django-rest-frameworkのserializerってどう呼ばれてるんだろう

# 目的
* [前に書いたやつ](https://qiita.com/kiri__n/items/879c1476a8f3d43a7294) でserializerの中身は読んだ
* でもこのserializerってどこでどう呼ばれてるんだろう

# 環境
* 前のと同じ
* Serializerの使い方とかは参考記事を参照

# 結論
* `mixins.py`で呼ばれてた
    * `create`と`update`のそれぞれで

```python
class CreateModelMixin(object):
    """
    Create a model instance.
    """
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
```

```python
class UpdateModelMixin(object):
    """
    Update a model instance.
    """
    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)
```
* `get_serializer`して`is_valid`して`perform_hogehoge`するっていう流れらしい
    * `perform_hogehoge`では`serializer.save()`してる

# 応用
* POSTとかPUTでAPIを呼ばれた時の挙動を帰るときはviewの`create`メソッドとか`update`メソッドを上書きしてやればよさげ
* DBにデータ書き込みはしないけどPOSTでAPIを提供したいときは↓みたいな感じ？

```python
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        # ここでserializer.validated_dataを使って何らかの処理をする
        return Response({'result': 'data'}, status=status.HTTP_200_OK)
```

# 参考
* https://slideship.com/users/@massa142/presentations/2018/05/RjVo67zy1JyQiYqe3GgpLB/
* http://note.crohaco.net/2018/django-rest-framework-serializer/
プリペアードステートメントでSQLを作成するときに同じ変数を２回使いたい



プリペアードステートメントを使うときにハマったので備忘録。


例えば、

```
$sql = 'SELECT * FROM orders WHERE buy_user = :user_id OR sale_user = :user_id AND delete_flg = 0';
$data = [':user_id' => $user_id];
```

だとエラーを吐く。

なので、

```
$sql = 'SELECT * FROM orders WHERE buy_user = :user_id OR sale_user = :id AND delete_flg = 0';
$data = [':user_id' => $user_id, ':id' => $user_id];
```

としなくてはならない。理由はわからないがPDOはそういう仕様らしい。バインドするときのキーは複数あったらだめらしい。
Mojaveでkarabinerを使ってcommandを英数・かな切り替えをオンにした時にハマったこと

# 環境

MacBook Pro (13-inch, 2018, Four Thunderbolt 3 Ports)
MacOS Mojave
Karabiner-elements

# ハマったこと

US keybordのMacを使っており、英数・かな切り替えをKarabiner-elementsで行なっていた。
ある日、Commandキーを押しながら複数選択ができないことに気がつく...


# 解決法

```bash
~/.config/karabiner/karabiner.json
```
このファイルの中身を変更することで解決。エディターで以下のファイルを開き、

```bash
vim ~/.config/karabiner/karabiner.json
```

以下の箇所を

```bash
"lazy": true
```

全て以下に変更。

```bash
"lazy": false
```

ここまで変更したら保存。すると、Commandキーを使用した複数選択も、英数・かな切り替えもできるようになりました。
docker-compose build でE: Failed to fetch http://...  Writing more data than expected (1123368 > 1086978)が発生する時の対応方法

# 環境
OS：macOS Mojave 10.14.3
Docker：18.09.2, build 6247962
docker-compose：1.23.2, build 1110ad01
docker-machine：0.16.1, build cce350d7
php：7.1.23

# 事象
dockerを以下のコマンドでビルドをすると

```
docker-compose build --no-cache workspace

.
.　省略 
.

+ groupadd -g 1000 laradock
+ useradd -u 1000 -g laradock -m laradock -G docker_env
+ usermod -p * laradock -s /bin/bash
+ apt-get install -yqq apt-utils php7.1-zip nasm
E: Failed to fetch http://220.152.42.162:80/data/06abb81878b24fba/archive.ubuntu.com/ubuntu/pool/universe/n/nasm/nasm_2.11.08-1ubuntu0.1_amd64.deb  Writing more data than expected (1088616 > 1086978)
```

となりビルドがエラーで落ちるといった事象が発生しました。

対象となる方は少ないかと思いますが、もし同じ事象でお困りの方がいましたら、一旦私が行った処置をシェアしたいと思います。
お役に立てれは幸いです。

# 解決ではないが一旦これでエラー回避
以下のファイルの対象の部分をコメントアウトするだけです。

```:laradock/workspace/Dockerfile
# always run apt update when start and after add new source list, then clean up at end.
RUN set -xe; \
    apt-get update -yqq && \
    pecl channel-update pecl.php.net && \
    groupadd -g ${PGID} laradock && \
    useradd -u ${PUID} -g laradock -m laradock -G docker_env && \
    usermod -p "*" laradock -s /bin/bash && \
    apt-get install -yqq \
      apt-utils && \
      #
      #--------------------------------------------------------------------------
      # Mandatory Software's Installation
      #--------------------------------------------------------------------------
      #
      # Mandatory Software's such as ("php-cli", "git", "vim", ....) are
      # installed on the base image 'laradock/workspace' image. If you want
      # to add more Software's or remove existing one, you need to edit the
      # base image (https://github.com/Laradock/workspace).
      #
      # next lines are here becase there is no auto build on dockerhub see https://github.com/laradock/laradock/pull/1903#issuecomment-463142846
      - libzip-dev zip unzip \
      + # libzip-dev zip unzip \　コメントアウトした
      # Install the zip extension
      - php${LARADOCK_PHP_VERSION}-zip \
      + # php${LARADOCK_PHP_VERSION}-zip \　コメントアウトした
      # nasm
      - nasm && \
      + # nasm && \　コメントアウトした
      php -m | grep -q 'zip'
```

# 結論
時間がなくなぜエラーが発生しているのかまだわかっていません。
私が必要とする環境では、必要のないモジュールでエラーが発生していたので一旦コメントアウトで対応しました。

もし解決方法をご存知の方がいらしたら是非教えていただけると嬉しいです。
11日目: Domain-Adversarial Training of Neural Networks

# Domain-Adversarial Training of Neural Networks 要約
## 読んだ論文
Domain-Adversarial Training of Neural Networks
Yaroslav Ganin, Evgeniya Ustinova, Hana Ajakan, Pascal Germain, Hugo Larochelle, François Laviolette, Mario Marchand, Victor Lempitsky
https://arxiv.org/abs/1505.07818
上記の論文を読んだので簡単にまとめます．Journal of Machine Learning Research 17 (2016) 1-35の論文で719引用されている良論文．ただし，35ページ．．．

## 3行でまとめる
- 昨日同様，ドメイン適応すればいいことあるよねという企画．
- ドメイン適応問題において，ドメイン検出器を敵対させることでドメイン汎用的な特徴抽出器を鍛える．
- 理論の裏付けと徹底的な検証が行われている．

## 関連研究
以前も紹介した東大松尾研の岩澤先生が人工知能学会全国大会で行動認識の個人適応における類似手法を試している様子です．和文のSlideShareもあるのでこちらも[参考](https://github.com/jojonki/arXivNotes/issues/63)にしましょう．英文でもDomain adversarialな手法は結構提案されている様子でした．


## 提案手法
### 前置き
- 理論の背景に関する部分は読み飛ばした．
- 35ページの内Methodに絞って読んだにもかかわらず重い！！！
- 理論背景の説明と変数の種類が多いので対応付けるのが大変．

### シンプルなMLPの場合
![20190323_001.png](https://qiita-image-store.s3.amazonaws.com/0/376859/97628d37-ad2d-737a-5ede-9a4457cd6e4a.png)

重要なのは上記の損失関数の最適化である．

- まず，各関数，変数の説明を行う．
 - nはソースドメイン（ラベルあり）のデータ数
 - n'はターゲットドメイン（ラベルなし）のデータ数
 - $L_y^i$はソースドメインのラベルに関する予測の損失
 - $L_d^i$はドメイン検出器の予測の損失（ソースドメインかターゲットドメインかを識別する）
 - $W,b,V,c,u,z$は全てNNのパラメータ
 - $W,b$は入力から隠れ層へのパラメータでここは$L_y, L_d$共通
 - $V, c$は$L_y$のsoftmaxに対するパラメータで，$u,z$は$L_d$のsoftmaxに対するパラメータ
- 以上を踏まえると上記の損失関数は，
 - 第一項：ソースドメインのラベル予測に関する損失（サンプル数で正規化）
 - 第二項：ソースドメインのドメイン予測に関する損失（サンプル数で正規化）
 - 第三項：ターゲットドメインのドメイン予測に関する損失（サンプル数で正規化）
となる．第一項をラベル予測，第二，三項をドメイン予測（λで重要度設定）とも考えられえる．
- ここで，最適化は
 - $W, V, b, c$ ラベル予測に関する部分は最小化（ラベル予測の精度が高まるように学習）
 - $u, z$ ドメイン予測に特化した部分は最大化（ドメインが予測できないように学習）

これを行うことで，ソースドメインのラベル予測時に，ドメイン予測を最大化するような敵対をさせつつ学習することで，ドメインに汎用的な特徴抽出ができるという発想である．これが後々のAFLにつながっていくようである（[3日目参照](https://qiita.com/himatya/items/38278b9e7cae756213b6)）．

## まとめ
- ドメイン予測を敵対させることでドメイン共通な特徴を学習する手法を提案した論文である．
- 恐らくこれが一番最初の提案？と思われ，ここからAFL等に発展していったと思われる．

## 昨日の補足
- 昨日の記事の方を編集します（$L_{similarity}$の話）．

## 所管
本記事だけ読むと簡単なのだが，原文を追いかけるのはすごい大変でした．多分2時間くらいかかっています．更にその前に論文選定やらバックグラウンド調査やらしたりしていたので合計3時間くらいかかりました．ただ，今後敵対的な特徴表現抽出や，ドメイン適応問題は考えていきたいので良い論文でした．
Roomのcolumn追加方法

#はじめに
覚書程度なので注意。
わかりづらいと思う。
後これがあってるかどうかもわかんない…。

#変更箇所
- DBのVersion管理してるところ（AppDataBase）
- DBの呼び出し箇所（Activity,Fragment）
- DBの中身書いてるところ(Interface)

### AppDatabase
DBのVersionをあげる（今回の場合は 1 → 2）

```Kotlin:AppdataBase.kt
@Database(entities = [DBのテーブル（クラス）::class], version = 2) //この部分を２へ
abstract class AppDataBase : RoomDatabase() {
    //DAOとか書いてあるけども今回は省略
}
```

### Activity,Fragment
呼び出し部分の前に変更させるSQL文を記述

```Kotlin:Migration.kt
val MIGRATION_1_2 = object : Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                //カラム追加
                database.execSQL("ALTER TABLE [テーブル名] ADD [追加したいカラム名] [追加するカラムの型]")
            }
        }
```

呼び出し部分でMigrationを行う

```Kotlin:Main.kt
     val dataBase =
            Room.databaseBuilder(activity.applicationContext, AppDataBase::class.java, "データベース名")
                .addMigrations(MIGRATION_1_2) //Migration
                .build()
```

### Interface
追加したカラムのcolumnInfoを作る

```Kotlin:InterFace.kt

@Entity
class Database {
    @PrimaryKey(autoGenerate = true)
    var userId: Int = 0

//// 追加部分
    @ColumnInfo(name = "追加したカラム名")
    var 変数名: [型]? = ""
}
```

#終わりに
DBを壊さずにこれで一応カラム追加とかできる。
PHPで関数を書く方法

#PHPで関数を作る方法
こんにちは、[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしているueken0403です。
Progate/PHPのPHPⅠを学習し終えたので、得た学びを共有したいと思います。
今回は、PHPで関数を作る方法を解説したいと思います。

プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。



##PHPでは関数が使える

PHPには、「組み込み関数」という便利な関数が元々埋め込まれており、決められた命令を打ち込めばそれらを使うことができます。
関数は、
［関数］()
という風に書くのですが、この()に与える数を「引数」と言います。
ちなみに読み方は「いんすう」ではなく「ひきすう」です。
例えば、strlenという関数があるのですが、これは引数の文字列の文字数を数えて返してくれる関数です。

##PHPでは関数が作れる

関数を作るには「function 関数名(){ 処理 }」という書き方をします。
関数名は自由につけることができます。
作った関数を呼び出すときは、「関数名()」という風に書きましょう。

##簡単な関数の例

めちゃくちゃ簡単ですが、「三角形の面積の公式」の関数を作ってみましょう。
三角形の面積の公式は当然「底辺×高さ÷2」ですね。
普通は英語を使うのですが、今回は便宜上日本語で行きますね。
自分としてもそっちの方が整理しやすいのでご容赦ください。

では関数の名前を「三角形の面積」にして、1つ目の変数を「＄底辺」2つ目の変数を「＄高さ」とします。
そうした場合、目的の関数は、

function 三角形の面積(＄底辺,＄高さ)｛echo ＄底辺*＄高さ/2;｝

となります。

これで「三角関数の面積(3,4);」のように呼び出し、引数を入力すれば勝手に計算をしてくれます。(答えは６)


##まとめ

今回は、PHPで関数を作る方法を解説しました。
用意されたものだけでなく、自分で関数を作れるのはシンプルに便利だし、応用の幅が広そうですね。
まだまだ初心者ですが、プログラミングの可能性を感じるレッスンでした。
MacでAndroid-x86 8.1を動かしてみる

Androidを急遽触りたくなったが端末が手元に見当たらず・・・
なので[Android-x86](http://www.android-x86.org)使ってMax上でAndroidを動かしてみました。

Android-x86は、Qemu,Parallels Desktop,VirtualBoxとかで動かせそうですが、お手軽に試せそうなVirtualBox上で動かします。

# VirtualBoxインストール
https://www.virtualbox.org
から最新版ダウンロードしてきて、インストールします。
# ISOイメージの入手
http://www.android-x86.org/download
64bitかつ最新のandroid-x86_64-8.1-r1.isoを選びました。
# Android-x86の起動
VirtualBox開いて、新規ボタンを押します。

タイプは**Linux**,バージョンは**Linux 2.6 / 3.x / 4.x.(64-bit)**を選びます。
![スクリーンショット 2019-03-23 23.43.48.png](https://qiita-image-store.s3.amazonaws.com/0/113452/79820084-83ab-c784-b10a-8229db834512.png)

続いて、メモリーサイズは2GB以上にするのが良さそうなので念のため4GB取っておきます。Android上で動かしたいアプリによっては多めがいいと思います。
![スクリーンショット 2019-03-23 18.16.50.png](https://qiita-image-store.s3.amazonaws.com/0/113452/89bb99c1-9a3f-47fa-6418-11a104993be4.png)

ストレージは最低8GBあれば大丈夫そう。
![スクリーンショット 2019-03-23 18.17.04.png](https://qiita-image-store.s3.amazonaws.com/0/113452/193a6981-9372-557a-87d5-689ea976ab67.png)
![スクリーンショット 2019-03-23 18.17.18.png](https://qiita-image-store.s3.amazonaws.com/0/113452/09e0fb4c-ffd6-3029-3739-e69e7500f680.png)
![スクリーンショット 2019-03-23 18.17.28.png](https://qiita-image-store.s3.amazonaws.com/0/113452/4fb77d73-9ca2-0e7b-5f13-bd3ac357dd76.png)
![スクリーンショット 2019-03-23 18.17.45.png](https://qiita-image-store.s3.amazonaws.com/0/113452/38bc8377-5d9d-8639-5e02-5a99fe07434b.png)

次に作成したマシンの設定を押します。
![スクリーンショット 2019-03-24 0.33.45.png](https://qiita-image-store.s3.amazonaws.com/0/113452/7974a47b-a82b-0d3a-907b-a2386500b736.png)

ディスプレイのアクセラレーションの3Dアクセラレーションを有効化を選択します。必要に応じてプロセッサー数を変更しておきます。
![スクリーンショット 2019-03-23 23.46.13.png](https://qiita-image-store.s3.amazonaws.com/0/113452/8b9b71d9-f253-ccb1-0eea-044b7ad5c33a.png)

いよいよ、Androidの起動です。
先ほど入手したISOイメージを指定し、Startします。
![スクリーンショット 2019-03-23 18.19.21.png](https://qiita-image-store.s3.amazonaws.com/0/113452/86d7b21d-e548-6380-8785-267bc05dcef6.png)

今回は取り急ぎ試したいので、Live CDから起動させます。
![スクリーンショット 2019-03-24 0.14.18.png](https://qiita-image-store.s3.amazonaws.com/0/113452/262d3391-9fbc-42c0-c573-7c227ab8e28f.png)

お、なんか出てきました。
![スクリーンショット 2019-03-23 18.20.24.png](https://qiita-image-store.s3.amazonaws.com/0/113452/51bb3115-8e4e-794b-ec56-4cc81f833d0a.png)
しばらくすると初期セットアップ画面が出てきました。
![スクリーンショット 2019-03-23 18.21.49.png](https://qiita-image-store.s3.amazonaws.com/0/113452/a447eb9e-52b3-ede8-74cb-14d51539717d.png)
セットアップ進めて、ちゃんと動いていそうです。YouTubeもちゃんと見れました＾＾
![スクリーンショット 2019-03-23 18.24.22.png](https://qiita-image-store.s3.amazonaws.com/0/113452/63ff5413-7182-e4dc-0ec9-cf1083d00b13.png)

# 所感
お手軽に試せたのでよかったです。
ただ、いくつかアプリ入れてみましたが、動かないアプリもありました・・・
マシンのリソースが足りないのかアプリの問題か不明ですが。。

簡単にできるので怪しいアプリ試すのに利用したりするのがいいと思いましたw
また、今回はVirtualBoxを用いましたが、Qemuでも動かせるので暇な時やってみようと思います。

# おまけ
Live CD Bootでなくインストールして起動も試しましたが、再起動したらまたインストーラーが起動してしまいました。
対策としては、起動順序入れ替えるか、ISOデバイス削除したら良さそうでした。
![スクリーンショット 2019-03-24 0.25.47.png](https://qiita-image-store.s3.amazonaws.com/0/113452/c69d279c-6531-6e6d-b421-493612aa082d.png)
![スクリーンショット 2019-03-24 0.25.58.png](https://qiita-image-store.s3.amazonaws.com/0/113452/954a3fd2-7fe0-a6ea-f592-7ad8fc089764.png)

# 参考
http://www.android-x86.org/documents/virtualboxhowto
Ruby 2.5.xでdeep-coverを使うときは、エッジケースのバグがあるので注意

Ruby 2.5.x + deep-coverでエッジケースのバグを見つけました。
原因はおそらくRubyのバグです。
Ruby 2.6.0では再現しません。

詳細はこちら
https://github.com/deep-cover/deep-cover/issues/47

## deep-coverを有効にすると、以下のコードの挙動が変化します。

```ruby
class NgClass
  def self.my_class_method(
      a0: 0, a1: 0, a2: 0, a3: 0, a4: 0, a5: 0, a6: 0, a7: 0, a8: 0, a9: 0,
      b0: 0, b1: 0, b2: 0, b3: 0, b4: 0, b5: 0, b6: 0, b7: 0, b8: 0, b9: 0,
      c0: 0, c1: 0, c2: 0, c3: 0, c4: 0, c5: 0, c6: 0, c7: 0, c8: 0, c9: 0,
      d0: 0, d1: 0,
      x: 0
    )
    x
  end
end
```

## deep-coverなしでも以下のコードはRuby 2.5.xで仕様どおりに動きません

deep-coverが書き換えたコード

```ruby
($_cov ||= {})[0]||=Array.new(38,0);$_cov[0][37]+=1;_temp=nil;((_temp=(class NgClassRewritten
  $_cov[0][36]+=1;((_temp=(def (self).my_class_method(
    a0: ($_cov[0][0]+=1;0), a1: ($_cov[0][1]+=1;0), a2: ($_cov[0][2]+=1;0), a3: ($_cov[0][3]+=1;0), a4: ($_cov[0][4]+=1;0), a5: ($_cov[0][5]+=1;0), a6: ($_cov[0][6]+=1;0), a7: ($_cov[0][7]+=1;0), a8: ($_cov[0][8]+=1;0), a9: ($_cov[0][9]+=1;0),
        b0: ($_cov[0][10]+=1;0), b1: ($_cov[0][11]+=1;0), b2: ($_cov[0][12]+=1;0), b3: ($_cov[0][13]+=1;0), b4: ($_cov[0][14]+=1;0), b5: ($_cov[0][15]+=1;0), b6: ($_cov[0][16]+=1;0), b7: ($_cov[0][17]+=1;0), b8: ($_cov[0][18]+=1;0), b9: ($_cov[0][19]+=1;0),
        c0: ($_cov[0][20]+=1;0), c1: ($_cov[0][21]+=1;0), c2: ($_cov[0][22]+=1;0), c3: ($_cov[0][23]+=1;0), c4: ($_cov[0][24]+=1;0), c5: ($_cov[0][25]+=1;0), c6: ($_cov[0][26]+=1;0), c7: ($_cov[0][27]+=1;0), c8: ($_cov[0][28]+=1;0), c9: ($_cov[0][29]+=1;0),
        d0: ($_cov[0][30]+=1;0), d1: ($_cov[0][31]+=1;0),
        x: ($_cov[0][32]+=1;0)
    )
    $_cov[0][34]+=1;_temp=nil;x
  end);$_cov[0][33]+=1;_temp=_temp))
end);$_cov[0][35]+=1;_temp=_temp))
```

## Rubyの修正差分

誰か、元となるrubyの修正差分やバグ報告を知っていたら教えてください。
Docker コマンドで Volume の設定をしようとしたら invalid volume specification エラーに遭遇した

一応解決できたので備忘録として残しておく。

## 前提
- ホストOS: Windows10
- WSL: Ubuntu16.04
- Docker: 18.09.3
- WSL上のシンボリックリンク: `workspace -> /mnt/c/Users/<user_name>/workspace`
- `<user_name>` のところは適宜置き換えてください


## エラーについて

`src` ディレクトリが存在するディレクトリで下記コマンドを実行したところ、「無効なボリューム指定してるよ」と、エラーが出た。

- コマンド
    - `docker run -v "$(pwd)"/src:/src <container>`
    
    ※ コンテナの `WORKDIR` は `src` に設定してある

- エラー内容
    - ```
      docker: Error response from daemon: invalid volume specification: '/home/<user_name>/workspace/hoge/src:/src'.
      See 'docker run --help'.
      ```

## 対応

ローカルのパス指定方法（ `"$(pwd)"/src` ）を変更してみる

### 検証①

`/home/<user_name>/workspace/hoge/src` に変更してみる

#### 結果

同様のエラーが出て検証失敗
まあ当然でしょう。

### 検証②

`/mnt/c/Users/<user_name>/workspace/hoge/src` に変更してみる

#### 結果

```
docker: Error response from daemon: invalid volume specification: '/mnt/c/Users/<user_name>/workspace/hoge/src:/src'.
See 'docker run --help'.
```

いけると思ったが、失敗。。

### 検証③

`C:\\Users\\<user_name>\\workspace\\hoge\\src` に変更してみる

### 結果

いけたー！


## 結論

WSL から見たファイルパスを指定をしても、Docker Daemon からしたら分からない！ってことっぽい。
WSL 便利だけど、変なところで詰まるのでやっぱりMacの方が絶対ラク。。
GCP で tensorflow 遊び5.2

今更ながら、データの確認の話

データの shape さえ分かっていれば中身は見なくてもネットは組めるし、教師データとの突き合わせであとは勝手に学習されてなにがしかの結果は出てくるんですが、一応データを見るところもやっておく。

このシリーズで扱っているデータは、某コンペのゴルフ場検出という例題で、 landsat-8 の 7 channel 画像というもので、format は tiff なんだが、普通に viewer で見ようとするとみんな固まってくれる。
最悪 C で手で loader 書くかとフォーマット調べてて、なんだこれ？フォーマット壊れてね？ってしばらく悩んだが、od -h を hexdump の替わりに使ってはダメだったというオチでした。
去年はこの辺でやる気が8割方尽きた。

結局、散々探し回って scikit-image でなら以下のようにして読めるのでした。

```py
#! /usr/bin/env python

import sys
from skimage import io
import matplotlib.pyplot as plt

im = io.imread(sys.argv[1])

print(im.shape, im.dtype)
print(im.max(), im.min())

io.imshow(im[:,:,0])
io.show()
```

7 channel あるので、rgb 仮定した普通の viewer じゃ表示させられないので、以下のようにして並べてみるとなんとなく構造が見えてくる。


```py
#! /usr/bin/env python

import sys
from skimage import io
import matplotlib.pyplot as plt
import cv2
import numpy as np

im = io.imread(sys.argv[1])

mean = im.mean()

im20 = np.ones(im[:,:,0].shape, im[:,:,0].dtype)
im20 *= mean
print(im20.shape, im20.dtype)

im21 = cv2.hconcat([im[:,:,0], im[:,:,1], im[:,:,2], im[:,:,3]])
im22 = cv2.hconcat([im[:,:,4], im[:,:,5], im[:,:,6], im20])

im2 = cv2.vconcat([im21, im22])

io.imshow(im2)
io.show()
```

### 去年参考にした資料

* http://rs.aoyaman.com/seminar/about3.html
* https://blog.esrij.com/2013/07/12/landsat-8-dc99/
* http://redd.ffpri.affrc.go.jp/pub_db/course_materials/_img/2013_basic/2013_basic_chap06.pdf

### 発掘された去年の読解メモ


```hexdump``` による先頭部分

```
0000000 49 49 2a 00 08 00 00 00 0c 00 00 01 03 00 01 00
0000010 00 00 20 00 00 00 01 01 03 00 01 00 00 00 20 00
0000020 00 00 02 01 03 00 07 00 00 00 9e 00 00 00 03 01
0000030 03 00 01 00 00 00 01 00 00 00 06 01 03 00 01 00
0000040 00 00 01 00 00 00 11 01 04 00 08 00 00 00 cc 00
0000050 00 00 15 01 03 00 01 00 00 00 07 00 00 00 16 01
0000060 03 00 01 00 00 00 04 00 00 00 17 01 04 00 08 00
0000070 00 00 ac 00 00 00 1c 01 03 00 01 00 00 00 01 00
0000080 00 00 52 01 03 00 06 00 00 00 ec 00 00 00 53 01
0000090 03 00 07 00 00 00 f8 00 00 00 00 00 00 00 40 00
00000a0 40 00 40 00 40 00 40 00 40 00 40 00 00 1c 00 00
```

先頭が ```4949```なのでリトルエンディアン。後続は ```2a00``` と ```08000000``` で
tiffのフォーマット通り。続く ```0c00``` はタグが12個あることを示している。
各タグは12byteあるので

```
00 01 03 00 01 00 00 00 20 00 00 00
01 01 03 00 01 00 00 00 20 00 00 00
02 01 03 00 07 00 00 00 9e 00 00 00
03 01 03 00 01 00 00 00 01 00 00 00
06 01 03 00 01 00 00 00 01 00 00 00
11 01 04 00 08 00 00 00 cc 00 00 00
15 01 03 00 01 00 00 00 07 00 00 00
16 01 03 00 01 00 00 00 04 00 00 00
17 01 04 00 08 00 00 00 ac 00 00 00
1c 01 03 00 01 00 00 00 01 00 00 00
52 01 03 00 06 00 00 00 ec 00 00 00
53 01 03 00 07 00 00 00 f8 00 00 00
```

のように並んでいる。タグ構造は2+2+4+4byteで、エンディアンを考慮すると先頭3行は

```
0100h, 0003h, 00000001h, 00000020h
0101h, 0003h, 00000001h, 00000020h
0102h, 0003h, 00000007h, 0000009eh
```

となる。これらが順にイメージの幅と高さ、色深度でshortで表現されており（0003h）幅と高さは（即値で）20h=32、色深度の方は7layerあって9ehに実体がある。
000009eh から読み進めれば

```
40 00 40 00 40 00 40 00 40 00 40 00 40 00
```

があり、エンディアン考慮して 0040h がbit数で、64bitすなわち8byte整数であるとわかる。
ノンプログラマ向けのGASレクチャ資料を公開します。(V8エンジン対応)

# 2022/3/21 更新！

Qiitaでこの記事を公開していたら、本を出版することになりました！！キャー！ありがとうQiitaさん。

[ケーススタディでしっかり身につく! Google Apps Script超入門](https://www.amazon.co.jp/dp/4297126273)
![GAS本.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/68c54083-2d8f-c3c7-2dfa-5178a8083951.jpeg)

ベースはGASレクチャーの内容ですが、説明の仕方を変えたり、コンテンツ追加したりしてますのでぜひお手にとってほしいです！



# 2020/5/1 更新！

資料をV8エンジン対応版 に更新しました！

主な変更内容は

- `var` をやめて `const` `let` に置き換えた
- 文字列の扱いを [テンプレート文字列](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/template_strings) を使うようにした
- 内容を見直して説明を厚くしたり、表現を変えたりした

2020/5/1時点で、世の中はコロナウィルス対策で非常事態宣言が出されているゴールデンウィークを迎えていますが、ステイホームしてる間にGASの学習をしたい人のお役に立ってほしい！

資料(Googleプレゼンテーション)はこちら！！
https://docs.google.com/presentation/d/1B4av1gPS9xW4XVRqcih6R4Oe5nQabsm3AYO54Y9HDQ0/edit?usp=sharing

----------



2018年に社内のノンプログラマ向けに「GoogleAppsScriptレクチャー」を行いました。
その時の資料が、Googleプレゼンテーションにして400ページを超えてしまっていて、公開しようにもQiitaに書き起こすのは大変だし、SlideShareにPDFで公開しようかなと思ったのですが、今後資料を更新する可能性もあるし、更新してアップすると別投稿扱いになるのかなとか思ってずっと躊躇していたのですが、まぁだったらGoogleプレゼンテーションのままでいいんじゃないかな、と思い至ったのでここに公開します。

# ノンプログラマの方へ

このところRPAブームではありますが、(高いお金を払って導入するような)RPAツールは確かに強力かもしれませんが、私の印象では「そんなツール使わなくてもGAS(とその周辺のこと)がわかってたら自分たちでなんとかなることも多いのでは？」という思いが強いです。

プログラミングが義務教育になるじゃないですか。2019年時点で「社会人としてPC(を始めとするITスキル)が無いと話にならない」という時代になってると思うのですが、おそらく向こう10年20年たったら「社会人としてプログラミングできないなんて話にならない」っていう時代になると思うんです。AIに仕事が奪われるんじゃなくて、プログラムできる人によってその作業が置き換えられるんです、きっと。(まぁAIもプログラムなんだろうけど)

現時点でプログラミング初心者が学ぼうと思ったときに、GASって入り口としては最適な気がします。環境構築などの作業が不要だし、参考になる文献は豊富だし、そういう意味で初学者への参入障壁が低いのです。

GASやってみようかな、って思った方にこの資料が参考になれば嬉しいです。

(が、GASが学べる資料、サイトはいっぱいあるので自分に合ったものを探すのがいいと思います！元も子もないけど、[Google Apps Script入門 \(全20回\) \- プログラミングならドットインストール](https://dotinstall.com/lessons/basic_google_apps_script_v2) なんて最高だと思います。(有料プランだけど)


その他、私の思いは 

[プログラミングできるようになると何がいいのか？](https://qiita.com/sakaimo/items/3a598ca304e13ee3ccdd) 
とか 
[ノンプログラマにGASを広めたい話](https://qiita.com/sakaimo/items/5941b45bc1a227557645)

にまとめてあります。


# レクチャ資料の内容について

GASといいつつ半分くらいはJavascriptのことになってますし、「体系的」「網羅的」な内容ではないと思います。私が思う「これを知ってれば自分の業務を自動化することに使えるのでは？」という基準で作りました。ので、その道に通じている人から見ると説明が不足しているところがあるかもしれませんがご了承ください

スライドのはじめにも書きましたが

>実際のレクチャではこの資料を見ながら、私がホワイトボードに書いて説明したり、ライブコーディングしていくなどの補足要素があってこそ成り立つ部分もあったりします。
>
>ですので、まったくの初学者がこのドキュメントを見たときに説明不足で「え？」ってなる箇所があるかもしれませんが、そゆことでご了承ください。


可能であれば私が直接教えたい！



# すでにデキる方へ

「間違い」があったらご指摘いただきたいです。間違った知識が広まるのはよろしくないので。

さらに「教える側」の方には、ぜひ「もっとうまい説明の仕方」をお聞きしたいです。「こういう図を使うといい」とか「こういう流れで話をするといい」など、アドバイスほしいです！

私が教えた中では「ループ処理」が詰まりポイントでした。



# 資料はこちら

Googleプレゼンテーションです。

# V8対応以前のもの
https://docs.google.com/presentation/d/1nHxLlNwNg23j_bp0JBgRhjUQpnm0E_S5OK4VAXiS2y8/edit?usp=sharing


# 2020/5/1 更新！ V8エンジン対応版
https://docs.google.com/presentation/d/1B4av1gPS9xW4XVRqcih6R4Oe5nQabsm3AYO54Y9HDQ0/edit?usp=sharing
terraform importを試してみたので手順とか個人的ハマりポイントとか

# terraform import手順

簡単な例でS3バケットのimportをしてみる。
先に書いておくと、terraform importは現状のAWSリソースの情報をいい感じにterraformのtfファイルに書き起こしてくれるわけではなく、tfstateファイルにリソース情報を記録してくれるだけ。
あとはterraformのドキュメントとtfstateファイルを参考にtfファイルを手書きする感じとなる。

## 1. importしたいリソースをmain.tfに記載

`resource (リソースタイプ) (リソース名)` の形式で記載する。
※リソース名はterraform内の識別名

```:main.tf
resource "aws_s3_bucket" "test" {
}
```

## 2. terraform importコマンドでterraform.tfstateファイルに状態を保存


`terraform import (リソースタイプ).(リソース名) (importするリソースID)`の形式でコマンドを実行する。
※S3バケットの場合importするリソースIDはバケット名

```bash
terraform import aws_s3_bucket.test tomohiko.io
```

※もしエラーが出たら`terraform init`を実行してAWSプラグインをインストールする

## 3. terraform.tfstateファイルからmain.tfファイルに必要なパラメータを抜き出しmain.tfファイルに記載

terraform.tfstateファイルにimportしたリソースの状態が記録されるので、その情報とterraformのドキュメントを参考にmain.tfファイルを完成させる。

※デフォルト設定のS3を作成するだけならbucketの指定だけで大丈夫です。

```:main.tf
resource "aws_s3_bucket" "test" {
  bucket = "tomohiko.io"
}
```

# 個人的ハマりポイント

## IAM Role

IAM Roleを定義するためには下記3つのresourceと1つのdataを定義する必要がある。

policy

* aws_iam_role
* aws_iam_policy_document
* aws_iam_role_policy

data

* aws_iam_policy_document

自分の書いたコードの一部を抜粋するとこんな感じ。

```
resource "aws_iam_role" "IAMロール名" {
  name               = "IAMロール名"
  assume_role_policy = "${data.aws_iam_policy_document.IAMロール名.json}"
}

data "aws_iam_policy_document" "IAMロール名" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["ecs-tasks.amazonaws.com"]
    }
  }
}

resource "aws_iam_role_policy" "IAMロール名" {
  name   = "IAMロール名"
  role   = "${aws_iam_role.IAMロール名.id}"
  policy = "${data.aws_iam_policy_document.IAMロール名-policy.json}"
}

data "aws_iam_policy_document" "IAMロール名-policy" {
  statement {
    actions = [
        "s3:*"
    ]
    resources = [ "*" ]
  }
}
```

## ECS

コンテナ起動時にこんな感じのエラーが出る

```
CannotPullContainerError: API error (500): Get https://111122223333.dkr.ecr.us-east-1.amazonaws.com/v2/: net/http: request canceled while waiting for connection"
```

AWSのドキュメントに全て書いてあるが、パブリックサブネット+パブリックIP自動割当じゃないとインターネットに接続できず、コンテナイメージをプルできないため。
(もしくはIP自動割当OFF+NATゲートウェイを設置&ルーティング設定)

[コンテナイメージをプルできないエラー \- Amazon Elastic Container Service](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task_cannot_pull_image.html)
railsで複合主キーをやめるmigration

# 概要

railsのシステムでは複合主キーは認められてません。全てテーブルがidという自動採番の主キーを持つのが決まりです。

それはわかっていたのですが、多対多の中間テーブル、例えば、モデルで言えば下記ようなものです。

```rb
class User < ApplicationRecord
  has_many :user_skills
  has_many :skills, inverse_of: :users, through: :user_skills
end

class Skill < ApplicationRecord
  has_many :user_skills
  has_many :users, inverse_of: :skills, through: :user_skills
end

# これが私のいうところの中間テーブルです。
class UserSkill < ApplicationRecord
  belongs_to :skill
  belongs_to :user
end
```


これだけは自分の経験上納得がいかないというか、先入観も大きかったと思いますが、下記の理由で複合主キーを使っていました。

* 必要のないIDの分の無駄な容量が増える
* 頻繁にすげ替えが行われるとIDが枯渇するんじゃないか？

ただ、複合主キーで運用してみていくつかの問題がわかっています。

* UserSkillをレシーバーにして削除ができない。
* UserSkillをレシーバーにして更新ができない。
* UserSkillをeager_loadできない。

他にもあるかもしれませんが、今の所私が把握してるのは上記です。

最近は容量に関して言えばストレージもだいぶ低価格になってきてるし、アクセス速度の早いストレージも低価格になってきてます。IDの枯渇に関してはbigintであれば一般的なシステムでは多分問題にならないので、気にしなくてもいいかもと思うようになってきました。

[こういうGem](https://github.com/composite-primary-keys/composite_primary_keys)もあるのですが、いつまでメンテナンスされるかわからないし、深いところに手を入れてるのでメンテナンスが止まったとき自分でどうにかするコストがかかりそうだと思いました。

そこでRailsの恩恵を受けた方がいいと思うテーブルに関しては複合主キーをやめてみようと思い、そのmigarationを書いてみました。

```rb
class UserSkillToSinglePKey < ActiveRecord::Migration[5.2]
  def change
    remove_foreign_key :user_skill, :skill
    remove_foreign_key :user_skill, :user
    reversible do |change|
      change.up do
        execute 'ALTER TABLE user_skill DROP PRIMARY KEY'
      end
      
      change.down do
        execute 'ALTER TABLE user_skill ADD PRIMARY KEY (skill_id, user_id)'
      end
    end
    add_column :user_skill, :id, :primary_key, unsigned: true, first: true
    add_foreign_key :user_skill, :skill
    add_foreign_key :user_skill, :user
  end
end
```

ポイントとしては生SQLのところで`reversible`を使ってる点、foreign_keyを外さないと主キーをDROPできないことと、`add_column :user_skill, :id, :primary_key`とすると、勝手にAUTOINCREMENTになるところくらいですかね。

もし、運用しているサービスにやるのであれば、テーブルロックがかかるのでレコード数によっては問題になるかもしれません。また、一度外部制約を外すので不整合が起きる可能性があるとは思いますのでその点のも考慮に入れてください。
flexboxで全体は中央に配置するが中身は左寄せで並べたい時の方法

# 始めに
flexboxで中央寄せにする場合は `justify-content: center`を使うと思いますが、これを使うと以下のように下の部分も中央に並んでしまいます。

![スクリーンショット 2019-03-23 23.42.21.png](https://qiita-image-store.s3.amazonaws.com/0/187768/50b80bc0-94c8-2062-03d5-8583ea9e8c6f.png)

これを以下のように全体は中央に揃えつつ、下の部分はきちんと左から並べるようにする方法を紹介したいと思います。
![スクリーンショット 2019-03-23 23.41.56.png](https://qiita-image-store.s3.amazonaws.com/0/187768/a716ead7-39e2-5afc-53d0-11d96efeabd2.png)

# やり方
やり方は単純で、ラッパーとなるflexboxの幅をアイテムが入るギリギリの幅にし、中央寄せにします。
例えばアイテムの幅が120pxの場合、4カラムを表示するには480px必要になります。この時ラッパーの幅を480pxにして`margin: 0 auto`でラッパーを中央寄せにしたら左から並べつつ全体を中央に寄せられます。
5カラムを表示するには600px必要になるので、600pxからはラッパーの幅を600pxにすればいいです。

```scss:4カラム、5カラム指定
.flex-center {
  display: flex;
  margin: 0 auto;  // ブロック全体を中央寄せになるように設定
  flex-wrap: wrap;

  // 4カラム表示のためのサイズ設定
  @media only screen and (min-width: 480px) {
    max-width: 480px;
  }

  // 5カラム表示のためのサイズ設定
  @media only screen and (min-width: 600px) {
    max-width: 600px;
  }
}
```

図で表すとこんな感じになります（この図で伝わるか微妙ですが・・・）

![スクリーンショット 2019-03-23 23.48.37.png](https://qiita-image-store.s3.amazonaws.com/0/187768/10a207d9-004a-303d-e917-e2f2b9cafef4.png)

ここまで書いて後はなんとなくわかってきたと思いますが、後は表示したいカラム数ぶんだけ書いていけばいいです。CSSで書くと大変ですが、SCSSですとmixinとループが使えるので、割と簡単にできます。
このやり方の場合、途中でカラム数に限界がきてしまいますが、大体のサイトはmax-widthを設けて中央寄せにすると思うので問題ないと思います。

```scss:カラムごとの幅設定をmixinを使って指定
// カラムが収まる幅になるように段階的に調整する
// $column-width: 1カラムの幅
// $max-column: 最大カラム数
@mixin flex-fitting($column-width, $max-column) {
  @for $i from 1 through $max-column {
    @media only screen and (min-width: $i * $item-width) {
      max-width: $i * $item-width;
    }
  }
}

.flex-center {
  display: flex;
  margin: 0 auto;
  flex-wrap: wrap;
  
  @include flex-fitting(120px, 10);
}
```

# 終わりに
中央寄せをしつつ中身は左寄せというのは方法がなかなか思いつかなかったのですが、SCSSを駆使すれば比較的簡単に実装することができました。他の人も色々考えているようで、JSや擬似要素を使って空の要素を入れるやり方もありました（参考サイトにリンクを貼りました）。
今回の内容のサンプルコードをCodePenで書いたので、実装の詳細はこちらを参考にしてみてください。

<p class="codepen" data-height="286" data-theme-id="0" data-default-tab="css,result" data-user="wintyo" data-slug-hash="WmPQzg" style="height: 286px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="flex centering">
  <span>See the Pen <a href="https://codepen.io/wintyo/pen/WmPQzg/">
  flex centering</a> by wintyo (<a href="https://codepen.io/wintyo">@wintyo</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# 参考サイト
* [Flexbox で全体を中央に配置しつつ最後の行を左揃えにする](https://qiita.com/QUANON/items/e14949abab3711ca8646)
* [Flexboxで最後の行を左寄せにレイアウトする](https://www.frontnote.work/flexbox-tips/)
Ansibleのparse_cli_textfsmフィルターを使ったNWテスト ②事前事後の差分確認

# はじめに

前回は、Ansibleを使った事前事後の無影響確認を行いました。

[Ansibleのparse_cli_textfsmフィルターを使ったNWテスト ①事前事後の無影響確認](https://qiita.com/tech_kitara/private/d30b3219e8362d7592af)

それ以外のテストパターンとして、想定結果は定義せず、単純に事前事後の差分を表示させたい場合もあると思います。

前回と大きな違いはありませんが、備忘録を兼ねて、変更部分をメインにご紹介します。

# Playbook
今回は(5)と(6)の間でスタティックルートの追加・削除を行っています(A)。
また、(11)のassertモジュールは使わず、フィルタープラグインの一種である`difference`を使って、事前事後のリストの内、事前のみに含まれるもの(B)、事後のみに含まれるもの(C)を抽出しています。
(一発で増減を抽出してくれるのが一番手っ取り早いのですが、ちょっと探した限り見当たりませんでした。。)

```yaml:playbook2.yml
---

- hosts: cisco
  gather_facts: no
  connection: network_cli

  tasks:

    # 前回の(1)～(5)と同様のため省略

    - name: configure static route #(A)
      ios_config:
        lines:
          - ip route 10.3.0.0 255.255.255.0 192.168.1.202
          - no ip route 10.3.1.0 255.255.255.0 192.168.1.202

    # 前回の(6)～(10)と同様のため省略

    - name: display the list only included in "before" #(B)
      debug:
        msg:
          - "{{ sorted_route_before | difference(sorted_route_after) }}"

    - name: display the list only included in "after" #(C)
      debug:
        msg:
          - "{{ sorted_route_after | difference(sorted_route_before) }}"

  vars:
    extracted_route_before: []
    extracted_route_after: []
```

# 出力結果
結果を見ると、ルート削除した`10.3.1.0`が(B)で表示され、追加した`10.3.0.0`が(C)で表示されていることが分かります。

```yaml:
[centos@localhost ansible]$ ansible-playbook -i inventory playbook2.yml

PLAY [cisco] *******************************************************************

(省略)

TASK [configure static route] **************************************************
changed: [192.168.1.200]

(省略)

TASK [display the list only included in "before"] ******************************
ok: [192.168.1.200] => {
    "msg": [
        [
            [
                "10.3.1.0", 
                "24", 
                "192.168.1.202", 
                "S"
            ]
        ]
    ]
}

TASK [display the list only included in "after"] *******************************
ok: [192.168.1.200] => {
    "msg": [
        [
            [
                "10.3.0.0", 
                "24", 
                "192.168.1.202", 
                "S"
            ]
        ]
    ]
}

PLAY RECAP *********************************************************************
192.168.1.200              : ok=12   changed=1    unreachable=0    failed=0   

[centos@localhost ansible]$ 

```
jQueryオブジェクトは$だけではないことを知っていますか？

jQueryオブジェクトとは、ここでは有名な`$`のこととします。
`$('.class-name')`の様に使いますよね。

## jQueryオブジェクトは$だけではないことを知っていますか？
大したことではないのですが、jQueryを導入すると、`jQuery`というオブジェクトもグローバルで定義されます。`$ === jQuery`はTrueです。

`$`は、ChromeのJS Consoleで定義済みの関数のため、そのサイトにjQueryが入っているか確かめるのには`jQuery`が定義されているか確かめるのがおすすめです。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
フルリモートで開発している会社で使用しているツール

# はじめに
私は普段リモートワークで開発しているのですが、会社全体リモートを数ヶ月間する機会があり潤滑に業務を行えていました。色々な会社の方とお話しする機会があるのですが、リモートワークを導入してもうまく機能せず、廃止したという話をよく耳にします。働き改革やエンジニア不足が進む現在において、リモートワークが世に広がるために貢献できれば良いな、という気持ちを込めて記事を書かせていただきます。
尚、Railsを使用した自社サービスの開発を行なっております。

# ツール

## GitHub
言わずも知れたコードのやり取りをできるツール。

## AWS
言わずも知れたクラウドサーバ。

## slack
ベースとしてやり取りに使用しているチャットツールです。
業務内容もそうですが雑談も多くすることが重要です。
作業はWorking out loudですることがおすすめ。
他のツールと連携し、通知先に設定しておくと他の人の作業やサービスの問い合わせを検知でき便利。

## esa
ドキュメントを書き溜めるツール。
仕様やアイデアなどを書き溜めています。

## Qiita team
こちらもドキュメントを書き溜めるツールではあるのですが、esaは開発チーム・Qiitaは会社全体と使い分けています。

## pivotal tracker
タスク管理ツール。スクラムで使用しています。

## Trello
ボードでタスクを管理するのに使用しています。

# Lastpass
社内で使用している共有パスワードを管理しているツール。

## G Suite
様々な会社で使用していて、自身の経験上gmailを使用している会社ではどこも使っています。

## Realtimeboard
現在はmioに変更されたが、URLはrealtimebordのまま。
オンラインで同期的にボードを共有できるサービス。物理的にワークショップを開いているのと近い感覚でアイデアなどの出し合いをできます。
私的に一押しのツールです。

## Zoom
今勢いのあるビデオチャットツール。録画することも可能で、MTGに参加できないメンバーもあとで録画を確認することで議事録とは違った形で非同期にMTGを共有することができる。

## sentry
エラー通知サービス。Webサービスに組み込み定期的にエラーの棚卸しをすることで既存のバグを調査することができます。

## intercom
CS部門とのやりとりで便利。

# 他社で使っていた時に有効だと感じたツール

## Remotty
ソニックガーデン製のツール、常にカメラで顔を写しあたかもオフィスにいるようにやり取りをすることができる。
[Python] 45秒で東大数学（2019年 前期第１問）を解いてみた

Pythonを使って45秒で東大の入試問題を１問解けるのか検証してみました。

Sympyの `integrate(f, (x, a, b))`を用いれば
関数fをxについてaからbまで積分計算することができます。

では早速問題を見てみましょう。
##問題：
2019年 東京大学 前期日程 数学（理科） 第1問
[読売新聞オンラインより問題および解答部を引用](https://www.yomiuri.co.jp/nyushi/sokuho/k_mondaitokaitou/tokyo/mondai/mondai/1306675_5409.html)
<img width="401" alt="Screen Shot 2019-03-23 at 9.44.27 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/315941/ebf583e3-703c-3f9f-5aa3-798fe6f643ad.png">
##手計算での解法
まずは上記の式を展開して、
<img width="495" alt="Screen Shot 2019-03-23 at 9.49.42 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/315941/578ae39b-d30a-0f27-d25b-b84d6d7fbdae.png">
展開した第1項目から4項目までの定積分をそれぞれ計算して最後に
足し合わせます。
<img width="261" alt="Screen Shot 2019-03-23 at 9.47.57 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/315941/92ed4034-1767-f500-2b93-aca7856473d9.png">
##Sympyで解いてみる
まずはSympyをImportして変数xを定義

```sympy:import.py
import sympy as sym
x = sym.Symbol('x')
```
間違えないようにひたすら式を打ち込む
念の為、表示して確認。

```sympy:import.py
f = (x**2+x/sym.sqrt(1+x**2))*(1+x/((1+x**2)*sym.sqrt(1+x**2)))
print(f)
```
出力：(x**2 + x/sqrt(x**2 + 1))*(x/(x**2 + 1)**(3/2) + 1)

打ち間違えがなさそうなら
いよいよ０から１まで積分

```sympy:integrate.py
F = sym.integrate(f, (x, 0, 1))
print(F)
```
出力：**-35/12 + pi/8 + 5*sqrt(2)/2**
解けました。
解答例と比べても合っているようです。

##結論
高速でタイプしてギリいける感じです。
ちなみに１回目は式に目が慣れていなかったので失敗。2分以上かかりました。
よって45秒以内に解を出すにはいかに早く打てるかが鍵となります。
特に途中でタイプミスがあると致命的。
リズムに乗るために本家の45秒を聴きながらやってみるのも良いでしょう。
[![](https://img.youtube.com/vi/fTmJwrD6IzU/0.jpg)](https://www.youtube.com/watch?v=fTmJwrD6IzU)
AWS Certified Security Specialtyの模試を受けてみる

この前一つ受かったのでプラクティスのタダ券がGETできました。
アソシエイトとプロを制覇したわけですが、ここ最近いろいろ増えてきています。
とりあえずどれか受けてみようと思います。ただし、クラウドプラクテショナーは費用対効果薄いので除外。専門知識系のどれか。

## クラウドプラクティショナー

アソシエイトレベルの下のレベルで、入門という位置づけ。とりあえず受けたら？みたいな。
特に特定のカテゴリではなさそう。

https://aws.amazon.com/jp/certification/certified-cloud-practitioner/

>AWS 認定クラウドプラクティショナー試験は、AWS クラウドの知識とスキルを身に付け、全体的な理解を効果的に説明できる個人が対象です。他の AWS 認定 (AWS 認定ソリューションアーキテクト – アソシエイト、AWS 認定デベロッパー – アソシエイト、AWS 認定 SysOps アドミニストレーター – アソシエイトなど) で扱われる特定の技術的役割からは独立しています。

## AWS 認定セキュリティ – 専門知識

セキュリティの専門知識を問う認定試験。レベル的にはアソシエイトとプロの間の位置づけらしいが、一部の知識はプロ以上のものが求められると思う。ただ、この試験はこれまでと被る所が多そうで他の専門知識に比べると専門性は薄く感じる。

>AWS プラットフォームのセキュリティ強化における技術的な専門知識を認定します。経験豊かなセキュリティ担当者が対象です。

## AWS 認定ビッグデータ – 専門知識

awsでbig dataというとredshiftだとかそういう感じ？サンプル問題を見た感じだとそんなにビックデータビックデータしてなかった。なんとなく解けそうな気がしなくもない。

>データから価値を引き出すために AWS のサービスを設計および実装するのに必要となる技術的な専門知識を認定します。複雑なビッグデータ分析に携わる方が対象です。

## AWS 認定高度なネットワーク – 専門知識

ネットワークに特化してる認定試験。これまでの試験の延長線上にあるような気もする。vpnだとかそのあたりが出てくるのかな。苦手じゃないかもしれない。

>AWS、および大規模なハイブリッド IT アーキテクチャの設計および実装における技術的な専門知識を認定します。複雑なネットワーク業務に携わる方が対象です。

## AWS 認定 機械学習 – スペシャリティ

SageMakerとか出てくるんだと思う。サンプル問題みてみても専門性高いですね。これはちゃんと学ばないときついかという感じ。

>AWS クラウドを使用して機械学習 (ML) モデルを構築、トレーニング、チューニングおよびデプロイするのに必要となる技術的な専門知識を認定します。開発およびデータサイエンスの業務に携わる方が対象です。

## そんなわけで、セキュリティスペシャリストを受けてみることにしました。

ネットワークを受けてみようと思ったんだけど・・なぜか選んでみようと思ってpsiのサイト開くと一覧にない。。専門系はMLとセキュリティしかないんですもの。
消去法でセキュリティです。あんまり自信ないです。4割取れたらいい方なんじゃないかな。

AWS認定アカウントのサイトにログインして、```特典```のページを開きます。
受かった試験があれば、```AWS Free Practice Exam Voucher```というのが有効になっているので、```特典を有効にする```をクリック。コードが表示されるのでこれを模試の支払いの時に使います。そしたら支払金額が0に。

試験時間は60分。20問くらいかな。
それでは行ってきます！




・・・・・




ただいま。
そんなわけでお試しで受けてみましたよ。
深く考えずテンポよく答えてみました。20問で30分くらい。

![94.png](https://qiita-image-store.s3.amazonaws.com/0/308709/5263f431-c02e-2c9f-d29c-961bf631e370.png)

- Trasted Advisor
- Cloud Trail
- KMS, CMK
- Inspector

のあたりが多かったです。あとはiamやらセキュリティグループやらの基本的な部分。
CMKのあたりはあまりよくわからんかった。キーマテリアルのインポートとかぜんぜん馴染みないし。
ただ、正直、そんなに答えにくい問題はなかった。もしかしたらそこそこ取れてるんじゃ？とか思ってる。悪くなかったらそう遠くない内に本試験も受けてみよう。

しかし、模試なんてすぐ結果くるかと思ったら、10分経っても来ないですね。
なんか新しい試験ほど通知が遅いのかな。気長に待つか。結果きたら追記します。追記がない場合は結果が死ぬほど悪かったと思ってください。

## 追記

15～20分くらいで結果届きました。

```
総合スコア:  50%

トピックレベルスコア:
1.0  Incident Response: 0%
2.0  Logging and Monitoring: 75%
3.0  Infrastructure Security: 50%
4.0  Identity and Access Management: 75%
5.0  Data Protection: 33%
```

ん～、微妙だ。
でもちゃんとサンプル問題を勉強したり、キャプチャしといた模試の問題を振り返ればいけるぐらいかもしれない。
次受けるのはこれかプラクティショナーにしよう。
当研究室のシステム

当研究室で使用しているシステムの紹介．10～50名程度の小規模グループ用に構築．

![lab_system.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284261/45424709-e9c4-11b9-2527-caa03982b022.png)



gatewayを境に外部/内部ネットワークを分割．

サーバのうちデータを扱うhomeとsamba，それらのデータと他のサーバのデータのバックアップを扱うものは独立のPC．

ほとんどのサーバはXCP-ng上にVMsとして稼働．~~Dockerも考えたけれど，ハードウェアが壊れたときの復旧の速さを考慮して選択~~．Dockerを触ってみたくなり勉強，使用開始．XCP-ng上のVMで利用しつつ，ハードウェアに余裕が出来ればそちらに展開．
複数台のXCP-ngを稼働してVMごとコピーして分散保存しておけば，XCP-ngが壊れてもすぐ復旧可．

ユーザが使用しているPCはUbuntu Desktopであり，LTSPによるFat clientとして稼働．
個別にインストールするのではなく，LTSPサーバで一括管理，LTSPサーバからPXEを利用して各個人のPCにダウンロード・実行．

## 方針
あまり設定・保有データが変わらないものはXCP-ng，そうでないものはDocker．
XCP-ngは複数台稼働しており，バックアップとしてVMごと他のマシンにコピーしている．よって何かあった時にバックアップのVMを起動させれば最短で復旧できる．
一方，データ変更の頻度が高い場合，VMでのバックアップは効率が悪い．どのみちバックアップサーバにデータをバックアップしているのでDockerfileによってシステムを復旧，バックアップサーバからデータも復旧，の方が効率良さそう．

何事にも例外はあるけれど(cups, gitlabなど)．

# 個々のシステム
- [php-fpm on Docker](https://qiita.com/NeK/items/8b539a81a3d9af005471)
- [Apache2](https://qiita.com/NeK/items/22d5849da05cca717a76)
    - php-fpm + http2可
- [PostgreSQL on Docker](https://qiita.com/NeK/items/15d7dbe20d1ace57ffb8)
- [Nextcloud](https://qiita.com/NeK/items/82e16a9cbd2378742cd0)
- [cupsサーバ on Docker](https://qiita.com/NeK/items/e6f52748c73b9062c1aa)
    - [cupsサーバ on Ubuntu Server](https://qiita.com/NeK/items/ddbc1c00065e487777ed)
- [Ubuntu 22.04/20.04 LTS上でのLTSPサーバ構築 : fat / thin clientの管理](https://qiita.com/NeK/items/0a10f9e83bafd6bf980c)

## 細々
- [Ubuntu ServerでDocker Engine + Compose](https://qiita.com/NeK/items/d9431d5cdfa16dffe6dc)

### 段階ごとの説明
- Apache2
    1. 基本: [Apache2 on Docker](https://qiita.com/NeK/items/51bbee008f11f0c62e0e)
    1. php-fpm使用してパフォーマンスアップ: [Apache2 on Docker + php-fpm on Docker](https://qiita.com/NeK/items/17e32812efc2a44b0b53)
    1. 更にhttp2可: [apache2(http2) on Docker](https://qiita.com/NeK/items/22d5849da05cca717a76)
        - 最終形
- Nextcloud
    1. [Nextcloud with Apache2 + PostgreSQL on Docker](https://qiita.com/NeK/items/e3954e87bb5d55e5c5a5)(
        * 対応 : [Apache2 on Docker](https://qiita.com/NeK/items/51bbee008f11f0c62e0e)
    1. [Nextcloud with Apache2 + php-fpm + PostgreSQL on Docker](https://qiita.com/NeK/items/910920aad1644a1ef5b6)
        * 対応 : [Apache2 on Docker + php-fpm on Docker](https://qiita.com/NeK/items/17e32812efc2a44b0b53)
    1. [Nextcloud with Apache2(http2) + PostgreSQL on Docker](https://qiita.com/NeK/items/82e16a9cbd2378742cd0)
        * 対応 : [apache2(http2) on Docker](https://qiita.com/NeK/items/22d5849da05cca717a76)
    1. Nextcloud with Apache2(http2) + PostgreSQL on Docker + ONLYOFFICE on Docker
        * 最終形