OmniAICreator/Qiita-1.07M huggingface dataset:
削除した S3 オブジェクトを復元する

投稿内容は私個人の意見であり、所属企業・部門見解を代表するものではありません。

##参考
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/user-guide/undelete-objects.html

##目的
S3のバージョニングを有効にして削除したオブジェクトを復元してみます

##手順

S3バケットでバージョニングを有効にする
プロパティ＞バージョニングの有効化
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78184/7d55dcc9-0c05-adb3-939c-875d32b2529d.png)

テスト用のファイルをアップロード

```yaml

AWSTemplateFormatVersion: '2010-09-09'
Resources:
  SecurityGroupB:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: vpc-26505643
      GroupDescription: SecurityGroupB
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: '443'
        ToPort: '443'
        CidrIp: 0.0.0.0/0
  SecurityGroupC:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: vpc-26505643
      GroupDescription: SecurityGroupC
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: '22'
        ToPort: '22'
        CidrIp: 172.0.0.0/32
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78184/463b3b96-3142-8822-1e40-25015c085fa0.png)

編集して再度アップロード

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  SecurityGroupB:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: vpc-26505643
      GroupDescription: SecurityGroupB
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: '80'
        ToPort: '80'
        CidrIp: 0.0.0.0/0
  SecurityGroupC:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: vpc-26505643
      GroupDescription: SecurityGroupC
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: '22'
        ToPort: '22'
        CidrIp: 172.0.0.0/32
```
バージョンを表示すると最新バージョンと古いバージョンが表示される
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78184/990ebdfd-2d0b-973d-5353-20e3fd8d2709.png)

バージョンを非表示して、オブジェクトを削除する。

バージョン表示すると、削除マーカーと表示される
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78184/72942999-0cb6-799a-0847-df32562f7353.png)

S3は、オブジェクトがバージョニングが有効なバケット内にあったため、そのオブジェクトは削除されず、削除マーカーを挿入し、オブジェクトを削除したものとみなします。
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/DeleteMarker.html

ここでは、復元したいので、削除マーカーがついたオブジェクトを選択し削除します
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78184/22f2eee4-1d39-0391-d5c2-1ae83b833582.png)

バージョンを非表示にすると削除されたオブジェクトが復元できています
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78184/245b0729-4eba-e805-8b2d-3acc869844a0.png)

復元したオブジェクトは、修正後のファイルなので、一番古いものにリストアするには、再度バージョンを表示し、最新バージョンのオブジェクトを表示して削除します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/78184/771ccf66-e121-b84e-cc8a-1147240746b2.png)

バージョンを非表示にオブジェクトをダウンロードして中身を確認すると最初の状態のファイルにリストアされています

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  SecurityGroupB:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: vpc-26505643
      GroupDescription: SecurityGroupB
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: '443'
        ToPort: '443'
        CidrIp: 0.0.0.0/0
  SecurityGroupC:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: vpc-26505643
      GroupDescription: SecurityGroupC
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: '22'
        ToPort: '22'
        CidrIp: 172.0.0.0/32
```
Pythonでサードパーティー製モジュールのインストール

#Python サードパーティ製モジュールのインストール

##pyzmailのインストール

失敗したケース

```
sudo pip3 install pyzmail
```

```
Command "python setup.py egg_info" failed with error code 1 in /private/tmp/pip-install-uf8eu0aq/distribute/
You are using pip version 10.0.1, however version 18.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
```

改善策

```
sudo pip3 install pyzmail36
```

pyzmailモジュールはinactiveになったため、開発者がpyzmail36モジュールを開発し直してくれたようです。
crontabではほとんどPATHが通っていない事を確認する

最近、oracleに対してSQLPlusやSQL*Loaderで定期的にデータを云々する必要があったのですが、crontabでハマって手間取ったので備忘録も兼ねて残しておきます。

# 前提
OS：CentOS Linux release 7.0.1406 (Core)

# 結論
* crontabでは`/usr/bin`と`/bin`しかパスが通っていない
* ちなみに実行時のカレントディレクトリはユーザのホームディレクトリ

# 確認
## printenvでPATHを表示した場合
```bash
[kabu0404@DARIUS ~]$ printenv PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/kabu0404/.local/bin:/home/kabu0404/bin
```

## crontabで同じコマンドを実行した場合
```bash
[kabu0404@DARIUS ~]$ crontab -l
*/1 * * * * printenv PATH > ~/path.txt
[kabu0404@DARIUS ~]$ cat path.txt
/usr/bin:/bin
```

## crontab内でパスを通した場合
```bash
[kabu0404@DARIUS ~]$ crontab -l
*/1 * * * * printenv PATH > ~/path_before.txt; export PATH=/usr/local/bin:$PATH; printenv PATH > ~/path_after.txt
[kabu0404@DARIUS ~]$ cat path_before.txt
/usr/bin:/bin
[kabu0404@DARIUS ~]$ cat path_after.txt
/usr/local/bin:/usr/bin:/bin
```

## 実行時のカレントディレクトリ
ついでに調べてみた

```bash
[kabu0404@DARIUS ~]$ crontab -l
*/1 * * * * pwd > ~/pwd.txt
[kabu0404@DARIUS ~]$ cat pwd.txt
/home/kabu0404
```

# チラシの裏
crontabを使用する場合は、実行するスクリプト内でパスを通すか、コマンドをフルパスで書くか、どちらかでしょうか。パスを通した方が、別環境でパスが違う時とかに対応しやすそうですかね。
いずれにせよ`which`を使うなどして「自分が使うコマンドがどこにあるのか」というのは意識しておいた方が良さそうですね。
[cocoa][swift]BUKURO.swift 2017-12 を振り返る

<p>2017年12月6日（水）の夜間、東京都豊島区の<a href="http://co-forest.com/">池袋コワーキングスペース OpenOffice FOREST</a>におきまして、「BUKURO.swift 2017-12」を開催致しました。</p>

# 勉強会について
<ul>
<li>Cocoa勉強会 関東 Swift分科会 です。</li>
<li>ほぼ毎月、池袋コワーキングスペース OpenOffice FOREST で開催してます。</li>
<li>macOS/iOS/watchOS/tvOSプログラマーのための勉強会です。</li>
<li>プログラムに関する知識や経験を共有を目的としています。</li>
<li>会の活動内容や発表資料、サンプルコードは公開を前提としています。</li>
<li>申し込みは、connpassから。<br /><a href="https://cocoa-kanto.connpass.com/">https://cocoa-kanto.connpass.com/</a></li>
</ul>

# 概要
<ul>
<li>発表資料は<a href="https://cocoa-kanto.connpass.com/event/71296/">connpassページ</a>からどうぞ！</li>
<li>会場の様子は、ハッシュタグ『#cocoaswift #cocoastudy #bukuroswift』でtweetしています。</li>
</ul>

# ぼっち開発について
<p>今回からMAKERS関連の発表をしていこうとなったのですが、それに賛同していただいて、用意していただいた発表が『ぼっち開発について』。<br />
紹介されているのは、日誌を書くこと。自分はこういう話を聞くと、直ぐに日誌をどう実装するかと脱線してしまいますが、そんなことにならないように、来年こそは頑張らないと！という気持ちになりました。<br />
資料は、実際のノートの内容が掲載されているため、公開されません。あしからず。</p>

# Swiftリファレンスを作っています
<p>Swiftは仕様が複雑だ！書籍の説明は申し訳ないですが冗長だ！だったら自分でリファレンスを作ればいい！githubで公開すれば、執筆手伝ってくれるかも！<br />
ということで、始めました。<br />
<a href="https://github.com/murakami/Swift_in_a_Nutshell">Swift_in_a_Nutshell</a></p>

# Swiftで線形代数
<p>発表者は自身の欠点は分かっています。目的があったのに、その手前で興味が赴くままに進んでしまう。神経回路網の数理をやりたいのに、その基礎となる線形代数から始めてしまう。BLASを使った例です。</p>

# TensorFlowについて
<p>GoogleのMachine Learning Developer Meetupに参加してきたので、それの報告です。ただ、TensorFlowそのものより、登壇された伝説のJeff Dean氏の話題で盛り上がってしまいました。<br />
彼のキーボードはキーが二つしかないそうです。0と1だそうです！<br />
gccの最適化オプション-o4を指定すると、彼にソースが送られ、最適化されて返ってくるそうです！</p>

# BUKURO.makers
<p>ものづくり関連として、今回は、昔販売されていた左手で操作するSmartScrollという機器をSwiftでI/O KitのUSB Device Interface使って利用する挑戦が発表されました！</p>

# 三次元グラフフィックスの相談
<p>参加者からの相談で三次元グラフィックスについて、議論が白熱しました。これについては、機会をみて、取り上げたいと考えています。</p>

# Xcodeのバージョンをあげたら単体テストで警告が
<p>これも参加者からの相談です。皆で解決策を探っていきました。</p>

【関連情報】
<a href="https://qiita.com/advent-calendar/2018/cocoa">Cocoa Advent Calendar 2018</a><br />
<a href="https://cocoa-kanto.connpass.com/event/71296/">BUKURO.swift 2017-12</a><br />
<a href="https://cocoa-kanto.connpass.com/">Cocoa.swift</a><br />
<a href="https://www.facebook.com/groups/cocoa.kanto/">Cocoa勉強会 関東</a><br />
<a href="http://www.bitz.co.jp/weblog/">Cocoa練習帳</a><br />
<a href="https://qiita.com/m_yukio">Qiita</a><br />
Pythonのmapでリストの要素全てに対してインスタンスメソッドに呼び出しを行う。

覚書です。

## 概要
`map()`とlambdaを使うとワンライナーでかける。

## サンプル

```python:sample.py
class MyClass:
    def __init__(self,num):
        self.num = num
    
    def double(self):
        return self.num * 2

