OmniAICreator/Qiita-1.07M huggingface dataset:
OpenCVを用いる画像の基本的な操作方法

#画像をx軸またはy軸に移動させる
■コード

```translate.py
import cv2
import numpy as np

#read image
img = cv2.imread("gotg_rocket.jpg")

#shift image to left(negative value) or right(positive value)
tx = 100

#shift image to up(negative value) or down(positive value)
ty = 100

#transformation matrix(need to be float value)
M = np.float32([[1,0,tx],[0,1,ty]])

#width and height of image
h = img.shape[0]
w = img.shape[1]

#translate image
translated = cv2.warpAffine(img,M,(w,h))

#show image
cv2.imshow("Original",img)
cv2.imshow("Translated", translated)
cv2.waitKey(0)
```

■実行結果
・元の画像
![original.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797320/7b3ed689-7879-9f79-3792-6532302664be.png)
・変換した画像
![translated.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797320/59693c0d-a1fa-6a1b-9717-3a67d608b8c2.png)


#画像を回転させる
■コード

```rotate.py
import cv2

#read image
img = cv2.imread("gotg_rocket.jpg")

#width and height of image
h = img.shape[0]
w = img.shape[1]

#get center of image
center = (w//2,h//2)

#rotation angle(in degree)
angle = 40

#scale rate(if don't want to change the size  of image, set to 1)
scale = 1.0

#transformation matrix
M = cv2.getRotationMatrix2D(center,angle,scale)

#rotate image
rotated = cv2.warpAffine(img,M,(w,h))

#show image
cv2.imshow("Original",img)
cv2.imshow("Rotated", rotated)
cv2.waitKey(0)
```

■実行結果
・元の画像
![original.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797320/06d33e8e-b93a-9586-3c19-e8d402b1404b.png)

・変換した画像
![rotated.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797320/ebdb5095-95a1-c2ea-2213-f80f9e039c5a.png)


#画像のサイズを変更させる
■コード

```resize.py
import cv2

#read image
img = cv2.imread("gotg_rocket.jpg")

#resize width
w = 300

#resize height(keeping the scale rate)
h = int(300/img.shape[1]*img.shape[0])

#resize image
resized = cv2.resize(img,(w,h))

#show image
cv2.imshow("Original",img)
cv2.imshow("Resized", resized)
cv2.waitKey(0)
```

■実行結果
・元の画像
![original.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797320/7c18df2e-902f-6296-4548-7558f6a512a6.png)

・変換した画像
![resized.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797320/dd7e50cb-8fbb-8dc2-27af-9740a1a089a7.png)


#画像を反転させる
■コード

```flip.py
import cv2

#read image
img = cv2.imread("gotg_rocket.jpg")

#flip image (-1:vertical & horizontal, 0: vertically, 1:horizontal)
flipped = cv2.flip(img,0)

#show image
cv2.imshow("Original",img)
cv2.imshow("Flipped", flipped)
cv2.waitKey(0)
```

■実行結果
・元の画像
![original.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797320/4e808ff3-db13-d722-4e18-f53f3ddec7da.png)

・変換した画像
![flipped.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797320/185cd4ad-e4f5-1004-0ec5-920c3530355a.png)
jQueryのセレクター

セレクターの指定の仕方とかの基本
jQueryやるなら、ここの指定の仕方をしっかりと抑えてDOMのイメージができないと、
とんでもない指定で不要なタグに対してもイベントや設定を行ってしまう可能性がある。

