OmniAICreator/Qiita-1.07M huggingface dataset:
rearでレスキューシステムとデータを1ISOに統合するときの注意点

rearで起動イメージとデータを1ISOにアーカイブしようとしたときに、ハマった点をめも。

* 1ISOファイルが4GB-1Byteを超えると、アーカイブに失敗する。

> genisoimageパッケージの仕様らしい。
Xorrisofsというパッケージなら容量制限は突破できるらしいが、
バックアップを作れてもbootはできなかった、という記載もあった。

参考
> https://bugzilla.redhat.com/show_bug.cgi?id=1462189

てわけで、以下の定義ファイルのように、1ISOに入れないようにした。

```conf
# Default is to create Relax-and-Recover rescue media as ISO image
# set OUTPUT to change that
# set BACKUP to activate an automated (backup and) restore of your data
# Possible configuration values can be found in /usr/share/rear/conf/default.conf
#
# This file (local.conf) is intended for manual configuration. For configuration
# through packages and other automated means we recommend creating a new
# file named site.conf next to this file and to leave the local.conf as it is.
# Our packages will never ship with a site.conf.
OUTPUT=ISO
OUTPUT_URL="file:///var/tmp/rescue"
BACKUP=NETFS
BACKUP_URL="file:///var/tmp/data"
```

コマンド実行は以下。

```terminal
TMPDIR="/var/tmp" rear mkrescue
TMPDIR="/var/tmp" rear mkbackuponly

もしくは
TMPDIR="/var/tmp" rear mkbackup
```
楽天銀行のハッピープログラムのステージを上げるために楽天競馬に自動ログインして100円だけ入金するためのプログラムを作ったよ

