OmniAICreator/Qiita-1.07M huggingface dataset:
ロータリーエンコーダー

# ロータリーエンコーダーを試す
スイッチサイエンスさんで購入した[Sparkfunのイルミネーションロータリーエンコーダー](https://www.switch-science.com/catalog/5446/)を試した。これに関しては、英語を含めて記事をほとんど見かけないこともあり、ここに記録することとした。

## データシートなど
ロータリーエンコーダーのデータシートは[こちら](https://cdn.sparkfun.com/datasheets/Components/LED/EC12PLRVF-D-24K-24-24C-0206-6H%28SPEC%29.pdf)にあるが、イルミネーション部については[こちら寸法図](https://cdn.sparkfun.com/assets/4/2/9/a/a/Part_5239_EC12PLGRSDVF-D-25K-24-32___07-6H_H_.pdf)を参照する。

### 配線など
上記資料から抜粋。

ロータリーエンコーダーの回路図は下記のとおり。
![回路図１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/9808c7e7-df95-d938-375c-6ca4359cd63b.png)

ここでは、10KΩのPullup抵抗のみ用い、ピンAやBにつながる10KΩ抵抗や0.01μFのコンデンサは使用していない。ただし、コンデンサを使用した方が、回したときの動きとソフトウェアで取得する値とが滑らか（？）、、などの記載がどこかにあった覚えあり。

イルミネーションの回路図は下記のとおり。
![回路図２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/6bac462a-5234-e9bc-e610-6244dff647a6.png)

ピン1がGND、ピン2および3がLED、ピン4がボタンである。

また、ピンの配置は下記のとおり。

![配置２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/10acc274-949c-6e55-a69c-46f5bb16faae.png)![配置.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/7b26cada-325a-9639-0005-3ef86e18a6ef.png)

## 実験
回したら可変LEDの色が変化するというもの。用いた可変LEDは[こちら](https://www.switch-science.com/catalog/3886/)である。

### ソースコード
コードはSparkfunサイトからたどれる[こちら](https://github.com/sparkfun/Rotary_Encoder_Breakout-Illuminated/blob/master/Firmware/RG_Rotary_Encoder/RG_Rotary_Encoder.ino)にあるものをほぼそのまま使う。ここでは可変LEDの追加部分のみ記載する。

```c++
#define VAR_LED 9     // 可変LEDをつなげるGPIOポート番号
#define LED_INIT 127  // 可変LEDの初期値
```

```c++
setup() {
  // 他は上述ソースコードと全く同じ

  analogWrite(VAR_LED, LED_INIT);  // 可変LEDの初期値をセット
}
```

analogWriteの第2引数はデューティ比であり、0から255までの値をとる。

```c++
loop () {
  if (rotary_change)
  {
    Serial.print("rotary: ");
    Serial.println(rotary_counter, DEC);
    rotary_change = false; // Clear flag

    //blink for visual feedback
    setLED(OFF);
    delay(10); //try not to make this too long, otherwise the Arduino will miss ticks
    setLED(x);
    { // @@@
      analogWrite(VAR_LED, LED_INIT+rotary_counter*5);
    } // @@@
  }

  // 他は上述ソースコードと全く同じ
}
```

loop()では、//@@@で囲まれた部分のみ追加している。変数rotary_counterはint型であり、回したときに得られる値である。初期値は0であり、-32768から32767での値をとるはず。。analogWrite()のデューティ比（0から255）の値に無理やり変換されることになる。

繰り返しになるが、上述以外の記載は、オリジナルの[ソースコード](https://github.com/sparkfun/Rotary_Encoder_Breakout-Illuminated/blob/master/Firmware/RG_Rotary_Encoder/RG_Rotary_Encoder.ino)を参照されたし。

### テスト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/70bc9093-5671-fe71-14cc-c6abe8a47e7e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/afe25812-9c0a-9b3c-a2a9-c7772094ec28.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/e8ecdfd9-11cf-c13e-e0ee-856a9be3888c.png)

ロータリーエンコーダーを回すことにより、可変LEDの明るさが変化する。なお、ロータリーエンコーダーを押すとイルミネーション（色）が変わる。
swiftでボタンを押された時効果音を流す

AVFoundationというフレームワークがあるみたいね
以下appleサイト
https://developer.apple.com/documentation/avfoundation/


    import AVFoundation

    var player: AVAudioPlayer!

    func playSound(soundName: String?) {
        let url = Bundle.main.url(forResource: soundName, withExtension: "wav")
        player = try! AVAudioPlayer(contentsOf: url!)
        player.play()
        
    }

forResourceに名前
withExtensionに拡張子
を入れると音が鳴るよ
swiftでカウントダウンタイマーを作る


swiftでカウントダウンタイマーを作るテンプレです

```swift
    var secondsRemaining = 60
    var timer = Timer()
    
    timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateCounter), userInfo: nil, repeats: true)
        }
    
    @objc func updateCounter() {
        //example functionality
        if secondsRemaining > 0 {
            print("\(secondsRemaining) seconds to the end of the world")
            secondsRemaining -= 1
        }
    }
```

   timeIntervalというのが測る間隔値みたい
Mint HCMを立ち上げてみる

Mint HCMは、Suger CRMをベースに作られている、Open SourceのHCMソリューションです。
https://minthcm.org/

どんなことができるのか、試して見るために、AWS Lightsailの環境にインストールしてみた際の備忘録です。

# 0. 事前準備
AWS LightsailでLAMP環境を用意します。
PHPのバージョンが7.1でなければ、インストールが完了しないので、ミドルウェアは、自分でインストールする必要があります。
![2021-05-03_21h37_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626057/074d96cf-1797-842d-5a76-da0929c4e392.png)

私は以下のミドルウェアをインストールしました。

 - apache2.4
 - PHP7.1
 - MySQL5.6

>PHPに関連して、いくつかハマったところを、メモしておきます。

> - アップロードファイルサイズの変更しておく。
> - ZIPのモジュールをインストールしておく。
> - IMAPのモジュールをインストールしておく。

# 1. モジュールのダウンロード
Mint HCMのサイトから、モジュールをダウンロードします。![1280px-MintHCM_-_Installation_-_Start.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626057/f416642d-3cc0-1d88-f51c-ba87fd3f7391.png)

https://minthcm.org/download/

Lightsail上で、`wget`で取得できます。

> `wget https://ma.minthcm.cloud/asset/11:minthcm-release-3-0-8.zip`


# 2.モジュールの配置
ダウンロートしたモジュールを`unzip` し、`/opt/bitnami/apache/htdocs/` に配置します。

私の環境の場合、フォルダの権限を `apache:daemon` にする必要がありました。

```
 sudo chown -R apache![2021-05-03_21h43_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626057/e4b99446-b836-a1e9-e296-44bce688596d.png)
:daemon ./[フォルダ名] 
```

次に、MINT HCMの各フォルダの権限設定を行う。
これを実行しないと、インストール時にエラーとなります。

```
  sudo chmod -R 755 .
  sudo chmod -R 775 cache custom modules themes data upload
```

# 3.インストールの実行
``http://[サーバーIP]/[フォルダ名]/install.php``にアクセスし、インストールを行います。

### 3.1 "I agree"を選択し、"Next"をクリックします。
![1280px-MintHCM_-_Installation_-_Start.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626057/b69f940c-00b8-2b36-980b-ed0e15a4f5a1.png)


### 3.2 チェックが通れば、以下の画面が表示されるので、NEXTボタンをクリックします。
![2021-05-03_17h08_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626057/6c535842-cb65-f95b-6656-f07b0cc167d5.png)

### 3.3 DBの設定、SMTPサーバーの設定を行い、インストールを進めます。
マシンスペックにもよりますが、5分程度でインストールは完了するかと思います。
もし、なかなか終わらないようなら、どこかの設定がおかしい可能性があります。


### 3.4 ログイン画面が表示されれば、インストールは完了です。
![2021-05-03_21h43_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626057/f5f6069c-0f32-44af-53bf-02d78cd58820.png)
コードでUIScrollViewサンプル作成


##バージョン

・Xcode1２.4
・Swift5

##概要
コードでUIScrollViewのサンプルを作成した備忘録

##コード

```swift:test.swift
import UIKit

class ViewController: UIViewController {
// インスタンス化
    let outView = UIView()
    let scrollView = UIScrollView()
    let inView = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        // 背景色の決定
        scrollView.backgroundColor = UIColor.black
        inView.backgroundColor = UIColor.blue
        view.backgroundColor = UIColor.systemBlue
        
        // かくviewに子要素として追加
        scrollView.addSubview(inView)
        view.addSubview(scrollView)
        
        // scrollViewの制約の設定
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        scrollView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        
        // inViewの制約の設定
        // inView：AutoLayoutで使用したContainerViewに該当
        // Autosizingという仕組みをAutoLayoutに変換する設定するフラグ：falseでAutoLayoutを有効化
        inView.translatesAutoresizingMaskIntoConstraints = false

        // 横スクロールにするため、高さ：scrollViewと同一、幅：2000.0に設定
        inView.widthAnchor.constraint(equalToConstant: 2000.0).isActive = true
        inView.heightAnchor.constraint(equalTo: scrollView.heightAnchor).isActive = true
        inView.leftAnchor.constraint(equalTo: scrollView.leftAnchor).isActive = true
        inView.rightAnchor.constraint(equalTo: scrollView.rightAnchor).isActive = true
        inView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
        inView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
    　　}
    }
```

##参考にさせて頂いた記事
[コードでUIScrollView(とその子どもたち)をAutoLayout配置](https://qiita.com/samekard/items/31407a3c2a1aac191008)
[[Xcode11] UIScrollViewとAutolayoutのベストプラクティス](https://qiita.com/Swift-User/items/67a5dd3d9eabf513aa2c)
ScrollViewについての備忘録


##バージョン

・Xcode 12.4
・Swift5

##概要
ScrollViewについて色々試したのでその備忘録
やり方は[[Xcode11] UIScrollViewとAutolayoutのベストプラクティス](https://qiita.com/Swift-User/items/67a5dd3d9eabf513aa2c)を参照。
ContainerViewを以下のように条件を変えてサンプルの作成
１.Width：ScrollViewと同一、Height：２０００
2.Width：２０００、Height：ScrollViewと同一
3.Width：２０００、Height：２０００

##1

![スクリーンショット 2021-05-02 14.28.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423922/a0b18e93-cc3d-9d9b-f188-1b18515f1a82.png)

##2
![スクリーンショット 2021-05-02 14.29.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423922/bad77f53-3054-6858-ba68-3422e2b0480d.png)


##3
![スクリーンショット 2021-05-02 14.29.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423922/94f49006-7971-8697-b33f-655462f8dc8b.png)


実機の画像
![スクリーンショット 2021-05-02 14.30.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423922/1c7928a2-53c1-3223-fa38-d97e86b0a1b8.png)

各設定に対するイメージ
ScrollView：スクロール操作ができる場所。ScrollViewの大きさの覗き窓を設定してContainerViewを切り取って見ている。
ContainerView：Viewとは別のレイヤーでScrollViewの上にある。大きさはViewの大きさに縛られない。


##参考にさせて頂いた記事
[[Xcode11] UIScrollViewとAutolayoutのベストプラクティス](https://qiita.com/Swift-User/items/67a5dd3d9eabf513aa2c)
【TP転職市場PJ日記その3】ログイン画面の実装やると思ったらほぼ完了

#今回は
ログイン画面の実装だよーあんま時間かけたくないよー

#ってことで
laravel のjetstreamという認証系の仕組みをそのまま使ってみることにした。

構築系はまたもや先人系の記事を見つけ愚直に実行…
[先人URL]

https://qiita.com/daisu_yamazaki/items/607ea579a374c4187562

https://qiita.com/manbolila/items/498aae00f3574c72f031

と思いきやnodejsとやらが入っておらずインストールして再度進めたが
上手くいかずnodejsの調達周りも調査結論、バージョンを指定しないと問題がでるとのことで
バージョン指定込みでインストール方法を先人に教えてもらう。

https://zukucode.com/2019/06/docker-laravel-nodejs.html

なんとか上手くいき画面を開くと…

![login.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570502/5df87ea4-b8e9-1ad6-0ebb-22c7efef8a25.png)


こんな感じ。さらにアカウント登録も進めると…

![login後.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570502/f5ba09ce-fc88-a2a3-7cde-ff4edd77a418.png)

こんな感じで入れるｗ（もう３分の１終わった感がする）
一応一般的なwebサイトと同様にメールアドレスでのメールアドレスの生存確認もやってみたらこんな感じ。

![mail.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570502/d73e34d4-d8a8-5462-8190-a93822d96f2a.png)

ちなみにローカルでメール確認には先人のMailHogを利用

https://qiita.com/ucan-lab/items/49e7f4986564f68e95c4

後は日本語化すればほぼログイン周りは完了かなといった感じがするわ。

今回のこのサービスではメルアドの認証が一通り終わったら
所属チームやTwitterアカウントの登録等のフォームも設けて更新できるようにしていこうと思う。
一応プロフィール設定画面が用意されたのでそのまま流用する前提で項目を追加してそのページで更新させるぞい。

#残作業として

* メニューの表示制御(プレイヤー、運営、「どちらでもない」の３パターン)
* メニュー画面上で気になる件数の表示
* 募集ページの検索・登録・更新・削除画面
* 一致している条件があったらお知らせバッチ

明日も作業しよ＾＾
そしてウイイレやらなくて今日久しぶりにやったらランクマは負けまくってます。
がんばろ＾＾
ショートカットキーまとめ

ショートカットをすぐ忘れるので、よく使っているショートカットキーをまとめてみた。
コピー・ペーストなど忘れなさそうなことは載せていません。（メモなのであくまで主観です）
随時更新予定

## Windows
| やりたいこと | ショートカットキー |
|:-:|:-:|
| 特大アイコン | Ctrl + Shift + 1 |
| 大アイコン | Ctrl + Shift + 2 |
| 中アイコン | Ctrl + Shift + 3 |
| 小アイコン | Ctrl + Shift + 4 |
| 一覧 | Ctrl + Shift + 5 |
| 詳細 | Ctrl + Shift + 6 |
| 並べて表示 | Ctrl + Shift + 7 |
| コンテンツ | Ctrl + Shift + 8 |
| 削除 | Shift + Delete |
| 設定を開く | windowsキー + I |
| ウインドウ切替え | Alt + Tab |

## Mac
| やりたいこと | ショートカットキー |
|:-:|:-:|
|  Delete | Ctrl + D |
| 隠しファイル表示 | Shift + Command +. |
|||

## Google Colaboratory
| やりたいこと | ショートカットキー |
|:-:|:-:|
| セルの実行 | Ctrl + Enter |
| セルの実行 + 次のセルに移動 | Shift + Enter |
| 全セルの実行 | Ctrl + F9 |
| 現在のセルより上を全て実行 | Ctrl + F8 |
| 現在のセルより下を全て実行 | Ctrl + F10 |
| 実行中断　| md + M + I |
|　セルの削除　| Ctrl + M + D |
| 上にコードセルを挿入 | Ctrl + M + A |
| 下にコードセルを挿入 | Ctrl + M + B |
| テキストセル→コードセルに変更 | Ctrl + M + Y |
| コードセル→テキストセルに変更 | Ctrl + M + M |
| コードセルレベルの編集を戻す | Ctrl + M + Z |
(CtrlはmacではCommand）

## Chrome
| やりたいこと | ショートカットキー |
|:-:|:-:|
| お気に入り追加 | Ctrl + D |
| アドレスバーに移動 | Ctrl + l |
| 再読み込み | Ctrl + R |
| 強制再読み込み | Shift + F5|
| 画面を終了| Ctrl + W |
| 新規タブ | Ctrl + T |
| リンク先を新しいタブで開く | Ctrl + クリック |
| 次のタブに移動する | Ctrl + Tab |
| 前のタブに移動する | Ctrl + Shift + Tab |
| 現在のタブを閉じる | Ctrl + W |
| 閉じたタブを再び開く | Ctrl + Shift + T |
| ダウンロード表示 | Ctrl + J |
| ブックマーク マネージャを開く | Ctrl + Shift + O |
| 履歴表示 | Ctrl + H |
|||

## 参考資料
### Windows
[Windows のキーボード ショートカット](https://support.microsoft.com/ja-jp/windows/windows-%E3%81%AE%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89-%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88-dcc61a57-8ff0-cffe-9796-cb9706c75eec)
[【完全無料】Windowsショートカットキー一覧【PDF配布】](https://pasonyu.com/windows-shortcut/)
[137個のWindowsショートカットキー一覧表（PDF有）](https://office-hack.com/windows/windows-shortcutkey-list/)
[【Windows】オリジナルのショートカットキーを作成してバッチファイルやアプリ等を超速起動する方法](https://mugendennou.net/windows/windowstips/defineoriginalshortcutkey/)
[Windows10ショートカットキー設定方法 - 追加作成や変更時の注意点](https://boxil.jp/beyond/a6773/)

### Mac
[Mac のキーボードショートカット](https://support.apple.com/ja-jp/HT201236)
[【Mac】使わないともったいない！覚えておきたいMacのキーボードショートカット35選](https://koneta.nifty.com/koneta_detail/191031001072_1.htm)
[Mac – ショートカットキーの一覧表（まとめ）](https://pc-karuma.net/mac-keyboard-shortcuts-list/)
[Macのショートカットキー早見表92個｜効かないときの対処法も紹介します](https://www.sejuku.net/blog/124447)
[Macのショートカット変更が自由度高すぎてはかどる](https://enjoy.sso.biglobe.ne.jp/archives/mac_shortcut2/)
[Macで独自のキーボードショートカットを作成/変更する方法! macOSのアプリごとメニューに好きな組み合わせを設定しよう](https://sp7pc.com/apple/mac/10293)

### Google Colaboratory
[【Google Colaboratory】作業が捗るショートカットキーを厳選して紹介！](https://blog.kikagaku.co.jp/google-colaboratory-shortcut)

### Chrome
[Chrome のキーボード ショートカット](https://support.google.com/chrome/answer/157179)



[ショートカットキー一覧［完全版］- パソコン仕事が爆速になるWindows、Office、Googleのキー操作 286選](https://dekiru.net/article/18619/)
Pandas DataFrame/Serieseの継承

# TL;DR  
- pandasのDataFrameやSeriesを普通に継承するとViewの取得時などにpandasDataFrameのDataFrame/Seriesに戻ってしまうなど不都合が起こる
- だから以下のようにする
- 公式ドキュメントは[こちら](https://pandas.pydata.org/pandas-docs/stable/development/extending.html#subclassing-pandas-data-structures)

```python
from __future__ import print_function
import pandas

# 誤った実装方法
class MyWrongSeries(pandas.Series):
    def __init__(self, *args, **kwargs):
        pandas.Series.__init__(self, *args, **kwargs)
        self.my_attribute = 'value of my attribute'
        self.my_temporal_attribute = 'value of my_temporal_attribute'

# 正しい実装方法
class MySeries(pandas.Series):
    # temporary properties
    _internal_names = pandas.Series._internal_names + ['my_temporal_attribute']
    _internal_names_set = set(_internal_names)
    # normal properties
    _metadata = ['my_attribute']
    @property
    def _constructor(self):
        return MySeries
    def __init__(self, *args, **kwargs):
        # call super class constructor
        pandas.Series.__init__(self, *args, **kwargs)
        self.my_attribute = 'value of my_attribute'
        self.my_temporal_attribute = 'value of my_temporal_attribute'

if __name__ == '__main__':
    print('Wrong Implmentation')
    wrong = MyWrongSeries([1,2,3,4,5])
    print(type(wrong))      # __main__.MyWrongSeries
    print(type(wrong[0:1])) # pandas.Series
    print()

    print('Right Implmentation')
    s = MySeries([1,2,3,4,5])
    print(type(s))      # __main__.MySeries
    print(type(s[0:1])) # __main__.MySeries

    print(s.my_attribute)          # 'value of my_attribute'
    print(s.my_temporal_attribute) # 'value of my_temporal_attribute'

    s.my_attribute = 'changed value of my_attribute'
    s.my_temporal_attribute = 'changed value of my_temporal_attribute'

    print(s[0:1].my_attribute)          # 'changed value of my_attribute'
    print(s[0:1].my_temporal_attribute) # 'value of my_temporal_attribute'
```
JavaScriptで動画からサムネイルを作成する


## 概要

動画からサムネイルを作成するプログラム。
動画から任意のシーンを選んで画像として保存します。

## 使い方

1. 動画ファイルを開く
2. サムネイルにしたいシーンを選択する
3. セーブボタンを押すと、サムネイルを保存できます

サムネイル画像の仕様は**1280×720**の**JPEG**。YouTube向けです。

## 動作サンプル
https://gistpreview.github.io/?29900cf73dcafa971e4b2de3e2e2cb9c


## 画像編集機能


このプログラムには画像編集機能があります。
テキストエリアにSVGを入力することでサムネイルを編集できます。

例えばサムネイルに文字を入れたいなら、次のようになります。

```html:サムネイルに文字を入れる例
<text x="100" y="200" font-family="Meiryo" font-size="90px" fill="#fff" stroke="#000" stroke-width="12px" paint-order="stroke">テスト</text>
```

サムネイルに画像を加えたいなら、画像ファイルをD&Dすると追加できます。

##ソース

ソースはHTML1枚です。クライアントサイドですべて動作します。
自分用のプログラムなのでノーデザインですが、よければご自由にお使いください。

https://gist.github.com/worldace/29900cf73dcafa971e4b2de3e2e2cb9c
【Unity error CS0619】Standard Assetsをインポートしたときのエラーの解決方法

# エラーテキスト

`Assets\Standard Assets\Utility\SimpleActivatorMenu.cs(10,16): error CS0619: 'GUIText’ is obsolete: 'GUIText has been removed. Use UI.Text instead.`

↓　日本語に訳すと

`「GUIText は廃止されました」
GUITextは削除されました。代わりにUI.Textを使用してください。`

となります。


テキスト通り**SimpleActivatorMenu.cs**の内容を変更していきます。

# 動画

https://youtu.be/G-ywWomgk9o

動画でも手順を見ることができます。


<br>

# 解決法

###1．エラーで指定されたファイルを開く
![Screenshot 2021-04-19 05-03-49_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1208356/c33362dd-e067-ef3b-a5e9-eae2f0ad3386.png)
SimpleActivatorMenu.csを開く。
エラーコードをダブルクリックすると、目的のファイルを開いてくれます。
<br>

###2．GUI.TextをTextに変更する。
SimpleActivatorMenu.cs内の

`public GUI.Text camSwitchButton;`

を

`public Text camSwitchButton`



に変更。
<br>

### 3.UnityEngine.UIを追加する
同じくSimpleActivatorMenu.cs内に

`using UnityEngine.UI`

の一行を追加する。
<br>

# 変更後のSimpleActivatorMenu.cs

```SimpleActivatorMenu.cs
using System;
using UnityEngine;
using UnityEngine.UI; // 追加

namespace UnityStandardAssets.Utility
{
    public class SimpleActivatorMenu : MonoBehaviour
    {
        // An incredibly simple menu which, when given references
        // to gameobjects in the scene
        public Text camSwitchButton; // GUIText -> Textに変更
        public GameObject[] objects;


        private int m_CurrentActiveObject;


        private void OnEnable()
        {
            // active object starts from first in array
            m_CurrentActiveObject = 0;
            camSwitchButton.text = objects[m_CurrentActiveObject].name;
        }


        public void NextCamera()
        {
            int nextactiveobject = m_CurrentActiveObject + 1 >= objects.Length ? 0 : m_CurrentActiveObject + 1;

            for (int i = 0; i < objects.Length; i++)
            {
                objects[i].SetActive(i == nextactiveobject);
            }

            m_CurrentActiveObject = nextactiveobject;
            camSwitchButton.text = objects[m_CurrentActiveObject].name;
        }
    }
}
```

<br>

#おわり
修正後はファイルを保存します。
Unityに戻るとエラーが治っているはずです。
<br>
LeetCode 1000000本ノック【703. Kth Largest Element in a Stream】

# 目次

|No.|項目|
|:----:|:-------------|
| 1 | [概要](#概要) |
| 2 | [問題](#問題) |
| 3 | [解法](#解法) |
| 4 | [ヒープを使った解法（本当はこっちが正答）](#ヒープを使った解法（本当はこっちが正答）) |

# 概要
<!-- 発端や概要を記載 -->
●発端
　・競プロ初心者、コーディング面接でズタボロにされ、
　・最低限のアルゴリズム学習とコーディング力強化を習慣化するため記事化
●環境
　・LeetCodeブラウザ上で実装（vscodeに拡張機能にするかもシレナイ）
　・言語はpython3
●その他ルール
　・google検索は自由に（直接的なLeetCodeの問題解説ページはNG）
　　（60分実装して実装出来なければ解説ページ参照）
　・[コーディング面接対策のために解きたいLeetCode 60問](https://1kohei1.com/leetcode/)から問題選出
　・「1000000」は任意の2進数とする


<!-- 各チャプター -->
<a id="#Chapter1"></a>
# 問題
- [703. Kth Largest Element in a Stream](https://leetcode.com/problems/kth-largest-element-in-a-stream/)


>Design a class to find the kth largest element in a stream. Note that it is the kth largest element in the sorted order, not the kth distinct element.

>Implement KthLargest class:

>KthLargest(int k, int[] nums) Initializes the object with the integer k and the stream of integers nums.
int add(int val) Returns the element representing the kth largest element in the stream.

⇨「リストの中でk番目に大きい値を見つける KthLargest クラスを作成します。
　メソッドは、引数kとnumsを初期化する init と、
　k番目の要素を返す add　の２つです」と書いてあります。知らんけど。

`ex1
Input
["KthLargest", "add", "add", "add", "add", "add"]
[[3, [4, 5, 8, 2]], [3], [5], [10], [9], [4]]
Output
[null, 4, 5, 5, 8, 8]`

※仕様がちょっとややこしいかもなので、例題で超絶簡単に整理

>[<font color="Blue">"KthLargest"</font>, "add", "add", "add", "add", "add"]
[[<font color="Blue">3, [4, 5, 8, 2]]</font>, [3], [5], [10], [9], [4]]
Output
[<font color="Red">null</font>, 4, 5, 5, 8, 8]

↑最初にクラス名(KthLargest)の指定でinitが実行され、下記のように初期化
　***k = 3　が　nums = [4, 5, 8, 2]***
　初期化処理に戻り値は無いためOutputは***null***

>["KthLargest", <font color="Blue">"add"</font>, "add", "add", "add", "add"]
[[3, [4, 5, 8, 2]], <font color="Blue">[3]</font>, [5], [10], [9], [4]]
Output
[null, <font color="Red">4</font>, 5, 5, 8, 8]

↑次はaddのため配列numsに***3***が追加されて***nums は [ 3, 4, 5, 8, 2]***となり
　「ソート後にk番目の値を返す」ためOutputは***4***　※[ 2, 3, ***4***, 5, 8,]

後は繰り返し繰り返し。。。


<a id="#Chapter2"></a>
# 解法
実施時間：35分

~~英語読めないと~~少々分かりにくいですが仕様を満たす実装自体は
特に難しくはなかったです。

要件としては

・initメソッド
　k　と nums　を初期化
・addメソッド
　引数valを配列numsに追加し、
　降順ソートの後、
　k番目に大きい値を返す

とシンプルですね。

```python
class KthLargest:
    def __init__(self, k: int, nums: List[int]):
        self.k = k
        self.nums = nums

    def add(self, val: int) -> int:
        self.nums.append(val)
        if len(self.nums) >= self.k:
            self.nums.sort()
            return self.nums[-self.k]
```

<a id="#reference"></a>
# ヒープを使った解法（本当はこっちが正答）

簡単すぎて逆に不安になったので解法を探してみました。

[ゼロから始めるLeetCode Day80「703. Kth Largest Element in a Stream」](https://qiita.com/KueharX/items/8999b2b903596639fbfa)

やっぱり全然違いました。。。

悔しいので、実は処理速度には大差ないのではと期待を込めてパフォーマンス比較。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502026/24f6afb8-cb7c-3525-77cf-36305883d411.png)

***↑毎回ソートパターン***

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502026/696cc611-123b-1359-deb6-723deeca992f.png)

***↑ヒープパターン***


えぇ。。。ネタでやってみたらマジで変わらんやん。。。

どうやらある程度の処理量が無いとヒープ優位にはならんようです。知らんけど。
GITの操作

git の勉強を行ったので、その備忘録
<h3>
GITとは：バージョン管理システム</h3>

<b>・バージョン管理の流れ</b>
　　ファイルを作ったり修正したりある程度のまとまりになったら、履歴データベースに保存する。

　　１．作業ディレクトリ
　　２．ステージングエリア
　　３．リポジトリ(ローカル、リモート）

---

<h3>コマンド一覧</h3>

<ul>

<li>git config -l ：設定の一覧を見る
<li>git config -help(git help config)：設定のマニュアルを確認する
<li>git init：gitで使うことを宣言する。
<li>git add：ステージングエリアに保存する。
<li>git commit： リポジトリに保存する。
<li>git log：履歴を表示する
<li>git log -p：変更された場所も確認できる。
<li>git log --stat：どのファイルが何箇所変わったかを確認できる。
<li>git status：現在の状態を確認する
<li>git checkout -- <file>：ステージングエリアに保存したのを取り消す。
<li>git diff：どこをどのように編集したかを確認する。
　　※ステージングエリアにあげてしまうと確認不可
<li>git diff --cached：ステージングエリアにあげてしまった時にどこをどのように編集したかを確認する。
<li>git rm <ファイル名>：ステージングエリアやコミットしたあとにファイルを消す
<li>git mv <ファイル名>：ステージングエリアやコミットしたあとにファイルを移動する
<li>git commit --amend：直前のコミットを変更してくれる
<li>git reset --hard HEAD：コミット前に実施すると、作業ディレクトリもステージングエリアも一気に直前のコミットに戻す
<li>git reset --hard HEAD　<commitID>：作業ディレクトリもステージングエリアも指定したコミットIDのコミットへ戻す。
<li>git reset --hard ORIG_HEAD：取り消し前のコミットへ戻す
　　※ORIG_HEAD：前回取り消された情報が１つだけ格納されている
<li>git branch：ブランチ情報が見れる
<li>git branch <ブランチ名>：ブランチを作成できる
<li>git checkout <ブランチ名>：ブランチ名のブランチへ切り替える
<li>git merge <ブランチ名>：今いるブランチに、指定したブランチをマージさせる。
<li>git branch -d <ブランチ名>：ブランチを削除する。
<li>コンフリクトの解決方法：コンフリクトしている箇所で、どちらかを選んで修正する。
<li>git tag (tag name)：直近のコミットにタグを付ける。
<li>git tag (tag name)(commit id)：指定したcommit idにタグをつける。
<li>git tag -d (tag name)：指定したタグ名を削除する。
<li>git config --global alias.co checkout：エイリアスを使用し、checkoutをcoで使えるようにする。(※他のコマンドでも可能)
<li>git init --bare：共有リポジトリを作成する。
<li>git remote add origin (repos location)：別のリポジトリを登録する。
<li>git push origin master：共有リポジトリに対して、MASTERの内容を突っ込む。
<li>git clone　<共有リポジトリ先> <フォルダ名>：共有リポジトリの中身を<フォルダ名>の中にコピーする。
<li>git pull origin master：共有リポジトリの内容を、持ってきてマージしてくれる。
<li>共有時のコンフリクトの解決方法：Mergeの時のコンフリクトと同様に、コンフリクトしている箇所でどちらかを選んで修正する。
Node.jsでGoogle Spread Sheetsを読み取る 【Sheet API v4】


Google Sheet API v4版です。手順など定期的にアップデートしてますが、改めてまとめてみました。

> 過去記事: [Node.jsでGoogle SpreadSheetsを操作してみよう。【GAS不使用】](https://dotstud.io/blog/google-spreadsheets-from-nodejs/)

async/awaitで書いたり、モジュールも使ったりだいぶシンプルに出来るようになってきました。

GAS不要なのでNode.jsでやりたい人向けですね。

## 環境

* Node.js v16.0.0
* [googleapis](https://github.com/googleapis/google-api-nodejs-client) v73.0.0
* [google-auth-token-generator](https://www.npmjs.com/package/google-auth-token-generator) v0.1.2

## 手順

### 作業フォルダ&利用モジュール準備

```bash
$ mkdir sheet
$ cd sheet
$ npm init -y
$ npm i googleapis google-auth-token-generator
```

### credentialsファイルを作成

公式の[Node.js quickstart](https://developers.google.com/sheets/api/quickstart/nodejs?authuser=1)を見て`credentials.json`をDLしましょう。

アプリケーション種類はデスクトップアプリにします。

> ![スクリーンショット 2021-05-04 0.24.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/16861b58-8908-84d6-17fa-8e12deae9140.png "スクリーンショット 2021-05-04 0.24.17.png")

`client_secret.json`や`client_secret_xxxxxxx.json`といった名前の場合もありますが、`credentials.json`にリネームします。

また、先ほど作成したsheetフォルダに`credentials.json`を設置します。

### tokenの生成

パーミッションを選択してtokenを作成します。

```bash
$ npx google-auth-token-generator
```

今回は既存のシートの読み取りだけしたいので、パーミッション選択では`spreadsheets.readonly`を選択します。

> ![スクリーンショット 2021-05-04 0.20.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/27ef1eb8-39ff-ef7b-00da-590a72a357e7.png "スクリーンショット 2021-05-04 0.20.09.png")

認証など進めるとtoken.jsonが生成されます。

### Sheet APIでスプレッドシートの値を見る

サンプルコードが以下です。

```js
'use strict';

const {google} = require('googleapis');
const {oAuth2ClientGen} = require('google-auth-token-generator');

(async () => {
    const auth = oAuth2ClientGen({library: google});
    const sheets = google.sheets({version: 'v4', auth});

    try {
        const res = await sheets.spreadsheets.values.get({
            spreadsheetId: '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms',
            range: 'Class Data!A2:E',
        });

        const rows = res.data.values;
        if (rows.length) {
          console.log('Name, Major:');
          // Print columns A and E, which correspond to indices 0 and 4.
          rows.map((row) => {
            console.log(`${row[0]}, ${row[4]}`);
          });
        } else {
          console.log('No data found.');
        }

    } catch (error) {
        console.log('The API returned an error: ' + error);
    }
})();
```

### 実行

```bash
$ node app.js 
Name, Major:
Alexandra, English
Andrew, Math
Anna, English
Becky, Art
Benjamin, English
Carl, Art
Carrie, English
Dorothy, Math
Dylan, Math
Edward, English
Ellen, Physics
Fiona, Art
John, Physics
Jonathan, Math
```


実態は公式チュートリアルにもあるこちらのシートの内容を読み込んでます。

> https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit?usp=sharing

## よもやま

[google-auth-token-generator](https://www.npmjs.com/package/google-auth-token-generator)は自作モジュールなので公式の手順と若干異なりますが、YoutubeやGmailなどGoogle系のAPIで同じ処理を書くのが辛いのでnpmパッケージ化してみました。

今回cliツールだけじゃなくてrequireできるモジュールとしてもアップデートさせてみましたが個人的にはめちゃ便利です。
MicroStackのHorizonでRuntimeErrorが起きたときの対処法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314089/4b240490-36ac-4033-df84-a4ca09fa17e8.png)
こんな感じのエラーが出たときの対処法(雑)

```
Unable to create a new session key. It is likely that the cache is unavailable.
```

`/etc/memcached.conf`の`#-l 127.0.0.1`をコメントアウトしてその下に`-l 0.0.0.0`を追記

```/etc/memcached.conf
# Specify which IP address to listen on. The default is to listen on all IP addresses
# This parameter is one of the only security measures that memcached has, so make sure
# it's listening on a firewalled interface.
#-l 127.0.0.1
-l 0.0.0.0
```
外付けSSDにWindows10をインストールしてみました

Windowsで試してみたいけど、今の環境は壊したくない場合に有効ですが
セットアップを実行したPCでないと使えないようです
Windows標準のインストーラーでは外付けSSDにインストールできません

diskpartを使ってパーティションを作成して．．．って手動やっていくのも難しそう
ということで、今回は Rufus というツールを使って外付けSSDにインストールしてみました

１．インストール用のISOファイルの作成
   https://uupdump.net/
   からISOファイル作成するためのコマンドファイルをダウンロードします

　ブラウザーでUUP dumpへ接続します
![uup2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061326/953fbc01-2f67-056c-1354-239504b0446b.jpeg)

　21H1 を選択します
![uup3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061326/29ab6f8d-62ac-4786-44ce-8e329250a652.jpeg)

　一番上の Feature update to Windows 10, version 21H1 (19043.964) amd64 を選択します
![uup4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061326/5fd6649d-4ccf-624d-e0af-6c29ec0f0e27.jpeg)

　　LanguageをJapaneseに指定してNextを選択します
![uup5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061326/24261401-1c7b-19a0-de4f-064b69681318.jpeg)

　　Editionはお好みで指定してNextを選択します
![uup6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061326/f5b3f9ff-4be3-3dc8-b1ad-d23e12856dfe.jpeg)

　　Create download package を選択してコマンドファイルをダウンロードします

![uup8.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061326/44a83079-5085-00ec-f258-887b25fb3753.jpeg)

　　コマンドファイルのzipを展開します
　　uup_download_windowsを選択し管理者として実行します

![uup9.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061326/9ec9a473-ac17-9ffe-079f-d720bfac680d.jpeg)

　　詳細情報を選択します

![uup10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061326/1cd28e6b-f7fa-9424-eb5a-c074d93070f3.jpeg)


　　実行　を選択します

![uu1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061326/f7f0c269-88d3-0edc-f4ad-be2290b231a9.jpeg)

　１時間３０分～２時間ほどかかります

２．Rufus をインストールします
　　https://rufus.ie/ja/
 　ブラウザーで接続します
![uup11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061326/8a9bd8e5-8513-1aac-72f5-b6fe0e6e5a49.jpeg)

　下のほうへスクロールするとダウンロードがあります
![uup12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061326/ace8a844-1f70-12fa-63a9-3416c463d4eb.jpeg)

　　Rufus 3.14 を選択してインストールします
　　インストールするSSDをパソコンに接続して Rufus を起動します
![uup13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061326/3b629e2b-f05c-f700-3974-87c8df921bd6.jpeg)

　　デバイスにSSDが表示されていない場合、詳細なドライブプロパティを表示　を選択して
　　USB 接続の HDD を一覧表示　を選択してみてください

　　ブートの種類　は　右側の「選択」ボタンを選択して、先ほど作成したISOファイルを
　　指定してください

　　イメージオプションは　Windows To Go を選択してください

　　パーティション構成は　MBR ターゲットシステムは　BIOSまたはUEFI を選択してください

　　スタート　を選択するとSSDに書き込みが始まります

　　書き込みが完了すると、これで準備完了です

　　念のため、内臓ディスクの電源ケーブルを抜いておいてSSDからブートできれば
　　セットアップを行ってください

   キーボードの設定が英語キーボードになっていると思いますので
　　スタート⇒設定⇒時刻と言語⇒言語⇒A字　日本語　を選択すると
![lang.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061326/1764376d-5666-cc20-9fea-52debbe8220b.jpeg)

　　オプションが表示されオプションを選択すると

![lang2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061326/709ab306-79a1-9963-f619-0b6da485a9f0.jpeg)

　　ハードウェアキーボードレイアウトの項目でレイアウトを変更するを選択して
　　日本語キーボードに設定してください
オンプレでVMwareを触ってきた人のためのAWS速習

普段オンプレミスのインフラエンジニアをやっていますが、やればすぐわかるだろうと思い続けて数年経ちましたが一向に触る機会がやってこないので、個人でAWSに入門してみることにしました。
やはりインフラになじみのない人よりはすんなり理解出来ましたが、いくつか普段のオンプレミスでの仮想環境(VMwareなど)と考え方が異なる点がありましたので、備忘録として残しておきます。

# まずざっくりEC2の作成方法
一般的な手順はネット上にたくさん転がっているので、そちらに説明を譲るとして、EC2インスタンスを作成する中で普段仮想環境ばかり触っている私が気になった点について記載しておきます。

- イメージの選択
![evidence_001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141823/1844ea0d-e95c-9c97-aec9-592cf3d67afc.jpeg)
そこまで戸惑うほどでもないが、VMの側だけ作ってOSをインストールするのではなく、あらかじめ用意されたAMIというイメージをもとにインスタンスを作成する。
自分でカスタマイズしてマイAMIとして登録しておけば、いわゆる仮想マシンテンプレートのような使い方が出来る。
dockerイメージとかvagrantとかでも元々のイメージを引っ張ってきてカスタマイズしていくやり方をするけど、今後はこちらが主流になるんだろうな。OSインストールすることもなくなるのかと思うと少し寂しい・・・

- インスタンスタイプの選択
![evidence_002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141823/0a947e8b-cc0c-2acb-1f7e-4b30f0e1917f.jpeg)
VMwareではvCPUのソケット、コア数、予約する周波数などやメモリの割り当て、予約値、予約値のロックなどを最初から細かく指定するが、AWSのEC2ではインスタンスファミリーと呼ばれるテンプレみたいなものから選ぶ形となっている。
組み合わせがたくさんあり、ここから選ぶだけでも十分使えそうだが、CPUのコア数を変更したり、マルチスレッドを無効化したりすることもできる（インスタンス毎にできる）。
参考：[CPUオプションを最適化する](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-optimize-cpu.html)

- インスタンスの詳細設定
![evidence_003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141823/2b9d786a-ae73-1dfa-7725-866edad75f99.jpeg)
詳細設定と書いているが、VMwareの詳細設定とは全然違う。リソース以外のネットワークの指定やIAMロールの指定などを行う画面。AWSではVPCというSDN(Software Defined Network)上で動くので、その辺の知識が最低限必要となる。標準スイッチ作ってNWチームに教えてもらったVLAN IDを設定するだけではつながらない。
NSXの経験がある人だったら、ほとんど同じ感覚で使えると思う。

その後追加ディスク(EBS)やタグ（名前とか付けれる）、セキュリティグループ(≒オブジェクトベースFW)などの設定があるが、VMware ESXi にNSX組み合わせて構築したことがある人なら悩まずに進めると思う。

# その他オンプレエンジニア疑問に思ったこと
一番気になったのは、仮想化のオーバーヘッドやCPU、メモリのオーバーコミットの扱いである。
これについては、いろいろと資料を漁ると次のようなことが分かった。

- 基本的にはオーバーコミットされず、インスタンス毎にリソースが占有される。ただし"T"インスタンスファミリーはオーバーコミッドされる
- クロック周波数はどうなるの？→インスタンスファミリー毎に使われているCPUが異なる。オーバーコミットされないという言葉をそのまま受け取れば、インスタンスファミリーで使われているCPUのクロック数をそのまま予約している状態ということ？（間違っていたら教えてください！）[Amamzon EC2 インスタンスタイプの選び方](https://pages.awscloud.com/rs/112-TZM-766/images/C2-07.pdf)



### その他参考

- [Amazon EC2 Performance Deep Dive](https://d0.awsstatic.com/events/jp/2017/summit/slide/D4T2-5.pdf )
- [Amazon EC2 インスタンスタイプ](https://aws.amazon.com/jp/ec2/instance-types/)


この記事はAWS初学者を導く体系的な動画学習サービス
「AWS CloudTech」の課題カリキュラムで作成しました。
https://aws-cloud-tech.com
AWS無料枠を意図せず超えてしまった話(backup storage exceeding free allocation)

AWSで20円ほどの課金が発生してしまいました。請求書を確認するとRDSで料金が発生しているとのことです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/e918887f-7282-d426-9fed-7fa99e6c34c7.png)
<hr>
スナップショットを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/df7e57f2-4cc3-e576-8f8e-23d04ac8fbb8.png)
<hr>
DBインスタンス削除済みのものが残ってました。これが原因で請求されてるそうなのでアクションから削除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/e032fa03-c9b1-8d0c-51de-4e80897209fa.png)
<hr>
#Scratch での幽霊の効果とスタンプを組み合わせのテスト【 #GWアドベントカレンダー 2021/5/3 】

この記事は、2021年の [GWアドベントカレンダー](https://gw-advent.9wick.com/calendars/2021/103) 5/3の分の記事です。

## はじめに
Scratch で「幽霊の効果（透明度を変えるもの）を適用したスプライトでスタンプを押すと、透明度が設定されたスタンプが押される」というのを知り、これを応用したものを試してみようと思っているのですが、その前に「挙動をまずは確認してみた」というのが今回の記事です。

## 透明度の異なるスタンプを押す
今後、試してみたいこととして「透明度の異なるスタンプをいろいろ重ねて、視覚的に面白いものを作れないか検討する」というものがあるのですが、今回は「単一のスプライトで透明度の異なるスタンプを押してみて、見え方を確認する」ということだけやってみます。

### 結果
先に、試してみた結果を 2つ掲載します。

1つ目は「一定の透明度のスプライトを使い、スタンプを同じ場所に重ねて押す回数を変えてみて透明度を変える」というもの。
![スタンプを押す回数を変える.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/def85176-d6ce-61b7-c9f4-d90890f47af8.jpeg)

2つ目は「スプライトの透明度を変えてスタンプを押す」というもの。
![幽霊の効果の大きさを変える.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/0f6b29f3-441a-626d-1594-758533049f3b.jpeg)

### 作った内容
#### 1つ目
最初に、1つ目の「一定の透明度のスプライトを使い、スタンプを同じ場所に重ねて押す回数を変えてみて透明度を変える」というほうのコードを掲載します。
![お試し1のコード.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/4c35b75a-e192-754a-94d5-bd283dddf82f.jpeg)

処理の最初に、スプライトの幽霊の効果を 90 にします（100 にすると完全に透明になる）。その後「スタンプを1回押す⇒場所を変える⇒スタンプを2回押す⇒場所を変える⇒スタンプを3回押す⇒...」という処理を行うのがおおまかな内容です。

スタンプを重ねて押す処理は、処理時間を削減するために以下のブロック定義の「画面を再描画せずに実行する」を使っています。
![ブロック定義.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/a14dae13-8db3-7a79-9d59-99e4eb194a52.jpeg)

#### 2つ目
次に 2つ目の「スプライトの透明度を変えてスタンプを押す」というほうのコードについて説明します。
![お試し2のコード.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/7612d740-0254-00d1-416c-6d3b0e45ca7e.jpeg)

内容は単純で、最初にスプライトの幽霊の効果を 90 にします。その後「スタンプを押す⇒場所を変える⇒幽霊の効果を少し変える⇒スタンプを押す⇒...」という処理を繰り返す、というのがおおまかな内容です。
幽霊の効果を変えるのは -3ずつで、それを30回繰り返しているので、最初は 90 だった幽霊の効果が最後には 0 になります。
EC2にPHPでWebAPIをサクッと作る

## やりたいこと
- 検証用のEC2にWebAPIをサクッと作る
- PHPで実装

クライアントの要望でEC2上にPHPで簡単なRestAPIを作成することになった。
作成するのはPostとPutの2つのAPIのみ。

PHP自体が初なのでそもそもの実現方法から検討。

調べたところ生のPHPでもroutingなどは行えそうではあったが、Larvelの軽量フレームワークLumenであれば割と手軽に入れて実装自体も簡単そうだったので今回はLumenで対応。

![Screen Shot 2021-05-03 at 0.25.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245027/e5d76a8d-9663-dbef-b547-dfe5c95cd82f.png)
https://lumen.laravel.com/

## 手順
### 1. EC2にapacheをインストール

まずは更新

```
sudo yum update -y
```

次にインストール

```
sudo yum install httpd
```


### 2. EC2にphpをインストール
EC2用のPHPを入れることで7系のPHPのインストールが行える。
（LumenがPHP7.3以降しか対応していない）

```
sudo amazon-linux-extras install php7.4 -y
```

### 4. EC2にcomposerをインストール
Lumenを利用するために必要なcomposerをインストールする。

公式サイトに記載があるコマンドをコピペして実行
https://getcomposer.org/download/


```
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
```

composerの本体はbin以下においておく

```
sudo mv composer.phar /usr/local/bin/composer
```


### 5. Lumenのセットアップ

まずはLumenで必要なライブラリをインストール

```
sudo yum install php-mbstring php-pecl-memcached php-gd php-apcu php-xml -y
```

続いてLumenを入れていく

```
composer global require "laravel/lumen-installer=~1.0"
```

プロジェクトの雛形を作成する

```
cd /var/www/html
lumen new blog
```

※上記のコマンドの最後の`blog`がフォルダ名になるので自由に変える
※apache上で動かすので `/var/www/html`　配下に作成した。



なお、Lumenを入れずにcomposerの以下のコマンドでもプロジェクトの雛形は作成可能

```
composer create-project --prefer-dist laravel/lumen blog
```

### 6. 権限設定
Lumenのログとキャッシュのフォルダに書き込み権限を付与する。
これやらないとログが出せない。

```
cd /var/www/html/blog
chmod -R 777 bootstrap
chmod -R 777 storage
```

### 7. Apache Virtual Hostの設定
`/etc/httpd/conf.d`以下に`vhost.conf`を作成する。
※ファイル名は拡張子が`.conf`であればなんでもOK

中身を記載する
※`DocumentRoot`と`ServerName`でどのドメインでアクセスされたらどこをDocumentRootにするかを指定するための設定

```
<VirtualHost *:80>
    DocumentRoot /var/www/html/blog/public
    ServerName [EC2のパブリックDNS名称]
    <Directory "/var/www/html/blog/public">
        # allow .htaccess 
        AllowOverride All

        # Setting Laravel environment
        SetEnv APP_ENV development

        # Allow access
        Require all granted
    </Directory>
</VirtualHost>
```

一旦これでポート80のhttpの通信に対応できるようになる。
Direcory以下を記載しないとRestのRountingが動かないので記載する。
APP_ENVとかは多分なくても動く。

ドメイン直下にアクセスするとLumenのバージョンが表示される。

```
Lumen (8.2.3) (Laravel Components ^8.0)
```


### 8. 完了
これで一通りの設定は完了
あとは好きなように実装するのみ。



## 参考
- https://qiita.com/miriwo/items/b25f9d4d74b7103f6ff6
【AWS】lambdaでKMSを用いて環境変数の暗号化・復号化【Python】

# 概要

lambda使っててAPIを叩きたい時にシークレットキーなどの情報を環境変数に平文で置きたくないですよね．
その時に用いるサービスが**KMS(Key Management Service)**です．

この記事ではKMSを用いて`lambda_function`の中で使用する環境変数の暗号化からプログラム中で復号化するところまでご紹介します(私自身AWS初心者で嵌ってしまったポイントがあるので記事にしました)．

lambdaで使用する言語は`Python`で，コンソール上で操作を行います．

# 流れ

ざっくりした流れは以下のようになります．

1. KMSのカスタマー管理型キーの作成
2. 対象のLambda関数に KMS:Decrypt 権限を与える
3. 環境変数の作成・暗号化
4. 関数上で暗号化された環境変数の復号化

## 1. KMSのカスタマー管理型キーの作成

KMSの管理コンソールへ行き，**キーの作成**を行います．
キーのタイプの選択がありますが，対称でいいと思います．

今回は「user/kms-test」というエイリアスをつけました．
説明やタグは適当に設定しましょう．
![2021-05-03_22h53_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427721/a833c630-a283-ffb9-918f-893b1c03516d.png)

次の**キーの管理アクセス許可の定義**や**キーの使用アクセス許可の定義**は各々の設定に合わせます．
ここでlambda関数にのみ権限を与えるのが本来いいとは思います(が面倒なので私はAdminに設定しました)．
たとえば[こちらの記事](https://www.yamamanx.com/aws-lambda-kms-python-environ/)ではこの時点でlambda関数にロールを設定しています．

## 2. 対象のLambda関数に KMS:Decrypt 権限を与える

まず実行ロールの設定します．IAMコンソールの[こちらのページ](https://console.aws.amazon.com/iam/home#/policies)にアクセスしてポリシーの作成を行います．

下の図のように設定を行います．サービスに**KMS**，アクションに**Decypt**，リソースに先程作成したKMSのカスタマー管理キーのARNを記述します．
![2021-05-03_23h08_21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427721/a859b55f-69d1-e23c-59cb-bc1405e5b6c6.png)
名前は**lambda-kms-decrypt-policy**としました．

次にlambda関数に今作成したポリシーをアタッチします．
[こちらのページ](https://console.aws.amazon.com/iam/home#/roles)にアクセスして対象のlambda関数のロールを選択します．すると**ポリシーをアタッチします**というボタンがあると思うのでクリックしてください．そこで先程作成したポリシーを選択します．

## 3. 環境変数の作成・暗号化

続いてlambdaでの作業になります．コンソールのlambdaのページから対象の関数のところに行きます．
**設定→環境変数**で環境変数の作成をクリックします．

今回は`TEST_ENCRYPT`という環境変数を試しに作ってみます．
暗号化の設定のところで**転送時の暗号化に使用するヘルパーの有効化**にチェックを入れると暗号化できるようになります．

![2021-05-03_23h19_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427721/5e5acdd4-c366-205a-5ed4-c522bba9afe9.png)

そこで先程作成したKMSキーを選択します．すると下の図のように値が暗号化されました．

![2021-05-03_23h21_51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427721/1fc3a305-538f-eef3-1a64-d2a20e590df4.png)

これで環境変数の設定は以上です．

## 4. 関数上で暗号化された環境変数の復号化

`lambda_function`の例を示します．
以下のコードをテストするとログに暗号化された文字列と復号化された文字列が表示されるはずです．

```python:lambda_function.py
import json

import boto3,os
from base64 import b64decode

def lambda_handler(event, context):
    
    ENCRYPTED = os.environ['TEST_ENCRYPT']
    print(ENCRYPTED)
    DECRYPTED = boto3.client('kms').decrypt(CiphertextBlob=b64decode(ENCRYPTED),EncryptionContext={'LambdaFunctionName': os.environ['AWS_LAMBDA_FUNCTION_NAME']})['Plaintext'].decode('utf-8')
    print(DECRYPTED)
    
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

```

# 最後に

私もAWS初心者のためこれで正しいのか正直わかりません．有識者の方，助言などぜひよろしくお願いします．
あと，**転送時の暗号化に使用するヘルパーの有効化**についてですが，こちらはCDKからは操作できないのでしょうか？コンソール上だけからの設定だと面倒くさいなと思いました...


# 参考

https://dev.classmethod.jp/articles/decrypt-sensitive-data-with-kms-on-lambda-invocation/
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-intro-execution-role.html#permissions-executionrole-console
https://aws.amazon.com/jp/premiumsupport/knowledge-center/kms-invalidciphertextexception/
STM32L010と内蔵ADCで電流を測る 330.0uAまで　10kΩ上側


目的
主にNJL7502Lの微小な電流を測る。
電源のショートが防げて安全になる
まだ確認していない論理的に動くはず05/03


```c++

        //電圧を電流に変換 ex 330.0uA -> 3300 uAの十倍を出力
        s=(s*6600)>>13;

が

        //電圧を電流に変換 ex 330.0uA -> 3300 uAの十倍を出力
        s=4095-s;
        s=(s*6600)>>13;


```


参考
https://qiita.com/caa45040/items/036e92f42bb09b5f8316
STM32L010と内蔵ADCで電流を測る 330.0uAまで　10kΩ下側


```c++

// 電流の測定 10kome max330.0uA !!!上側10kΩ

#include "mbed.h"

//10の割り算 0から1028までは、正しい。主に0から999
#define DVI10(n) ((n*205)>>11)

//アナログ入力の設定
AnalogIn adc_vbat(A3); //PA_4
//AnalogIn adc_vbat(A0); //767

#define ADDR_LCD    (0x7C)   //  address

//I2C i2c(I2C_SDA, I2C_SCL); //767
//I2C i2c(dp5, dp27); //1114
I2C i2c(PA_10, PA_9); //010

char    data_read[8];   //i2cバッファー

char INIT_com[]={0x0,0x38,
0x0,0x39,
0x0,0x4,
0x0,0x14,
0x0,0x70,
0x0,0x56,
0x0,0x6C,
0x0,0x38,
0x0,0xC,
0x0,0x1,
0x40,0x41};

char INIT_cls[]={0x0,0x1};

char ch_hex_a_b[5];
char *ch_hex_a(int l_num)
{
    int a,b,c;

    b=DVI10(l_num);
    c=l_num-(b*10);
    l_num=b;
    a=DVI10(l_num);
    b=l_num-(a*10);

    ch_hex_a_b[0] = '@';
    ch_hex_a_b[1] = '0' + a;
    ch_hex_a_b[2] = '0' + b;
    ch_hex_a_b[3] = '0' + c;
    ch_hex_a_b[4] = 0;

    return(ch_hex_a_b);
} //ch_hex_a

int ii;  //ループカウンタ
int s;   //アナログ読み取り値

int main()
{
    //printf("767\r\n"); //767
    //液晶の初期化
    for(ii=0;ii<11;ii++){
        i2c.write(ADDR_LCD, &INIT_com[ii*2], 2);wait_ms(2);
    } //for
    
    //無限ループ
    while (1) {
        //液晶のクリア
        i2c.write(ADDR_LCD,INIT_cls,2);wait_ms(2);

        //adcの読み込み 0から4096
        s = (adc_vbat.read_u16()>>4);

//        s = 4096;
//        printf("-\n\r"); //767
//        printf(" A=%d",s); //767
        
        //電圧を電流に変換 ex 330.0uA -> 3300 uAの十倍を出力
        s=4095-s;
        s=(s*6600)>>13;

//       s = 3300;
//         printf("\t c=%d",s); //767


//小数点以上と小数点以下を分ける iiは10の桁 sは1の桁
ii = s;
if     ( ii >= 3000 ) { ii = DVI10( (ii - 3000)  ) + 300; s = s - (ii*10); }
else if( ii >= 2000 ) { ii = DVI10( (ii - 2000)  ) + 200; s = s - (ii*10); }
else if( ii >= 1000 ) { ii = DVI10( (ii - 1000)  ) + 100; s = s - (ii*10); }
else                  { ii = DVI10( (ii       )  )      ; s = s - (ii*10); }

//        printf("\t t=%d %d\r\n",ii,s); //767
        
        //温度の小数点以上の表示
        i2c.write(ADDR_LCD, ch_hex_a( ii ) ,4);

//printf("%s",ch_hex_a( ii )); //767

       //温度の小数点以下の表示
        ch_hex_a( s*10 );
        ch_hex_a_b[1] = '.';
      //ch_hex_a_b[2] = '0' + s;
        ch_hex_a_b[3] = 'u';
        i2c.write(ADDR_LCD, ch_hex_a_b ,4);

//printf("%s\r\n",ch_hex_a_b); //767

        //1秒待つ
        wait_ms(1000);

    }//while

}//main

//容量削減
void error(const char* format, ...){}



```
[RPA]UiPath_読み込んだExcelのデータテーブルをテキストエディタに転記する


## [0]はじめに
今回は前回の内容の続きになります。

https://qiita.com/Zitan/items/93146402a4ddcf881cfb

一般事務系の作業で、Excelのデータを別のシステムに転記することがあるので、それっぽいことができればな、と。

## [1]アクティビティ「アプリケーションを開く」
前回の続きです。今、Excelアプリケーションスコープ内はこんな感じになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408638/12a576c3-5f08-5ae6-662f-752e5738ec57.png)

この、Excelアプリケーションスコープ内に、アクティビティ「アプリケーションを開く」をドラッグアンドドロップします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408638/30112dcc-8823-badd-ec34-b308253097fd.png)
「画面上でウインドウを指定」とあります。事前にテキストエディタ(今回サクラエディタ)を開いておいて下さい。

サクラエディタのウインドウを選択します。
[![Image from Gyazo](https://i.gyazo.com/78313b6623bf9108837b21eb15c26b8b.gif)](https://gyazo.com/78313b6623bf9108837b21eb15c26b8b)

下の画像の通り、三本線のボタン？をクリックして、「セレクターを編集」を選んで下さい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408638/e9803657-84e3-5e2c-4868-87afdd537503.png)

セレクターエディターを開くと、今開いていたアプリを認識するための情報が入っています。
既定でチェックが全て入っていて、これによって一意に特定しているようです。
ちょうど、サクラエディタを閉じてしまったので、「検証」が赤色のエラーになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408638/f911611d-316c-98d9-52cf-d8e30a3e7093.png)

いつもエディタを開いているとは限らないのでもう少しセレクターの制約をゆるくします。
これでどうでしょう？「検証」がオレンジ色になりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408638/7be4ad30-2431-6c67-67bc-1416cf0b3d49.png)

「検証」をクリックしてみると緑色になりました。認識できたようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408638/090e4316-713b-b6f6-8e24-7b359916ac07.png)


## [2]アクティビティ「文字を入力」

「アプリケーションを開く」の表示名を「サクラエディタを開く」に変更しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408638/82897883-1b6c-63e5-70cf-1b8722c7bfc9.png)

「サクラエディタを開く」の中にアクティビティ「文字を入力」を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408638/885c1d6f-e48e-c3a4-d6b7-25fe03825f8c.png)

引数は前回取得したExcelのデータテーブルの配列の一要素を代入します。
「<font color="Red">dtExcelSheet_1.Rows(0).Item(1).ToString</font>」
一旦この式を代入します。

## [3]実行してみる
実行結果です。
サクラエディタが新しく起動して、B1セルの値が転記されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408638/272560a7-316f-4463-3922-2aa499068e1e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408638/838a39b8-0356-c274-2df5-b46a6b66a838.png)


## [4]まとめ
いかがでしょうか。
実際の業務ではは条件分岐やループ処理をしますが、Excel内の一つのデータが別のアプリケーションへ書き込みできることが確認できました。
Webブラウザの検索キーワードを事前にExcelに格納しておいて、欲しい結果をExcelに書き込むうようなプロセスも作ってみたいと思います。
※一回処理ができたらループ処理へ応用したいと思っています。
「Win+R」から始まるWindowsのショートカット

Y子です。
今日は、「Win+R」（ファイル名を指定して実行）から始まる、Windowsの便利なショートカットをメモっておきます。
_【[確認環境：Windows 10 Pro (Bld. 19041.928)](https://qiita.com/koiwaiwaiko/items/ef2d457ae1e1a7c8b698 "Windows10のバージョンを確認・表記する")】_

# 「ファイル名を指定して実行」とは何か
「ファイル名を指定して実行」とは、パスが通っているアプリを簡単に起動するための、簡易的なコマンド入力画面のことです。

見た目はこんな感じ。
![WinR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1265690/9d3f140e-e37b-8ddf-0e38-29bb5d0028fe.png)

起動手順は複数あると思いますが、ここでは2通り紹介しておきます。
どちらで起動しても、同じ「ファイル名を指定して実行」が表示されます。

(1) 「スタートメニュー」→「Windowsシステムツール」→「ファイル名を指定して実行」
![Start-ファイル名を指定して実行.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1265690/85cfc821-a3aa-da2a-219d-c3087a8fe382.png)

(2) ショートカット「`Win + R`」

覚えておきさえすれば、後者の方が圧倒的に楽ですね。

次項からは、「ファイル名を指定して実行」が表示されている状態で入力するコマンドについて述べます。

# アプリを起動する
これらのコマンドはパスが通っているため、「ファイル名を指定して実行」から使えます。
わたしは、上の3つ（`cmd`、`notepad`、`calc`）は特によく使っています。

|入力するコマンド|起動するプログラム|備考|
|:-|:-|:-|
|__cmd__|コマンドプロンプト|3文字で起動できるので簡単|
|__notepad__|メモ帳|電器屋の店頭でノートPCのキー入力を試すのによく使います|
|__calc__|電卓|4文字で起動できるので簡単|
|__winver__|Windowsのバージョン情報|[ここ](https://qiita.com/koiwaiwaiko/items/ef2d457ae1e1a7c8b698#2-winver%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89 "Windows10のバージョンを確認・表記する")で使いました|
|__mspaint__|ペイント||
|__control__|コントロールパネル|Windows10ではスタートメニューから辿りにくいので、Win+Rからの起動が便利|
|__regedit__|レジストリエディター||

`C:\Windows\System32`フォルダ内の各アプリは、パスが通っているので同様に起動できます。（`cmd`や`notepad`などもこれです）

また、インストールされていれば、Excel（`excel`）、Word（`winword`）、PowerPoint（`powerpnt`）なども使えます。

パスが通っている（システム環境変数やユーザ環境変数に登録されている）フォルダであれば、その中の実行ファイルも扱えます。そのためにパスを通すのもアリと思います。

# フォルダを開く
フォルダのパスを指定するなどして、フォルダを開くことができます。

|入力するコマンド|開くフォルダ|備考|
|:-|:-|:-|
|__c:__|Cドライブ|もちろん「d:」「e:」なども（あれば）使えます|
|__shell:sendto__|SendTo|ここにショートカットを置くと、コンテキストメニューの「送る」に表示されます|
|__shell:startup__|スタートアップ|ここにショートカットを置くと、ログイン時に自動で実行されます|
|__shell:recent__|最近使った項目|自分が過去数日間に開いたファイル等のショートカットが並んでいます|

`shell`で始まる特殊フォルダは、ほかにもいろいろあるようです。

https://www.atmarkit.co.jp/ait/articles/1401/24/news036.html

# URL等を開く
メールで、「このサイトを見て」とURLが送られてきたり、「ファイルサーバのここに置いた」とネットワーク上のパスが送られてくることがあると思いますが、これらを「ファイル名を指定して実行」にペーストして実行すれば、ブラウザや適当なアプリケーションで開くことができます。

# おまけ：メモ帳を白背景として使う
自分に合ったテキストエディタ（わたしは「サクラエディタ」か「秀丸」）をインストールしてしまうと、「メモ帳」はなかなか出番がなくなりますが、たまに「最大化したメモ帳を背景に、小さいスクショを撮る」なんて用途で使ったりもします。
無地の白背景を一番早く用意できるのが、メモ帳な気がします。
`Win+R`、`notepad`、`Win+↑`
5秒かかりません。ご参考まで。

# おわりに
ショートカットは、覚えれば覚えるだけPC操作が楽になりますが、覚えるのが苦痛の場合はどうしたらいいんでしょうね笑。
覚えると決めて、反復するしかないか。

では！
RubyでServerless Frameworkを構築するための覚書

Ruby使ってさっくりlambda functionのAPIを立ち上げるための覚書

# 準備
Serverless Framework のインストール

```bash
$ npm install -g serverless
```

テンプレートの展開

```bash
$ serverless create -t aws-ruby
```

rbenvを利用しているのでRubyのバージョンを指定

```bash
$ rbenv local 2.7.3
```

## API Gatewayを生やしてHTTPリクエストを受け付けるように修正

```yml
# serverless.yml
functions:
  handler:
    handler: handler.webhook
    events:
      - httpApi:
          path: /webhook
          method: get
```

## デプロイ

```bash
$ serverless deploy -v
```

## 環境変数
### dotenv
開発をする上でdotenvを利用

https://github.com/neverendingqs/serverless-dotenv-plugin

step1: serverless-dotenv-pluginをインストール

```bash
$ npm i -D serverless-dotenv-plugin
```

.envファイルの修正

```.env
SAMPLE_ENV=hogehoge
```

serverless.ymlの修正

```yml
frameworkVersion: '2'

useDotenv: true

...

functions:
  webhook:
    handler: handler.hello
    events:
      - httpApi:
          path: /hello
          method: get
    environment:
      SAMPLE_ENV: ${env:SAMPLE_ENV}
```

https://www.serverless.com/framework/docs/environment-variables/

# 参考
[Building an API with Ruby and the Serverless Framework
](https://www.serverless.com/blog/api-ruby-serverless-framework)