lis = [MyClass(1), MyClass(2), MyClass(3)]

lis_2 = map(lambda x: x.double(), lis)

for i in lis_2:
    print(i)

# output
# 2
# 4
# 6
```
C++によるデザインパターン（TemplateMethodパターン）編

# はじめに
現在、デザインパターンを学習するために、デザインパターンの本として評価が高い「増補改訂版Java言語で学ぶデザインパターン入門」を読んでいます。ただ文字通り、この本のデザインパターンはJavaで書かれているので、C++を主に使う自分の学習のためにこの本の中のJavaのコードをC++に書き換えてみました。元のJavaのコードは[ここ](http://www.hyuki.com/dp/index.html#download)からダウンロードできます。今回は、TemplateMethodのC++版のコードを書いてみました。(*2018/11/21 AbstractDisplay のデストラクタでメモリリークが起こるバグを修正*)

#TemplateMethodとは
TemplateMethodとは、似たような機能のクラスをまとめて、スーパークラスで処理の流れを決定するパターンです。例えるなら、パワポのテンプレート機能は、同じスライドを作成するという作業は共通しており、各テンプレートは微妙にそれぞれのデザインが違うということに似ていると思います。

#CharDisplayクラス

~~本当はコンストラクタの引数の型をcharにするべきですが、めんどくさいし、本質は変わらないのでstd::stringにしています。ようするに手抜きです。~~きちんとchar型で動くように修正しました。

```c++:CharDisplay.cpp
#include"CharDisplay.h"

CharDisplay::CharDisplay(const char *ch) : ch(ch){}


void CharDisplay::open() {
	std::cout << "<<" ;
}

void CharDisplay::print() {
	std::cout << ch;
}

void CharDisplay::close() {
	std::cout << ">>" << std::endl;
}
```

```c++:CharDisplay.h
#pragma once
#include"AbstractDisplay.h"

class CharDisplay : public AbstractDisplay {
private:
	const char *ch;

public:
	CharDisplay(const char *ch);
    void open();
	void print();
	void close();
};
```

#StringDisplayクラス
```c++:StringDisplay.cpp
#include"StringDisplay.h"

StringDisplay::StringDisplay(std::string string) :string(string), width(string.size()) {}

void StringDisplay::open()
{
	printLine();
}

void StringDisplay::print()
{
	std::cout << "|" + string + "|" << std::endl;
}

void StringDisplay::close()
{
	printLine();
}

void StringDisplay::printLine()
{
	std::cout << "+";

	for (int i = 0; i < width; i++) {
		std::cout << "-";
	}
	std::cout << "+" << std::endl;
}
```

```c++:StringDisplay.h
#pragma once
#include"AbstractDisplay.h"
#include<string>

class CharDisplay : public AbstractDisplay {
private:
	std::string ch;

public:
	CharDisplay(std::string Newch);
    void open();
	void print();
	void close();
};
```

#AbstractDisplayクラス(main関数も含む)
ここでは、Javaのガベージコレクションを再現するために、unique_ptrを使用しました。また、Javaの元コードにfinalが使われているので、ここでもC++11から追加されたfinalを使用しています。

```c++:AbstractDisplay.cpp
#include"AbstractDisplay.h"
#include"StringDisplay.h"
#include"CharDisplay.h"

void AbstractDisplay::display()
 {
	open();
	for (int i = 0; i < 5; i++) {
		print();
	}
	close();
}

int main() {
	std::unique_ptr<AbstractDisplay> d1(new CharDisplay("H"));
	std::unique_ptr<AbstractDisplay> d2(new StringDisplay("hello world"));
	std::unique_ptr<AbstractDisplay> d3(new StringDisplay("こんにちは"));

	d1->display();
	d2->display();
	d3->display();

}
```

```c++:AbstractDisplay.h
#pragma once
#include<iostream>
#include<string>
#include<memory>

class AbstractDisplay {
public:
　　virtual ~AbstractDisplay() {};
	virtual void open() = 0;
	virtual void print() = 0;
	virtual void close() = 0;
	virtual void display() final;
};

```

#最後に
本記事では元コードのC++の書き換えに重点を置いたためにデザインパターン自体の説明は端折っています。デザインパターンや元コードの解説について詳しく知りたい場合は元コードが載っている「増補改訂版Java言語で学ぶデザインパターン入門」をおすすめします。本記事がデザインパターンで悩むC++学習者の手助けになれば幸いです。
Pythonでasyncioとコルーチンを使ってスレッドっぽい非同期処理をする

## TL;DR
Pythonでコルーチン使いつつ、割とスレッドモデルっぽい動作を`asyncio`を使って実現する。

## やりたいこと
- 複数のコルーチンが非同期に実行される前提
- それぞれ個々のコルーチンの実行が終わった時点で、返り値を即座に受け取って処理したい

### もう少し詳しく 
- 参考：[Pythonにおける非同期処理: asyncio逆引きリファレンス](https://qiita.com/icoxfog417/items/07cbf5110ca82629aca0)（すごくタメになるのでオススメ）

ここの「並列で処理を行いたい(固定長)」のところに、`asyncio.gather`と`asyncio.wait`を使った例がそれぞれ載っているけど、返り値の処理はいずれも__全部のコルーチンの処理が終わってから__行われるようになっていた。
これを、__各コルーチンが終了した時点で即座に__返り値の処理もさせつつ他のコルーチンの終了も待つ、ということをしたい。

### 利用したバージョン
Python3.7.1 です。
ちょっとバージョンが下がると動かないかもしれない。

## 方式1： `asyncio.as_completed`を使う
こんな感じ。

```Python
import asyncio

# コルーチン1
async def test1():
    await asyncio.sleep(3)
    print('now in test1.')

    return "test1"

# コルーチン2
async def test2():
    await asyncio.sleep(1)
    print('now in test2.')

    return "test2"

# 結果の非同期受信用
async def fmap(f, fs):
    for res in asyncio.as_completed(fs):
        r = await res
        f(r)


if __name__ == '__main__':
    # 複数の coroutine から future のシーケンス作成
    f1 = asyncio.ensure_future(test1())
    f2 = asyncio.ensure_future(test2())
    futures = [f1, f2]

    # future シーケンスを実行して、処理が終わるごとにすぐ受信側処理もする
    loop = asyncio.get_event_loop()
    loop.run_until_complete(fmap(print, futures))
```
実行結果。

```
now in test2.
test2
now in test1.
test1
```
## 方式2： コールバックを使用する
```Python
import asyncio
import functools

# コルーチン1
async def test1():
    await asyncio.sleep(3)
    print('now in test1.')

    return "test1"

# コルーチン2
async def test2():
    await asyncio.sleep(1)
    print('now in test2.')

    return "test2"

# コールバック
def callback(f, future):
    f(future.result())


if __name__ == '__main__':
    # 複数の coroutine から future のシーケンス作成
    f1 = asyncio.ensure_future(test1())
    f2 = asyncio.ensure_future(test2())
    futures = [f1, f2]
    # コールバック設定
    for f in futures:
        f.add_done_callback(functools.partial(callback, print))

    # future シーケンスを実行
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.gather(*futures))
```
結果は方式1と同じです。個人的には方式1の方が好き。

## `asyncio.as_completed` を簡単に解説
方式1を書いてるときにちょっとハマったので、`asyncio.as_completed`の動作をわかったなりに少し解説してみる。

先程書いたコードの中でこの関数を使ってる `fmap` というコルーチンを見ると、

```Python
   async def fmap(f, fs):
       for res in asyncio.as_completed(fs):
           r = await res
           f(r)
```
関数bodyの1行目で、`asyncio.as_completed(fs)` の返り値から`for`文で`res`を拾ってきてる。実は`asyncio.as_completed(fs)`の型は`Iterator[Awaitable[...]]`となっていて、awaitableオブジェクト（実はコルーチン）のイテレータになってる。
通常のイテレータは`Iterable`な型を持つ値をくるむのだけれども、その`Iterable`の非同期版が`Awaitable`だと思えばいい。
なので、`Awaitable`型の変数`res`に対して`await`文を適用し、

```Python
    await res
```
とすることで、さらに`Awaitable`でくるまれた中身の値が取り出せるという仕組み。
Gitでプルリク作ってコンフリクトが起きた時に、「merge」コマンドで解消する手順

#コンフリクトが起きているときにマージコマンドで解消する手順
###ローカルの作業ブランチから、masterブランチに向けてプルリク作っていた場合
作業していたブランチ上で

```$ git merge master```

上記コマンドを実行し、現在のブランチにmasterをマージする。
次に

```git status``` で変更ファイル確認して、
```git add -A```
```git commit -m "マージした～"```

これで再度pushし、プルリク作ればコンフリクトは解消されている！
<!DOCTYPE>って何？

ようこそ、HTML Advent Calendar 2018へ！カレンダーのはじめにふさわしく、HTMLの冒頭に書く`<!DOCTYPE>`について掘り下げてみます。

## 今ではだいぶシンプルになったけど

HTML5では`<!DOCTYPE html>`とごくシンプルなものですが、昔はもっと長く、しかも何種類もありました。

* HTML 4.01 Strict…`<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">`
* HTML 4.01 Transitional…`<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">`
* HTML 4.01 Frameset…`<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">`

