OmniAICreator/Qiita-1.07M huggingface dataset:
レゴみたいなお気軽IoTモジュール M5Stack を使ってみる

#はじめに
電子工作好きなだけど、センサー類とかモジュールばっかり増えちゃって、また家にいられないことも多いので、外出先とかでもお手軽にいじれるものがないかと物色。一時期入手困難だった [M5stack](https://ja.wikipedia.org/wiki/M5Stack) も入手しやすくなってきたので、いろいろ試してみることにする。M5StackはArduino互換機で、基本的にははんだ付けを必要としないマイコンキットです。

#準備

- M5Stack -- 大きく分けてstackC （長細いやつ）とGo（正方形）の２つがある。Go の方がセンサーが多くていろいろ遊べそう。基本的な開発環境とか扱いは一緒。
- PC or Mac --- 母艦として使用
- USB-C のケーブル

今回は、M5Flow で制御するための環境を準備します。

#ファームを最新版にする

##M5Burnerのダウンロード
M5Burnerを使ってファームをダウンロードしてから、更新します。

MBurner のダウンロードサイト
[https://m5stack.com/pages/download](https://m5stack.com/pages/download
)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231182/c0202394-0a87-4d31-cca3-ab82ada02441.png)

Mac版、Winwdows版両方あり。
##M5Burnerのインストール

ダウンロードしたファイルを解凍し、M5Burner.exeを実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231182/29f3d2a7-9170-e1e6-57e6-193cbae3301c.png)

##M5Burnerでファーム更新

1. USBでモジュールをPCと接続します。
2. M5Burnerを起動し、左ペインからファームイメージのダウンロードを行います。
3. ダウンロードをしたら、「Burn」ボタンを押してイメージファームへ書き込みを行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231182/949401dd-22f2-4b82-a781-c89a6f59fb8a.png)

もし、エラーが発生した場合は、Baudrateを変更して再度試してみてください。
成功すると100%までいき

```
Leaving...
Staying in bootloader.
```

という表示になります。

#つなげてみる
M5Stack はIoTモジュールtということもあり、もうすぐにWifiに接続して、ネットワーク経由でモジュールを操作することができます。そのためには、まずM5StackのWifi設定をPCかスマートフォンで、MSStackにWifi経由で直接接続する必要があります。

<img width="1317" alt="IMG_20200102_202626.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231182/dc7aa38d-3007-9324-2ac7-4adeb04d704e.png">

起動後、Setup - Switch internet mode を選択するとWifi設定の画面が表示されるので、その設定にしたがってPC かスマートフォンのSSIDを変更して直接M5Stackに接続します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231182/23d162f9-5c6b-c908-e087-acf993eb3247.png)

Wifiの設定が終わるとAPI Key が表示されるので、メモっておきます。

#M5Flow からの制御

[http://flow.m5stack.com/](http://flow.m5stack.com/)にブラウザでアクセスします。最初にAPI Key をきかれるので、メモった(もしくはM5Stackに表示されている)API Key を入力します。これで、直接インターネット経由で直接制御することができるようになりました。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231182/f9f9b006-3447-26dd-4bb0-606d35247fa7.png)

あとはコード書いて右上の再生ボタンを押すだけです。すぐにデバイスに書いたモジュールがロードされて実行されます。すごいね、これ。エミュレータいらないじゃん。

#つぎに向けて

モジュールがおしゃれ。なんかこの可愛さを生かしたものつくりたいな。候補は、卓上ｘｘとか。身に着けてもいいね。ネックレスとか受けるかもね。
Micro:bit 最初のパッケージに入っているプログラムに戻す方法


なんかいつもググってる気がするので、日本語でメモしておきます。

#問題の背景
マイクロビットを買って開封した直後のデモってよくできてるんですよ。はじめて触る人に、直感的に何ができるかを理解してもらうのにとても良いのです。でも、一旦ほかのプログラムで上書きしちゃうと、消えちゃうんです。例えば、プログラミング教室などで一斉にモジュールを生徒さんに触ってほしい時とか、モジュールを使いまわしていると消えちゃうわけです。

#答え　リストアの方法

以下のマイクロビットサイトからHEXファイルをダウンロードして、マイクロビットに書き込みます。

マイクロビットの工場出荷時の状態にする方法：
https://support.microbit.org/support/solutions/articles/19000021613-first-experience-demo-program

#さいごに
未来の自分に役立ちますように。
【小ネタ】JupyterをPDFに変換する簡単な方法

# はじめに
自分で書いたJupyter notebookをHTMLで保存してiPhoneで閲覧したところ、Texで書いた数式がうまく表示されませんでした。次にPDFでの保存を試みましたが、日本語を含んでいると標準のPDF出力は使えませんでした。

もちろんその解決方法は色々とありますが、ちょっと大変です。
[Qiita:日本語のJupyter NotebookをPDFとしてダウンロードする](https://qiita.com/masa-ita/items/8d5ebe8afe0d580af184)
[Qiita:Jupyter notebookからpdfに変換する[mac]](https://qiita.com/yasudadesu/items/7b4edec4498e425bf50c)

# 解決策
レイアウトが若干崩れる問題はありますが、手っ取り早いのはJupyterをHTMLでエクスポートして、ブラウザから印刷でPDFに変換する方法です。Google Chromeを使った手順を以下に示します。

1. "File" -> "Export Notebook As..." -> "Export Notebook to HTML"でJupyterをHTMLで保存する。
![exportHTML.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455608/30d68f0c-39fc-b778-2ee0-6cbcece6a49c.png)


2. ブラウザでそのHTMLファイルを開く。印刷をクリックする。
![print.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455608/fad7ad48-ea8c-8644-9279-4e237b6c7c00.png)

3. 送信先を"PDFに保存"に変更して、"保存"をクリック。
![PDF_print.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455608/ac704827-b8ff-047e-d78b-7f3dd4c2ffa9.png)

# 結果
日本語やTexもちゃんと表示されます。
![pdf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455608/7fe9f6ff-b231-7e82-8ba4-17c84e1e01ce.png)

# まとめ
~~いかがでしたか~~
(スマートスピーカー × obniz ) 声だけで部屋の電気をON,OFF ‼

# はじめに
スマートスピーカーを先日購入したものの、時間がなく勉強・実践をする機会がなかったため、年末年始の時間を使い「おうちハック」をしようと思い作ってみた。残念ながら、スマートスピーカから直接、部屋の電気を入・切ができなかったので今回は簡易版のもので作ってみる。

# 使用したもの
- obniz board
- Echo Show5 (スマートスピーカー）
- サーボモータ

# 制作の流れ
1. サーボを動かすプログラムを書く
　
2. obnizとスマートスピーカを連携
スマートスピーカ(Alexa)とobnizをIFTTTを介して連携させる。
3. 設置、実装

# 1.サーボを動かすプログラムを書く
電気のスイッチをオンにするプログラムは以下のように書いた。同様にオフにするときについても書く(obniz_numberはobniz固有の8桁の数字のことである)

```html
      (async function(){
        var obniz, servomotor; //変数設定


        obniz = new Obniz('obniz_number');
        await obniz.connectWait();
        servomotor = obniz.wired("ServoMotor",{"signal":2, "vcc":1, "gnd":0});
        while (true) {
          await ObnizUI.Util.wait(0);
          servomotor.angle(10);
        }

      })();
```

# 2. obnizとスマートスピーカを連携
[参考記事:obnizの公式HP](https://obniz.io/ja/lessons/airobot/lessons_airobot_googlehome)

(1) プログラムをリポジトリに保存
リポジトリに保存したプログラムはwebhookから自動で実行することがでいる。そのため、開発方法としてはリポジトリで新規作成してプログラムを書くか、別のエディタでプログラムを組んだ後にリポジトリにアップロードするかのどちらかであると思う。

(2) イベントに登録
開発者コンソール画面のイベントから「新規作成」ボタン->名前と実行するプログラムを選択、きっかけは「Webhook」とする。

このイベントはサーバーレスで設定ができるので便利ではあるが、3×(登録しているobnizの数)までしか登録できないので注意！![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474340/56e3212a-4dd6-6ca9-84de-ba79c9071a6c.png)


(3)IFTTTとの連携(iftttの登録　必要)
IFTTTへの登録は今回の記事では割愛する。
IFTTTにアクセスして、メニュー画面から「create」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474340/6d876946-9750-912b-0337-5468abd47940.png)

createボタンを押すと、下のような画面が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474340/8acdac85-dca4-67a2-288e-d5b5218d77e8.png)

今回は、もし(If)「電気をつけて」と言ったら(amazon Alexa) Then Webhookを起動してobnizを動かしたい。のでその設定を行う。

alexa側ではいろいろな設定ができるが、今回は"Say a specific phrase"を選択
Alexa triggerの後に設定した特定のフレーズを言うことによって起動される。

- ここで注意点であるが、Alexa trigger は、「Alexa」という意味ではなく、そのまま「trigger」まで言わなければいけないということに注意！つまり「アレクサ　トリガー　設定したフレーズ」と言う。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474340/ce85c109-fb30-4b9b-b6a7-30f9c9544f73.png)
その後の設定は簡単！設定したいフレーズを入力するだけ！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474340/1bf1d3d1-b8cd-94d2-ce1a-1e0b4398c2b4.png)

Thatの部分はwebhooksを選択 → Make a web request を選択
→ URLの欄に、obnizのコンソールのイベントのページで、WebhookのEndpointの直下に書かれているURLを入力する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474340/561e7691-2801-7662-56b9-cbe1814174ba.png)

