OmniAICreator/Qiita-1.07M huggingface dataset:
【Android】XML内部で、画像の大きさを変える

#はじめに
アンドロイドを学び始めたので、備忘録として残しておく、自分用のメモです。
改善点などがあればご指摘お願いします。


下記の画像のサイズを変更した場合、何も設定していなかったら。
<img width="138" alt="スクリーンショット 2019-06-04 15.23.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328210/e6125973-2f52-cb6d-b68b-1550892cc714.png">

このようになります。
<img width="116" alt="スクリーンショット 2019-06-04 15.23.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328210/a93427ff-38b1-6892-d1c1-f250879c3c21.png">




#解消法

【scalType】の値を`center`から`fitCenter`にすればいい
<img width="460" alt="スクリーンショット 2019-06-04 15.25.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328210/5bdeba48-4ea9-9858-74e5-016e6136ba0e.png">


<img width="120" alt="スクリーンショット 2019-06-04 15.26.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328210/bcdf6339-cc1a-fa7d-c768-25d860d69929.png">
AWS GuardDutyをBoto3で有効化

# AWS GuardDutyをBoto3で有効化
---
AWS GuardDutyをGUIで有効化する場合、各リージョン毎でGUIによる
操作が必要(2019年5月時点）。

とても面倒なのでBoto3で自動的に有効化するスクリプトを書いた。
各リージョンのEC2を監視するコードにGuardDutyをEnableにする
コードに入れ替えただけ。


```
import boto3

ec2 = boto3.client('ec2')
regions = map(lambda x: x['RegionName'], ec2.describe_regions()['Regions'])

for region in regions:
    
    if region == 'ap-northeast-1':
        print('hello')
        
    else:
        
        client = boto3.client('guardduty', region_name=region)
    
        print(region)

        response = client.create_detector(
                ClientToken='string',
                Enable=True,
                FindingPublishingFrequency='SIX_HOURS'
                )

        print(response)
```

### その他
---

なぜかGUIで有効化した東京リージョン（ap-northeast-1）のみエラーを返すため
東京リージョンを除外している。
yumで任意のバージョンのkubernetesをインストールしたいとき

#TL;DL
CentOSにKubernetesをインストールするときに、`yum install kubelet kubeadm kubectl`すると最新が入ってしまうと嫌な人向けにバージョン指定するやり方をメモしておくものです

#前提
```:/etc/os-release                      
NAME="CentOS Linux"                        
VERSION="7 (Core)"                         
ID="centos"                                
ID_LIKE="rhel fedora"                      
VERSION_ID="7"                             
PRETTY_NAME="CentOS Linux 7 (Core)"        
```
#レポジトリ作成
```
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
        https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF

```
#指定方法
```
yum install <component>-<version number(X.XX.X-X)>.x86_64
```

#実行例
1.13.5を指定する場合

```
yum install -y kubelet-1.13.5-0.x86_64 kubeadm-1.13.5-0.x86_64 kubectl-1.13.5-0.x86_64
```
[adb] Oculus Questのバッテリー状態をリモートで取得する

Questで遊んでいるのでQuest向けになっていますが、叩いてるコマンド自体は普通のAndroidと同じです。
あらかじめ、当該端末の開発者モードをオンにして、USBでのadb接続許可をしておいてください。


## adbのリモート許可設定とリモート接続

※あらかじめQuestのIPアドレスを調べ、IPアドレスを固定化しておくと楽。
USB接続したうえで下記コマンドを入れる。

```bash
adb tcpip 5555
adb connect {QuestのIPアドレス}:5555
```
※IPアドレスのあとにポート番号を入れておかないと接続できない
　また、リモート接続許可をしている状態では、ID/PW認証なしで同一ネットワーク上にあるPCから接続できてしまうため、終了したら`adb usb`を実行してリモート接続を切っておくことをお勧め。

参考: [ネットワーク経由でadb実行する](https://qiita.com/hamup/items/d0757af393a5462b686a)

接続完了後はUSB接続を外す。


## dumpsysでバッテリー状態を取得

`adb shell`でシェルを開いてコマンドを入れる

### バッテリー残量を取得
下記コマンドで数値化されたバッテリー残量を取得できる。

```bash
adb shell
dumpsys battery | grep 'level' | sed -r 's/[^0-9]//g'

97
```

### バッテリー温度を取得

1桁目は小数点と思われる

```
adb shell
dumpsys battery | grep 'temperature' | sed -r 's/[^0-9]//g'

290
```

### dumpsys batteryで取得できる情報

```bash
monterey:/ $ dumpsys battery
Current Battery Service state:
  AC powered: false
  USB powered: false
  Wireless powered: false
  Max charging current: 
  Max charging voltage: 0
  Charge counter: 0
  status: 3
  health: 2
  present: true
  level: 97
  scale: 100
  voltage: 4209
  temperature: 290
  technology: Li-ion
```
codebuildから、rails db:migareを実施する際のRDS接続エラー

codebuildで はまったのでメモを残します。

## codebuild
buildspec.ymlを読ませて実行している。
` - docker run --rm --env RAILS_ENV=$RAILS_ENV --env SECRET_KEY_BASE=$SECRET_KEY_BASE --env DB_HOST=$DB_HOST --env DB_NAME=$DB_NAME --env DB_USERNAME=$DB_USERNAME --env DB_PASSWORD=$DB_PASSWORD $REPOSITORY_URI:latest rails db:migrate`  

## エラーコード　
しかし、mysql接続エラーとなってしまう。
`Mysql2::Error::ConnectionError: Can't connect to MySQL server on 'hoge.fuga.ap-northeast-1.rds.amazonaws.com' (110) `

## 調査  
### 見直したところ  
1. 同一privateネットワーク上のEC2から、RDSへのmysql接続確認。
2. セキュリティグループ設定確認。
3. IAMのロール設定確認。
4. codebuildの環境変数確認。

それぞれ確認をおこなったが、改善されず。
有識者の指摘により、VPC項目に設定が入っていないことが発覚。

## 原因
codebuildの設定において、環境のVPC指定、サブネット、セキュリティグループが指定できていなかったため、NW接続許可されずエラーが発生した。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211196/aaa6245e-5afd-9f97-e6c3-1a14120f084b.png)
上記の画像はcodebuildの設定のサマリ表示。ここでは、VPCやサブネットなどがが表示されない。 

![無題1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211196/c2d39b86-7511-2c94-23cb-55c39ce72f6c.png)
詳細画面ではじめて、サブネットの設定画面が表示される。
登録時のサブネット指定が必須ではないため、未設定のまま通過してしまうことがある。

##対応
VPC、サブネット、セキュリティグループ設定することで解決した。

## 反省点
codebuildの環境変数が、VPCやサブネット対象項目が必須だと思っていた。
概要表示でもVPCやサブネットも含めて表示されていると思っていた。

思い込みと節穴EYEで時間を無駄に消費したので反省します。思い込み怖いね。
動画配信目線でWWDC2019で気になったことメモ

だらだらとWWDC 2019で動画配信目線で気になったことのメモです。

# AppStoreのインストールサイズが50%削減？

何かビルド形式に制限が加わる可能性があり、外部フレームワークが使えなくならないか確認が必要

# iPadOS

iOSと分離するとAVプレイヤー周りの挙動がiOSとiPadOSで異なるなんてことが起こりそう

## Split View

全画面再生を前提としたプレイヤーがSplit Viewで正しく表示されるのか？？ 

## desktop-class browsing

iPadのSafariがMacと同じような感覚で使えるようになるらしい。
ということはUserAgentの判別基準に注意しないといけない可能性が高い。
特にコンテンツフォルダーの契約で、iPadはアプリのみ許可していて、Safariでの提供の契約をしていない場合は要注意。

# macOS

## iPadOSアプリをmacOS向けにビルドできるProject Catalyst

基本的にはうれしい機能。ただし、これもiPadOSとmacOSで挙動が異なる可能性は高い。
また、DRMのエージェントや外部フレームワークが正しく動作するかが課題。

macOS向けにアプリを提供するかはこちらの判断によるので、macOSが勝手にサービス範囲に入ってしまうみたいなことはないはず。
Jaspersoft Studio 備忘録

# 概要
JasperReportsで帳票を作成するにあたり、Jaspersoft Studio（JSS）を使用して帳票テンプレートを作成したが、色々と実現に苦慮した個所などを備忘的に本稿にまとめる。

# JasperReportsとは？
* JasperReportsとは、Javaで動作するオープンソースの帳票出力ライブラリ
* 米Jaspersoft社により開発されていたが、Jaspersoft社が米TIBCO Softwareに買収された事により、現在はTIBCO社により開発が続けられている
* JasperReports LibraryはLGPL、Jaspersoft StudioはEclipse Licenseで利用可能。したがって通常の利用範囲であれば商用利用可能

# Jaspersoft Studio（JSS）インストール関連
* Jaspersoft Studio（JSS）とは、Eclipse上で動作するJasperReportsのレイアウト作成ツール（2019/12/01 時点での最新は v6.10.0）
* 導入にはJSSを直接インストールする方法と、既存のEclipseにJSSプラグインをインストールする方法がある（参考：[Jaspersoft Studioとは](https://community.jaspersoft.com/wiki/jaspersoft-studiotoha)）
* インストール手順は以下を参照（参考の手順は対象バージョンがやや古いため、適時読み替えて実施すること）
    * [アプリケーション版インストール手順](https://community.jaspersoft.com/wiki/jaspersoft-studionoinsutoru)
    * [プラグイン版インストール手順](https://community.jaspersoft.com/wiki/jaspersoft-studiopuraguinnoinsutoru)
* Eclipse部分については一部日本語化が出来る（Jaspersoft Studio 機能自体は日本語化できないが、それでもだいぶマシにはなる）  
    * [日本語化手順](http://memo.eightban.com/jasperreports/jasperreports_translate)  
※ Eclipse バージョン確認  
上記サイトの方法では確認が出来なかったので、Help > About TIBCO Jaspersoft Studio より Eclipse RCP のバージョンで確認、→ 4.7.3（Oxygen）

# 日本語（マルチバイト文字）出力対応
* 日本語の帳票出力に対応するためには、日本語フォントを導入する必要がある
* 殆どの例では、無償で商用利用可能なIPAフォントを採用している（[IPAフォント入手先](https://ipafont.ipa.go.jp/old/ipafont/download.html)）
* Jaspersoft Studio でフォントを追加するには、Window → Preferences → Fonts から行う 
* PDFファイルにフォントを埋め込みか否かを Embed this font in PDF document にて指定できる。フォントを埋め込む場合は表示PCにフォントファイルがなくとも表示可能となるが、その分ファイルサイズが大きくなる。また、埋め込む場合はフォントの配布にあたるため、ライセンスを確認する必要がある（IPAフォントは配布OK）。
* 設定したフォント情報は Window → Preferences → Fonts の Export からjarファイル形式でエクスポート可能。テンプレートファイルと共に稼働環境に配置する。

# 帳票テンプレート作成関連
* 明細を縦2列以上で表示する  
Report プロパティ > Page Columns > Column Count に 列数を設定し、Column Width に 列幅を設定する。
* カラムフッターを明細の直後に出力する  
Report プロパティ> Float Column Footer にチェックを入れる。
* 縦書きを実現する  
残念ながら縦書きを素直に実現する方法は無いため、TextField を文字数分、縦に並べて用意し、それぞれに１文字つずつ切り出して出力する。  
1文字目：(\$P{param}.length()>0?(\$P{param}.substring(0,1)):"")  
2文字目：(\$P{param}.length()>1?(\$P{param}.substring(1,2)):"")  
    ：
* NULLを空文字として表示する（NULLを表示しない）  
TextField プロパティ> Blank When NULL を true にする。

* 合計欄等の最後に値が確定する項目は、評価タイミング（TextField プロパティ> Evaluation Time ）を Report 等にする事で不確定状態のまま表示されることを回避できる。
（例：Evaluation Time : Now）この例では合計金額欄を評価するタイミングでは小計、消費税が評価されていないため、nullとして表示されてしまう。
<img width="400px" alt="Now" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339580/3846ad89-1a91-278f-606c-05daa3ba558a.png">
（例：Evaluation Time : Report）この例では合計金額欄を評価するタイミングをレポート出力後に行うため、合計欄の計算が可能になり金額が出力される。
<img width="400px" alt="Report" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339580/b7d73f56-efd8-c0ba-e61c-f13da46fc924.png">
サーバーへ情報を送信する方法GET

入力フォーム（ブラウザ側）から値をサーバー側へ送信する方法にはGETとPOSTがある。
###POSTの例
```html
<from method="post">
<input type="text" name="pass">
</form>
```

###GETでの渡し方
```html
<form method="get" action="http://hoge.com/">
<input type="text" name="name" value="hoge">
<input type="text" name="pass" value="password">
<input type="submit" value="送信">
</form>
```

この場合、実際の送信先URLはこうなるよ
(http://hoge.com/?name=hoge&pass=password)
`?`以下は送信先へ渡す値(クエリパラメータという)
URLの後ろに？をつけて、`key=value`の形で渡し、複数の値を渡す場合は間に`&`をつける。

- URLを使って文字をサーバーへ渡せる
- ブラウザからURLを手入力しても直接渡せる
- 渡せるデータサイズ（文字数）に制限あり（ブラウザによるけど）
- URLに送信した値が表示されてしまう
- URLに載せているので、例えばお気に入りに保存しておいてサイドアクセスすると同じ結果の画面がでる

（グーグル検索もGET方式だ）

###POST（復習）
- 通信のbody部に載せてサーバーへ
- 渡せるデータサイズに制限なし
- 画像（バイナリデータ）も送れる
- 見せたくないデータを送れる（ただしセキュリティ上万全かどうかは別の話）

###その他
- `GET`はなにかを取得したい時に使い、`POST`はなにかを新しく登録するときに使う。
- `PUT`,`DELETE`なんかもあるけど`form`タグには`GET`,`POST`しかないので最初のうちはこれだけで良し。
- `GET`でやるべきことも`POST`でやってる現実。

>【参考】
ウェブカツ(https://webukatu.com/plan/list/?afid=p5lxu1kvh03rayd2ctjsw4e9bgzq8nom)
GETとPOSTの違いについて(https://qiita.com/kanataxa/items/522efb74421255f0e0a1)
VSCode でファイル保存時にPrettierに自動整形してもらう

# やりたいこと
VSCode に Prettier の拡張機能をインストールして自動整形してもらいたい。

# ちょっと困ったこと
他の方の記事をみると、User Settings の json ファイルを書き換えるようなことが書いてあるが、どこにあるんだろう＆なんかGUIで設定できそう。

# やり方
1. VSCode に Prettier の拡張機能をインストールする。
![スクリーンショット 2019-06-04 14.25.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114828/406eec18-8140-3a2d-d196-774aebeccc59.png)

2. Command + Shift + P を押して `Open User Settings` を開く
![スクリーンショット 2019-06-04 14.24.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114828/bfc350f5-bb0b-5cc0-2828-95c469d88e26.png)

3. `Text Editor` -> `Formatting` の順で選択して、 `Format On Save` にチェックを入れて終わり
![スクリーンショット 2019-06-04 14.24.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114828/919b91ec-0edd-afd3-b6c4-de492efdf59d.png)

# 参考
[VS Code上でファイル保存時にPrettierを走らせる](https://qiita.com/Naturalclar/items/690be378984b3a24a138)
[[React Native]VSCodeでPrettierを入れる](https://qiita.com/ozaki25/items/fde66fd971690767394a)
新フレームワーク「SwiftUI」の発表

## SwiftUIについて
WWDC2019で発表されて、twitterでかなりバズってます。(2019/06/04現在) 
公式ドキュメントが上がっていたので、ざっくりと概要をかきます。

## 何が今までと変わるか？
キャッチコピーは「Better apps. Less code.」 
良いアプリを少ないコードで書けちゃうらしい、公式のコードはこんな感じです。
下記にイメージも貼っときます。

``` swift:sample.swift
List(landmarks) { landmark in
   HStack {
      Image(landmark.thumbnail)
      Text(landmark.name)
      Spacer()
      
      if landmark.isFavorite {
         Image(systemName: "star.fill")
            .foregroundColor(.yellow)
      }
   }
}
```  
  
[SwiftUI公式紹介ページ](https://developer.apple.com/tutorials/swiftui)
<img width="803" alt="swiftUI.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418332/b63a87c8-b2c0-2f68-e012-612a654a1d95.jpeg">


## コードについて
TableViewを使用せずに、リストビュー形式で表示してるっぽい？ 
すごく読みやすいコードになってますね...
チュートリアルによると、コンポーネントを配置すると、テンプレみたいなコードが生成されて、それに手を加えていくって感じらしい。

## ライブプレビュー
コードの修正がリアルタイムで、プレビューに反映される機能が追加されました。
Playgroundで似たようなことはできたけど、SwiftUIの場合コンポーネントのドラッグドロップで、簡単にコードとビジュアルを確認することができるようになるのはすごく便利。

## チュートリアル
自分用にURL貼っときます。今度やってみよう
[Swift UI チュートリアル](https://developer.apple.com/tutorials/swiftui/creating-and-combining-views)

## あとがき
twitterとかで、ReactNativeいらなくなるんじゃないかって声が結構あったのにびっくりしました。
アプリ開発の経験多そうな人のSwiftUIへの前評判は軒並み良いですね。
個人的に唯一気になるのが、AutoLayoutを何とかしてくれるんでしょうか...
CNNの画像判別器を作ろうとした

##はじめに
　ディープラーニングの基本は大体わかってきたので、Flaskでそれを用いたウェブアプリを作ってみたくなった。Flaskを使うのも初めてなので、動いてくれればよしとする。

##分類器
　どんな分類器を作るかだが、ディープラーニングを勉強しているときにMNIST-fashionという画像データを学習させたモデルがあったので、それを再利用することにした。このモデルは白黒の画像データ（Tシャツや靴など）を渡すとその衣服の名を返す。精度は微妙。

```python
open('mnist_fashion_model.json',"w").write(model.to_json())
model.save_weights('mnist_fashion.h5')
```
こんな感じでmodelを保存しておく。

##Flaskで実装

###フォルダ
　ディレクトリツリーはこんな感じ。かなりシンプル。

```
mnist_fashion_app/
|---app.py
|---mnist_fashion_model.json
|---mnist_fashion.h5
|---templates/
|      |---first_page.html
|      |---result.html
|---static/
|     |---style.css
```
保存したモデルのファイルをくっつけておく。

###app.py

いらないライブラリもインポートしてるかも。
index()でfirst_page.htmlにとばし、result()でfirst_page.htmlから得た画像データをモデルにいれて、その出力をresult.htmlで表示させている。

```python
from flask import Flask, render_template, request
import numpy as np
import io
from keras.models import Sequential, model_from_json
from PIL import Image
from keras.layers.core import Dense
from keras.optimizers import RMSprop

app = Flask(__name__)

@app.route("/")
def index():
    return render_template("first_page.html")


@app.route("/result", methods=["POST"])
def result():
    image = request.files["image"]

    img = Image.open(image)
    img_resize = img.resize((28,28))
    img_resize = np.asarray(img_resize)
    im_gray = 0.299 * img_resize[:, :, 0] + 0.587 * img_resize[:, :, 1] + 0.114 * img_resize[:, :, 2]
    im_gray = im_gray.astype('float32')/255.0
    im_gray = im_gray.reshape(-1, 784)
    model = model_from_json(open('mnist_fashion_model.json').read())
    model.load_weights('mnist_fashion.h5')
    model.compile(loss='categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])
    answer_bin = model.predict(im_gray)
    num = np.argmax(answer_bin)
    dic = {0 : 'T-shirt',
           1 : "Trouser",
           2 : "Pullover",
           6 : "Shirt",
           7 : "Sneaker",
           8 : "Bag",
           9 : "Ankle boot"}

    answer = dic[num]

    return render_template("result.html", answer=answer)

if __name__ == "__main__":
    app.run(debug=True)

```
###first_page.html

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>first_page</title>
  </head>
  <body>
    <h1>Fashion Discriminator</h1>
    <h2>Upload your fashion picture</h2>
    <form action="/result" method="post" enctype="multipart/form-data">
      <input type="file" name="image" accept="image/png, image/jpeg">
      <button type="submit">submit</button>
    </form>
  </body>
</html>

```
###result.html

```html
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Result</title>
  </head>
  <body>
    <h1>This is a {{ answer }}</h1>
  </body>
</html>
```
style.cssはフォントサイズだけ。

##動かしてみる

![靴.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401707/1547a72f-1f5f-2cf0-3d71-88c6c3c125f5.jpeg)
この画像を入れてみる。This is a Sneaker とでれば成功である（スニーカーではないが）。


結果、This is a Bag とでた。

##振り返り
　FlaskでCNNのモデルを用いたウェブアプリを作るという最低限の目標は達成したが、精度の悪さや、入れる画像によってはエラーがでるなど、改善点も多く見つかった。

##参考文献

この本を参考にした。

「Python機械学習プログラミング達人データサイエンティストによる理論と実践」
著者Sebastian Raschka, Vahid Mirijalili
発行所　株式会社インプレス
Azure Basic A0のCentOS7.1にGitLabを入れようとしたらメモリ不足でハマった件

※この記事自体ははてなブログの過去記事（2015年）から移転しました。内容古めなのでご注意ください。

# 要約＝題名

GitLabが面白そうと思い、AzureでGitLabサーバーを立ててみようと思ったら、何故かSELinuxへの登録が上手くいきませんでした。
しかしそこはオープンソース。既に悩んでいた方の記事があり、そのコメントで解決しました。感謝。

# 解法

ググったら下記の記事が出てきました。


> Marcelo de Castro @belfalas-vinyamar  11 months ago
> Well, I solved my problem.
> 
> The cause was that the command semodule -i /opt/gitlab/embedded/selinux/rhel/7/gitlab-7.2.0-ssh-keygen.pp takes a lot of memory, and it was being killed for becoming out of memory, enabling a swap file solved it for me.
> 
> But I do think that receiving an exit code of '' should output some options of causes, like the out of memory problem.

[https://gitlab.com/gitlab-org/omnibus-gitlab/issues/295#note_355769:embed:cite]


要するにSELinuxがout of memory（メモリ不足）で落ちているとのことなので、素直にメモリを追加します。
Basic A1に切り替えたところ、うまく動きました。

最終的にAzureはあんまり関係なかったのですが、備忘まで。
rails c/rails consoleで反応しなかった時の対応

rails consoleで,下記のように入力できるが、反応しなくなった時の対処法

```
   ...> quit
   ...> .quot
   ...> rails c
   ...> cd
   ...> cd
   ...> .quit
   ...> rails db:migrate:reset
   ...> "
   ...> '
   ...> quit.
   ...> ^C
   ...> ^C
   ...> ^C
   ...> 
   ...> exit
   ...>    ...
   ...> reload
   ...> ^C
   ...> 
   ...> Error: incomplete SQL: quot

```

**スペルミスや閉じ忘れがないか確認**
閉じ忘れとは、””や；のこと

原因がわからなかった場合、Ctrl + Cで通常は閉じられる。
Ctrl + Dで強制終了です。
個人開発でサービス作ったら、ドンズべりしたって話

昨日スマブラで初めて戦闘力400万いきました。大塚です。

# はじめに
個人開発でサービス作ってバズって老後も安泰！みたいな構想を描きながら、サービスをロンチしました。
そして、ものの見事に一ヶ月程アクセス0という大敗を成し遂げ、サイトをクローズすることになったので自分なりの分析結果を発表します。

個人開発したいって思ってる人は是非僕の失敗を参考にしてください。

# この記事で触れない部分
- 使用したフレームワークやインフラ環境
- ロンチまでに行った作業の内容

# どんなサイトを作ったか
ジャンル問わずの転職サイトです。※「人材紹介」ではなく「求人情報サイト」です。
URLは下に貼っておきます。
[転職サイトなら【JobChan】 | 転職サイト JobChan](https://jobchan-hit.com/)

# なぜ失敗したのか

まず間違いないと思ってるのは<b>求人情報サイトなのに求人情報がない</b>ことが理由だと思っています。
当然ですね。

あとは、サイトのトップページにメッセージがないからユーザが次のステップに何をしたらいいかわからないというのもあると思います。

# なぜ当然のことで失敗すると気づかなかったのか

これは本当に言い訳なんですけど、
他サイトのコピー求人を後で作ればいい(未遂なんで許して下さい)とか、営業メールを時間ある時に手当たり次第送ればいいやと思ってました。

でもね、、無理でした。コピーする勇気もなかったですし営業メールを送る気力もわきませんでした。

この失敗の要因をもっと、どのサイトにも当てはまるように言うなれば、<b>ロンチ後にアクセスをどうやって増やしていくか計画していないことが失敗の要因</b>だと思います。

# じゃあどうすれば失敗しなかったのか

<b>プログラミングをやめればよかったと思っています。</b>

---
- そもそも、絶対失敗しないということは不可能なので、まずはHTMLとCSSだけでサイトを作って公開する。
- アクセスがあるかどうか判断した後、本格的にシステムとして作り込んでいく。

---

こういうフローにすれば8割以上の工数がなくなりサービス自体を複数作れてヒットしたものに沢山時間を使うことができたなと思っています。


# さいごに
<b>失敗はしたけど作ってよかったと思っています。</b>

ゴールデンウィークに何回も徹夜して、徹夜ってバカ効率悪いじゃん、早起きしようよって気づけましたし、一人でもちゃんと?サイト作れるんだなって思って自信にもなりました。

長文となりましたが、読んで頂きありがとうございました!
~~一ヶ月位このままサイトは残しておくので~~よかったら、ちら見してください(*^^)
※運用費を安くできたのでこのまましばらく残します。
ひどいコードの解析メモ

#はじめに
既に退職されている面識のない人のコードを見たらひどかったため、
何がひどいのかを自分の中で整理するために指摘事項をまとめる。
元コードは業務用なので書かない。
言語仕様に存在しないことを指摘している可能性もある。

#前提
201x年のソース。
開発者は2000年代初頭にはすでにプログラマだった。
言語はVisualBasic2008。
業務用Webシステム。画面は10以上。DBアクセス有り。

#指摘事項
共通化をせずにコピペしすぎ。
ログ出力がない。（デバッグやリリース後の追跡が困難）
ViewとModelが分離していない。（Formファイルに2000行以上で実装）
定義すればいい値を逐一ベタ打ち。（マジックナンバー、javascript向けに渡す1行命令文など）
SelectCaseで書けるものをElseIfの繰り返しで表現。（行数が増えるし見にくい）
Sessionを未使用。
StringBuilderを未使用。
DB接続設定を逐一記述している。
配列を未使用。（当然ArrayList、List<T>、ラムダ式などは未使用）
関数を分離していない。（Page_Load関数に500行以上）
クラスを使っていない。
importsを使っていない。
元号（平成）変換方法は西暦+-1988のみ。
GoTo文を使用。
同じ型の変数宣言を一行毎にしている。（カンマ区切りでまとめればいい）
宣言がすべてPublic。
Constなし。
外部ライブラリが1つもない。（使ってはいけない規約はない）
有益なコメントが少ない。

#どうしてこうなった
学習意欲がない？
検索エンジンを使う技術がない？
ソースレビューされたことがない？
前職がソース行数で評価される職場だった？
会社が初級書籍を支給したら上手くなった？
キャリアの初期に上手な同僚や上司に恵まれなかった？

#感想
基礎知識・技法の有無で大きな差がつく。（オブジェクト指向、リファクタリング、共通化、、、）
知っている知っていないの差は大きい。
経験年数と実力は必ずしも比例しない。
とりあえず動くものを作れば、一定の評価はされる。
動くものを作っても能力が高いわけではない。
ソースを読むことができなければ、他のプログラマの能力を判定できない。

動くものを作るくらいには上手だが、
「ソフト」ウェアを作れないくらいには下手な人だったと思います。
Nest.js×TypeGraphQLのresolver.tsで引数を扱う注意点

# editorの自動補完を信じてはいけない
例えば以下のように
- @nestjs/graphql
- type-graphql
からmoduleを読み込む場合
- Args
- Resolver
- Query
はどちらのmoduleからもimportできます。
開発で使用するeditorによっては、自動補完で適切でないmoduleからimportされる場合があります。

# import元がややこしい
Nest.js×GraphQLの時もそうですが、Resolver, Queryはnest側のmoduleになります。
ObjectType, Field, ArgsType, ID, Args等の直接、型定義に関わるmoduleはtype-graphql側からimportする必要があります。

```typescript

import { Resolver, Query } from "@nestjs/graphql";
import { ObjectType, Field, ArgsType, ID, Args } from 'type-graphql'
```
Raspberry Pi3B+でcron使えるまで

##経緯
ラズパイを起動時にpyenvのpythonでpythonスクリプトを実行させたい

##環境
RaspberryPi3b+
stretch(Release 9.9)
Python3.4(pyenv)

##cronログを有効

```
sudo vi /etc/rsyslog.conf
```

```/etc/rsyslog.conf(抜粋)
###############
#### RULES ####
###############

#
# First some standard log files.  Log by facility.
#
auth,authpriv.*         /var/log/auth.log
*.*;auth,authpriv.none      -/var/log/syslog
#cron.*             /var/log/cron.log
daemon.*            -/var/log/daemon.log
kern.*              -/var/log/kern.log
lpr.*               -/var/log/lpr.log
mail.*              -/var/log/mail.log
user.*              -/var/log/user.log
```

cronの行のコメントアウトを消す. すると、cronのエラー文などが取得できる

このまま、cronにスケジュールを記述しても下のエラーが出てしまう。

```/var/log/cron.log
raspberrypi /USR/SBIN/CRON[2331]: (CRON) info (No MTA installed, discarding output)
```

##MTA導入

```
sudo apt-get install postfix
```

これでさっきのエラーは出ない

##crontabに記述
今回は起動時に実行

```
crontab -e
```

```
#起動時に実行
@reboot python /home/<ユーザー名です>/Desktop/test.py >/home/<ユーザー名です>/Desktop/error.log 2>&1
```

/home/<ユーザー名です>/Desktop/error.logにはpythonスクリプトで吐いたエラー内容が記述される。

再起動してみると、pyenvに入っているpythonでなくラズパイにプリインストールされているpythonで実行される。
試しにcronで登録したpythonを下のように書いてみましょう。

```/home/pi/Desktop/test.py
import sys

print(sys.version)
```

すると

```/home/pi/Desktop/error.log
2.7.1
#今回はpyenvに入っているpython(3.4)を使いたい
```

んー、つらい...

よくよく、考えるとラズパイが立ち上がってからの順番が問題では？と思う
つまり、pyenvのpathが通る前にcronが実行されているのでは？？

自分はpyenvのpathを ~/.bashrcに記述しているのでこれらのスクリプトもcronに登録

```~/.bashrc
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
```

上のスクリプトをコピー、して登録

```
#起動時に実行
@reboot export PYENV_ROOT="$HOME/.pyenv"; export PATH="$PYENV_ROOT/bin:$PATH"; eval "$(pyenv init -)"; python /home/<ユーザー名です>/Desktop/test.py >/home/<ユーザー名です>/Desktop/error.log 2>&1
```

これで、再起動すると

```/home/pi/Desktop/error.log
3.4
#今回はpyenvに入っているpython(3.4)を使いたい
```
vue.js で 単一コンポーネントで pug を使ったときに　pug-plain-loader text "export default "" outside root element will be ignored. と出る


調べても調べても出てこなかったので

同じエラーになった人のために共有


## こういうの使いたいとき

template で pug 使いたい

```
<template lang="pug">
  div
    p counter: {{ counter }}
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';

export default class App extends Vue {
  // 略
}
</script>

```

## こういうエラーでる

`pug-plain-loader text "export default "" outside root element will be ignored.`


## 結論

バージョン

## OK

```
    "vue-loader": "15.0.0",
    "pug-plain-loader": "^1.0.0",
```

## NG

```
    "vue-loader": "15.7.0",
    "pug-plain-loader": "^1.0.0",
```

## 推測


`pug-plain-loader` がリリースされてから、なんか1年くらいメンテされてない


## ちなみに Webpack の pug の設定

```

      {
        test: /\.pug$/,
        oneOf: [
          // this applies to pug imports inside JavaScript
          {
            exclude: /\.vue$/,
            use: ['raw-loader', 'pug-plain-loader']
          },
          // this applies to <template lang="pug"> in Vue components
          {
            use: ['pug-plain-loader']
          }
        ],
      }

```

## 参考

https://stackoverflow.com/questions/51073702/vue-pug-language-has-not-been-recognized-in-vue-template
Web開発に人気の言語でできることを、初心者目線で解説してみた。

[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしている田島一毅です。プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

##プログラミング学んでるけど何ができるんだ？？
現在プログラミングを学び始めて1か月弱。

最初に学んだHTMLやCSSといったマークアップ言語では、「これでWebページの見た目を整えられるんだなあ。かっこいいなあ。」と思っていました。

しかし、学習が進んで、プログラミング言語には様々なパラダイムが存在すること、どうやらアルゴリズムという複雑なものを学ぶ必要があることを知り、

**「これ学んでどうなるんだ？！」**

**「言語の種類多すぎだろ！！」**

**「どの言語で何ができるんだよ？！」**

という気持ちになりました（笑）

そんなこんなで、プログラミング言語別にできることを調べたので、この記事で紹介します。

といっても、言語の種類は非常に多いので、今回はWebアプリ・サービス系の言語に絞って紹介しますね(汗)

##1.　PHP

###PHPの特徴
PHPは、商用利用のWebサービスを簡単に作ることのできる言語です。

Webアプリ開発に特化していいるため、文法がシンプルで初心者でもわかりやすいのが特徴です。

また、ブログ作成によく利用されるWordPressは、PHPによって作られているため、ブログなどと連携したECサイトなども作りやすいのが非常に嬉しいです。

###PHPでできること
上でも紹介していますが、PHPでできることは、

- Webアプリ開発
- 具体的には、ショッピングカート機能、お問い合わせフォーム、ログイン機能、検索機能など
- SNS開発

など、Webアプリ開発を簡単にできます。


##2.　Java

###Javaの特徴
Javaは、複雑な処理を簡単にすることのできる言語で、業務システムの自動化や効率化に長けています。

JVM(Java Virtual Machine)という仮想マシン上でJavaは動くため、Java上でトラブルが発生した時に、他の部分への影響が少ないのが嬉しいです。

また、オブジェクト指向の言語のため、書きやすく理解しやすいコードが欠けますが、設計に時間がかかるため、小規模のシステムを作る場合は、先ほど紹介したPHPを利用するのがよいでしょう。

<br>

【補足】オブジェクト指向の簡単な説明

オブジェクト指向とは、誤解を恐れずに簡単に説明すると、

**「あるモノというくくりを作り、それに細かいデータを加えてそのモノを利用する」**

という考え方ですが、オブジェクト指向についての理解の仕方は人によって少し異なるので、調べてみてください。

このようなオブジェクト指向の言語では、コードを見やすくまとまりよく書けるのですが、事前の設計に時間がかかるというデメリットもあります。


###Javaでできること

- 配送システム、取引システムなどの業務システム
- スピードや堅牢性が求められる大規模Webサービス
- Androidアプリ開発(ほとんどのAndroidアプリ開発にJavaが利用されています。)
- ゲーム開発

など、広い分野で利用されています。

上でも述べた通り、小規模な開発ではPHPを利用するのがよいのではないでしょうか。


##3.　Ruby

###Rubyの特徴
Rubyは、オブジェクト指向の言語で、Webサービスを簡単に立ち上げ、継続的な機能の改善・追加が可能な言語です。

Rubyは、スクリプト言語といって、ソースコードを書いてすぐに実行＆確認ができるという特徴があります。

また、Rubyを学ぶときに必ず通る道が、**Ruby on Rails**というRubyのフレームワークです。

フレームワークとは、簡単に言えば、ある機能を簡単に利用できるようにしてくれるもので、コードを書く際の生産性を上げてくれます。

このRuby on Railsというフレームワークが非常に充実していることもあり、スピードを重視する企業からの需要が高まっています。

###Rubyでできること

- Webサイト制作
- スマホアプリ開発
- API作成(他のソフトウェアと機能を共有するための仕組みの作成)

などができます。

###PHPとの違いは？
「PHPでできることの中にも**Webサイト制作**とあるけど、**PHPと何が違うの？**」

と考えた方もいるでしょう。

PHPの強みは、学習がしやすいことです。

また、Rubyの場合はフレームワークはRuby on Railsの一択になりますが、PHPの場合は様々なフレームワークを利用できるのもポイントです。

一方、Rubyには、Ruby on Railsという絶大な人気を誇るフレームワークが存在するのが強みです。

また、PHPは実行が簡単にできてしまうため、個人での開発ならまだしも、チームでの開発の場合トラブルが起こりやすいのですが、Rubyではそのようなことが起こりにくいので、チームでの開発にも向いています。

これらを踏まえて言語を選ぶのが大切ですね。


##4.　JavaScript

###JavaScriptの特徴

JavaScriptは、オブジェクト指向の言語で、Webページに動きを付けるのによく使われます。

JavaScriptは、ブラウザとテキストエディタさえあれば動かすことができるため、初心者に優しい言語と言えるでしょう。

###JavaScriptでできること

- Webページに動きを付ける
 - ボタンの実装
 - スライドショーなどのアニメーション実装
 - SNSの埋め込み
 - カレンダー機能の実装　etc
- Webアプリ開発
- スマホアプリ開発
- ゲーム開発

などといったことができます。

Webサイトに動きを付けることに長けていて、ここで紹介した意外にも様々な機能をWebページに付けることができます。


##まとめ
今回は、Web系の言語でできることを、言語別に、初心者目線で紹介しました。

何を作るかという目的に応じて、言語を選んでいくことが大切ですね。
Azure App Serviceで独自ドメイン(カスタムドメイン)を使用する

独自ドメイン ( カスタムドメイン ) を Azure App Service に設定する方法です。

##ドメイン取得
[お名前.com](https://www.onamae.com/)などドメインレジストラで、使用したいドメインを取得します。ちなみにAzureからも購入は可能です。
ここでは example.com を取得したとして説明します。
##AppServiceプランの設定
exampleと言うAppService を作成することとします。[^1]
[^1]: 新規作成と既存の設定変更で操作の違いはありますが、AppServiceプランのサイズの考え方は同じなので読み変えて下さい。
その際、AppServiceプランでカスタムドメインが利用できるサイズを選択しなければなりません。
カスタムドメインの利用がサポートされているのはD1以上のサイズとなっています。
SSLを利用する場合はB1以上のサイズとなります。残念ながら無料プランでは利用できません。
![azure01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226493/8dc1b1df-d77d-4e2b-9032-b808db0de2fe.png)

##DNSの設定
DNSの設定値確認のため、AppServiceのカスタムドメインを開き-「カスタムドメインの追加」をクリックします。
そうすると検証用の画面が表示されるので、「カスタムドメイン」に目的のドメイン名を入力し、検証ボタンを押します。
DNS登録していないので「ドメイン所有権」にDNSに設定が必要内容が表示されます。
![azure02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226493/fba2c36b-6a2a-779f-e1e4-6665eec97735.png)

この情報を利用して、DNSの設定を行っていきます。
DNS レコードの設定方法は、DNSを管理している業者によって異なります。
ここでは、例として [お名前.com](https://www.onamae.com/) の DNS レコードを設定の設定方法を記載しておきます。

DNS関連機能の設定ページから、DNSレコードの追加を行っていきます。
![お名前01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226493/e33bede8-ebfb-a999-817b-e77813b8bd35.png)

Azureで検証を行った時に「ドメイン所有権」に表示されている内容を追加登録するだけです。
![お名前02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226493/78ae4bd5-1d1d-e20c-b7ff-e5aae06b215d.png)

例えば example.com と www.example.com の設定をする場合は下記の通りです。

example.com

|DNSレコード|設定値|
|:--|:--|
|Aレコード|IPアドレス|
|TXT|example.azurewebsites.net|

www.example.com

|DNSレコード|設定値|
|:--|:--|
|CNAME|example.azurewebsites.net|

サブドメインを追加する場合も同じ要領でAppServiceを追加して、CNAMEを追加するだけです。

##カスタムドメインの追加
DNS設定が完了したら、Azureに戻って再度検証を実行してください。
「ドメイン所有権」のエラーがなくなったら、カスタムドメインの追加をクリックしたら完了です。

DNS設定は即時に反映されず、反映されるまでに数分～数時間かかる場合があります。
![azure03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226493/7d7d2a57-d618-1c2f-3e48-e8c1c66f223d.png)

##注意点
カスタムドメイン適用前は、マイクロソフトが用意してくれているSSLが有効ですが、カスタムドメインとなることでSSLが効かなくなります。別途SSL証明書の購入と設定が必要となります。SSLについては、また別の機会にでも・・・
AWSとGCPをBGPでVPN接続する

AWSとGCPをVPN接続してみたので忘備録。

# 構成図
![VPN between AWS to GCP (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51320/086c3ab4-240d-7d75-1255-f438d4453a6c.png)



# 手順詳細
以下、①〜⑨の手順を実施する。VPCの基本設定やSG（AWS）、Firewall（GCP）の記載は割愛。

① 【GCP】 外部IPアドレスの予約
任意のリージョンで外部IPアドレスを予約します。

② 【AWS】 カスタマーゲートウェイの作成
カスタマーゲートウェイを作成します。
IPアドレスには、先にGCPで予約した外部IPアドレスを入力します。
どちらでも実現可能ですが、今回はルーティングは動的にします。

③ 【AWS】 仮想プライベートゲートウェイの作成
仮想プライベートゲートウェイを作成します。
ASNはデフォルトで。

④ 【AWS】 仮想プライベートゲートウェイをアタッチ
仮想プライベートゲートウェイをVPCにアタッチします。

⑤ 【AWS】 VPN接続の作成
仮想プライベートゲートウェイとカスタマーゲートウェイを繋ぐ、VPN接続を作成します。
トンネルオプションは設定なしとします。

⑥ 【AWS】 VPN接続設定のダウンロード
ベンダー：Genericを選択して、設定テキストファイルをダウンロードします。

⑦ 【GCP】 クラウドルーターの作成
ネットワークおよびリージョンを選択します。
Google ASNには、AWSカスタマーゲートウェイで設定したBGP ASN(デフォルトでは65000)を入力します。

⑧ 【GCP】 VPNの作成
「従来のVPN」にてVPNを作成します。
・ゲートウェイの設定
ネットワークおよびリージョンを選択し、IPアドレスは①で予約したアドレスを選択します。
・トンネルの設定
前手順（⑥）でダウンロードした設定ファイルを元に入力します。
リモートピアアドレスには「Outside IP Addresses:Virtual Private Gateway」のIPアドレスを、IKEバージョンはIKEv1を、IKE事前共有キーは「Pre-Shared Key」を入力します。
ルーティングオプションはBGP、クラウドルーターは前手順（⑦）で作成したものを選択します。
BGPセッションのピアASNには「Virtual Private  Gateway ASN」を、Cloud Router の BGP IPには「Inside IP Addresses：Customer Gateway」を、BGP ピア IPには「「Inside IP Addresses：Virtual Private Gateway」を入力します。
トンネルは、可用性のため２本とも設定しておいた方がベターですが、１本でもとりあえずは動きます。

⑨ 【AWS】 ルートテーブルの編集
ルートテーブルを編集し、ルート伝搬を有効化します。

# まとめ
AWS、GCPともわかりやすく、概ね、簡単に進みましたが、BGPセッションの設定が、設定ファイルとGCPコンソール上の入力項目名が紐づかずに、若干苦戦しました。（オンプレルーターに触れたことがないのが原因かも）
ハイブリッドクラウド環境の構築も、ハードルがだいぶ下がった印象です。
Domain-Driven Design Quickly ①

本家DDD本はとっつきにくいという噂があるので…
初心者の私はまずはこれを読んでDDDを理解したい！
[Domain Driven Design（ドメイン駆動設計） Quickly 日本語版](https://www.infoq.com/jp/minibooks/domain-driven-design-quickly/)

## そもそもドメインとは

**domain**(名詞)
- 領地、領土
- 領域、分野、...界

後者の方が当てはまりそう。
例えば、 `銀行のシステム`を作るなら`銀行業務の細部、ルール、問題点`などがドメイン。

## ドメイン駆動開発(DDD)とは

- **[前提] ドメインに対する十分な知識がないままソフトウェアを作ることは不可能である**
  - そもそもソフトウェアを作る目的は、そのドメインの業務をより効率的にするためなので…
- ソフトウェアは現実世界のドメインを**モデル化**して取り込む、という考え方
  - 全てを取り込む必要はない、取捨選択
  - これが**設計**である
- **モデルを他人に伝える**ことがもっとも大切

## 設計の段階に見るDDDの重要性

- ソフトウェアの設計
  - DDDが担当する部分
  - 家を構成するようなもの
  - やり直すのが大変


- コードレベルの設計
  - DDDの次の段階
  - 部屋のレイアウトを決めるようなもの
  - 修正が簡単

## アジャイル、XPとの相性

- DDDと合う点
  - 完璧な設計をしない手法
  - その代わり、**反復・柔軟性**によってより良いソフトウェアを作る


- DDDが解決できる点
  - 継続的リファクタリングは、設計の知識がない人がやるとゴミコードが生み出されるだけ
  - 設計しすぎてしまうのをうまく抑える
【AWS】MFA認証にMicrosoft Authenticatorを使う 

MFA認証に**Microsoft Authenticator** アプリを使用しているOffice 365ユーザーは多いと思います。
AWSでこれを使っている方が少ない印象だったので、手順を残しておきます。


### 用意する端末
- PC or MAC
- お手持ちのスマホ

### 手順
お手持ちのスマホにアプリをインストール
<img width="320" alt="01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/035cdc5c-fbdc-777e-48c4-2b37764ef3ef.png">

AWSにログイン、アカウント名のタブで、マイセキュリティ資格情報をクリック
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/8fd62a9d-58a2-da7b-e499-fbfa9192743d.png)

MFAの有効化をクリック
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/677445ca-1203-a416-5181-62b4068edf76.png)

仮想MFAデバイスを選択、続行をクリック。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/8c24a7bf-3bfd-7a81-3e20-b6987fee1eac.png)

QRコードの表示をクリック
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/d8ccd787-d6d3-b78e-199f-c84e67cf61f6.png)

スマホでQRコードリーダーを開く
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/eff682c8-2d4b-9186-74d9-e21009e45d60.png)

PCに表示されたコードを読み取り、Authenticatorで開くをクリック
![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/98042715-a650-2746-3c0a-3b69dfa032c7.png)

Amazon Web Serviceの項目が追加されます。カウントがゼロになる前にこの6桁の数字を...
<img width="320" alt="08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/e9079039-2638-c225-993e-5a05bab5f852.png">

PCのMFAコード1に入力
![09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/a38e77c8-2ecd-858a-6c85-e7eb42503d16.png)

スマホに戻り、先ほど入力した数字のカウントが切れて、新しい数字になったら、この数字を...
<img width="320" alt="10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/bfc5f675-72ea-7af8-02b5-18d9ee47642c.png">

今度はMFAコード2に入力し、
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/bb30712f-5684-fd28-29bf-b26bc6d3d68d.png)

MFAの割り当てをクリック
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/89f877ca-80e4-ce5d-ea86-f2e48418eab9.png)

この画面が出たらOK
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/50d89884-a4ab-94b8-5bd5-2066679ca277.png)

### さいごに
[**Well-Architectedフレームワークに関する記事**](https://qiita.com/Catetin0310/items/0dc1da1773b71e55d4ee)でも触れたように、セキュリティの担保はクラウド利用時の最重要項目です。なかでもMFA認証の有効化は必須。皆さんもれなく設定しましょう。
Ubuntu16.04.6のカーネルバージョンを16.04相当に戻す方法

#はじめに
Blackmagicの古いドライバがインストールできず、原因をみたらカーネルのバージョンでした。インストール時にオンラインアップデートをかけたのが良くなかったようです。
※事情により新しいドライバが使えない

と言うわけで新しいカーネルから古いカーネルに戻そうとしたのですが、途中でミスをして渋々grubを書き換えました。

この方法はあんまり良いやり方ではないと思います。
間違った方法を取ったので急遽リカバリーしたかたちです。
ですのでおススメはしません。
#参考になったサイト・記事
https://qiita.com/ego/items/36e9baccc80097950195
https://robotics4society.com/2016/06/15/ubuntu-boot/
#手順
####当該カーネルをインストールする
上記の https://qiita.com/ego/items/36e9baccc80097950195 で書かれている内容そのまんまなのですが

```
sudo apt-cache search linux-image
```
and 
でイメージを検索しましてインストールしたいイメージを探します。
僕の場合は4.4.0.31でした。
次にカーネルをインストールします。

```
sudo apt install linux-image-extra-4.4.0.31-generic linux-image-4.4.0.31-generic linux-image-4.4.0.31-lowlatency
```

インストール後、リブートして起動画面でESCを押しカーネルを選択します。
起動時のカーネルが古くなっていれば成功です。
####この後、新しい方のカーネルを削除してしまう
どこの記事を見たかは定かではないのですが/bootの中にある新しい方のイメージを削除します。この後、今調べた感じでは`update-grub`をすれば良さそうですが・・・
※ちなみに正しい方法は恐らくこちらかとhttps://qiita.com/jiey@github/items/33894296d62b1a329665

結果、どうなるかと言いますとgrubのデフォルトは新しいカーネルを指定しているので既に消してしまっている為、起動できません。ESCで毎回指定するしかありません。
####GRUBを手で書き換える
この時点で新しい方のカーネルと古い方のカーネルが記述されていると思います。そこで新しいほうのカーネルの記述を削除します。
次にデフォルトを記述している**[menuentry ‘Ubuntu’]**から始まる部分の記述を現在のバージョンに合わせて書き換えます。
※後ほどサンプル載せる予定です・・・

menuentryは複数箇所ありますが、対象は**[submenu ‘Advanced options for Ubuntu’]**の上です。

後は設定を保存してリブートしましょう。
万が一のためにSSHは有効にしておきましょう・・・
デバッグやテストデータで役立つ？実在する日本一長い〇〇入力フォーム

##入力テストするときに~~役に立たない~~役に立ちそうな長い名前
適当に調べただけなので、あくまでテスト用のデータとして使ってください。
`あああああああああああああああああああああ`とかで満足できない完璧主義に捧げます。

###日本一長い姓
**勘解由小路（かでのこうじ）**

###日本一長い名
**太郎喜左衛門将時能(たろうきざえもんのしょうときよし)**

###日本一長生きの生年
**1905年(明治38年　112歳)**

###日本一長い地名
490-1436
**愛知県海部郡飛島村大字飛島新田字竹之郷ヨタレ南ノ割**

###日本一長い駅名
**富山地方鉄道富山市内軌道線呉羽線の富山トヨペット本社前駅**

###日本一長いマンション名
**シャルマンフジビルト・モアー住之江公園駅前アーバンヴィレッジ**


##おまけ

###世界一長い名前
ファースト/ミドルネーム
**Adolph Blaine Charles David Earl Frederick Gerald Hubert Irvim John Kenneth Loyd Martin Nero Oliver Paul Quincy Randolph Sherman Thomas Uncas Victor Willian Xerxes Yancy Zeus**

ラストネーム
**Wolfeschlegelsteinhausenbergerdorffvoralternwarengewissenhaftschaferswesenchafewarenwholgepflegeundsorgfaltigkeitbeschut
zenvonangereifenduchihrraubgiriigfeindewelchevorralternzwolftausendjahresvorandieerscheinenbanderersteerdeemmeshedrraums
chiffgebrauchlichtalsseinursprungvonkraftgestartseinlangefahrthinzwischensternartigraumaufdersuchenachdiesternwelshegeha
btbewohnbarplanetenkreisedrehensichundwohinderneurassevanverstandigmenshlichkeittkonntevortpflanzenundsicherfreunanleben
slamdlichfreudeundruhemitnichteinfurchtvorangreifenvonandererintlligentgeschopfsvonhinzwischensternartigraum**

~~絶対親恨んでるだろうな~~


ちなみにボクは`あああああああああああああああああああああ`で満足するタイプなので使わないです。
プログラミング講習（仮）01

#プログラミング講習（仮）01
##目的
勉強したい人の支援

##内容
環境確認からprintfまで

## gcc 確認

```
$gcc
gcc: fatal error: no input files
compilation terminated.
```

```
$gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
```

## ファイル作成 (touch コマンド)
touch ファイル名

```
$touch prex01.c
```

## ファイルの確認 (ls コマンド)
```
$ls
prex01.c
```

## ファイル記述 (vim)
```
$vim prex01.c
```
``` prex01.c
#include <stdio.h>

void main() 
{
  printf("Hello, World.\n");
}
```

## ファイルの確認 (cat コマンド)
cat ファイル名

```
$cat prnx01.c
```

## コンパイル
gcc -o 出力名 入力ファイル

```
$gcc -o exe prex01.c
```

## 実行

```
./exe
```
WebアプリでJPGファイルをハンドリング

# 背景

通常、次のようなURLをブラウザでクリックすると、直接、画像ファイルをGETするため、
自作したWEBアプリでハンドリングできない。
画像ファイルのGETメソッドをWEBアプリで捕まえて、特定のフォルダにあるファイルを返すようにしたかったので、その方法について学習した。

# 環境

- Visual Studio 2017
- asp.net

# 問題

大きな問題は、Webアプリ(asp.Net)に関して初心者ということである。
プログラムを作るにあたって、次の二点が理解できなかった。

- ルーティング  
リクエストを受けてコントローラーのメソッドを呼び出させる方法が分からない。  
例えば、http://hoge/test.jpg というリクエストが来た時に、hogeController.GetImage()を実行させる方法である。

- 画像データをクライアントに渡す方法が分からない  

# 分かったこと

インターネットの情報と同僚のコードから学んだ結果、次のような処理を用意すれば解決できることが分かった。

- 指定URLのJEGをハンドリングすることをWebConfig.xmlに記述する。
- 指定URLをハンドリングするコードを作成する。  
    - アプリ起動時にそのコードを呼び出す。（例えばGlobal.asaxのApplication_Start） 
- バイナリを返すのはController.Fileを使えばよい  

# サンプル

```xml
<system.webServer>
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
      <!-- hoge/*.jpg のURLをWeb Appでハンドリングすることを設定 -->
      <add name="JpgFileHandler" path="hoge/*.jpg" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>
```

```c#
        protected void Application_Start()
        {
            // ルートを登録
            RouteConfig.RegisterRoutes(RouteTable.Routes);
        }
```
```c#
        public static void RegisterRoutes(RouteCollection routes)
        {
            string imageDir = TurfConfig_SynergyRecorder.Instance.SvidImageDirName.ConfigValue;

            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.RouteExistingFiles = true;

            // jpeg指定で呼び出されるコントローラーを設定
            routes.MapRoute(
                name: "hoge",
                url: "hoge/{filename}.jpg",// ハンドリング対象URL
                defaults: new { /*Controller Name*/controller = "Hoge", /*呼び出されるメソッド*/action = "GetImage" }
            );
        }
    }
```

```c#
    public class hogeController : Controller
    {
        public ActionResult GetImage()
        {
            byte [] image = LoadJpeg();
            return this.File(image, "image/jpeg");
        }
```


# 参考
https://docs.microsoft.com/ja-jp/aspnet/core/mvc/controllers/routing?view=aspnetcore-2.2#route-names
https://stackoverflow.com/questions/34498184/difference-between-filecontentresult-and-filestreamresult
https://under-programmer.hatenablog.com/entry/close_stream
https://stackoverflow.com/questions/186062/can-an-asp-net-mvc-controller-return-an-image
rvenvをアンインストールして今後anyenvで**env管理する

#環境
Ubuntu(WSL)

#anyenvとは
○○env系を管理してくれる便利なソフト
anyenv install ○○で何でも楽にインストールできる！
https://github.com/anyenv/anyenv

#インストール
以下WSLのubuntuの環境で作業していきます。OSごとのインストール方法は[github](https://github.com/anyenv/anyenv)へ

```
$ git clone https://github.com/anyenv/anyenv ~/.anyenv
# pathの設定
$ echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bashrc
# シェルの設定
$ echo 'eval "$(anyenv init -)"' >> ~/.bashrc
# シェル再起動
$ exec $SHELL -l

#インストールの確認
$ anyenv -v
anyenv 1.1.0
```

再起動後、こんなのが出てくるから、指示通りコマンドを実行

```
$ exec $SHELL -l
ANYENV_DEFINITION_ROOT(/home/sasa/.config/anyenv/anyenv-install) doesn't exist. You can initialize it by:
> anyenv install --init

$ anyenv install --init

```

自動でアップデートしてくれるプラグインをインストール

```
$ mkdir -p $(anyenv root)/plugins
$ git clone https://github.com/znz/anyenv-update.git $(anyenv root)/plugins/anyenv-update
$ exec $SHELL -l
```

インストールできる**envを見てみる

```
$ anyenv install -l
  Renv
  crenv
  denv
  erlenv
  exenv
  goenv
  hsenv
  jenv
  luaenv
  nodenv
  phpenv
  plenv
  pyenv
  rbenv
  sbtenv
  scalaenv
  swiftenv
```

既にrbenvが入っている場合、rbenvを消しちゃう

```
$ rm -rf ~/.rbenv
$ rbenv -v
Command 'rbenv' not found...
```

`anyenv install hoge`でインストールできます。詳しくは`anyenv -h`で！

**envをインストールした後は
`exec $SHELL -l`で再起動をお忘れなく！

#参考サイト
nodenvのインストールについて記載されています
http://dslab.work/2019/04/21/post-114/
macでのanyenvのインストールについて記載されています
https://qiita.com/fuku_tech/items/17d65344a36a08bafc69
【Git】コミットハッシュ(短縮形)からコミットハッシュ(フル)を得る


`git rev-parse コミットハッシュ`でOK。

```bash:bash
$ git rev-parse 9c3f6b9e
9c3f6b9ed6734dda6983992ccf790b8f805be690
```

このコマンドはハッシュの特定に**失敗すると0以外を返す**。
従ってエイリアスや関数の引数でコミットハッシュを入力するときの1段目に置いておけばフィルタとして利用できる。
BitriseでAndroid Lint

# はじめに
[Android Lintと修正方法](https://qiita.com/yoppie_x/items/4ada5a4c12ff9fd057a4)についてまとめました。
この記事ではBitriseにある`Android Lint`のステップについてまとめます。
[BitriseとDeployGateを連携しAndroidアプリのアップデートを配布](https://qiita.com/yoppie_x/items/c4279c6eaa0e03cef861)についてもまとめているので、興味のある方はこちらも参考にしてください。

# 手順
1. `Android Lint`をWorkflowに追加
2. `Env Vars`に環境変数を追加
3. `Module`と`Variant`を修正

# Android LintをWorkflowに追加
一瞬です。
Workflowにある+ボタンでAndroid LintのStepを選択し追加します。
<img width="362" alt="スクリーンショット 2019-06-04 12.14.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356260/098094a8-f090-12fb-7854-ec7c28a67c39.png">

# Env Varsに環境変数を追加
Lintを行うModuleとVariantを環境変数として定義します。
Workflow EditorにあるEnv Varsタブを開きます。
`$WHOLE_PROJECT = app`、`$VARIANT_DEBUG = debug`を作成しました。
こちらはLintしたい内容によって変更する必要があります。
<img width="1395" alt="スクリーンショット 2019-06-04 12.26.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356260/cbdc8b4c-5c03-c81d-c167-ee85f96207f8.png">

# ModuleとVariantを修正
Workflowに追加したAndroid LintのModuleとVariantの設定を修正します。
Env Varsに追加した環境変数を設定します。
<img width="1051" alt="スクリーンショット 2019-06-04 12.38.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356260/0523f81b-0415-c823-9811-f5dcc6626778.png">

# Lintの結果
ビルドしLintした結果はそれぞれのビルドのリンク内にある`APPS & ARTIFACTS`というタブに出力されます。
ErrorやWarningがある場合このようになります。
<img width="1370" alt="スクリーンショット 2019-06-04 11.57.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356260/cd0c28e8-40c8-c260-0cb4-fe0f79a2a8ba.png">
問題がない場合このようになります。
<img width="1374" alt="スクリーンショット 2019-06-04 12.09.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356260/ba1a377a-1d27-7761-5208-5a67a44eb6fd.png">
Flutter ちょっと Tips 〜要素サイズいっぱいに表示する〜

## 画面いっぱいに何かを表示したい
Container の constraints: BoxConstrains.expand() で、expand メソッドに何も渡さなければ要素のサイズいっぱいに表示してくれる。
この手の実装としては必要最低限だけど、取っ掛かりとしてここから考えると良さそうな感じ。

```Dart
    return Container(
      constraints: BoxConstraints.expand(),
      child: 【表示したいもの】
    );
```


###例
とりあえず動かしたい人向け
コピペすれば動く

```Dart
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      home: Scaffold(
        appBar: AppBar(title: Text(_title)),
        body: ImageWidget(),
      ),
    );
  }
}

class ImageWidget extends StatelessWidget {
  ImageWidget({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      constraints: BoxConstraints.expand(),
      child: Image.network(
          "http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=369577&type=card",
          fit: BoxFit.contain),
    );
  }
}
```

`fit: BoxFit.contain` のところが、「画面サイズに合わせて画像が全部表示されるギリギリの大きさまで拡大する」の意味みたい。


### 公式ドキュメント
Container
https://api.flutter.dev/flutter/widgets/Container-class.html

BoxConstraints.expand constructor
https://api.flutter.dev/flutter/rendering/BoxConstraints/BoxConstraints.expand.html

Image.network
https://api.flutter.dev/flutter/widgets/Image/Image.network.html

BoxFit enum
https://api.flutter.dev/flutter/painting/BoxFit-class.html
gem install bundle でこけて、can't find gem bundlerが出る時

gem install bundleしようとすると`can't find gem bundler`が出ました。

簡単ですが共有します。
`gem install bundle
Successfully installed bundle-0.0.1
Parsing documentation for bundle-0.0.1
Done installing documentation for bundle after 0 seconds
1 gem installed`

どうやらbundle -0.0.1のversionが入っているみたい
多分入ってない、よねこれ。

という訳で、
`gem install bundler -v 1.16.0`
などのversion指定をしてやりましょう。

`gem install bundler -v 1.16.0
Fetching: bundler-1.16.0.gem (100%)
Successfully installed bundler-1.16.0
Parsing documentation for bundler-1.16.0
Installing ri documentation for bundler-1.16.0
Done installing documentation for bundler after 4 seconds
1 gem installed`

`bundler -v
Bundler version 1.16.0`
入り申した。
”ほかのホストのハードウェアオブジェクトのステータス”について

”ほかのホストのハードウェアオブジェクトのステータス”について
仮想基盤プロジェクトに携わった際にESXi上で上記のエラーが出力されました。その際のsolutionを下記に記載します。

-　solution
1. iLO＞診断＞iLOをリセット＞リセット
2. vCenter上でストレージアダプタ&ストレージデバイス＞再スキャン
論理値型

##bool,true,false のあれこれ
```go
package main

import "fmt"

func main() {
	t, f := true, false         // var t, f bool = true, falseでもOK
	fmt.Printf("%T %v\n", t, t) //bool true
	fmt.Printf("%T %v\n", f, f) //bool false

	//%vは型に関係なく値を出力するが、%tは少し厳密に型まで評価して正しければ出力する。
	fmt.Printf("%T %v %t\n", f, f, f) //bool false false
	fmt.Printf("%T %v %t\n", f, 1, f) //bool 1 false
	fmt.Printf("%T %v %t\n", f, f, 1) //bool false %!t(int=1)

	//論理演算子
	fmt.Println(true && true)  //true
	fmt.Println(true && false) //false
	fmt.Println(false && true) //false
	//どちらかがfalseだとfalseを返す

	fmt.Println(true || true)   //true
	fmt.Println(true || false)  //true
	fmt.Println(false || true)  //true
	fmt.Println(false || false) //false
	//どちらかがtrueだとtrueを返す

	fmt.Println(!true) //false
	fmt.Println(!false) //true
}
```
>【参考】
現役シリコンバレーエンジニアが教えるGo入門(https://www.udemy.com/share/100BhMB0obeFpbTX4=/)
AmplifyConsoleからデプロイ中、GraphQLスキーマのビルド時に発生する"Unknown directive '~' "の対処法

### 追記 (2019/6/5)
一番下に詳細を記述していますが、なんとamplify console側が対応してくださりました！

# Amplifyとは
Amplify は、AWS を利用したモバイルやウェブアプリケーションを開発やバックエンドの構成を用意にするフレームワークです。各種AWSサービスとFrontendの連携、Backendの手軽な構成を可能。

# 構成
![amplify-qiita (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166345/c33b873d-e0c5-2c2c-de11-654f79329adf.png)

## Frontend
Vue.js

## Backend
AWS AppSync + GraphQL + DynamoDB

# 環境
- Amplify CLI == 1.7.0
- Vue-CLI  ==  v3.0.0

# GraphQL Schema 定義

```GraphQL:schema.graphql
type Book @model @key(fields: ["category", "title"]){
  category: String!
  title: String!
  price: Int!
}
```
<code>@model</code>や<code>@key</code>はamplify側のディレクティブ
DynamoDBの Partition key や Sort Keyを設定する際に使われるのが<code>@key</code>ディレクティブ。
最初の要素が Partition Key、その次が Sort Key になる。

# GraphQLスキーマのビルド

```
$ amplify api gql-compile

GraphQL schema compiled successfully.
Edit your schema at /path/to/schema.graphql or place .graphql files 
in a directory at /path/to/schema
```

ローカルではビルドに成功する。

# AmplifyConsoleにてデプロイ
ビルド設定は以下の通り

```yaml:amplify.yml
version: 0.1
backend:
  phases:
    build:
      commands:
        - '# Execute Amplify CLI with the helper script'
        - amplifyPush --simple
frontend:
  phases:
    preBuild:
      commands:
        - yarn install
    build:
      commands:
        - yarn run build
  artifacts:
    baseDirectory: dist
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*
```

### Localで上手くいっていたビルドでこける

```error:build.log
SchemaValidationError: Schema Errors: Unknown directive "key".
```

ログを詳しく確認してみると

```
## Install AWS Amplify CLI
RUN /bin/bash -c ". ~/.nvm/nvm.sh && \
	npm install -g @aws-amplify/cli@1.5.1"
```

なるほど。。どうやらConsole側がinstallしている@aws-amplify/cliのバージョンが古いらしい

# 解決策

amplify.ymlのビルド設定に追記する

```yaml:amplify.yml
~
backend:
  phases:
    build:
      commands:
        - '# Execute Amplify CLI with the helper script'
        - npm install -g @aws-amplify/cli   // ---------------- 追記 ----------------
        - amplifyPush --simple
~
```

Frontendからビルドが始まれば問題ないが、連携の都合上Backendのビルドとなってしまうため追記が必要になる。

# 終わりに
こういったバージョン違いによる不都合はよくあることなので真っ先に疑わないといけないなと反省。

# 追記 (2019/6/5)

GitHubにissue立てていたのですが、なんと1日足らずで対応してくださりました！！
わざわざTwitterにリプライをくださる神対応ぶり！ありがとうございます！！

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">Please try again. The new CLI is available in all regions.</p>&mdash; Nikhil Swaminathan (@TheSwaminator) <a href="https://twitter.com/TheSwaminator/status/1136027633383137280?ref_src=twsrc%5Etfw">2019年6月4日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>