OmniAICreator/Qiita-1.07M huggingface dataset:
【RPA】ドキュメントのデジタル化機能/ツール別比較

新型コロナ禍でリモートワークやデジタル化の促進のため、紙業務をデジタル化するためのAI-OCR機能とRPAとの連携が大変注目されています。この機能はインテリジェント・ドキュメント・プロセッシング (Intelligent Document Processing、IDP)とも呼ばれます。通常のRPAツールはDX Sute、TegakiなどのAI-OCR専用ツールとの外部連携をすることで実現をしますが、RPAツール内に組み込まれているとより一層の連携が可能になります。ちなみに、RPAの中で単純に画像や文字、UIなどの画像認識をする「OCRコマンド」とは別のもので、ドキュメント全体の意味をとらえて全体をデジタル化することができます。

ということで、ドキュメントのデジタル化機能について主要6大RPAソフトウェア (WinActor、BizRobo!、UiPath、Automation Anywhere、Blue Prism、Power Automate)の比較をしてみたいと思います。

**凡例**

* 👍: RPAツール群の一部として対応している。
* ❌: 対応なし。(外部AI-OCRと連携する必要あり)

|RPAソフトウェア|IDP機能 (機能名)|説明|
|:--|:--:|:--|
|WinActor|❌ |WinActorは今のところ特にドキュメントデジタル化のソリューションを出しておらず、DX Suite等外部AI-OCRツールとの連携が必須となります。2020年3月に登場したVer.6.3.0から搭載されている**WinActorEye**という従来の画像認識の上位機能があり、ドキュメントを部分的に文章として読み込めますが、あくまでも簡易的な読み込みに留まります。**NaNaTsu**というブランドでNTTデータが地方自治体向けにDX Suiteとの連携サービスを実施しています。|
|BizRobo!|❌|2018年より**BizRobo! Document**というブランドでいくつかのソリューションを提供していますが、いずれも外部AI-OCRツール連携です。|
|UiPath|👍 UiPath Document Understanding|2020年2月より限定リリースとなった**UiPath Document Understanding**を使うと、ドキュメント認識のAIスキルをStudio内で統合して使うことができるようになります。固定フォーム、ABBYY、Microsoft Formsなどを扱うことができます。|
|Automation Anywhere|👍 IQ Bot|RPAベンダーの中では最も早い2017年より**IQ Bot**と呼ばれるドキュメントデジタル化機能を搭載しています。複数のOCRエンジンを搭載して選択することができ、特に非定型で種類の多いフォームの読み込みに強い。|
|Blue Prism|❌|Blue Prismは今のところ特にドキュメントデジタル化のソリューションを出しておらず、DX Suite等外部AI-OCRツールとの連携が必須となります。**Blue Prism Decipher**という自前のツールを開発中のようです。|
|Power Automate|👍 AI Builder (Azure Form Recognizer)|Power Platformの一部として、マイクロソフトでは2019年5月に発表され、プレビューリリースとなった**AI Builder**(APIでは**Azure Form Recognizer**)という、定型フォーム(レシートなど)やカスタムモデルの認識とOCRを組み合わせたサービスがあり、Power Automate (or Azure Logic Apps) との連携も可能となっています。|


# 関連記事

