OmniAICreator/Qiita-1.07M huggingface dataset:
Linuxのnlコマンドに相当するコードをPythonで実装してみた

Linuxの[nlコマンド](https://atmarkit.itmedia.co.jp/ait/articles/1703/30/news024.html)に相当するコードをPythonで実装してみました。

```test.txt
AAA
BBB
CCC
```

```nl.py
import sys
if len(sys.argv) > 1:
    try:
        f = open(sys.argv[1], 'r')
    except FileNotFoundError:
        print('Error: File {0} is not found.'.format(
            sys.argv[1]), file=sys.stderr)
        sys.exit(1)
else:
    f = sys.stdin

lines = f.readlines()
f.close()

i = 1
for line in lines:
    if line == '\n':
        print()
        continue
    print('\t' + str(i) + ' ' + line, end='')
    i += 1
```

出力結果

```
$ python nl.py test.txt
    1  AAA
    2  BBB
    3  CCC
```
Tikzでエラー

# はじめに
2本の直線の交点をTikzパッケージを使って求めようとしたところ、エラーが出ました。

# エラーメッセージ
```
Package pgf: No shape named `intersection-1' is known
```

# 原因
一方の直線のdomain(定義域)が間違っており、交点が存在しませんでした。
S3にオブジェクトをアップロードして引数をlambdaに送りたいとき

今まではS3をトリガーにLambdaを発火させていたのですが、これだと追加の変数を設定することができず、どうすればいいか悩んでいたときに、InvokeInputに渡せばいいことを知りました。

## 参考

https://qiita.com/yukpiz/items/269277a97053237a6980

## go server側

S3にアップロードしたあとに、invokeして変数を渡すようにしました。

```main.go
package main

import (
	"encoding/json"
	"fmt"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/lambda"
)

// これはLambda関数の完了で返すための構造体定義
type Response struct {
	Message string `json:"message"`
	Ok      bool   `json:"ok"`
}

// 別のLambdaに渡すための構造体定義
type Event struct {
	Records []Record `json:"Records"`
}

type Record struct {
	S3    S3    `json:"s3"`
	Input Input `json:"input"`
}

type Input struct {
	OriginLocation      string `json:"originLocation"`
	DestinationLocation string `json:"destinationLocation"`
	FrameID             string `json:"frameNumber"`
}

type S3 struct {
	Bucket Bucket `json:"bucket"`
	Object Object `json:"object"`
}

type Bucket struct {
	Name string `json:"name"`
}

type Object struct {
	Key string `json:"key"`
}

func Handler() (Response, error) {
	fmt.Println("handler")
	// 呼び出したLambdaに渡すデータ
	payload := Event{
		[]Record{
			{
				S3{
					Bucket{
						Name: "uploaded-photos",
					},
					Object{
						Key: "xxxxxx.jpg",
					},
				},
				Input{
					OriginLocation:      "HND",
					DestinationLocation: "TPE",
					FrameID:             "frame",
				},
			},
		},
	}
	jsonBytes, _ := json.Marshal(payload)

	// このlambdaはaws/aws-lambda-go/lambdaではなく、
	// aws/aws-sdk-go-aws/service/lambdaなので注意
	svc := lambda.New(session.New(&aws.Config{
		Region: aws.String("ap-northeast-1")}))

	input := &lambda.InvokeInput{
		FunctionName:   aws.String("arn:aws:lambda:ap-northeast-1:xxxxxx:function:CreateThumbnail"),
		Payload:        jsonBytes,
		InvocationType: aws.String("Event"),
	}

	_, _ = svc.Invoke(input)

	return Response{
		Message: "success",
		Ok:      true,
	}, nil
}

func main() {
	fmt.Println("start")
	Handler()
}

```

## lambda側

Lambda側ではrecordの中の引数を受け取るようにしました。

```lambda_function.py
def lambda_handler(event, context):
    for record in event['Records']:
        bucket = record['s3']['bucket']['name']
        key = unquote_plus(record['s3']['object']['key'])

        selectedImageID = record['input']['frameID']
        originLocation = record['input']['originLocation']
        destinationLocation = record['input']['destinationLocation']
```
Swift バイナリツリー③


バイナリツリー③
---

最小値、最大値を返す。

```swift

public func minimum() -> BinarySearchTree {
    var node = self
//変数nexｔにnodeの左ノードガ存在する限り回していく。
    while let next = node.left {
      node = next//nodeを更新していく
    }
    return node//nodeを返す
  }
//バイナリツリーは左が一番小さいから発見できる

//同様に右ノードが存在する限りwhileで回していく。
  public func maximum() -> BinarySearchTree {
    var node = self
    while let next = node.right {
      node = next
    }
    return node
  }
//バイナリツリーは右側の端っこにある最大ノードが存在する



```
AWSのパスワードポリシー設定方法

[zenn](https://zenn.dev/mo_ri_regen/articles/aws-password-policy)にも同様の記事を書いています。更新頻度はzennのほうが多めです👋

コンソールにログインするためのカスタムパスワードポリシーの設定を行おうと思います。
IAMからカスタムパスワードポリシーの設定ができます。

ちなみにデフォルトでは下記のようなパスワードポリシーになっています。

> パスワードの文字数制限: 8～128 文字
> 大文字、小文字、数字、! @ # $ % ^ & * ( ) _ + - = [ ] { } | ' 記号のうち、最低 3 つの文字タイプの組み合わせ
> AWS アカウント名または E メールアドレスと同じでないこと

## コンソールで設定

1. [コンソール](https://console.aws.amazon.com/iam/)にサインインして、左ペインのダッシュボードにアカウント設定があるのでそれをクリックします。

    <img src="https://gyazo.com/297afde3165f74acd3bcc4bf5384d4e5.png" alt = "アカウント設定をクリック" width="30%">
2. 「パスワードポリシーを変更する」ボタンをクリックします。

    ![「パスワードポリシーを変更する」ボタンをクリック](https://gyazo.com/0a5af55a6219c587a9b7cee0247ba5a7.png)

3. 内容を読んで設定すれば完了 🎉

   ![パスワードポリシーの設定](https://gyazo.com/e6da9f2835b5fbfc4ad1fc1fd63ffa78.png)

## CLI で設定

CLI は[こちら](https://aws.amazon.com/jp/cli/)からダウンロードできます。
下記コマンドでパスワード設定できるようです。(動作未確認)

```bash
# カスタムパスワードポリシーの作成またはカスタムパスワードポリシーの変更
aws iam update-account-password-policy
# パスワードポリシーの表示
aws iam get-account-password-policy
# カスタムパスワードポリシーの削除
aws iam delete-account-password-policy
```

## 参考

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html
【Ruby on Rails】非同期コメント投稿時のRoutingError (No route matches [PATCH]....)を解消した話


#対象者

* コメント投稿時に[PATCH]を呼び出すエラーに遭遇している方


#目的

* ルーティングエラーを解消して、正常に稼働させる

#実際の手順と実例
###1.前提

* コメント機能を非同期で実装
* 投稿時、ターミナルに下記のエラーが現れる

![スクリーンショット 2021-08-27 20.30.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681213/a4a9cf6d-9721-c5f8-b3bc-37b2648678a1.png)

`````
ActionController::RoutingError (No route matches [PATCH] "/articles/19/comments/72"):
````

よく見ると投稿を押した段階でPATCHが呼び出されている、、、、
→本当はPOSTがほしい

* **rails route**コマンドで確認してもPOSTはあるし、PATCHはない
* 以下CommentsController

````comments_controller.rb
class Public::CommentsController < ApplicationController

  def create
    @article = Article.find(params[:article_id])
    @comments = @article.comments
    @comment = current_user.comments.new(comment_params)
    @comment_new = Comment.new
    @comment.article_id = @article.id
    @comment.save
  end
:
:
:
  def comment_params
    params.require(:comment).permit(:comment_content, :article_id, :user_id, :rate)
  end

end

```
###2.結論（解決策）

**saveメソッドの後に @comment = Comment.newを挿入**

以下追記版です

````comments_controller.rb
class Public::CommentsController < ApplicationController

  def create
    @article = Article.find(params[:article_id])
    @comments = @article.comments
    @comment = current_user.comments.new(comment_params)
    @comment_new = Comment.new
    @comment.article_id = @article.id
    if @comment.save
      @comment = Comment.new #追記
    else
      redirect_to request.referer #非同期できなかった場合、リダイレクトされる
    end
  end
````


###3.原因

Viewのform_withの部分で

```comment.show.html.erb
 <%= form_with(model: [@article, @comment], remote: true) do |f| %>
```

@commentがすでに保存済みのためupdateを呼び出していました。

@commentは新規の投稿なんだよー
と教えて上げるために、
save後にnewメソッドを改めて定義しました。


####投稿者コメント
最初は意味がわからん！と思っていましたが、
冷静に順を追って考えて記事を探して解決に至りました。
解決のお役に立てたら嬉しいです。


####My Profile
プログラミング学習歴３ヶ月目のアカウントです！
プログラミングスクールで学んだ内容や自分が躓いた箇所等のアウトプットの為に発信しています。
また、プログラミング初学者の方にわかりやすく、簡潔にまとめて情報共有できればと考えています。
もし、投稿した記事の中に誤り等ございましたら、コメント欄でご教授いただけると幸いです。
Qiita Daily Survey memo 2021.08.28

# Qiita Daily Survey memo 2021.08.28
Qiita の記事を可能な限り毎日読むために、読んだmemoを公開することでモチベーションを維持しようという試み。

# [【React / Laravel / AWS Lambda】ポートフォリオ (カンバン方式のタスク管理アプリ) を作成しました。](https://qiita.com/zuka-e/items/9a985f0dd5db21bc48d7)
zuka-e さんの記事。アイコンかわいい。
タイトルの通り、カンバン方式のタスク管理アプリを作成され、その知見を共有してくださっている記事になります。
印象的なのは、機能や環境、画面など、すごくきっちり書いてくださっているところで、アプリの全体イメージがすごくつかみやすかったです。

自分用にメモを抜き出すと…
MySQL Workbench で MySQL の ER図 をエクスポートしてくれる機能はぜひぜひ使いたいので、試してみたいと感じました。
また、日時を指定するUIがとても使いやすそうなため、参考にさせていただきたいなーと思いました。

[トップデベロッパーになるために作成したいアプリ8選](https://qiita.com/baby-degu/items/f905c8ee972cf46ce11b) や [フロントエンドのコーディング課題６選-このフロントエンドの課題、実装できますか？](https://qiita.com/baby-degu/items/d68e52a0727248ba2750) でも紹介されている通り、trello clone はぜひぜひチャレンジしたい課題の一つです。
すごくいい感じに実装されていて、すごいなーと思いました…！！


# [マネージャー・リーダーの私にとって有益な知見が得られた書籍](https://qiita.com/kazuo_reve/items/6976029e72763ea73245)
柏原 一雄(kazuo_reve) さんの記事。
マネージャー・リーダーをされているうえで、有益な知見を、どの書籍から得たかの情報と一緒に共有してくださっている記事です。
とてもとても参考になる内容ばかりで、参考になるところを紙に書き出そうとしたら、上からほとんど全部書き出して模写見たくなってしまいました…。
なかでも特に…となると、 DoCAP と 鎖 の例えはぜひぜひ覚えておきたいと思います。
詳しい内容は、元記事をご参照くださいー！

紹介いただいている本の中で、特に惹かれたのは『測りすぎ――なぜパフォーマンス評価は失敗するのか?』です。
タイトルが面白いのもありますが、データ収集・ログ取りと、その可視化・分析・評価は絶対にするべきと考えていましたが、はたしてコストに見合っているのか…？と言われると、目をそらしたくなります。
rails consoleで例外発生時のエラーメッセージが文字化けする場合の対処方法

## 発生する問題
rails consoleで例外が発生し、そのエラーメッセージに日本語が含まれていた場合、"\xE3\x83\x90\xE3..."みたいな形で日本語が文字化けする。

たとえば以下は本来であれば「バリデーションに失敗しました: Eメールを入力してください」というエラーメッセージを表示すべき場合に文字化けする例である。

```
> User.create!
/(railsのパス)/validations.rb:80:in `raise_validation_error': \xE3\x83\x90\xE3...(省略) (ActiveRecord::RecordInvalid)
```

## 原因

rails consoleで使われているirbのバージョンが1.3.5以下だとこの問題が発生する。

rails consoleで使用されているirbのバージョンを確認する場合は、rails console上で`irb_info`と入力する。

```
> irb_info
=> 
Ruby version: 3.0.0
IRB version: irb 1.3.0 (2020-12-25)
InputMethod: ReidlineInputMethod with Reline 0.2.0
```

## 対処方法

Gemfileに`irb`を追加して、`bundle install`を実行する。（なぜ追加したのか、コメントを残しておくと良い）

```rb:Gemfile
# rails consoleの文字化けを解消する
gem 'irb', '>= 1.3.6'
```

rails consoleを起動し、irbのバージョンが1.3.6以上になっていることを確認する。

```
> irb_info
=> 
Ruby version: 3.0.0
IRB version: irb 1.3.7 (2021-08-12)
InputMethod: ReidlineInputMethod with Reline 0.2.7
RUBY_PLATFORM: arm64-darwin20
```

これで例外メッセージが文字化けせずに表示されるはず。

```
> User.create!
/(railsのパス)/validations.rb:80:in `raise_validation_error': バリデーションに失敗しました: Eメールを入力してください (ActiveRecord::RecordInvalid)
```
[シリーズ 全3回] Jenkins の実行済み全ジョブのコンソールログを取得する


# 概要

次のようなジョブ定義の構造になっている場合に、

```
job
|-- A
    |-- ジョブ1
    |-- ジョブ2
    |-- ジョブ3
```

「**ジョブ1**」の実行済みの全ジョブのコンソールログを PlainText 形式で取得するまでの手順を記している.

|コンテンツ|一言|
|:--|:--|
|[[01] Jenkins API を使って全ジョブの URL を取得する](https://qiita.com/robozushi10/items/e40b76ace457ae894151)|Jenkins API操作|
|[[02] Jenkins API を使って実行済みジョブのジョブ番号を取得する](https://qiita.com/robozushi10/items/53b0bf8aceb8f7a4e11f)|Jenkins API操作|
|[[03] Jenkins の実行済み全ジョブのコンソールログを PlainText で取得する](https://qiita.com/robozushi10/items/62f31ec80a7cdef405f4)|Jenkins API操作|


以上
[03] Jenkins の実行済み全ジョブのコンソールログを PlainText で取得する


|シリーズトップページ|
|:--|
|[[シリーズ 全3回] Jenkins の実行済み全ジョブのコンソールログを取得する](https://qiita.com/robozushi10/items/9750017484313808975b)|

# 概要

次のようなジョブ定義の構造になっている場合に、

```
job
|-- A
    |-- ジョブ1
    |-- ジョブ2
    |-- ジョブ3
```

「 **ジョブ1**」の実行済みの全ジョブのコンソールログを PlainText 形式で取得する方法.

# コード

実行済みジョブの番号を取得する処理の詳細については、「[02](https://qiita.com/robozushi10/items/53b0bf8aceb8f7a4e11f)」を参照すること.

```bash
#!/bin/bash

# 「ジョブ1」の実行済み全ジョブの番号を取得する
Ns=`curl -X GET --user '<ユーザ名>:<APIキー>' "http://<IP>:<PORT>/job/A/api/json?tree=allBuilds[number]&depth=1" | jq -r '.allBuilds[].number'`

# 実行済み全ジョブのコンソールログを PlainText で取得する
for N in $Ns
do
  # ジョブ番号ごとにログ置き場を作る
  mkdir -p LOG/$N
  # ログをダウンロードする
  curl -X GET --user '<ユーザ名>:<APIキー>' "http://<IP>:<PORT>/job/A/jobs/ジョブ1/${N}/consoleText" > LOG/$N/consoleText
done

```

以上
[02] Jenkins API を使って実行済みジョブのジョブ番号を取得する

|シリーズトップページ|
|:--|
|[[シリーズ 全3回] Jenkins の実行済み全ジョブのコンソールログを取得する](https://qiita.com/robozushi10/items/9750017484313808975b)|


# 概要

次のようなジョブ定義の構造になっている場合に、

```
job
|-- A
    |-- ジョブ1
    |-- ジョブ2
    |-- ジョブ3
```

「 **ジョブ1**」の実行済みの全ジョブ番号を取得する方法


# 実行例

`api/json` のみだと直近 100件の情報しか取得できなかった.

そこで、`api/json` の直後に `?tree=allBuilds[number]` を付与してやると、
全件のジョブ番号が取得できた.

なお、ジョブの URL を動的に得たい場合は、「[01](https://qiita.com/robozushi10/items/9750017484313808975b)」を参照すること.

```bash
$ curl -X GET --user '<ユーザ名>:<APIキー>' \
  "http://<IP>:<PORT>/job/A/api/json?tree=allBuilds[number]&depth=1" | \
   jq -r '.allBuilds[].number'
```

# 参考にしたサイト

|URL|
|:--|
|https://stackoverflow.com/questions/54119863/get-build-details-for-all-builds-of-all-jobs-from-jenkins-rest-api|

以上
[01] Jenkins API を使って全ジョブの URL を取得する


|シリーズトップページ|
|:--|
|[[シリーズ 全3回] Jenkins の実行済み全ジョブのコンソールログを取得する](https://qiita.com/robozushi10/items/9750017484313808975b)|

# 概要

次のようなジョブ定義の構造になっている場合に、

```
job
|-- A
    |-- ジョブ1
    |-- ジョブ2
    |-- ジョブ3
```

「ジョブ1」「ジョブ2」「ジョブ3」の URL (次) を取り出す方法.

```
http://<IP>:<PORT>/job/A/job/ジョブ1
http://<IP>:<PORT>/job/A/job/ジョブ2
http://<IP>:<PORT>/job/A/job/ジョブ3
```


# 実行例

ジョブ A の URL に対して `api/json` を付与して GET メソッドを発行し、
url フィールドを取り出せば良い.

ここでは jq コマンドで取り出しているが、JSON 構造を扱える他の方法でも良い.

```bash
$ curl -X GET --user '<ユーザ名>:<APIキー>' http://<IP>:<PORT>/job/A/api/json | \
  jq -r '.jobs[].url'
```

　
以上.
Phoenixのwebsocket部分のみ使いたい

とある件でPhoenixでwebsocket部分のみ使いたいことがあったのでPhoenixプロジェクトの新規立ち上げ時に変更できる設定についてここに書こうと思います。僕自身がほとんど触れていない機能とかもあるので間違ってたらごめんなさい。

## mix tasks
[Phoenix公式のガイド](https://www.phoenixframework.org/)にもあるように通常は下記のコマンドを実行して新規プロジェクトを作成します。

```
mix phx.new　app_name
```

これを実行するとcontrollerとかデータベースあたりのコードとかいろいろたくさん生成されます。普通にアプリを作る場合はそれでいいのですが今回はwebsocketで使いたいだけなので極端な話channel以外いらないです。しかしありがたいことにオプションがありそこでいろいろいじれます。

### options
公式ドキュメントの[mix phx.new options](https://hexdocs.pm/phoenix/Mix.Tasks.Phx.New.html#module-options)の部分になります。
ぶっちゃけ公式ドキュメントを日本語に翻訳するだけになっちゃいますがオプションはこのようになってます。

#### --live
これはPhoenixのLiveViewの機能を使うときの設定みたいです。僕自身LiveViewを使ったことがないのであまり詳しいことはわからないです。

#### --umbrella
どういうこと？？よくわからん。一つのプロジェクト内に複数アプリ作るってことぉ？？

#### --app
OTPアプリケーションって何？ｗ
ググったらワンタイムパスワードとかでてきたけどｗ
だれか教えてください。


#### --module
Google翻訳 -> 「生成されたスケルトンの基本モジュールの名前」
ちょっとなにいってるかわからない。

#### --database
使うデータベースを選ぶことでそれに合わせたアダプタになります。デフォルトはpostgreSQLだったはず。mySQLとか使いたいときはこのオプション入れたほうがいいです。あとから変更するのめんどくさいです。

#### --no-webpack
mix phx.newを実行したら一緒にjs周りもセッティングしてくれるのですがそのへんをやらないようにするやつです。フロント部分は別にするときやapiサーバとして実装するときはjsとかいらないのでこのオプション使うかもー(アル中カラカラ風)


#### --no-ecto
ectoについてはここでは説明しませんがまあそのまんまの意味でectoを作らないっていうオプションです。
軽く触れておくと基本的にPhoenixはectoを通してDBに接続するのでこのオプションを設定するとDB使えません。DB接続しないときの設定です。

#### --no-html
これももうそのまんまです。html生成しないようにするやつです。


#### --no-gettext
gettextはなんか多言語対応するときに使うらしい。僕自身は多言語対応しないといけない場面に今のところでくわしたことないのであんまわからないです。


#### --no-dashboard
デフォルトの場合だとダッシュボードのページが生成されるのですがそれを生成させないオプションです。個人的にはいらないことのほうが多い気がする。


#### --binary-id
これはecto内の設定ですね。主キーにバイナリーIDを使うかどうかの設定。使ったことないから詳しいことは知らないです。

#### --verbose
なにこれｗ
デバッグに使えるの？

## さいごに
ほとんど使ったことない機能であんまかけることなかったです。すみません。
今現在僕がよくわかってない部分もけっこうありますがわかり次第追記しようとは今のところ思ってます（思ってるだけ）。なのでこんなことができるんやなあ程度に流してもらえると助かります。

つたないしょうもない文章を最後まで読んでいただきありがとうございます。。

## 追記
[@torifukukaiou](https://qiita.com/torifukukaiou)さんが[「phx.newのオプションの疑問点について答えてみます (Elixir/Phoenix)」](https://qiita.com/torifukukaiou/items/de54cbfd3298f0b9837b)でこの記事に回答する形で記事を書いてくださいました。ぼくのおふざけまじりな記事がお恥ずかしいですが有難うございます！！
オプションについて知りたい方は@torifukukaiouさんの記事も読むことをおすすめします。
kaggle初心者のタイタニックの次にやるオススメのコンペ

# はじめに
機械学習の学び方や学習フローを調べると、やったほうがいい事として**「Kaggle」**に参加することが書かれてることが多いです。
Kaggleはデータサイエンティストの闘技場みたいなものでして。

[Titanicコンペ](https://www.kaggle.com/c/titanic)がチュートリアルとして有名ですよね。

実際のデータに触れて、前処理やモデル構築をして、より良いモデルを作っていく。
そうした練習ができるということで初心者からするととても有益です。

ただ、自分もそうなのですが、

###**「Kaggleのアカウントは作った。タイタニックコンペもやってみた。この後どないすりゃええねん！」**

となる初心者の方は多いのではないでしょうか？

実際自分は、タイタニックコンペが終わった後どのコンペに参加したらいいかわからず、モチベが出ずに放置してしまいました。

ただ最近、再び本腰入れて機械学習を学び始めて2ヶ月、Kaggleに再びチャレンジしてみようということでチャレンジしており、Kaggleの楽しさがわかってきて、自分なりにタイタニックの後はこれをやったほうがいいのではと思うところがまとまったので、同じ境遇の方の参考に少しでもなればと思って共有させて頂きます。

# 結論：[Tabular Playground Series](https://www.kaggle.com/c/tabular-playground-series-sep-2021)に参加しよう

表題の通りです。
[コチラ](https://qiita.com/abe_yu/items/e58fae1fee185a909318)の記事にも書かれていますが、自分もこのコンペをタイタニックの次におすすめしたいです。

（2021/09/01） 更新
9月になったので **[Sep 2021](https://www.kaggle.com/c/tabular-playground-series-sep-2021)** が開催されてます。(表題リンク先も9月に変更してます)
ざっと見た感じ特徴は下記と一緒ですが、今度は2値分類のようです。
レコード数は90万越えと結構ボリュームあります。
また1ヶ月頑張ります。


記事の通り、毎月新しいデータで開催されており、8月は **[Aug 2021](https://www.kaggle.com/c/tabular-playground-series-aug-2021)**が実施されていました。

特徴としては
**1. データ構成がタイタニックと一緒で取り組みやすい。混乱しにくい。（train.csv, test.csvと提出用csvの3つ）
2. レコード数が比較的多い。(trainデータが25万、testデータが15万)
3. 変数名が匿名化されており、いわゆるドメイン知識が必要とされない。（その分難しさもありますが...)
4. Activeなコンペであった。**

ということが挙げられます。

1に関しては、データの取り込み、データの状況を見てみるといったファーストステップが簡単という意味で大事な所です。

これは僕の反省点でもあるのですが、タイタニックの次に複数テーブルのコンペをやってみた所、そもそもどのテーブルと繋げたらいいかとかで困惑してしまい、データ自体を見れない、面白くないとなってしまいKaggleから離れることになってしまいました。

もちろん甘えてばかりだと何も身につかないのは事実です。
が一番良くないのって、**理想を追い求めすぎて、挫折してしまうこと**だと思います。

いきなりコードがすらすら書ける、すぐデータの重要なところを特定できて、モデル選択がすぐできる、なんて無理な話なので、初心者なら初心者なりに少しずつステップアップが大事だと思います。自分がそうなので。

2は多すぎず少なすぎのデータ量でこの後に繋げやすいです。

3は変数名があると、これとこれが関係しそう、これとこれを組み合わせたら良さそうなどという特徴量の生成が大事になっちゃいます。Kaggle初心者がこれを行うのは正直、ハードル高くないですか？

このコンペは匿名化されており、そうしたことにあまり時間が割かれないので初心者に優しいポイントです。

4は個人的には一番大事なポイントです。
何当たり前のこと言ってんだというツッコミが入りそうですが、やはり他の人も参加して、リアルタイムに順位が動いてというアクティブなコンペの方がモチベが出ます。

初心者は**「過去のコンペのノート見て勉強しろ」**という指摘は間違ってないですが、それでモチベーション維持できる人の方が少ない気がします。自分がそうです。

というのもクローズしたコンペって期限がなく、いつでもスコアが出せるし、提出回数制限もないので、一回提出して、次はここを変えて提出しようという気にならないんですよね。

昔の自分はデータだけDLして、ノートを参考に、一回ベースラインを提出して終わりとなったコンペがたくさんあります。

ただこのコンペに参加してからは毎日上限まで提出してスコアを見るのが楽しくなりましたし、明日はこのモデルの結果を提出しようとか、Kaggleを意識する時間が以前より格段に増えました。

# 画像コンペなら[Digit Recognizer](https://www.kaggle.com/c/digit-recognizer/data)がいいかも

自分はテーブルコンペより画像コンペに興味があったので、そういう人もいるかと思って画像コンペの初心者向けのものも共有できればと思います。

これはいわゆるMNISTデータのコンペです。0~9までの手書き文字を分類します。
データの概要欄にも**「初心者はここから始めてください」**と言ってるくらいです。

ローリングリーダーボードなので、疑似的ではありますが、期限もあるのでモチベーションは保ちやすいです。

普通のMNISTって`tensorflow`の`Dataset`から簡単にDLして用意できるので画像データを`Tensorflow`に読み込ませる流れというか、前処理が簡単すぎて、いざローカルのjpgファイルを読み込ませたい！
ってなった時に**「ん？どうやって読み込むんや？」**ってなりがちだと思います。

このデータはjpgといった画像ファイルではないですが、28×28 = 784ピクセルの1つ1つの値が0~255の範囲でcsvファイルに記載されてます。それを4次元の画像データとして読み込ませるまでの処理が学べるので有益なコンペだと思います。

# 最後に

タイタニック→Tabular Playground Seriesコンペで前処理、モデル構築・予測・評価、スコア提出、スコアアップの楽しさを学ぶ→興味のあるコンペへ

初心者は上記のフローでやるとモチベーションを保ったまま次に繋げやすいのではないかと思います。

現在自分もこの2つのコンペに参加してますので、コンペ期間が終わったら、コンペへの感想などまとめられたらと思います。

同じ機械学習やデータサイエンス学びたての方の参考に少しでもなれば嬉しいです。
AWS Cloud9 または Amazon Linux でShopify CLIを使う

# はじめに

Shopify Appを構築するために使うShopify CLIをCloud9にインストールした時の手順です。おそらくAmazon Linuxでも同様の手順で動かせます。

# 依存するものをインストール

以下をインストールします。

* ruby2.6
* ruby-devel

```console
sudo amazon-linux-extras install ruby2.6
sudo yum install ruby-dev
```

# Shopify CLIをインストール

パッケージを適当なところにダウンロードします。

https://github.com/Shopify/shopify-cli/releases から最新バージョンを確認します。今回は2.2.2が最新でした。

```console
 wget  https://github.com/Shopify/shopify-cli/releases/download/v2.2.2/shopify-cli-2.2.2-1.noarch.rpm
```

```console
 sudo yum install shopify-cli-2.2.2-1.noarch.rpm
```

確認

```console
$ shopify version
2.2.2
```

# ハマったところ

最初に `sudo yum install shopify-cli-2.2.2-1.noarch.rpm` を実行したところ、

```console
Error: Package: shopify-cli-2.2.2-1.noarch (/shopify-cli-2.2.2-1.noarch)
           Requires: ruby >= 2.6.0

```

というエラーだったのでrubyのバージョンを確認したところ

```console
ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
```

と一見要件を満たしているようなのですが、`amazon-linux-extras install ruby2.6` でインストールしないとだめでした。

ruby全くわからないのですがそういうもんなんですかね。
gradle-docker-compose-pluginで、no such serviceが出るようになった



[gradle-docker-compose-plugin](https://github.com/avast/gradle-docker-compose-plugin)を使っていて、以下のようなメッセージが出てテストが起動しなくなってしまいました。

```
Container __test_dockercontainer  Creating
Container __test_dockercontainer  Created
Container __test_dockercontainer  Starting
Container __test_dockercontainer  Started
no such service: test_dockercontainer
Container __test_dockercontainer  Stopping
Container __test_dockercontainer  Stopped
Container __test_dockercontainer  Removing
Container __test_dockercontainer  Removed
```


調べたところ、いつのまにか`Desktop Compose V2`が有効になっていたのが原因でした。

Use Docker Compose V2　が有効になっていました。

![スクリーンショット 2021-08-27 20.40.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49910/298113b4-c4dd-dcae-dc52-69e6db5992f3.png "スクリーンショット 2021-08-27 20.40.06.png")


チェックをOFFにすることで解決しました。


Docker Compose V2への対応考えねばですね。




[Compose V2 release candidate \| Docker Documentation](https://docs.docker.com/compose/cli-command/#installing-compose-v2)


[「Docker Desktop 3\.6」がリリース、Docker Compose V2はリリース候補が登場：CodeZine（コードジン）](https://codezine.jp/article/detail/14732)
WSL2でGitクライアントを使う


## TL;DR
- WSL2ではWindows側にGitクライアントをインストールするが、そのままではWSL側のファイルが見えないよ
- WSL2をWindowsにネットワークドライブとして認識させることでアクセスできるよ


## 課題
私はGUIのGitクライアント使う派です。最近はメインPCがWindowsのためWSL2を使用して開発していたのですが、GitクライアントからWSL側のファイルが見えませんでした。

Explolerからは `\\wsl$\` でWSL内のファイルへアクセスできるのですが、Gitクライアントから開こうとするとアクセスできません、というようなメッセージがでて弾かれる状態でした。

## 解決策
https://github.com/microsoft/WSL/issues/4273#issuecomment-508844541
こちらで提示されている通り、`\\wsl$\Ubuntu` をネットワークドライブとして設定すると、Gitクライアント経由でもアクセスできるようになりました。

## 備考
一旦ネットワークドライブとして認識したあとは、Gitクライアントからも `\\wsl$\` でアクセスできるようになりました。
なので私の勘違いという説もあるのですが、備忘録として残しておきます。
railsで.envの値を読み込めなかったときにやること

## 結論
`spring stop`を実行して、もう一度`rails c`でコンソールを立ち上げるとOK

```
$ spring stop
$ rails c
```

## 問題が起きた時の状態

`.env`ファイル

```.env
AUTH0_DOMAIN=https://XXXXXXXXXXXXX/
AUTH0_IDENTIFIER=https://XXXXXXXXXXXXXXX
```

```console
$ rails c
Running via Spring preloader in process 19140
Loading development environment (Rails 6.0.4)
irb(main):001:0>  ENV['AUTH0_DOMAIN']
=> nil
```

## spring stopを実行

```
$ spring stop
```

```console
$ rails c
Running via Spring preloader in process 19270
Loading development environment (Rails 6.0.4)
irb(main):001:0> ENV["AUTH0_IDENTIFIER"]
=> "https://XXXXXXXXXXXXXXX"
```

ちゃんと読み込めた
文章構成力を上げるSDS法

SDS法とは、「Summary ・ Details ・ Summary」の略です。

**Summary　＝　全体の概要**
最初に、あなたが伝えたいポイントを「～についてお伝えします」と書き出します。

**Details　＝　詳細の説明**
次に、Summary（概要）の内容を具体的に説明していきます。

**Summary　＝　最後に全体のまとめ**
最後に、「以上、～についてお伝えしました」といったように全体をまとめます。



SDS法を使って文章を作ってみると以下の通りです。

```
Suumary
今日は、なぜ文章テンプレートがあなたの文章力を飛躍させるのか？ についてお伝えします。

Details
文章テンプレート（型）を使いこなし、あなたの文章力を飛躍させるには、3つのステップがあります。

ステップ1「守」：型通りに文章を書いてみる
ステップ2「破」：型を自分なりにアレンジしてみる
ステップ3「離」：型から離れ自在に文章を書いてみる

Summary
以上から、「文章テンプレート（型）」を使いこなすことが、あなたの文章力を飛躍させる、ということについてお伝えしました。

```
yukicoder contest 311 参戦記

# yukicoder contest 311 参戦記

1時間遅れの参加でAしか解けませんでした.

## [A 1656 Recuperation](https://yukicoder.me/problems/no/1656)

B 日でストレスが A×B になって、それを癒やすのに A×B 日かかるので、合計日数は B + A×B = (A+1)B 日ですね.

```python
from sys import stdin

readline = stdin.readline

T = int(readline())

result = []
for _ in range(T):
    A, B = map(int, readline().split())
    result.append((A + 1) * B)
print(*result, sep='\n')
```

## [C 1658 Product / Sum](https://yukicoder.me/problems/no/1658)

直感的に A<sub>1</sub>=x, A<sub>2</sub>=y, A<sub>3</sub>=1, A<sub>4</sub>=1, ..., A<sub>N</sub>=1 なんだろうなと思い、xy/(x + y + N - 2) = K という式を書きましたが、ここから式変形する才能がありませんでした orz.

```python
N, K = map(int, input().split())

result = [1] * N
result[0] = 2 * K
result[1] = 2 * K + N - 2
print(*result)
```
rails tutorial2章進めた時の覚書

2章でhello_appに加え、toy_appを製作したが、

```
$ git push heroku master
```

は同じように叩いてしまっていいのか？
上書きされる感じになるのかな？

herokuの管理画面見る限り、
- hello_app
- toy_app

の2つがアップロードされているわけではない?から、上書きされてるのかしら。


``` herokuアプリをブラウザで開く
 $heroku open --app アプリ名
```
参考: https://qiita.com/RyomaMaeda/items/60c96e8255996cbb375c

``` アプリ名確認
$ heroku apps
```

アプリブラウザで確認したらエラー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198412/6dcbc71b-1168-72c3-31af-6a439af240fb.png)

rails tutorialに則りログ確認からの migrate

```
$ heroku logs
ActionView::Template::Error (PG::UndefinedTable: ERROR:  relation "users" does not exist
$ heroku run rails db:migrate
```

無事表示を確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198412/7783cd59-855f-d6f1-5cd4-44b811b91334.png)

ユーザー作るとまたさっきのエラー出る
> 最後に、もし2.3.3.1の演習をやっていれば、「最初のユーザーのマイクロポストを表示する」というコードを削除する必要があることに注意してください。

と書いてあるが、2.3.3.1の演習がどれかわからない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198412/6eb0794f-78f8-6708-3562-32d469c45461.png)
これだ

その後、該当コードをコメントアウトして、git add するが、ファイルの変更がトラッキングされず、commitもpushもできない

一度cloud9上でrunボタンを押してから再度 git diff したらちゃんと変更がトラッキングされていた。
謎。

ちなみに下記コメントアウトしてpushしたら、ユーザー製作してもエラーでず正常に動作した。

```erb
$ <%= @user.microposts.first.content %>
```

なんで？呟きがないのに呟きを表示しようとしたからエラーがでた？
検証するために、下記コードを書いてユーザーを新規に製作したところ、普通に同じエラーでた。
コードがそもそも間違っているのか、*呟きがないのに呟きを表示しようとしたから* という仮説が間違っているからのどちらかなのかはわからず。

```erb
if @user.microposts.first.content != null then
    <%= @user.microposts.first.content %>
  else
  end
```

一個前のコメントアウトしただけのcommitに戻す
```
$git log #戻したいcommitのハッシュ値を取得
$git reset --hard ハッシュ値
```

 この後、
```
$git push heroku master # エラー出る
$git pull heroku master
```

とかしてたらわけわかんなくなった。
【初心者向け】初めての模写コーディングで役立つ豆知識・学習メモ（9/16）

#学習内容
- HTML/CSSコーディング練習
- Railsアプリ開発2周目突入（rails new）

##学んだこと
###HTML/CSSコーディング練習
####flex関連
- flex, flex-wrap, justify-content, aligin-itemsは親要素に付ける
- 複数の要素を横並びにしたいときは親要素にdisplay: flex;を指定する
- 要素の間隔を広げたい場合はgap: ○○px;で指定すれば簡単
- また、画像とテキストを横並びにするときは子要素の両方にwidth: 100%;を付ける

####ボタン関連
- ボタンを中央寄せしたいときはdisplay: block;とmargin: auto;を指定する
- display: block;を付けてブロック要素に変更
- paddingで余白をとる
- cursor: pointer;と擬似要素でopacityを指定すれば、よりボタンっぽくなる
- ボタンの原型クラスと色付けクラスで分けると汎用性アップ

####inputタグ関連
- inputタグを中央寄せするときはwidthで横幅を指定してからmargin: auto;を付ける
- border-radius: 1000px;を指定すると角が丸くなる

###footer関連
- footerはcopyrightにクラスを指定してtext-alignを指定すれば任意の方向に動かせる
Jetpack Composeで、Mutable系統をStateに登録したらあかん

Mutable系統をStateに入れていて、数日ドツボにはまったのでメモしておきます。

# 問題

Jetpack Composeの勉強のために、以下のようなアプリを作成しました。

![スクリーンショット 2021-09-16 221859.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674896/0da3bc47-e6fa-a1e2-6e7e-b7a70b453272.png)

ソースコードは以下の通りです。

```kotlin:List.kt
@Composable
fun List(){
    
    //表示するStateを作成
    val list by remember { mutableStateOf((0..3).toMutableList()) }

    LazyColumn(Modifier.fillMaxSize()){
        
        //カラムを表示する部分
        item{
            for(i in list){
                LazyCard(text = i.toString())
            }
        }
        
        //ボタンを表示する部分
        item { 
            AddButton(onClick = {
                list.add(list.size)
            })
        }
    }
}
```

これでボタンを押せば、カラムが増えていくはず・・・ですがなぜか増えません。

# 解決策？

原因ですが、おそらく

```kotlin:List.kt
        //ボタンを表示する部分
        item { 
            AddButton(onClick = {
                list.add(list.size)
            })
        }
```
ここで`add`関数を使っていますが、これでは差分を検知してくれないからではないかと思います。

そこでこの部分をとりあえず以下のように書き直してみました。

```kotlin:List.kt

    //表示するStateを作成
    val list by remember { mutableStateOf((0..3).toMutableList()) }

    ・・・

        //ボタンを表示する部分
        item { 
            AddButton(onClick = {
                val tempList = list
                tempList.add(list.size)
                list = tempList
            })
        }
```

これで、listに再代入しているので差分を検知してくれるはず・・・がまたしてもピクリともしない。


# 原因

なぜ検知してくれないのかと思い、`tempList`に要素を追加したタイミングでそれぞれの値を見てみました。

```kotlin:List.kt

        //ボタンを表示する部分
        item { 
            AddButton(onClick = {
                val tempList = list
                tempList.add(list.size)
                Log.d("debug", "list: $list, tempList: $tempList")
                list = tempList
            })
        }
```

すると驚くことに、以下の結果が出力されました。

```
D/debug: list: [0, 1, 2, 3, 4], tempList: [0, 1, 2, 3, 4]
```

これはつまり

```kotlin
tempList.add(list.size)
```

が実行されたタイミングで`list`の方にも反映されているということです。
ということは

```kotlin
val tempList = list
```

ここでの代入は値渡しではなく、参照渡しになっている？ということでしょう。

確かにそう考えると、`add`関数では差分を検知しないし、最後の代入でも差分がない。
UIの再描写が走らないはずです。

# 解決策

GoogleのCodelabを見て回っていたら、このような感じで記述していました。

```kotlin:List.kt

    var list by remember { mutableStateOf((0..3).toList()) }

    ・・・

        //ボタンを表示する部分
        item { 
            AddButton(onClick = {
                list = list + listOf(list.size)
            })
        }

```

なるほど・・・完全に新しく作り直していますね。
確認したところ、これだと正しく動作しました。

となってくると、StateでMutable系統を使うのはやめた方がよさそうですね。
`add`関数が使えない時点で通常の型の代わりに使うメリットがないし、むしろバグの温床になりそうです。

# 補足
参照渡しになるのはKotlin(正確にはJava)の仕様のようですね。
プリニティブ型では値渡し、クラス型では参照渡しをするようで、Mutable系統はもちろんクラス型なので参照渡しになるということのようです。

# 参考
https://developer.android.com/codelabs/jetpack-compose-state?hl=ja#0

http://syrinx.q.t.u-tokyo.ac.jp/tori/java/basic/entity_ref.ht
[Rails]Gemを使ってモーダル作成

# はじめに
本記事では、Gemを使ったモーダルの作成方法を記述します。

## 参考動画
ブックマークしているサイトがもろ見えになるので、上は切りました。
「決して」やましいものはありません。

![05adb4091ab2c978dffd22ddbd5045d2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1768158/8bcc6b41-7ff5-2a27-ae1e-b4c7ebb3a7b4.gif)

# 流れ

`gem`のインストールです。

```ruby
gem 'data-confirm-modal'
```
からの

```
bundle install
```
からの

```application.js
// = require data-confirm-modal
コメントアウトでOK
```

```erb
<%= link_to food_path(food.id), method: :delete, data:
  { confirm: '本当に削除しますか?削除すると投稿の復元はできません',
  cancel: 'やめる',
  commit: '削除する'}, title: '削除確認' do %>
  <i class="fas fa-trash-alt"></i>
<% end %>
```
`dataは{}`、`titleは{}には入れない`ようにそれぞれ注意ですね。

検索ボタン押したら検索フォームがブワッと出てくるような
おしゃれなモーダルを作成する場合は、CSSとjQueryを使ったモーダルでいいと多いますが、
今回のような削除は、このGem使った方が、
`え？ほんとに削除するの？感`が出るので、私はこっちが好きです。

適材適所ってやつですかね。

難しいと思ったら思いの外簡単にできたので、覚えておきたいところです。

以上です。

# 終わりに
色々なGemがあるんですね。
もっといろんなGemを知ってアプリケーションを良くする武器を揃えたいです。

以下参考サイトです。
[Ruby on Railsで削除ボタンを押したときに確認ダイアログを表示させる方法](https://yokonoji.work/rails-delete-dialog)
[data: {confirm: }の確認ダイアログをいい感じにする【Ruby on Rails】](https://fuchiaz.com/rails-gem-data-confirm-modal/)

明日も頑張ります!
【Swift5】Firebase Authでメールの重複チェックを行う

## 背景
Firebaseでメールの重複チェックを行う時に、Firestoreのuserデータから検索を行う手段が多かったので
Firebase Authのみで重複チェックを行う方法を記載しようと思いました。

## 実装
```swift
import Firebase

func checkEmailExist(email: String, completion: @escaping ((Result<Bool, Error>) -> Void) {
  // SignInの方法を取得するメソッドを使用
  Auth.auth().fetchSignInMethods(forEmail: email, completion: { (method, error) in
    if let err = error {
      completion(.failure(err))
      return
    }
    // すでにメールアドレスの認証などされている場合は
    // methodの中に"EmailLink"や"Email"などの認証方法が入る
    guard let method = method, !method.isEmpty else {
      // 何もない場合は存在しない
      completion(.success(false))
      return
    }
    
    // methodに認証方法が入っている場合は存在する判定
    completion(.success(true))
  })
}
```

上記のメソッドをメールアドレスを入力しているViewControllerなどから呼び出してあげれば良いです！
Result型がわからない場合に備えて、ViewControllerでの実装例も載せておきます。

### 実装例
```swift
import UIKit

class SampleViewController: UIViewController {
  @IBOutlet var textField: UITextField!

  override func viewDidLoad() {
    super.viewDidLoad()
  }

  @IBAction func tapButton(_ sender: Any) {
     guard let email = textField.text else {
       return
     }

     checkEmailExist(email: email, completion: { result in
       switch result {
         case let .success(isExist):
           if (isExist) {
             // メールアドレスが重複した時の処理
           } else {
             // メールアドレスが重複していないので、認証処理を行う
           }
         case let .failure(error):
           // エラー時のハンドリング(ダイアログ出したり) 
       }
     })
  }
}
```

## 他の実装方法について
```swift
FirestoreのDB構造
Users
  - ユーザーA
    - hogehoge1@sss.com
  - ユーザーB
    - hogehoge2@sss.com
```
上記のようにFirestoreのUsersコレクションを作成してメールアドレスで検索する方法もありますが、
セキュリティ的にメールアドレスを全てのユーザーが見れる状態はあまり良い状態ではない(そういうアプリであれば良いですが)
と思うので、こちらの方法はあまり推奨できないと思います。


良いFirebaseライフを！
includesで発行されるSQL【Rails】

rails 6.0.2
ruby 2.7.1

# includesとは

N+1問題を起こさないように、関連テーブルのデータをキャッシュしてくれるメソッド。
しかし、関連テーブルのデータをキャッシュするといっても
一体どのようにして、データを取得してきているのだろうか。

実はincludesは、モデルの関連など見て以下のどちらかの最適とrailsが判断したメソッドを実行している。
(このrailsの判断が正しいとは限らない。*後述)

preload|eager_load|
---|---|
|関連ごとにSQLを発行してキャッシュ。　|left_joinを用いて、キャッシュ。|


preload、eager_loadがどの様なSQLを発行してるか見ていく。

以下の様なモデルがあるとする。

```ruby:user.rb
class User < ApplicationRecord
belong_to :country  #国
has_many  :posts    #投稿

end
```

## preload
preloadは、関連ごとにSQLを発行してキャッシュする。
いったいどういうことかというと、以下のようなrubyコードでは

```ruby
User.all.preload(:posts,:country)
```
以下のようなsqlが発行される。　

```sql
--user.allのsql
select * from users;
--postsのキャッシュのsql in句は、user.id
select * from posts where user_id in (1,2,3,4,5,6.....);
--countryのキャッシュのsql in句は、user.county_id
select * from countries where id in (1,2,3,4,5,6.....);
```

## eager_load
left_joinを用いて、キャッシュ。
いったいどういうことかというと、以下のようなrubyコードでは

```ruby
User.all.eager_load(:posts,:country)
```
以下のようなsqlが発行される。　

```sql
--user.allのsql兼、postsのキャッシュ兼、countryのキャッシュ
select * from users u
left join posts p on p.user_id = u.id
left join countries c c.id = u.countries ;
```

以上の様にsqlが発行される訳だが、
railsのincludesがpreload,eager_loadの使い分けを完璧にできる訳ではない。

例えば、以下のように複数のテーブルをキャッシュしたい時、
countryだけ、preloadで他は全てeager_loadみたいなことは出来ない。
全部preload　or 全部eager_load のどちらかである。　

```ruby
User.all.includes(posts: [:comments],:country,:profies)
```

preloadでキャッシャしたらまずいところ
eager_loadでキャッシュしたらまずいところがそれぞれあり、
railsでも使い分けをしている訳だが、
このようなことが起きると、意図せぬところでパフォーマンスの低下が起きてしまう。

したがって、各メリットデメリットを理解しておく必要がある。


# メリットデメリット

## preload
### メリット
1.メモリの圧迫を防げる。
　例えば、中間テーブルを持つN対Nの関係のテーブルをeaager_loadを使ってキャッシュした場合。
　その実行結果のレコード数は単純に取得したかったデータ量よりもはるかに多くなってしまい、メモリを圧迫してしまうこ　とになる。

　
### デメリット　
 ① IN句が大きくなりすぎる場合がある。
　例えば、例で用いたrubyコードのUser.allが1万件あった場合、in句が膨大な長さになり、
　以下の様なことが起きる。

　・ ネットワークI/Oを圧迫する。
　・ rdbmsによってin句に指定できる数には限界がある、Oracleは、1000個らしい。
参考　https://oreno-it.info/archives/816

② 関連先テーブルを使って絞り込みなどができない。
別のsqlでキャッシュをしてるので、関連テーブルのカラムをwhereで使うことはできない。
つまり以下の様なrubyコードはエラーになる。

```ruby
irb(main)> User.preload(:country).where(countries: {name: '日本'})

ActiveRecord::StatementInvalid (PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "members")
LINE 1: SELECT "users".* FROM "users" WHERE "members"."name" = $1 LI...
```

## eager_load
### メリット
① 関連先テーブルを使って絞り込みなどが出来る。
以下が実行可能。

 ``` ruby
irb(main)> User.eager_load(:country).where(countries: {name: '日本'})
```

② 一対一,N対一の関連テーブルを取得するのに良い。
　・一対一,N対一の関連の場合、結合の結果のレコードが増えるわけではないので、
　　結合によるメモリの圧迫は少ない。
　・sqlの発行回数が少ない。（通信回数、rdbmsの構文解析などの時間が減る。）


### デメリット
① 関連がN対ー,N対Nの場合のパフォーマンス
 left_joinなので無駄なデータを沢山とってきてしまい、パフォーマンスは下がる。
パッケージを管理コマンド rpm と yum

## 概要

エンジニア駆け出しの時にCentOSなどを使用していた際、
rpmとかyumという言葉が出てきて何？ってなりましたので、
自分の備忘として記事を残します。

まず、yum も rpm も「パッケージを管理するコマンド」という理解でOKです。

## 結論
rpm = 個々のパッケージを扱うのパッケージ管理コマンド
yum = RPM パッケージを扱うためのパッケージ管理コマンド


## rpm
- パッケージを個々で管理するので依存関係は解決されない
- rpmファイルを個別に指定する
- リポジトリに依存しない
- インストール時にパッケージ名で指定できる
- パッケージ名はわかってるだけではインストールできない

## yum
- rpmをまとめているので依存関係を自動解決してくれる
- パッケージ名さえわかっていればインストール可能

基本的にyumコマンドを使う頻度の方が多いです。

## rpm コマンド
コマンドのオプションは以下記事拝借
[【 rpm 】コマンド（応用編その1）――パッケージの情報を調べる（1）](https://atmarkit.itmedia.co.jp/ait/articles/1609/20/news019.html)

- インストール

```
rpm -ivh [パッケージ名]
```
- update

```
rpm -Uvh [パッケージ名]
```
- 削除

```
rpm -e [パッケージ名]
```

## yum コマンド
コマンドのオプションは以下記事拝借
[【 yum 】コマンド（応用編その3）――パッケージ／システムをアップデートする](https://atmarkit.itmedia.co.jp/ait/articles/1609/06/news023.html)

- インストール可能なパッケージの一覧を出力

```
yum list
```

- パッケージをインストール

```
yum install [パッケージ名]
```

- システムにインストールされたパッケージをアップデートする

``` 
yum update
```

## yum update の注意点
yum update を実行すると
インストールされているパッケージのバージョンがすべて最新のものに更新されます。

定期的にyum updateを実行して、最新の情報にすることで、
脆弱性の改善の恩恵を受けられます。

ですが、パッケージがアップデートされることによって、
既存のシステムに影響を与え、不具合が発生する可能性があるので注意が必要。
CCNA OSI参照モデル 物理層

今回はOSI参照モデルの物理層に関する記述です。

復習ですが、物理層はOSI参照モデルのレイヤ1で、
電気信号や機器に関するプロトコル群です。

PCやサーバー以外にハブなどもネットワーク機器に含まれます。
代表的なネットワーク機器はハブです。
これは単に集線機能+リピータ機能のリピータハブと
スイッチングハブに分かれます。
これは決まった宛先に送ることができないハブと
決まった宛先に送ることができるスイッチがあります。

リピータ機能は減衰した電気信号を増幅させる機能があります。
ハブもスイッチも隣接するノードの通信を可能にしますが、
異なるネットワークの機器にも送るためにはルータを使います。
ただ、ハブはレイヤ1,スイッチはレイヤ2、ルータはレイヤ3です。

ハブで使うケーブルで最も良く使うのはツイストペアケーブルです。
2本の線の「より」によってノイズが防がれています。これはLANで
最もよく使われています。シールドがあるSTP(Shielded Twisted Pair)と
UTP(Unshielded Twisted Pair)に分かれます。
セグメント長は約100メートルです。

品質や速度によってカテゴリーに分かれます。
LANはCat3以上になります。
ケーブルの末端にはRJ-45コネクタがついています。
これはNICや多くのネットワーク機器に対応しています。

PCに付いているのはNIC(Network Interface Card)です。
これに繋ぐことにより、ネットワークに接続できます。

ケーブルの種類は2種類あります。
ストレートケーブルとクロスケーブルに分かれます。
これは両端のピンの配置が同じか違うかがポイントです。
同じだとストレートケーブル、違うとクロスケーブルです。

ポート(モジュラージャック)の種類によって変わってきます。
1・2番で送信、3・6番で受信するのをMDIポート
反対をMDI-Xポートと言います。
これはPCとルータはMDIポート、スイッチとハブはMDI-Xポートになります。
これが同じポートだとクロスケーブル、違うポートだとストレートケーブルになります。

他のケーブルとしては光ファイバーケーブルがあります。
これは電気信号を光信号に直して送るケーブルになります。
光の通り道をコア、それを抑えるクラッドに分かれます。
長距離通信、高速通信が可能になるが、高価です。

これも2種類に分かれます。それはモード(光信号)が
1本のSMF(シングルモードファイバ)と複数の
MMF(マルチモードファイバ)に分かれます。

**同軸ケーブル**

これは初期のイーサネットで使われていました。
テレビなどで使われています。

**シリアルケーブル**

これは主にWANで使われています。

#最後に

自分のアウトプットとして知識を出していますので、分かりにくい点等があると
思いますが、良ければ見て頂けると幸いです。
勉強中の身ですので、もし不明点や間違った点がありましたら是非コメント下さい。
Webシステムのセキュリティ対策まとめ　-ファイアウォール-

#はじめに
様々な攻撃に晒されるWebサイトのセキュリティを強化するためにどんなWebセキュリティ対策あるのかということで
今回、学んだことをアウトプットしてみたいと思います。

#前置き
Webシステムへの攻撃を防ぐ方法として、有効なのは攻撃者からアクセスさせないこと。しかし、完全にアクセスを遮断してはWebシステムとしてサービスを提供することが不可能となる。
そこで、サービスに必要な通信だけを許可し、それ以外の通信したら良いという考えになります。
インターネットと内部ネットワークの間に設置し、送受信されるデータを監視の許可、拒否を行うものがファイアーウォールとなります。

#ファイアウォール
ファイアウォールとは、自社のサーバーを不正アクセスやサイバー攻撃などから守るために使われるセキュリティ機能です。ファイアウォールを日本語に直訳すると「防火壁」。名前のとおりインターネットと自社サーバーネットワークの間に設置し、外部からの攻撃を監視・制御し、内部ネットワークを保護する役割を果たします。

#パケットフィルタリング型
__[メリット]__
ファイアウォールにはいくつかの方式がある。多く使用されているのがパケットフィルタ型と呼ばれるもの。
事前に、通信を許可するIPアドレス・ポートや、宛先情報をルールとして設定することでルールと違った通信を遮断が可能。

__[デメリット]__
仕組み自体がシンプルなので、パケットを見ただけでは攻撃されているか判別がつかないバッファオーバーフロー攻撃やウイルス付きEメールなどの攻撃は防ぐことはできません。そのため、他のファイアウォールやセキュリティ製品と組み合わせる必要性がある。

#アプリケーションゲートウェイ型
__[メリット]__
従来のパケットフィルタリングよりも詳細に、通過を許可する通信を特定・制御するための仕組み。HTTP・FTP・SMTPなどアプリケーションプロトコル毎に、通信を制御する仕組みを準備し、外部ネットワークとのやり取りを許可したり遮断したりします。

__[デメリット]__
アプリケーション層まで確認するため、高精度なアクセス制限を設けることが可能です。しかし、通信内容の処理に時間がかかったり、構築までに高いコストが発生する。

#サーキットレベルゲートウェイ型
__[メリット]__
トランスポート層レベルの通信を監視・制御する方式です。コネクション単位の制御も可能で、パケットフィルタリングよりも設定や管理が簡単です。

コネクション単位で通信可否を判断するため、パケットフィルタリングでは防げない送信元IPアドレスの偽装を防ぐことが可能です。また、どのアプリケーションプロトコルでも汎用的に使用できるのもメリットの一つ.
【PHP】継承とオーバーライドについて

基礎の基礎に戻ってみました。

## 継承とは
すでに存在しているクラスを元にして、新しいクラスを作ること
元のクラスの事を**親クラス、基底クラス**と呼びます。
新しいクラスは**子クラス**と呼んでます。

### 継承することのメリット
親クラスで定義した関数を、子クラスでも同じように使用することができます。
これによって、同じような処理を複数書かなくて良くなります。
+コードの可読性も上がるので、メンテナンスがしやすくなります。

### 継承の使い方
`class 子クラス名 extends 親クラス名{}`という形で継承することができます。

```php
<?php
// 親クラス
class ParentClass {
  public function test(){
    print '親クラスのメソッドです'."\n";
  }
}

// 子クラス 
class ChildClass extends ParentClass {
  
}

$a = new ChildClass();
echo $a->test();

//出力結果///////
親クラスのメソッドです
?>
```

## オーバーライド とは
子クラスが親クラスの関数を上書きすること
**継承**をしていることが条件です。
`親クラスと同名の関数を子クラスでも定義してあげる`ことによって、オーバーライドできます。(**※引数も合わせること**)

### オーバーライド のメリット
1つの関数名で、クラスに応じて適切な処理（関数）を行わせることができます。

### 使用例
```php
<?php
// 親クラス
class ParentClass {
  public function output(){
    print '親クラスのメソッドです'."\n";
  }
}

// 子クラス 
class ChildClass extends ParentClass {
  public function output(){
    print "子クラスのメソッドが親クラスをオーバーライドしました"; 
  }
}

$test = new ParentClass();
$test->output();

$test2 = new ChildClass();
$test2->output();
?>
////出力結果//////
親クラスのメソッドです
子クラスのメソッドが親クラスをオーバーライドしました
```
継承をしているので、関数名が被ってしまうとシステム側で「どっち実行すればいいの？」ってなりそうですが大丈夫です。

### オーバーライドの使い方
例えば、複数のクラスがあって、1つだけ別の処理をさせたい場合などに使えます。

```php
<?php
// 4つのクラスでは、親クラスの処理をそのまま使いたい
class ParentClass {
  public function duplicateCheck($id){
    return [];
  }
}

// 1つのクラスだけ、DBの重複チェックをしたい
class ChildClass extends ParentClass {
  public function duplicateCheck($id){
      return DB::findxx($id);
  }
?>
```
こういった場合に使うことができます。
【基本情報技術者試験】自分用メモ～よく間違えるところまとめ～

## RAM
RAMとは、半導体でできたメモリのことです。
以下の2つに分けられます。

- DRAM（Dynamic Random Access Memory：ディーラム）
  - メモリセル構造が単純なので高集積化することができ、ビット単価を安くできる
  - 時間の経過と共に記憶している内容が薄れてしまうため、定期的に同じ内容を書き直す必要がある揮発性メモリ
- SRAM（Static Random Access Memory：エスラム）
  - データを保持するためのリフレッシュ操作またはアクセス操作が不要
  - メモリセルにフリップフロップ回路を利用している
  - 時間の経過と共に記憶している内容が薄れてしまわないため、定期的に同じ内容を書き直す必要がない揮発性メモリ


## エンタープライズアーキテクチャ（EA：Enterprise Architecture）
エンタープライズアーキテクチャとは、社会環境や情報技術の変化に素早く対応できるよう「全体最適」の観点から業務やシステムを改善する仕組みであり、組織全体として業務プロセスや情報システムの構造、利用する技術などを、 整理・体系化したものであり、大企業や政府機関などといった巨大な組織(enterprise)の 業務手順・情報システムの標準化、および組織の最適化を進め、 効率よい組織の運営を図るための方法論です。
以下の4つの体系から構成されています。

- ビジネス・アーキテクチャ（政策・業務体系）
  - ビジネス戦略に必要な業務プロセスや情報の流れを体系的に示したもの
- データ・アーキテクチャ（データ体系）
  - 業務に必要なデータの内容，データ間の関連や構造などを体系的に示したもの
- アプリケーション・アーキテクチャ（処理体系）
  - 業務プロセスを支援するシステムの機能や構成などを体系的に示したもの
- テクノロジ・アーキテクチャ（技術体系）
  - 情報システムの構築・運用に必要な技術的構成要素を体系的に示したもの
EmbulkをJava8のまま使用し続ける

サーバーにインストールされているJavaを8から11にアップデートしたいが、
EmbulkがまだJava8までしか対応していない。

```
$ embulk gem list
[ERROR] embulk does not support Java11 yet.
```

[Embulk v0.11 / v1.0 に向けて: プラグイン開発者の皆様へ](https://zenn.dev/dmikurube/articles/get-ready-for-embulk-v0-11-and-v1-0)

そのためEmbulkはJava8のまま使い続ける方法。

localhostのApacheのログファイルをlocalhostのMySQLにインポートする想定

### Java8と11をインストール

```
$yum install -y java-1.8.0-openjdk

$yum install -y java-11-openjdk

# Java11に切り替える
$alternatives --config java

```

[【Java】複数バージョンのJavaを切り替えて使う方法](https://qiita.com/nkojima/items/e3de6052554ee1d77144)

### Java8のパスを直接指定する方法

Java8のパスを確認

```
$alternatives --config java
```

.bash_rc にエイリアスを設定する。

```
$vim .bashrc
alias embulk='/usr/jvm/java8のパス/java -java $HOME/.embulk/bin/embulk'
```

即設定を反映させる。

```
$source bash ~/.bashrc
```

動作確認

```
$embulk gem list
```

### Dockerを使う方法

[Docker コンテナで Embulk を動かす](https://qiita.com/hoto17296/items/a7d69172050fa9aab045)
を参考に設定。


```Dockerfile:Dockerfile

FROM openjdk:8-jre-alpine

RUN wget -q https://dl.embulk.org/embulk-latest.jar -O /bin/embulk \
  && chmod +x /bin/embulk

RUN apk add --no-cache libc6-compat \
  && embulk gem install embulk-output-mysql \
  && embulk gem install eembulk-parser-apache-custom-log

WORKDIR /work

ENTRYPOINT ["java", "-jar", "/bin/embulk"]

```

イメージをビルド

```
$docker build -t embulk .
```

embulkはDockerコンテナ内で実行するので、localhost(ホストOS）に繋ぐときは
``--add-host``でlocalhostとホストOSのIPを紐づける必要がある。

[Dockerコンテナ内からホストへlocalhost でアクセスしてみる](https://qiita.com/kai_kou/items/5182965ea75c85cf1e3f)
[dockerコンテナの中でホストマシンのIPアドレスを取り出す](https://qiita.com/johejo/items/83cb83a885b8ac996ec9)

```
$docker run --rm  --add-host=localhost: <ホストのプライベートIPアドレス> -it -v $(pwd):/work embulk run config.yml
```

config.ymlファイルの中のパスは、Dockerコンテナの中から見たパスになるので、絶対パスにしている場合は、Dockerコンテナ内から参照できるように書き換える必要がある。

[Dockerコンテナにホストマシンのディレクトリをマウントする／マウントされたパスを確認する](https://mrkmyki.com/post-934)
Dockerの開発環境から踏み台サーバー経由でdbに接続 [ Rails ]

## 目的
開発マシン上のdockerで動作するrailsアプリケーションのdb接続を
踏み台サーバー経由でrdsに接続したい。

![スクリーンショット 2021-09-16 13.39.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664524/7e161536-c88b-ddea-3bdc-cf7143806244.png)


## 方法
### 前提
◦踏み台サーバー
  ・エンドポイント ip: 12.12.12.12
  ・pemファイル /Users/hoge/.ssh/hoge.pem
  ・接続ユーザー root
◦dbサーバー
  ・エンドポイント　private domain: hogehoge.internal (踏み台から見て)
  ・postgreSQL(portは、5432)


① macターミナルから以下コマンドを実行、SSHポートフォーワーディングを行う。


```shell
ssh -N -L 5434:hogehoge.internal:5432 -i /Users/hoge/.ssh/hoge.pem -p 22 root@12.12.12.12
```

② database.ymlの行き先をmacの5434に設定。


```yml:database.yml

host: host.docker.internal
port: 5434
```

注) docker上で動くrailsアプリの場合なので、
*localhost*　でなく　*host.docker.internal* で指定


③ rails サーバーを立ち上げる
正しくdbに接続されてることを確認。　


## sshポートフォーワーディングとは
sshポートフォーワーディングとは、sshコマンドのポート転送機能のこと。
sshコマンドは通常以下のように使用されるが、


```sh
 ssh 10.10.10.10
```


ここに-L オプションをつけるとポートの転送先を設定できる。

例えば、

```sh
ssh -L ポート番号1:10.10.10.11:ポート番号2　10.10.10.10 
```

これを実行すると、　
localhost:ポート番号1への接続が、10.10.10.10を経由して
10.10.10.11:ポート番号2に転送されるようになる。
vimでディレクトリを開くとファイラーとして使える

vimでディレクトリを開くと、vim8.1ではvimファイラーとしてnetrwが標準で利用できる。

```shell
❯ vim --version
VIM - Vi IMproved 8.1 (2018 May 18, compiled Apr 15 2020 06:40:31)
```

## 使い方
ファイル名にカーソルを合わせてENTERを押すと、ファイルがvimで開かれる

参考：[vimの標準ファイラnetrwは普通に良さそうな話し](https://qiita.com/gorilla0513/items/bf2f78dfec67242f5bcf)
Javaのlogging 

#### it depends on! situation
#java.util.logging
java 1.4から提供しているlogging utility
7 levelのloggingを提供している

- SEVERE(highest value)
- WARNING
- INFO
- CONFIG
- FINE
- FINER
- FINEST(lowest value)


```java
private static final Logger logger = Logger.getLogger(MyApplication.class.getName());

logger.info(Level.INFO, "it is test for {0}","log");
```


長所：外部ライブラリー使用せず、使える

短所：What means "FINE"? "FINER"? "FINEST"?


#log4j
- thread safe?
- performance に最適化
- ALL, TRACE, DEBUG, INFO, WARN, ERROR and FATAL

```java
private static Logger logger = LogManager.getLogger(MyApplication.class);
logger.info(Level.INFO, "it is test for {0}","log");
```

# Slf4j(Simple Logging Facade For Java)
現在PRJで使っているログ
ファサード？　フランス語で。。？外観？



### REF
- https://casualdevelopers.com/tech-tips/how-to-process-java-logging-with-slf4j-logback-lombok/ (日本語)
- https://www.fwantastic.com/2019/12/javautillogging-vs-log4j-vs-slf4j.html (韓国語)
[AWS基礎③] IAM・CloudTrailでアクセス管理（セキュリティ対策）

<h2>初めに</h2>
AWSの基礎について学習しています。
今回、AWSのサービスの１つであるIAMとCloudTrailについて学習したのでまとめていきます。
読みとして、「アイアム」と「クラウドトレイル」です。
どちらもAWSのセキュリティ対策の一種です。

<h2>:fist:通常の作業はIAMユーザーで行った方が良い</h2>
<img width="400" alt="スクリーンショット 2021-09-16 22.19.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/73a033ef-e831-e6d9-ad04-29c63dcb0e52.png">

AWSアカウントを作成するとルートユーザーが作成されますが、
ルートユーザーは色々なことができてしまう（完全なアクセス権を持つ）ため、
通常の作業はIAMユーザーで行うのがベストだそうです。


AWSユーザーと、グループを作成管理でき、
グループごとに操作権限の付与が可能なので、
複数人で作業をする場合にはIAMは必須なんだと思います。

<h3>IAM設定①グループ作成</h3>
注意：詳しい手順は説明してません。

IAMではグループを作成することができ、グループにはポリシーが設定できます。
<img width="400" alt="スクリーンショット 2021-09-16 22.22.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/39aa17a0-9447-2191-d48e-d42f62607f3f.png">
今回はS３の権限のみ付与してみます！試しに！
<img width="400" alt="スクリーンショット 2021-09-16 22.25.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/42fa8911-4e16-6f73-cd7b-e9cb3cdcd226.png">

<h3>IAM設定②ユーザー追加</h3>
グループ作ったらユーザー追加してみます。
<img width="400" alt="スクリーンショット スクリーンショット 2021-09-16 22.29.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/bb78a13e-ce1b-a7ce-ad18-376d83462033.png">

そうするとIAMユーザーとしてサインインできます！

<img width="300" alt="スクリーンショット 2021-09-16 22.31.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/6b471898-9f8f-95d2-f1f6-907e395d1036.png">

<h3>権限ないところにアクセスしてみる！</h3>
このIAMユーザーには権限がないCloudWatchのページに行ってみます。
ページ自体は開けますが、、以下のように、
「権限がない」と表示されます！
![スクリーンショット 2021-09-16 22.32.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/3246fac1-c4ce-a8be-a5c5-a579d6ed4185.png)

<h6>このようにしてAWSを荒らされない、破壊されないようにできるんですね！！</h6>

<h2>:fist:CloudTrailで操作ログを記録する</h2>
いつ誰が何をしたのかを記録してくれるのがCloudTrailです。
こちらはデフォルトで有効になっていますが、保存期間は90日間のみです。
S３（ファイルの置き場）に操作ログを保存することで、
ずっと保存できますが、S3は有料です

AWSアカウントのアクティビティ（活動）を可視化することで、
AWSサービスの不正利用などを監査できます。

<h2>終わり</h2>
今回AWSのセキュリティ対策の一種であるIAMとCloudTrailをまとめてみました。
CCNA　OSI参照モデル

今回はOSI参照モデルについて書いていこうと思います。

通信に関するルールをプロトコルと言います。
これが違うと通信が上手くいきません。
これを役割毎に整理されたプロトコルをプロトコルスタックと言います。
当初、これは自社製品同士でしか使えないプロトコルスタックを作っていました。
これを異なる会社の製品でも使えるようにしたプロトコルスタックを
OSI(Open System Interconnection)参照モデルと言い、
ISO(国際標準化機構)が策定しました。

これはネットワークで必要とされる機能を7つのレイヤに分かれます。
これを階層化と言いまして、メリットとしてはそれぞれの役割を明確にできることと、
変更があっても最小の変化で済むことです。

レイヤ1:物理層　電気信号や機器に関するプロトコル群です。
レイヤ2:データリンク層　隣接ノードに関するプロトコル群です。
レイヤ3:ネットワーク層　エンドツーエンドに関するプロトコル群です。
レイヤ4:トランスポート層　通信における信頼性に関するプロトコル群です。
レイヤ5:セッション層　アプリケーション間の接続に関するプロトコル群です。
レイヤ6:プレゼンテーション層　ユーザが見て触れるデータに関するプロトコル群です。
レイヤ7:アプリケーション層　アプリケーション固有のプロトコル群です。

上のレイヤから下のレイヤにヘッダという制御情報を付与します。
このことをカプセル化と言います。レイヤ2ではトレーラを付けます。
反対を非カプセル化と言います。
それぞれのレイヤでの単位があります。
その中でも特に覚えて欲しいのがレイヤ2.3.4です。
レイヤ4ではセグメント、レイヤ3ではパケット、レイヤ2ではフレームになります。
その単位をPDU(Protocol Data Unit)と言います。

#最後に

自分のアウトプットとして知識を出していますので、分かりにくい点等があると
思いますが、良ければ見て頂けると幸いです。
勉強中の身ですので、もし不明点や間違った点がありましたら是非コメント下さい。
Tezos clientでblock levelごとのoperation数を調べる方法

Tezos のblockごとのoperation情報が知りたかったら RPC interface を使うと調べることができるようだ。

Tezos nodeが動いているサーバー上で例えば次のようなコマンドをするとTezos RPC 機能を使うことができる。

```ocaml
./tezos-client rpc get /chains/main/blocks/1600000/hash
```
```json
"BKmvtKhYPKSniwP6mGNtFrsTU2umW6t6hYoWug7uFBQQboaFsrW"
```

blockごとのoperationのhash一覧は次のパスで取得できる:

```
GET /chains/<chain_id>/blocks/<block_id>/operation_hashes
```

`<chain_id>` は本番環境のmainnetなら `main` でOK。`<block_id>` はブロックレベルで指定することができる。

```sh
./tezos-client rpc get /chains/main/blocks/1600000/operation_hashes
```

なぜかoperationのリストのリストになっているので、数を調べるためにjqで flattenしてから lengthを取る。

```sh
./tezos-client rpc get /chains/main/blocks/1600000/operation_hashes | jq ". | flatten | length"
```
yumコマンド実行時にexcept KeyboardInterrupt, e:とエラー出る場合の対処法

## 事象

EC2 インスタンスに awslogs パッケージをインストールしようとしたらエラーになった。

```
#sudo yum install -y awslogs

  File "/bin/yum", line 30
    except KeyboardInterrupt, e:
                            ^
SyntaxError: invalid syntax
```

## 原因
pythonの3になった際、シンボリックリンクを書き換えてしまったらしい

yumコマンドがpythonで書かれているので、
以下の2つのファイルのスクリプトの先頭行の部分を、python2に修正することで対応する

/usr/bin/yum
/usr/libexec/urlgrabber-ext-down

```
#!/usr/bin/python
```
↓

```
#/usr/bin/python2
```

## 再度awslogs パッケージをインストールコマンド実行
```
#sudo yum install -y awslogs
```

これでyum コマンドでのエラーが解消できているはず。