OmniAICreator/Qiita-1.07M huggingface dataset:
備忘録〜htmlの構造〜

######この記事ではhtml.cssのプロゲートでの学習を自分の言葉で書き出しています。何か訂正や付け足しなどがございましたらご教授いただけると大変嬉しいです。

##HTMLの全体構造
大きく分けてHTMLは３つのマトリョーシカがある
##１.HTMLのマトリョーシカ

```haml:qiita.html
<html>
htmlのコードを全てここに記入していく
</html>
```

##2.headとbodyのマトリョーシカ

```haml:qiita.html
<html>
  <head>
    htmlで使う部品を記入
  </head>
  <body>
    htmlの見た目の構造を組み立てる部分
  </body>
</html>
```

##3.bodyの中にdivで分けたマトリョーシカ
主に`header`、`main`、`footer`

```haml:qiita.html
<html>
  <head>
  </head>
  <body>
    <div class="header">
    </div>
    <div class="main">
    </div>
    <div class="footer">
    </div>
  </body>
</html>
```
あとはdiv中で分けたマトリョーシカの中に同じくdivで分けるなどしてデザインを作っていく
円同士の衝突処理【開発備忘録-5月後期】

専門学校に通い始めてはや2カ月。
5月後期の作品は専門学校の課題として提出するということもあり、比較的力を入れて制作を行った。
その中で、新たに得た知見や反省点をここにしたためていこうと思う。


今作は「**円形の駒をぶつけあって戦う、簡単戦略シミュレーション**」。
小学校の卓上でよく遊ばれる「消しゴムバトル」、あるいはおはじきのようなものをイメージしてもらうと伝わりやすいだろうか。
ゲームの詳細はここでは割愛。Twitterにて紹介動画を上げているので、興味があればそちらを参照してほしい。
https://twitter.com/i/status/1401753151816929281
https://twitter.com/i/status/1401781344192000010
https://twitter.com/i/status/1401803148465827840

--------------------------------------------

さて、本作を作るにあたって最も重要になる処理が「**円の衝突**」である。
衝突処理のフローとしては、

**１．衝突判定(当たり判定)**
**２．押し戻し処理**
**３．運動量・ベクトル計算**
以上の３ステップとなる。


１に関しては今回円同士であるがゆえに非常に簡単で、
「**2円の半径の合計>=2円の中心間の距離**」
となる場合、衝突していることとなる。
円の中心間の距離は言わずもがな、三平方の定理で求めることができる。

２については今作のように厳密な計算を求める必要がなければ、
円同士を最短距離…すなわち、円の中心を結ぶ線の延長線に向かって必要分移動させてやれば良い。
実際、この処理でも今作では全く違和感なく動いているように見えた。

問題となるのが3である。
円Aに向かって円Bが衝突する状況を思い浮かべてほしい。
直撃した場合円Aは勢いよくはじかれ、円Bも今までの運動とは反対方向へ跳ね返されるのに対し、
掠めるように当たった場合円Aはほとんど動かず、円Bは素通りするかのように動くはずだ。

物理数学に疎い私には思いつかなかったが、どうやらこれは衝突した円を串にささった団子にたとえると、
「**串に対して水平方向にはたらく力**」
「**串に対して垂直方向にはたらく力**」
一度この2つに運動を分解することで解決するようである。

要するに、衝突計算に関係がある力と無い力を一度分離し、関係のあるものだけで計算するというのが大前提となるのだ。

ここまでを理解したうえで下記の記事を読むことで、実際の計算を行うことができるだろう。
(ちなみに記事内に出てくる変数「t」とは、どうやらタンジェントのことのようだ。私はこれでしばらく悩んだので、念のため。)
https://hakuhin.jp/as/collide.html

-----------------------------------------------------

ここまでが技術的なお話。
次に、開発のスケジュール管理についてだ。

-----------------------------------------------------

今回は課題提出ということで期限が設定されていたのだが、私は期限までにゲームを完成させることはできなかった。
もちろん一通り遊ぶことはできるのだが、PvEモードやチュートリアルなどをはじめ、実装したかった仕様を涙を呑んで諦めることになってしまったのだ。
また、期限に追われ余裕がなくなってしまったことで生活習慣は乱れ、しょうもないミスをして学校の先生にもお叱りを受けるなど、肉体的にも精神的にも追い込まれる形になってしまった。

いくつか原因はあるのだが、一番大きいのはゲーム開発の流れの誤解…というよりも、無知であろう。
制作の初期には凝ったタイトル画面を作り、意気揚々と開発を進めていたのだが、途中からわけがわからなくなり頓挫。
そのタイミングで構造体や関数などを習ったこともあり、それまで書いたコードをはじめから組み直し、そうこうしているうちに期限が迫る…と。
冷静に振り返ると、あまりにも計画性が無さ過ぎて笑えて来るほどだ。

そんな中、制作終盤において先生方が質問対応を行ってくれる授業があったため、ゲーム制作の計画についての指導を仰いでみたところ、非常に納得のいく話があったので共有しておこう。

それは、「**一番難しい処理から作るべし**」ということ。
確かに工数の見積もりが最も難しい、あるいは実現可能かすら危うい部分から済ませておけば、後々困ることは減るのではないだろうか。

当然のことのようで、過去の私にはできていなかったことである。
これまで同様、プレイヤー目線でしかゲームを追えていなかったことの表れでもあるだろう。
逆に言えば、これからはゲームクリエイターとしての目線に立たなければならない。

---------------------------------------------------------------

以上、大きく２点が５月後期の制作にて学んだことである。
もちろん細かいことを挙げだせばキリがないが、今回は割愛させてもらおう。

今作は規模が大きく、６月にめり込む形となってしまったこともあるので、６月前期、次回作は軽めの一品を予定している。
三角関数についての理解が怪しい部分が多いので、円や波を利用した作品を作りたいところだ。
csvhelperのエラー処理

# Summary 
csvhelperにおけるエラー処理

## script

```fsharp
#r "nuget: csvhelper"

open System.Globalization
open System.IO
open CsvHelper
open CsvHelper.Configuration


[<CLIMutable>]
type public Csv =
  {
    name : string
    price : int
    color : string
    memo : string
  }


[<Sealed>]
type public CsvMap () as this =
  inherit ClassMap<Csv>()
  do
    this.Map(fun x -> x.name).Index(0) |> ignore
    this.Map(fun x -> x.price).Index(1) |> ignore
    this.Map(fun x -> x.color).Index(2) |> ignore
    this.Map(fun x -> x.memo).Index(3) |> ignore


let public csvRead  (streamReader:StreamReader)  =

  let csvConfig : CsvConfiguration  =
    CsvConfiguration(CultureInfo.CurrentCulture)
    |> fun x ->
      x.Delimiter <- ","
      x.HasHeaderRecord <- true
      x.DetectColumnCountChanges <- true
      x

  use csv = new CsvReader(streamReader , csvConfig )
  csv.Context.RegisterClassMap<CsvMap>() |> ignore

  let mutable flg = true
  while flg do
    try
      flg <- (csv.Read())
      if flg
      then csv.GetRecord<Csv>() |> printfn "%A"
    with
      | :? BadDataException ->
        printfn "bad data exception!"
      | :? TypeConversion.TypeConverterException ->
        printfn "type conversion exception!"
      | _ ->
        printfn "others exeption!"


new StreamReader( "./fruits.csv"  )
|> csvRead

```

## Csv1

```csvs
name,price,color,memo
apple,300,red,solid sweet!
banana,1,980,yellow,great sweet!
cherry,520,black,very delicious!
```

error

```
{ name = "apple"
  price = 300
  color = "red"
  memo = "solid sweet!" }
bad data exception!
{ name = "cherry"
  price = 520
  color = "black"
  memo = "very delicious!" }
```

## csv2

```csvs
name,price,color,memo
apple,300,red,solid sweet!
banana,aaa,yellow,great sweet!
cherry,520,black,very delicious!
```

error

```
{ name = "apple"
  price = 300
  color = "red"
  memo = "solid sweet!" }
type conversion exception!  
{ name = "cherry"
  price = 520
  color = "black"
  memo = "very delicious!" }
```

# 現場からは以上です
AWS Lambda で TensorFlow を使う

# 手段
Lambda は ECR のイメージからコンテナを展開し、その中の関数を使うことができます
というわけで以下のフローで実現します

* TensorFlow が使えるイメージ作成
* ECR にプッシュ
* Lambda にデプロイ

# ツール
* Docker
* AWS CLI
* serverless（lambdaにデプロイするのに使います。`npm install serverless`で導入できます。）