※この投稿は楽天銀行のハッピープログラムを利用している方向けの記事になります
※ハッピープログラムについては[公式ページ](https://www.rakuten-bank.co.jp/happyprogram/)をご確認ください


少し前に楽天銀行のハッピープログラムが改悪されました
積み立てNISAで毎日積み立てを行うことでハッピープログラムのステージアップと毎月それなりの楽天ポイントが獲得できるということを改悪ちょっと前に知った自分としては少しショックな出来事でした。

ステージアップすることでATM手数料が無料になったりとポイント以外のメリットもあるので、改悪後のステージアップの方法についてアフィブログなど見ていたところ「楽天競馬に100円だけ入金して出金するを毎日やればOK」みたいな記事を発見。
回数が稼げるのでステージアップは確かに可能、ただ毎日やるのはめんどくさいので、勉強がてらseleniumで自動入金プログラムを作ってみることにしました。

とりあえずコードをgithub上に公開しましたのでreadmeみてどうぞ・・・
この投稿ではちょっとだけつまづいた点について書こうかと思います
https://github.com/rohisama/raku-keiba-auto


## Windowsで動いたけどUbuntuで動かん
OS違うと挙動が変わるってのはあるあるですね。

### なんかエラーが出る
具体的には実行時に以下のようなエラーメッセージが出ていました

~~~
selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: exited abnormally
  (unknown error: DevToolsActivePort file doesn't exist)
  (The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)
~~~
とりあえずggったら[有力な情報](https://www.ytyng.com/blog/ubuntu-chromedriver/)があったのでtry
私の環境では `options.add_argument("--no-sandbox")` を追加で動くようになりました

### 新規タブ画面の要素が取れない
楽天競馬のTOPページから[入金]ボタンを押したときに新規タブが開いてログインページに遷移するのですが、そのページの要素(ID/PWのテキストボックス)が取れないエラーが出ました。
これはsleep突っ込んだらとれるようになりました。
もうちょっといい方法があるのでしょうが、とりあえず使えればOKということで・・・


あとは、こいつをcrontabとかで毎日正午くらいに実行するようにしておけば私のハッピープログラムのステージは一生保証されることでしょう・・・フヒヒ
まぁ、ページがリニューアルされたら対応は必要になりますが(失敗時にSlack通知でもさせるか・・・)
ちなみに、楽天のほかの公営競技についてもハッピープログラムの対象になるそうなので、その辺もそのうち自動化してこうかな。
【Apache Sparkで機械学習】SparseVector(疎ベクトル)とDenseVector(密ベクトル)

# 概要
- Apache SparkのSparseVector(疎ベクトル)とDenseVector(密ベクトル)についての整理

## 環境
- Apache Spark [2.4.3](https://spark.apache.org/releases/spark-release-2-4-3.html)
- 機械学習パッケージ **spark.ml**

# SparseVector(疎ベクトル)とは

Sparse(スパース)とは「スカスカしてる」という意味。  

あるベクトルの要素に0がたくさん含まれるような場合
たとえば

``[0.1,0.0,0.0,0.0,0.3]``

というベクトルがあったとき、

このベクトルを表現するには

「**最初の要素の値が0.1**、**最後の要素の値が0.3**であり**要素数が5**である」


という情報だけで十分だよね、という考え方にもとづく。（その他の要素の値は**0.0**とする)

こうやって、情報量を抑えられるので**メモリも節約できる**というのがご利益。

スパースベクトル的なものは、たいていの機械学習ライブラリで実装されてる。

# SparkでSparceVector

さて、Sparkでスパースベクトルを作る方法は簡単。

**spark.ml**パッケージの**org.apache.spark.ml.linalg.SparseVector**を使う。

**SparseVector**クラスはインデックスの配列(indices)と値の配列(values)を指定して初期化する

``[0.1,0.0,0.0,0.0,0.3]``を作りたいときはインデクスの配列(indices)``new int[] { 0, 2 }``と値の配列(values)`` new double[] { 0.1, 0.5 }``で初期化すればOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170905/8f1974ee-ff26-05cf-1dad-5b7d337cd272.png)



```java:SparseVector
// SparseVector(疎ベクトル)
int size = 3;//ベクトルの要素サイズ
int[] indices = new int[] { 0, 4 };
double[] svalues = new double[] { 0.1, 0.5 };
Vector svec = new SparseVector(size, indices, svalues);
System.out.println("SparseVector=" + Arrays.toString(svec.toArray()));
```

```text:実行結果
SparseVector=[0.1, 0.0, 0.0, 0.0, 0.5]
```

``Vector#toArray``で配列化できるが、必要ない場合はもちろん消費されるメモリはindices(添え字の配列)とvalues(値の配列)のみ保持されるのでメモリが節約される。

# DenseVector(密ベクトル)とは

スパースベクトルと対をなす。一般的な配列と同じようにベクトルの要素の値をすべて保持してる。

``[0.1,0.0,0.0,0.0,0.3]``

# SparkでDenseVector

DenseVecotrは値の配列(values)を指定して初期化する

``[0.1,0.0,0.0,0.0,0.3]``を作りたいときは、その要素数の配列``new double[] { 0.1, 0.0, 0.0, 0.0, 0.5 }``を渡して作るのがDenseVector(密ベクトル)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170905/880cfccb-904d-ec6e-2e83-753847a61952.png)

```java:DenseVector
// DenseVector(密ベクトル)
double[] dvalues = new double[] { 0.1, 0.0, 0.0, 0.0, 0.5 };
Vector dvec = new DenseVector(dvalues);
System.out.println("DenseVector=" + Arrays.toString(dvec.toArray()));
```

```text:実行結果
DenseVector=[0.1, 0.0, 0.0, 0.0, 0.5]
```


# フルソースコード(Java)

**Apache Spark**をJavaから使う

```java:SparkVectorExamples.java
package org.riversun.spark;

import java.util.Arrays;

import org.apache.spark.ml.linalg.DenseVector;
import org.apache.spark.ml.linalg.SparseVector;
import org.apache.spark.ml.linalg.Vector;

public class SparkVectorExamples {

	public static void main(String[] args) {

		// DenseVector(密ベクトル)
		double[] dvalues = new double[] { 0.1, 0.0, 0.0, 0.0, 0.5 };
		Vector dvec = new DenseVector(dvalues);
		System.out.println("DenseVector=" + Arrays.toString(dvec.toArray()));

		// SparseVector(疎ベクトル)
		int size = 5;// ベクトルの要素サイズ
		int[] indices = new int[] { 0, 4 };
		double[] svalues = new double[] { 0.1, 0.5 };
		Vector svec = new SparseVector(size, indices, svalues);
		System.out.println("SparseVector=" + Arrays.toString(svec.toArray()));
	}
}
```

```text:実行結果
DenseVector=[0.1, 0.0, 0.0, 0.0, 0.5]
SparseVector=[0.1, 0.0, 0.0, 0.0, 0.5]
```
Goで設計に役立つEnumの実装を考える

# はじめに
JavaでEnumを使った設計パターンはよくあるんですが、Goで同等のことをどうやるか考えてみました。

# 料金区分を例に
[現場で役立つシステム設計の原則](https://g.co/kgs/ijdRPr)ではJavaのEnumを使った料金区分の設計と実装が紹介されています。
この例を参考にGoで適用するとどうなるか考えてみました。

まずは本と同様に料金区分をinterfaceで実装します。

```go
type Fee interface {
	Yen() int
	Label() string
}

type adultFee struct{}

func (adultFee) Yen() int {
	return 1500
}

func (adultFee) Label() string {
	return "大人"
}

type childFee struct{}

func (childFee) Yen() int {
	return 1000
}

func (childFee) Label() string {
	return "子供"
}
```
料金区分(Fee)をinterface
大人料金(adultFee)と子供料金(childFee)はFeeのinterfaceを満たしています。

# 設計でJavaのEnumを使う魅力
- 定義したものだけを呼べて、定義していないものを呼び出すとコンパイルエラーになる。
- valueOfメソッドで文字列からenumの値を取得できる

# GoでのEnum実装 - 変数で定義
Goで実装してみます。

```go
var FeeType = struct {
	Adult   Fee
	Child   Fee
	ValueOf func(s string) (fee Fee, err error)
}{
	Adult: adultFee{},
	Child: childFee{},
	ValueOf: func(s string) (fee Fee, err error) {
		switch s {
		case "adult":
			fee = adultFee{}
		case "child":
			fee = childFee{}
		default:
			err = fmt.Errorf("未定義の料金タイプ %s", s)
		}
		return
	},
}
```

ポイントは定義したものだけを呼び出せるようにstructのメンバーとして定義済みの値を用意しました。
また、valueOfについてもstructのメンバーとして追加しています。

# GoでのEnum実装 - 関数で定義
変数での定義が気になる方は、こんな方法も

```go
func FeeType() struct {
	Adult   Fee
	Child   Fee
	ValueOf func(s string) (fee Fee, err error)
} {
	return struct {
		Adult   Fee
		Child   Fee
		ValueOf func(s string) (fee Fee, err error)
	}{
		Adult: adultFee{},
		Child: childFee{},
		ValueOf: func(s string) (fee Fee, err error) {
			switch s {
			case "adult":
				fee = adultFee{}
			case "child":
				fee = childFee{}
			default:
				err = fmt.Errorf("未定義の料金タイプ %s", s)
			}
			return
		},
	}
}
```

変数と違い関数なので間違っても上書きされないので安心です。

# まとめ
今回はGoでJavaのEnum相当の機能を作り込む方法を考えてみました。
こんなやり方もあるよという方がいればコメント欄などで教えてもらえると嬉しいです。

# 参考
[GoでEnumを定義する 〜intやstringよりも厳密に〜](https://qiita.com/ikngtty/items/ad135599a2f92e6035fa)
AWS Lambdaで環境変数のKMS暗号化を利用した際にハマったこと

# はじめに

AWS Key Management Serviceを利用してAWS Lambdaに設定する環境変数をKMS暗号化して利用しようとした際にハマったことのメモ。

# ハマったこと

## CloudFormationで「伝送中の暗号化のためのヘルパーの有効化」を設定できない

CloudFormationでKMSキーの作成からLambda関数の環境変数への適用までを行いたい。
そこで以下のようなスタックテンプレートを作成してスタックを作成してみた。

```stack-template.yml
Parameters:
  AccessToken:
    Type: String
  (中略)
  Key00:
    Type: AWS::KMS::Key
    Properties:
      KeyPolicy:
        Version: "2012-10-17"
        Id: !Sub ${appName}-aws-apikey-00-keypolicy
        Statement:
          -
            Sid: "Allow administration of the key"
            Effect: "Allow"
            Principal:
              AWS: !Sub arn:aws:iam::${AWS::AccountId}:root
            Action: "*"
            Resource: "*"
          -
            Sid: "Allow use of the key"
            Effect: "Allow"
            Principal:
              AWS: !GetAtt Role00.Arn
            Action: 
              - "kms:Encrypt"
              - "kms:Decrypt"
              - "kms:ReEncrypt*"
              - "kms:GenerateDataKey*"
              - "kms:DescribeKey"
            Resource: "*"
  Function00:
    Type: AWS::Lambda::Function
    Properties:
      Environment:
        Variables:
          access_token: hogehogetokun
      KmsKeyArn: !GetAtt Key00.Arn
      (中略)
```

しかし、CloudFormationにより作成されたLambda関数のコンソールを見てみると、`保管時に暗号化する AWS KMS キー`は指定されているが、`伝送中の暗号化のためのヘルパーの有効化`は無効のままのため、環境変数は暗号化されず平文が丸見えである。
![img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258416/d2a77b79-949a-f5db-85e2-3e51a1b85ceb.png)

調べてみるとクラスメソッドの下記の記事でも、同箇所でCloudFormationで環境変数を暗号化までする方法が見つからなかったようで、本箇所のみ関数のコンソールから設定している。

https://dev.classmethod.jp/cloud/aws/lambda-slack-cloudwatch-cloudformation/

仕方がないのでわたしもコンソールから手動で`伝送中の暗号化のためのヘルパーの有効化`を有効化してKMSキーを指定し、環境変数を平文で表示されないようにした。
![img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258416/2d7109bb-2235-a526-3944-2dde0a8680f5.png)

## 環境変数の復号結果がbytes型になる

KMS暗号化された環境変数をコード内で復号すると既定でbytes型の文字列になる。
文字列として扱いたい場合は`decode('utf-8')`などでバイト列から文字列にデコードする必要がある。

```lambda_function.py
import boto3,os
from base64 import b64decode

def lambda_handler(event, context):
    ENCRYPTED = os.environ['access_token']
    DECRYPTED = boto3.client('kms').decrypt(CiphertextBlob=b64decode(ENCRYPTED))['Plaintext']
    print(DECRYPTED)
    print(DECRYPTED.decode('utf-8'))
```

```
# 実行結果
b'hogehogetokun'
hogehogetokun
```

環境変数を暗号化した際に「コード」ボタンで表示できる「シークレットスニペットの復号」のコード内では特にutf-8デコードはされていなかったので、`DECRYPTED`が後続の処理にうまくわたせずにハマった。

# 参考

https://qiita.com/seisyu1985/items/880c5e49e8c8677bc9e3
https://qiita.com/FGtatsuro/items/f45c349e06d6df95839b
https://python.civic-apps.com/python3-bytes-str-convert/

以上
scikit-image でテンプレートマッチング

match_template というそのものズバリな関数があります。

`skimage.feature.match_template(image, template, pad_input=False, mode='constant', constant_values=0)`

# 公式ドキュメント
[Module: feature — skimage docs](https://scikit-image.org/docs/stable/api/skimage.feature.html#skimage.feature.match_template)
[Template Matching — skimage docs](https://scikit-image.org/docs/stable/auto_examples/features_detection/plot_template.html)

# 使用例1
第1引数に入力画像、第2引数にテンプレート画像を指定すればOK。

```python
import matplotlib.pyplot as plt
import numpy as np
import skimage
import skimage.feature
import skimage.io
from matplotlib.patches import Rectangle

img = skimage.io.imread('img.png', as_gray=True)
img = skimage.img_as_ubyte(img)
templ = skimage.io.imread('templ.png', as_gray=True)
templ = skimage.img_as_ubyte(templ)

result = skimage.feature.match_template(img, templ)
r, c = np.unravel_index(np.argmax(result), result.shape)

plt.figure()
plt.subplot(2, 1, 1)
plt.imshow(templ, vmin=0, vmax=255, cmap='gray')

plt.subplot(2, 2, 3)
plt.imshow(img, vmin=0, vmax=255, cmap='gray')
rect = Rectangle((c, r),
                 templ.shape[1],
                 templ.shape[0],
                 fill=False,
                 color='red')
plt.gca().add_patch(rect)

plt.subplot(2, 2, 4)
plt.imshow(result, vmin=-1, vmax=1, cmap='bwr')

plt.savefig('figure.png')
plt.close()
```

![figure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119255/e73cbcc8-085c-7c68-711c-54012dda0583.png)


# 使用例2
`pad_input=True` とすると、テンプレート画像が入力画像から多少はみ出していても検出できるようになります。

```python
import matplotlib.pyplot as plt
import numpy as np
import skimage
import skimage.feature
import skimage.io
from matplotlib.patches import Rectangle

img = skimage.io.imread('img.png', as_gray=True)
img = skimage.img_as_ubyte(img)
templ = skimage.io.imread('templ.png', as_gray=True)
templ = skimage.img_as_ubyte(templ)

result = skimage.feature.match_template(img, templ, pad_input=True)
r, c = np.unravel_index(np.argmax(result), result.shape)

plt.figure()
plt.subplot(2, 1, 1)
plt.imshow(templ, vmin=0, vmax=255, cmap='gray')

plt.subplot(2, 2, 3)
plt.imshow(img, vmin=0, vmax=255, cmap='gray')
rect = Rectangle((c - templ.shape[1] // 2, r - templ.shape[0] // 2),
                 templ.shape[1],
                 templ.shape[0],
                 fill=False,
                 color='red')
plt.gca().add_patch(rect)

plt.subplot(2, 2, 4)
plt.imshow(result, vmin=-1, vmax=1, cmap='bwr')

plt.savefig('figure.png')
plt.close()
```

![figure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119255/82142e73-3abe-b064-c4c4-eb641caf7982.png)
【Git】.gitignoreでファイル管理しよう

ソース管理にGitを使用しています。
基本的にはGitでバージョン管理をするわけですが、中には例外となるファイルも存在します。

今回はGitでソース管理をする上で、除外するファイルの管理方法についてまとめました。

# Gitで管理すべきでないファイルとは？

- 自動作成されるファイル
 - ログファイル
 - パッケージファイル
 - バックアップファイル
 - ビルド後の成果物
 - エディタ特有のファイル
- OSのファイル管理に使用されるファイル
 - Thumbs.db(Windows)
 - .DS_Store(macOS)
- 共有すべきでないファイル
 - パスワードが記載されたファイル

自動作成されるファイルをあえてGitでバージョン管理する必要はありません。
また、パスワードが記載されているファイルに関しては、セキュリティの兼ね合いからGitで管理するかをきちんと検討する必要があります。

# .gitignoreを使って管理しよう

Gitで管理すべきでないファイルは.gitignoreファイルを作成し、管理しましょう。
.gitignoreとは、簡単に説明すると「Gitが無視してくれるファイル/フォルダの定義」のことです。

.gitignoreファイルは作成したディレクトリ配下のパスにのみ有効です。
ファイルを作成する際はどのパスを有効にしたいかを考えてから作成しましょう。

# .gitignoreの作成方法
作成方法は簡単で、エディタで.gitignoreファイルを作成します。
作成したファイルにGitで管理したくないファイル名やフォルダ名を入力します。

```
.vscode/
node_modules/
dist/

*.log

Thumbs.db
.DS_Store
```

使用する技術やIDEやエディタを指定してgitignoreを生成してくれるサイトもあります。
<img width="533" alt="コメント 2019-07-28 002654.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/e0881d41-04ea-4915-6868-080a877c12c8.png">
[gitignore.io](http://gitignore.io/)で検索し、.gitignoreを作成する参考にしてみるのもいいでしょう。

# まとめ
Gitで管理すべきでないファイルというものは、個人で使用している場合は自分の判断で問題ありません。

ただ、業務で使用しているソース管理をGitでする場合に関しては、自分の判断だけで決めてはならない場合もあります。
そういった場合は、きちんとルールを確認し、判断することが重要です。
rearの一時領域の変更方法

# rearバックアップ時の一時領域

通常であれば、/tmpが使われる。しかし、起動イメージ内にバックアップデータも含めたりすると、
/tmpが溢れてしまい、こんな感じになってしまう。

```
cp: cannot create regular file '/tmp/rear.vZcBEdh17zZY11r/tmp/isofs/backup/backup.log': No space left on device
```

回避策は以下。

```
TMPDIR="/var/tmp" rear mkbackup
```

TMPDIR変数をexportするのはだめらしい。最新だとできるのかもしれないが、試してない。

> https://github.com/rear/rear/issues/967
Quasar(Vue.js)をTypeScript化してみる

Vue.jsでハイブリットアプリやPWAを開発するのにQuasarがとても便利そうなので、TypeScript化してみようと思います。

# Quasarとは
Vue.jsでクロスプラットフォーム開発ができるフレームワークです。
SPAやPWA、SSR、Mobileアプリ(iOS、Android)、Desktopアプリなどに対応しています。
https://quasar.dev/

MobileアプリとしてはCordovaを使っているようなので、ReactNativeというよりは、IonicやOnsernUIに近いハイブリットアプリのようです。
UI Componentが豊富で、特にDesktopアプリやPC向けのSPAなどを開発する際にあると嬉しいコンポーネントが色々と用意されています。

# TypeScript化する
## 1. Quasar CLIでアプリを作成する
チュートリアルに沿って下記コマンドを実行します。
https://quasar.dev/quasar-cli/installation

```
$ npm install -g @quasar/cli
$ quasar create hoge-app
```

## 2. package.jsonを修正する
Quasar CLIでサービスを稼働しやすくするため、npm scriptsに下記コマンドを追加します。

```json:package.json
"scripts": {
  "dev": "quasar dev",
  "build": "quasar build",
  "build:pwa": "quasar build -m pwa"
}
```

## 3. Extensionを追加する
QuasarをTypeScritp化するためのExtensionを追加します。
※まだベータ版のようです。(2019/7/27時点)

```
$ quasar ext add @quasar/typescript
```

いくつか設定について聞かれますが、基本はrecommendedかYesで問題ないです。

```
? Please choose how to derive webpack: Use the fork-ts-checker-webpack-plugin module for type-checking (recommended)
? Rename .js files to .ts (experimental) Yes
? Will you use VSCode for this project? (Adds ESLint and Vetur configuration quirks, you must manually install the extensions) 
Yes
? Generate prettier configuration (ESLint and VScode, if used)? Yes

? Overwrite ".eslintrc.js"? Overwrite
```

## 4.TypeScriptライクな表記に変更する
デコレーターを使います。
併せてtsファイルをvueファイルから切り出します。

```ts:page/Index.ts
import Vue from 'vue';
import Component from "vue-class-component";

@Component({
  name: 'PageIndex'
})
export default class Index extends Vue {
  public message: string = "This is a test message";
}
```

```html:page/Index.vue
<template>
  <q-page class="flex flex-center">
    <p>{{message}}</p>
  </q-page>
</template>

<script lang="ts" src="./Index.ts"></script>
```

## 5.サービスを起動する
npmコマンドでサービスを起動し、以下のような画面が表示されていればTypeScript化成功です。

<img width="1429" alt="Quasar_App.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92492/6eae9efd-56e1-c465-64ee-aa485efa7fc6.png">
UbuntuでPython2.X.Xが最初から端末にデフォルトされているが、それをPython3.X.Xのデフォルトにしたい

　UbuntuではPython2.X.Xが最初から端末にデフォルトされているが、それをPython3.X.Xのデフォルトにしたい。

　色々と検索をして弄ってみたが、どれも上手く行きませんでした。

　それで端末を立ち上げてpythonと入力して、enterをしたら、Python2.7.15がデフォルトであると表示されました。
![Screenshot from 2019-07-27 23-19-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442057/ddb62839-da9f-d8e8-514b-ee709285d194.png)

　しかし、今使っている教材が、Python3.X.Xをデフォルトにして、学習するものだったので、さてどうするべきかと思っていて、端末にPython3.7(現時点で最新のもの)と入力してenterしてみると、当然使えなかったのです。

　それでもう一度、端末を良く読んでみたら、次の　$ sudo... を使うことが出来ますと英語で表示されておりました。（残念ながらスクリーンショットを忘れてしまいました。） 

　そして、それをコピペして実行してみると次のような状態になりました。
![Screenshot from 2019-07-27 23-20-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442057/6585dd22-62a5-9975-cfaf-57c7b29b14a0.png)

　一応、python3.7.3がデフォルトとして使えると表示されております。

　事業所のwindows7でPythonをインストールしたときは、こんな手間は要らなかったのです。

　どうもUbuntuの場合は、これから端末に入力するという際には、WinやMacとは違う独自の文字入力があるようで、それを上手く探して、使いこなすというところに持っていく必要があるようです。例えば ￥ や / の入力ですとか…、Ubuntu仕様の記載方法が分からないでおります。

どうも他の人のページを見ていると、Python 2.7.15はUbuntuからアンインストールは出来ないと、書いている方がおられまして、それでこれからどうするかということになったのです。

このまま使い続けても、端末は果たしてpython3.7.3として「自動的」に起動するかどうかを、今確認をとっているところであります。

![Screenshot from 2019-07-27 23-53-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442057/363cf8be-f493-2b79-4df5-a92b55f4d728.png)

という現時点での話でありました。
何か良い知恵が御座いましたら、コメント頂けると嬉しいです。

これから随時、Python の記事を自分のためにレポートします。

Qiita初心者で、読みやすい文章の書き方もわかりませんが、どうぞご指導頂けると嬉しく思います。宜しくお願い致します。

参照　次の記事を試させて戴きたいと思っております。
[PyenvによるPython3.x環境構築(CentOS, Ubuntu)](https://qiita.com/akito1986/items/be5dcd1a502aaf22010b)
Visual Studio Codeのフォントをゆたぽんコーディングにする方法

VS Codeでコーディングする際にゆたぽんコーディングを使用しています。

最初はかわいらしい文字だし、誤字を防ぐ目的で使用していたのですが、慣れると愛着が湧くもので今ではゆたぽん設定しなくちゃ！
と、使命感にかられるようになってしまいました。笑

いつPCセットアップすることになっても困らないようにゆたぽんコーディングにする方法をまとめました。

# ゆたぽんコーディングをPCにダウンロード

[ゆたぽんダウンロードページ](http://net2.system.to/pc/font.html)からダウンロードします。
<img width="641" alt="コメント 2019-07-27 210632.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/afff1c51-740a-9515-5f73-471a7ce9c281.png">
最新バージョンをクリックすると、PC内にダウンロードされます。
<img width="445" alt="コメント 2019-07-27 210311.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/61d1c69d-cd6f-4660-659f-8a8ce7b45375.png">
ダウンロードされたら「yutapon_coding_081.ttc」をクリックします。
<img width="707" alt="コメント 2019-07-27 210917.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/85d20553-8c91-9e23-52a9-b84d0e28b86a.png">
画面左上に `インストール(I)` があるので、クリックします。
ダウンロードが終わったら、画面を閉じてください。
これでダウンロードまで終了です。

# VS Codeのフォントを変更
<img width="593" alt="コメント 2019-07-27 223454.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/5e363271-72ab-14db-0889-edd1de8071dc.png">
 `Windowsキー` → `font` → `フォント設定`をクリック → 使用可能なフォント検索画面に「yutapon」と入力します。
<img width="593" alt="コメント 2019-07-27 223611.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/f0e17679-c66d-f5ff-f9df-71985d6b650d.png">
フォント名を確認します。
<img width="626" alt="コメント 2019-07-27 221526.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/0ea9ec65-ae78-bcd9-0f49-316e99293307.png">
VS Codeを開いて `Ctrl` + `,` で設定画面を開きます。
<img width="410" alt="コメント 2019-07-27 234048.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/f08d34ee-db47-2d36-1a67-9c122aec5c81.png">
 `Editor:Font Family` にフォント名を入力すれば完了です。

# まとめ
プログラミング用フォントにもいくつも種類があります。
自分が見やすいフォントと出会い、快適なエンジニアライフを送りましょう。
LINE Pay APIを手軽に試してみた

# はじめに
@nkjmさんの[ある記事](https://qiita.com/nkjm/items/b4f70b4daaf343a2bedc)の影響を受けて自分もLINE PayのAPIを試してみました。LINE APIとは何か、その導入方法とは？についての内容は最初に示したリンク先がかなり詳細に書いてあるので省きます。APIを使ったサンプルコードもリンク先の記事のものを使いました。
なのでコードの詳細は記事を見てもらうとして、私の方では以下の２つだけ変更してもう少し気軽に使ってみました。

- ngrokでデプロイ環境なしでhttpsサーバーを立てた
- 直接LIFFに組み込んでリッチメニューから決済画面を起動してみた

# ngrokでhttpsサーバーを立ててみた
[ngrok](https://ngrok.com/)についての解説などは既にいくつか[記事](https://qiita.com/mininobu/items/b45dbc70faedf30f484e)があります。とりあえず簡単に説明するとFirebaseとかAWS,Herokuにデプロイしなくてもhttpsのサーバーがローカルで立てられるツールです。導入方法はいくつかあるみたいですが、[npmにもある](https://www.npmjs.com/package/ngrok)のでそこから

```
npm install ngrok -g
```

でインストールしてしまえばすぐに使えます。起動方法も、

```
ngrok http 5000
```


と打ってしまえば一発です。そしたら↓のような感じの結果が表示されます。

```
Session Status                online
Session Expires               7 hours, 36 minutes
Update                        update av9 minutes ersion 2.3.34, Ctrl-U to update)
Version                       2.3.27Region                        United States (us)Web Interface                 http://127.0.0.1:4040
Forwarding                    http://XXXXX.ngrok.io -> http://localhost:5000
Forwarding                    https://XXXXX.ngrok.io -> http://localhost:5000
```

とりあえず必要なのは一番下の`https://XXXXX.ngrok.io`です。このURLを獲得したら、[この記事](https://qiita.com/nkjm/items/b4f70b4daaf343a2bedc)の内容で設定した環境変数を少しいじります。

```/.env
LINE_PAY_CHANNEL_ID=YOUR ID
LINE_PAY_CHANNEL_SECRET=YOUR SECRET
LINE_PAY_CONFIRM_URL=https://XXXXX.ngrok.io/pay/confirm
```

`LINE_PAY_CONFIRM_URL`にさっき取得したURL＋/pay/confirmのものを設定します。後、記事の方では`LINE_PAY_HOSTNAME=プロキシのホスト名`を設定していましたが、テストしてみるだけだったら今回は不要です。

# リッチメニューから決済画面のLIFFを呼び出す。
リッチメニューからLIFFの起動については[偶々書いた記事](https://qiita.com/ufoo68/items/94510bafa0a9f53f8099)がありました。参考にしてみてください。
ただ、この記事だとリッチメニューの登録をcurlでコマンド打ってやってましたが（この頃あまりLINE APIよくわかってなかった）、別に[LINE Official Acount Manager](https://manager.line.biz/)というところからサイト上のGUIでできるのでそっちの方が楽だと思います。また、リッチメニューの登録には画像が必要になります。特にこだわりなければ適当に作ったものを置いておくので使ってください。サイズは2500*1686です。

![LINE Pay.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/09d2bf0e-2f6b-a5e8-544e-53cf3a69204e.jpeg)

# 動作結果
最初はこんな感じでリッチメニューが立ち上がります（なんとも雑）。
![iOS の画像 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/787a729c-3a30-1003-6af6-eb6ce288137d.png)
メニューをタップしてLIFFが起動して決済方法の選択画面に移ります（といってもLINE Payのみ）。
![iOS の画像 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/d0a21239-265c-ea06-2811-1daa6e98643e.png)
LINE Payを選んで決済画面に移ります。LIFF上だと最初からログインされているので楽ですね。
![iOS の画像 (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/add3d93b-6403-a95b-44f3-5611dd3860cb.png)
決済に成功したらこんな感じの画面になります。
![iOS の画像 (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/5d767feb-691b-1a5b-ee4f-e01e9f5932a9.png)

# 最後に
LINE Payを実際に導入する場合は加盟店の登録が必要になるみたいですが（[こちら](https://pay.line.me/jp/intro?locale=ja_JP)を参照）、Sandbox（要はテスト環境）で使うだけなら特に面倒な手続きはいりません（[こちら](https://pay.line.me/jp/developers/main/main?locale=ja_JP)を参照）。
今回は購入するものを「チョコレート」とハードコーディングしていましたが、折角なのでUI上のメッセージのやり取りから買い物かごリストを作るとかやってみたいですね。
vue-codemirrorはproductionモードだと挙動が変わるようです

## vue-codemirrorはproductionモードだと挙動が変わるようです。
タイトルの通りです。バグなのかわかりませんが、productionの時のみcodemirrorタグが生成されたりと、生成されるDOMエレメントが微妙に違います。

スタイルが適用されないなどのトラブルがある場合は、DOMを確認してみるのが良さそうです。
この記事が参考になれば幸いです。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
【mac】diskutilコマンドでliveUSBを作成する

# はじめに
liveUSBを作成するフリーソフトは数多く存在するが、
mac環境を汚したくない人向けに下記の手順でliveUSBを作成できる

### 参考
mac環境が汚れてもいい人はこれを進める
フリーソフト「UNetbootin」
https://unetbootin.github.io/

## コマンドライン
ubuntu16.04のイメージディスクが入ったliveUSBを作成した例
 
```
# mountされているディスクの確認
diskutil list

# ディスクのフォーマット(MS-DOS:ファイルシステム,UNTITLED:ディスク名) 
diskutil eraseDisk MS-DOS UNTITLED /dev/disk3

# ディスクのアンマウント
diskutil unmountDisk /dev/disk3

# isoイメージの書き込み(if=<isoイメージ>,of=<ディスク>,bs=<ブロックサイズ>) *1
sudo dd if=~/Downloads/ubuntu-16.04.6-server-i386.iso of=/dev/disk3 bs=8056

# ディスクの取り出し
diskutil eject /dev/disk3
```

*1:書き込み終了時に下記のエラーぽい表示が出るが、きちんとliveUSBとして読み込めるので問題ない。
![write_iso_to_usb_finished.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251749/cb0528fc-3b6c-b2bd-8e48-9ac22870c8b9.png)
certbot-auto renewではまったこと - Nginxのaliasとrootの違い


###Spec and Software
- EC2 Amazon Linux2
- Flask app with Nginx as reverse proxy
- Docker
- certbot-auto


###Issue
証明書が切れてから二日間くらい試行錯誤してました。何度やっても以下のエラー。

```
Challenge failed for domain <サイト>
http-01 challenge for <サイト>

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: <サイト>
   Type:   connection
   Detail: unknownHost :: No valid IP addresses found for <サイト>

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address. Additionally, please check that
   your computer has a publicly routable IP address and that no
   firewalls are preventing the server from communicating with the
   client. If you're using the webroot plugin, you should also verify
   that you are serving files from the webroot path you provided.
```

###References
- https://stackoverflow.com/questions/10631933/nginx-static-file-serving-confusion-with-root-alias
- https://community.letsencrypt.org/t/how-to-nginx-configuration-to-enable-acme-challenge-support-on-all-http-virtual-hosts/5622/3
- https://community.openhab.org/t/using-nginx-reverse-proxy-authentication-and-https/14542

###Root cause

1) 問題点は以前証明書を発行した後に以下の内容を変えていた点。

- /etc/nginx/nginx.conf
- /etc/nginx/sites-available/<サイト>.conf


2) この部分を全く考慮していなかった点。

```
location ^~ /.well-known/acme-challenge/ {
  alias /path/to/your/directory/;
}
```

ちなみにこの"^~"も知らなくてここで調べました。

- https://www.keycdn.com/support/nginx-location-directive



###Fix
1)に関しては今後は気をつける
2)はログにヒントが /var/log/letsencrypt/letsencrypt.log

```
2019-07-22 21:49:18,483:DEBUG:certbot.plugins.webroot:Attempting to save validation to /path/to/your/directory/.well-k
nown/acme-challenge/XXXXXXXXXXXXXXXX
```

この行を探して/etc/nginx/sites-available/<サイト>.confで

```
location ^~ /.well-known/acme-challenge/ {
  alias /path/to/your/directory/;
}
```

を追加したらサクッといけました。。。

```
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/<サイト>/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/<サイト>/fullchain.pem (success)
```

###Tips
あと、まずはdryrunするといいです。自分の場合はこれになってしまいました。

- https://community.letsencrypt.org/t/too-many-requests-of-a-given-type-how-do-you-reset-this/44182/2
CodeForces Round #531 E (1102E) Monotonic Renumeration

CodeForces Round #531 E (1102E) Monotonic Renumeration
===

https://codeforces.com/contest/1102/problem/E

問題の制約から実装の制約にうまく落とせるかが難しい。

この問題は以下のように言い換えられる。

- 数列a(a1,a2..an)を走査していき数列b(b1,b2..bn)が何組生成できるかを数え上げる
- 数列aのある要素をxに対して、はじめて出現する場所をFx, 最後に出現する場所をLxとする
- FxからLxまでに対応するBnはすべて同じ値となる。これをロックされている状態と呼ぶ。
- ロックされていない状態で、始めて出てくる数字(これはxがFxの時に他ならない)のとき、対応するBnはBn-1に対して同じ値でもよいし、+1してもよい。

この実装は以下の通りとなる。

- 結果を1(通り)に設定する
- ロックされている位置は設定されていない
- 数列aを走査し、各値毎のFx, Lxをdictで学習する
- 再度aを走査する。
- (n!=1の場合),今の数字のFxが今の場所であるとき、結果を2倍する(またmodする)
- ロックされている位置について、今の数字のLxのほうが大きければその数に変更する

このようになる考察は以下の通り。

```
制約の確認をすると、
制約a b1は"0"である
制約b aの数字が同じ場合、対応するbの値はすべて同じである。例えば、a2=2なら
  1 2 3 4 5 2 2 6 7 の場合
  0 0 ? ? ? 0 0 ? ? となる
制約c 数列bの各項はb[i] = b[i-1] か b[i] = b[i-1] +1である
  つまり、前の項に1を足してもいいし、そのままでもいい

制約b, cを考えると、の意味は(制約aからb1 = 0は固定なので、
 1 2 3 4 5 2 2 6 7 の場合
 0 0 ? ? ? 0 0 ? ? となる
 0 1 ? ? ? 1 1 ? ? となる
が考えられる。
a=3,4,5の?については、
 1 2 3 4 5 2 2 6 7 の場合
 0 0 0 0 0 0 0 ? ? 
 0 1 1 1 1 1 1 ? ? 
のいずれかに固定される。なぜなら、前の項から+0から+1しかできないため、
a6の2が0なのに15が1になってはならない。
つまり、2ではさまれている区間についてはすべて同じ数でなければならない。
```

例えばほかに、
1 2 3 2 2 2 1 6 3
を考えると、

```
0 0 0 0 0 0 0 0 0
の一通りしか存在しえない。この根拠をいかに述べる。
まず、b10のため、1の際に7項目の1は0となる。
0 ? ? ? ? ? 0 ? ?
また、上記のように、1項目～7項目は0であるため、
0 0 0 0 0 0 0 ? ?
となる。これにより、3項目の数字3に対応するbは0になる。すなわち、
0 0 0 0 0 0 0 ? 0
は確定する。となると、8項目が0であることは自明であるため、0と確定する。
```

この考察を基に、条件を考えると、上記のような実装となる。

```Python
mod = 998244353

n = int(input())
dat = list(map(int, input().split()))
num_firstpos = dict()
num_lastpos = dict()

# ある数字が
# num_firstpos: 最初に出現する場所
# num_lastpos: 最後に出現する場所
for i in range(n):
    num_lastpos[dat[i]] = i
    if dat[i] not in num_firstpos:
        num_firstpos[dat[i]] = i

# 結果の初期値は1通り
res = 1

# dat[0]の読み込み
cur = 0
skipto = num_lastpos[dat[0]]

while cur < (n - 1):
    # インクリメントと文字の読み込み
    cur += 1
    curval = dat[cur]

    # もし、ロックされていないて、
    if skipto <= cur:
        # この数字が過去に出ていない時に限って
        # (過去に出ているなら値はロックされているので)
        if num_firstpos[curval] == cur:
            # この数字の取りうるのは2通りなので、結果を倍にする
            res *= 2
            res %= mod

    # スキップ位置の更新
    skipto = max(skipto, num_lastpos[curval])

# 結果の表示
print(res)
```

https://codeforces.com/contest/1102/submission/57788782
投稿日時を日本時間表記にする方法

# はじめに
ruby on railsでチャットアプリ作成中
メッセージを投稿すると日時の表記が日本時間になっておらず表示のされ方もなんか見にくい。。

#解決方法

config/application.rb 
config.time_zone = 'Tokyo' を追記して時間設定を日本にする。
[![Image from Gyazo](https://i.gyazo.com/6ac42de1fffcfb680070ef6b476b709d.png)](https://gyazo.com/6ac42de1fffcfb680070ef6b476b709d)

app/views/messages/_messages.html.haml　
.strftime("%Y-%m-%d %H:%M")　を追記して表示の仕方を見やすくしてあげる。
[![Image from Gyazo](https://i.gyazo.com/a8c151f9a4815baface7fca2c2232e68.png)](https://gyazo.com/a8c151f9a4815baface7fca2c2232e68)

もし非同期通信とか使っていたらこっちにもちゃんと変換されるようににも追記しておきましょう。
messages/index.json.jbuilder 
[![Image from Gyazo](https://i.gyazo.com/367a94deebfb2043c3a0b113cfcead41.png)](https://gyazo.com/367a94deebfb2043c3a0b113cfcead41)
#結果
こんな感じで表示されればおk！
[![Image from Gyazo](https://i.gyazo.com/c697039d5e2d037f6a34713ee91bfb48.png)](https://gyazo.com/c697039d5e2d037f6a34713ee91bfb48)
AAとかのBlock diagrams tools調べてて、graph-easyにたどり着いたのだが。

# Installation

>cpan Graph::Easy

でinstallするという記事をいくつか見かけましたが、できなかったのですが
下記コマンドでinstallできました。

```bash
$ perl -MCPAN -e 'install Graph::Easy'
```

# example

```bash
$ graph-easy <<< '[ Load balancer ] --> { start: front, 0; } [ server 1 ], [ server 2 ]'
+---------------+          +----------+
| Load balancer | -+-----> | server 1 |
+---------------+  |       +----------+
                   |       +----------+
                   +-----> | server 2 |
                           +----------+
```

ただし、日本語だとずれる。

```bash
$ graph-easy <<< '[ ロードバランサー ] --> { start: front, 0; } [ サーバー 1 ], [ サーバー 2 ]'
+----------+          +--------+
| ロードバランサー | -+-----> | サーバー 1 |
+----------+  |       +--------+
              |       +--------+
              +-----> | サーバー 2 |
                      +--------+
```

# さいごに

そうこうしている頑張って、調べているうちに気づきました。
[Monodraw](https://monodraw.helftone.com/)使えば
もっと簡単にGUIで書いて、markdownへコピペしてできることに気づいた。。。今後これ使う。
有料版でも買い切りで、複数Macでいけるみたい。

```markdown

┌───────────────┐       ┌──────────────┐
│ Load Balancer │───┬──▶│   Server 1   │
└───────────────┘   │   └──────────────┘
                    │                           
                    │   ┌──────────────┐
                    └──▶│   Server 2   │
                        └──────────────┘
```

ただ、やっぱり日本語はずれた。まぁ英語がいいよね。

```
┌───────────────┐        ┌──────────────┐
│   ロードバランサー    │───┬───▶│    サーバー 1    │
└───────────────┘   │    └──────────────┘
                    │                    
                    │    ┌──────────────┐
                    └───▶│    サーバー 2    │
                         └──────────────┘
```
php-master-changes 2019-07-26

今日は run-tests.php の修正、ドキュメントの修正があった！

# 2019-07-26
## morrisonlevi: Remove .post files only for passing tests
- https://github.com/php/php-src/commit/5649267b257c78e46a934434c0bff894e0b5b694
- [7.2~]
- run-tests.php で、成功したテストのみ .post ファイルを削除するよう修正
- 残しときゃこけたテストの分をスクリプトで処理できるよということらしい

## cmb69: Remove duplication
- https://github.com/php/php-src/commit/e1c80d8ea71c4ca70cf3fcd0dd8f4db1918bcd91
- [7.4~]
- UPGRADING で、zend.exception_ignore_args についての記述が二箇所にあったのを修正

## theodorejb: Fix typos in UPGRADING and improve wording in a few places
- https://github.com/php/php-src/commit/0e6e2297fcb27103cc5d550ee8434680ff1e879e
- [7.4~]
- UPGRADING で、typo / 英語の修正

## petk: Mention also API versions bumps
- https://github.com/php/php-src/commit/f1c4b48c840bc65782e77728feea9aa2e1268ca6
- [7.4~]
- docs/release-process.md で、API バージョン引き上げルールについて追記
エンジニアになって一年間経つので 今までやってきたことをまとめようと思う


#  目的

人は簡単に記憶をなくしてしまう。それがたった一年のことであっても...()

要するに忘れっぽいのでメモっておくとあとから振り返れて便利よねってことです。
今までの自分を客観的に見れるので 頑張り度がわかるし
いま自分に何が足りていないかも確認できるからとっても便利〜〜！ やったね！！！



## ◆  使用してきた環境・言語・フレームワーク・ツール
  
■ 言語

* Ruby
* Javascript


■ ツール・フレームワーク

* Git
* Github
* Zenhub
* Ruby on Rails
* AngularJS
* Protractor
* Cordova
* GAS
* GoogleAnalytics
* AWS (lambda)
    * S3（ちょっとだけ）
* Kintone（ちょっとだけ）
* Redash
    * Mysql
* Confluence
* Slack


## 環境

 * Mac
    * Linux
        * Bash・Zsh
 * iOS
    * iPhone SE~XR(開発視点で)
    * iPad
 * Android
 * Docker（ちょっとだけ）
 * AWS
    * CloudWatch
    * SNS
    * Lambda
    * S3



## ◆ 詳細とコメント (% = 達成率、己の認識する達成度合い)





* Backend -> 40%(100%)
    * Ruby on Rails
        * Tests & Codes
            * Comments: 
            * 実際に新機能を作成したことはほとんど無いことになる...><
            * 来年度は新機能を作成できるように動いていく　Backend 弱すぎ問題;;　
            * 何かしらサービス作っていく過程でAPIサーバつくりたい
               




*  Frontend -> 70%(100%)
    * AngularJS (!!?)
        * Codes
            * Comments:
              * この一年で多少なりとも理解と実装ができるようになった部分。
              * ほぼ未経験ながら先達の実装を真似ながら 頑張った。
                * 新機能開発に一部携わった部分だが、スマホ対応で壊滅的な実装をしてしまったのが反省点。
                * 素のJSを使用しているためTypescriptを使用したい...
                  Async/AwaitとES6文法を抑えたい。
               


               　　　　　
* E2E Tests -> 10%(100%)
    * Protractor
        * Automatic tests on browser
            * Comments: 
              * 入社当時、走り始めていたPJで、開発に慣れるという意味でも丁度いいテーマだった。
              * 色々任せてくれたので、命名規則作成したりディレクトリ構成を考えたりなどやりたいことが試せて楽しかった。
              * うまく活かせれば大きな資産となりうるが最初の構成とロードマップをきちんと作っていかないと簡単に負債になる。。。
              * あと割と維持コストが高いのも難点...><


*  AWS (lambda)  -> 80%(100%)
   

    * Comments : 
       * KPIの通知をするためだけに、人が毎日30分かけてパワポを作ってそれをメールで通知していた
       * 指定時間にLambdaで必要な数値をRedashからAPIで取得、その結果をSlackで通知するように変更した。
       * 仕様検討、構成から実装までトータルで行えたので非常に楽しかった。
       * Ruby で書いたので勉強にもなったし、Lambdaの学習にもなって一石何鳥になったかわからない。

       * Lambda で Ruby 書く上での作法に悩まされたのは内緒


    




## ◆ 今年の目標（今の自分に足りないもの）

※ Trello で管理して毎月レビューする

* Infra
    * Must
        * Linac１取得(~2020/08/01)　
    * Want
        * Linac2取得
        * 可能ならばAWS関連の資格ひとつ


* Backend
    * Must
        *  Ruby Silver の取得(~2020/08/01)　
    * Want
        * 下記のAPIサーバ構築


* Frontend
    * Must
        * Vue.js もしくは Angular でサービスを作成する(~2020/08/01)　
        * ↑ Typescriptでの実装


* Books
    * Must
        * 読みかけ本の読破
    * Want
        * 技術書*2
        * 役立つ系*1


## ◆ やったこと・総括


* ほぼ未経験のくせに医療系ベンチャーでひよっこエンジニアからスタート
    * Backend Frontend 両方を担当、主に Bug Fix とE2Eテスト作成
        * 新規開発は少しだけ　主にフロント　基本何でもやる
        * お問い合わせへの調査などもおこなう　何でもやる
        * スマホアプリ関連も一通り触ってビルドや開発証明書までは抑えた
        * なんにもわからないところからある程度は一人で動けるようになった（補助ももちろんしてもらった）ので、今年も更に頑張る！つよつよエンジニア+αになりたい


* BIツール（Redash）の管理のために前任者が遺したDocker触り始めました
    * 一時期社内のデータ作成業務を受けてた
        * SQL組んだことなかったところから始めた割には頑張ってたんじゃないかと思う
        * → 変なSQLじゃなければ頑張って大抵かけるようになったのでこれからもがんばる




*  読んだ本がめちゃ少ないのでこれから読んでいく（ゲームしすぎた。。。反省点><）
    * 良いコードを書く技術（途中）
    * 思いのままに人を動かす 心理学入門（途中）





## ◆ まとめ

社会人になって、変な会社にばかり厄介になってしまい、
ここに来てようやくまともな会社に入社できたのはこの一年で一番の収穫でした。
給料も上がったしね。

ただ、気が抜けたのか今年はかなり緩めにやってきてしまったので
今年は気を入れ直して自分自身のバリューを上げて、パフォーマンスを上げて行きたいと思います！
計算機を利用していて嬉しかったこと、悲しかったこと 

計算機を利用していて嬉しかったこと、悲しかったこと 


# 嬉し 
　１命令をコメントにしただけで、高速処理になったこと 

# 悲し 
##１　４時間の入力が、ハングして消えた 

 データの自動バックアップするソフトを使おう 
 １時間に１回は保存しよう。（できれば１０分） 

## ２　買ったばかりのノートPCが壊れた 

保証には入ろう 
 ノートPCは保護袋に入れて持ち運ぼう 

## ３　アセンブラの自作ソフトを動かしたらディスクを初期化 

 ディスクは初期化禁止にしよう 
システム管理者で自作アプリは動かさない
Vue + Quasarで環境を設定する

# Quasar

https://quasar.dev/
Vue.jsベースのフレームワークです。
Vue.jsで色々試す際に、スタイルまで設定するのは時間がかかると思っていたところ、存在を教えていただいたので利用してみました。

既にあるプロジェクトにQuasarを組み込む内容ではなく
新規にQuasar入りのプロジェクトを作成する内容となります。

# Quasar CLI Installation
Quasarの導入には、Quasar-Cliを利用するのが簡単だということなので、インストールを行います。(`node>=8.9.0` `npm>=5.6.0` `yarn>=1.6.0`)が必要です

また、quasar-cliの利用にはvue-cliが必要ということなので両方のインストールを行います。

```bash
$ yarn global add vue-cli
$ yarn global add quasar-cli
```

次に
`quasar init <フォルダー名>`でプロジェクトの作成を行います。対話式で色々聞かれるので、自分の作りたいものに合わせて設定を行います。

```bash
? Project name (internal usage for dev) hoge
? Project product name (official name; must start with a letter if you will buil
d mobile apps) Quasar App
? Project description A Quasar Framework app
? Author hoge <hoge@hoge.com>
? Check the features needed for your project: (Press <space> to select, <a> to t
oggle all, <i> to invert selection)ESLint
? Pick an ESLint preset Standard
? Cordova id (disregard if not building mobile apps) org.cordova.quasar.app
? Should we run `npm install` for you after the project has been created? (recom
mended) yarn
```

プロジェクトが作成されるので、cdでディレクトリを移動した後に、`quasar dev`を行うとローカルの開発環境が起動し、自動的にブラウザに画面が表示されます。（と、書いてありますが、自分はこのままでは起動できなかったので下記の動作を行いました。同じく動かない状況の方は、同じことを試してみてください。）

```bash
#To get started:
$ cd hoge
$ quasar dev
```

<img width="1291" alt="スクリーンショット 2019-07-27 22.18.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205283/7d5d22c9-3a8c-358c-78e7-91cf5ab31dab.png">

# quasar devでローカル環境が起動しない
理由はわかりませんが上記の動作で起動しなかったため、生成されたファイルを少し修正してみました。何故動くのかまでは調査できていないため、わかる方がいたら教えてください、、mm
<img width="259" alt="スクリーンショット 2019-07-27 22.27.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205283/f0ce0d28-72a7-90ae-55a3-aad96a5b9d3e.png">
上記のようなディレクトリが生成されているので、package.jsonに変更を加えます。
9行目scriptsの中に、`"dev": "quasar dev",` `"build": "quasar build",` `"build:pwa": "quasar build -m pwa",`を追加します。とりあえずローカルを起動するだけなら１行で良いと思います。
<img width="526" alt="スクリーンショット 2019-07-27 22.33.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205283/91c743be-f585-ee5e-7ebf-9955ee28298a.png">
↓
<img width="528" alt="スクリーンショット 2019-07-27 22.35.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205283/f3aa9c4a-f4c4-8159-496f-b748137cc04f.png">

これを追加したら、プロジェクトの位置で
`yarn dev`を行えば起動されます。

```bash
 $ yarn dev
```

さっそく色々試してみます。
私のnode開発スタイル

Git for Windows, Vim環境でNode.jsプログラムの開発環境を確認してみたが、まずはここに記述するスタイルで開発してみる。

### プログラム開発環境

はい、vim。以下のプラグインを利用する。

* プラグイン管理：dein
* タブ設定にキーマップのカスタマイズ版
* JsDocの自動生成プラグイン：heavenshell/vim-jsdoc
* 自動的に対応する括弧を挿入する：Townk/vim-autoclose
* js用インデックスとシンタックスカラー：pangloss/vim-javascript

これだけ。
あまり最初から色々使うと本当に必要だと感じて利用したときのありがたみに欠けるし、使わないプラグインによって重くなる可能性やキーマップのバッティングにより動作に異常をきたすかもしれない。
後は、タブスペース＝４、タブを空白に変換、インデント幅とタブキーで挿入される空白の量は４。
ちなみに、NERDTreeは私にとっては少し使いづらいし、わざわざツリー表示したい場面も今のところないためvim標準の:editコマンドで十分と判断。
正直、タブ表示機能も、画面分割機能があれば不要かもと思ったが、１画面フルでソースが見れる状態が簡単に切り替えられるのは少し魅力があるため使ってみる。

### JsDocの利用

関数を記入したらJsDocプラグインでドキュメントを作成する。

* 関数にカーソルを合わせて:JsDocを実行

### 編集中のnode.jsの実行

はい、shellの機能を利用する。
具体的にはCtrl-zによりvimプロセスを一旦停止して、shellプロンプトに戻ってからnodeコマンドを使いたいように使う。この時、サーバープログラムを動かす場合はバックグランドでnodeを動かす。

* 編集中のnode実行のためのshellへの切り替え：Ctrl-z
* nodeをバックグランドで実行：node jsプログラム &
* nodeプログラムを停止：fgしてからctrl-c、もしくはkill プロセスID
* 編集へ戻る：fg

これぐらいかなぁ。
あとはvimの標準コマンドとshellの機能を使えばとりあえず十分。
IntEnumで変数を使って数値を出力する

### IntEnumの変数利用

すごい単純な話だった。
以下のプログラムで 3 と出力される。

```python:test.py
from enum import IntEnum

class Blood(IntEnum):
    A = 1
    B = 2
    AB = 3
    O = 4

your_blood = 'AB'
print(Blood[your_blood].value)
```
ターミナルからコマンドでVS Code起動する方法

一度設定したらまた設定し直すことはパソコンが壊れることがない限り、必要にならないかとは思いますが個人的な備忘録として書き留めます



VScodeを以下のサイトからダウンロードを行い
https://code.visualstudio.com/

特に設定を行わなかった場合はターミナルからコマンドを入力してもVSCodeを起動することができないです。

起動コマンド　`$code`


VSCode上で　`Shift + Command + P` を入力することでコマンドパレットと呼ばれる、VSCode上で使用することができるコマンドの一覧が表示されます。

<img width="807" alt="設定_—_projects_と_キーボード.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234233/45134838-e73e-2856-e0ad-def6c0277b45.png">


入力欄にshellと入力することで上記のような表示がでてくるのでそちらを選択肢すすめると

VSCodeを起動できるようになります。
JavaScriptでオブジェクトの配列をグループ分け(groupby)して表示する


以下のように配列が与えられている時に、重複しているものをカテゴリ分けして、それぞれに紐づくプロパティの値を子要素として出力させる結果を得たいと思った。（画像①のようなイメージ）

```constant.js
    const fruits = [{
            name: 'apple',
            price: 100
        },
        {
            name: 'apple',
            price: 500
        },
        {
            name: 'apple',
            price: 1000
        },
        {
            name: 'banana',
            price: 100
        },
        {
            name: 'banana',
            price: 300
        },
        {
            name: 'banana',
            price: 500
        },
        {
            name: 'banana',
            price: 700
        },
        {
            name: 'orange',
            price: 100
        },
        {
            name: 'orange',
            price: 300
        },
    ];
```
画像①
<img width="224" alt="Screen Shot 2019-07-27 at 22.03.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135287/e3f387c5-860b-2809-fc11-f7809fee4c52.png">


アプローチとしては以下。
１.配列のプロパティの値が全部で何種類なのか検出する
2.それぞれのpriceを配列として更にグループ分け
3.二重のfor文で表示させる

以下のようなコードを買いたところ、期待通りの結果を得ることが出来た。

```index.js

    function fruitArrGroupBy(list, keyGetter) {
        const map = new Map();
        list.forEach((item) => {
            const key = keyGetter(item);
            const collection = map.get(key);
            if (!collection) {
                map.set(key, [item]);
            } else {
                collection.push(item);
            }
        });
        return map;
    }
    var groupedFruitArr = fruitArrGroupBy(fruits, fruit => fruit.name);
    
    //配列のキーが何種類あるのかを出す(重複を外した配列を生成する)
    var fruitTypeList = fruits.filter(function(v1,i1,a1){ 
        return (a1.findIndex(function(v2){ 
            return (v1.name===v2.name) 
        }) === i1);
    });

    //HTMLにレンダリング
    for (let i = 0; i < fruitTypeList.length; i++) {
        $("body").append(`<h1>${fruitTypeList[i].name}</h1>
                           <ul class="wrapper${i}"></ul>`);
        $("body").append(``);
        var fruitItemArray = groupedFruitArr.get(`${fruitTypeList[i].name}`);
        for(var j = 0;j < fruitItemArray.length ;j++){
            $(`.wrapper${i}`).append(`<li>${fruitItemArray[j].price}円</li>`)
        }
    }

```


しかし、もっとコードを改良出来るのではと思い信頼のおける先輩に相談したところ、親切に色々とフィードバックいただき、ここまで短くすることができた。
(※大きな表示の変更は変わらないという前提で)

```index.js
        var fruitsObj = {};
        var fruitsObjArr = [];
        // fruitsObj[number] = { name: 'Newcomer!' },
        for (var k = 0; k < fruits.length; k++) {
            //キー名に配列の値が無かったら
            if (fruits[k].name in fruitsObj != true) fruitsObjArr = [];
            fruitsObjArr.push(fruits[k].price);
            console.log(fruitsObjArr);
            fruitsObj[fruits[k].name] = fruitsObjArr;
        }
        console.log(fruitsObj);

        for (const key in fruitsObj) {
            $('body').append(`<h1>${key}</h1><ul class="wrapper-${key}"></ul>`);
            if (fruitsObj.hasOwnProperty(key)) {
                for (let i = 0; i < fruitsObj[key].length; i++) {
                    $(`.wrapper-${key}`).append(`<li>${fruitsObj[key][i]}円</li>`)   
                }
            }
        }
```
kindleの蔵書リストを抽出してみる

* 一連の操作はmacos上で行いました。

# 概要
kindleの蔵書が１０００冊に達し、何を持っていたのか管理できないか検討する

https://qiita.com/sasasin/items/fcef210fa49ff8d54e46
http://hushin-text.fdempa.com/2016/10/09/kindle-json.html
などを参考にしました。
# 手順
1. curlで書籍情報を取得
2. jqでjsonを加工しタイトルを抽出
でやろうと思います。

# やり方１　書籍情報を取得
amazonのマイアカウントのkindleのコンテンツ管理ページにchromeなどのブラウザを使ってアクセス
ブラウザの開発機能を使ってnetworkをwatchします。
ブラウザからコンテンツ管理ページを下にスクロールしていって次を表示ボタンを押下していって全ての蔵書をブラウザに読み込ませる。
開発機能のnetwork上に一連の操作で発行したコマンドが表示されているので、右クリックでcURLでコピーする
適当なテキストエディタにペーストする
curlコマンドのリストがペーストされるのでその中から[curl 'https://www.amazon.co.jp/hz/mycd/ajax' ]となっているもののみ抽出する

＊このcurlのコマンドを端末から実行するとjsonデータがダウンロードされます。

# やり方2 jsonを加工する
jsonから書籍と著者,ASINを抜き出してリスト化しようと思います。
jsonの加工用コマンドは`jq`なのでaptなりbrewなりで取得する。

`jq '.OwnershipData.items[] | {title:.title ,author: .authors ,ASIN:.asin} ' `
を書籍情報のjsonを対象に食わせてやれば欲しい情報のリストが手に入る

最終的なコマンドは
` curl 'https://www.amazon.co.jp/hz/mycd/ajax' 何かcache的な文字列  --compressed | jq '.OwnershipData.items[] | {title:.title ,author: .authors ,ASIN:.asin} ' `
これをnetworkメニューからコピーしてきたcurlのコマンドに対して行えばkindleの蔵書一覧が手に入る

# 追記
久しぶりに溜まったキンドルのリストを管理しようとしたらやり方を忘れたのでスクリプト化した

```sh
# 手順
# chromeでアマゾンの蔵書一覧を表示してF12を押下して開発モードに移行する
# networkモニターを表示しながら再読み込みを行うと蔵書一覧を読み込んだ時のコマンドが表示されるのでCopy all cURLを行う
# テキストエディタにコピペした必要なコマンド(curl 'https://www.amazon.co.jp/hz/mycd/ajax' )のみ抽出し実行するとjsonが取得できる

search_string="curl 'https://www.amazon.co.jp/hz/mycd/ajax' "
# 抜き出したcurlのコマンド一覧を以下のcurl_listにコピペする。
curl_list="./copy_curl_list.txt"
# 一時ファイル
tmp_file="./tmp_comand.sh"
json_file="./tmp_json_file.json"
# 出力結果
kindle_book_list="./kindle_list.txt"

tail $tmp_file
cat $curl_list | while read line; do
    if [[ $line =~ $search_string ]] ;
    then
        echo $line >> $tmp_file
    fi
done
/bin/bash $tmp_file >> $json_file
cat $tmp_file
rm $tmp_file

# json fileが複数行ならこっち
cat $json_file | while read line; do
    cat $line | jq '.OwnershipData.items[] | {title:.title ,author: .authors ,ASIN:.asin} ' >> $kindle_book_list
done

# json fileが１行ならばこっち
cat $json_file | jq '.OwnershipData.items[] | {title:.title ,author: .authors ,ASIN:.asin} ' >> $kindle_book_list

```
Jetson Nano で TP-LINK Archer T2U Nano を使う

## Jetson Nano で無線LANを使いたい。
Jetson Nano には、無線LAN機能が無い。無線LAN(とBluetooth)を使うためには、Intel 8265NGW との組み合わせが正統派らしい。けど、ケチって TP-LINK Archer T2U Nano にしたら、ちょっとだけ苦労した。ので、情報共有まで

## ドライバのダウンロード&ビルド
- ドライバ(RealTek 88XX)のURLはここ。素直に git clone すること

```
git clone https://github.com/abperiasamy/rtl8812AU_8821AU_linux
```
- ディレクトリを移動し、Makefile の 74〜76 行目くらいの設定を以下のように設定する(...I386_PC を n、...ARM_JET_NANO を y に変更)

```
CONFIG_PLATFORM_I386_PC = n
CONFIG_PLATFORM_ARM_RPI = n
CONFIG_PLATFORM_ARM_JET_NANO = y
```
- os_dep/linux/usb_intf.c の 300行番台あたりに以下を追加する。要はRTL8821A に、T2U Nano のベンダIDとプロダクトIDを登録する、ということ。（ちなみに、WikiDevi に記載されているIDは違っているので注意）

```
#ifdef CONFIG_RTL8821A
(略)
	{USB_DEVICE(0x2357, 0x011E),.driver_info = RTL8821}, /* TP-Link - Archer T2U Nano */
#endif
```

- あとは、上記 GitHub のURLに紹介されてる手順で行えばOK（dkms add/build/install をやってくれる）。

dkmsが入ってなかった場合は事前にインストールすること

```
sudo apt install dkms
```
あとは、以下のとおり sudo make を実行すればドライバのインストール終了。

```
sudo make -f Makefile.dkms install
```

- インストール後、T2U Nano を差し込んで、再起動すればT2U Nano を認識してくれている（はず）。ただし、2.4GHz帯と5GHz を両方同時には使えない（ようだ）

## 変更点
T2U Nano の場合、チップ指定は、Realtek 8812 よりも 8821 のほうがよいらしい（以下ISSUEも参考に）。

## 参考リンク
[A.B.PeriasamyさんのドライバGitHub](https://github.com/abperiasamy/rtl8812AU_8821AU_linux)
[GitHubにあったISSUE](https://github.com/aircrack-ng/rtl8812au/issues/334)
[Swift] バックグラウンドで処理を継続させたい場合に、処理数が多いとダメな時があるっぽい

バックグラウンドでも動くタイマーアプリを作ろうとして
https://qiita.com/rc_code/items/f0d9d19e7844fbcf0260
↑この記事と
https://qiita.com/SatoTakeshiX/items/8e1489560444a63c21e7
↑この記事を参考に作っていた時にわかったこと

## 動くパターン
```swift
timer = Timer.scheduledTimer(
            timeInterval: 0.1, //⇦ここ
            target: self,
            selector: #selector(handleTimer(_:)),
            userInfo: nil,
            repeats: true
        )
```

## 動かないパターン
```swift
timer = Timer.scheduledTimer(
            timeInterval: 0.01, //⇦ここ
            target: self,
            selector: #selector(handleTimer(_:)),
            userInfo: nil,
            repeats: true
        )
```

覚書。
TypeScript x create-react-app x re-ducksのサンプル完成

# 概要

以下の記事のサンプルを一旦完成させた。
https://qiita.com/Miracle-T-Shirt09/items/c903e3460be6aa187426

# 前回投稿時からの変更点

主な変更点は以下の通り

- TypeScriptの型推論を利用して不要な型指定は削除した
- ducksディレクトリを廃止して階層を一つ浅くした
- redux-actions-typeを利用してaction周りの型を整理
- types.tsの廃止
- mapDispatchToPropsは関数ではなくオブジェクトに

詳しくはこちら
https://github.com/MasahikoJinno/re-ducks-study/pull/6

修正点色々あるけど、方針的にはTypeScriptの型推論を生かして行こうよというもの。
ガチガチに型指定をしてしまったら記述量も増えてしまうので、TypeScriptの良いところに乗っかろうと思った。

# 今後の予定

今のままだと機能が少なすぎて明らかにTypeScriptもre-ducksもいらないので、以下のような機能をこのサンプルに盛り込むつもり。

- Firebaseの利用
    - Firebase Authを使ったユーザ認証(多分Twitter認証)
    - FireStoreを使ったデータの永続化
- ルーティングの実装
- Service Workerの実装
    - 全く使ってないので
    - create-react-appでworkboxどう使うかもイマイチわからないから勉強がてら実装してみる
- Next.jsの利用
    - もうcreate-react-appじゃなくなっちゃうけど
    - react-routerちょっとしんどいなって思ってきたのでNextのお勉強する

# おわり

最後までご覧いただきありがとうございました。
質問等あれば受け付けます。
【iOS】iOS開発初心者の個人的に参考になったswift記事まとめ

# 趣旨
swift関連でお世話になった、参考になった記事のまとめ。
個人的に詰まった時にために参考にするためにまとめます。
勉強初めて１月程度の初心者なのでswift関連のおすすめ記事などあれば教えていただけると助かります。
多くなってきたら分類します・・・たぶん
随時更新していくはず

# 記事一覧

#####デリゲートの概要
デリゲートってそもそも何ってなった際に以下の記事を読んだ。
この記事を理解して初心者向けの記事読んだほうが個人的には良いと思った。
[参考先](https://medium.com/@ttorii20/delegate%E3%81%A8%E3%81%AF%E4%BD%95%E3%81%8B-swift%E3%81%AE%E5%88%9D%E5%BF%83%E3%82%92%E6%8C%AF%E3%82%8A%E8%BF%94%E3%82%8A-%E6%9B%B8%E3%81%8D%E3%81%BE%E3%81%99-580ef2865814)


#####iOSの設定画面への遷移方法
アプリ側からiOS本体側への設定画面への遷移方法。
[参考先](https://qiita.com/shnj884/items/1bb1b2b3360a009f154c)

#####Slider
スライダーの記事。
[参考先](https://joyplot.com/documents/2017/03/19/swift-uislider/)
[参考先](https://swift.tecc0.com/?p=694)

#####地図
基本的なとこ
[参考先](https://dev-reco.com/350)

#####地図でのピンのたてかた
swift5では地味に違ってる気がする。
あとピンを複数立てる場合は配列で渡すようになってるみたい
[参考先](https://dev-reco.com/384)