* [【RPA】プロセスマイニング・タスクマイニング (プロセスディスカバリー) 対応状況/ツール別比較](https://qiita.com/Okura_/items/320e84651403ac4266a1)
* [【RPA】ロボット実行環境のOS対応状況/ツール別比較](https://qiita.com/Okura_/items/8975d6cd7ba0ff2ff61b)
* [【RPA】基本用語/ツール別比較](https://qiita.com/Okura_/items/2cb0dd2ce17356bb50ea)
* [【RPA】どのランタイム環境上で作られているか/ツール別比較](https://qiita.com/Okura_/items/a3f9393267e655e7300d)
* [【RPA】メールの送受信/ツール別比較](https://qiita.com/Okura_/items/369d95a938a05e836417)
* [【RPA】自動化に対する思想/ツール別比較](https://qiita.com/Okura_/items/1c8b29d40d98f2e5ce63)
* [【RPA】サーバー管理の仕組み/ツール別比較](https://qiita.com/Okura_/items/dfc380ec50df6b289391)
* [【RPA】トリガー・スケジュール機能/ツール別比較](https://qiita.com/Okura_/items/7d5e617260378fd2947f)
* [【RPA】ロボットの稼働方法 (ヒトロボ協働型・ロボ自律型)別ライセンス提供/ツール別比較](https://qiita.com/Okura_/items/e9c9f394ae5805481b2b)
* [【RPA】オブジェクト指向のロボット作成/ツール別比較](https://qiita.com/Okura_/items/923706e8f4c8e3628522)
* [【RPA】シンクライアント操作への対応/ツール別比較](https://qiita.com/Okura_/items/13de777603cd9912992b)
* [【RPA】SAP対応/ツール別比較](https://qiita.com/Okura_/items/b265ca3f083b92471b58)
* [【RPA】対応ブラウザー/ツール別比較](https://qiita.com/Okura_/items/8501117954139300f427)
* [【RPA】コーディング知識の必要度/ツール別比較](https://qiita.com/Okura_/items/71a577e2141591c88a33)
* [【RPA】UI Automation 対応状況/ツール別比較](https://qiita.com/Okura_/items/95a78c46454ae0dac036)
* [【RPA】ログイン情報の保管方法/ツール別比較](https://qiita.com/Okura_/items/12cdcc743670c6d9c7c7)
【随時更新】MSYS2の使い方

Windows + MSYS2でやっていこうと思っています。

[Windowsのコマンドライン開発環境](https://qiita.com/ymdymd/items/2fe0235e8126f06e74ca)

## HOME
MSYS2は標準で`/home/<username>`をホームディレクトリとして動作します。
ただ、私はWindowsのホームディレクトリ`%USERPROFILE%`を使うよう変更しています。
`HOME`を参照するツールも`USERPROFILE`を参照するツールも、等しく管理できるようになります。

### .ssh
OpenSSHだけは`HOME`も`USERPROFILE`も参照してくれず、`/home/$USER`を参照します。

参考: [Windows-アプリケーション/MinGW-MSYS/MSYS2のOpenSSHでのホームディレクトリの扱い - yanor.net/wiki](https://yanor.net/wiki/?Windows-%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3/MinGW-MSYS/MSYS2%E3%81%AEOpenSSH%E3%81%A7%E3%81%AE%E3%83%9B%E3%83%BC%E3%83%A0%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%AE%E6%89%B1%E3%81%84)

## pacman
pacmanを使いましょう。

### ミラーサイト指定

```:/etc/pacman.conf（抜粋）
[mingw32]
Include = /etc/pacman.d/mirrorlist.mingw32

[mingw64]
Include = /etc/pacman.d/mirrorlist.mingw64

[msys]
Include = /etc/pacman.d/mirrorlist.msys
```

参考: [msys2のミラーにjaistを使いたい - Qiita](https://qiita.com/yumetodo/items/94a80ca9d6171e9352a2)

### コマンド

```
pacman -Qs # インストールされたパッケージの部分一致検索
pacman -Ql # 指定したパッケージが保有しているファイルを表示
pacman -Fl # 指定したパッケージが保有しているファイルを表示
pacman -Fy # サーバーから最新のパッケージデータベースをダウンロード
pacman -Rs # 不要な依存関係を削除
```
React Developer Toolsで全てのコンポーネントを表示

chromeの拡張機能でReact Developer Toolsはデフォルトで定義したコンポーネントしか表示しないようになっている。
タグのコンポーネント（divタグやpタグなど）も全て表示するには、「歯車マーク」→「components」で、全てのfilterを×ボタンで消すと表示されるようになる。

![スクリーンショット 2020-11-23 19.49.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513214/36a626b6-9a72-cbf5-9825-6e7036245762.png)


【変更前】
![スクリーンショット 2020-11-23 19.53.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513214/371f1da5-1d89-9f6b-b403-4a7233763177.png)


【変更後】
![スクリーンショット 2020-11-23 19.53.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513214/6afd7d10-4227-abfb-8c82-d67c79d3595d.png)
3次元剛体の運動方程式の立て方1_運動学

# 前回

https://qiita.com/GANTZ/items/0478b59d50bf45e38e0d


# つづき
前回は，ベクトルについて詳しく述べました．
今回は，角速度，速度について詳しく記述していきます．

座標系A上に固定されている点Pの速度を考えます．ここで，点PはA上に固定されているため　$r_{AP}^A$　(AからPへの代数ベクトル，A座標系で表現)は時不変の定ベクトルになります．よって，座標系AでPを見る際の速度は

```math
v_{P}^A = 0
```
であるといえます．
座標系Oで見る際の速度は0であるとは限りません．なぜなら，A座標系が並進移動・回転をしている可能性があるからです．結論から述べると

```math
v_{P}^O = v_{A}^O + C_{OA} cross(\omega_{A}^A) r_{AP}^A
```
となります．$\omega_{A}^A$は座標系Aの角速度ベクトルです．

座標系Aの原点の速度（並進速度）が　$ v_{A}^O  $　
座標系Aの回転による速度が　$cross(\omega_{A}^A) r_{AP}^A $
になります．並進速度はわかると思いますが，回転による速度は，意味不明だと思います．

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/deb13396-209f-bb72-ca72-af1aa27e95be.png)
座標系Aが回転していることで，点Pには速度ベクトルが発生していることがわかると思います．
この幾何速度ベクトルは，

```math
\vec \omega_A \times \vec r_{AP}
```
という外積で計算できます．[参考](http://w3e.kanazawa-it.ac.jp/math/physics/category/mechanics/motion/rotational_motion/henkan-tex.cgi?target=/math/physics/category/mechanics/motion/rotational_motion/angular_velocity_vector.html)リンク

代数ベクトル計算する場合は，$\vec \omega_A $,$ \vec r_{AP}$両方同じ座標系で代数ベクトルとして表現する必要があります．$ \vec r_{AP}$はA座標系でないと定ベクトルではないので，両方Ａ座標系で表現し，外積します．よって$cross(\omega_{A}^A) r_{AP}^A $となります．
$v_{P}^O $はO座標系表現なので，並進速度と合成する際は，$C_{OA}$を掛けて，O座標系に変換して足しています．

### 追記（飛ばしていいです）
直感的でなく数学的に証明することもできます．

```math
C_{OA} C_{OA}^T = I
```
を時間微分すると

```math
\dot{C_{OA}} C_{OA}^T +C_{OA} \dot{C_{OA}^T} = 0
```
ここでの時間微分は，各要素の時間微分です．

```math
\Omega = \dot{C_{OA}} C_{OA}^T
```
とすると

```math
\Omega + \Omega^T = 0
```
よって，対角成分は0,対象成分は正負が反転$\Omega_{i,j} =-1*\Omega_{j,i} $である．
よって

```math
\Omega=\left(
    \begin{array}{ccc}
      0&-w_z&w_y\\
w_z&0&-w_x\\
-w_y&w_x&0\\
    \end{array}
  \right)\\
=cross(w)
```
と書ける．ここで，新しいベクトルを定義した．

```math
\omega = 
\left(
    \begin{array}{ccc}
      w_x\\
w_y\\
w_z\\
    \end{array}
  \right)\\
```
話を戻して,

```math
\dot{C_{OA}} C_{OA}^T +C_{OA} \dot{C_{OA}^T} = 0
```
より

```math
\begin{eqnarray}
\dot{C_{OA}} C_{OA}^T &=& -C_{OA} \dot{C_{OA}^T}\\
\therefore \dot{C_{OA}} &=& -C_{OA} \dot{C_{OA}^T}  (C_{OA}^T)^{-1}
&=&-\Omega^T  C_{OA}\\
&=&-cross(w)^T C_{OA}\\
&=&cross(w)C_{OA}\\
\end{eqnarray}
```

$C_{OA}$は,$e_{AX}^O$を座標系$A$の$x$方向単位幾何ベクトルを$O$座標系で表した代数ベクトルとすると

```math
C_{OA} = [e_{AX}^O , e_{AY}^O , e_{AZ}^O]
```
と書けますので，列で見ると

```math
\begin{eqnarray}
\dot{e_{AX}^O} &=& cross(w)e_{AX}^O\\
\dot{e_{AY}^O} &=& cross(w)e_{AY}^O\\
\dot{e_{AZ}^O} &=& cross(w)e_{AZ}^O\\
\end{eqnarray}
```
が導かれます．

# 座標変換行列の時間微分と角速度ベクトルの関係
先ほど求めた結果を用いて座標変換行列の時間微分を求めてみます．
$r_{OP}^O$を時間微分することを考えます．

```math
\begin{eqnarray}
\frac{d}{dt} r_{OP}^O &=& \frac{d}{dt} r_{OA}^O  + \frac{d}{dt} r_{AP}^O\\
 &=& v_{A}^O  + \frac{d}{dt} (C_{OA}r_{AP}^A)\\
 &=& v_{A}^O  + (\frac{d}{dt} C_{OA} ) r_{AP}^A\\
 \end{eqnarray}
```
$r_{AP}^A$は時不変なので，$\frac{d}{dt}r_{AP}^A = 0$となり，現れません．
先ほどの結果

```math
v_{AP}^O = v_{A}^O + C_{OA} cross(\omega_{A}^A) r_{AP}^A
```
と比較すると

```math
\frac{d}{dt} C_{OA}  =  C_{OA} cross(\omega_{A}^A)
```
が得られます．この関係は頻繁に表れるので覚える価値ありです．角速度ベクトルはA座標系で表している必要があることも大切です．


以上で運動学的説明を終わります．
次に3質点剛体を用いて，目標である，3次元のオイラー・ニュートンの運動方程式を導出します．

https://qiita.com/hiRina/items/04e8c208bc1cc43d0daa
Raila チュートリアル_4章_学習メモ

#学んだ事
##カスタムヘルパー
+ 新しく作成した関数を格納しておくファイル
##Rubyの復習
###式展開
通常、文字列をつなげる際には「+」記号が用いられるが、＃｛〇〇｝"ほげ"と記載する事で、「〇〇ほげ」という文章になる。
※その前には変数で定義する必要がある。
###後続if
後続するifの条件式が正のときだけ実行されるという書き方が可能
```puts "x is not empty" if !x.empty?```
###破壊的メソッド
配列の並びを変更して保持したい時に使うらしい。
```ex)ruby:qiita.rb
a = [12 , 6, 4]
a.sort!
= [4, 6, 12]
a = [4, 6, 12]
```
DNNに入れる前の画像の前処理(正規化など)をいくつか(MNIST)

# 画像の前処理各種

DNNに入れる前の前処理をいくつかMNISTに適用したのでメモ。

## ライブラリのインポートと日本語フォントの設定

```python
import keras
from keras.datasets import mnist
import matplotlib.pyplot as plt
import numpy as np
import cv2
%matplotlib inline
```


```python
from matplotlib import rcParams
rcParams['font.family'] = 'sans-serif'
rcParams['font.sans-serif'] = ['Hiragino Maru Gothic Pro', 'Yu Gothic', 'Meirio', 'Takao', 'IPAexGothic', 'IPAPGothic', 'VL PGothic', 'Noto Sans CJK JP']
```

## mnist ロード

```python
#Kerasの関数でデータの読み込み。データをシャッフルして学習データと訓練データに分割
(x_train, y_train), (x_test, y_test) = mnist.load_data()

# 2次元データを数値に変換
#x_train = x_train.reshape(60000, 784)
#x_test = x_test.reshape(10000, 784)
# 型変換
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
# 255で割ったものを新たに変数とする
#x_train /= 255
#x_test /= 255
```
## 各種処理を行った際の画像を表示

```python
img = x_train[0]
plt.title('元画像')
plt.imshow(img, cmap='gray',clim=[0,255])
plt.show()
img_07 = img*0.7
plt.title('0.7')
plt.imshow(img_07, cmap='gray',clim=[0,255])
plt.show()
img_std = (img_07 - np.mean(img_07))/np.std(img_07)*16+64
plt.title('ブライトネス・コントラスト調整背景白')
plt.imshow(img_std, cmap='gray',clim=[0,255])
plt.show()
img_norm = np.zeros(img_std.shape)
img_norm = cv2.normalize(img_std, img_norm, 0, 255, cv2.NORM_MINMAX)
plt.title('背景白正規化')
plt.imshow(img_norm, cmap='gray',clim=[0,255])
plt.show()
plt.title('0.7正規化')
img_norm = cv2.normalize(img_07, img_norm, 0, 255, cv2.NORM_MINMAX)
plt.imshow(img_norm, cmap='gray',clim=[0,255])
```

![test_normalize_3_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490869/ff92053a-b73f-61eb-e241-7fd4807b3e50.png)
![test_normalize_3_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490869/db6d33e0-d4fa-d01c-a149-7451e7c4c4b1.png)
![test_normalize_3_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490869/52689ac4-0696-ddee-1336-b825fd9dfb74.png)
![test_normalize_3_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490869/06a9a2fa-9cf3-0700-5bd6-da5a0480d307.png)
![test_normalize_3_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490869/22958805-4f72-5559-bf76-d6d3fdada848.png)
エンジニアのインターンに応募する前に準備しておくべきこと

#この記事の対象者
- Progateやドットインストール、Udemy、N予備校、書籍、などのプログラミング教材を一通りこなしており、インターンを通して実務経験を積みたい人。
- インターンに参加してみたいけど何も行動できていない人。
- 長期インターンに応募してみたいけど、自分の今のレベルがどれくらいかわからないから、未経験でも参加できる1dayや3dayなどにしか参加したことがない人。
- インターンの応募フォームを見て絶望した人。（自分はコレです。）
- ゴミクズみたいな制作物をHerokuで公開している人。

以上のような方を想定してこの記事は書かれています。


以下、軽い自己紹介なので飛ばしてもらってOKです。

---
ちなみに自分は地方国公立大学の文系2年です。
高3のセンター終わったときに志望校がC判定だったので、一つレベルを落として受験することになり、いざその大学の過去問を見てみると簡単すぎて、暇になりProgateを始めました。なので、プログラミング歴としては約１年９か月くらいでしょうか。
学んだ教材としては、Progate、ドットインストール、Youtube、書籍、N予備校です。N予備校以外のネット教材でプログラミングの基礎を学んでN予備校で実際にどのように一つのアプリを作るのかなどを学びました。最近は、Reactにはまっていて、Youtubeで英語圏の人のハンズオンで作っている動画を見ながら勉強しています。しかし、もう３年に近づいてきたのでそろそろ就活にも向かわないといけないと思い、インターン応募をしようとするも何も書くことがなさ過ぎて、絶望してすぐさま対策に取り掛かっている状況です（笑）。

#インターン応募のフォームに大体あるもの
1.志望理由
2.制作物・ポートフォリオ
3.開発で工夫した点
4.Github,Qiita,Blog のURL
5.過去に参加したインターン、コンテスト
6.希望分野

以上の６つが大体どの企業のインターン応募のフォームにあります。

#制作物・ポートフォリオに関して
基本的にチュートリアルで作るようなTodoアプリ、掲示板などをそのまま公開するのはやめましょう。というのも、一番重要なのは自分が技術的にどこまで制作物を説明することができるかどうかだからです。

制作物の作成において注意すべきこと

###1. なぜ作ったのか説明できるか？
基本的に聞かれるか書く必要があるので、できるだけ自分の実体験に基づくもの、ニーズのあるものを作りましょう。就活ということを意識するなら自己表現の一つでもあります。自分が好きなものや趣味、毎日していることを効率化するようなものを作ってみましょう。また、なぜ作るのかを考えていくと課題解決力も身につきます。反対に、「なんとなく、簡単そうだったから」「Youtube、記事で書いてあったから」というような物はたとえクオリティの高いものでも、あれ？この人は自分で考えることができない人なのかな？という印象を与えかねないので注意です。

###2. なぜその言語、フレームワーク、ライブラリを使うのか？（客観的に）
単純に、「好きだから」「それ以外使ったことがないから」ではなく、客観的に他の言語との違いを軽く出しながら、メリット・デメリット言えるようにしましょう。「募集要項に書いてあったから」というように書きたくなるような気もしますが、一歩踏み越えて客観的に分析してみましょう。

###3. コーディング上のルールでのこだわりはあるか？
特に、個人開発において多いことですが、振り返ったときにコードがどんな動きをしているのか分からないという状態に陥りがちです。

なので基本的にコーディングする時は、関数、変数、定数の命名規則を決めて、コメントによる関数の説明（引数、返り値がどういう値なのか等）を行いましょう。人に見てもらう前提で書いてみると全然違うと思います。


###4. 制作過程を残しているか？
Qiitaもしくは自分のブログ（Note,はてブ,自作ブログ）に制作過程を残しましょう！

自分の知らなかったこと、環境構築や機能の実装において躓いたことなどをTipsみたいな感じでその都度更新していったり、進捗状況の報告に使いましょう。アウトプットすることで、結局インターンの面接やフォームに書かないといけないことを記録に残しておけて、見返すだけで良いのでとてもおススメです！

#過去に参加したインターン、コンテストに関して
ぶっちゃけどんなものでも良いですが、最近だとオンラインの1day,3dayはやっているのでそれに軽く参加しておけばOKです！

正直、始めて実務経験積みたいと思っている人ならそんなもんでしょう。

#最後に
自分個人としては、まだどのインターンにも参加したことがないペーペーで、学生エンジニアと名乗るのもおこがましいぐらいのものではありますが、ここから地道に努力し続けたいと思っています。直近の目標としては、ReactのProjectでいろんなものを作っていくのをQiitaでアウトプットを残していき、それが終わればオリジナルのポートフォリオを作って夏のインターンまでには間に合わせるつもりです！暖かく見守ってもらえると嬉しいです。
大手日系メーカーからITベンチャーに転職して思うこと

#大手日系メーカーからITベンチャーへ
何を思ったかITベンチャーへ転職をして半年が経ちました。(やっていたことはPHP, HTML, JavaScriptなど)
なんとなく半年経って思うことをまとめておこうと思います。

#転職して思うこと
20代の若いうちは貴重な時間なので、もしやりたいことがあるのであれば転職は早いうちにしたほうがいいと思った。
（年次が上がれば上がるほど転職を決断するのは難しかっただろう…）

大手勤務時代は、やりたくないことをしてただただ時間が過ぎていく感じがした。
（まぁ、かと言ってベンチャーがそうじゃないとは言い切れないところがあるが、
大手特有の若手に対して理不尽な感じとか何事にも納得できない感じとかは今はしない）

あと、周りのほとんどの人が仕事に対して情熱がなかった。
なんとかやり過ごそうとする人が多く、きつかった。
何のために仕事をして、何がしたいのか分からなかった。
向上心のある人と働きたいと思った。

<b>＜環境について＞</b>
大手勤務時代は人が多くて人付き合いに疲れて、仕事に集中できなかった。
ベンチャーは人数が少なくていい。
無駄に気を使う必要がない。風通しが良い。
<font color="LightGray">老害っぽい人が少ない、社内政治に巻き込まれない、興味のないゴシップに巻き込まれない（小声）</font>
若手が多いからか気が合うのかも。。

大手、特に日系メーカーだとルールが厳して、それを守らないと酷く怒られる。
中には理解に苦しむものも多く、若手は仕事しづらい場合も多い。
ベンチャーにはそもそもルールが少なく、社員同士で考えながら物事を進めていく感じがあってよい。
なんだがだいぶ自由になれた気がする。

ただ、結局のところ大手でもベンチャーでも被雇用者であるわけで、ある意味では雇い主の奴隷みたいなところはある。
そこらへんのバランスは自分の中でもうまく考えてやっていかないといけないなぁと思うところですね:eyes:

#ITベンチャーに行って得たもの👍
・やる気のある前向きな同僚（メーカー時代は会社に居座ろうとする考えの人が多かった）
・活気のある職場（同上）
・より主体的に行動ができる（他部署や業績不振に影響される不安から解放された、”歯車感”が減った）
・勉強すればするほど仕事にも活きてくるので勉強が楽しい
・プログラミングの技術的な話が聞けて、成長できる
<b>・会社大きくなっていくことを考えるとなんだかロマンがある</b>

#大手メーカーを辞めて失ったもの👎
・年功序列で上がっていく給料
　　→資格取得などして自分で自分の評価を上げていく（修羅の道）
・安定（？）
　　→首を切られてもある程度は生きていけるように知識と技術力を身に着ける（修羅の道）
・良い世間体や社会的信用（？）
　　→ある意味しょうがない
・ローンが組みにくくなった
　　→ローンは組まない
・大企業に勤める友人とは話が合いにくくなったかも
　　→ある意味しょうがない
Google HomeのFamily Bellで終業チャイムを鳴らす

昨今の在宅勤務にメリハリをつけるため、終業時刻にチャイムを鳴らしたいと思いました。
Google Homeでチャイムを鳴らすには、最近追加された[Family Bell](https://support.google.com/assistant/answer/10011399?hl=en)という機能が簡単そうです。
Family Bellは日本ではまだ提供されていないことになっていますが、Androidの言語設定を一時的に英語にしてGoogle Homeアプリを起動すれば、設定できることがわかりました。

# 設定方法
まず設定→システム→言語と入力→言語でEnglish (United States)を第一言語に設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335774/fc020b80-8b61-3b36-f535-6e5e623b6919.png)
次にHomeアプリを起動して、右上のアイコンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335774/709d4881-732b-cd94-114f-622c3558d91a.png)
Assistant settingsを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335774/710d6ab3-1e3a-1a0f-95f2-c007b1b6f1c2.png)
スクロールしてFamily Bellを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335774/73899dc7-d5f0-78d2-2d8d-ef25164898f5.png)
+ Add a bellで設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335774/22c67636-fb77-720e-5758-6d1a70c01489.png)
Bell announcementにチャイムといっしょに読み上げさせるメッセージ(日本語も使えます)、Timeに時刻を入力し、Repeats onで曜日を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335774/b2848daf-2c21-122e-ab2f-51cd8f7473dd.png)
これで設定できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335774/ecb7754f-c469-bfaf-a00f-c53244f79902.png)

設定後に言語を日本語に戻しても、設定したFamily Bellには影響ありません。

# 今後
祝日にまで鳴ってしまうのはご愛敬ですが、[今後の更新で一日間止める機能が追加される](https://blog.google/technology/families/helpful-google-holiday/)とのことで期待しています。
音は万人受けしそうなチャイム音に固定されていて、[“Kids love the sound of the bell,”](https://www.engadget.com/google-family-bell-smart-speaker-display-150006076.html)という[ヘンリーフォード的セリフ](https://ja.wikipedia.org/wiki/%E3%83%98%E3%83%B3%E3%83%AA%E3%83%BC%E3%83%BB%E3%83%95%E3%82%A9%E3%83%BC%E3%83%89#T%E5%9E%8B%E3%83%95%E3%82%A9%E3%83%BC%E3%83%89)もわからないではないですが、更新ついでにカスタマイズできるようになるとうれしいところです。

このほか、もっと高度な設定ができる[Google Assistant Routines](https://blog.google/products/assistant/get-better-handle-work-day-home-google/) (これもまだ英語のみ) というのもあるようです。また調べてみます。

# その後
Family Bell、とうとう[日本語対応](https://blog.google/products/assistant/plan-perfect-weekend-new-google-assistant-features/)しました。言語を切り替えなくても設定できます。
英語設定で保存しておいた日本語のメッセージは読み上げられなくなっていましたが、日本語設定で再度保存すると直りました。
さくっとdocker/nginx

## 概要
さくっとdockerでnginx/Hello Worldしたいときのメモ

## 用途
CloudRunやFargateでのHello Worldなど。。。

## 準備
ディレクトリー構成

```bash
.
├── Dockerfile
├── index.html
└── nginx.conf
```

```Dockerfile:Dockerfile
FROM nginx:latest

COPY ./index.html /usr/share/nginx/html

EXPOSE 80
```

```nginx.conf
server {
    listen       80;
    server_name  hello_nginx;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
```

```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>nginx</title>
</head>
<body>
  <h1>Hello World</h1>
</body>
</html>
```

## コマンド
```bash
# ビルド
$ docker build --tag hello-nginx .
# 確認
$ docker images -a hello-nginx
# 起動
$ docker run -d --name hello-nginx-container -p 80:80 hello-nginx
# 停止
$ docker stop hello-nginx-container
# 削除
$ docker rm hello-nginx-container
```

## 備考
毎回忘れてしまう。。。

サンプル
[https://github.com/koffe0522/docker-nginx](https://github.com/koffe0522/docker-nginx)
ScalaでLocalDateTime.nowを含むメソッドをテストする

# 概要

Scalaで現在時刻を取得するような処理を含むメソッドをテストする方法をいくつか考えてみました。
雑なTipsですm(_ _)m

# 現在時刻を取得する関数をデフォルト引数にする

こちらは現在時刻をデフォルト引数にする方法です。

```scala
// テスト対象のクラス
class DefaultArgTime {
  def getCurrentDayOfMonth(now: LocalDateTime = LocalDateTime.now()): Int =
    now.getDayOfMonth
}

// テストコード
class DefaultArgTimeSpec extends org.specs2.mutable.Specification {
  "#getCurrecntDayOfMonth" should {
    "return" in {
      new DefaultArgTime().getCurrentDayOfMonth(
        LocalDateTime.of(2020, 1, 1, 1, 1)
      ) === 1
    }
  }
}
```

テストコードでは単に現在時刻を引数として指定してやればいいだけなので、お手軽かと思います。個人的には一番よく使う方法です。
ただ、`DefaultArgTime`の呼び出し元からは、自由に`LocalDateTime`型を渡せてしまうので、`getCurrecntDayOfMonth`は意図しない呼び出し方がされる危険性もあるかと思います。

# テスト時に時刻を取得するメソッドをoverrideする

こちらは、現在時刻を取得する処理をprotectedメソッドで定義してやって、テスト時にoverrideするという方法です。

```scala
// テスト対象のクラス
class TraitTime {
  def getCurrentDayOfMonth(): Int = now.getDayOfMonth
  protected def now: LocalDateTime = LocalDateTime.now()
}

// テストコード
class TraitTimeSpec extends org.specs2.mutable.Specification {
  "#getCurrentDayOfMonth" should {
    "return" in {
      val traitTime = new TraitTime() {
        override protected def now: LocalDateTime =
          LocalDateTime.of(2020, 1, 1, 1, 1)
      }
      traitTime.getCurrentDayOfMonth() === 1
    }
  }
}
```

こちらの方法のメリットとしては、(先ほどの現在時刻をデフォルト引数として渡す方法と比較すると)publicメソッドの引数に`now`のような余計な引数を定義する必要がないということが考えられます。
ただ、現在時刻を取得するprotectedメソッドを用意して、テスト時にoverrideするのは若干面倒ですね。

# specs2-mockでspyする

こちらはspecs2-mockの`spy`メソッドを使った方法です。

```scala
// テスト対象のクラス
class SpyTime {
  def getCurrentDayOfMonth(): Int =
    now.getDayOfMonth

  def now: LocalDateTime = LocalDateTime.now()
}

// テストコード
class SpyTimeSpec extends Specification with Mockito {
  "#getCurrentDayOfMonth" should {
    "return" in {
      val spyTime = spy(new SpyTime())
      spyTime.now returns LocalDateTime.of(2020, 1, 1, 1, 1)
      spyTime.getCurrentDayOfMonth() === 1
    }
  }
}
```

`now`を余計にpublicメソッドとして定義する必要があるので、無駄がありますが、場合によってはこの方法もアリかと思います。
Qiita 初心者のMark down備忘録

# 概要
今まではQiitaを見る側だったのですが、今後は自ら得た知識を発信したいと思い
Qiitaを始めたので まず投稿するために Mark down記法などを備忘録として残してみようと思います。

# 記述方法

## ヘッダータグ
「#」を文の前に記載し、スペーズか改行 を挟む事により ヘッダーになる
H1は「#」を1個、H3は「#」を３個個数により変動する

## 黒枠の作成

``` 
（例） カッコは抜く
「 ``` 」
〜 文字 〜 
「 ``` 」 
```

バッククォートを三つ記載し、文の間に囲む

## プログラミングコードの反映
```javascript:言語：ファイル名
~ code ~
```
バッククォートを三つ記載 + 「言語名:ファイル名」
最後にバッククォートを三つで閉じる

## イタリック体 と 強調
（例）「 * 」イタリック体「 * 」 になります
*イタリック体* になります

（例）「 ** 」太字「 ** 」 になります
**太字** になります

## 打ち消し線
（例）「 ~~ 」打ち消し「 ~~ 」 になります
~~打ち消し~~ になります

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

### 埋め込み方法
CodePenにて「Create」から「New Pen」を選択
作成後 「save」 し 「Embed」
「HTML(recommended)」を貼り付け

# 参考文献
[Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)
【CloudFront】CloudFrontとは

## CloudFrontとは
AWSが提供する **CDN（Content Delivery Network）**サービス
ユーザーへの静的および動的なウェブコンテンツ（`.html`、`.css`、`.js`、イメージファイルなど）の配信を高速化する

## CloudFrontの仕組み
1. クライアントがCloudFrontにアクセスすると、DNSサーバーにCloudFrontのドメイン名を問い合わせる
2. DNSサーバーは、CloudFrontのドメイン名をCloudFrontに問い合わせる
3. CloudFrontは、クライアントの位置情報を元に位置情報DBから最適なエッジサーバーのIPアドレスを応答する
4. DNSサーバーからエッジサーバーのIPアドレスの応答を受けたクライアントは、そのエッジサーバーにアクセスし、コンテンツを要求する
5. コンテンツの要求を受けたエッジサーバーは、キャッシュが無ければオリジンサーバーからコンテンツを取得する
6. エッジサーバーが応答としてクライアントにコンテンツを送る

- **オリジンサーバー**：配信するオリジナルのファイルが配置されているサーバー
- **エッジサーバー**：オリジンサーバーからコンテンツをキャッシュし、ユーザーにコンテンツを配信するサーバー
- **ディストリビューション**：ドメインごとに割り当てられるCloudFrontの設定

## 暗号化通信
### クライアント - エッジサーバー間の暗号化
- デフォルトのドメイン名（`cloudfront.net`ドメイン）で利用する場合は、SSL通信（HTTPS）を行うことが可能
- 独自ドメインを利用している場合、X.509PEM形式のSSL証明書をインポートして利用可能

### エッジサーバー - オリジンサーバー間の暗号化
オリジンサーバーの実装方法によって利用出来る暗号化の種類が異なる

**1. S3バケット**
デフォルトでは、S3バケットオリジンサーバーからコンテンツを取得する際の通信は、クライアントからアクセスされたプロトコルで行われる
HTTPS通信を必須にするためには、**Viewer Protocol Policy** の値を **Redirect HTTP to HTTPS** または **HTTPS Only** にする

**2. S3静的ウェブサイトホスティング**
S3静的ウェブサイトホスティングのエンドポイントがHTTPS通信を受け入れていないため、エッジサーバーとの通信でHTTPSを利用出来ない
→ カスタムオリジンとして暗号化を行う必要がある

**3. カスタムオリジン**
CloudFront側で **Origin Protocol Policy** の値を **Redirect HTTP to HTTPS** または **HTTP Only** にし、カスタムオリジンサーバーにSSL/TLS証明書をインストールする

## 署名付きURL
コンテンツへのアクセスを一定期間に限定したい場合、URLの有効期間などを詳細に制御することが出来るもの

- 生成する際に有効期間を選択する
- 限定された目的でコンテンツを配信する場合は短時間を指定する（例：映画レンタルや音楽ダウンロードのオンデマンド配信など）
- 既知のユーザーに配信する場合は長期間を指定する（例：投資家への事業計画の配信、従業員への教育資料の次配信など）

## オリジンサーバーの保護
CloudFrontのオリジンサーバーのURLが外部に漏洩し、オリジンサーバーに直接アクセスされることはセキュリティ的に大きな問題になるため、リスク回避のためにオリジンサーバーを保護するための機能を備えている

オリジンサーバーの実装方法によって保護方法が異なる

**1. S3バケット**
**Origin Access Identity（OAI）** を利用することで、S3バケットへのアクセスをCloudFrontからのみに制限可能

**2. S3静的ウェブサイトホスティング**
CloudFrontからアクセスするためにはS3静的ウェブサイトホスティングをパブリックに設定する必要があるため、外部からのアクセスに注意が必要

**3. カスタムオリジン**
オリジンカスタムヘッダーを利用し、CloudFrontで指定された任意のヘッダーをオリジンサーバー側でチェックすることで、アクセスをCloudFrontからのみに制限可能
※ オリジンサーバーへのアクセス自体はパブリックに設定する必要があるため、オリジンサーバーのURLの外部漏洩に注意が必要
UbuntuでCloudflared使ってDNS over HTTPS

ネットワーク管理者にどんなサイト見てるかバレるのはツライので、DNS over HTTPSの設定をしたときのメモ

# 環境

Ubuntu 18.04

# Cloudflaredのインストール

## cloudflaredのダウンロード

https://developers.cloudflare.com/argo-tunnel/downloads/

## aptでインストール

https://linuxfan.info/post-1881

## systemdを書いて起動

https://qiita.com/onokatio/items/42fb4a2811600680591b

インストール場所は`/usr/local/bin/cloudflared`なので注意

# UbuntuのDNSの設定

https://qiita.com/ajitama/items/b9e517db17755a30886f

あとは適当にプロセス再起動して終了。

# まとめ

きちんと暗号化できてるかは確認してない。
AVPlayerViewControllerのコントロールバーを監視する

# 概要
画面をタップすると表示・非表示が切り替わるコントロールバーを監視します。
あまりニーズがなさそうな情報ですが、つい最近コントロールバーの表示に合わせて自作UIを表示するという要件が実際にありましたのでメモを兼ねて投稿します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110227/eac87929-02fc-abc5-edbd-c96b0f330ece.png" width=100%>

# 開発環境
Xcode 12.1
Swift 5

# AVPlayerViewControllerのレイヤー構成  
AVPlayerViewControllerの動画再生時の画面レイヤーはこのようになっています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110227/a5c03bd4-fa86-75c7-36b2-6bae3996c0ac.png" width=70%>
目的のバーはAVViewの配下にあります。

# 監視対象 
バーの表示・非表示の切り替えはAVViewのisHiddenプロパティではなく親のAVTouchIgnoringViewのisHiddenプロパティで行われているのでこいつを監視します。
**<font color="Red">※Objectice-Cの場合は"isHidden"ではなく"hidden"キーになるようです</font>**

# 実装

```swift:ViewController.swift
    @IBAction func pressedMoviePlayButton() {
        let playerViewController = CustomAVPlayerViewController()
        self.present(playerViewController, animated: true) {
            playerViewController.player?.play()
            playerViewController.find(view: playerViewController.view)
        }
    }
```


```swift:CustomAVPlayerViewController
    private var observers = [NSKeyValueObservation]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let path = Bundle.main.path(forResource: "sample", ofType: "mp4")!
        let url: URL = .init(fileURLWithPath: path)
        let item: AVPlayerItem = .init(url: url)
        let player: AVPlayer = .init(playerItem: item)

        self.player = player
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)

        // 監視を解除する
        observers.forEach {
            $0.invalidate()
        }
        observers.removeAll()
    }
    
    // AVTouchIgnoringViewを探す
    func find(view: UIView) {
        
        let targetViewName = "AVTouchIgnoringView"
        
        view.subviews.forEach {
            
            if !self.observers.isEmpty { return }
            
            // isHiddenプロパティをobserveする
            if String(describing: type(of: $0)).isEqual(targetViewName) {               
                self.observers.append($0.observe(\.isHidden, options: .new, changeHandler: { (_, change) in
                    print("\(change.newValue)")
                }))
                return
            }
            self.find(view: $0)
        }
    }
```
WSLの文字コードの扱いについて

## 概要
WSLを使った場合の文字コードの扱いがわかりにくかったので、試してみた結果をメモとして残します。

## 要点
* WSLのコンソール出力は、UTF-8のみが正しく表示される。(呼び出し側のコマンドウィンドウのコードページに変換されて表示される。)
* リダイレクトした結果にはlocaleが反映される。

## 具体例
* SJISを指定したコンソール出力は文字化けする。

    ```
    >wsl LANG=ja_JP.sjis date
    2020N 11 23 j 13:59:46 JST
    ```
* utf8を指定したコンソール出力は正常。

    ```
    >wsl LANG=ja_JP.utf8 date
    11月 23日 月曜日 14:01:23 JST
    ```
* SJISをリダイレクトした結果はSJIS。

    ```
    >wsl LANG=ja_JP.sjis date >datesj.txt
    >type datesj.txt
    2020年 11月 23日 月曜日 14:03:25 JST
    ```
* WSLを有効化した直後のlocaleは`LANG=C.utf8`ですが、その状態でもUTF-8の日本語がコンソールに出力されます。
* 
    ```
    >wsl LANG=ja_JP.utf8 date >dateu8.txt
    >wsl LANG=C.utf8 cat dateu8.txt
    2020年 11月 23日 月曜日 14:08:34 JST
    ```

## 注意点・補足
  * Windows 10 Home 1909で確認した結果です。
  * デフォルトのLANGの設定は`wsl locale`
で確認できます。
  * WSLのLANGのデフォルトを`sudo update-locale LANG=ja_JP.SJIS`などと変更しても、コンソール出力はUTF-8のままなのでWSLでSJISを処理した結果のコンソール表示が文字化けする現象は回避できません。
windows環境でjavaのprocessbuilderからshell scriptを実行させるための設定



1. Install [Git for windows](https://gitforwindows.org/). (If you have installed [sourcetree](https://ja.atlassian.com/software/sourcetree), this is done.)
2. Add `;.SH` to the end of `PATHTEXT` from Control Panel > System > Advanced > Environment Variables.
3. Add `C:\Program Files\Git\usr\bin;C:\Program Files\Git\mingw64\bin` to the end of `PATH` from Control Panel > System > Advanced > Environment Variables.
【備忘録】ubuntuにてdockerインストールからJupyterLab起動までの流れ

#はじめに
VPSサーバのubuntu内にdokcerをインストールして、jupyterlabの起動までを行います

#前提
今回はAWSのlightsailを用いてubuntu環境を用意しました　
https://qiita.com/s-inoue-git/items/1bcf1a28ed73090c3d86


#目次
1. dockerインストール
2. Dockerfileの転送
3. containerの起動


#1. dockerのインストール

```bash
sudo apt-get update
#sudo apt-get install docker.io #古いバージョンがインストールされてしまう
sudo apt-get install docker-ce
docker --version
#Docker version 19.03.8, build afacb8b7f0
```
バージョン情報が確認できればインストールの成功です！
※docker.ioとdocker-ceの違い
https://qiita.com/nnagashima/items/79887825ce9d7c8b24ab

dockerコマンドのたびにsudoを入力するのが面倒なため、ユーザ(ubuntu)をdocker groupのなかに加えます

```bash
sudo gpasswd -a ubuntu docker
#Adding user ubuntu to group docker
exit
#ログアウトしないとグループの追加が反映されません
```

#2. Dockerfileの転送
```bash
#sftp接続
sftp -i ~/.ssh/Lightsail_ubuntu_20201123.pem ubuntu@3.112.200.82
sftp> put Dockerfile
```
今回は以下チュートリアルで作成したDockerfileを転送しました
https://qiita.com/s-inoue-git/items/2b5c65a1f11a1ba4a38e

#3. containerの起動
docker runのコマンドを実行

```bash
docker run -v $(pwd)/volume:/home/work -p 8888:8888 --name anaconda-env -it anaconda-img
```
あとは、ファイヤウオールの設定を変更して、どこからでもアクセスできるようにすれば、「パブリックIP：ポート番号」でアクセスできるようになります
今回は学習用なのでセキュリティー設定ガバガバです。。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/861809/ca092a90-641d-dda7-cc18-0d7ef3209a81.png)

jupyter-labにアクセスできれば完了です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/861809/c741c9a2-25fa-a7b0-256a-4a289afb25f3.png)
BuildConfigを使ってDockerfileをbuildしてみた

だんだん寒くなって来ましたね。体調にはみなさん気をつけましょうー！

本日は、Openshfit4で利用できるBuildConfigを利用してDocker Buildを行いたいと思います。

CI/CDを検討する際に、Openshfit側でDockerBuildができたら便利だと思う人も少なくないと思います。その際は、BuildConfigを活用してみるのも面白いと思います。

## BuildConfigとは

> ビルド設定は、単一のビルド定義と新規ビルドを作成するタイミングについてのトリガーを記述します。ビルド設定は BuildConfig で定義されます。 BuildConfig は、新規インスタンスを作成するために API サーバーへの POST で使用可能な REST オブジェクトのことです。
ビルド設定または BuildConfig は、ビルドストラテジーと 1 つまたは複数のソースを特徴としています。ストラテジーはプロセスを決定し、ソースは入力内容を提供します。

OpenshiftでBuildの方法を提供してくれる機能となっています。また、Openshfitで以下の方法でBuildを使用することが可能です。

> OpenShift Container Platform ビルドシステムは、ビルド API で指定される選択可能なタイプに基づくビルドストラテジー を幅広くサポートします。利用可能なビルドストラテジーは主に 3 つあります。
- Docker ビルド
- Source-to-Image (S2I) ビルド
- カスタムビルド

今回はDocker ビルドを利用します。

## 今回の実施内容

![buildconfig-ページ1のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675393/ca393b19-f9f9-d302-10e0-2dd3b2a2edcf.png)


1. GithubからDockerfileを取得
2. BuildConfigを利用してBuildを実施
3. ImageStreemを利用して内部レジストリにイメージを保存

### Github確認

以下のような[リポジトリ](https://github.com/ysuke25/wildfly-app-demo.git)を用意しました。リポジトリ内にはDockerfileが含まれています。

![スクリーンショット 2020-11-23 17.29.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675393/b0aa566a-b66a-03cd-0ab8-408d12ca05b1.png)


上記のDockerfileを取得してきてOpenshfit内でBuildを行います。

### BuildConfig確認

```yaml
kind: BuildConfig
apiVersion: build.openshift.io/v1
metadata:
  name: java-test
  labels:
    build: java-test
spec:
  output:
    to:
      kind: ImageStreamTag
      name: 'java-test:latest'
  resources: {}
  strategy:
    type: Docker
    dockerStrategy:
        dockerfilePath: ./Dockerfile
  source:
    type: Git
    git:
      uri: 'https://github.com/ysuke25/wildfly-app-demo.git'
      ref: master
```

ポイント

- 「strategy」にDockerを指定します
- 「strategy.dockerStrategy」にDockerfileのPathを入力します
- 「source」に取得もとのGitを指定します。もちろん、ブランチの指定も可能です。

上記のようなBuildConfigを作成します。上記のYamlをocコマンドを利用してOpenshfitへ適用します。

```yaml
oc create -f test-java-buildconfig.yaml
```

### 実施コマンド

上記の準備ができたら以下のコマンドでbuildをスタートすることが可能です。

```yaml
oc start-build java-test
```

## まとめ

簡単でしたがBuildConfigを利用してDocker Buildを行う方法を記載しました。

ローカルで動かしたDockerfileをそのままOpenshfitでも利用した場合やデプロイを簡単にした場合に有用な機能だと思います。今回は紹介しませんでしたがwebhookをトリガーと設定することも可能ですので、commitしたら自動的にBuildが走る構成も取ることができます。

また、Buildの方法をOpenshfitにまとめることでマルチクラウド展開なども用意になるかもしれません。

ぜひBuildConfigを利用してみてください。

## 参考

[https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.6/html/builds/understanding-image-builds](https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.6/html/builds/understanding-image-builds)
GitHubのデフォルトブランチ名がmainになってからプッシュできず詰まっていたのを解決できた件

# はじめに
c++で作品を作っていてGitHubにコミットしてプッシュしようとしたときのことでした

今までは、デフォルトブランチ名がmasterだったときはらくらくできていたが、デフォルトブランチ名がmainブランチに変更されてから
この謎は始まったのであった。

自分が忘れないようにメモとして書いているものだが、もし同じように困っている人の役に立てたら幸いです。

## どういう謎だよ

まずいつも通りにGitHubで新しいリポジトリを作成して
ターミナル下記を入力

git init 
git remote add origin [新しいリポジトリを作成したURL]
git add .
git commit -m "first commit"

//ここで、pushなりgit pullなりで問題が起こる

git push origin main
git
 * branch            main       -> FETCH_HEAD
fatal: refusing to merge unrelated histories

とか
error: src refspec main does not match any.
error: failed to push some refs to 'origin'

とか

git pullで

fatal: 'origin' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists

他にも、masterでプッシュしてしまうと、mainブランチとmasterができてしまったりして
2つブランチができてしまうことがありました

もしmainブランチとmasterブランチを作りたいのであればいいのですがそうでない場合...
###うわぁぁぁぁ!!!初見殺しだァァァ!

##何が起きているのか、解決方法を探す

### git clone でできているリポジトリから解決した方法

git branchで現在いるブランチを確認

git branch
* master

ん?masterになっている。
そういえば、git cloneで取ってきていないからか。これじゃあできないわけだ。

GitHubで作ったリポジトリをクローンする

git clone [リモート リポジトリのurl]

それで
git branch
* main

これでgit pushできるはず!

### git cloneを使わないやつで解決した方法

git init
git remote add origin [リモートリポジトリのURL]
git add [ファイル]
git commit -m "ここにコメントを入れる"
git branch

もし* masterと表示になっていたら
git fetch
git checkout main
git push

#解決方法のまとめ

GitHubのデフォルトブランチ名がmainブランチに変わってから、
新しくリポジトリを作成したときにpushできない問題が起きたら、
先にリポジトリを作成してgit clone で取ってくるか、
上記で書いたgit cloneを使わない方法で解決できた。

#謝辞 + IT勉強会にどんどん参加しようぜ!!

今回のGitHubに関して行き詰まっていたのを解決できたのは IT勉強会CoKonPileの参加者様と関係者の協力で解決できました!
CoKonPileの皆様、ヒントや解決方法を一緒に考えていただき、ありがとうございました!

IT勉強会、どんどん参加しよう!!!!!!!!
【Linux】echoコマンドの使用方法

# はじめ
Linuxコマンドの一つのechoコマンドについて、自分がよく使用している方法をアウトプットします。
※全ての使用方法は網羅できておりませんので、ご了承下さい。

# echoコマンドとは？

このようなことができるコマンドになります。

- 画面に文字列の表示
- コマンドの実行結果の表示
- 文字列をファイルに出力
- 文字列をファイルに追記

# echoコマンドの使用方法(例)

## 文字列の表示

指定の文字列を表示します。

```bash:コマンド
echo "文字列"
```

### コマンド実行例

```bash:実行例
[root@tspweb01 test]# echo aaaaa
aaaaa
```

## コマンドの実行結果の表示

コマンドの実行結果を表示します。

```bash:コマンド
echo $?
```
- コマンドの実行結果

|  実行結果  |  内容  |
| ---- | ---- |
|  0  |  True(コマンドの実行が成功)  |
|  1  |  False(コマンドの実行が失敗)  |
|  127  |  コマンドが見つからない |

### コマンド実行例
- True(成功)

```bash:実行例(True)
[root@tspweb01 test]# true
[root@tspweb01 test]# echo $?
0
```
- False(失敗)

```bash:実行例(False)
[root@tspweb01 test]# false
[root@tspweb01 test]# echo $?
1
```

- コマンドが見つからない

```bash:実行例(コマンドが見つからない)
[root@tspweb01 test]# wh
-bash: wh: コマンドが見つかりません
[root@tspweb01 test]# echo $?
127
[root@tspweb01 test]#
```

## 文字列をファイルに出力

指定の文字列をファイルに出力します。

```bash:コマンド
echo "文字列" > ファイル名
```

### コマンド実行例

```bash:実行例
[root@tspweb01 test]# echo "testtest" > test.txt
[root@tspweb01 test]# cat test.txt
testtest
[root@tspweb01 test]#
```

## 文字列をファイルに追記

指定の文字列をファイルに追記します。

```bash:コマンド
echo "文字列" >> ファイル名
```

### コマンド実行例

```実行例
[root@tspweb01 test]# cat test.txt
testtest
[root@tspweb01 test]# echo "testtest" >> test.txt
[root@tspweb01 test]#
[root@tspweb01 test]# cat test.txt
testtest
testtest
[root@tspweb01 test]#
```

### 注意

実作業の際には、`>`と`>>`を間違えないようにお気をつけ下さい。
(意味が全然違います。)

- `>` : ファイル全体の上書き
- `>>` : ファイルの最終行に1文を追記

重要なファイルの作業を実施する際は、必ず`cp`コマンドにてバックアップを取得しましょう。

# まとめ

echoコマンドでは、このようなことができます。

- 画面に文字列の表示
- コマンドの実行結果の表示
- 文字列をファイルに出力
- 文字列をファイルに追記

bashスクリプトに応用してみては、如何でしょうか？

# 参考
[echoコマンドの詳細まとめました【Linuxコマンド集】](https://eng-entrance.com/linux-command-echo)
[意外と便利なコマンドtrue/false](https://news.mynavi.jp/itsearch/article/hardware/3104)
UniRxの「Debug」オペレータが便利

# 「Debug」オペレータ

UniRxには「`Debug`」という便利なオペレータが存在します。
これは「Observable上で起きたすべてのイベントをログに出力する」というオペレータです。

* どの値が発行されたか
* 何の例外が起きたか
* どのタイミングで`Subscribe()`されたか
* どのタイミングで購読が中断されたか

などをこのオペレータ1つですべて知ることができます。

## 定義

定義としてはこうなってます。

```cs
// copy from https://github.com/neuecc/UniRx/blob/master/Assets/Plugins/UniRx/Scripts/UnityEngineBridge/Diagnostics/ObservableDebugExtensions.cs
public static IObservable<T> Debug<T>(this IObservable<T> source, string label = null)
{
#if DEBUG
    var l = (label == null) ? "" : "[" + label + "]";
    return source.Materialize()
        .Do(x => UnityEngine.Debug.Log(l + x.ToString()))
        .Dematerialize()
        .DoOnCancel(() => UnityEngine.Debug.Log(l + "OnCancel"))
        .DoOnSubscribe(() => UnityEngine.Debug.Log(l + "OnSubscribe"));

#else
    return source;
#endif
}

public static IObservable<T> Debug<T>(this IObservable<T> source, UniRx.Diagnostics.Logger logger)
{
#if DEBUG
    return source.Materialize()
        .Do(x => logger.Debug(x.ToString()))
        .Dematerialize()
        .DoOnCancel(() => logger.Debug("OnCancel"))
        .DoOnSubscribe(() => logger.Debug("OnSubscribe"));

#else
    return source;
#endif
}

```

`Do()` + `DoOnCancel()` + `DoOnSubscribe()` ということで、**Observable上で起きたすべてのイベント**をログへ出力できるようになっています。
しかもラベルを付与したり、`UniRx.Diagnostics.Logger`を利用することもできます。

ちなみに`UniRx.Diagnostics`名前空間に定義されているのでこちらへのusingを忘れずに。

## 使い方

`Observable`の途中に`Debug()`を挟むだけです。

```cs
using UniRx;
using UniRx.Diagnostics;
using UnityEngine;

public sealed class DebugSample : MonoBehaviour
{
    private readonly Subject<int> _subject = new Subject<int>();

    private void Start()
    {
        _subject
            .Debug("Debugサンプル") // Debugオペレータ
            .Subscribe()
            .AddTo(this);

        _subject.OnNext(1);
        _subject.OnNext(2);
        _subject.OnNext(3);
        
        Destroy(gameObject);
    }

    private void OnDestroy()
    {
        _subject.Dispose();
    }
}
```

```text:実行結果
[Debugサンプル]OnSubscribe
[Debugサンプル]OnNext(1)
[Debugサンプル]OnNext(2)
[Debugサンプル]OnNext(3)
[Debugサンプル]OnCancel
```

### ログの読み方

|メッセージ|意味|
|:--|:--|
|OnSubscribe|`Observable`が`Subscribe()`された|
|OnNext(Value)|`Value`という値の`OnNext`メッセージが発行された|
|OnCompleted|`OnCompleted`メッセージが発行された|
|OnError(ex)|`ex`という型の`OnError`メッセージが発行された|
|OnCancel|`Subscribe()`の`Dispose()`が実行された|

# 最後に

**UniRxについて学べる技術書が出版されました。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47146/6b8033a6-679d-45f7-b6ad-30b37ab94cee.png)

- [UniRx/UniTask完全理解](https://asciidwango.jp/post/631460628113014785/unirxunitask%E5%AE%8C%E5%85%A8%E7%90%86%E8%A7%A3)

（ちなみにこの`Debug`オペレータについて、本の中で解説するのを忘れています。本当にすいません…。）
SORACOM Napterを利用してリモート環境からIoT端末へアクセス(SSH/RDP)をする

## 概要
* SORACOM Napterを利用してリモート環境からIoT端末へアクセスをする。
    * Remote PC(or InterNet) → SORACOM Napter → IoT Device
* これを利用してリモートでIoT端末の操作ができる。

## 事前準備
* SORACOM SIMが利用できること、まだの場合は[こちら](https://qiita.com/muneki/items/b7da92ad5ced9708e1a1)を参照

## 手順
1. [SORACOMのユーザコンソール](https://console.soracom.io/#)へログインする
2. オンデマンドリモートアクセスの設定をする。
    * 「SIM管理」 → 対象のSIMを選択 → 「操作」 → 「オンデマンドリモートアクセス」
3. 設定を入力し「OK」

    | 項目 | 値 | 備考 |
    | ---- | --- | --- |
    | TLS | 無効 | SSHやRDPの場合は元々暗号化済みのため不要 |
    | デバイス側ポート | 任意 | 例)SSHは22,RDPは3389を入力 |
    | アクセス可能時間 | 任意 | この時間を過ぎると自動で設定が解除される |
    | アクセス元IPレンジ | ●.●.●.●/32 | 接続元のIPアドレス |

4. オンデマンドリモートアクセスの設定をするとアクセス先の情報が表示される。
    * 専用で払い出されたグローバルIPアドレスとポートを経由してアクセスが可能になる。

## 公式ドキュメント
* [SORACOM Napter ](https://dev.soracom.io/jp/napter/what-is-napter/)
* [SORACOM Napter のご利用料金](https://soracom.jp/services/napter/price/)
   * 1アカウントにつき1SIM分は無料利用可能とこと。
Docker コンテナで x11 アプリを動かす (コンテナからのネットワークアクセス対応)

# Docker コンテナで x11 アプリを動かす (コンテナからのネットワークアクセス対応)

[Docker コンテナ上で動く X11 アプリケーションのウィンドウをディスプレイに表示させる](https://qiita.com/hoto17296/items/7c1ba10c1575c6c38105) という記事で xeyes を動作させることができたのですが、


以下のように `--net host` を指定しています。

```
$ docker run --rm -it \
    --net host \
    -e DISPLAY=$DISPLAY \
    -v $HOME/.Xauthority:/root/.Xauthority \
    xeyes
```

`--net host` は docker host と docker container の間だけで通信できるネットワークを利用します。

なので、 docker container からインターネットに接続したい場合には使用することができません。

この記事では、container からネットワークにアクセスできてかつ X11 アプリを使えるようにします。


## Dockerfile

[オリジナル](https://qiita.com/hoto17296/items/7c1ba10c1575c6c38105) との違い

* `xeyes` を直接 CMD で起動していましたが、ネットワークアクセスを試すために `/bin/bash` を起動します。
* `bash` を image にインストールします。(ここはテスト目的なので本質とは関係ないです)

`conf/Dockerfile` の中身

```
FROM alpine

RUN apk --no-cache add bash xeyes

CMD ["/bin/bash"]
```

## docker image のビルド

```
docker build -t xeyes conf
```

## local ユーザーのみ X の接続を許可する

```
xhost +local:
```

## container の起動

[オリジナル](https://qiita.com/hoto17296/items/7c1ba10c1575c6c38105) との違い

* 環境変数 `DISPLAY` に `unix${DISPLAY}` を渡す。
* `/tmp/.X11-unix` を `-v` でホストと共有する。

```
docker run --rm -it \
    -e DISPLAY=unix${DISPLAY} \
    -v /tmp/.X11-unix:/tmp/.X11-unix \
    -v $HOME/.Xauthority:/root/.Xauthority \
    xeyes
```

## コンテナからのネットワークアクセス確認

```
bash-5.0# ping www.example.com
PING www.example.com (93.184.216.34): 56 data bytes
64 bytes from 93.184.216.34: seq=0 ttl=51 time=149.040 ms
64 bytes from 93.184.216.34: seq=1 ttl=51 time=172.391 ms
64 bytes from 93.184.216.34: seq=2 ttl=51 time=195.793 ms
^C
--- www.example.com ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 149.040/172.408/195.793 ms
```

## コンテナから x11 アプリを起動

```
bash-5.0# xeyes
```

### エラーメッセージ

`xhost +local:` を実施していない場合、以下のエラーになります。

```
bash-5.0# xeyes 
No protocol specified
Error: Can't open display: unix:0
```

## GitHub

GitHub にこの記事で書いた Dockerfile やスクリプトなどを置いています。

https://github.com/m-tmatma/xeyes-docker
dockerメモ

# はじめに
この記事は、自分がdockerでよく利用したコマンドを自分用に書き残したものです。


# 環境
- macOS Catalina 10.15.7
- Docker version 19.03.13


## Dockerイメージの取得
DockerHub等からimageを取得する。

```docker
docker pull ubuntu
```
## イメージの確認
取得したイメージをimagesで取得。

```docker
docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu-python       latest              91d4b5ba1c2d        4 weeks ago         605MB
ubuntu              18.04               56def654ec22        8 weeks ago         63.2MB
```
上記の場合、ubuntuとubuntu-pythonというimageがある。

## imageの削除

```docker
docker rmi [imageID or image名]
```
ubuntu-pythonを消す場合、

```docker
docker rmi ubuntu-python
docker rmi 91d4b5ba1c2d
docker rmi 9
```
で消すことができる。
IDは前方一致のため、最後のコマンドでは9から始まるimageIDを持つimageがすべて削除される。

## Dockerfileからimageを作成

```docker
docker build -t [image名]:[TAG名] [Dockerfileのディレクトリ] 
```
## コンテナ（停止した）からimageを作成

```docker
docker commit [コンテナ名 or コンテナID] [image名]:[TAG名]
```

## コンテナの起動
作成したimageからコンテナを起動する。

```docker
docker run -itd --name [コンテナ名 or コンテナID] [image名]
```
> よく利用するオプションについて
>
> --name [コンテナ名]は省略できますがランダムで名前がつけられます。
> -it 標準入出力をコンテナに結びつける(キー入力する場合)。
> -d コンテナをバックグランドで実行
> -p [ホストのポート]:[コンテナのポート]

コンテナ作成時にボリュームをマウントしたい場合、
(以下例はカレントディレクトリをマウント)

```docker
docker run --name myubuntu -itd \
--mount type=volume,src=$(pwd),dst=/vol ubuntu /bin/bash
```
> (-v [ホストDIRの絶対パス]:[コンテナの絶対パス])
>上記(-v)の場合、volumeかbindのどちらでマウントされているのかわからない。
> ホストとコンテナ間でデータを同期させたいとき(非推奨)は、 
> --mount type=bind,src=<パス>,dst=<パス>
>コンテナにボリュームをマウントしたいときは、 
>--mount type=volume,src=<ボリューム名>,dst=<パス>

##　コンテナの確認

```docker
docker ps 
```
>docker ps -aで停止しているものもすべて表示
>docker ps -aqで停止しているコンテナも含めコンテナIDを表示

## コンテナの停止、再スタート、削除

```docker 
docker stop [コンテナ名 or コンテナID]　 #停止
docker start [コンテナ名 or コンテナID]  #再スタート
docker rm [コンテナ名 or コンテナID]     #削除
```
コンテナをすべて削除したい場合、

```docker 
docker rm $(docker ps -aq)
```

## コンテナにログイン
作成したコンテナにログインしてshellを起動する。

```docker
docker exec -it [コンテナ名 or コンテナID] bash
```
## コンテナから抜け出す
Ctrl + D　または exit と入力すると抜け出せます。

```docker
root@b789a85f6d39:/# exit
```

## ログの出力
dockerアプリで出たログを出力して見る。

```docker
docker logs [コンテナ名 or コンテナID]
```

## コンテナ情報の確認
指定コンテナに関する全ての情報を取得。

```docker
docker inspect [コンテナ名 or コンテナID]
```
基本的には一部の情報しかいらないので、
--format optionでピンポイントで出力する。

```docker
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' [コンテナ名 or コンテナID]
## コンテナに割り振られているIPアドレスの取得
```
>--format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 
でNetworkSettings.Networks内のIPAddressを取得している。
FizzBuzzの出力結果

# 1〜100までを出力した場合

答え合わせ用を想定しています。

- 3の倍数では `Fizz`
- 5の倍数では `Buzz`
- 3の倍数、かつ5の倍数（つまり15の倍数）では `FizzBuzz`

1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz
31
32
Fizz
34
Buzz
Fizz
37
38
Fizz
Buzz
41
Fizz
43
44
FizzBuzz
46
47
Fizz
49
Buzz
Fizz
52
53
Fizz
Buzz
56
Fizz
58
59
FizzBuzz
61
62
Fizz
64
Buzz
Fizz
67
68
Fizz
Buzz
71
Fizz
73
74
FizzBuzz
76
77
Fizz
79
Buzz
Fizz
82
83
Fizz
Buzz
86
Fizz
88
89
FizzBuzz
91
92
Fizz
94
Buzz
Fizz
97
98
Fizz
Buzz
TextGANでAssertion `srcIndex < srcSelectDimSize` failed.がでた場合

TextGANのgithub
https://github.com/williamSYSU/TextGAN-PyTorch
独自のデータセットに関してSeqGANを適用したら下記のエラー。

```terminal
...
Assertion 'srcIndex < srcSelectDimSize' failed
...
...
RuntimeError: CUDA error: CUBLAS_STATUS_ALLOC_FAILED when calling `cublasCreate(handle)`
```
gpuでの実行をやめてcpuで実行したら以下のエラー。

```terminal
IndexError: index out of range in self
```

<解決方法>
/TextGAN-PyTorch/dataset/
にあるXX_iw.dictとXX_wi.txtを削除。
(XXはデータセットの名前(ex..image_coco.txt->image_coco_wi_dict.txt))
Figmaで角を丸くする方法(border-radius)

Figmaで表を作ったときに、**四隅の角の丸みを角ごとに変えたい**と思ったときに
どうやってやるんだっけとなったので、備忘録として残しておきます。

こちらを読めば、こんな感じで**角ごとに丸みを変えることができる**ようになります。

![83259fff6716b6f4c7fecf4bce14be65.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592040/8523a1bf-a6ea-0337-b87d-626f8d82978e.png)

## STEP1
 まずは、適当に図形を作ります。
![9f3677a538d89182a58bf73cbd025449.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592040/bd75701a-96b6-fb9e-5746-ec5f724310b4.png)


## STEP2
ここの数値を調整すると全体の角が丸くなります。
![5f5ff3a08a7517390ef05f37fed2a20b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592040/32a5752a-3b4c-d8ac-5339-5f83247bf791.png)

# STEP3
四隅を個別に調整するためには、横の四角っぽいやつをクリックします。
![d7bb7e19673a341d0bd2aeb41f4137b1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592040/a27df90f-0e32-2b4d-650b-fca1eba49434.png)

## STEP4 
そして、四隅の丸み具合を調整できるようになりました。
順番は
左上（200）→右上(20) → 右下(500) → 左下(0)
です。
![578dd68708587266eecdd870ca99080f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592040/7501497e-6d48-9878-7145-895edbb4cede.png)
REST API開発での仕様書生成、コード生成（Python編）

# 内容
* REST API開発の効率化のため、ツールを使って仕様書生成、コード生成、スタイルチェック、自動フォーマットをすると思います。
* Pythonを対象に、私が便利だと思っているツールをまとめます。
* 開発エディターは、VSCodeです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100414/f7e7b238-fc10-c969-bf46-97b9ae2c474f.png)


# REST API関連
* OpenAPI仕様をyaml形式で書いて、REST APIのインターフェース仕様書生成とコード生成をします。
    * インターフェース仕様書
    * サーバー側のスタブ（コントローラー、HTTPリクエスト・レスポンスのモデル）
    * フロント側のREST API用のクライアントSDK 
* サーバースタブの生成は非常に便利です。
    * PythonでFlaskのコードを生成すると、OpenAPI仕様をベースにHTTPリクエストの制御をするFlaskアプリ（connexionというライブラリでラップされている）のコントローラーまでできます。
    * OpenAPI仕様を基に、HTTPリクエストのバリデーションをしてくれるので、自分でバリデーションのコードを開発する必要がありません。
    * また、クライアント側に対しては、サーバー側が完成するまでのスタブサーバーとして利用することもできます。
* クライアントSDKも便利です。自分でエンドポイントやリクエストを作っていくより簡単です。
* 使用するツールは下記です。

|用途|ツール名|説明|リンク|
|:---|:---|:---|:---|
|OpenAPI仕様の編集|VSCode + OpenAPI Editor(拡張機能)|VSCode上で、OpenAPI仕様を書きます。左サイドに、パスやスキーマの目次ができるのが便利です。|https://marketplace.visualstudio.com/items?itemName=42Crunch.vscode-openapi |
|OpenAPI仕様の参照|VSCode + Swagger Viewer(拡張機能)|OpenAPI仕様をドキュメントとして参照することができます。|https://marketplace.visualstudio.com/items?itemName=Arjun.swagger-viewer|
|OpenAPI仕様のバリデーション|openapi-generator|CLIでOpenAPI仕様のバリデーションができます。<br>OpenAPI Editorでは検出しきれないエラーも検出できます。ただ、これでも検出しきれないバグはあります。例えば、スキーマでrequiredに設定した項目が、実はプロパティ定義されていないとか。こういったものは、サーバースタブをコード生成して、起動してみるとエラーするので気づきます。|https://github.com/OpenAPITools/openapi-generator|
|コード生成|openapi-generator|OpenAPI仕様（yamlファイル）からコード生成（サーバースタブ、クライアントSDK）できます。|同上|
|ドキュメント生成|openapi-genrator|REST APIインターフェース仕様書をHTML形式で生成します。|同上|

# Python関連
* 開発したコードから、クラス図、クラス仕様書を生成します。
    * クラス仕様書を生成する前提として、docstringを書く必要があります。
* コード開発では、Linter（スタイルチェック）とFormatter（自動フォーマット）も便利です。
* 使用するツールは下記です。

|用途|ツール名|説明|リンク|
|:---|:---|:---|:---|
クラス図の生成|Pyreverse|クラス図生成|https://pypi.org/project/pylint/|
クラス仕様書の生成|Sphinx|クラス仕様書生成|https://www.sphinx-doc.org/ja/master/<br>[Sphinxインストール手順](https://www.sphinx-doc.org/ja/master/usage/installation.html)|
docstringの記載補助| VSCode + Python Docstring Generator | コードからdocstringの雛形を生成することができます。例えば、メソッドの場合は、サマリー行、引数の名前、型、戻り値の型がコードから生成されるので、自分では説明を書くだけでOKです。| https://marketplace.visualstudio.com/items?itemName=njpwerner.autodocstring |
|Pythonのスタイルチェック|VSCode + flake8|pep8に準拠しているかチェックして結果表示してくれます。|https://pypi.org/project/flake8/|
|Pythonの自動フォーマット|VSCode + autopep8|ある程度、自動でpep8に準拠するようにコードを自動修正してくれます。例えば、クラス定義の上に2行空白行を開けるとか、引数に半角スペースを入れるとか。|https://pypi.org/project/autopep8/|


# DB関連
* コード開発では多くのケースでDBを利用します。
* GUIで、ER図、テーブル定義、DDL生成ができる便利なツールがあるので紹介します。
* EclipseのプラグインのERMasterです。
* ER図をGUIで書けば、そこからExcelのテーブル仕様書、DDL文を生成することができます。
* 概念データモデルはパワポやdraw.ioで書いて、論理データモデルからERMasterで書くと良いと思います。

|用途|ツール名|説明|リンク|
|:---|:---|:---|:---|
ER図、テーブル定義、DDL生成|ERMaster|Eclipseのプラグインで、GUIで、ER図、テーブル定義、DDL生成ができます。|http://ermaster.sourceforge.net/index_ja.html|
gitの基本コマンド

gitを使うときのメモ

### clone
```
git clone https://github.com/...
```

### add
```
git add .
```

### pull
```
git pull origin ブランチ名
```

### commit
```
git commit -m comment
```

### push
```
git push origin 
```

## おまけ
### フォルダ削除
```
rm -r ディレクトリ名
```
【 Python】GoogleColaboratoryの最大の弱点・デメリット【初心者向き】

GoogleColaboratoryとは、という話は割愛しますが、普段GoogleColaboratoryを使用していて、「これは・・・」というデメリットがあったので、それを説明します。

主にデメリットは2つあります。

###1.定期実行ができない
通称「12時間/90分ルール」ですね。

連続使用12時間という制約はそんな重たい操作をするわけではないので、そこまで困ることはないのですが、やはり定期実行できないというのはデメリットだなと感じました。

###GUIが使用できない
個人的にこれが一番大きなデメリットでした。

例えばブラウザ操作の自動実行で、特にJavaScriptが使用されているサイトのスクレイピングの時に困ってました。
もちろん要素が指定できるのなら問題ないのですが、canvas要素をダウンロードする時とかはどうしてもGUIを使用します。

これが使用できないというのが個人的にデメリットだと感じました。
###結局、ローカルで環境構築した方が良い
結局のところ、ローカルで環境構築した方が良いです。
もちろん環境構築でエラーが多発するとイライラするので・・・
入り口としてGoogleColaboratoryは良いと思いますが、できることが増えてプログラミングにも慣れた勉強も兼ねてローカルでの環境構築はやった方がいいですね。

あとはGoogleColaboratoryはスペックが非常に良いので、大量データの取り扱いは向いてますね。
ブラウザ操作とかは、できるけどやっぱりローカル環境の方が良いと思いました。

ある程度プログラミングに慣れた今は環境構築もそんなに苦ではないです。
やはり何も知らないところでdockerやらAnacondaなどと言われてもわかりませんからね。
いきなり真っ赤なエラー文言見せつけられたら嫌になりますし、しかも英語だし。

そういった点に耐性ついてから環境構築でも良いのかなと思います。