# 実装
それでは実装していきましょう
## イメージ作成
以下のような構成を作成します

```
project
├── Dockerfile
├── app.py
└── requirements.txt
```


#### Dockerfile 作成
AWS のパブリックイメージからビルドしていきます

```dockerfile
FROM public.ecr.aws/lambda/python:3.8

COPY . ${LAMBDA_TASK_ROOT}
RUN pip install -r requirements.txt
CMD ["app.handler"]
```



#### requirements.txt 作成
python で必要になるライブラリを書いていきます
今回は TensorFlow が必要なので、こちらを記述します
必要があれば、numpy なども書いておきましょう

```requirements.txt
tensorflow==2.5.0
```



#### app.py 作成
今回は TensorFlow を動かしたいだけなので、動作確認だけします

```app.py
import tensorflow as tf


def handler(event, context):
    return {
        'statusCode': 200,
        'body':
            {
                'predict': tf.__version__,
            }
    }
```


#### ECR にプライベートリポジトリを作成
ECR にプライベートリポジトリを作りましょう
今回は、`func1` という名前のリポジトリにしました
![0123.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516428/a88ba7ab-f96f-9319-b7b3-ba31bd4b99b8.png)


#### ECR にプッシュ

まずは、パブリックイメージをプルできるように認証を得ておきます

````shell
$ aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws
````

次に、プライベートリポジトリにプッシュできるよう認証を得ておきます

```shell
$ aws ecr get-login-password | docker login --username AWS --password-stdin {アカウントID}.dkr.ecr.{リージョン}.amazonaws.com.
```

その後、イメージを作成してプッシュしましょう
プッシュすると、ダイジェストが返ってくるので控えておいてください

```shell
$ docker build -t func1 .
$ docker tag func1 {アカウントID}.dkr.ecr.{リージョン}.amazonaws.com/func1
$ docker push {アカウントID}.dkr.ecr.{リージョン}.amazonaws.com/func1
digest:  sha256:~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # 控えておく
```
<br>

## Serverless でデプロイ
serverless を使って、lambda にデプロイしていきます
#### serverless.yml 作成
プロジェクト配下に作成します

```
project
├── Dockerfile
├── app.py
├── requirements.txt
└── serverless.yml
```

Lambda にデプロイする際の設定を書きます
先ほど控えたダイジェストを使って、ECR にあげたイメージを指定します

```serverless.yml
service: tf-test

provider:
  name: aws
  stage: dev
  region: ap-northeast-1

functions:
  hello:
    image: {アカウントID}.dkr.ecr.{リージョン}.amazonaws.com/func1@sha256:{ダイジェスト}
    memorySize: 2048
    timeout: 180
```

#### serverless を AWS にアクセスできるようにする
serverless用に AWS の IAM ユーザーを作成しておきます
プログラムによるアクセスにチェックを入れておいてください
アクセス権限は AdministratorAccess をアタッチします

作成時に取得したアクセスキーとシークレットアクセスキーで、serverless にアクセス権限を付与します

```shell
$ serverless config credentials --provider aws --key {アクセスキー} --secret {シークレットアクセスキー}
```

#### デプロイ

以下のコマンドでデプロイ完了です！

```shell
$ serverless deploy
```
Ktor でPOSTリクエストを送る際、詰まったこと

# 困ったこと
Ktor使用時、POSTメソッドでJSONを受け取った際、データの中身を受け取ることができなかった

# 構成
- ktor_version=1.5.1
- kotlin_version=1.4.21
- exposedVersion=0.31.1

# ソースコード
```Application.kt
fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)

@Suppress("unused") // Referenced in application.conf
@kotlin.jvm.JvmOverloads
fun Application.module(testing: Boolean = false) {
    install(Locations) {
    }

    install(ContentNegotiation) {
        jackson {
            enable(SerializationFeature.INDENT_OUTPUT)
        }
    }
    routing {
        userController(userService) // ここでコントローラーを呼び出す
    }
}
```

```UserController.kt
fun Routing.userController() {
    data class UserRegisterLocation(val name: String, val email: String)
    post("/user"){
        val registerRequest = call.receive<UserRegisterLocation>()
        val request = RegisterUserRequest(registerRequest.name, registerRequest.email)
        call.respond("status" to "OK")
    }
}
```
このように書けば、```registerRequest```変数でUserRegisterLocation型のデータを受け取れると思ったが、

```
curl -H 'Content-Type:application/json' -X POST -d '{\"name\":\"test\", \"email\":\"test@example.com\"}' http://localhost:8080/user
```
のようにリクエストを送信するとログに以下のように表示される

```
[eventLoopGroupProxy-4-1 @call-handler#3] INFO  Application - Unhandled: POST - /user, io failed
```

# 解決策
公式のドキュメントを読むと、クラスはトップレベルで定義する必要があるということらしい。

https://jp.ktor.work/servers/calls/requests.html

そこで、```UserController.kt```内でUserRegisterLocationをuserController関数内で定義していたものを、トップレベルで定義するように変更すると

```UserController.kt(修正後)
// data classをトップレベルで定義する
data class UserRegisterLocation(val name: String, val email: String)

fun Routing.userController() {
    post("/user"){
        val registerRequest = call.receive<UserRegisterLocation>()
        val request = RegisterUserRequest(registerRequest.name, registerRequest.email)
        call.respond("status" to "OK")
    }
}
```

```
TRACE Application - 200 OK: POST - /user
```
と返ってきた
【docker-compose】requests.exceptions.HTTPError: 500 Server Error: Internal Server Error for url: http+docker://localhost/version

## エラー内容
下記の記事を参考に
https://qiita.com/eighty8/items/0288ab9c127ddb683315

```
$ docker-compose run --rm app rails new . --force --database=mysql --skip-bundle
```
を入力したところ、下記のエラーが発生。

```
Traceback (most recent call last):
  File "docker/api/client.py", line 268, in _raise_for_status
  File "requests/models.py", line 941, in raise_for_status
requests.exceptions.HTTPError: 500 Server Error: Internal Server Error for url: http+docker://localhost/version

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "docker/api/client.py", line 214, in _retrieve_server_version
  File "docker/api/daemon.py", line 181, in version
  File "docker/api/client.py", line 274, in _result
  File "docker/api/client.py", line 270, in _raise_for_status
  File "docker/errors.py", line 31, in create_api_error_from_http_exception
docker.errors.APIError: 500 Server Error for http+docker://localhost/version: Internal Server Error ("b'dial unix docker.raw.sock: connect: connection refused'")

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "docker-compose", line 3, in <module>
  File "compose/cli/main.py", line 81, in main
  File "compose/cli/main.py", line 200, in perform_command
  File "compose/cli/command.py", line 60, in project_from_options
  File "compose/cli/command.py", line 152, in get_project
  File "compose/cli/docker_client.py", line 41, in get_client
  File "compose/cli/docker_client.py", line 170, in docker_client
  File "docker/api/client.py", line 197, in __init__
  File "docker/api/client.py", line 221, in _retrieve_server_version
docker.errors.DockerException: Error while fetching server API version: 500 Server Error for http+docker://localhost/version: Internal Server Error ("b'dial unix docker.raw.sock: connect: connection refused'")
[6004] Failed to execute script docker-compose
```

## 解決策
こちらの記事を参考に、
https://github.com/docker/for-win/issues/9561
docker-compose.ymlのversion指定をシングルクォーテーションからダブルクォーテーションに変えたらエラーが消えました。

```
# 修正前
version: '3'
```

```
# 修正後
version: "3"
```

理由はわかりません。
Rails 条件つきバリデーション

<h2>条件つきバリデーションとは？</h2>
標準であるバリデーションだけでは対応できずに、特定の条件を満たす場合に実行したいバリデーションのこと。

[if],[unless]オプションを使用して記述することで、
特定の条件に対応することができる。

引数にProc,Arrayを使える。


<pre>if #特定の条件でバリデーションを行いたい時に使用
unless #特定の条件でバリデーションを行いたくない時に使用</pre>

<h3>if,unless</h3>

<pre>class Pass < ApplicationRecord
  validates :number, presence: true, if: :pass_number?

  def pass_number?
    pass_type == "pass"
  end
end</pre>


<pre>class Money < ApplicationRecord
  #money_validate関数の呼び出し
  validate :money_validate
　
　def money_validate
    unless money.nil? || money > 0.0
  end
end</pre>



<h3>Proc</h3>
<cite>呼び出したいProcオブジェクトを:ifや:unlessで使うこともできます。Procオブジェクトを使うと、個別のメソッドを指定する代りに、その場で条件を書けるようになります。ワンライナーに収まる条件を使いたい場合に最適です ~Railsガイド~</cite>