# 3.設置、実装
完成品が下の写真である。調整も行い、電気をONにするときのサーボの角度を175°、OFFにするときの角度を155°に設定した。「アレクサ　トリガー　電気をつけて」というと電気がつき、「アレクサ　トリガー　電気を消して」というと電気を消すことができる仕組みを作れた！！
![IMG_8967.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474340/bca74917-e55a-478c-e0a9-bc6243d53e3c.jpeg)
Storyboardの設定項目

趣味でiOSアプリ開発をかじっていた自分が、改めてiOS開発を勉強し始めた際に、曖昧に理解していたところや知らなかったところをメモしています。いつか書き直します。

## 参考文献

この記事は以下の書籍の情報を参考にして執筆しました。4章を読んでの内容になります。

- [よくわかるAuto Layout iOSレスポンシブデザインをマスター](https://www.amazon.co.jp/%E3%82%88%E3%81%8F%E3%82%8F%E3%81%8B%E3%82%8BAuto-Layout-iOS%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B7%E3%83%96%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%82%92%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC-%E5%B7%9D%E9%82%89-%E9%9B%84%E4%BB%8B/dp/4865940324/)

##起動時のstoryboardを設定

GUIで設定
プロジェクトファイルのMain Interfaceでstoryboardを指定する。
下記のように設定してあるとMain.storyboardファイルが読み込まれる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542614/8d7647af-3eaf-81f2-882c-7cc3cdcf2288.png)



##storyboardで開始時のビューを設定する方法
矢印をドラッグして持ってくるか、is initial View Controller にチェックを入れる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542614/8fac033b-2d6c-dc3e-eecb-071f3cd794d6.png)



##stackボタン
部品を複数選択して下記のボタンを押すとstackViewを作ることができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542614/37ff2362-45b0-d11a-acca-3e6bdfbfd052.png)


##親子関係にあるビューの制約
子ビューから親ビューへCtrol+ドラッグした時に追加できる制約で、親子間での比率など制約を設定できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542614/a834eaff-5de9-b17b-9f71-582e277dcc54.png)


##xibファイ ルの呼び出し
xibファイルを作成。
Viewを作って背景色を青にする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542614/a65241c6-1a38-7b30-74cd-c42baf77af0f.png)

####呼び出したい箇所で読み込む。
(guardでnilのチェックをしているが他の方法でもいい)

```swift
    // xibファイルの呼び出し
    guard let subView = Bundle.main.loadNibNamed("Xibファイル名", owner: nil, options: nil)?.first as? UIView else { return }
    self.view.addSubview(subView)
```

####カスタムクラスのビューに指定し、カスタムクラスを呼び出す。
xibファイルに属性を追加したりできる。

```swift:XibView.swift
import UIKit

class XibView: UIView {
  override init(frame: CGRect){
    super.init(frame: frame)
    loadNib()
  }
  
  required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)!
    loadNib()
  }
  
  func loadNib(){
    // xibファイル読み込み
    guard let view = Bundle.main.loadNibNamed("View2", owner: nil, options: nil)?.first as? UIView else { return }
    view.frame = self.bounds
    self.addSubview(view)
  }
  
}
```

使い方例

```swift
    let subView = XibView(frame: CGRect(x: 50, y: 50, width: 400, height: 700))
    self.view.addSubview(subView)
```

##storyboard分割
Storyboard Referenceを用いてstoryboardを分割し、参照することができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542614/20f814f6-d091-fdbc-ea7a-64b09dd61477.png)

分割したい範囲をまとめて選択し、「Editor」→「Reference to Stroryboard」を選択し、新しいstoryboardを名前をつけて保存。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542614/2eeafc38-6510-c38b-c914-4cf18c22f923.png)
選択した範囲だけで構成される　storyboardができた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542614/f1d97c6f-5923-86b5-dcac-54602676c07c.png)
分割元の方では参照するstoryboardが表示されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542614/be41a4e3-3922-5a30-57c7-f946bba0ed81.png)
亚信安全2020HW方案

## <font color=#983634>亚信安全HW背景介绍</font>
HW是以攻防实战为手段来提升重保和关键信息基础设施单位的安全建设和运维能力。从历年HW的实际情况看，只靠安全产品的简单堆砌 已经远远不能满足企业在攻防对抗背景下的安全需求。HW期间安全产品的可运维能力和安全人员的服务能力尤为重要。亚信安全以联动 的安全产品为工具，攻防专家服务为手段，以产品+服务共同帮助客户在HW防守中取得优异的成绩。
## <font color=#983634>亚信安全HW能力优势</font>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491410/3c9d2208-b0ea-5c31-30fd-7693873c5731.png)
## <font color=#983634>亚信安全HW整体方案</font>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491410/311efb15-4d13-8da5-ddfc-a9f3add89f13.png)
## <font color=#983634>亚信安全HW产品方案</font>
通过产品联动及高级感知运维平台，可以让HW期间产生的海量告警以更快捷，更轻快，更精准地被自动化处置，能够让更多用户享受
精密编排带来的好处，也能够解决安全产品多元化，碎片化以及运维专业化的落地问题。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491410/1ec1461d-5904-9ff6-1344-445c2164d8f5.png)
## <font color=#983634>亚信安全HW服务方案</font>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491410/81d914e5-eadf-d3cf-17c8-f0e78cc1c0a7.png)
<br/>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491410/c995fd8f-acc5-ad77-81e1-569089c54db9.png)
Auto Layoutの基本

趣味でiOSアプリ開発をかじっていた自分が、改めてiOS開発を勉強し始めた際に、曖昧に理解していたところや知らなかったところをメモしています。いつか書き直します。

## 参考文献

この記事は以下の書籍の情報を参考にして執筆しました。1,2章を読んでの内容になります。

- [よくわかるAuto Layout iOSレスポンシブデザインをマスター](https://www.amazon.co.jp/%E3%82%88%E3%81%8F%E3%82%8F%E3%81%8B%E3%82%8BAuto-Layout-iOS%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B7%E3%83%96%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%82%92%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC-%E5%B7%9D%E9%82%89-%E9%9B%84%E4%BB%8B/dp/4865940324/)

#Adaptivityなレイアウトを実現する

画面サイズの多様化により、どのようなウィンドウサイズでも対応できる柔軟性のあるレイアウトが求められるようになった。ウェブ世界のレスポンシブレイアウトとほぼ同じ意味合いで用いられます。

####Auto Layoutやトレイコレクションという概念。
Auto Layout : コンテンツをベースとしたレイアウト方法。
トレイトコレクション : 画面情報を抽象的なオブジェクトとして扱う概念。サイズクラスなど。


##サイズクラス
画面の高さと幅を抽象的に示す。

|端末と向き|高さ|幅|
|---|---|---|
iPad縦|Regular|Regular
iPad横|Regular|Regular
iPhone縦|Regular|Compact
iPhone横|Compact|Compact
iPhonePlus縦|Regular|Compact
iPhonePlus横|Compact|Regular

#Auto Layoutの基本概念
##制約式
Auto Layoutは制約を表した数式である制約式の連立方程式を解くことでレイアウトを決定している。

####例1
画像のButton2はButton1から50pt下の座標にある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542614/605a26fc-a39c-0e45-c0dd-e554122eed87.png)



この時の制約式

```swift
Button2.top = Button1.bottom + 50
```