```javascript
// ID指定(IDは1HTML内で必ず一意のやつ)
$("#id").click(function(){
  console.log($(this).val())
});

// Class指定(1HTML内で何回でも出現していいやつ)
$(".class").click(function(){
  console.log($(this).length)
});

// タグ指定
$("div").text("DIVの中にテキスト挿入");

// 入れ子(id="contents" の中にあるspanタグ全部のテキストを設定)
$("#contents span").text("span要素に適応")
```
Auth0 Errno::ECONNREFUSED (Failed to open TCP connection to :443

Auth0のチュートリアルにしたがって作成していたところタイトルのエラーが発生

サンプルのリポからcloneしても同じ内容だったので、おそらく設定などの不備があると思い調査

調査したところ以前作成したnestjsの設定と全く異なる部分がなかったので、とりあえずpryを入れて一つずつみて行った結果、envからデータを上手く撮れていないことが判明

```
def self.jwks_hash
    binding.pry
    # TODO, ここでエラー発生
    jwks_raw = Net::HTTP.get URI("https://#{ENV['AUTH0_DOMAIN']}/.well-known/jwks.json")
    jwks_keys = Array(JSON.parse(jwks_raw)['keys'])
    Hash[
        jwks_keys
            .map do |k|
          [
              k['kid'],
              OpenSSL::X509::Certificate.new(
                  Base64.decode64(k['x5c'].first)
              ).public_key
          ]
        end
    ]
  end
```


どうやらこの部分のenvがnilになっていて

```
jwks_raw = Net::HTTP.get URI("https://#{ENV['AUTH0_DOMAIN']}/.well-known/jwks.json")
```

、出力すると


```
ENV['AUTH0_DOMAIN']
=> nil
```


となっていました。

なのでdotenvの設定を修正
→gemがdotenv-railsではなくdotenvだったので変更したところ

```
"https://#{ENV['AUTH0_DOMAIN']}/.well-known/jwks.json"
=> 
"https://my-domain.auth0.com/.well-known/jwks.json"
```

このように表示されました。


そして、DOMAINが通ったところで問題なくリクエストが通りましt！！！

## 参考記事

[Auth0 Ruby on Rails TCP Error](https://stackoverflow.com/questions/48796306/auth0-ruby-on-rails-tcp-error)
[Rails5にAuth0を利用して認証機構を最速で追加して、爆速開発環境を構築していくぜ！](https://qiita.com/gaku3601/items/f4f17a8d2aea73825e92)
[Building Secure APIs with Rails 6 and Auth0](https://auth0.com/blog/building-secure-apis-with-rails-6-and-auth0/)
[Errno::ECONNREFUSED (Failed to open TCP connection to :80 - Authenticated requests fails](https://stackoverflow.com/questions/65549386/errnoeconnrefused-failed-to-open-tcp-connection-to-80-authenticated-reques)
[RSpec] binding.pry 単体テストコードの基本用法

# はじめに
メモ用に記録しています。
特に何かを参考したわけではありませんので、間違いはご指摘いただけると幸いです。

テストコード実行コマンド
**bundle exec rspec テストするファイル名** ←# spec/から記述


```spec/factories/orders.rb
FactoryBot.define do
  factory :order do
    price { 3000 }
  end
end
```

```spec/models/order_spec.rb
require 'rails_helper'

RSpec.describe Order, type: :model do
  before do
    @order = FactoryBot.build(:order)
  end

  describe '購入情報のデータの保存' do
    context '成功' do
      it "priceがあれば保存ができること" do
        expect(@order).to be_valid
      end
    end

    context '失敗' do
      it "priceが空では保存ができないこと" do
        @order.price = nil
        @order.valid?
        expect(@order.errors.full_messages).to include("Price can't be blank")
      end
    end
  end
end
```

基本用法
---
FactoryBotのインスタンスが正しく生成されているか？
インスタンス変数に代入されているか？
を確認します。

```spec/models/order_spec.rb
RSpec.describe Order, type: :model do
  before do
    @order = FactoryBot.build(:order)
    binding.pry  ←
  end
```

[![Image from Gyazo](https://i.gyazo.com/d049a15e4550b61d0e2f8cf39aa6c024.png)](https://gyazo.com/d049a15e4550b61d0e2f8cf39aa6c024)

price: 3000
という値が@orderに含まれていることがわかりました。
FactoryBotのインスタンス生成は成功です。

---

インスタンス変数に値は入っているか？
バリデーションを通してエラーがあるかどうか？
を確認します。

```spec/models/order_spec.rb
describe '購入情報のデータの保存' do
    context '成功' do
      it "priceがあれば保存ができること" do
        expect(@order).to be_valid
        binding.pry  ←
      end
    end
```

[![Image from Gyazo](https://i.gyazo.com/6d6aeddbc96aca9a5a3ea351fdc5a7cf.png)](https://gyazo.com/6d6aeddbc96aca9a5a3ea351fdc5a7cf)
@order.valid? の結果が trueとなっています。
「priceがあれば保存ができること」というテストは成功です。

---

インスタンス変数に値は入っているか？
バリデーションを通してエラーがあるかどうか？
エラーメッセージの内容は？
を確認します。

```spec/models/order_spec.rb
context '失敗' do
      it "priceが空では保存ができないこと" do
        @order.price = nil
        @order.valid?
        expect(@order.errors.full_messages).to include("Price can't be blank")
        binding.pry  ←
      end
    end
```

[![Image from Gyazo](https://i.gyazo.com/48d91bb9e0086d167319c79c060bf4f3.png)](https://gyazo.com/48d91bb9e0086d167319c79c060bf4f3)
インスタンス変数の中身が、代入した price: nil になっています。
これにより@order.valid?の結果は false になり、
エラーメッセージは "Price can't be blank" であることが確認できました。

「priceが空では保存ができないこと」というテストは成功です。
git pushするときにブランチ名を入力するのが面倒

# いままで
ローカル環境のブランチをGithub上の同じ名前のブランチにpushするとき、
いままではこんな感じでブランチ名を指定していました。

例）
　ローカル環境でfeature/sampleブランチにいて、
　Github上の同じ名前のブランチ（feature/sample）にpushするとき

```
$ git push origin feature/sample
```

# 問題点

問題点というほどでも無いのですが、毎回ブランチ名を入力しなければならないのが面倒だなぁと思っていました。
いざgit pushしようとしたとき、ブランチ名なんだっけ？となって

```
$ git branch
```
で確認することがよくあります。。。

# 対策

次のコマンドを使えば、ローカル環境の現在のブランチ名でgit pushすることが出来ます。

```
$ git push origin HEAD
```

Github上に同名のブランチが存在していない場合でも問題なくpushできます。
（git pushしたブランチと同名のブランチをGithub上に生成してくれます）

便利！
S3 事前署名付きURL を AWS CLI で生成

# はじめに

AWS S3 で、AWS CLI を使って署名付きURL を生成してみる備忘録です。署名付きURL は AWS マネージメントコンソールでは生成できないので、AWS CLI や SDK 経由で生成が必要です。

 

# 署名付きURL を生成

S3 上にファイルが格納されている状態です。`cloudfronttest-sugi01` という名前の Bucket に、test.html というオブジェクトがアップロードされています。

![1609765275119.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/86ee79e3-03b6-d8c2-7c96-c3fff7a99fc1.png)



AWS CLI で見るとこんな感じです。

```
> aws s3 ls s3://cloudfronttest-sugi01
2021-01-04 07:57:18        117 test.html
```



AWS CLI で署名付きURLを生成します。`expires-in` は、署名付きURLの有効期限を秒数で指定します。次のコマンドだと、60秒間のみアクセスできる指定方法です。

```
aws s3 presign s3://cloudfronttest-sugi01/test.html --expires-in 60
```



実行例

```
> aws s3 presign s3://cloudfronttest-sugi01/test.html --expires-in 60
https://cloudfronttest-sugi01.s3.ap-northeast-1.amazonaws.com/test.html?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAX3NQZCLY73NLWR7G%2F20210104%2Fap-northeast-1%2Fs3%2Faws4_request&X-Amz-Date=20210104T130707Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host&X-Amz-Signature=89b8f48a581dd84e6552378607a30052a99c790bf7075b021409a30a1304f54b
```



アクセスしてみると、HTMLファイルが表示されています (CloudFront はこの記事では関係ないので、無視してください)

![1609766710514.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/d18255a0-0a42-eed4-d767-36cd91383154.png)



60 秒後再度アクセスすると、有効期限が切れてアクセスできなくなります

![1609766734533.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/dae1479a-127c-533e-a560-d171248cdd67.png)





# 参考URL

https://dev.classmethod.jp/articles/generate-s3-pre-signed-url-by-aws-cli/
OpenCV AI Kit (OAK-D) 試してみた＠windows10

初投稿です。

2020年8月に[kickstarter OpenCV AI Kit](https://www.kickstarter.com/projects/opencv/opencv-ai-kit) でクラウドファウンディングされていたAIステレオカメラが届いたのでレポートです。

### 入手まで

2020年8月に[kickstarter OpenCV AI Kit](https://www.kickstarter.com/projects/opencv/opencv-ai-kit) で$149+20(送料)でpledgeしました。
成立後に追加で、送料オーバ分16ドル税14.9ドルで、最終的に199.9ドルです。
今は、[https://store.opencv.ai/](https://store.opencv.ai/)で買えるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76546/07cd80a7-6ea3-651e-4f31-5ae6cfb36056.png)

### 構成物

写真の通り。
電源は5.0V-3.0Aで世界各国用のコネクタがついてます。
少なくともチュートリアルのデモレベルなら、電源なしのUSBバスパワーで動きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76546/1f3481e3-d765-bd29-329d-3053a544ebe2.png)

### インストール作業

基本、[同梱されたカードのURL](https://docs.luxonis.com)に書かれたサイトのチュートリアルに従うのみです。
以下はwindows10のケースです。python3.9インストール済。

[Depth AI Python API](https://docs.luxonis.com/en/latest/pages/api/)

- PowerShellを管理者モードで開く

- 実行ポリシーを設定する

```powershell
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
```
- chocoでまとめてインストール

```powershell
choco install cmake git python pycharm-community -y
```

- pipでdepthai入れる

```powershell
python -m pip install depthai
```

### depthAI デモの準備

- depthaiを適当なフォルダにclone

```powershell
git clone https://github.com/luxonis/depthai.git
cd depthai
```

- 必要ライブラリのチェック用スクリプトを実行する ※公式だと仮想環境での実行を推奨

```powershell
python install_requirements.py
```

### depthAI デモの実行結果

- demoスクリプトを実行する (要カメラ接続)

```powershell
python depthai_demo.py
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76546/fece68bb-d336-166b-c0bb-e9d4d6222088.png)

mobilenetの20class分類で検出した物体までの距離が表示されます。
Zが奥行方向でしょうか。

画像は50cm程度手前からの撮影です。
人形(person)までの距離はまあまあですが、画面上のバイクまでの距離は誤差大です。
近距離すぎて視差が取れていないのかも。

#### DEPTH画像

先程の```depthai_demo.py```にオプションを付与することでdepth画像の出力も可能です。

```powershell
python .\depthai_demo.py -s metaout depth_raw -bb
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76546/03f49636-2396-f83c-7d89-ab950b76149c.png)

- 同画角の可視画像

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76546/af62e69f-fc08-25e1-9151-4fad6a697b92.png)

視差は、一般的なステレオでよく見る感じで、まあまあ取れてそうです。

物体検出の精度は、スピーカーをテレビモニタと間違っているように割と微妙。
[OpenVINOのその他のモデルを使うチュートリアル](https://docs.luxonis.com/en/latest/pages/tutorials/pretrained_openvino/)もあるので、差し替えれば簡単に良くなるとは思っています。



### まとめ

動くところまでは簡単に確認できました。

測距離の誤差要因は、パッシブステレオの特性、アルゴリズム的なもの、キャリブレーション不足、など色々考えられます。
今後はチュートリアルを進めつつ、サンプルコードの中身も読んだ上で、性能を引き出せるようにしていきます。


### 参考文献

https://docs.luxonis.com/en/latest/pages/api/
https://docs.luxonis.com/en/latest/pages/tutorials/pretrained_openvino/
Go言語の環境構築

# 環境構築に必要なもの
Go、VisualStudioCode、Goの拡張機能の3つをインストール

### ❶Goのインストール
Goは、homebrewを使ってインストール

```
ターミナルを開く
spotlightからターミナルを検索して起動
$ brew update
$ brew install go
```

まず、homebrewを最新バージョンにしておく
### ❷確認
```
$ go version
```

次のコードを実行して、goがインストールされているか確認
バージョンが返ってくれば、インストールされていることが確認できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/958284/1a1ad428-6cc3-7fd1-2b15-e4d8cc57b3ab.png)


### インストールページから
[Goインストールページ](https://golang.org/doc/install)

インストール後にちゃんとできているか❷と同様に確認

```
$ go version
```

### ❸VisualStudioCodeのインストール

[VisualStudioCodeインストールページ](https://code.visualstudio.com/download)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/958284/2a292c96-cbaa-db9c-81f6-8a49ebeb723b.png)

####インストール後
左のバーを(アクティビティバー)
四角のアイコンをExtensions
ここで、拡張機能をインストールできる

```
VisualStudioCodeを開く
表示が英語になっているので、日本語に変更
「Japanese Language Pack for Visual Studio Code」と検索
「Japanese」と入力すると、候補が出てくる
インストールをクリック
インストールが終わったらVisualStudioCodeを再起動
表示が日本語になる
```

### ❹Goの拡張機能のインストール
```
VisualStudioCodeのextensionsで「Go」を検索して、インストール
```

### 環境構築が完了したので次回は実行環境テスト！
文字列が左から何文字目に出てくるかを調べたい

任意の文字列の中から"get"が左から何文字目に出てくるか調べて、その数を出力したいと思います。

出力例は、

```bash
count_code("getexxcode")
 =>1
count_code("aaagetbbb")
=> 4
count_code("cozexxget")
=> 7
```

indexメソッドを使ってメソッドを作ります。
参考:
[Ruby 3.0.0 リファレンスマニュアル:indexメソッド](https://docs.ruby-lang.org/ja/latest/method/String/i/index.html)

使用例:

```ruby
str.index(検索したい文字列, 検索を開始する位置)
```

初めにメソッドを作成します。

```ruby
def count_code(str)

end
```

その中にindexメソッドを使って出力例のように出力したいと思います。

```ruby
def count_code(str)
  puts str.index("get", 0 )
end
```

これで、出力することができました。
しかしこのままでは出力例のようにならず、以下の結果となってしまいます。

```bash
count_code("getexxcode")
 => 0
count_code("aaagetbbb")
=> 3
count_code("cozexxget")
=> 6
```

最後に、

```ruby
def count_code(str)
  puts str.index("get", 0 ) + 1
end
```

としてあげることで出力例のようになります。
【Excel数式】表を作る際の自動ナンバリング計算式メモ

## Excelで表の左側に作る「No.」列の値を自動で設定するための計算式のメモ書き**

**前提**
* 「No.」列がB列
* 　ヘッダー行が1行目で明細の開始行が2行目の場合
* 2行目の「B」列。いわゆる「B2」の計算式

**何故メモするか**
表を作る機会が多く、「=ROW()-1(ヘッダー行の行数)」の計算式を設定していたが、ヘッダーより上の行に他の情報を追記するために挿入した場合等、計算式上の行数がズレてしまうためにナンバリングがズレることがままあった。計算式の修正が毎回面倒で、少なくともヘッダーの行がずれてしまっても該当列のナンバリングの計算式を検討した。

**計算式**
~~`=ROW()-(ROW()-1)+IF(ISNUMBER(B1),B1,0)`~~

@radames1000さまより
上の計算式の場合、行を削除したりすると正常にナンバリングができなくなることを指摘いただきました。

また、すごくシンプルで良い計算式を教えて頂きました！
同上でヘッダーが１行目。明細が２行目開始の場合のB列に「No.」列を設定する場合の「B2」に設定する計算式となります。

`=MAX($B$1:B1)+1`

**実際の画面**
![スクリーンショット 2021-01-04 22.51.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536171/a28ab602-3bc8-9037-bc5e-2472e740165f.png)

**解説**
```ROW()```は、自分の行数を取得する関数
```ROW()-1```は、自分の行数から-1しているので1行上の行数
まず前提として``ROW()-(ROW()-1)``でインクリメントさせる数値を計算するというか1ずつインクリメントするわけだから、ここの部分はまるまる``1``で置き換え可能です。今気づいた笑
``ISNUMBER(B1)``は、1つ上のセルの値が数値かどうかを判断する。
``IF(ISNUMBER(B1),B1,0)``とすることでヘッダー行の場合（つまり数値ではない場合）は0を数値の場合は、その数値（つまり「No.」の値）を加算する。

という事なのでこれでもいいのか。
~~``=1+IF(ISNUMBER(B1),B1,0)``~~
 
**使う時気をつけること**
* 「No.」列がBじゃない場合は、それらの列のアルファベット記号に合わせて修正する。
* 「B1」の部分は必ず計算式を設定するセルの1つ上のセルを対象とする。

**終わりに**
もっとこうしたら良いとか、そこおかしいのでは等あったら教えてください。

**更新**
2021/1/5 @radames1000さまコメントの指摘を反映
簡単カレンダー

#はじめに
　少し蛇足で、アプリにカレンダー機能を付けました。その流れを紹介します。まだ、使い物になるカレンダーではないので、もう少し調整していこうと思います。

##導入の流れ
1. Gemを記述
2. インストール
3. CSS記述
4. 表示
5. （ビューを生成）

##1. Gemを記述
```ruby:Gemfile
gem "simple_calendar", "~> 2.0"
```

##2. インストール
カレントディレクトリが作成中のアプリケーションであることを確認して、

```bash
% bundle install
```
##3. CSS記述
```css
*
 *= require simple_calendar ←これを記述
 *= require_tree .
 *= require_self
*/
```
##4. 表示
```erb

<%= month_calendar do |date| %>
  <%= date %>
<% end %>
```
![](https://i.gyazo.com/e644433b996e823cd23b0cf4a403cb66.png)
↑最低限、こんな感じのカレンダーができます。

##5. （ビューを生成）

```bash

rails g simple_calendar:views
```
このコマンドで生成されるビューを編集すると、細かくビューをいじることができるみないです。
【AWS】ECSのBlue/Green（ブルー／グリーン）とは？

個人用メモです。

AWSのCodePipelineで本番化する際に、ESCのブルー／グリーンデプロイという本番化手法が選択できる。

縮めてブルーグリーンと呼ぶことが多い。


##ブルーグリーンとは？
AWS上のDockerであるECSで本番環境を構築する手段の一つ。

以前のデプロイと比べ、**より安全で安定した本番化手法**。

レポジトリの変更内容を自動取得し、イメージ作成（ビルド）、テスト、本番化を実行するAWSのサービスCode Pipelineの本番化ステージの選択肢の一つ。


<br>
##ブルーグリーンの内容
ブルーグリーンは、**古いサーバーを残したまま新しいサーバーを構築し、一定期間経過後に新しいサーバーが安定したのを確認してから古いサーバーを消去**する仕様。

一定期間古いサーバーが残っているため、新しいサーバーで不具合があった際も古いサーバーに切り替えるのが簡単。



<br>
###ブルーグリーン以前の本番化処理
昔の本番化処理は、古いサーバーの中身を徐々に新しいのに置き換えていく仕様だった。（ローリングと呼ぶ）

これでは、不具合があった場合に元のバージョンに戻すなどの対応が大変だった。



<br>
##ブルーグリーンの由来
上述のように、古いサーバーと新しいサーバーで別々の環境が２つ存在する。

この２つの環境をブルーとグリーンとしているため、ブルーグリーンと言う。


<br>
##ブルーグリーンの実行画面
AWS CodeDeployで本番化の進捗状況を確認できる。
ブルーグリーンは以下のように４つのステップからなる。（待機時間なしの場合は3ステップ）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/3fbf2693-1934-22e9-5573-35b879ef3ba0.png)



<br>
＞[AWS公式 ブルーグリーン](https://aws.amazon.com/jp/quickstart/architecture/blue-green-deployment/)
【Spring】【Thymeleaf】CSRFトークンを入れる

###formやbuttonをカスタマイズしていると、送信先やCSRFトークンが入らなくて遷移できなかった
thymeleafを利用して

```java
<form th:action="@{url}" method="post">
```
のように`@{}`を使ってaction属性を書けば、自動的にCSRFトークンがhiddenで入る

つまり

```java
<form action="url" method="post">
```

では、CSRFトークンは入らない。
なのでこの状態でsubmitしても遷移できなかった。


###button毎に送信先を変える手法だと、CSRFトークンが入らない

```html
<form th:action="url" method="post">
<button type="button" onClick="submit();" th:formaction="@{url2}">
</form>
```

のようにして、jQueryのsubmit関数を利用すると、formタグのaction属性のurl先に対して提出されるみたい。

つまり、`th:formaction＝"@{url2}'とすればトークンが入ると思ったら駄目でした。


###対策

```html
<form th:action="url" method="post">
// ↓これを追加すればトークンが入る。つまり手動でトークンを入れる
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
<button type="button" onClick="submit();" th:formaction="@{url2}">
</form>
```

scriptを書いてどうにか書けないかなといろいろ試しましたがうまく行かなかったので、とりあえず手動で入れておけばbuttonを増やしても問題なさそうな気がします。

ただ、th:formactionも効かず、formのaction属性がsubmit先になります。


###submit()を変更してsubmit先を変更する
```javascript

<button type="button" onClick="setAction("好きなURL");">

<script type="text/javascript">
function setAction(url){
  $('form').attr('action', url); // action属性に引数のurlをセット
  $('form').submit(); // submitを実行（上でaction属性を変えたので、そこがsubmit先になる！）
}
</script>
```

これで、buttonを増やしてsubmit先を複数用意することも可能になると思われます。


もっと良い方法があれば教えていただきたいですm(__)m
JupyterLab3.0の起動ブラウザを指定する方法

# はじめに
JupyterLabのバージョンを2.2.0から3.0.0にアップグレードすると、起動ブラウザ指定がうまくいかなかったので、解決方法をメモします。

# 環境
- Python(3.7.6)
- JupyterLab(3.0.0)

# うまくいかない状態

　まず、うまくいかない状態を説明します。ウェブでJupyterLab ブラウザ指定と調べると、次の方法が載っています。コマンドラインで、

```powershell:command
jupyter notebook --generate-config
```

を打ち込み、~/.jupyter/jupyter/jupyter_notebook_config.pyを作り、jupyter_notebook_config.py内で

```Python:jupyter_notebook_config.py
c.NotebookApp.browser='"C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe\" %s'
```

を指定する方法です。JupyterLab 2.x.xまでは、起動の際、jupyter_notebook_config.pyも参照しているようです。

　しかし、JuypterLab 3.0.0になると、上記の設定をしても起動ブラウザを指定できません[^1]。指定方法が変更になっています。

# 解決方法

　単純ですが、`jupyter lab`でconfigファイルを作成します。コマンドラインで、

```powershell:command
jupyter lab --generate-config
```

を実行すると、~/.jupyter/jupyter_lab_config.pyが作成されます。~/.jupyter/jupyter_lab_config.py内の

```Python:jupyter_lab_config.py
c.ServerApp.browser = '"C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe\" %s'
```

のコメントアウトを外し、ブラウザexeのパスを記入して、保存します。そうすると、`jupyter lab`での起動ブラウザを指定することができます。"jupyter_lab_config.py"のファイル名は、"jupyter_server_config.py"であってもよいようです[^1]。

# 参考

[^1]: https://github.com/jupyter/docker-stacks/issues/1205#issuecomment-752247507
M1 MacでのWine 6.0-rc5のビルド

# Wine
WindowsアプリケーションをLinuxやmacOS上で動作させることができる[Wine](https://www.winehq.org/)の6.0-rc5をM1 MacのRosetta2環境でビルド&実行してみました。
macOS Catalina以降ではWine 6.0-rc5は64bitアプリケーションのみ対応となります。

32bitアプリケーション64bitアプリケーション両対応のCrossOver 20.0.2のビルドについては
https://qiita.com/asfdrwe/items/24cf3759edeb3fe56bc0
で解説しています。

## ビルド環境構築

~/Download/以下で作業しています。

```
$ cd ~/Downloads
```

Command line tools for XcodeとRosetta2上で動作するx86_64用homebrewをインストールしてください。

参考
https://qiita.com/royroy/items/338362362de73a94fc0c
https://qiita.com/shira-shun/items/0f6213f4923cb5544367


homebrewでbison、flex、mingw-w64、pkgconfig、freetypeをインストールし、bisonやflexにパスを通し、LDFLAGS等を設定します(XQuartzは不要です)。

```
$ brew install bison flex mingw-w64 pkgconfig freetype
$ export PATH="/usr/local/opt/flex/bin:/usr/local/opt/bison/bin:$PATH"
$ export LDFLAGS="-L/usr/local/opt/freetype/lib/ -L/usr/local/opt/flex/lib -L/usr/local/opt/bison/lib"
$ export CPPFLAGS="-I/usr/local/opt/flex/include"
```

## Wine 6.0-rc5のダウンロードと展開
https://dl.winehq.org/wine/source/6.0/wine-6.0-rc5.tar.xz
をダウンロードして展開してください。

```
$ tar xvfJ wine-6.0-rc5.tar.xz
$ cd wine-6.0-rc5
```


## Wineのビルド
そのままビルドするとwineを実行しても

```
display: macdrv_init_display_devices No GPUs detected
```

とメッセージが出てウィンドウが表示されないようなので、CrossOver-20.0.2からdlls/winemac.drv/cocoa_display.mを置き換えた上で、必要なinclude/wine/hostaddrspace_enter.hを追加したパッチを当てます。

https://pastebin.com/raw/Ruxp6FA3
をwinemac.drv.patchとして保存して

```
$ patch -p1 < ../winemac.drv.patch
```

### ビルド
とりあえず、/usr/local/wine-6.0-rc5以下にインストールするようにビルドします。

```
$ ./configure --prefix=/usr/local/wine-6.0-rc5 --enable-win64
$ make
```

### インストール
```
$ sudo mkdir /usr/local/wine-6.0-rc5
$ sudo chown "$USER":admin /usr/local/wine-6.0-rc5
$ make install
$ cd ..
```

## Wineの実行
wine64にパスを通して実行します。

```
$ export PATH="/usr/local/wine-6.0-rc5/bin:$PATH"
$ wine64 winecfg
```

[winetricks](https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks)は環境変数WINEをwine64になるように設定してください。

```
$ export WINE=/usr/local/wine-6.0-rc5/bin/wine64
$ ./winetricks
```

[7zip](https://sevenzip.osdn.jp/)のx64版が動作するのを確認していますが、インストーラーがx86のようなので、[msi版インストーラ](https://7-zip.org/a/7z1900-x64.msi)をダウンロードして、msiexecコマンドでインストールしてください。

```
$ wine64 msiexec /i 7z1900-x64.msi
```

## 参考サイト
https://wiki.winehq.org/MacOS/Building
https://github.com/Gcenx/macOS_Wine_builds/issues/15
アドベントカレンダー30日目：SREを読んでみた「オンコール対応」編①

今日からオンコール対応の章に入ります。

## バランスのとれたオンコール
オンコール対応は、オンコールの量と質でバランスをとる必要がある。
オンコールの量は、エンジニアがオンコール担当に費やす時間の割合。
オンコールの質は、オンコールシフト中に生じたインシデント数。
この2軸でバランスを取り、持続可能な状態を保つことが必要。

### 量におけるバランス
GoogleのSREでは持ち時間の内50%がエンジニアリングに使われます。
そのため、残りの25%がオンコール対応に使われ、さらに残りの25%はそれ以外の運用作業に使えるように残されます。
25%がオンコール対応に使える時間とすると、オンコールローテーションを維持するのに必要な人数も見えてきます。
また、作業量的にもっとチームを大きくすべき場合、Googleではマルチサイトのチームを作ることを好みます。
ただし、マルチサイトのチームではコミュニケーションと調整にオーバーヘッドが生じるので、その時の状況を鑑みて、判断されるべきです。

### 質におけるバランス
エンジニアはインシデント対応の際にその対応とポストモーテムの執筆のようなフォローアップの為の十分な時間を持つべきです。
根本原因の分析、改善、ポストモーテムの執筆には平均で6時間かかるということが分かっています。
一日12時間のオンコールシフトにおいては、2件のインシデント対応を行えることになります。
もしもこの限度を超えた場合は、運用の負荷を持続可能な状況に戻すための是正対応を行うべきです。

## まとめ
* インシデント対応は質と量でバランスをとる必要がある
* オンコールシフトルール（使える時間は25%）
* インシデント対応ごとにポストモーテムの執筆などのフォローアップを行う

#### 参考文献
1. Betsy Seyerほか　SRE サイトリライアビリティエンジニアリング　オライリー　131-134
ラズパイ4でGrovePi+を使う

## はじめに

ラズパイ4にGrobe Pi+を使ったときのメモ

## 環境

RaspberryPi 4 モデルB (4GB)を使いました。

Linuxカーネルのバージョン

```console
$ cat /proc/version
Linux version 5.4.79-v7l+ (dom@buildbot) (gcc version 8.4.0 (Ubuntu/Linaro 8.4.0-3ubuntu1)) #1373 SMP Mon Nov 23 13:27:40 GMT 2020

$ uname -r
5.4.79-v7l+
```

```console
$ python3 --version
Python 3.7.3
```


## 接続

こちら[GrovePi+](https://www.switch-science.com/catalog/2129/)を参考にGrovePi+をラズパイ4に接続します。

裏面は、USBポートとの接触で通電しないようマスキングテープで保護し、絶縁しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/4773b293-3847-eb52-1cb9-5615b8ffc53c.png)

ラズパイが通電していない状態で、GrovePi+を接続しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/25bd32ad-46f9-41b4-2fbb-e73ceafc8062.png)

## インストール

GrovePi+を利用できるように必要なモジュールをインストールします。以下サイトを参考にしました。

- [GrovePi+のinstall.shでCommand not foundが出たときの対処法](https://qiita.com/masa-ramenO/items/e924e1745d19a62d9abd)
- [Part 2. GrovePi Setup](https://github.com/initialstate/grovepi/wiki/Part-2.-GrovePi-Setup)

以下を実行すればインストール完了しました。

```console
$  sudo curl -kL dexterindustries.com/update_grovepi | bash
$  sudo pip install grovepi
$  sudo reboot
```

**ーー ↓↓↓ 追記 ↓↓↓ ーー**
クイックインストールとファームウェアアップデートの方法がここに書いてた→[DexterInd/GrovePi](https://github.com/DexterInd/GrovePi)

クイックインストール

```console
$ curl -kL dexterindustries.com/update_grovepi | bash -s -- --user-local --bypass-gui-installation
```

ファームウェアアップデート

```console
cd /home/pi/Dexter/GrovePi/Firmware
bash firmware_update.sh
```

※認識できなかったセンサーがファームウェアアップデートで認識できました！

**ーー ↑↑↑ 追記 ↑↑↑ ーー**

## 確認(1)

セットアップできているか確認します。
以下のように`grovepi`モジュールがインポートできれば成功です。
（`ModuleNotFoundError:`といったモジュールみつからない的なエラーがでたら失敗）

```console
$ python3
Python 3.7.3 (default, Jul 25 2020, 13:03:44)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from grovepi import *
>>>
```

## 確認(2) : LEDを光らせてみる

Lチカやってみます。
スターターキットのLEDデバイスを使います
<img width=300 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/5e8908a4-07c1-fb9a-1268-3fb73b006e2c.png" />

これを、こーする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/fcf98a64-4387-b250-c6c7-ac8d60ad3faf.png)

D4ポートに接続します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/fcf45f4b-0c1f-ce29-188d-825818795f21.png)

スクリプトを用意します。

```python:led.py
import time
from grovepi import *

led = 4

pinMode(led, "OUTPUT")
time.sleep(1)

while True:
    try:
        digitalWrite(led,1)
        time.sleep(1)
        digitalWrite(led,0)
        time.sleep(1)
    except KeyboardInterrupt:
        digitalWrite(led,0)
        break
    except IOError:
        print("Error")
```

そして実行

```console
$ python3 led.py
```

LEDがチカチカしたら成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/299bf91f-2190-bffd-6e84-6cc4d224ce23.png)

## さいごに

これで配線が苦手な私でもラズパイ＋センサーで遊ぶ環境ができました。
Go言語について触れてみる

# Go言語とは

```
2009年にGoogleが開発したプログラミング言語
```

Androidアプリの開発、iOSアプリの開発も可能

ちなみにGo言語の正式名称は「Go」
それだけだと別の意味にとらえられてしまうので、GolangやGo言語と呼ばれることが多い

# C言語の生みの親が開発した言語

Go言語はUNIXの開発に携わったロブ・パイク氏と
UNIXの開発とC言語を開発したケン・トンプソン氏が設計


Go言語はC言語を意識しながら設計されている言語で、C言語並みに処理が高速で、C言語以上にシンプルに記述することができる
時代に合わせ、より便利に使えるようにした新しいC言語。それがGo言語だと言える

# コンパイラ言語

```
Go言語は、コンパイラ言語
```

### コンパイラ言語とは
機械語に一括して変換してから実行するプログラミング言語のことで
処理が高速という特徴がある

その高速に処理できるコンパイラ言語の中でも、Go言語はより高速に処理ができる
JavaやC#は、仮想マシンを介して実行されるのに対して、Go言語は仮想マシンを介さずに実行されるから
Go言語は、処理が高速という特性を活かし、アプリケーションを動かすために必要なwebサーバーの構築や、大規模データの解析ツール開発などと相性が良い

### シンプルな構文

Go言語の構文はシンプル
シンプルなので、学習難易度が低く、他の言語を使える人は習得が早い

```
誰が書いても似たようなコードになるので、コードが読みやすい
開発効率をあげることができる
```

シンプルで学習難易度は低いですが、プログラミングを初めて勉強する方は
PythonやPHPなどのスクリプト言語から学習するのがおすすめ

#### 次回は環境構築を行います！！
【AWS】CodePipelineとは？各サービスでできることや設定手順の概要について

個人メモです。

##CodePipelineとは？
一言で言うと、**コードからテストを含めた本番化までを一気に行ってくれる**便利サービス。

Githubのコードからイメージのビルドし、テスト、本番化（デプロイ）の流れを自動で実行してくれる。

本番化せずとも、ソースからビルドの作成までといった設定もできる。編集はとても簡単。

<br>
####もう少し噛み砕くと
ローカルでソースコードを改修し、githubやCodeCommit(AWSのgithub)のレポジトリにプッシュすると、**変更を検知して自動でPipelineの実行を開始**する。

DockerのようにAWSの仮装コンテナ（ECS）にイメージを作成（ビルド）し、本番化しても問題ないかテストし、OKであれば本番化してくれるツール。

どこまでの処理を実行するかは好きに設定できる。

本番化の前に承認プロセスを追加することも可能。

コード（code）から本番化までの経路を一直線で辿っている(pipeline)ためCodePipelineと呼ぶ。


<br>
##CodePipelineの流れ
コード改修から本番化までは大きく６つのステップに分かれる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/cf8ed0ac-041a-2ea8-6d1d-16517a90db74.png)

| No | 項目 | 内容 |
|:-:|:-:|:-:|
| 1  | レポジトリ  | コードの改修内容をレポジトリにプッシュ  |
| 2  | ソース  | GithubやCodeCommitからソースを取得  |
| 3  | ビルド  | ソースからイメージを作成。（仮装コンテナに作成）  |
| 4  | テスト  | イメージが実行可能かテスト  |
| 5  | デプロイ  | 本番化  |
| 6  | 統合テスト | リンクチェッカーツールなどで検証  |



<br>
##CodePipelineの作成手順
作成手順は大きく４Steｐ。

1. パイプラインの作成
2. ソースの選択
3. ビルドの選択
4. デプロイの選択

**▼ポイント**

- ステージは２つ以上必須。
- ステージの追加はパイプライン作成後に可能
- ソースの複数選択もパイプライン作成後に可能


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/d312cfdf-332c-2806-d915-4ac1382184a5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/45bec748-cf59-bbd2-fbe7-5ca9f0840ce3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/34cd260c-caf0-233b-67e9-91da773071bd.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/e0aa1a7c-2e51-c10b-3ad4-10ce917ae9a5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/543195a8-19e9-15a0-df00-d0a06cdd7ae3.png)



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/4d7069ef-3491-7e62-0d4d-805e82b6a3ad.png)


###後からの設定変更
###ソースの複数選択
GithubとCodeCommit両者の選択や、Githubのサブモジュールの選択など、複数のソースを選択することができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/01f84d40-08c1-0d04-3a37-3fff87e8ed20.png)


###ステージ名の設定や追加
各ステージに名前をつけたり、ソースやビルドなどのアクションを追加することもできる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/21d72c84-7574-fbe6-0f95-5939aeb2058a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/a9c4513b-af1c-a74d-7a0b-7ed1d5296517.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/c11ddf86-c377-35d0-efef-178db974434a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/cc712438-1612-ee7d-ed71-428299e710e9.png)
【Flutter】TextFieldに初期値を持たせる方法 【Dart】

開発時に少し躓いたので共有します

```dart
class InitTextField extends StatelessWidget {
  InitTextField(this.title);

  final String title;

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: TextEditingController(text: title),  //ここに初期値
    );
  }
}
```


## 躓いたところ
以下のやり方でも初期値は設定可能だったが状態更新した時に
再レンダリングされなかった。上記の方法だと解決した

```dart
TextFormField(initialValue: title)
```
Jestのスナップショットテストでreact-native-vector-iconsがエラーを起こす問題の解決

# 前提
- ReactNative: 0.63.2
- expo: 39.0.0
- jest: 25.1.0
- jest-expo: 40.0.1

# 起きている問題
- スナップショットテストを書いていて、 `jest` を実行したところ、以下のようなエラーが発生した。

```
ReferenceError: You are trying to `import` a file after the Jest environment has been torn down.

      at Object.get Text [as Text] (node_modules/react-native/index.js:122:12)
      at Icon.render (node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/lib/create-icon-set.js:120:58)
      at finishClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7693:31)
      at updateClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7648:24)
      at beginWork$1 (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9159:16)

中略

    Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

    Check the render method of `Icon`.
        in Icon (created by Icon)
        in Icon (created by MaterialIcon)
        in MaterialIcon (created by FoodMediumItem)
```

テストコードは以下

```tsx
import React from 'react';
import renderer from 'react-test-renderer';
import { FoodMediumItemStory } from './stories';

it('renders correctly', () => {
  const tree = renderer.create(<FoodMediumItemStory />).toJSON();
  expect(tree).toMatchSnapshot();
});
```

# 原因
- `react-native-vector-icons`がObjectをreturnしていて、 `React.createElement` の正しい返り値になっていない模様。（ちゃんとソースコードまで読んでいない）

# 解決方法
`react-native-vector-icons` をmock化する。テストコードを以下のように変更した。

```tsx
import React from 'react';
import renderer from 'react-test-renderer';
import { FoodMediumItemStory } from './stories';

jest.mock('react-native-vector-icons/MaterialIcons', () => 'Icon'); //これを追加

it('renders correctly', () => {
  const tree = renderer.create(<FoodMediumItemStory />).toJSON();
  expect(tree).toMatchSnapshot();
});

```

# 参考文献
[react-native-vector-icons/MaterialIcons jest-expo snapshot test error with typescript](
https://stackoverflow.com/questions/61639734/react-native-vector-icons-materialicons-jest-expo-snapshot-test-error-with-types)
【tips】SQLite3でlong型を使う理由(C# Mono.Data.Sqlite)

#整数型(integer, int, long)のどれを使っても格納できる内容は同じ
SQLite3の整数型(integer, int, long)はすべてInteger型です。その例を下記に示します。

```:シェルコマンド
cd /tmp
sqlite3 workdb.sqlite   #ターミナルからこのコマンドを入力し、sqlite3インタープリターを起動します。
                        #workdb.sqliteはファイル名です。存在しない場合、新規作成されます。

#integer型, int型, long型を定義します。
> create table t001 (i1 integer, i2 int, i3 long);
> insert into t001 values(1,2,3);
> insert into t001 values(123456789012345678,223456789012345678,323456789012345678);

#全ての項目がinteger型であることが確認できます。
> select typeof(i1), typeof(i2), typeof(i3) from t001;
integer|integer|integer
integer|integer|integer

#int型(4バイト)を超える値でも格納できることが確認できます。
> select i1, i2, i3 from t001;
1|2|3
123456789012345678|223456789012345678|323456789012345678
```

なので、create table文を使う際、整数を明示するために'integer'もしくは略称の'int'を使えば良いと考えてしまいます。

#しかし、C#からSQLiteデータベースを使うのなら、話は別です

以下に、C#からSQLite3のデータを読み取るプログラムを書きました。しかしこのプログラムは、adapter.Fill(dataset, "tmp"); の行で、System.OverflowException例外がスローされます。

```CS:Program.cs
using System;
using System.Data;
using System.Xml;
using Mono.Data.Sqlite;

class MainClass
{
  public static void Main(string[] args)
  {
    SqliteConnection connection = new SqliteConnection("Data Source=/tmp/workdb.sqlite;Version=3;");
    connection.Open();

    string sql = "select * from t001;";
    using (SqliteDataAdapter adapter = new SqliteDataAdapter(sql, connection))
    using (DataSet dataset = new DataSet()) {
      adapter.Fill(dataset, "tmp");
      DataTable table = dataset.Tables["tmp"];
      foreach (DataRow row in table.Rows) {
        Console.WriteLine(row["i1"].ToString() + " " + row["i2"].ToString() + " " + row["i3"].ToString());
      }
    }
    connection.Close();
  }
}
```

#例外がスローされた理由

create table文で'i2 int'と定義していたため、値223456789012345678がC#のint型に収まらなかった(Value was either too large or too small for an Int32.)のが原因です。

|SQLite3の型|C#の型|
|:--------:|:---|
|integer|long型(8バイト)|
|int|int型(4バイト)|
|long|long型(8バイト)|
|(型名なし)|データ依存(long型,string型,byte[]型など)|

#C#(Mono.Data.Sqlite)で使用する場合の注意点
・intはintegerの略称ではない。
・integerを、C#(Mono.Data.Sqlite)はlong型と認識するが、C#のプログラマーにとってinteger=long型という認識が薄い。
・C#(Mono.Data.Sqlite)を使用する場合、create table文で使う型名はintとlongを使い分けるのがベスト。

#さいごに
　create table文の型名にlongが使えることは、SQLiteのドキュメントには明記されていません。というか、SQLite3はlong型を認識しません。'int'とか'long'とかが必要なのはMono.Data.Sqliteが型を決定する時です。
「2進数と16進数、2の補数表現」を参考にWolframAlphaでやってみた。

(オリジナルポスト)
https://qiita.com/newtakuproj0730/items/f24350b50e50f65c384e#符号ビット

以下でいいですか？
##WolframAlphaで
11011011_2
219
https://ja.wolframalpha.com/input/?i=11011011_2

100000000_2-11011011_2
37
https://ja.wolframalpha.com/input/?i=100000000_2-11011011_2
Unreal Engineから初めてのHoloLensビルドに失敗したときに見る記事

# 元記事
https://zenn.dev/iwaken71/articles/e1c2d5b3cd94df

# 開発環境
- Windows10 Pro
- Unreal Engine4.26 (以下Unreal)
- Visual Studio2019
- HoloLens2

# CompileエラーがないのにHoloLensビルドできない

エラー文を見ると、どうやら文字化けが起きるファイルが存在するようだ

```
D:\Program File\Epic Games\UE_4.26\Engine\Source\Runtime\Core\Public\Misc/Char.h(1): error C4819: �t�@�C���́A���݂̃R�[�h �y�[�W (932) �ŕ\���ł��Ȃ�������܂�ł��܂��B�f�[�^�̑�����h�����߂ɁA�t�@�C���� Unicode �`���ŕۑ����Ă��������B
```

# 解決法

`{PATH}\Epic Games\UE_4.26\Engine\Source\Runtime\Core\Public\Misc/Char.h`を開く。

126行目に、文字化けの原因になっているコメントがあるので消す (コメントなので消してもプログラムに関係ない)

これで解決！
PowerAutomateを使ってクラウドサービスの障害をタイムリーに検知する方法

# クラウドサービスへの依存が招く脅威
多くの企業が利用するクラウドサービスとしてAWS、GCP、Azureが挙げられます。それらは極めて高い可用性ではありますが障害が発生する可能性はゼロではありません。昨年も各クラウドサービスの障害が発生してITの現場は阿鼻叫喚の地獄絵図となりました…
そしてこれから更にクラウドへの依存度は高まり、障害の影響も大きくなっていきます。

# 晩酌時に起きた悲劇
2020年12月某日、日本時間の21時頃にGoogleのサービスにて障害が発生し、ほとんどのサービスが利用できない状態となりました。私も仕事上Googleのサービスと密に連携するシステムを担当しているため対岸の火事では無いのですが、なんとそれに気づいたのは子供が寝た後に呑気に晩酌していた22時頃です。スマホでスマートニュースを見ていたらGoogleがなんか大変な事になっていると気づき冷や汗だくだくでした…

# 検知はタイムリーが鉄則
今回の失敗は、タイムリーにクラウドの障害を検知できる仕組みを構築していなかった点にあります。
クラウドを使うという選択肢をとったのであれば、自社のサービスはもちろんのことクラウドの障害も検知しなければいけません。
という反省をもとに、MicrosoftPowerautomate（以下MSPA）を利用してクラウドサービスの障害を検知する仕組みを構築しました

# 作ったものと構成
・MSPAを利用する
・クラウドサービス側が提供しているRSSフィードを検知する
・RSSのアップデートを検知してMSPAを起動
・Slackに通知

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646573/8b376120-5b62-5343-e670-03e3c6a1fbe0.png)

# MSPAフロー
MSPAのフローはこんな感じです。トリガにはRSSフィードを設定し検知した内容をSlackの指定したチャンネルに送っています。
特に注目していただきたいのが赤枠の部分で、詳細は次章で説明します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646573/b439c6a3-3a08-0129-7930-69bca77d79e1.png)

# 障害検知にはRSSフィードを利用
ほとんどのクラウドサービスは、自社サービスのステータスダッシュボード画面を用意しています。主要クラウドサービスのステータスダッシュボードは以下です。

Google Workspace ステータス ダッシュボード
https://www.google.com/appsstatus#hl=ja&v=status

Google Cloud Status Dashboard
https://status.cloud.google.com/

AWS Service Health Dashboard
https://status.aws.amazon.com/

Azure の状態
https://status.azure.com/ja-jp/status

そして、それぞれのサービスで漏れなくRSSフィードのURLが用意されています。これは例えば何か障害が発生してサービスステータスに更新があった場合、こちらのRSSフィードが更新される仕組みとなっています。したがってMSPAのRSSフィードのURLに箇所にこれらのURLを指定しておくことでクラウド障害をリアルタイムで検知することができます。

例えばGoogleではページ最下部のここです。ここをクリックした後にジャンプするページのURLがRSSフィードのURLになります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646573/fbb63e5d-4e12-6fe2-2417-dcbf7bd24069.png)


ちなみにAWSでは各サービス/リージョン毎にRSSが用意されています…さすがクラウドナンバーワン企業ですね…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646573/77ca0096-9ac0-b442-52c9-258b8e596394.png)

# 実際の通知
初めに述べたGoogleの障害収束後、実際に通知されたGCPのステータスアップデートです。この時RSSフィードが更新されたのは23日の0時49分でしたがMSPAを介して通知が届いたのは0時51分(UTC)だったのでほぼリアルタイムにクラウドの状況を検知できた（検知できる）といえます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646573/9643e266-e146-a068-ccfe-cb00d93f4f42.png)
（諸事情によりメール画面のスクリーンショットですが、サンプルフローの通りに作ればSlackに通知されます）

# まとめ
クラウドの高可用性の上に胡坐をかかず、こういった仕組みを利用して障害検知することが大事だと思いました。でもできれば（いい意味で）使わないフローになって欲しいと願うばかりです。。。

# 最後に
「えっ？でもMSPAのサービスも一緒に落ちたら通知届かないよね？」と思ったあなた。素晴らしい着眼点ですね。そんなときはZaiperでも同じフローを組んでおきましょう。なんちゃって多重構成です(笑)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646573/226d253a-1495-f7de-f190-ec87fab5c126.png)
XHTMLからHTML5に移行する際に行う作業

今回はXHTMLからHTML5に移行するときにやっておくべき作業内容を備忘録として残しておきます。
ホームページのSSL化が著しくなった近年、サイトによってはHTML5化をしなければならない場合がでてくると思います。
HTML5では各種宣言がスマートになっていますので、XHTMLで使ってきた不要な宣言等は削除します。

###DOCTYPE宣言

変更前

```
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
```

変更後

```
<!DOCTYPE html>
```

###htmlタグ

言語の設定もhtmlタグでやってしまいます。

変更前

```
<html xmlns="http://www.w3.org/1999/xhtml">
```

変更後

```
<html lang="ja">
```

###メタ情報

XHTMLでは必須だったメタ情報も、HTML5では全く必要なくなります。
文字エンコードだけは必須ですが、よほどのことがない限りUTF-8を指定します。

```
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="content-style-type" content="text/css" />
<meta http-equiv="content-script-type" content="text/javascript" />
```

```
<meta charset="UTF-8">

```

###必要のないtype属性を削除
type属性もJSやCSSの読み込みにはもはや必要ないので削除。inputタグなど必要なものに関しては残しておいてください。

変更前

```
<link href="css/common.css" rel="stylesheet" type="text/css" />
<script src="js/common.js" type="text/javascript"></script>
```

変更後

```
<link href="css/common.css" rel="stylesheet">
<script src="js/common.js"></script>
```

###空要素を削除

変更前

```
<img src="hoge.png" alt="" />
<br />
```

変更後

```
<img src="hoge.png" alt="">
<br>
```
プロキシー環境下でpipを使ったらつまづいた話

ふだんまったく使わないPythonをたまたま仕事で使う機会があった。よくある企業のごとくHTTP(s)プロキシー下の環境のこともあり、pipでのパッケージ導入につまづいた。

# 対象
HTTP(s)プロキシー下でpipを利用するWindowsユーザー


# 事象
pipを使い、このような手順でパッケージを導入していたが、それでは導入できないパッケージにぶつかった。ちなみに--certパラーメーターで指定しているのはプロキシーを介してHTTPs通信するための自己署名証明書である。

```
> set HTTP_PROXY=http://<id>:<password>@<fqdn>:<port>
> set HTTPS_PROXY=%HTTP_PROXY%
> pip install pywinpty --cert="C:\path\to\certs\cert.pem" -vvv
Collecting pywinpty
  Using cached pywinpty-0.5.7.tar.gz (49 kB)
    ERROR: Command errored out with exit status 1:
/* snip */
    WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1123)'))': /simple/cython/
/* snip */
```

SSL/TLSでの接続不良が原因であることは明らかであった。そのため、コマンドライン引数で--trusted-hostパラメーターを指定したり、何をどう呼び出しているのかわからないので%APPDATA%\pip\pip.iniを用意するなどしてみたが解決に至らなかった。


# 解決方法
[pip: cert failed, but curl works, stackoverflow](https://stackoverflow.com/questions/19377045/pip-cert-failed-but-curl-works)に紹介されていた通り、環境変数PIP_CERTを設定したら解決した。pip config setを使っても解決できるかもしれない。

```
> set PIP_CERT=C:\path\to\certs\cert.pem
> pip config list
> pip install pywinpty
```


# 参考

 - [pip: cert failed, but curl works, stackoverflow](https://stackoverflow.com/questions/19377045/pip-cert-failed-but-curl-works)
 - [How to add a custom CA Root certificate to the CA Store used by pip in Windows?, stackoverflow](https://stackoverflow.com/questions/39356413/how-to-add-a-custom-ca-root-certificate-to-the-ca-store-used-by-pip-in-windows)
 - [pipで[SSL: CERTIFICATE_VERIFY_FAILED]が出る場合の解決法, Qiita](https://qiita.com/kobayashiss/items/ae22f0d9228c00b97342)
 - [pipでインストール時にエラーが出力される, Qiita](https://qiita.com/mako24/items/65279f4e6b8dd6b9af2c)
Python imageio.imwrite で PNG 保存は遅い

## 背景

imageio, 便利ですよね.

画像処理したデータ(画像)を, 可逆圧縮で 8bit or 16bit で保存したいので PNG で `imageio.imwrite` で画像保存していたのですが, なぜかスクリプトが重いなーと思ったら, PNG の書き込みが激遅でした.

https://github.com/imageio/imageio/issues/387

体感では, 256x256 くらいの画像でも 1 秒くらいかかります. BMP or TIFF で非圧縮だと 0.05 秒くらい.

## 対処

cv2.imwrite だと速くなるかも...?

あとは最新 imageio(PIL) だと速くなっているかもしれません.

自然画像的なデータだと, 可逆圧縮してもそんなにストレージ減らないので, 圧縮はあきらめて BMP or TIFF(8bit, 16bit, 32bit)にするのが手でしょう.

ちなみに imwrite で 16bit PNG 保存は, `PNG-FI` オプションをつけないと, 入力画像データが `[0, 255]` の範囲にある場合は自動的に 8bit にしてしまいますので注意です.
(Git)基本コマンド

#基本コマンド
**ファイル更新までの基本手順**
ざっくりした流れは以下のようにする

・ファイルを追加
・ファイルをコミット
・ファイルを更新

```:
git add .
git commit -m "任意のコメント" //コミット(Gitの内容を保存)
git push origin <branch-name>　// リモートにアップロードを行う
```
##git initコマンドの使い方
Gitのinitコマンドは、一言でいうと**「リポジトリを新規に作成」**するときに使用するコマンドである。

```:
$ git init
```

##git statusコマンドの使い方
このコマンドは、ワーキング・ツリーの状態を表示するためのもの。

```:
$ git status
```

##git checkoutコマンドの使い方
Gitのチェックアウト（checkout）とは、一言でいうと**「ブランチを切り替えたいとき」**に使用するコマンド。つまり、いま作業しているブランチから脱出して、新たに他の作業ブランチで作業をしたい場合に使用するためのコマンド。

```:
$ git checkout ブランチ名
```

git checkoutはブランチを切り替えるコマンド

```:
git checkout -b <branch名> 
```


##git branchコマンドの使い方
リポジトリ内の全てのブランチを一覧表示する。

```:
$ git branch
```
##git pull origin masterの使い方
mergeを行った後にこのコードを記載するとリポジトリにpull requestされる。

```:
$ git pull origin master　//最新のリポジトリ情報がダウンロードされる
```

##git log --onelineの使い方
書くコミットを１行で簡潔に表示する

```:
git log --oneline
```

##commitがmergeされていないが次の作業に移りたい場合。

```:
git add
git stash

↓ #masterブランチに切り替える
git branch -d <branch-name> #ブランチの削除
git checkout -b <branch-name>　#新しいブランチを作る
git stash pop #先ほどコピーしたものを新しいブランチに加える
git log – oneline #commitログが正しいか確かめる
```

commitを取り消す時に使う
いつ取り消すのか？
a.　commitを間違えてしてしまった時
b.　コードを書き忘れていた時
c.　これ以上コミットする必要がなくなった時
```:
git reset HEAD^ --soft
```
 
```:
git push -u origin <branch-name>
```

```:
git -u origin <branch-name> -f
```


RPをmergeした時に問題が起きたときの対処法（conflictなど）
```:
1. go to master
2. git pull
3. git reset --hard (static_pages commit -> your very first commit in master)
4. git push origin master --force
5. go to github
6. go to branches then VIEW ALL BRANCHES
7. delete static_pages branch
8. make student push static_pages branch again
9. make new pr
```
2021個人開発Webサービス案

明けましておめでとうございます。2021年もよろしくお願いします。

さて、今年の目標の1つとして、今年こそ個人のWebサービスを開発しようと思っています。
開発しようと思っているサービスと、使う予定の技術はざっと以下のような感じです。

# サービス名
　Tramories トラモリーズ（travel + memories）

# サービス概要
旅の写真（昔の写真も含む）を共有し合うサービス

# サービス詳細
投稿機能（写真＋簡単な説明）、タグ、コメント、いいね、ユーザーフォロー
　OAuth2認証（検討中）オススメ機能（検討中）

一般的なミニSNSっぽい感じですが、基本的には写真を投稿して共有する感じにしようかと。機械学習なんかも可能なら取り入れたい。

#使用技術

###サーバーサイド

　Java、Spring Boot（機械学習を入れる場合はPython、Flask）
Laravelを使うかかなり迷ったけど、今仕事で使っていることだし、Spring Bootにしようかと。
機械学習でおすすめ機能とかスパムフィルターとか取り入れるんだったら、Flaskで機械学習API作るのもありかなと思ったり。

###フロントエンド
　TypeScript、React
フロントエンドのフレームワークはこれかなと。JavaScriptで行くかTypeScriptにするかは若干迷っているけど。

###データベース
　MySQL
ここはこうなるか。PostgreSQLは一度も触ったことがないんで。最近流行りのNoSQLも今回はいいかなと。

###Webサーバー
　Apache
ここもこれしかないか。Nginxも最近は増えてきているようだけど、Apacheで。

###インフラ
　Microsoft Azure（Herokuなども検討中）
ここが一番の悩みどころ。以前AzureにWordpress入れたら1ヶ月で6000円とかしてすごい焦ったもんなあ。
誰かWebサービスを安くデプロイする方法を知っている方教えていただけるとありがたいです。

#ドキュメント、その他
　画面仕様書、テーブル定義書、機能設計書（処理フローなど）、単体テスト仕様書、結合テスト仕様書
個人サービス作る場合ってドキュメントとか公開するものなのかなあ？公開しないにしても仕事の練習になるだろうし、作ろうとは思っています。

少しづつ作って行って、何とか年内には公開したいなあ。
【Rails6】seedファイルに画像を追加する(ActiveStorage使用)

#はじめに
seedファイルに画像も追加したい時に、書き方が分からず悩んだので下記に記載します。
初学者による記載ですので、誤りがあればご指摘ください。

railsで画像を扱う場合、ActiveStorageかCarrierWaveを使っている場合が多いかと思います。
参考: [ActiveStorage vs CarrierWave](https://qiita.com/w5966qzh/items/510d4c2a3829524b2e64)

今回はActiveStorageを使っている場合ですので、使っている方のみお進みください。

#ユーザーの初期データをseedファイルに記載する
deviseを使用して作成したユーザーの初期データをseedファイルに記載していきます。

ユーザーモデルのカラムはこのようになっています。

```db/schema.rb

    t.string "name", null: false
    t.text "profile"
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.string "avatar"
    t.boolean "admin", default: false

```


deviseにデフォルトで入っているカラム以外に、ユーザー画像のカラムとして`avatar`を追加しています。
（その他にも、nameやprofile、adminを追加しています。)


```
% rails s
```

をしてブラウザから画像登録ができるか確認してください。
※私は最初できませんでした(笑)パラメータに`:avatar`を渡してないのが原因でした。

もしエラーなく追加できた場合は、seedファイルへの記載をしていきましょう。

```db/seeds.rb
user = User.create(name: "Saya", 
                  profile: "OLです。",
                  email: "aaa@aaa.com", 
                  password: "foobar", 
                  password_confirmation: "foobar",
                  admin: true)
```

まずはこれで下記コマンドを実施します。

```
% rails db:migrate:reset
% rails db:seed
```

上記で問題がなく初期データが反映されいるか確認しましょう。
問題がなければ画像(avatar)を追加します。


#seedファイルに画像を記載する

まず、`app/assets/images` に使いたい画像を追加します。
今回は`cat.jpg`というファイルを追加しました。

先ほどなぜ`user`を定義したのか。
それは、画像をattachするためです。
先ほどのseedファイルの記載にavatarを追加します。

```db/seeds.rb
user = User.create(name: "Saya", 
                  profile: "OLです。",
                  email: "aaa@aaa.com", 
                  password: "foobar", 
                  password_confirmation: "foobar",
                  admin: true)
user.avatar.attach(io: File.open(Rails.root.join('app/assets/images/cat.jpg')),
                  filename: 'cat.jpg')

```

そして

```
% rails db:migrate:reset
% rails db:seed
```

を実行してください。
反映されているかブラウザで確認してみましょう！


#最後に
ActiveStorageに関する情報が少なかったので、悩まれている初学者の方に届いたら幸いです！

参考
[ファイル/ IOオブジェクトの添付](https://edgeguides.rubyonrails.org/active_storage_overview.html#attaching-file-io-objects)
[【Rails 5.2】 Active Storageの使い方](https://qiita.com/hmmrjn/items/7cc5e5348755c517458a)
[Rails6 のちょい足しな新機能を試す64（db:seed 編）](https://qiita.com/suketa/items/38809e8455e59a5a3f90)
M5Stack Core2 for AWS その2

# M5Stack Core2 for AWS

[EduKitワークショップのサイト](https://edukit.workshop.aws/) にしたがって学習を進めると、最後は Intro to Alexa for IoT の課題です。M5Stack Core2 for AWS を Alexa にすることができます。

# Alexa Voice Service (AVS) Integration for AWS IoT

Alexaを動作させるための Alexa Voice Service (AVS) は通常Raspberry Piなど(M5Stackよりは高いスペック)が必要になります。Alexa Voice Service (AVS) Integration for AWS IoT (AFI) はM5StackのようなデバイスでもAlexaを動作させることができるようにした仕組みです。

デバイスはデバイスメーカーが提供するAWS IoT CoreにMQTTで接続して、負荷の高い処理はクラウド側で動作するようです。[Alexa Voice Service (AVS) Integration for AWS IoT のページ](https://docs.aws.amazon.com/iot/latest/developerguide/avs-integration-aws-iot.html) では、現時点で NXP i.MX RT 106 A と Qualcomm Home Hub 100 Development Kit for Amazon AVS の２つのデバイスが提供されてい流ようです。M5Stack Core2 for AWS では、Espressif社がAlexa Voice Service (AVS) Integration for AWS IoT環境を提供しています。

ということで、デバイスベンダーはAWS IoT Coreへの接続と、プロビジョニング(アプリ)で接続するデバイスを制限できるということになります。(簡単にM5StickVにポーティングするということはできなさそう)

![png](https://docs.aws.amazon.com/iot/latest/developerguide/images/iot-alexavoice-overview.png)

# 実行とハマりどころ

EduKitワークショップ全般を通じて、比較的入力する作業が多いのでビルドは慎重に進める必要があります。

環境は、こちらのブログ [WindowsでESP-IDF4.2環境を作る](https://lang-ship.com/blog/work/windows-esp-idf-42/) などで解説されていますが、ESP-IDF4.2環境を作るところから始まります。Python2.7は使えませんが、私の場合MacのデフォルトがPython2.7だったので途中でエラーになりました。Python3.9をデフォルトにしました。

ビルド時にエラーになり、Set up Environment Variables に記載された、

```
set CORE2FORAWS_PATH=/path/to/Core2-for-AWS-IoT-EduKit/Core2-for-AWS-IoT-Features-Demo
```

を、次のように変更しました（み さんのツイートを参考にさせて頂きました、ありがとうございます）

```
set CORE2FORAWS_PATH=/path/to/Core2-for-AWS-IoT-EduKit/Blinky-Hello-World
```

ビルドが終わったら、スマホアプリ (ESP Alexa) でWiFi接続のプロビジョニングを行いますが、なぜかiPhoneではデバイスを選択してパスワードを確認した後にアプリが終了してしまいます。代わりにAndroidで設定しました。Androidでは位置情報の許可が求められたので、位置情報を取得するようです。iPhoneでは位置の許可を取得できなくてアプリが終了してしまっているのかもしれません。

ようやく動作したら最初は英語をしゃべります。日本語に変更するのはスマホアプリ(ESP Alexa)です。次は住所がわからないと言ってくるので、ESP AlexaではなくAmazon Alexaアプリで住所を入力します。日本語でしゃべる場合は日本語で住所を入力する必要があるようです。

# まとめ

M5Stackのようなデバイスで普通に音声対話ができるようになってきていることに感動しました。ますます色々なデバイスに音声対話が組み込まれていきそうですね。