呪文のように長い上に、URLまで入っていて、そらで書けるものではありません。

どうしてこんなに長かったDOCTYPE宣言が、HTML5ではここまでシンプルになったのでしょうか。

## HTMLの先祖…SGML

では、歴史の針をぐいっと戻してみます。HTMLより前に、「テキスト＋タグ」で意味構造を表現するというプロジェクトとして、SGMLが始まりました。そして、HTMLはもともとこのSGMLの仕様に則って作られたものだったのです。

SGML自体は利用者がタグを定義できるのですが、その定義にはDTDという別な言語が使われていました。そして、SGMLとDTDを結びつけるためのものがDOCTYPE宣言でした。

```SGML
<!DOCTYPE ルート要素 PUBLIC "識別子" "URL（省略可）" [
  <!-- サブセット（省略可） -->
]>

<!DOCTYPE ルート要素 SYSTEM "URL" [
  <!-- サブセット（省略可） -->
]>
```

`PUBLIC`として既知の`"識別子"`でDTDを指定するか、`SYSTEM`として`"URL"`を指定するかで、文書のDTDを指定していました。そして、文書ごとの`サブセット`も指定可能でした。SGMLを元にしたHTMLにも、この形を受け継いだDOCTYPE宣言がなされることとなりました（上に挙げたHTML 4.01用の3つも、上の形に従っていることがわかると思います。DTDのURLも、HTTPSにリダイレクトされますがアクセスは可能です）。

## 現実問題

本気でSGMLを処理するには仕様が巨大すぎるために、SGMLが普及したのは狭い範囲にとどまり、「自分でタグを定義できるマークアップ言語」の普及はより簡略化したXMLの展開を待つこととなりました。

そして、HTMLのほうも、HTML 3.2以前の頃はInternet Explorer対Netscape Navigatorのブラウザ戦争が華やかなりし頃で、ブラウザごとに勝手に拡張がなされていました。これではまずいと、HTML 4.0ではブラウザの独自拡張もある程度は採用しつつ標準化を進めていきました。

ただ、いきなり標準に沿った表示に切り替えてしまうと、既存のページが全て崩れてしまうという大災害となるので、「新しいDOCTYPEを書いているものは標準に従って表示し、そうでないものは従来の表示（Quirksモード）にする」という処理が組み込まれました。これが**DOCTYPEスイッチ**です。

## HTML5においては

HTML5はSGMLから独立した形となっているので、理論的にはDOCTYPEは不要となるはずです。ただ、上のようにDOCTYPEスイッチがある以上、DOCTYPEなしではQuirksモードとなってしまいます。そこで、「既存のIE6などもきちんと標準モードに切り替わる」ことを考慮して選ばれた形が、`<!DOCTYPE html>`です。今から新たなHTMLを作る場合に他のDOCTYPEを使う必要はないでしょう。

## 結論

* 今は`<!DOCTYPE html>`だけでいい。
* 一度互換性で入れた機能は、あとから別な意味で制約になることもある。

## 外部リンク