storyboardのContaintsで制約の式が観れる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542614/890c51c8-1611-19a3-3b1e-ad464a8065b1.png)


####例2

緑のViewの上端と右端、左端を親ビューに固定し、緑ビューと親ビューの下端に20%のマージンを置く。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542614/61acc78b-c52f-75a3-7fae-55b63a6d955c.png)


この時の制約式

```swift
greenView.top = superView.top
greenView.left = superView.left
greenView.right = superView.right
greenView.bottom = 0.8 * superView.bottom
```


これらの線形式を一般化すると次の式になる。
y = ax + b

Auto Latoutでは上記の式を複数持つ線型方程式を解いている。

#Auto Layoutの基本概念

##オブジェクトの要素

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542614/3ff78b0c-e64f-73e9-4e54-63484e817475.png)

####Leading, Trailing
日本語や英語ではRight, Leftと同値だが、アラビア語などではLeftとRightが反転してしまうので。基本的にはこちらが使われる。

####Center X, Center Y 
x座標,、y座標。

####Baseline
テキストを整列するための基準線。文字列最初のBaselineのみFirstBaselineで示される。
gなどBaselineをはみ出す文字ように空白を調整したりする時など使える。

####NotAnAttribute
比較オブジェクトがない場合も要素を渡す必要があるので、代わりにNotAnAttributeを使う。

##Relation - 要素の関連性
Relationは制約式　y = ax +b の「=」の部分を示している。

```swift
enum NSLayoutReration : Int {   case LessThanOrEqual    // 制約より小さな値でレイアウトを実施
  case Equal    // 制約通りの...
  case GreaterThanOrEqual    // 制約より大きな...
}
```

##Priority - 優先度
1~1000の優先度を設定することができる。標準の値は1000で最大。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542614/2607af2f-78d1-5cd8-7695-c3db2223fe76.png)

##Intrinsic Content Size - 固有の寸法
UIButtonなどの文字列の長さ、フォントのサイズによって大きさを変えるオブジェクトに使われている。
値を取得することも可能。

##Content Hugging Priority, Content Compression Resistance Priority - コンテンツに対する優先度

「大きくなりにくさ」と「小さくなりにくさ」を定義している
vertical : 縦方向
horizontal : 横方向

storyboardから設定ができ、それぞれ優先度を指定できる。
優先度より低い制約では大きさが変わらない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542614/f0ae711f-ef4f-4dea-6cc8-104b7d1b2cb1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542614/763cb0aa-2d57-a519-b793-5ca36b7970d9.png)
質問です。rasｐberry pi 3 modelB にprotocolbuffersをmakeできない。

ラズベリーパイで画像認識をするために、Qiitaの投稿などをもとに”protocolbuffers”をインストールしています。” ./configure”でエラーが出てしまいます。その後"make”しようとしていますが、”make: *** ターゲットが指定されておらず, makefile も見つかりません.  中止.”となり、前に進むことが出来ません。
どなたか、解決方法を教えて頂けないでしょうか？
投稿元：https://qiita.com/kobayuta/items/59c7b84caf8994071357

以下エラーコード：
$ cd protobuf-3.7.1
$ ./configure
checking whether to enable maintainer-specific portions of Makefiles... yes
checking build system type... armv7l-unknown-linux-gnueabihf
checking host system type... armv7l-unknown-linux-gnueabihf
checking target system type... armv7l-unknown-linux-gnueabihf
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... no
checking for mawk... mawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking whether UID '1000' is supported by ustar format... yes
checking whether GID '1000' is supported by ustar format... yes
checking how to create a ustar tar archive... gnutar
checking for gcc... no
checking for cc... no
checking for cl.exe... no
configure: error: in `/home/pi/protobuf-3.7.1':
configure: error: no acceptable C compiler found in $PATH
See `config.log' for more details
$ make
make: *** ターゲットが指定されておらず, makefile も見つかりません.  中止.
$
GKEでnginxを外部アクセス可能にするまで

# はじめに
GKE上でクラスの作成からnginxを起動して外部からアクセスするために
自分がした手順を残しておきます。
# 手順
## 1.GCPアカウント無料トライアルの開始
1年間約33000円分のクレジットがついてくるとのことなのでこれを使った。

## 2.kubernetesクラスタの作成
以下GCP CloudConsole画面での操作。
Kubernetes Engine -> クラスタから作成できる。今回は標準のクラスタテンプレートをそのまま使った。

**備考**
kubernetesクラスタは、コンテナ化されたアプリケーションを実行するためのVM インスタンスのマネージド グループのこと。
(これはConsole画面に書いてあったことのコピペです)
このクラスタを作成しないことには何もできない。

## 3.ワークロードの作成
今回はデフォルトで選択されていたnginx:latestをそのまま使った。
![スクリーンショット 2020-01-03 12.50.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55609/9c78ddbd-c7ab-a6b8-9734-be651117955e.png)

- ワークロードの画面に表示されるのはノードの一覧。
- ノードは1つ以上のpodを管理している。
- podの個数はワークロードの作成時に決定する。
- デフォルトでは外部公開されない状態で作成される。

## 4.サービスの作成
3の手順で作成したノードの詳細画面からGUI上で選択できる。
画面の下の方にサービスの公開という項目があるので「公開」ボタンを押す。
![スクリーンショット 2020-01-03 13.02.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55609/0302b4c6-3625-2440-83d9-02535a8f849f.png)
Serviceのタイプをロードバランサで作成する画面が出てくるのでそのまま「公開」ボタンを押す。
![スクリーンショット 2020-01-03 13.02.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55609/a606bb9d-b603-e415-bee4-e14ab8216628.png)

**備考**
サービスを使用したアプリケーションの公開
https://cloud.google.com/kubernetes-engine/docs/concepts/service?hl=ja

## 5.ブラウザからアクセスする
Kubernetes Engine -> ServicesとIngressを開くと以下の様にサービスが作成されているので、
エンドポイントを選択するとnginxにアクセスできる様になっている。
![スクリーンショット 2020-01-03 13.05.34.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55609/278b5978-bf68-f5fa-d345-545cfe8d4862.jpeg)
![スクリーンショット 2020-01-03 13.45.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55609/ae8af4a6-b4ac-0fb0-6886-38d316a6b465.png)
Routing Error No route matches [PATCH] "/admin/users/1"が発生

最近の勉強で学んだ事を、ノート代わりにまとめていきます。
主に自分の学習の流れを振り返りで残す形なので色々、省いてます。
Webエンジニアの諸先輩方からアドバイスやご指摘を頂けたらありがたいです！

#Formtastic::UnknownInputError Unable to find input class Input

このエラーが起きた状況は、Active Adminで作成したユーザー管理画面において編集機能を追加するために
actionsに:editを追加した所、発生しました。

```app/admin/users.rb
actions :index , :show , :edit
```

Routing Errorと書いていることから、ルーティングに何らかのエラーが出ていることが考えられる。
さらにその下に
No route matches [PATCH] "/admin/users/1"
と書いてあることから、"/admin/users"ってところと[PATCH]がマッチしていないことが考えられる。

"rake routes"で、どの様に設定されているルーティングを見てみた所、エラー通りadmin_user_pathの[PATCH]が無かったです。
しかし、routes.rbの設定を変更してもエラーが直らず、というかactionsの方を追記しないといけないのではと思い。
以下の様に記述した所、Routing Errorが直りました。

```app/admin/users.rb
actions :index , :show , :edit, :update
```

これに直ぐに気づくことができなかったのが恥ずかしいです。。。