<cite><pre>class Account < ApplicationRecord
  validates :password, confirmation: true,
    unless: Proc.new { |a| a.password.blank? }
end
~Railsガイド~</pre></cite>


リファレンスには上記のように記述されていましたが、
Proc。newでオブジェクトを作成、引数aに渡し、
a.password.blank?で真偽値の判断？

<h2>条件付きバリデーションのグループ化</h2> 
<h3>with_options</h3>
1つの条件を複数のバリデーションでまとめて処理を行うにはwith_optionsを使用

<cite><pre>class User < ApplicationRecord
  with_options if: :is_admin? do |admin|
    admin.validates :password, length: { minimum: 10 }
    admin.validates :email, presence: true
  end
end 
Rails ガイド</pre></cite>

if: :is_admin?という条件に対してバリデーションが働く

<h3>Array,配列</h3>
バリデーションを行なう条件を複数定義する際には、Array 配列を使用
<cite><pre>class Computer < ApplicationRecord
  validates :mouse, presence: true,
                    if: [Proc.new  { |c| c.market.retail? }, :desktop?],
                    unless: Proc.new { |c| c.trackpad.present? }
end
Railsガイド</pre></cite>

備忘録です。

<H2>参考サイト</h2>
https://railsguides.jp/active_record_validations.html#%E3%83%90%E3%83%AA%E3%83%87%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%AB%E5%AF%BE%E5%BF%9C%E3%81%99%E3%82%8B-errors

https://qiita.com/tmzkysk/items/a0c874715ba38eb23350

https://www.y-hakopro.com/entry/2019/10/29/213945
SQLインジェクション

## SQLインジェクションとは
アプリケーションのセキュリティ上の不備を意図的に利用し、アプリケーションが想定しないSQL文を実行させることにより、データベースシステムを不正に操作する攻撃方法のこと、また、その攻撃を可能とする脆弱性のことです。
SQLに別のSQL文を「注入（inject）」されることから、「ダイレクトSQLコマンドインジェクション」もしくは「SQL注入」とも呼ばれます。

アプリケーションが入力値を適切にエスケープしないままSQL中に展開することによりで発生します。

次のようなSQLが発行されることを前提に説明します。

```sql
SELECT * FROM users WHERE name = '（入力値）';
```
ここで入力値に "1' OR '1' = '1" という文字列を与えた場合を考えると、SQL文は次のように展開されます。

```sql
SELECT * FROM users WHERE name = '1' OR '1' = '1';
```

上記のSQL文では条件が常に真となるため、nameカラムの値にかかわらず、レコードが全件取得できてしまいます。このような攻撃は、入力値が1つだけのものに限りません。
また、これを応用してSELECTの条件式にデータベース内の情報を確認するようなサブクエリーを含ませ、その抽出の成否によって本来参照することのできないデータベース内の情報（テーブル名など）を知ることができる、ブラインドSQLインジェクションと呼ばれる手法も存在する。
また、複数のSQL文を注入することによるデータの破壊や改竄、ストアドプロシージャを実行させ、情報の漏洩や改竄、OSコマンドの実行などを引き起こすこが可能のる場合があります。

### 対策
- 型を指定する
- 静的プレースホルダの利用する
- 発行するsql文の中で文字列展開をしない
- 文字エンコーディングを指定する
- 入力値に対してのチェックを行う

### Javaでの静的プレースホルダ実装例

```java
import java.sql.PreparedStatement;

public class Main {

    public static void main(String[] args) {
        /**
         * 省略
         */
        stmt = conn.prepareStatement("SELECT name, secret FROM users WHERE user = 'true' AND name = ? AND password = ? ");
        stmt.setString(1, name);
        stmt.setString(2, password);
        rs = stmt.executeQuery();
    }
}

```
【docker-compose】FileNotFoundError: [Errno 2] No such file or directory

## エラー内容
下記の記事を参考に
https://qiita.com/eighty8/items/0288ab9c127ddb683315

```
$ docker-compose run --rm app rails new . --force --database=mysql --skip-bundle
```
を入力したところ、下記のエラーが発生。

```
Traceback (most recent call last):
  File "urllib3/connectionpool.py", line 670, in urlopen
  File "urllib3/connectionpool.py", line 392, in _make_request
  File "http/client.py", line 1255, in request
  File "http/client.py", line 1301, in _send_request
  File "http/client.py", line 1250, in endheaders
  File "http/client.py", line 1010, in _send_output
  File "http/client.py", line 950, in send
  File "docker/transport/unixconn.py", line 43, in connect
FileNotFoundError: [Errno 2] No such file or directory

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "requests/adapters.py", line 439, in send
  File "urllib3/connectionpool.py", line 726, in urlopen
  File "urllib3/util/retry.py", line 410, in increment
  File "urllib3/packages/six.py", line 734, in reraise
  File "urllib3/connectionpool.py", line 670, in urlopen
  File "urllib3/connectionpool.py", line 392, in _make_request
  File "http/client.py", line 1255, in request
  File "http/client.py", line 1301, in _send_request
  File "http/client.py", line 1250, in endheaders
  File "http/client.py", line 1010, in _send_output
  File "http/client.py", line 950, in send
  File "docker/transport/unixconn.py", line 43, in connect
urllib3.exceptions.ProtocolError: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "docker/api/client.py", line 214, in _retrieve_server_version
  File "docker/api/daemon.py", line 181, in version
  File "docker/utils/decorators.py", line 46, in inner
  File "docker/api/client.py", line 237, in _get
  File "requests/sessions.py", line 543, in get
  File "requests/sessions.py", line 530, in request
  File "requests/sessions.py", line 643, in send
  File "requests/adapters.py", line 498, in send
requests.exceptions.ConnectionError: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "docker-compose", line 3, in <module>
  File "compose/cli/main.py", line 81, in main
  File "compose/cli/main.py", line 200, in perform_command
  File "compose/cli/command.py", line 60, in project_from_options
  File "compose/cli/command.py", line 152, in get_project
  File "compose/cli/docker_client.py", line 41, in get_client
  File "compose/cli/docker_client.py", line 170, in docker_client
  File "docker/api/client.py", line 197, in __init__
  File "docker/api/client.py", line 221, in _retrieve_server_version
docker.errors.DockerException: Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))
[5763] Failed to execute script docker-compose
```