* [FirefoxでのDOCTYPEスイッチ](https://developer.mozilla.org/ja/docs/Archive/Web_Standards/Mozilla_s_DOCTYPE_sniffing)
 * リストを見ていると、呆れるほど多くのDTD識別子が並んでいました。
新卒エンジニアが成長するために挑戦していること

こんにちは。あくあ([@aqua_engineer](https://twitter.com/aqua_engineer))と申します。
今年の4月にIT業界に新卒入社しました。時期的にエンジニアとして働き初めて半年が経過という段階になります。最近、エンジニアのスキルや知識の成長するために何が必要か。また、どのようなことをするべきかということを考える機会が増えてきたので、少し自分がやっていることをまとめていければと思います。
まだ自分の中でもどのやり方が自分に最適なのかどうかが定まっていない状態ですので、ご了承ください。

## とにかく情報を収集する
明らかに現状の自分には、知識が足りない！

このことは自分でも実感しています。というのも、大学時代に、ネットワークに関することの勉強に偏っていた。もちろんネットワークを学んだことで、役に立っていることもたくさんあります。しかし、サーバーサイドエンジニアでは、データベース、プログラミングスキル、サーバーの仕組み、インフラに関することなど様々な知識を持つことが要求されると思います。そのためにも、幅広い知識を持つためにも、自分の知らないことに関しては、すぐに吸収して行くことが大切であると思います。
普段から自分の知らないことに情報に敏感に反応でき調べる癖をつけていくようにする。

## 自分に足りないことが何かを認識する
自分がここの分野に関しての知識が少ないな、ここの分野苦手であるな、ということを知ることが必要であると感じています。苦手の克服をしていくことによって、自分の強みであることにも活かせるようになると思っています。

## わからないことがあったときに質問する前に
わからないことがあったときにすぐに聞いてしまうということをやっていましたが、自分でも事前にできる限り調べた上で質問をするようにしています。調べているうちに解決して、より自分の力になることもあるかもしれません。また、自分の意見を持った上で質問をするようにしたいと思います。

## どんなエンジニアになりたいか目標を持つ
長期的な期間（3~5年後）でどのような、状態のエンジニアになりたいかを考えておき、その状態を目標にする。
実現するために、達成するために必要なことを考え短期的な目標を立てて実践する。ここでの、短期的な目標については、できる限り具体的な目標にしておきたい。

## インプット・アウトプットできる機会を作っておく
自分の場合ですと、普段の業務の中で身につけられることがたくさんあると思っているので、わからないことや苦労したことに関してはメモをしておくようにしています。その場で解決できたことに関しては、解決法をまとめておく。また、解決できなかったことに関しては、後日時間が用意できるときに、調べて解決するようにしています。
### 具体的な行動
* 自分が調べてわかったことや問題にぶつかって苦労したことをブログに書く
    * [自分のブログ](https://aqua-engineer.com)
* 自分に足りない知識に関する本を買う
* 周りの人がやっていることに興味を持ち、情報を集める
* 自分が作ってみたいというものを作る
* サンプルのコードを少しアレンジしてみる

### まとめ
自分でも、大学時代とか自分で調べることなどをせずに過ごしていましたが、実際に社会人になり、エンジニア生活が始まってからは、自分から積極的に勉強をして、知識やスキルのある人になりたいと言う思いが強く持っていることに驚いています。

まだまだ、新卒でできないことが多い状態ですが、今のうちにたくさん困難にぶつかって成長していきたいと考えています。実際にやってみてうまくいかないことや自分には合わないやり方とかも見つかってくることもあるかもしれませんが、そのときは、どのように変えていけばよいのかを考えていきたいと考えています。
【復習】PHPにおけるforeachの使い方

##foreach文とは
配列を繰り返し文として表示するためのものです。
指定した順番で文章を表示させることができるためよく使われます。
ここではPHPの際に使うforeach文について復習していきます。


##foreach文の書き方
foreach文の書き方には**一次元配列**と**連想配列**というものがあります。

**一次元配列**

```php
foreach($array as $value) {
    echo '文字列';
}
```

**連想配列**

```php
foreach($array as $key => $value){
    echo '文字列';
}
```

##foreach文を使った例
####一次元配列

```php
<?php 
$baseballplayers = ['Akiyama', 'Genda', 'Yanagita', 'Yamakawa', 'Okamoto', 'Yamada', 'Uebayashi', 'Kai', 'Kikuchi'];
foreach ($baseballplayers as $value) {
    echo $value. '<br/>';
}
?>
```

予想される出力結果

```
Akiyama
Genda
Yanagita
Yamakawa
Okamoto
Yamada
Uebayashi
Kai
Kikuchi
```

####連想配列
```php
<?php
$baseballplayers = [
    '1番打者' => 'Akiyama',
    '2番打者' => 'Genda',
    '3番打者' => 'Yanagita',
    '4番打者' => 'Yamakawa',
    '5番打者' => 'Okamoto',
    '6番打者' => 'Yamada',
    '7番打者' => 'Uebayashi',
    '8番打者' => 'Kai',
    '9番打者' => 'Kikuchi'
];
foreach($baseballplayers as $key => $value){
    echo $key . 'は' . $value . 'です。<br>';
}
?>
```

予想される出力結果

```
1番打者はAkiyamaです。
2番打者はGendaです。
3番打者はYanagitaです。
4番打者はYamakawaです。
5番打者はOkamotoです。
6番打者はYamadaです。
7番打者はUebayashiです。
8番打者はKaiです。
9番打者はKikuchiです。
```
『ぱいそん』をパソコンにいれてみませう

#まえがき

ここは普通科高校卒業，工業大学在籍の情報学部女子大生の備忘録です
専攻はセキュリティ系です
なんせ普通科高校出身がゆえ，プログラマー思考が身についてないんです
大学で使う主言語はC
Pythonはほとんど使いません

Qiitaでは自分がPythonの勉強をするに当たっての導入方法，失敗談，成功例などを載せて行こうと思います
できるならばコメント等で掲載している内容とは違った方法やアドバイス，間違い等を言っていただき，私だけでなく見てくださる皆さんと勉強ができたらと…

CCENTの勉強もしなきゃなので更新頻度はめちゃめちゃいいわけではないです
現在大学2年後期のため授業課題等でいっぱいいっぱい…()

それでは，まじめなようでまじめでない，ポンコツのためのポンコツ備忘録のはじまりはじまり～


#そもそも『ぱいそん』ってどんな言語？

![python-logo.png](https://qiita-image-store.s3.amazonaws.com/0/296274/d71dfd2c-9ff3-4d36-b0ab-d5e9f7a27520.png)


さまざまな分野のアプリケーションで使われている、極めてパワフルな動的プログラミング言語
COM、.NET、CORBAなどのオブジェクトと組み合わせることができます
Windows、Linux/Unix、OS/2、Mac、Amigaなど多くのOSで使うことが可能
わたしが特に魅力的だと思った点はユーザーフレンドリーであるということです

まえがきにも書いたとおりプログラマー思考が身についていない自分にとって，ユーザーフレンドリーであることはとても重要
初めてPythonに触れたのは[Progate](https://prog-8.com)という，初心者向けに作られているプログラミング学習サイトでした
別にProgateの回し者とかではないですよ()

個人的にPythonはC言語よりも分かりやすくて学習しやすいと思いました

[Pythonの英語版公式サイト](https://www.python.org/)
[日本語版公式サイトはこちら](https://www.python.jp)

#Pythonの導入

続いてPythonのインストール方法についてです

ここは簡単，誰でもできます
猫にはできません，PCが使えてこの記事を読める人であればできます，たぶん

[『ここ』](https://www.python.org/downloads/)からパッケージがインストールできます
バージョンはそれぞれ必要に応じて選択してください

今回はリリースされて少し経っていますがPython3.7.0をインストールしようと思います

Downloadをクリックするとこのような画面が出てきます(2018/11/15現在)
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/296274/bf8f9d8a-4eba-e4d3-b4b7-668a68fc26a4.png)


わたしはこの中の「Windows x86-64 web-based installer」を選択しました
どれが良かったのか分からないし，違いもよく分からないし…

インストーラーを起動します
多分こんなアイコンしてるはず
![papa.PNG](https://qiita-image-store.s3.amazonaws.com/0/296274/da2aca94-c4d3-8550-d3a9-683fe91bc529.png)

起動するとこのような画面が出現します
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/296274/c21aa303-35b7-c9c8-c877-ade3c470c356.png)

64bit版ですね

インストールが終わるまでのんびり待ちましょう
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/296274/c18ddc3f-3a03-7feb-d7d8-c6c1192231f9.png)

インストールが終わりました
とりあえず閉じましょう
英語が全く読めません
分からないので余計なことはしません
何もしてないのに壊れました～！なんてことにはなりたくないし…
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/296274/df6ecf1c-687f-8ecc-1661-6912f36e5991.png)

Winキーを押して「P」の欄にこんなのが出てたら成功です！
おめでとうございます！しゅごい！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/296274/5be4d48a-590f-112c-1e1b-e825ef5a3cc9.png)

#かんそう
くそねみなので今日はここまで
とりあえずインストールできれば満点！！！！
また進展があったら書きます(･_･)
ちゃんと勉強します()
よく見たら日本語版サイトに色々載ってますね…
そんでもってお腹空きました眠いです
マツキヨに売ってるきなこ餅せんべい美味しいので食べてみてください

#参考文献
Pythonとは
https://www.python.jp/pages/about.html
Djangoアプリをherokuにデプロイする手引書

# Upload django to heroku !!!

## herokuコマンドをインストール
好きな方法でインストールしましょう。
ですが他の言語などに頼らない方法でインストールしたほうが後々楽かと思います。
ちょっと前まではRubyのgemでインストールするのが主流でしたが、今は廃止予定になっているそうです。

[ubuntuにインストールする方法](https://qiita.com/NAKKA-K/items/db1ad0d2569888946222)
[ダウンロードしてインストールする方法(+その他)](https://devcenter.heroku.com/articles/heroku-cli)

## アカウント登録
まず[herokuのsignupページ](https://signup.heroku.com/jp)で、アカウント作成しましょう。

## herokuにログイン

```bash
$ heroku login
```

## herokuアプリを作成
herokuでプロジェクトを作成する。プロジェクト名は省略すれば、自動で設定されます。

```bash
$ heroku create [project_name]
```

---

## プロジェクトに追加するファイル、設定

### runtime.txt
稼働させるプログラムのバージョンを記述します。

```bash
$ echo "`python -v`" > runtime.txt
```

## Procfile
herokuで稼働させる方法を記述します。
`gunicorn`はrunserverの本番環境版のようなものです。

```bash
$ echo "web: gunicorn [app_name].wsgi --log-file" > Procfile
```

runserverでもできます。

```bash
$ echo "web: python manage.py runserver 0.0.0.0:${PORT}" > Procfile
```

### [project_name]/settings.py
ファイルの最後に以下の設定を追記します。

```python:[project_name]/settings.py
import dj_database_url
DATABASS['default'] = dj_database_url.config()

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

ALLOWED_HOST = ['*']

STATIC_ROOT = 'static'

DEBUG = False

try:
  from .local_settings import *
except ImportError:
  pass
```

### [project_name]/local_settings.py
ローカル環境用の設定を追記。settings.pyを上書きする形で設定されます。
ファイルの最後に以下の設定を追記します。

```python:[project_name]/local_settings.py
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))

DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
  }
}

DEBUG = True
```

### [project_name]/wsgi.py
ファイルの最後に以下の設定を追記します。

```python:[project_name]/wsgi.py
from whitenoise.django import DjangoWhiteNoise
application = DjangoWhiteNoise(application)
```

## heroku環境変数の設定
この設定をしないと、herokuにpushしたときに怒られます。

```bash
$ heroku config:set DISABLE_COLLECTSTATIC=1
```

## herokuへアップ
gitを使用してアップします。
アップ先URLをremoteに登録します。  

```bash
$ git remote add heroku https://git.heroku.com/[project_name].git
$ git push heroku master
```

テスト用ブランチの内容を公開したい場合は以下のようにします。

```bash
$ git push heroku [test_branch]:master
```

## herokuでDBの反映

```bash
$ heroku run python manage.py migrate
```

## heroku で管理サイト用のアカウントを作成

```bash
$ heroku run python manage.py createsuperuser
```
    
## herokuにアップしたプロジェクトを起動
これをすることによって、ブラウザからアクセスできるようになります！！

```bash
$ heroku open
```


## まとめ

以上でherokuへのデプロイは完了です。
まず近くの人に使ってもらうでも、twitterなんかで宣伝するでもよし。
アプリケーションの稼働状況はherokuの管理ページから見ることができるので、そちらも確認しておきましょう。
ubuntuでherokuコマンドをインストールする方法

herokuコマンドはRubyのgemとしてインストールする方法がよく使われているのですが、以下の方法だとRubyが入っていない環境でも使えるので便利です。

```bash
$ wget -qO- https://cli-assets.heroku.com/install-ubuntu.sh | sh
```


これだけでもうherokuコマンドが使えます。
念のため確認しておきましょう。

```bash
$ heroku --version
```
terraform import した aws_iam_role の assume_role_policy の確認方法

下記のように `aws_iam_role` をimportしてきた時、

```bash
$ terraform import aws_iam_role.foo foo
```

`aws_iam_role` リソースの `assume_role_policy` は必須パラメータで、
「これの正確な定義はどこで分かるんだ :thinking: 」となります。

```bash
resource "aws_iam_role" "foo" {
  name               = "instance_role"
  path               = "/system/"
  assume_role_policy = ""
}
```

## 解決策

そんな時は、リソースの実体をみればOK。
awscli では以下で取得できます。
(`AssumeRolePolicyDocument` がほしかった `assume_policy_role`)

```bash
$ aws iam get-role --role-name=foo | jq .Role.AssumeRolePolicyDocument
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "cognito-idp.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "xxx"
        }
      }
    }
  ]
}
```

## Appendix

jsonをコピペでも良いのですが、data リソースなんかを使ってあげると、きれいに構造が見えます。

```bash
data "aws_iam_policy_document" "foo" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["cognito-idp.amazonaws.com"]
    }

    condition {
      test     = "StringEquals"
      variable = "sts:ExternalId"

      values = [
        "xxx",
      ]
    }
  }
}

resource "aws_iam_role" "foo" {
  name               = "foo"
  path               = "/service-role/"
  assume_role_policy = "${data.aws_iam_policy_document.foo.json}"
}
```

## References

- [aws_iam_role](https://www.terraform.io/docs/providers/aws/r/iam_role.html)
- [aws_iam_policy_document](https://www.terraform.io/docs/providers/aws/d/iam_policy_document.html)
ESXiに接続するNFSボリューム数を変更するときに気を付けること

#概要
現在携わっているプロジェクトにて、ESXiに接続するNFSボリューム数を変更する作業があったので、その際気を付けたい点をまとめる。

- ESXiはデフォルトで**最大8つ**のNFSボリュームを接続可能。
- それ以上接続するときは、3つのパラメータ**「NFS.MaxVolumes」、「Net.TcpipHeapSize」、「Net.TcpipHeapMax」**を変更する必要がある。
- これらのパラメータを変更し設定を反映するためには、**ESXiの再起動**が必要になる。
- 「NFS.MaxVolumes」だけ変更すると**最適なパフォーマンスがだせなくなる可能性がある**ため、他2つのパラメータも必ず変更する。

#####※各パラメータについて
**NFS.MaxVolumes**・・・ESXiに接続できる最大ボリューム数（Min:8~Max:256）

**Net.TcpipHeapsize**・・・ヒープメモリの量。VMkernel TCP/IP ネットワーク接続を管理するために割り当てられる。(Min:0~Max:32)
→NFS.MaxVolumesと直線的な関係がある。
→NFS.MaxVolumesが2倍、3倍となれば同様にNet.TcpipHeapSizeも2倍、3倍に増やす。

**Net.TcpipHeapMax**・・・ヒープメモリの最大量。VMkernel TCP/IP ネットワーク接続を管理するために割り当てられる。(Min:512~Max:1536)

#環境
- ESXi6.0
- vCenter Server Appliance 6.0
- vSphere Web Client 6.0
- vSphere Client 6.0


#変更手順
今回はNFS.MaxVolumesを最大値の256に変更した。
###①対象ESXiのConfigure→Advanced System Settingsを選択
![pic1](https://drive.google.com/uc?export=view&id=1dpgBz5nCUDFKecnWKvM8CpgdRxaTdX_C)
###②編集ボタンから対象パラメータの値を変更
NFS.MaxVolumes:256, Net.TcpipHeapSize:32, Net.TcpipHeapMax:1536
![pic2](https://drive.google.com/uc?export=view&id=17oh_KZJH8c6f8hQXF9791D5YSeOsvaxU)
###③ESXiをメンテナンスモードに変更
※対象ESXiにVMが乗っていないことを確認すること！VMが残ったままだった場合、vMotionし事前に他のESXiに退避させる。
![pic3](https://drive.google.com/uc?export=view&id=1nLqFX32ubEfOSndXioBW2DelP78qm9Ta)
###④ESXiを再起動
本環境ではクラウド上からESXiをリブートした。

###⑤変更したパラメータを確認→メンテナンスモード解除
※念のためパラメータが変更されているか確認すること。

#まとめ
環境の規模にもよると思うが、NFSの最大ボリューム数を変更する可能性がある場合は、設計段階から上記のパラメータを変更するかどうか決めておく方が後々良い。リリースしてから変更作業となると手間がかかってしまうのであらかじめ顧客から要件を聞いておくこと。（自戒を込めて）

#参考文献
- [NFS の詳細オプションの定義 ](https://kb.vmware.com/s/article/1007909?lang=ja)
- [ESXi/ESX ホスト上で NFS マウントの最大数を定義するデフォルト値を増やす](https://kb.vmware.com/s/article/2239?lang=ja)
PythonでRNN(LSTM)を動かしてみる

#RNN(LSTM)
RNNは時系列のデータを学習するためのモデルです．
RNNは長期記憶にとても弱い欠点があります．
それを改良したものがLSTMとなっています．

モデルや細かい説明は他のサイトに任せます．

#Pythonで実装
TensorFlowはバージョンアップが早く，すぐに過去のプログラムが使えなくなってしまいます．
なのでネットで探してみても自分の環境で動かせるプログラムがなかったので，
自分の環境で動かせるようプログラムを変更していきます．

この記事のプログラムを使って実行できるLSTMを作成していきます．
[TensorFlowのRNNを基本的なモデルで試す](https://qiita.com/yukiB/items/f6314d2861fc8d9b739f)
詳しい説明などはそちらのページを参考にしてください．

##環境
macOS Mojave
Python 3.5.2
TensorFlow 1.11.0

##変更箇所
###BasicLSTMCell(54行目)
```python:
cell = tf.nn.rnn_cell.BasicLSTMCell(num_of_hidden_nodes, forget_bias=forget_bias, state_is_tuple=False)
```
このままだと

```
WARNING:tensorflow:From /Users/~~/lstm_q.py:54: BasicLSTMCell.__init__ (from tensorflow.python.ops.rnn_cell_impl) is deprecated and will be removed in a future version.
```

と警告が出てしまいます．
これは`BasicLSTMCell`を`LSTMCell`に書き換えてねという警告なのでそのまま変更するだけです．

```python:
cell = tf.nn.rnn_cell.LSTMCell(num_of_hidden_nodes, forget_bias=forget_bias, state_is_tuple=False)
```

すると同じ行の`state_is_tuple=False`を`state_is_tuple=True`に変更してねと警告が出るのですが，
まだ勉強不足でこの警告は取り除けていません．
これは出力をタプル(データ型)で出してくださいという命令なのですがそのまま直してしまうと，
型が違いますとエラーが出てしまいます．
ちなみに，タプルとは更新が不可能なリストのようなものです．
このタプルを使うと計算時間が早くなるので，TensorFlowではタプルを使用することを推奨しているみたいです．
警告の取り除き方がわかる方はぜひコメントなどで教えてもらえればありがたいです．

###initialize_all_variables(120行目)

```python:
init = tf.initialize_all_variables()
```

このままだと

```
WARNING:tensorflow:From /Users/~~/tf_should_use.py:189: initialize_all_variables (from tensorflow.python.ops.variables) is deprecated and will be removed after 2017-03-02.
Instructions for updating:
Use `tf.global_variables_initializer` instead.
```

と警告が出てしまいます．
これも先ほどと同様`initialize_all_variables`を`global_variables_initializer`に変更してねという警告なので変更します．

```python:
init = tf.global_variables_initializer()
```

###save(sess, "model.ckpt")(145行目)
```python:
saver.save(sess, "model.ckpt")
```

このままだと

```
ValueError: Parent directory of model.ckpt doesn't exist, can't save.
```

エラーが出てしまいます．`saver.save`の第二引数にはパスを入れなければならないみたいなので，

```python:
saver.save(sess, "./model.ckpt")
```

このように変更しました．
ただしmacOSでは相対パスで対応しているのですが，
Windowsでは絶対パスを与えないといけないみたいなので注意してください．

###FileWriter("/tmp/tensorflow_log", graph=sess.graph)(139行目)
上の項目を直すことでエラーと一つ以外の警告は出なくなったのですが，
`tensorflow_log`が絶対パスの`/tmp/tensorflow_log`に保存されていたので変更しました．
このままの方が正解だったのかもしれませんがとりあえず作業ディレクトリの中に保存しました．

```python:
summary_writer = tf.summary.FileWriter("/tmp/tensorflow_log", graph=sess.graph)
```

を

```python:
summary_writer = tf.summary.FileWriter("./tmp/tensorflow_log", graph=sess.graph)
```

のように変更しました．

#次のステップ
このプログラムの理解度をより上げていき，
前回取得した為替データを使って学習していくことが目的です．
アニメーションを簡単にアプリに追加できるLottie

[Lottie](https://airbnb.design/lottie/)は、モバイルやWebなどでリッチなアニメーションを、イメージビューを追加するのと同じくらい手軽に使用できるようになるライブラリで、宿泊施設・民宿予約サービスを提供しているAirbnbが開発しています。

モバイルでは、Android、iOSのほか、ReactNativeもサポートしています。

アニメーションは、jsonファイルで追加するため、アプリのサイズが大きくなりすぎません。

アニメーションは、AfterEffectsにBodyMovinプラグインを追加すれば、
オリジナルのものが作成できるようですが、今は手を出せていません・・・

## AndroidアプリにLottieを追加する

今回は、Androidでお試し実装をしてみました。
なので、AndroidアプリにLottieを追加する際の手順についての説明になります。


### 手順1: SupportLibraryをAndroidXに変更する。

すでにAndroidXに変更済みの場合は、この手順は飛ばしてOKです。

Lottieの最新バージョンは、2.8.0(2018/11/15現在)なのですが、このバージョンから、SupportLibraryを使用しているプロジェクトには、Lottieを追加することができないようになりました。

そのため、SupportLibraryをAndroidXに変更する必要があります。
手順は以下のとおりです。

1. AndroidStudioを3.2にアップデートする。
2. Refactor > Migrate to AndroidX を選択する。
3. SupportLibraryをAndroidXに置き換える処理を実行する。

※ 注意点
compileSdkのバージョンが28以上、gradleのバージョンが3.2.0以上でないとこの機能は使用できないので、それぞれのバージョンが低い場合は、上げる対応を行ってください。


### 手順2: gradleにLottieを追加する。

build.gradleファイルに、以下のようにLottieリポジトリを追加してください。

```
dependencies {
    implementation 'com.airbnb.android:lottie:2.8.0'
}
```


### 手順3: レイアウトファイルにLottieAnimationViewを追加する。

アニメーションを表示させたい位置に、LottieAnimationViewを置きます。

    <com.airbnb.lottie.LottieAnimationView
            android:id="@+id/animation_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

基本的なパラメータ以外に以下のようなパラメータを設定する事ができます。

* 自動的にアニメーションをループさせたい場合

lottie_loopパラメータにtrueを設定します。

    app:lottie_loop="true"

* アニメーションファイルの読み込みが完了した際に自動的に再生をしたい場合

lottie_autoPlayパラメータにtrueを設定します。

    app:lottie_autoPlay="true"


### 手順4: 読み込ませたいアニメーションファイルをLottieAnimationViewにセットする。

レイアウトファイルで追加する場合
レイアウトファイルから、使用するアニメーションを指定する場合は、以下のパラメータを設定します。
アニメーションのファイルは、Rawやassetsなどに置くことができます。

    app:lottie_rawRes="@raw/hello_world"
    // or
    app:lottie_fileName="hello_world.json"

コードから追加する場合
コードから、使用するアニメーションを指定する場合は、以下のようにセットすることができます。

    animation_view.setAnimation(R.raw.hello_world)
    or 
    animation_view.setAnimation("hello_world.json")

## Lottieを使ってみて

簡単な手順でアニメーションが使用できるようになるので、画像だけではなく動きのあるアプリにしたい場合は、使用してみる価値は十分にあると思います。
アニメーションファイルも、自分で作成する以外にも、[こちら](https://www.lottiefiles.com/)から使用したいアニメーションを探すこともできます。

おもしろいアプリを作ってみたい場合は、Lottieの導入を検討する価値アリだと思います。
ぜひ試してみてください！

Lottieのサンプルアプリが、GooglePlayStoreで公開されているので、
こちらをインストールしてどんな感じなのかも見てみてください。
https://play.google.com/store/apps/details?id=com.airbnb.lottie

## 参考にしたサイト

https://github.com/airbnb/lottie-android
http://airbnb.io/lottie/android/android.html
連番IDの運用とDBのスケール

## はじめに
Twitterで下記のようなツイートをしたのですが、それの解説をする必要があるのでは、と思ったのでします。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">これ「シャーディングで連番id振りたいときに困るから自前で連番idを振る」っていうことをしてるblog記事なんだけど、シャーディングするとその連番id振る処理そのものがネックになってスケールしない」から設計ミスなんだけど、指摘するべきか悩む<a href="https://t.co/kNcNhiHEtF">https://t.co/kNcNhiHEtF</a></p>&mdash; ぽんこつ@本骨システム (@ponkotuy) <a href="https://twitter.com/ponkotuy/status/1062979642921934848?ref_src=twsrc%5Etfw">2018年11月15日</a></blockquote>

DBは正直あんまちゃんと勉強してないのであれなんですが、運用で得た知見で話をします。なんか指摘あったら下さい。

## RDBMSの特徴と問題点
MySQLとかPostgreSQLとかSQLServerなど、お仕事なんかで良く使うRDBMSなんですが、共通していくつかの特徴があります。特にここで重要なのは正しいデータのみを保存する「データ完全性」を重視してる点と、仕様変更に対して(特にNoSQLと比較して)追従しやすい、どんなクエリでもそこまでコストかけずにできる、などの特徴があります。

一方で、NoSQLが一部で流行ってることからも分かるように万能ではなく、最も重要な問題として「本質的に書き込みの速度がスケールしない」という問題があります。なぜなら、RDBMSの主要実装は、正しいデータが書き込まれたことを保証するために、書き込みを1箇所に集約しているからです。これが一般に言うmasterです。読み込みはslaveを立てることによって書き込みよりはスケールします。

また、RDBMSが本質的に苦手とするいくらかのクエリがあったり(集計なんかは割と苦手なイメージあります)、特化したタイプのNoSQLであればRDBMSより特定クエリが圧倒的に早かったりもします。

つまり簡単に言えば速度を若干犠牲にしつつ、正しいデータを柔軟に扱うことを重視したのがRDBMSと言えます。

### シャーディング
先程RDBMSは書き込みがスケールしないと言いましたが、ほぼ全てのRDBMS実装に解決する手段が用意されています。シャーディングです。シャーディングを利用して、そもそもの書き込み先を予め決めたルールに従って処理するサーバを割り振るようにしてしまえばよいという訳です。

そのようなものなので、シャーディングには様々な技術的な制約が付き纏いますが、RDBMSでちゃんとスケールしようとした場合必須になります。

## 連番ID
ここで本題に戻って連番IDの話をします。insertした順番にidを1→2→3と振ってく仕組みで、MySQLにはAUTO_INCREMENTとかあります。

ところでこの連番ID、きちんと重複無しに振っていくのは意外と難しいです。次のIDを保存する領域作って、取得する際にTransactionなどでロックを掛けて他のスレッドの割り込みが無いことを保証してIDを取得する必要があります。

1台ならあまり問題にならないこの仕組みですが、複数台を跨ぐと途端に問題が爆発します。複数台にIDを発行する必要があり、重複しないように管理しようとすると当然masterのような仕組みが必要になるでしょう。そうするとIDの発行がネックになってスケールしないことが分かります!なんのためにシャーディングにしたのでしょうか。RDBMSをスケールするためだったとおもうのですが。

そもそもなんですが、本質的にIDって被らなければ何でもいいものなので、連番である必要はない筈なんですね。勿論連番ID便利なこともちょいちょいあるのでスケールする必要がなければ使えばいいんですが。

そのようなIDを振る候補としては、素直にUUID(128bit)を使うか、シャーディングのルール内でunique制約を付けたランダムな値を含んだ64bit整数とかを使うといいです。どういうものかというと、シャーディングルールで64bitのidを32で割った余りが担当するサーバという設定にしておき、このidに対してunique制約を張るというものです。idチェックは1台のノード内で完結するのであまり大きなオーバーヘッド無しでidを設定することができます。(失敗したら重複したので再設定して再投入)
【Raspberry Pi】Raspbianインストール時にVNCとSSHを有効にする方法【Mac】

Raspberry PiでRaspbianを何回も再インストールしていて、その度に調べるのが面倒になったので自分の方法をまとめます。

まず、公式サイトからNoobsをダウンロードして、解凍。

フォルダ内にある"recovery.cmdline"というファイルをエディターで開いて

`quiet`

の部分を

`vncinstall`

と書き換えて保存。

次に、osフォルダ内にあるRaspbianのフォルダを開いて、"partition_setup.sh"というファイルをエディターで開く。

最終行付近の

`unmount /tmp/1`

の直前に

`echo "ssh" >/tmp/1/ssh`

と書き加え、保存する。

ここまで出来たらMicroSDカードを安全に取り外して、RaspberryPiに挿入する。

RaspberryPiを電源に接続し、Mac側でターミナルを開いてRaspberryPiのIPアドレスを特定する。

VNCビューアーを開いて、RaspberryPiのIPアドレスを入力し、
ユーザー名にpi
パスワードにraspberry
と入力して接続する。

ssh接続は

`sudo ssh pi@~~`

~~の部分はRaspberryPiのIPアドレスを入力すればよい。

以上でVNC接続・SSH接続の手順が完了。
次世代CSS in JSライブラリ、DICSSの紹介

Qiitaに[記事が0件](https://qiita.com/search?q=DICSS)、どころか日本語記事が全く存在しない新進気鋭のCSS in JSライブラリ、[DICSS](http://letsgetrandy.github.io/DICSS/)を紹介します。
以下は[DICSS-Directly injected CSS](http://letsgetrandy.github.io/DICSS/)の日本語訳です。


# Directly injected CSS

Sassは忘れてください。
LESSも忘れてください。
あなたに必要なのはDICSSです。
一度DICSSを使ってしまうと、もうLESSには戻れないでしょう。

CSSとJavaScriptを毎回別々にビルドすることに疲れましたか？
DICSSにはそんな心配事はありません。
なにしろ、DICSSはJavascriptです。
つまり、スタイルとスクリプトをひとつの言語でコーディングし、全てをひとつのファイルにコンパイルすることができます。
一度試してみれば、たちまちDICSSが好きになるでしょう。

DICSSは楽しく、そして簡単です。

## Is it safe?

これは安全ですか？

もちろんです。
DICSSはwrapperを使っています。

## How do you use DICSS?

DICSSはどうやって使えばいい？

`dicss.js`を好きなところに配置するだけです。
`head`タグでも`body`タグでも同じく動作します。

```html
<head>
    <script src="dicss.js"></script>
</head>
```

それだけで、すぐにDICSSを使い始めることができます。

```js
DICSS.putIn('body', 'transition: .1s linear');
DICSS.putIn('p', {
    "height": "100%",
    "width": "100%",
    "&.protection": {
        "border": "solid 1px transparent"
    },
    "a": {
        "color": "#fff"
    }
});
```

追加したスタイルを、後から削除することも簡単にできます。

```js
DICSS.pullOut('a', 'color');
```

## The possibilities are endless

DICSSはJSONに対応しているので、CSSをネストして管理することができます。

```js
var widgetDICSS = {
    'div.widget': {
        'a': {
            font: '1em Verdana,Arial,sans-serif',
            margin: '.5em'
        }
        //... etc
    }
};
```

なお、DICSSはバックエンドに対応しておらず、必要に応じてRESTを介してクライアントにデリバリーすることはできません。

## Why no min version?

どうしてミニマムバージョンはないの？

DICSSは非常に軽量であり、それでも必要であれば自身で行うことができます。

## Can DICSS be extended?

DICSSを拡張することはできますか？

もちろん！
DICSSは好きなだけ拡張することが可能です。
メソッドを`DICSS.extend()`に渡すだけです。
DICSSは成長しています。
有名なDICSSアドオンには以下のようなものがあります。

・COCSS (cross-origin DICSS)
・SECSS (security enhanced DICSS)
・DICSS-Pics (DICSS plugin for working with images)
・Circum-Sizer (calculate the circumference of a rounded element in CSS)

はい、たしかにこれらのアドオンは実際にはまだ存在しません。
しかし、あなたがそれを作るのを止めることのできる人は誰もいません。

DICSSに追加したい機能がありますか？
DICSSをよりよいものにするために、ぜひ私たちに協力してください。

## Is DICSS compatible with other frameworks?

他のフレームワークと同居はできますか？

はい。
DICSSをKnockout (KOCSS)、Backbone (BoneDICSS)、そしてAngular (Angular-DICSS)と統合するプロジェクトが進行中です。

##  Does DICSS work with LaTeX?

LaTeXで動きますか？

もちろん動作しますが、より手間はかかります。

##  It's not working. Help!

うごかないよ！助けて！

開発者ツールを開いて、`DICSS`と入力してみてください。
未定義であれば、DICSSの導入に失敗しています。

##  It's still not working!

いまだに動かないよ！

難しく考えすぎてないかい？
DICSSはあなたにもできる程度の中身だよ。

##  I don't like DICSS.

私はDICSSが好きではありません。

仕方ありません。
ほとんどの人がDICSSを好きになると信じていますが、しかしDICSSは万人向けではありません。
他にも選択肢はたくさんあるので、それらをかわりに使ってもかまいません。
そして、DICSSが好きではないという人にはDICSSを強制的に使わせないでください。


## Performance has gotten worse. It doesn't come up as fast as it used to.

DICSSを導入する前よりパフォーマンスが悪くなりました。

DICSSを`body`タグに書きましたか？
`head`タグに書くか、あるいはバックエンドを強化することでパフォーマンスが改善します。

##  THIS IS NUTS!

これはNUTSだ！

いいえ、これはDICSSです。
NUTSは[他のプロジェクト](https://github.com/letsgetrandy/NUTS)です。


# 感想

CSS in JSの究極系ですね。
特定のJavaScriptフレームワークに依存せず、デザイナーにもわかりやすいJSONでCSSを書くことができ、そして、万一素のCSSに戻すことになったとしても簡単に戻すことができます。

出されている例がLESSだのBackboneだのいちいち古い？
そういう細かいことをあまり気にするものではないよ。

[最終commit](https://github.com/letsgetrandy/DICSS)が3年前？
いえ、あまりに完成度が高すぎてもはや手の加えようがないのです。

さあ、今すぐDICSSを導入しましょう！
A Graph-to-Sequence Model for AMR-to-Text Generation

## 下書き

# 概要
- AMRグラフから意味情報を保ったまま文章を生成する方法を提案
    - 従来は linearized AMR から Seq2Seq モデルで decode していたが，これでは 非局所的な意味情報をモデル化できるものの，AMRのグラフ構造からの情報を失ってしまう
        - 大きなグラフでは長いセンテンスが生成されてしまう
- グラフレベルの意味情報を直接 encode する LSTM構造を提案
    - 従来のモデルを上回るパフォーマンス


## Abstract Meaning Representation とは
- 文章を，意味関係を捉えた有向非巡回グラフで表現する方法
    - 各ノードは Concept, 各エッジは Concept間の関係性を示す
- AMRの形式で文章の意味をグラフ構造に落とし込み，それを正しくセンテンスに復元できれば，何が嬉しいのか？？


[Tutorial: The Logic of AMR: Practical, Unified, Graph-Based Sentence Semantics for NLP](http://naacl.org/naacl-hlt-2015/tutorial-amr-semantics.html)
[構文情報を用いたAbstract Meaning Representationの高精度アラインメント](http://www.anlp.jp/proceedings/annual_meeting/2017/pdf_dir/P2-3.pdf)

> 自然言語処理において、意味解析は固有表現抽出、意味役割付与、共参照解析、固有表現抽出など多くの分野にまたがっている。しかしながら、それぞれの解析に関する研究は独立して行われており、別々の分野として発展してきた経緯がある。そのため、分野ごとにデータを学習する手法も、評価に用いるデータも、結果を評価する手法も異なっている。したがって、分野間の関連性や相互作用を捉えた解析を行うことは難しくなっており、複数の分野で解析されてきた意味表現を一括して表現することができる形式が長い間望まれてきた。
それを受けて新しく考案された意味表現方法が抽象的意味表現 (Abstract Meaning Representation,AMR) [2] である。AMR は文中から意味を持った概念のみを取り出し、それをグラフ構造で表現したものである。このグラフは根を持ちサイクル構造を内部に含まない有向グラフとなっている。例として、“The boy wants for the girl to believe him.” に対する AMR を図 1 と図 2 にて示す。図 1 は AMR を視覚的にわかりやすいグラフ構造によって図示したもの、図 2 はデータ中での AMR を示したもので両者が表現していることは同じである。
AMR にはその中の各部分が文中のどの単語に対応しているかという対応関係がデータ中で示されておらず、明らかではない。こうした対応関係を特定するのがアラインメント処理である。文から AMR を生成するパーザーのほとんどはアラインメント結果を利用して機械学習を行っており、精度が高いアラインメント処理は AMR の応用上重要になっている。


## AMR-to-text generation
- AMR では単語の時制や活用の情報が除かれるため，AMRの各ノードを単にフレーズに変換してもぎこちない文章に鳴ってしまう
- Seq2Seqモデルを用いたモデルがこれまでの SOTA だが，入力としてAMRを用いるには グラフを直列にする必要があった
    - グラフ上では近いノード（親・子）であっても直列化されるとだいぶ離れてしまい， RNNが元のグラフ構造を推測するのは困難
- グラフ構造を直接 Encode する LSTM 構造を提案

## graph-to-sequence model

![スクリーンショット 2018-11-04 14.33.41.png](https://qiita-image-store.s3.amazonaws.com/0/140539/459e798e-0a7f-a14c-b7f9-e14e75ff7609.png)

- $h^j_t$ ： AMR グラフの各ノード j の時刻 t 隠れ状態 (時刻 0 の初期状態はハイパーパラメータで初期化)
- $x^l_{i,j}$ : AMR の ノードi からノード j へ伸びる ラベル l を持ったエッジ

これらを用いて，各ノードに対して 下記を定義し，これら４変数を入力した LSTM で各ノードの隠れ状態を $h^t_j$ を更新していく 
- $x^i_j$ : 入力エッジベクトルの総和，
- $x^o_j$ : 出力エッジベクトルの総和
- $h^i_j$ : 入力ノード隠れ状態の総和
- $h^o_j$ : 出力ノード隠れ状態の総和


![スクリーンショット 2018-11-15 21.28.36.png](https://qiita-image-store.s3.amazonaws.com/0/140539/852ee5d4-fe0c-4495-5574-931c47f665d3.png)

![スクリーンショット 2018-11-15 21.28.41.png](https://qiita-image-store.s3.amazonaws.com/0/140539/f606b305-2fa6-fc3a-b176-6d0ec36b1023.png)

![スクリーンショット 2018-11-15 21.28.48.png](https://qiita-image-store.s3.amazonaws.com/0/140539/d9b75070-3eca-f056-6233-6b4ef143abc9.png)


## LSTMのステップ数
- １ステップ計算する毎に，各ノードの隠れ状態には隣接するノードの情報が集約されていく
    - N ステップ計算することで N 個先のノードの情報を得ることができる
    - 直列なグラフであれば最悪でもノード数分計算すれば全体の情報を考慮することができる

## エッジ（LSTMの入力）ベクトルの作成方法
PHP: PHP_INT_MAXを超える数値をstringにしたとき指数表記にさせない方法

PHPの整数最大値は、定数`PHP_INT_MAX`で参照することができ、64ビット環境で`9223372036854775807`である。

これに`1`を足した数値は`9223372036854775808`になるのだが、`PHP_INT_MAX + 1`をstring型に型変換すると指数表記の`'9.2233720368548E+18'`になる。

```php
assert(strval(PHP_INT_MAX + 1) === '9.2233720368548E+18');
```

数値としては指数表記で間違いはないが、string型で`'9223372036854775808'`のように指数表記でない形式が欲しい場合はどうしたらいいのだろうか？

その場合は、`bcadd`関数で計算すると良い。

```php
assert(bcadd(PHP_INT_MAX, '1') === '9223372036854775808');
```
非同期実行 Sidekiqの導入 Mac Ubuntu

# はじめに
ついに弊社でもsidekiqを導入することにしました。（おせえよ）
導入に至った経緯はこんな感じ。

- rundeckでバッチを定期的に起動している
- バッチが増え的たら重くて動かなくなった（一応動くけど）
- rundeckがおもい原因は重大なメモリ不足
- メモリ不足の原因は数時間かかるバッチのレスポンスをひたすら待っているから
- sidekiqに蹴り飛ばすしかねえ

という感じなのですが、今後の非同期実行処理にもかなり有用なので積極的に取り入れていきたいですね。
※レスポンスが必要な処理には向いてませんので何でもかんでもはNG。

<font color='red'>（注意）かなり手探りでふわっとしています。</font>
<font color='red'>（注意）作業ログなので殴り書きチックです。</font>

# ローカルの環境設定と実装
sidekiq使うにはredisが必要です。
redisはNoSQLデータベースでsidekiqのジョブの管理とかに使ってます。
最低限のことしか設定してないんで、各自不便に思ったところは調べて改造してください。

## Macにredisをインストール
``$ brew install redis``

## gemの追加
sinatraはダッシュボードを見るために必要です。

```ruby:Gemfile
# sidekiq
gem 'sidekiq'
gem 'sinatra', require: false
gem 'redis-namespace'
```

``$ bundle install``


## 設定ファイルの用意

```ruby:config/initialize/sidekiq.rb
Sidekiq.configure_server do |config|
  config.redis = { url: 'redis://127.0.0.1:6379', namespace: 'sidekiq' }
end

Sidekiq.configure_client do |config|
  config.redis = { url: 'redis://127.0.0.1:6379', namespace: 'sidekiq' }
end
```

## ワーカーの作成
generateで作っても普通にファイル作ってもOK。
こいつにぶん投げることになります。
``rails g sidekiq:worker Update``

```ruby:/app/workers/get_info_worker.rb
class UpdateWorker
  include Sidekiq::Worker

  def perform
    update_service = Products::UpdateService.new
    update_service.execute
  end
end
```

## コントローラーの修正
さっき作ったワーカーにぶん投げます。

```ruby
def product_update
  UpdateWorker.perform_async
  render json: { result: sidekiq_web_url }.to_json
  rescue StandardError => e
    raise e
end
```

## routesの修正
ダッシュボード見るために設定します。

```ruby:routes.rb
  require 'sidekiq/web'
  mount Sidekiq::Web => '/sidekiq'
```

## redisの起動
``$ redis-server``
<img width="520" alt="スクリーンショット 2018-11-15 16.24.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/147005/51495fb0-11a4-88c0-bbc0-d1f39f356431.png">





## sidekiqの起動
``$ bundle exec sidekiq``
<img width="465" alt="スクリーンショット 2018-11-15 16.24.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/147005/5f3fad0e-24a6-312c-328c-78eb8a273af5.png">


## 完了！
http://localhost:3000/sidekiq
でダッシュボードが確認できます。
<img width="1384" alt="スクリーンショット 2018-11-15 16.10.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/147005/8fcf2241-fdad-68f3-f7ac-e925e4dc97bf.png">




# 本番環境設定
今回の対象は
Ubuntu 16.04.5 LTSです。

## redisの設定
まずはインストール。
``$ sudo apt install redis-server``
完了して、
``sudo service redis start``
がエラーなく実行できればOKです。

## sidekiqの設定
``$ bundle install``
これでOK。最高

デーモンで起動
```$ bundle exec sidekiq --daemon --environment=production --logfile /project/[rails_project]/log/sidekiq.log```


# まとめ
難しすぎる...
これからうまく使えるようになればと思いましたねえ！！！

ブログで見たい方はこちら
[非同期実行 Sidekiqの導入 Mac Ubuntu](http://nabesys.com/article/2018/11/15641/)
ffmpeg資料集

`ffmpeg`を使用するにあたり、参考にしたサイト集です。
割と色々できて面白いことがわかったので、今後他にも色々試してみます。


# 全般的

[ffmpeg公式](https://ffmpeg.org/) (英語)
[動画処理の定番ツール「ffmpeg」ことはじめ](https://qiita.com/kitar/items/59f80bba2ca997e0f5e6)

# gif -> mp4

[FFmpegでgifアニメをmp4に変換する](https://qiita.com/razokulover/items/fe45833c997b338c638a)

# drawtextフィルタ

[ffmpeg drawtextフィルタで遊んでみる](http://fftest33.blog.fc2.com/blog-entry-45.html)

# concat

これだとうまくいかなかった: [ffmpegで動画を結合する（最新版concatの使い方）](https://webnetforce.net/ffmpegde-dong-huawo-jie-hesuru-zui-xin-banconcatno/)
これの通り、`file ''`を書いたら動いた: [ffmpegでファイルをリストにして、動画を連結させる方法](https://yatta47.hateblo.jp/entry/2016/07/19/200000)
Angular js でストップウォッチを作ったメモ

## Angular jsを使ってストップウォッチを作る

ユーザ側に経過時間を見せながらログを取るアプリケーションを作る必要があったので，ここにメモ

表示用のhtml

```html:index.html

<!DOCTYPE html>
<html ng-app="app">
  <head>
    <!-- import Library | Framework -->
    <title>ストップウォッチ</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.5/angular.min.js"></script>
    <script src="./Time_control.js"></script>
  </head>
<body>
    <div ng-contoller="time_controller">
        <!-- 表示用 -->
        <p>{{time_status}}</p>
        <div>
            <input type="button" value="start" ng-click="start()" ng-class="{disabled :start_status}">
        </div>
        <div>
            <input type="button" value="end" ng-click="stop()" ng-class="{disabled :stop_status}">
        </div>
    </div>

</body>
```

ng-controllerでコントロールの範囲を決めて，その中のng-clickに対してイベントリスナーをJS側で書いていく

```JavaScript:Time_control.js
var app = angular.module("app",[]);

app.controller("time_control",function($scope,$interval){
    $scope.time_status = "00:00";
    // 外のメソッドからアクセスしたいため，グローバル変数へ
    time = 0;
    // startのボタンのみ有効
    $scope.start_status = "";
    $scope.stop_status = "disable";
// スタートを押した際にカウントを始める
  $scope.start = function(){
    // スタートボタンは無効化する
    $scope.start_status = "disabled";
    $scope.stop_status = "";
    // 1秒間に1回処理を呼び出すようにする
    timer = $interval(function(){
      time++;
      var sec = parseInt((time % 60) / 10) == 0 ? "0" + (time % 60).toString() : (time % 60).toString();
      var min = parseInt(time / 600) == 0 ? "0" + parseInt(time/60).toString() : parseInt(time/60).toString();
      $scope.time_status = min + ":" + sec;
    },1000);
  }
    // ストップを押したら時間を止めるようにする
  $scope.stop = function(){
    $interval.cancel(timer);
    $scope.start_status = "";
    $scope.stop_status = "disabled";
  };
})

```

コードはこんな感じ

注意するところはcontollerの中の引数を\$scopeだけではなく\$intervalも入れること
割とそのエラーで今後ハマりそう。。
Lubuntu18.04ではVino (VNCサーバー) が使えない

#結論から書くとLubuntuではvinoは使わない方が良い
vino-preferencesがGNOMEの事情でなくなって、GNOMEユーザー以外がvinoの設定を単独でできなくなったらしい。
https://bugs.launchpad.net/ubuntu/+source/vino/+bug/1775999
基本的に問題点はここに書いてある。が、特に解決策が書いてあるわけでも、解決する気があるわけでもなさそう。と言うわけで、違うVNCサーバーを使う方が良い。


## 一応試したこと（結果的には使えない情報）
`vino`をインストールする。

```
$ sudo apt install vino

...

15/11/2018 20時10分35秒 Autoprobing TCP port in (all) network interface
15/11/2018 20時10分35秒 Listening IPv6://[::]:5900
15/11/2018 20時10分35秒 Listening IPv4://0.0.0.0:5900
15/11/2018 20時10分35秒 Autoprobing selected port 5900
15/11/2018 20時10分35秒 Advertising security type: 'TLS' (18)
15/11/2018 20時10分35秒 Re-binding socket to listen for VNC connections on TCP port 5900 in (all) interface
15/11/2018 20時10分35秒 Listening IPv6://[::]:5900
15/11/2018 20時10分35秒 Listening IPv4://0.0.0.0:5900
15/11/2018 20時10分35秒 Clearing securityTypes
15/11/2018 20時10分35秒 Advertising security type: 'TLS' (18)
15/11/2018 20時10分35秒 Clearing securityTypes

```
起動はできる。パスは通っていないので、直接動かす。

```
$ /usr/lib/vino/vino-server
```
これで起動はする。MacOSXの画面共有から繋いでみても繋がらない。サーバーのセキュリティ設定がダメだと言われる。vinoを起動している端末にこんな表示が出る。

```
15/11/2018 20時39分47秒 Client Protocol Version 3.3
15/11/2018 20時39分47秒 rfbClientConnFailed("No security type suitable for RFB 3.3 supported")
```

ちなみに、RealVNCでも繋いでみると、似たような理由で繋がらない。

```
15/11/2018 20時10分52秒 Client Protocol Version 3.7
15/11/2018 20時10分52秒 Advertising security type 18
```
ちゃんとは理解していないけど、サーバー側のvinoはTLS(18)と言うセキュリティで受けたがっていて、クライアントのセキュリティはそれよりも厳しいものを要求しているので繋がらないっぽい。
普通のubuntuをインストールすれば良いのだろうけど、個人的な趣味でLubuntuを使いたいので、他のソフトを探すことにする。これから調べる。