##参考にした記事
・[エラー解決Routing Error　No route matches - Qiita](https://qiita.com/life_code/items/b148643312f13096ac7a/)
・[rails APIモード＋ActiveAdminで、管理者画面にてユーザーを削除しようとしたらNo route matchesのエラーが発生した際の対処法 - Qiita](https://qiita.com/inteM/items/89c7b98ff9b7cd36790d/)
MySQLでカラム名が変えられない

ドットインストールでPHP学習入門を取り組んでいる際...

```php:index.phpにて

  // ユーザーをDBに登録してブラウザに user add!!! と出力したい
  $db->exec("insert into users (name, score) values ('tanaka', 99)");
  echo "user add!!!";
```

よっしゃ、これでOKなはずと思ったがブラウザで以下エラーが表示される:fearful:

```
エラーSQLSTATE[42S22]: Column not found: 1054 Unknown column 'score' in 'field list'
```

# 原因
ターミナルでusersテーブルを見ると、scoreで作ったはずがscireと作っていました。

```
mysql> desc users;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| name  | varchar(255) | YES  |     | NULL    |                |
| scire | int(11)      | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
```

ささっとググり、ターミナルでカラム名を変更るためにコマンドを叩く

```terminal
alter table users change column scire score;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
```
あれなんでエラーが出るんだろう.....

# 対策
**カラム名を変更するときは型も指定しなければいけない**
先ほどのコマンドの最後に**int**を追加して再度実行すると、無事DBにデータも登録出来てブラウザにも期待通りの出力が出来ました:v_tone2:

```
mysql> alter table users change column scire score int;
Query OK, 0 rows affected (0.12 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc users;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| name  | varchar(255) | YES  |     | NULL    |                |
| score | int(11)      | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

```
Svelete module 挙動 メモ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32636/bcfddb43-d60d-ebde-3b53-983191e6319e.png)


```html:App.svelte
<script>
	import { onMount } from 'svelte';
	
	import Box, {moduleVariable} from './Box.svelte';
	console.log(moduleVariable);
	
	let boxone;
	let boxtwo;
	
	onMount(async () => {
		console.log("boxone.text", boxone.text);
		console.log("boxone.moduleVariable", boxone.moduleVariable);
		console.log("boxone.getModuleVariable()", boxone.getModuleVariable());
		console.log(Box.moduleVariable);
	});
	
</script>

<Box bind:this={boxone} text="Box one" moduleVariable="aaa"/>
<Box text="Box two" moduleVariable="aaa"/>
```

```html:Box.svelte
<style>
	.box {
		border: solid 1px black;
	}
</style>

<script context="module">
	let count = 0;
	export let moduleVariable = "a default variable in a module context";
</script>

<svelte:options accessors={true}/>

<script>
	import { onMount } from 'svelte';
	
	export let text = "Empty";
	
	onMount(async () => {
		count += 1;
		console.log(text, count);
	});
	
	export function getModuleVariable() {
		return moduleVariable;
	}
	
	function buttonClick() {
		console.log("buttonClick");
	}
</script>

<div class="box">
	{text}, {moduleVariable}
</div>
<button on:click={buttonClick}>
	button
</button>
```
JavaScript:クイックソートを末尾再帰にしてみる

クイックソートを末尾再帰にしようと思ったのだが、「あれ、これ無理じゃん」と思ったので調べてみた。
継続渡し、というものがあってそれを使うとできるらしい。

元記事：[再帰クイックソートの可視化](http://nanto.asablo.jp/blog/2007/02/06/1167686)

詳しくは元記事を参照してください。
ここでは、アロー関数を使って今風にしてみたらどうなるか?をやってみます。


```js:
// 先頭の要素との大小で配列を二つに分割する関数
const divByHead = xs =>
  xs.slice(1).reduce(
    (acc,e)=>
      e <= xs[0] ? {...acc, le:[...acc.le, e]}
      : {...acc, gt:[...acc.gt, e]}
    , {le:[], gt:[]}
  )

// 末尾再帰でないクイックソート
const qs = xs =>{
  if(xs.length === 0) return []
  const divided = divByHead(xs)
  return  [...qs(divided.le), xs[0], ...qs(divided.gt)]
}

//継続渡しスタイルのクイックソート
const qs_cps = xs => k =>{
  if(xs.length === 0) return k([])
  const divided = divByHead(xs)
  return qs_cps(divided.le)(
    v1 => qs_cps(divided.gt)(
      v2 => k([...v1, xs[0], ...v2])
    )
  )
}

// 使いかた:
const qs2 = xs => qs_cps(xs)(v => v);
qs2([9,4,5,7,2,5,1]);   // [ 1, 2, 4, 5, 5, 7, 9 ]

qs([9,4,5,7,2,5,1]);    // [ 1, 2, 4, 5, 5, 7, 9 ]
```
できた!
どうしてうまくいくのか?説明はできないが、ふわっとは理解できたし、末尾再帰への変換もできそう。
Python 忘備録

# 趣旨

python 関係でググる前にこれ読んどけ的な団員向けメモ。

- **セミコロンはいらない**
- **変数は宣言不要**
- **字下げはスペース**でやる。TABは許されない。
- **None** を使う。NULL, null, nil, undefined などは無い
- **True**, **False** は先頭大文字。true, false ではない
- **if, for, while は末尾にコロンが必要**。括弧は不要。
- **begin** や **end** はない
- if, for, with, while, try, def などの本文はインデントも必要。
- else は字下げしてコロンも必要
- **論理和、論理積、否定は or, and, not**
- **switch/case はない**。elif を使う。
- **a++ は不可**。a+=1
- next ではなく **continue**
- **剰余は %** (mod ではない）
- ライブラリ読み込みは import, as で短縮できる
- 引数受け取りは sys.argv。仕様は C と同じで0番目にコマンド名が入る。でも argparse 推奨。
- print は改行が入る。end="" を入れと改行されない。
- キャストは明示的に必要 int(a) とか
- **double はない**。float はある。
- printf 的な構文は % を使う。"%02d"%val みたいな。
- f = open("file","r") または with open("file","r") as f:
- write はアスキー書き込み、改行は入らない。バイナリは別途
- コメントアウトは #。複数行は ``` (バッククオーテーションx3）
- range(0,x) は 0 から x-1 まで
- 強制終了は sys.exit(error_code)
- 配列の初期化は a = [] とか a = [1,2,3] とか
- 配列の要素追加は arr.append(item)
- 連想配列の初期化は a = {} とか a = {"hoge":2,"huga": "xx"} とか。
- 連想配列の参照は a['key'] = value
- ビット演算は C と同じ( `&`: 論理積, `|`: 論理和, `>>`: 右シフト, `<<`：左シフト、 `^`: 排他的論理和、 `~`: ビット反転 )

正規表現はこのあたり：https://qiita.com/luohao0404/items/7135b2b96f9b0b196bf3

json はこのあたり：https://qiita.com/unchainendo/items/7865bdcdaadd62f2e435

とりあえず下のコードを一度みておくべき。

```syntax.py
# import cv2
# import tensorflow as tf
import sys

def main():
    x = 0
    y = 2

    args = sys.argv
    if len(args) < 2:
        print( "%s: too few args"%args[0] )
        sys.exit(1)
    else:
        try:
            x = int(args[1])
        except:
            print( "%s is not a number."%args[1] )
            sys.exit(2)

    z = x * y
    print( "x * y = %d, "%z, end="" )

    arr = []
    for i in range(0,x):
        arr.append(i)

    sum = 0
    for a in arr :
        sum += a
        
    wstr = "sum:%d"%sum
    rstr = ""
    print( wstr )
    
    with open("test.txt", "w") as fw:
        fw.write( wstr )
    
    with open("test.txt", "r") as fr:
        rstr = fr.read()
        print( "read data =", rstr )

    h = {}
    h['hoge'] = x
    print( "hash['hoge'] = %d"%h['hoge'] )

if __name__ == "__main__":
    main()

```
## 型関連

```py
a = 10
print(float(a)
# 10.0
b = 10.01
print(int(b))
# 10
c = "1.01"
d = "-1.01"
print(int(c))
# エラーになる
print(float(c))
print(float(d))
# 1.01
# -1.01
e = "0x10"
print( int(e,16) )
# 16
f = 10.01
print( str(f) )
# '10.01'
```

## 数値計算

- int: 整数肩に変換。絶対値が小さくなる整数へ切り捨て・切り上げ
- math.floor：小数を切り捨て
- math.ceil: 小数を切り上げ
- round：小数を四捨五入
- random.random(): 0から1の間の小数の乱数を発生させる。(要 `import random`）

```.py
import math
a = 1.11111
b = -2.22222
str = "-3.14159"
print( int(a) )
# 1
print( int(b) )
# -2
print( math.floor(a) )
# 1
print( math.floor(b) )
# -3
print( math.ceil(a) )
# 2
print( math.ceil(b) )
# -2
print( round(a) ) 
# 1
print( round(b) )
# -2
import random
print( random.random() )
# 0.48396949711696924 など
```


## 正規表現

## ファイル読み書き

## 子プロセス実行

## 配列の初期化、操作

## 連想配列

### JSON 関連
【jQuery】pickadate.jsを使ってフォームにカレンダーを表示させる

こんにちは！スージーです！
久し振りにrailsでアプリ開発を開始したのでその際に使った`datepicker`についてまとめ

## datepickerとは

![スクリーンショット 2020-01-02 18.25.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428016/34bea1f8-09e7-6cb2-7678-c3cc9855deae.png)

日付入力フォームを選択した時に表れるカレンダー


## 参考記事

>
結局、どのdatepickerが一番使い勝手がよいのかhttps://qiita.com/knt45/items/6d74f6785cd4547ae53b

>
Rails Application Build Guides
https://rails.densan-labs.net/form/datetime_register_form.html

>
pickadate.js
https://amsul.ca/pickadate.js/

>
pickadate-rails
https://github.com/veracross/pickadate-rails


## 準備

```ruby:Gemfile
gem 'pickadate-rails'
```
で`bundle install`

```js:application.js
//= require pickadate/picker 追記
//= require pickadate/picker.date 追記
//= require pickadate/picker.time 追記
//= require jquery_ujs
//= require_tree .
```

```scss:application.scss
@import "pickadate/classic";
@import "pickadate/classic.date";
@import "pickadate/classic.time";
```
cssレイアウトは`default`又は`classic`が選べるようになっている

## Jsファイル

```js:datepicker.js
$(function() {
  $( "#datepicker" ).pickadate(); // カレンダー表示のイベント
});
```
Jsはこれだけで使えるようになる。リファレンスには色々なレイアウトのカレンダーが用意されている。

## turbokinksでイベント発火しない

jQueryあるあるですがturbolinksをtrueのままにしているとページをリロードしないとイベント発火しないので、今回は不要なので削除。`application.js`,`application.html.erb`のturbolinksに関するコードは削除。`gem 'turbolinks'`も削除して`bundle install`します。

## contorollerのアクション作成

```ruby:datepickers_controller.rb
class datepickersController < ApplicationController

  def new
    @datepicker = Datepicker.new
  end

  def create
    @datepicker = Datepicker.create(datepicker_params)
    if @datepicker.save
      redirect_to :root
    else
      render :new
    end
  end

  private

  def datepicker_params
    params.require(:start_day).permit(:start_day).merge(user_id: current_user.id)
  end
end
```
この辺はお決まりのnew/createアクションです

## 完成

カレンダーで日付を選択して登録できている事をパラメータを確認

```terminal:ターミナル
Started POST "/start_days" for ::1 at 2020-01-03 12:50:13 +0900
Processing by StartDaysController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"4Ug39AI0MM0azF2XqNEcTOSQNjpNWQ+ovCSI7PFrPPatvEM8avbMZ6MII5JdxZnni+Hssbo7x6NTAjA0udiH7Q==", "datepicker"=>{"datepicker"=>"3 January, 2020"}, "commit"=>"登録"}
```

パラメータの値がちゃんとDBに保存されています

## まとめ

日付の選択は何かを登録する場面で使う事が多いかと思いますし、年月日をそれぞれ入力するのはUI/UX的に煩雑になってしまいますが、datepickerを使えば便利になりますし、簡単に実装もできました。
ラズパイ4にdartのstable版をインストール

# 背景
公式ページの [Get the Dart SDK | Dart](https://dart.dev/get-dart) からだとインストールができなかった
ラズパイ自体を調べたら、以下の結果が得られた

```zsh

# debianでサポートしているマルチアーキテクチャを調べる
$ dpfg --print-architecture
# arm hard floatの略、ハードウェア浮動小数点をサポートするarmプロセッサー(armv7+)
armhf

# cpuでどんな機能をサポートしているのかが参照できる
$ less /proc/cpuinfo
processor       : 0
model name      : ARMv7 Processor rev 3 (v7l)
BogoMIPS        : 108.00
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xd08
CPU revision    : 3
︙
# Featuresでサポートされている機能が分かる

# ラズパイのマシン（ハードウェア）のタイプを調べる
$ uname -m
armv7l
```
[5.4. dpkg を用いたパッケージの操作](https://debian-handbook.info/browse/ja-JP/stable/sect.manipulating-packages-with-dpkg.html)
[linux - What is difference between arm64 and armhf? - Stack Overflow](https://stackoverflow.com/questions/37790029/what-is-difference-between-arm64-and-armhf)
[Instruction Sets | Floating Point – Arm Developer](https://developer.arm.com/architectures/instruction-sets/floating-point)

パッケージマネージャからインストールする場合だとAMD64 (64-bit Intel)しかサポートしていないため、ラズパイのマシンタイプと合わない
[Is Dart available for Raspberry Pi? - Stack Overflow](https://stackoverflow.com/questions/20021336/is-dart-available-for-raspberry-pi)

つまり、cpu情報から分かったマシンタイプARMv7に合ったSDKをzip形式で直接ダウンロードするしかない

# ダウンロード&配置
[Archive | Dart](https://dart.dev/tools/sdk/archive)
アーカイブページでStable版のARMv7をダウンロードする

ダウンロードできたら、 `/usr/lib` 配下にコマンドのバイナリファイルを配置させる

```zsh

# ダウンロードしたディレクトリまで移動してから実行
$ sudo unzip <ダウンロードしたzip>
$ mv dart-sdk dart
$ mv dart /usr/lib/

# 使っているshellに合わせてファイルパスを通す
export PATH="$PATH:/usr/lib/dart/bin"
```

これでラズパイ環境でもdartが使えるようになる
PHP if文書き方まとめ

# 目的

- PHPのif文の書き方をまとめる

# 分岐で使用する比較演算子

|比較演算子  |意味  |
|---|---|
|A < B  |AがBより小さい  |
|A <= B  |AがB以下     |
|A > B  |BがAより小さい  |
|A >= B  |BがA以下     |
|A == B |AがBと等しい   |
|A === B |AがBと型も含めて等しい   |
|A != B |AがBと異なる   |
|A !== B |AがBと型も比較対象として異なる   |

# 偽になる値

- 文字列の場合: 空か"0"の時
- 数値の場合: 0 0.0など
- 論理値の場合: false
- 配列: 要素の数が0の時
- データがnullの時

# 書き方の例

- ifのみを用いた分岐

```php
if (条件式) {
  条件式が真の時の処理
}
```

- elseを用いた分岐

```php
if (条件式){
    真の時の処理;
}else{
    偽の時の処理;
}
```

- elseifを用いた分岐

```php
if (条件式A){
    条件式Aが真の時の処理;
}elseif (条件式B){
    条件式Bが真の時の処理;
}else{
    条件式が偽の時の処理;
}
```

# より具体的な書き方の例

- 変数`age`の値に応じて二十歳か二十歳じゃないのかを表示する処理を記載する。

```php
if ($age == 20){
    echo "二十歳です";
}else{
    echo "二十歳ではありません";
}
```

- 変数`age`の値に応じて二十歳か二十歳じゃないのかを表示する処理を記載する。条件式を否定する。

```php
if (!($age == 20)){
    echo "二十歳ではありません";
}else{
    echo "二十歳です";
}
```

- 変数`score`の値に応じてそれぞれ結果を返す条件分岐式

```php
if ($score > 80) {
    echo "grate!";
}elseif ($score > 60){
    echo "soso!";
}else{
    echo "bad!";
}
```
TypeScript EnumにvalueOfメソッドを実装する

TypeScriptのEnum（列挙型）にはvalueOf（文字列から対応するenum要素を取得する）メソッドが用意されていないため、実装を追加する方法を調査した。なお、Enumには任意のメソッドを追加できないため、namespaceを利用して実装している。

##### Numeric Enum

自動インクリメントされた数値が割り当てられる数値型（Numeric）Enumでは、逆引きマップ（Reverse Mapping）が利用できるため、`Enum[string]` でvalueOf相当の処理を実現できる。ただし、そのままでは型エラー（Element implicitly has an 'any' type...）となるため、以下のいずれかの記述とする必要がある。

* `Enum[string as keyof typeof Enum]`
* `(<any>Enum)[string]`

###### 実装例

```typescript
/* Numeric Enum */
enum Color { Red, Green };

// toString()
Color.Green.toString(); // => '1'
Color[Color.Green]; // => 'Green'

// valueOf()
namespace Color {
  export function valueOf(str: string) {
    return Color[str as keyof typeof Color];
  }
}
const str = 'Green';
Color.valueOf(str); // => NumericEnum.Green
```

##### String Enum

任意の文字列を割り当てる文字列型（String）Enumでは、Reverse Mappingが利用できない（※）ため、自分で逆引き用のMapオブジェクトを用意する必要がある。

###### 実装例

```typescript
/* String Enum */
enum Color { Red = 'red', Green = 'green' };

// toString()
Color.Green.toString(); // => 'green'

// valueOf()
namespace Color {
  const reverseMap = new Map<string, Color>();
  Object.keys(Color).forEach((s: string) => {
    const e = (<any>Color)[s];
    reverseMap.set(e.toString(), e);
  });
  export function valueOf(str: string) {
    return reverseMap.get(str);
  }
}
const str = 'green';
Color.valueOf(str); // => StringEnum.Green
```

※ Numeric Enumと同様にEnumのキー名からEnumを取得することはできるが、Enumに割り当てた文字列からEnumを取得することはできない。

```typescript
let str = 'Green'
Color[str as keyof typeof Color]; // => Color.Green
str = 'green'
Color[str as keyof typeof Color]; // => undefined
```

##### 参考

* [Enums - TypeScript Documentation](https://www.typescriptlang.org/docs/handbook/enums.html)
* [静的関数を持つ列挙型(Enum with static functions) - TypeScript Deep Dive](https://typescript-jp.gitbook.io/deep-dive/type-system/enums#wotsuenum-with-static-functions)
* [How do I convert a string to enum in TypeScript? - Stack Overflow](https://stackoverflow.com/questions/17380845/how-do-i-convert-a-string-to-enum-in-typescript)
* [Reverse-Mapping for String Enums - Stack Overflow](https://stackoverflow.com/questions/44883072/reverse-mapping-for-string-enums)
* [#20813 Iterating on a string enum - GitHub](https://github.com/Microsoft/TypeScript/issues/20813)
【SQL】メモ3(テンポラリテーブル作成(CREATE TEMPORARY TABLE ))

###0.目的
SQL忘却防止のため

###1.SELECT結果からテンポラリテーブルを作る
※複数テーブルを扱うときは、テーブル名.列名とすると
長くなるし扱いにくいため
FROM句でテーブル名 エイリアス名とすると
エイリアス名でアクセスできて便利。


```sql
-- SELECT結果を代入
CREATE TEMPORARY TABLE tmp_nohibrid as
 SELECT T1.id,T1.dname0,T1.type0 
 FROM tbl_dino T1
 WHERE T1.n_src1=0 and T1.n_src2=0;
```

###2.型指定してテーブルを作成してから、データを挿入する
```sql
-- 型指定して作成
CREATE TEMPORARY TABLE tbl_nohibrid
 (id INTEGER
,type0 TEXT
,dname0 TEXT
);

INSERT INTO tbl_nohibrid(id,type0,dname0)
 SELECT T1.id,T1.type0,T1.dname0
 FROM tbl_dino T1
 WHERE T1.n_src1=0 AND T1.n_src2=0;
```
初学者によるプログラミングMemo　#16 sliceメソッド（[]メソッド）

# はじめに
今回はsliceメソッドを使用するお話です
破壊的メソッドにも触れます
なお、本記述はMacにおいて、Railsでの開発を前提としています
また、まだまだひよっこですので、不備等ございましたらご指摘いただけると幸いです

# 目次
- "slice"メソッドについて
- []について
- 破壊的メソッドについて
- 問題
- 破壊的メソッドを使わない様に書いてみる

## "slice"メソッドについて
[こちら](https://ref.xaio.jp/ruby/classes/string/slice)によると「sliceメソッドは、[]の別名です。引数にしたがって文字列の中から部分文字列を取り出します。」とあります
引数に整数一つを指定すると、その一文字を取り出す事ができます　*Ruby1.9以降
少し使ってみます

```.rb
array = "school"
p array.slice(0)
=> "s"
```
0番目の一文字を取り出せました
元の変数には変化がありません

```.rb
array = "school"
p array.slice(0)
p array
=> "s"
=> "school"
```

## []について
silceメソッドの別名というだけあって、使い方は同じです

```.rb
array = "school"
p array[0]
=> "s"
```
0番目の一文字を取り出せました
同じく元の変数には変化がありません

```.rb
array = "school"
p array[0]
p array
=> "s"
=> "school"
```
記述的にはシンプルなので、こちらを使うほうが良さそうですね

## 破壊的メソッドについて
破壊的メソッドとは、実行した時に元となったのオブジェクト自身の内容を変更してしまうメソッドのことです。
基本的には、メソッドの最後に"!"がつきます
先ほどの配列"array"でやってみましょう

```.rb
array = "school"
p array.slice!(0)
=> "s"
```
ここまでは同じです
しかし、元の配列の中身を示すとこうなります

```.rb
array = "school"
p array.slice!(0)
p array
=> "s"
=> "chool"
```
"s"が取り出されたことにより、元の配列から"s"が消えてしまいました
この様に、元のオブジェクトの値自体を変更してしまうメソッドのことを破壊的メソッドと呼びます

## 問題
私の通っているスクールで、この様な問題が出ました
同じだと問題があるので、少し変えます

```.rb
array('Ruby') => 'byRu'
array('python') => 'thonpy'
array('Hi') => 'Hi'
```
配列"array"に対して、「最初から２文字を最後尾に持ってくるメソッドを作ろう」という問題です

先ほどの"slice"メソッドと、破壊的メソッドを使用すれば、簡単に答えを導く事ができます
前提知識として、slice(0,2)とすれば、「前から数て"0"番目から"2"文字分を取り出す」という意味になることが必要です

```.rb
def array(str)
  array = str.slice!(0,2)
  new_array = str + array
  return new_array
end

p "文字を入力してください"
input = gets.chomp
p array(input)
```
"input"のなかに好きな文字を入れれば最初から２文字を最後尾に持ってくる事が可能です

しかし、問題は破壊的メソッドを使用しているという点です
破壊的メソッドに関して、何名かのご意見を拝見いたしましたが、初学者の私にとってどうすべきかの判断は付けづらかったので、状況によっては使って良いという解釈で行きたいと思います。
使わないほうがいいと思った理由の一つには、元のオブジェクトの中身を変えてしまうので、自分以外の人がメンテナンスをする際に辿るのが大変な事があげられます。
使ってもいいシチュエーションがあるなと感じた理由の一つには、配列オブジェクトに対してハッシュオブジェクトを格納していく際、"<<"メソッドを使用します（これも破壊的メソッドです）が、そういった場合は使ってもいいのではないかなあと思います。今の私では、それ以外で配列にハッシュオブジェクトを格納する方法を知らないということもありますが…


## 破壊的メソッドを使わない様に書いてみる
では、先ほどの問題を、破壊的メソッドを使わずに解いてみましょう
といっても、最初から２文字を取り出せているので、そこまで難しくはありません。
前提知識として、「数値をマイナスにすると後ろから数えて何番目を指定する」ということくらいです

```.rb
def array(str)
  array = str.slice(0,2)
  length = str.length
  back = str.slice(2-length,length-2)
  new_array = back + array
  return new_array
end

p "文字を入力してください"
input = gets.chomp
p array(input)
```
こんな感じですね
ポイントは"(2-length,length-2)"のところでしょうか
入力される文字列が何文字か決まっていないので、"2-length"とすることで、後ろから３番目を必ず指定できます
今回は最初から２文字と決まっているので、２から引きましたが、これも何文字までと指定する様に変えてあげれば汎用性（あるのか？）が増えますね

今回はこれで以上です
AWS  trusted adviser による制限監視

AWS Limit Monitorを使う
https://dev.classmethod.jp/cloud/aws/aws-answers-try-aws-limit-monitor/

実行している流れ
1. CloudWatch Events作成。定期的にMaster Lambda Functionを呼び出す。
2. Master Lambda Function は、指定したAWSアカウント単位で Child Lambda Function を起動します。複数のAWSアカウントに対応
3. Child Lambda Function は、AWSアカウント単位で Trusted Advisor、および Trusted Advisor で管理されていないEC2インスタンス全体の上限数、CloudFormation Stack の上限数、DynamoDB の各種キャパシティユニットをチェック
4. サービス制限値の80%以上利用しているリソースがある場合、SNSをキック
5. ユーザーはアラートメールを受信
WebBrowser コントロールで XML 表示

# 概要

XML を画面に表示する場合、System.Windows.Forms.WebBrowser コントロールを使用し、DocumentText プロパティに内容をセットすることで実現可能だが、タグ名に <b>head</b> などがある場合に上手く表示されない問題がある。
(head で始まる header 等でもダメ)

## 例

```XML:表示させるXML

<?xml version="1.0" encoding="utf-8"?>
<doc>
  <header>ヘッダ</header>
  <data>データ</data>
</doc>
```

IE で表示した場合、下図のようになる。

|IE で表示|
|:-:|
|![WebBrowser_IE.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298163/44132b2b-6bda-90df-666d-52064b44a49c.png)|

### 通常

DocumentText に文字列を設定した場合は IE と同じように表示されない。。
コントロール内部で HTML の HEAD タグと誤認してそう。

|WebBrowser で表示 1|
|:-:|
|![WebBrowser_EG1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298163/4a8ac41a-5ecb-8cf7-606a-5572b579f4fd.png)|

```C#:通常コード
this.webBrowser1.DocumentText = xml;
```

### 改良

XML 文字列を一旦ファイルに保存し、Navigate メソッドを呼ぶことで、IE と同じような表示となった。

|WebBrowser で表示 2|
|:-:|
|![WebBrowser_EG2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298163/d5acba93-1791-b4c3-2361-ebf0bdd9ac72.png)|

```C#:改良コード
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.xml");
File.WriteAllText(path, xml);
this.webBrowser1.Navigate(path);
File.Delete(path);
```
[Validation設定]ユーザー登録

##Validation設定

ユーザー登録時につけたバリデーションの記録です。

**今回でたエラー**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540209/6c40c5d9-4187-344c-ca4b-3f8353ffaaf2.png)

セキュリティの関係で`^`を`\A`にしろと言われました

```ruby:user.rb
validates :kana_firstname, :kana_lastname, presence: true, 
            # カナのみ可
            format: { with: /\A([ァ-ン]|ー)+\z/, message: "is must NOT contain any other characters than alphanumerics." }
```
これでエラーは無くなりました！


**参考**

- [[Rails5] Device SNS認証後に独自のユーザ登録フォームを実装する方法](https://qiita.com/onoxeve/items/992a803fadbd23b55fda)
- [Railsバリデーションまとめ](https://qiita.com/h1kita/items/772b81a1cc066e67930e)
- [form用正規表現判定/備忘](https://qiita.com/fubarworld2/items/9da655df4d6d69750c06)
- [Railsの正規表現での^と$](https://qiita.com/kentana20/items/3f37bbc8eb04d9ce927d)

**user.rbに書いた他のバリデーション**

```ruby:models/user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
        :recoverable, :rememberable, :validatable, :omniauthable, omniauth_providers: [:facebook, :google_oauth2]
  
  validates :nickname, :firstname, :lastname, :birthday, presence: true
  validates :password, presence: true, length: { minimum: 7 }, 
            # 英数字のみ可
            format: { with: /\A[a-z0-9]+\z/i, message: "is must NOT contain any other characters than alphanumerics." }
  validates :email, presence: true, 
            # 重複不可
            uniqueness: { case_sensitive: false }, 
            # 英数字のみ可,@を挟んだemailの形になっているか
            # /^\S+@\S+\.\S+$/   /\A[a-z0-9]+\z/i  /^[a-zA-Z0-9]+$/
            format: { with: /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i, message: "is must NOT contain any other characters than alphanumerics." }
  validates :kana_firstname, :kana_lastname, presence: true, 
            # カナのみ可
            format: { with: /\A([ァ-ン]|ー)+\z/, message: "is must NOT contain any other characters than alphanumerics." }
            has_many :sns_credentials

```
Serveoの代わりにlocalhost.runを使ってみた

# Serveoとは
元ネタはこちら: [ngrok大好きな私がServeoで感動した話](https://qiita.com/sskmy1024y/items/8395c85d09931d7dea27)
簡単に説明すると、ローカル環境を手軽に公開できるサービスです。sshするだけなので、ssh環境さえあればどんな環境でも使えます。

## Serveoが使えなくなってた

私は最近使っていなかったので気がつかなかったのですが、、2020年1月3日現在[サービスダウン](http://serveo.net/)しているとのこと（[コメントで教えていただきました :pray: ](https://qiita.com/sskmy1024y/items/8395c85d09931d7dea27?utm_campaign=email&utm_content=link&utm_medium=email&utm_source=public_comment#comment-1c04e71f9ff2bb8b1a76)）

そこで代わりのサービスとして教えていただいた`ssh.localhost.run`を試してみたので、記事にしました。

# ssh.localhost.run

サイトは[こちら](http://localhost.run/)。これもsshするだけ。

## とりあえず使ってみた

静的サイトを作って、使い勝手を試してみました。サイトは`create-react-app`で即席buildした手抜きです。

### localhostで動かす

<img width="714" alt="スクリーンショット 2020-01-03 11.17.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265811/65f2f838-a3c0-e8e1-663d-f81a654c759d.png">

ポート番号`5000`で動かすとこんな感じ。

### ssh.localhost.runに接続

sshでポートフォワーディングします。

```sh:使い方
ssh -R 80:localhost:<ポート番号> ssh.localhost.run
```

<img width="682" alt="スクリーンショット 2020-01-03 11.17.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265811/28caa7c1-fc41-c774-7cf8-b011d4c34c84.png">
接続時にランダムなURLが生成されるようです。
ちなみにユーザ名を指定することで、`<username>-<uuid>`という形で、多少サブドメインを変更できる模様。

### サイトを開いてみる

<img width="714" alt="スクリーンショット 2020-01-03 11.18.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265811/44699b7f-5fd4-06ee-5f66-3248d5ed7847.png">

開けました :tada: 

## Seveoとの比較

サービスサイトを比較した限りだと、Serveoの方がサブドメインの指定や複数トンネルをまとめるなど、いろいろできる感じがありました。
とはいえ、モックサイトなどを簡単に公開するという程度なら使えそうな予感。

# まとめ

研究室にサービス公開用のオンプレサーバがあって、最近この手のサービスはほとんど使わなくなっていました。
とはいえローカル環境を簡単に公開できるサービスは便利ですね。
CFn と SAM

API
DynamoDBテーブル
Lambda関数
Elasticache
…を使用している場合、Elasticache以外はSAMで管理し、ElasticacheはCFnで管理するのがよい（…のだと思う）

# 参考
- AWS Lambda と Amazon API Gateway で安全なデプロイを行うためのベストプラクティス
 - https://dev.classmethod.jp/cloud/aws/aws-summit-berlin-deploy-bp/
- AWS公式
 - https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/transform-section-structure.html
 - https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/kinesis-tutorial-spec.html
- AWS SAM 構文を利用した CloudFormation による Lambda と API Gateway の作成
 - https://recipe.kc-cloud.jp/archives/13383
[DB] Azure Cosmos Db, User-defined functions UDF を使う

CosmosDbは階層構造を持っているため必ずしもその層に値が定義されているとは限りません。今回はAzure Search用にデータをフラット化する際にその層に値が定義されてない場合(NULLの場合）処理の方法をカスタマイズしたい！　そんな時のUDFです。

# Azure Cosmos DB

Azure Cosmos DBに関しては下記の投稿を参照してください。
:point_right_tone2: [Azure Cosmos DB 基礎編](https://qiita.com/syantien/items/dee280c2982d9d6b7a67)


# (Cosmos DB) SQL APIでサポート
SQL API (Cosmos DBを作る際にSQL APIを指定した場合) はUDFをサポートしています。指定の処理を行い、一つの値を返すことによって、その返された値を1フィールド値として表現することができます。

# サンプルコード（簡易版）

早速サンプルコードを見てみましょう。

```javascript

UserDefinedFunction regexMatchUdf = new UserDefinedFunction
{
  Id = "REGEX_MATCH",
  Body = @"function (input, pattern) {
    return input.match(pattern) !== null;
  };",
};

UserDefinedFunction createdUdf = client.CreateUserDefinedFunctionAsync(
  UriFactory.CreateDocumentCollectionUri("myDatabase", "families"),
  regexMatchUdf).Result;  
```

## SQLでの実装

フィールドの値として表示します。

```sql
SELECT udf.REGEX_MATCH(Families.address.city, ".*eattle")
FROM Families
```

フィルターとして実装することもできます。

```sql
SELECT Families.id, Families.address.city
FROM Families
WHERE udf.REGEX_MATCH(Families.address.city, ".*eattle")
```

# サンプルコード（ちょっとアドバンス版）

下記のサンプルコードではより条件を複雑（カスタマイズ）したものになります。

```javascript

UserDefinedFunction seaLevelUdf = new UserDefinedFunction()
{
  Id = "SEALEVEL",
  Body = @"function(city) {
    switch (city) {
      case 'Seattle':
        return 520;
      case 'NY':
        return 410;
      case 'Chicago':
        return 673;
      default:
        return -1;
    }
};

UserDefinedFunction createdUdf = await client.CreateUserDefinedFunctionAsync(
  UriFactory.CreateDocumentCollectionUri("myDatabase", "families"),
  seaLevelUdf);

```

## SQLでの実装

```sql
SELECT f.address.city, udf.SEALEVEL(f.address.city) AS seaLevel
FROM Families f
```

# 次

次回はUDFの管理方法を見ていきます。（いつになるかは・・未定）

# 参照
https://docs.microsoft.com/bs-latn-ba/azure/cosmos-db/sql-query-udfs
macOSにGoの開発環境をインストール（備忘録）

# Goのインストール
Homebrewでgoをインストール

```{bash:ターミナル}
$ homebrew install go
$ go version
  go version go1.13.4 darwin/amd64
```

ちゃんとhomegrew（自家醸造）して、Cellar（貯蔵庫）に入ったgoが使われていることを確認。

```{bash:ターミナル}
$ which go
  /usr/local/bin/go
$ ls -al /usr/local/bin/go
  lrwxr-xr-x  1 shizuku  admin  26 11 17 19:23 /usr/local/bin/go -> ../Cellar/go/1.13.4/bin/go
```

# GOPATHとPATHの設定
- ホームディレクトリにgoディレクトリを作成してGOPATHに設定。
- PATHにGOPATH/binを追加。

下記の2行を.bash_profileに追加しておく。

```{bash:.bash_profile}
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
```

# Visual Studio Code (vscode) のインストール
## vscodeのアンインストール
vscodeの環境をクリーンにしたかったので、すでにインストールされているvscodeと設定ファイルをアンインストール。

- vscodeの本体はFinderのApplicationフォルダからゴミ箱に移動
- vscodeの設定ファイルはターミナルで削除

```{bash: ターミナル}
$ rm -rf  ~/Library/Application\ Support/Code
$ rm -rf ~/.vscode
```

# vscodeのインストール
vscodeの最新版をダウンロードしてインストール
https://code.visualstudio.com/

# Goプラグインのインストール
vscodeで"go"キーワードでプラグインを検索。Microsoft製のms-vscode.goを選択してインストール。
![go_plugin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126781/82dc665b-5360-daf1-ff85-3d25331db969.png)

vscodeのコマンドパレットで"> Go: Install/Update Toolsを実行して、Goの各種ツールを全て選んでインストール。
![go_tools.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126781/0423d364-3cad-d85a-c83b-c9042358373e.png)

Goのツールは、GOPATHに設定したディレクトリにインストールされる。

```{bash: ターミナル}
ls ~/go/bin/
bolt		go-symbols	goimports	gore		impl
dlv		gocode		gomodifytags	gorename	kuzusi
fillstruct	godoc		gopkgs		gotests
go-outline	godoctor	goplay		guru
```

ここまでの設定でvscode上でGoの実行、デバッグが可能。

# vscodeのキーマップ設定
キーマップ設置はデフォルのまま。
Macの場合は、デフォルトでControlキーを使ってEmacsライクなカーソル移動ができるので。
CodeBuild のリンク

# 参考
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/how-to-create-pipeline.html
https://aws.amazon.com/jp/blogs/news/create-multiple-builds-from-the-same-source-using-different-aws-codebuild-build-specification-files/
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/getting-started.html
MacBook のバックライトをオフにするショートカットキーを作る

自分は MacBook を外部ディスプレイに繋ぐときは内蔵ディスプレイは使わないスタイルなので、外部ディスプレイにつないでいる間は内蔵ディスプレイを切っておきたい。(開いた状態で画面を切るのは無理なので、バックライトをオフにしておきたい)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16369/e5e18498-58d1-df82-456b-9890573fe063.png)

スリープから復帰するたびに内蔵ディスプレイが明るくなってしまうので、毎回 Touch Bar を触って画面を暗くするのが面倒くさい。ショートカットキーいっぱつでバックライトをオフにできないものかと考えた。

## 内臓ディスプレイの輝度を操作する方法
ググっていくつか試したもののうまくいかなかった方法。

### NVRAM の値をいじる方法
Mac には NVRAM という記憶領域があり、ここに画面輝度の情報が保存されているらしい。

> NVRAM (不揮発性ランダムアクセスメモリ) は、Mac がすばやくアクセスできるように所定の設定情報を記憶しておく小容量のメモリです。
> NVRAM に記憶される設定情報には、音量、画面解像度、選択されている起動ディスク、時間帯、最近起きたカーネルパニックの情報などが該当します。

[Mac で NVRAM または PRAM をリセットする \- Apple サポート](https://support.apple.com/ja-jp/HT204063)

NVRAM の値は `nvram` というコマンドで取得と変更ができるらしいので、これを使えばバックライトが操作できるのではないか。

``` console
$ nvram backlight-level
```

と実行すると、輝度によって違う値が返ってくることがわかる。

輝度が最低 (バックライトオフ) のときの値はどうやら `%00%00` らしいので、これを設定してみる。

``` console
$ sudo nvram backlight-level='%00%00'
```

が、画面輝度には反映されない・・・。

どうやら NVRAM の値を書き換えられるだけでハードウェアを操作することはできないらしい。
諦め。

### `Brightness Down` キーを送る方法
Mac の画面輝度を下げる物理キー (Brightness Down) はキーコードが `0x91` なので、これを仮想的に押したことにすれば輝度が下がるのではなかろうか。

``` console
$ osascript -l JavaScript -e 'const app = Application("System Events"); app.keyCode(0x91)'
```

**お、少し暗くなった。**

(物理キーは1回押せば輝度が1段階下がるので) あとはこれを16回送信すれば輝度最小になるじゃ〜ん！

``` console
$ osascript -l JavaScript -e 'const app = Application("System Events"); for (let i = 0; i < 16; i++) { app.keyCode(0x91); }'
```

と思ったのも束の間、全然うまくいかないんだなこれが。

全然輝度が変わらないことがあったり、中途半端に暗くなったり、思うような挙動をしない。
`delay(1.0)` を挟んでみたりしてもダメ。

どうやら物理キーを押すのと `0x91` を送信するのとでは何か振る舞いが異なるらしい。
諦め。

## 最終的に採用した方法
**[brightness](https://formulae.brew.sh/formula/brightness) というコマンドを入れた。**

`brew install brightness` で入る。

実装を読むと、C から CoreDisplay の API を呼んでいるようだ。
https://github.com/nriley/brightness/blob/master/brightness.c

最初からそれでよかったのではという気もしなくもないが、できれば何もツールを入れずに実現したかった・・・。

``` console
$ brightness 0.0
```

と実行するだけで画面輝度が最小になるが、これだと接続されているすべてのディスプレイの輝度を下げられてしまうので、内蔵ディスプレイ (built-in) の輝度だけを下げるようにする。

``` shell:builtin-display-brightness.sh
#!/bin/bash -eu

BUILTIN_DISPLAY_ID=$(brightness -l 2>/dev/null | grep built-in | sed -E 's/^.*ID (0x.+)$/\1/g')
brightness -d $BUILTIN_DISPLAY_ID $1
```

``` console
$ ./builtin-display-brightness.sh 0.0
```

できた。
便利かよ・・・。

## ショートカットキーを割り当てる
Karabiner-Elements の Complex modifications を使って、`option` + `[` で画面輝度が最小になるように設定した。

``` json:karabiner.json
{
    "description": "option + [ で内臓ディスプレイのバックライトを消す",
    "manipulators": [
        {
            "from": {
                "key_code": "open_bracket",
                "modifiers": {
                    "mandatory": [
                        "option"
                    ]
                }
            },
            "to": {
                "shell_command": "PATH=$PATH:/usr/local/bin /path/to/builtin-display-brightness.sh 0.0"
            },
            "type": "basic"
        }
    ]
}
```

注意点としては、[Karabiner-Elements の shell_command は /usr/local/bin に PATH が通っていない](https://qiita.com/hoto17296/items/f9caadd7be6445bdc7ee) ので、`PATH=$PATH:/usr/local/bin` と書いておかないと「`brightness` コマンドが見当たらない」とエラーになってしまう。