## 解決方法
単純に、Dockerを立ち上げていないだけでした。
僕はDocker Desktopを使っているので、アプリを立ち上げるだけでした。
Linux基礎学習まとめ② viエディタの基本操作(カーソル移動、編集操作）

##概要
Linuxには、`vi`というエディタ（ページャ）が存在します。
`vi`を用いることによって、様々なファイルを編集したり、シェルスクリプトなどのプログラミングを行うこともできます。

ここでは、よく使いそうな`vi`の操作をメモしておきます。
操作としては、`Esc`を押した際のコマンドモードを前提としています。



##実行環境
- macOS BigSur 11.4
- CentOS7 (macOS上でLinux環境を構築する方法は[こちら](https://qiita.com/tamago3keran/items/781728815e359243ff33)を参考にしました)

##1. カーソル移動系
|操作キー|動作 | 
|:---- |:------|
|`h`   |`←`    |
|`j`   |`↓`    |
|`k`   |`↑`    |
|`l`   |`→`    |
|`gg`  |ファイルの先頭に移動|
|`G`  |ファイルの末尾に移動|
|`:n`  |n行目に移動|

##2. 編集操作系（コピペ、検索、置換）
|操作キー|動作 | 
|:---- |:------|
|`x`   |１文字削除    |
|`dd`   |１行削除   |
|`yy`   |１行コピー   |
|`p`   |カーソルの次にペースト    |
|`P`   |カーソルの前にペースト   |
|`u`   |編集操作の取り消し    |
|`/"string"`|検索したい文字列("string")をハイライト、nで下方向、Nで上方向にカーソル移動|
|`:[option]s/old/new/g[option]`   |基本的な置換の形。%で全体、nで行数指定、gの有無で全てかどうか等、様々なオプションの組み合わせで置換する    |



##終わりに
上記にいくつかの操作をまとめましたが、全てを網羅できてはいません。
当たり前に使いすぎて気づいていないけど便利な操作などあれば教えていただきたいです。

##参考文献
この記事は以下の情報を参考にして執筆しました。
- [Linux標準教科書(ver.3.0.2)](https://linuc.org/textbooks/linux/)
残プロ　第-6回　~.csvをpythonで編集~

# 簡単な流れ

1.**pandas.read_csv**でcsvファイルを一括読み込み
2.**itertuples**メソッドによって得たイテレータをfor文で回し，一行ずつ解析
3.要素の更新には**at**または**iat**を利用し個別に操作(replace等を使えばまとめての更新が可能)
4.**to_csv**で書き込み


# サンプル.py

関数として実装すると下記のようになります．

~~~ python:
import pandas as pd

def csvEdit(path_csv):
	csv = pd.read_csv(path_csv)
	for row in csv.itertuples():
		csv.at[row[0], 'hoge'] = huga
	csv.to_csv(path_csv)
~~~

少しだけitertuplesについて説明します．rowに格納されるタプルですが，これには先頭にindex名，そしてその行のデータが格納されています．rowはただのコピーなので代入等の要素操作は元データであるcsvに行ってください．
また，csvファイルの形によってはiterrowsメソッドの使用の検討をおすすめします．インデックスを明記している場合や特別に扱う必要がある場合ですね．

# 実行例

先ほどの関数内にprintを加えて実行してみます．encoding, indexの指定もしておきます．

**実行前**
![sample_csv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578927/38f2459b-a3b6-6447-eef6-b91bd612a6b3.png)


~~~ python:sample.py
import pandas as pd

def csvEdit(path_csv):
    csv = pd.read_csv(path_csv, encoding='utf-8')
    for row in csv.itertuples():
        csv.at[row[0], 'weight'] -= 5
        print(row)
    csv.to_csv(path_csv, encoding='utf-8', index=False)

if __name__ == '__main__':
    _ = csvEdit("sample.csv")

~~~


~~~ terminal:terminal
Pandas(Index=0, name='marcello', height=183, weight=80, other=nan)
Pandas(Index=1, name='david', height=190, weight=80, other=9.0)
Pandas(Index=2, name='lilian', height=185, weight=79, other=nan)
Pandas(Index=3, name='paolo', height=179, weight=74, other=nan)
~~~


**実行後**
![edited_sample_csv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578927/b4c40a15-9a34-014c-3eeb-fd7e39089315.png)

全員5キロの減量に成功しました！


# 次回　第-7回では...

一行ごとのデータ数を増やします．deadlineに細かく時間まで設定できるようにしたり，習慣の場合は曜日指定ができるようにする予定です．
goenv を使うべきか gvm を使うべきか

調べるとすぐにわかると思うのですが、Go の環境管理（？）ツールとしては `goenv` と `gvm` の二つがメジャーでして、この二つの比較というのが誰もが通る道になると思います。ただ、総合的にみると `goenv` が使いやすいと個人的には思いますし、実際に使っている方も多い印象です。

## goenv

Goenv のメリットは他言語の *env ツールとインタフェイスが同じにできてある点です。なので他言語で慣れている方にとっては使い方がすぐに覚えられて、扱いやすいでしょう。あとは anyenv に組み込まれているのはこちらなので、anyenv を使う場合には無条件でこちらを使うことになると思います。

    goenv install 1.11.1
    goenv local 1.11.1

さらに、Homebrew でのインストールに対応しているので、MacOS ユーザとしては嬉しいところです。ただ、残念なことに `brew install goenv` しても、古いバージョンしか落ちてきません。😅

見たところ Goenv 自体はメンテを続けているものの、2018年12月のリリースを最後に beta リリースばかりが続いている状態です。古いバージョンでは Go 1.14.4 までしか扱うことができませんので、今日日使いものにならないでしょう。

Homebrew を使わないインストール方法も（もちろん）用意されていますので、MacOS であるかに関わらずこちらの方法でインストールすることをおすすめします。

[goenv/INSTALL.md at master · syndbg/goenv](https://github.com/syndbg/goenv/blob/master/INSTALL.md#installation)

もしくは、以下の記事で紹介されているように `--HEAD` フラグ付きで `brew install` することでも対応が可能です。（定期的なバージョンアップが必要なツールにはなるので、Homebrew でパッケージ管理するに越したことはないのかな、という気はしました。）

    brew uninstall goenv && brew install --HEAD goenv

[【解消済み】goenvで最新のgoのバージョンが表示されない問題 - ポンコツエンジニアのごじゃっぺ開発日記。](https://www.pnkts.net/2021/06/07/upgrade-goenv)

## gvm

GitHub のスター数で見ると断然 gvm の方が多いです。ただ goenv も十分多いですので、そこまで気にしなくて良いのかなという印象です。

*   gvm : 6.3k
*   goenv: 1k

使い方は goenv と比較すれば独特ですので、Usage を見ながら使うことになると思います。ただ、機能自体は一般的な **env ツールと変わらないので、使い方に困るレベルではないと思います。

    gvm install go1.4
    gvm use go1.4

インストール方法がこの bash スクリプトを実行することしか対応しておらず、これに関してはちょっと不親切かなと思いました。（profile をいじっているせいか、手持ちの PC の一つではインストールが失敗してしまいました…。）

    bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)

[https://github.com/moovweb/gvm#installing](https://github.com/moovweb/gvm#installing)

## 余談：各ツールの Go の最新リリースへの追従

リリースされたばかりのバージョンだったりすると、gvm であれ goenv であれば対応されていないことがあります。対応されるのを待つというのもいいのですが、プルリクエストを出せばしれっとマージしてもらえるので、早く使えるようになって欲しい場合には、過去のプルリクエストをもとに出してみるのをオススメします。

（さらに余談になってしまいますが）実際に過去のプルリクエストの変更を見てもらえるとわかるのですが、難易度のごくごく低いタスクになりますので、学生の方などで「OSS にコントリビュートしてみたい！」という方にもオススメです。
GraphViewで削除可能なノードをすべて消す方法

GraphViewの資料が少ない(QiitaでもGraphViewタグの記事が4つしかない）ので些細な事でもメモしておきます。

全てのノードを消す方法がないかな？と探したところ、
GraphView.cs内のCollectDeletableGraphElements()がちょうど良い感じだったので、移植＆一部修正して実装。

```cs:MyGraphView.csの一部
///全てのDeletableなElementを消すボタン押下コールバック
private void OnClickDeleteAllDeletableElements()
{
    var elements = new HashSet<GraphElement>();
    static bool DeletablePredicate(GraphElement e) => (e.capabilities & Capabilities.Deletable) == Capabilities.Deletable;

    CollectElements(graphElements, elements, DeletablePredicate);

    foreach (var graphElement in elements)
    {
        RemoveElement(graphElement);
    }
}
```
まとめてRootNode(非deletable)以外を消したいときに使えそうです。
Laravel user()とuserの違い　動的プロパティ　リレーションメソッド

#概要
他のテーブルとリレーションを結ぶuser( )などのリレーションメソッド。
user( )と使う場面と単にuserとして使う場面もある。
なんとなくで使っていたがここらでスッキリさせておくために、今回は
この２つの違いについて自分なりにまとめておく。

#リレーションメソッド

```User.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザーの全ポストの取得
     */
    public function posts()
    {
        return $this->hasMany('App\Post');
    }
}
```

[表題ではuserで書いたが書きにくかったのでpostで書いてます]

これはUserモデルとposts()という1対多のリレーションメソッドですね。

あるユーザーの持つPostを取得したいときは以下のようなコードになるでしょう。

`idが1のUserの全Postを取得`

```
$user = App\User::find(1);
$posts = $user->posts;
```

さてこの`$posts`に入っているのはなんでしょうか？
`posts()`で定義しているのに`$user->posts`と( )がついていません。

この`$posts`に入っているのは**Postモデルのインスタンスのコレクションです。**

 posts()の中身はこうでした。

```
return $this->hasMany('App\Post')
```

ですので`$this->hasMany('App\Post')`を返していることは確実です。

では、この`$this->hasMany('App\Post')`がコレクションを返しているのか？
そうではなくてこれはHasMany オブジェクトというものを返しています。

`$user->posts`ここで動的プロパティというものを呼び出しているんですね。

#動的プロパティ

プロパティってのは何かの性質、特徴を表すものですから。
それが動的ってことはなんらかの原因によって性質が変わるものってことでしょうか？

調べたところ
インスタンスのプロパティには attributes と呼ばれる各レコードのカラムの値の他に、relations というものもあって、その中身には定義したリレーションメソッド名を key、リレーションメソッドの制約に従って取得したリレーション先のモデルインスタンスのコレクションを value とした連想配列が入っているそうです。
ここのrelations 内の値は定義されたリレーションメソッドやリレーション先のテーブル内容によって動的に変わるので、**動的プロパティ**と呼ばれているということですね！なるほど！

#()がつくと？

先ほどの動的プロパティを使わずに有効な全 Post を取得するコードを書いてみましょう。

```
$user = App\User::find(1);
$posts = $user->posts()->where('active', 1)->get();
```

ここでは`posts()`としてからwhereで一致するものを探してからget()で取得しています。

こちらの$user->posts()の時点では、`return $this->hasMany('App\Post')`の結果の
 HasMany オブジェクトが返ってきています。

HasMany オブジェクトを考えるために、
HasMany の基底クラスである HasOneOrMany の実装を見てみましょう。

```
*略
public function create(array $attributes = [])
{
    return tap($this->related->newInstance($attributes), function ($instance) {
        $this->setForeignAttributesForCreate($instance);
        $instance->save();
    });
}
```


`$this->related`にPostモデルの仮のインスタンスが入っていて、`newInstance($attributes)`で意味のあるモデルインスタンスを生成しています。
そして`setForeignAttributesForCreate() `で外部キーがセットされてそのままそのモデルをsaveしているんですね。

なので今回の場合は$user->posts() で user_id が埋められた状態になっててそれをwhereで一致したものをget()しているということです。

#2つの違い

だったら記述の少ない動的プロパティだけで良いじゃんってことになりますが、HasMany オブジェクトなどの Eloquent リレーションオブジェクトはクエリビルダとしても動作するという大きな特徴があります。

クエリビルダは Laravel で SQL の記法を書きやすくするもので、where('active', 1)といった記法をメソッドチェーン的に繋げられます。
コレクションが返ってくる動的プロパティではそのまま繋げられないが、Eloquent リレーションオブジェクトであればそのまま繋げて制約を追加することが可能ということですね。

反対に、動的プロパティは「遅延ロード」されるという性質を持っています。
遅延ロードとは、アクセスされたときにだけリレーションのデータをロードするというもので、このため、あらかじめアクセスしておいて EagerLoadができるのです。


#まとめ

**1.posts()などの()がつくものはリレーションメソッド　postsは動的プロパティである。**
**2.動的プロパティpostsでUserモデルのコレクションが返ってきている。
**3.リレーションメソッドposts()の時点では結びつけているもの（今回だとuser_id--テーブル書くの省略していますが笑--）が返ってきてそれをクエリビルダでメソッドチェーン的につなげられる！。**

ということになるかと思います！

しかしこれ頻出すると思うのですが記事がかなり少ない。。。
慣れたら感覚で使いこなせるのかな？

何かありましたらコメントお願いします！
【Android】SplitInstallManagerのListenerで期待する動作がしなくて困った話(備忘録)

## 環境
- PC
    -  M1 MacBook Air
- Android Studio
    -  Arctic Fox 2020.3.1 Beta 3
-  Google Play Core Library
    - com.google.android.play:core-ktx:1.8.1

## 困ったこと
DFMを実装する際、 `SplitInstallStateUpdatedListener` の `REQUIRES_USER_CONFIRMATION` を通らないことがある

```sample.kt
    private val listener = SplitInstallStateUpdatedListener { state ->
        when (state.status()) {
            SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION -> {
                splitInstallManager.startConfirmationDialogForResult(state, this, DFM_REQUEST_CODE)
            }
            SplitInstallSessionStatus.DOWNLOADING -> {
                // do something
            }
            else -> {
                // do something
            }
    }
```

サンプルコード↓
https://github.com/sasakitomohiro/DFMSample

## 原因
`REQUIRES_USER_CONFIRMATION`はモジュールサイズが150MBを超える場合でないと通らないらしい？ことが原因っぽい
その他、wifi接続している状態かどうかや端末によって挙動が変わるらしい
https://issuetracker.google.com/issues/171501820
【kotlin】ListViewで2行表示 SimpleAdapter 

#■2行のListViewを作ります。

![スクリーンショット 2021-06-07 22.21.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558142/ed53ba05-da2c-ca08-1eba-5033e48cfb93.png)

activity_main.xmlにListViewを作った程

#1
■SimpleAdapterを使えば2行になる。
SimpleAdapterを使うには
MutableListの配列の中にMutableMapを入れた配列が必要
map型のキーはstringで値の型はなんでもいいです。

空のmap型が入るMutableListを作る。
データを後にこの中に入れていく。

``` kotlin
//MainActivity.kt
 val lvMenu = findByID<ListView>(R.id.lvMenu)
 //空の配列を用意
 val mnuList: MutableList<MutableMap<String,String>> = mutableListOf()
```

#2
Map型の配列を作り
mutableListに
mutableMapOf()の配列を入れていきます。

``` kotlin
 val lvMenu = findByID<ListView>(R.id.lvMenu)
 val menuList: MutableList<MutableMap<String,String>> = mutableListOf()
 
 //nameとpriceがキー ピカチュウと800円が値　ピカチュウが1行目に入る。
 var menu = mutableMapOf("name" to "ピカチュウ","price" to "800円")
 //空の配列menuListにmenuを追加する(add)。
 menuList.add(menu)
 //同じ事をする。
 menu = mutableMapOf("name" to "ヒトカゲ","price" to "850円")
 menuList.add(menu)
 //同じ事をする。
 menu = mutableMapOf("name" to "カメックス","price" to "12000円")
 menuList.add(menu)

//入ったイメージ menuList((name = ピカチュウ,price = 800円),(name = ヒトカゲ,price = 850円),(name = カメックス,price = 12000円))
```

#3
■SimpleAdapterのオブジェクトを作るのに5個の引数が必要！

```kotlin
SimpleAdapter(context:Context,data:MutableList<MutableMap<String,*>>,resource:Int,from: Array<String>,to:IntArray)
```

▼第1引数
context: Context
どの画面

▼第2引数
data:MutableList<MutableMap<String,*>>
リストのデータ

▼第3引数
resource:Int
リストビューのレイアウトを表すR値
例: android.R.layout.simple_lvMenu_item_2
これで2行になる。

■重要！！ 第4引数と第5引数

▼第4引数
from: Array<String>
リストデータのキーが入る配列を準備

arrayOf("name",""price)
順番的に
nameが第5引数のandroid.R.id.text1に入る
priceが第5引数のandroid.R.id.text2に入る

▼第5引数
to:IntArray
■ListViewの各行の画面部品のidのR値の配列
intArrayOf(android.R.id.text1,android.R.id.text2)を準備

android.R.id.text1がリストビューの1行目になるtext
android.R.id.text2がリストビューの2行目になるtext

▼第4引数と▼第5引数でリストデータの入る行を決めている。

``` kotlin
 val lvMenu = findByID<ListView>(R.id.lvMenu)
 val menuList: MutableList<MutableMap<String,String>> = mutableListOf()

 var menu = mutableMapOf("name" to "ピカチュウ","price" to "800円")
 menuList.add(menu)

 menu = mutableMapOf("name" to "ヒトカゲ","price" to "850円")
 menuList.add(menu)

 menu = mutableMapOf("name" to "カメックス","price" to "12000円")
 menuList.add(menu)

 //SimpleAdapterの第4引数に入ります。
 val from = arrayOf("name","price")
 //SimpleAdapterの第5引数に入ります。
 val to = intArrayOf(android.R.id.text1, android.R.id.text2)
 //リストビューにデータを表示させるadapterを作る。
 val adapter = SimpleAdapter(this@MainActivity,menuList,android.R.layout.sample_list_item_2,from,to)
 //lvMenuにadapterを入れる。
 lvMenu.adapter = adapter
```

これで最初のような画面ができます。
【Docker-compose】コンテナ起動時にport is already allocatedエラーが発生したときの対処方法

Laravelのwebアプリを作成するために、Docker-composeで環境構築してコンテナを起動したところMySQLの立ち上げでエラーが発生しました。
自分用の記録としてエラーの解消方法をメモします。

##開発環境
docker-compose version'3'
MySQL '5.7'

##やりたいこと
Docker-composeで環境構築してLaravelのアプリを作成したい。
ということで```docker-compose.yml```を以下の通り編集して、```docker-compose up```コマンドを叩いた。

```yml:
version: '3'
services:
  web:
    image: nginx:1.15.6
    ports:
      - '8000:80'
    depends_on:
      - app
    volumes:
      - ./docker/web/default.conf:/etc/nginx/conf.d/default.conf
      - .:/var/www/html
  app:
    build: ./docker/php
    volumes:
      - .:/var/www/html
    depends_on:
      - mysql
  mysql:
    platform: linux/x86_64
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: memo_app
      MYSQL_USER: user
      MYSQL_PASSWORD: password
      MYSQL_ROOT_PASSWORD: password
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
volumes:
  mysql-data:
```

##エラー内容
```
Bind for 0.0.0.0:3306 failed: port is already allocated
```
エラー文によると、3306番ポートが既に割り当てられているので、MySQLが起動できずエラーが発生してしまったらしい。
他のアプリでもDocker-composeとMySQLでアプリを作成していたので、そのコンテナが原因か。

##対処方法
まずは次のコマンドで現在起動中のコンテナを確認。

```:ターミナル
docker ps
```

起動中のコンテナの中から、3306番ポートを使用しているコンテナを停止する。

```:ターミナル
docker stop (対象のCONTAINER ID)
```
これで無事に```docker-compose up```できました！！
scrollHint スクロールのヒントが出るやつ

# scrollHint スクロールができることを表示する

今回はテーブルなどで横スクロールできることがわかるように、補助的なアニメーションを表示させる

今回はpugとstylusを使っています。
コンパイルが必要になるので、html、CSSがいいって人は下記サイトで変換してください

- pug
    - https://html2pug.vercel.app/
- stylus
    - https://www.cssportal.com/stylus-to-css/

## サクッとデモが見たい方

下記コードペンで、デモを作っているので参考にしてください
https://codepen.io/xhisashix/pen/RwpJZPWhttps://codepen.io/xhisashix/pen/RwpJZPW


## ディレクトリ構成

```bash
.
├── stylus
│   ├── scroll-hint.css
│   └── style.styl
├── index.pug
└── js
    └── scrollHint.js
```

## CDNの読み込み

```pug
script(src="https://unpkg.com/scroll-hint@latest/js/scroll-hint.min.js") // scrollHintのCDN
script(src="./js/scrollHint.js") // 下記のjs
````

## pug

```pug
.section
  .table.table_container
    table
      tr
        th タイトル
        th タイトル
        th タイトル
        th タイトル
        th タイトル
        th タイトル
        th タイトル
        th タイトル
        th タイトル
      tr
        td content
        td content
        td content
        td content
        td content
        td content
        td content
        td content
        td content
      tr
        td content
        td content
        td content
        td content
        td content
        td content
        td content
        td content
        td content
```

## stylus

```stylus
.section
  margin 0 auto
  max-width 980px
  width 90%
  background #ccc
  .table
    overflow-y scroll
    margin 0 auto
    width 600px
    table
      border 1px solid #ddd
      tr
        box-sizing border-box
        padding 15px 20px
        min-height 30px
        border-top 1px solid #ddd
        th, td
          box-sizing border-box
          padding 20px
          min-width 150px
          background #eee
        td
          background #fff
```

### 注意点

```html
<link rel="stylesheet" href="https://unpkg.com/scroll-hint@latest/css/scroll-hint.css">
```

上記のCSSを読み込むと実装できなかったので、下記よりCSSをダウンロードしています。
https://appleple.github.io/scroll-hint/


ディレクトリの構成のscroll-hint.cssが上記でダウンロードしてきたcssファイルになります。

## js

```js
new ScrollHint('.table_container', {
  suggestiveShadow: true,
  remainingTime: 5000,
  i18n: {
    scrollable: 'スクロールできます',
  },
});
```


## 最後に

そんなに使うことはないかもしれませんが、
テーブルの構造的にレスポンシブにするの難しいときとかに便利なので、使って見てください.


誰かの約に立てれば幸いです。
Azure予算とコストアラートを設定してみた

# コストアラートを設定してみた
<!-- 発端や概要を記載 -->
Azureは月・四半期・年単位で予算を設定して、予算を超えるとアラート通知してくれるお財布にやさしい機能があります。


# 設定
<!-- タイトルとアンカー名を編集 -->
1. AzurePortalにログイン-> https://portal.azure.com
1. リソースグループの左ペインから[***予算***]を選択。
1. [+追加]から予算を追加
![予算.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347341/552e2205-0f85-88e6-03cf-37cc62a38818.png)

- 名前：予算名を付けます。使える文字は半角英数字、アンダーバー、ハイフンです。
- リセット期間：どのタイミングでコスト総額を区切るか決めます。請求書が発行されたタイミングと期間をまたいだタイミング（月が替わった、年が変わった等）から月・四半期・年単位で選べます。
- 作成日：予算を適用する開始日を選択します。
- 有効期限：予算を適用する終了日を選択します。
- 金額：予算額を設定します。

4.[次へ]から通知の設定をします。
![予算通知.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347341/3c18c303-24b7-7f88-958a-3a3715f4afef.png)

- 警告条件：予算の何％超えたら通知がいくか設定します。アラートのタイミングは「予測」か「実測」から選べます。
- アラートの受信者：アラート通知先のメールアドレスを指定します。

5. [作成]を押して完了です。

#まとめ
今回は「月1500円の予算 かつ 予算の80%(1200円)を超えると予測したらアラート通知」が来るように設定しました。
実際にアラートが来るのは月のコスト予測が1200円になったタイミングなので、40円/日（30日後に1200円になる）のリソースを設定した段階で通知が来ます。
ここら辺は予測・実測と予算をうまく調節してもらえたらと思います。
KMSを用いて機密情報をプログラム実行時に復元する

センシティブなデータを暗号化してソースコードに埋め込む。

## 手順

暗号化文字列を作成する方法

```Python
import boto3
import base64

def main():
    key_id = 'マスターキーのARN'
    Plaintext = '暗号化対象の文字列'

    response = kms.encrypt(
        KeyId = key_id,
        Plaintext = Plaintext
    )['CiphertextBlob']

    Ciphertext = base64.b64encode(response).decode('utf-8')
    print('Ciphertext='+Ciphertext)

if __name__ == '__main__':
    main()
```
上記処理で得られたCiphertextはKMSのマスターキーによって暗号化されている。

プログラム中で使用する場合は以下のようになる

```Python
key_id = 'マスターキーのARN'
Ciphertext = '上記処理で得られた暗号化文字列'

response = kms_client.decrypt(
    CiphertextBlob=Ciphertext,
    KeyId=key_id
)

plaintext = response['Plaintext'].decode('utf-8')
```
KMSで暗号化しているため、仮にソースコードが流出したとしても、KMSのDecrypt API実行権限
がなければ機密情報が漏れる心配がなく安心ですね。

## おわりに
暗号化文字列の複合化にKMSの権限が必要なため、プログラムを実行するサービスに対して
忘れずにKMS実行権限を付与しましょう。
[基礎]Gitコマンドについてまとめてみた②

#はじめに

続きまとめていきます！
自分用なので、①を見たい方は[こちら](https://qiita.com/tochisuke221/items/286da98300bfa118f1c7)をご覧ください。

#ブランチ関連のコマンド
##ブランチを新規追加する

```:terminal
git branch ブランチ名
```

##ブランチの一覧

```:terminal
git branch

git branch -a
```

##ブランチの切り替え

```:terminal
git checkout 既存ブランチ

#ブランチを新規作成した上で切り替える
git branch -b ブランチ名
```

##変更履歴をマージする

```:terminal
git merge ブランチ名
git merge リモート名/ブランチ名　
```

##ブランチの変更・削除

```:terminal
git branch -m ブランチ名　#作業中のブランチ名の変更
git branch -d ブランチ　#削除
git branch -D ブランチ名　#強制終了
```

#リベース関連のコマンド
※リベースで気を付けないといけないのは、**Githubにpushしたコミットは絶対にリベースしてはいけません！！！親コミットが変わってしまい、プッシュできなくなります**
そして、プッシュできなくなったからといって、git push -f とするのも絶対にやめましょう！完全に履歴が壊れてしまいます


##リベースで履歴を整えた形にする
```:terminal
git rebase ブランチ
```

##プルのリベース型

```:terminal
git pull --rebase リモート名　ブランチ名
```
##複数のコミットをやり直す

```:terminal
git rebase -i コミットid
git rebase -i HEAD~3

# やり直したいcommitをeditにする
edit gh21f6d ヘッダー修正
pick 193054e ファイル追加
pick 84gha0d README修正

# やり直したら実行する
git commit --amend

# 次のコミットへ進む（リベース完了）
git rebase --continue
```

##コミットの並び替えや削除

```:terminal
git rebase -i HEAD~3

pick gh21f6d ヘッダー修正
pick 193054e ファイル追加 #消したら削除できる
pick 84gha0d README修正
```

##コミットをまとめる

```:terminal
git rebase -i HEAD~3

#コミットは1つにまとめる
pick gh21f6d ヘッダー修正
squash 193054e ファイル追加
squash 84gha0d README修正
```

##コミットの分割

```:terminal
git rebase -i HEAD~3

pick gh21f6d ヘッダー修正
pick 193054e ファイル追加
pick 41gha0d READMEとindex修正

# コミットを分割する
pick gh21f6d ヘッダー修正
pick 193054e ファイル追加
edit 84gha0d READMEとindex修正

git reset HEAD^
git add README
git commit -m 'README修正'
git add index.html
git commit -m 'index.html修正'
git rebase --continue
```

#タグ付コマンド
##タグ一覧

```:terminal
git tag
```

##タグの作成（注釈付タグ）

```:terminal
git tag -a タグ名　-m メッセージ
```

##タグの作成（軽量なもの）

```:terminal
git tag タグ名
```

##タグのデータ表示

```:terminal
git show タグ名
```

##タグをリモートリポジトリに送信する

```:terminal
git push リモート名　タグ名

#一斉にタグを送信
git push origin --tags
```

#スタッシュのコマンド

##作業の一時避難

```:terminal
git stash
git stash save
```

##避難した作業の確認

```:terminal
git stash list
```

##避難した作業の復元

```:terminal
#最初の作業を復元
git stash apply
```
#ステージの状況も復元

```:terminal
git stash apply --index
```

#特定の作業を復元する

```:terminal
git stash apply スタッシュ名
git stash stash@{1}
```

##避難した作業を削除する

```:terminal
#最新の作業を削除する
git stash drop

#特定の作業を削除する
git stash drop スタッシュ名
git stash drop stash@{1}

#全作業を削除する
git drop clear
```

#おわりに

基本的なコマンドを抑えました。
もっと勉強して開発にスムーズに入れるように準備します
HHKBに入門しようと説明書通りにペアリングしようとしたらMacで検出できなかった話

## はじめに
 初めて出たボーナス（寸志）で仕事環境を向上させようとPFUの「HHKB Professional HYBRID Type-S（英字）」を購入し早速利用しようと思い取扱説明書通りにペアリングをしようとしたらキーボードが検出されず１時間ぐらい格闘してしまったので他の人が同じミスをしないためにも記しておきます．

##環境
Macbook pro 13inch
macOS BigSur(14.1)
Happy Hacking Keyboardファームウェア　A0.46

## 発生した問題
取扱説明書通りに以下の手順で行ってもペアリングができない！！！　　

説明書では
Macのシステム環境設定　＞　キーボード ＞　Bluetoothキーボードを設定
から設定しろと言われるが，**ずっとキーボード検出中**となり，HHKBをに検出しない．

Bluetooth設定からは`HHKB-Hybrid_n(nは1~4の数値で初期設定なら１）`が検出されており，Bluetooothが飛んでいないや，Mac側で　HHKBのBluetoothをつかんでいないわけではない．

ググってHHKBのBluetooth登録の初期化やMacの再起動を試すも効果なし．
（せっかくのボーナスで購入したお高いキーボードなのに使えないだって(´；ω；`)ｳｯ）

## 解決方法
解決方法はめちゃくちゃシンプルです．
~~Typoe-Cの有線で繋げば使えるようになります！！！！~~
と言う冗談は置いておいて，**システム環境設定　＞　Bluetooth　**からHHKB-Hybrid_n(nは1~4の数値で初期設定なら１）`を追加することで無事接続することができました．

お手元に取扱説明書があるな，iOS / iPadOSに書いてある手順で解決します．

説明書が手元にない方のために手順を書いておきます．(Mac用に一部手順の名前を変更しています）


1. システム環境設定　＞　Bluetooth
1. デバイスの欄にHHKB-Hybrid_n(nは1~4の数値で初期設定なら１）が表示されていることをを確認する（表示されていない場合，Mac側のBluetoothがonになっているか，HHKB側のインジケーターの点滅がペアリングモード（青色点滅１秒に4回）となっているかを確認する）
1. HHKB-Hybrid_n(nは1~4の数値で初期設定なら１）をダブルクリックで接続する
1. 表示されている***ペアリング用の数字をHHKBで入力***し`Returnキー`を押す（日本語配列なら`Enterキー`）
1. 接続済みと表示されているのを確認し，またHHKBのインジケーターが消灯したのを確認する
1. 接続完了

## まとめ
なかなかHHKBの説明書通りにやったのに検出できない！！！とパニックになる人は少ないと思いますが，もしも検出できず接続できないとこまっている方の助けになれば幸いです．
DAPLinkをGCCでお手軽にビルドする

Mbed OS対応デバイスやmicro:bit等でターゲットマイコンに書き込むための仕組みとして、DAPLinkが使われています。

DAPLinkは、インターフェスとして使用するArmマイコン上で動作し、オープンソースプロジェクトして公開されていますが、ビルドツールとしては有償ライセンスが必要なKeil MDKが必要でした。

最近、DAPLinkのGitHubリポジトリに作成された`experimental_compilers`ブランチを使用することでGCCでビルドが可能になりましたので、試してみました。

Experimental branch for GCC build  
https://github.com/ARMmbed/DAPLink/tree/experimental_compilers

この記事ではLPC1114FN28用のDAPLinkをビルドする手順を紹介します。

## ビルド手順

### ビルドツール

* ホストOS macOS Big Sur 11.4
* cmake 3.20.3
* ninja 1.10.2
* python 3.9.5
* arm-none-eabi-gcc (GNU Tools for Arm Embedded Processors 9-2019-q4-major) 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599]

### venvのインストールと起動
```
$ python3 -m venv .venv3
$ source .venv3/bin/activate
```

### DAPLinkのビルド
```
# リポジトリのクローン
$ git clone -b experimental_compilers https://github.com/ARMmbed/DAPLink daplink-gcc
$ cd daplink-gcc

# 必要なモジュールのインストール
$ pip3 install -r requirements.txt

# ビルド
$ python3 tools/progen_compile.py -t make_gcc_arm lpc11u35_ssci1114_if
```

### ビルド時のログの例
```
(.venv3) 22:37@daplink-gcc > python3 tools/progen_compile.py -t make_gcc_arm lpc11u35_ssci1114_if
Preprocessing ../../../source/hic_hal/nxp/lpc11u35/gcc/lpc11u35.ld
Compiling ../../../source/board/ssci1114.c
Compiling ../../../source/daplink/HardFault_Handler.c
Compiling ../../../source/daplink/circ_buf.c
Compiling ../../../source/daplink/cmsis-dap/DAP.c
Compiling ../../../source/daplink/cmsis-dap/DAP_queue.c

（中略）

Compiling ../../../source/usb/winusb/usbd_core_winusb.c
Assembling ../../../source/hic_hal/nxp/lpc11u35/gcc/startup_LPC11Uxx.S
Assembling ../../../source/rtos2/RTX/Source/GCC/irq_cm0.S
Linking build/lpc11u35_ssci1114_if.elf
Memory region         Used Size  Region Size  %age Used
    m_interrupts:          1 KB         1 KB    100.00%
          m_text:       53336 B        59 KB     88.28%
        m_cfgrom:           9 B         4 KB      0.22%
          m_data:        7856 B       7904 B     99.39%
        m_cfgram:         142 B        256 B     55.47%
        m_data_2:          2 KB         2 KB    100.00%
       m_usb_ram:          40 B         2 KB      1.95%
   text	   data	    bss	    dec	    hex	filename
  54352	   1308	   8791	  64451	   fbc3	build/lpc11u35_ssci1114_if.elf
  54352	   1308	   8791	  64451	   fbc3	(TOTALS)
Converting build/lpc11u35_ssci1114_if.hex
Converting build/lpc11u35_ssci1114_if.bin
build/lpc11u35_ssci1114_if_crc
board_id None
family_id None
bin_offset None
Start 0x0, Length 0xd96c, CRC32 0x63d8970e
```

### ビルドしたバイナリの確認

```
$ ls projectfiles/make_gcc_arm/lpc11u35_ssci1114_if/build/*.bin
projectfiles/make_gcc_arm/lpc11u35_ssci1114_if/build/lpc11u35_ssci1114_if.bin
projectfiles/make_gcc_arm/lpc11u35_ssci1114_if/build/lpc11u35_ssci1114_if_crc.bin
```

`lpc11u35_ssci1114_if_crc.bin`がチェックサム付きのバイナリなので、それをインターフェスチップに書き込みます。書き込み方法は、以下を参考にしてください。  
https://os.mbed.com/teams/Switch-Science/wiki/Firmware-LPC1114FN28

## DAPLinkの今後
公式リポジトリの`Discussions`に`The road to DAPLink 0256 (and beyond) `という記事が公開されています。
https://github.com/ARMmbed/DAPLink/discussions/819

今後の予定などが記載されているので、興味のある方はご覧ください。

以上です。
PySide2　Pyinstallerでのエラー

環境　Winndows10　Pro
　　　Python3.8

PySide２で簡単なツールを作ってから、PyInstallerでexeファイルに変換後にはまった事をメモ。
exeファイルを作成したまでは良かったが、なぜか、distディレクトリにPyside2のフォルダーが生成されないので、気になりながら
exeファイルを実行したら以下のエラーが発生。

````
Failed execute.script dir_maker
```
pip　listを実行したらインストールしたはずのPySide2がない。

pip3 listを実行したらインストールされていた。

VS Codeでは、
form PySide2の部分が波線が引かれているのが気になり、調べてみた。
[Visual Studio Codeの設定「虎の巻」：Python編](https://www.atmarkit.co.jp/ait/articles/1711/24/news034.html)

の記事を読んでVsCodeの環境にも問題があるのではと思い、この記事を参考にして環境を設定。
VsCodeでは波線が消えた。
再度、Pyinstallerを実行したら
distフォルダにPySide2のディレクトリも生成され、exeファイルが正常に実行された。
VsCodeでPython3.8の環境に設定していないので、PySide2なんて知らないよとなっていたようです。
JavaのExceptionの中に特定のExceptionが含まれるか再帰的に調べるプログラミング

javaの例外（Exception）の中に特定の例外（Exception）が含まれているか、再帰的に調べるコードです。

containsExceptionメソッドの第一引数に特定の例外の型、第二引数に例外（Exception）を指定して呼び出し、特定の例外が含まれている場合trueを返し、含まれていない場合falseを返します。

第二引数がnullの場合、falseを返します。
第二引数がnullではなく、型が第一引数と同じ型の場合、trueを返します。
上記以外の場合、例外の中の例外（cause.getCause()）を引数に自分自信を呼び出します。（再帰呼び出し）


```java:Utility.java
package test;

public class Utility {

	public static boolean containsException(Class<?> clazz, Throwable cause) {
		if (cause == null) {
			// 例外（cause）がnullの場合、falseを返す
			return false;
		} else if (clazz.isInstance(cause)) {
			// 例外（cause）の型が引数のclazzの場合、trueを返す
			return true;
		} else {
			// 上記以外の場合、例外（cause）の中に含まれる例外（cause.getCause()）を引数に自分自身を呼び出す
			return containsException(clazz, cause.getCause());
		}
	}
}
```

　
　
以下は上記のcontainsExceptionメソッドを呼び出すMain関数の例です。

e3（Exception）は、e3（Exception）中にe2（IOException）が入っており、e2（IOException）の中にe1（SQLException）が入っている例外です。
第一引数のSQLException.class、第二引数にe3を指定して、containsExceptionメソッドを呼び出して、e3の中にSQLExceptionが含まれるか調べます。
含まれる場合true、含まれない場合falseが表示されます。

```java:Main.java
package test;

import java.io.IOException;
import java.sql.SQLException;

public class Main {

	public static void main(String[] args) {

		Exception e1 = new SQLException("message e1");
		Exception e2 = new IOException("message e2", e1);
		Exception e3 = new Exception("message e3", e2);
		
		boolean result = Utility.containsException(SQLException.class, e3);
	
		System.out.println("result=" + result);
	}

}
```

```:結果
result=true

```
 
 
---
以上
UE キャラクターの移動方向を向くカメラの作成

# はじめに
よくあるTPS視点RPGのプレイヤーキャラクターを移動させると進行方向を自動で向いてくれる実装のメモです。

## 実装環境
UE5 EarlyAccess (UE5の機能は使いません)
ThirdPersonTemplateを使用

## 実現したいもの
1. 左スティックでキャラクターが移動する。
2. カメラも進行方向を映すように自動で回転する。

## ThirdPersonTemplateの状態
ThirdPersonTemplateの実装では、左スティックでキャラクターは移動しますがカメラは回転せずに付いてきます。
進行方向を見るためには、左スティックで移動操作をしながら右スティックorマウスでカメラを操作する必要があります。
この操作を左スティック一つで行えるようにしていきましょう。

# 実装方法の検討
### 通常のスティック操作によるカメラ回転
+ 通常、進行方向を向く挙動をするには左スティックで移動しながら右スティックでカメラを回転させます。
+ 左スティックで真正面に進む場合は回転させません。左右への移動量がある場合にカメラを回転させています。
+ 左スティックの水平成分をカメラの回転に割り当てることで、左スティック一つでキャラクターの移動と進行方向を向くカメラの挙動が実装できそうです。

### 自動カメラ回転の計算方法
+ 計算しやすくするため垂直時にはカメラの回転量を0とし、左右の時には1となるような計算式を考えます。
+ 進行方向のベクトルとカメラの右方向ベクトルと**内積**を取ることで、垂直時には0、平行時には1（-1)の結果が取得できます。
+ これにカメラの回転速度をかけることで左スティックだけで移動とカメラの回転が実現できそうです。

# 実装手順
ThirdPersonCharacterのブループリントには既にキャラクターの移動に関するノードが組まれています。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157391/05f24fc2-7bb3-2a12-dc7b-39faa3b897cf.png)


まず進行方向をそれぞれベクターの変数にセットします。
![image (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157391/2c74e6b6-005b-86c4-9e0d-106ee9cec324.png)

Tickイベントを実装しベクターを足し合わせ進行方向のベクトルを求めます。
AddMovementInputでキャラクターの移動を行った後、進行方向ベクトルとカメラの右ベクトルから内積を計算しカメラの回転量を求めます。
求めた回転量をAddControllerYawInputにわたすことで、進行方向を向くようにカメラが回転してくれます。

完成したノード。関数にまとめました。
![image (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157391/d7718f98-27d8-b43e-55e3-1be74bd475c1.png)

![image (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157391/8310bde0-5118-e674-f7b3-ddcf2cade781.png)

MapRangedClampを使用しているのは、左スティックの水平成分が一定値を超えた場合にカメラが回転しはじめるようにするためです。

### 完成したもの
![Animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157391/82dd5924-5010-331d-3dc6-d538c4fda869.gif)

# おわりに
色々ゲームの移動挙動を観察すると、進行方向にカメラが回転し始めるのがしばらく移動してからだったり、歩いてる時と走っている時で回転速度が違ったり、TPS視点でもアクションゲームでは回転補正がなかったり、似たようなゲームでもそれぞれ挙動が異なっていて何を考えてこの挙動を仕様にしたのか考えるのも面白かったです。
[Unity] 画面キャプチャをドライブにアップロードする

# 概要
Unityエディタ上で画面をキャプチャして、それをファイル出力せずドライブにアップロードする
# 経緯
UI実装してデザイナーに確認する度にキャプチャをとることが増え、多少なりとも自動化できないかと思い至った
# 実装
GASでウェブアプリ作ってそれを叩くだけ

```javascript
function doPost(e) {
  var json = JSON.parse(e.postData.contents);

  var folder = DriveApp.getFolderById(json.folderId);
  var blob = Utilities.newBlob(json.data, json.mime, json.fileName);
  folder.createFile(blob);

  var text = "upload succeeded";
  var output = ContentService.createTextOutput(text);
  output.setMimeType(ContentService.MimeType.TEXT);
  return output;
}
```

```c#
IEnumerator Co(string gasId, string folderId, Action<string> callback)
{
    yield return new WaitForEndOfFrame();

    var texture = ScreenCapture.CaptureScreenshotAsTexture();

    var data = new PostData
    {
        folderId = folderId,
        fileName = DateTime.Now.ToString("yyyy/MM/dd/HH:mm:ss") + ".png",
        mime = "image/png",
        data = texture.EncodeToPNG(),
    };

    var request = new UnityWebRequest(
        $"https://script.google.com/macros/s/{gasId}/exec",
        UnityWebRequest.kHttpVerbPOST,
        new DownloadHandlerBuffer(),
        new UploadHandlerRaw(Encoding.UTF8.GetBytes(JsonUtility.ToJson(data)))
    );

    yield return request.SendWebRequest();

    try
    {
        callback(request.downloadHandler.text);
    }
    catch (Exception e)
    {
        Debug.LogError(e);
    }
}
```

~~何番煎じか分からないが~~とりあえず備忘録的な感じで
加えて細かい設定ができるようにエディタウィンドウ実装したり、フック作って通知したり