OmniAICreator/Qiita-1.07M huggingface dataset:
AWS CloudShellでクリスマスツリーを眺めよう

※１発ネタです。

## はじめに（建前）
先日、AWS CloudShellがリリースされました。
マネージメントコンソール上からAWS CLIを使用できるようになったことでCLIに触れるハードルがグンと下がった気がします。
[AWS CloudShell – Command-Line Access to AWS Resources](https://aws.amazon.com/jp/blogs/aws/aws-cloudshell-command-line-access-to-aws-resources/)

少し触ってみたら、（コンソールサービスだけど文字色とかも表現できるのかな？）という疑問が湧いてきたので試してみようと思います。

## （本音）
コロナ禍で気軽にイルミネーションを見に行くこともできないのでコンソールでピカピカ光るクリスマスツリーを見よう！

## 実践！！

### CloudShellコンソールを開く
CloudShellはAWS マネージメントコンソールから使用することができます。

![スクリーンショット 2020-12-17 9.32.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246580/3918a494-2e9d-9f14-6b70-22078fb5bd0d.png)

![スクリーンショット 2020-12-17 9.35.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246580/a9fd6e7b-e602-2cff-332d-c72457484678.png)
開けました。

### クリスマスツリーを見るぞ！！！！！
今回は↓を使用します。
[sergiolepore/ChristBASHTree](https://github.com/sergiolepore/ChristBASHTree)

コマンドを貼り付けて実行します。

```bash
curl https://raw.githubusercontent.com/sergiolepore/ChristBASHTree/master/tree-EN.sh | bash
```

ピカピカのクリスマスツリーを見ることができました。

![Dec-17-2020 09-40-36.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246580/bb7b314c-0220-13dc-4bd2-c163072576ad.gif)

これで今年のクリスマスも家で一人で過ごすことができます。

## おまけ
クラスメソッドさんはSLを走らせています。（ミスリード）
[AWS CloudShellでSLを走らせてみた #reinvent](https://dev.classmethod.jp/articles/sl-on-aws-cloudshell/)
RailsAPIモードをRailsに戻す方法


RailsAPIを構築した時のコマンド

```bash
docker-compose run web rails new . --force --database=mysql --api --skip-bundle
```
これでRailsAPIを生成しました。
↓
通常のRails戻したい。
↓
同じディレクトリで、今度は --apiを引いて、

```bash
docker-compose run web rails new . --force --database=mysql --skip-bundle
```
RailsAPI時に作成したファイルはそのまま残っています。


```ruby:application_controller.rb
- class ApplicationController < ActionController::API
+ class ApplicationController < ActionController::Base
```

```ruby:application.rb
- config.api_only = false
```


あとはdockerで必要なコマンドを実行するだけです。

```
docker-compose build
```
```
docker-compose run web rails db:create
```
```
docker-compose up -d
```

補足
https://shakacode.gitbooks.io/react-on-rails/content/docs/additional-reading/convert-rails-5-api-only-app.html
https://stackoverflow.com/questions/36669981/how-do-you-convert-a-rails-5-api-app-to-a-rails-app-that-can-act-as-both-api-and
CakePHPのルーティング

# ルーティングまとめ

##デフォルトルーティング


デフォルトルートの URL パターン:
`http://example.com/controller/action/param1/param2/param3`


```
（例）

URL: /monkeys/jump
Mapping: MonkeysController->jump();

URL: /products
Mapping: ProductsController->index();

URL: /tasks/view/45
Mapping: TasksController->view(45);

URL: /donations/view/recent/2001
Mapping: DonationsController->view('recent','2001');
```


###名前付きパラメーター
```
URL: /contents/view/chapter:models/sections:assosiations
Mapping: ContentsController->view();

コントローラでの受け取り

$this->passedArgs['chapter'] = 'models';
$this->passedArgs['sections'] = 'associations';

または

$this->params['named']['chapter'] = 'models';
$this->paramas['named']['section'] = 'associations';
```
PostfixでSMTPリレーサーバを構築する

Postfixで、25番ポートで受け取り、サブミッションポート(587)を使用してリレーさせるためのサーバを構築した際の手順をまとめたものです。セキュリティはIP制限で実施する想定であるため、度外視してます。

# 環境

- AMI: Amazon Linux 2 (arm版)
- インスタンス：t4g.micro

EC2のt4g.microインスタンスが、トライアルで無料で利用できたため、こちらを利用しています。Amazon Linux 2では、postfixがデフォルトでインストールされているため、インストール処理は省略します。

# 追加した設定
SMTPリレーを有効にするため、/etc/postfixにある、main.cfを書き換えます。

```plaintext:main.cf

myhostname = xxx.yyyyy.jp
mydomain = yyyyy.jp #送信で利用するドメイン

#postfixで待ち受けるインターフェース
inet_interfaces = all
#inet_interfaces = localhost

#以下の設定を入れないとうまく動作しない環境あり、詳しくは次項で紹介します
local_recipient_maps =

#どの領域からアクセスを受け付けるか
mynetworks_style = subnet
mynetworks = 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16

# transport にあるメールリレー設定を参照するよう transport_maps を追加する
transport_maps = hash:/etc/postfix/transport

# SMTP認証有効
smtp_sasl_auth_enable = yes
# relay_password にある認証情報を参照するよう設定
smtp_sasl_password_maps = hash:/etc/postfix/relay_password
smtp_sasl_security_options = noanonymous

# STARTTLS 有効
smtp_tls_security_level = may

# /var/log/maillog に TLS 関連のログを出力
smtp_tls_loglevel = 1

# TLSで使用するサーバ証明書ファイル
smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt

```

次に、同じ階層のtransportファイルを書き換えます。（デフォルトで入力されているものはすべてコメントになっているため、消してしまっても問題ありません。）

```plaintext:transport
localhost :
localhost.localdomain :
<hostname> :
* smtp:<SMTPサーバ名>:<ポート番号>
```

```<hostname>``` の部分には、hostnameコマンドで出てきた表記を入力します。以下の例の場合は、```ip-172-31-39-242.ap-northeast-1.compute.internal```と記載します。

```
[root@ip-172-31-39-242 postfix]# hostname
ip-172-31-39-242.ap-northeast-1.compute.internal
```

ファイルを保存したら、ハッシュ化が必要であるため、以下のコマンドを打ち込んでください。

```
[root@ip-172-31-39-242 postfix]# postmap /etc/postfix/transport
```

次に、メール送信用の認証情報を設定するため、relay_passwordファイルを作成します。

```plaintext:relay_password
<SMTPサーバ名>:<ポート番号> <アカウント名>:<パスワード>
```

こちらもハッシュ化が必要です。ハッシュ化した後は、元のファイルは削除したほうがセキュリティ的に良いかと思います。

```
[root@ip-172-31-39-242 postfix]# postmap /etc/postfix/relay_password
```

すべて終わったら、postfixを再起動します。対象のSMTPサーバーに対して、メールが送れているのを確認できればOKです。

# 注意点
メールを送信する際のFromの情報を、SMTP認証で使用するアカウントと一致させておかないと、リレー後のサーバで拒否される可能性があるので注意してください。

# local_recipient_mapsについて
local_recipient_mapsの設定を入れずにpostfixを動かしていたところ、一部の環境で以下のエラーが発生しました。

```
Recipient address rejected: User unknown in local recipient table
```

調べたら[こちら][1]の記事が出てきたため、local_recipient_mapsの設定を実施したところうまくいきました。ただ、送信先のドメインが外部ドメインを指定していたため、なぜ現象が発生したのかが不明です。


# 参考にしたサイト
[Postfix で知らないローカルユーザを拒否する][1]
[Postfixによるメールリレー設定][2]

[1]:http://www.postfix-jp.info/trans-2.1/jhtml/LOCAL_RECIPIENT_README.html
[2]:https://smtps.jp/docs/integrate/si/postfix/index.html
Conda内のPythonバージョンが変更できない問題の解決法

# 問題点

Anacondaでpythonのバージョンを3.8.5として環境を作成。
![スクリーンショット 2020-12-17 9.19.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443567/ad756e80-4b9d-a55b-5cae-71d75e30ce9c.png)

だが、condaを実行させるとpythonのバージョンが2.7.16となってしまう。

```
(base) renato@MacBook-Pro ~ % conda activate renatoenv
(renatoenv) renato@MacBook-Pro ~ % python --version
Python 2.7.16
```

# 実行した内容

①Anacondaの再インストール
②pyenvのインストール

①を行っても変化なかったので、記事としては割愛。②を説明します。

## pyenvとは
pythonのバージョンを簡単に切り替えることができるようにしてくれるツールです。２系列と３系列との切り替えに便利です。

## pyenvのインストール
ではまず、 pyenvをインストールしましょう。gitから持ってくる場合上のコマンドを、brewが使える場合は下のコマンドを利用してもできます。

```
$ git clone git://github.com/yyuu/pyenv.git ~/.pyenv
$ brew install pyenv
```

bash_profileの編集
次にpyenvのパスを通すためにbash_profileを編集します。

```
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
```

最後にbash_profileの保存を適用します

```
$ source ~/.bash_profile
```

すると、Pythonのバージョンが変更されました。

```
(base) renato@MacBook-Pro ~ % conda activate renatoenv
(renatoenv) renato@MacBook-Pro ~ % python --version
Python 3.8.5
```

## 参考文献

この記事は以下の情報を参考にして執筆しました。

- [pyenvのインストール、使い方、pythonのバージョン切り替えできない時の対処法](https://qiita.com/koooooo/items/b21d87ffe2b56d0c589b)
チームビルディング挑戦記録（中間報告1回目）

# はじめに
事業会社の開発部に所属するアプリケーションエンジニアが、チームビルディングに挑戦していく記録です。
2019/11頃から取り組んでいることなので、少しずつ投稿していきます。

# チームビルディング
チームビルディングとは、メンバーが主体的に個性や能力を発揮しながら一丸となってゴールを目指すチームになるための取り組み

# なぜやるのか
現状から、課題を記載します。

## 現状
現在働いている組織は、8名体制で行っている。

```
マネージャ　：　１名
　チーム
　　┣チームA：リーダ１名、メンバー2名
　　┣チームB：リーダ１名、メンバー1名
　　┗チームC：リーダ１名、メンバー1名
```

扱っている、プロダクトは６つ、各プロダクトにより言語や手法、オーナーが異なる。
ドキュメントやコミュニケーション方法、開発工程などもチームやプロダクトにより異なる。


## 問題
部内進捗会はあるが、オンスケ・遅延・課題・リスクなど全てにおいて各チームの所感でしかない。
評価指標がなく、事前のリスク潰し込みができていない。
結果、問題が起きたらリスケを繰り返す負のサイクルが生まれている。

# 目的
各チーム、プロダクトをみんなで評価して、改善できるようにする。
そして、ブラックボックスになっている作業を分解し、生産性向上→品質向上を目指す。

# アプローチ記録
1. バックログを有効活用
    - 作業依頼のチケット管理としてでしか利用していなかった。
    - 開発作業や、行っているタスクを全て記載する。
    - そして、マイルストーン、計画を記録する。
    - バックログをベースに進捗確認をする。
2. CI/CDの導入
3. ドキュメント改善
4. チームや働き方に対してブレスト（LeanCoffee）
5. モブプログラミング
6. 部内ルールの設定


# 今後
少しずつ詳細を投稿していきますので、私の記録が誰かのお役に立てればいいなーって思ってます
Go: Cloud Firestore のデータを削除 (Delete)

```go:firestore_delete.go
// ---------------------------------------------------------------
//
//	firestore_delete.go
//
//					Dec/16/2020
//
// ---------------------------------------------------------------
package main
 
import (
	"context"
	"fmt"
	"log"
	"os"
 
	firebase "firebase.google.com/go"
	"google.golang.org/api/option"
)
 
// ---------------------------------------------------------------
func main() {
	fmt.Fprintf (os.Stderr,"*** 開始 ***\n")
	key_in := os.Args[1]
	fmt.Printf ("key_in = %s\n" , key_in)
	// 初期化
	ctx := context.Background()
	sa := option.WithCredentialsFile("./application_default_credentials.json")
	app, err := firebase.NewApp(ctx, nil, sa)
	if err != nil {
		log.Fatalln(err)
	}
 
	client, err := app.Firestore(ctx)
	if err != nil {
		log.Fatalln(err)
	}

_, err = client.Collection("cities").Doc(key_in).Delete(ctx)
if err != nil {
        // Handle any errors in an appropriate way, such as returning them.
        log.Printf("An error has occurred: %s", err)
}
 
	// 切断
	defer client.Close()

	fmt.Fprintf (os.Stderr,"*** 終了 ***\n")
}

// ---------------------------------------------------------------
```

実行コマンド

```bash
project_id="project-dec16-2020"
echo $project_id
export GOOGLE_CLOUD_PROJECT=$project_id
#
go run firestore_delete.go t0923
```
dart2(flutter)でasync関数がFutureを返すってところの仕様確認メモ



https://dart.dev/codelabs/async-await#working-with-futures-async-and-await

![スクリーンショット 2020-12-17 9.00.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16626/e7c68172-d372-5db8-00ad-992f84d24a1d.png)

https://dart.dev/guides/language/specifications/DartLangSpec-v2.2.pdf

> It is a compile-time error if the declared return type of a function marked async is not a supertype of Future<T> for some type T.

> It is a compile-time error if the declared return type of a function marked sync* is not a supertype of Iterable<T> for some type T.

> It is a compile-time error if the declared return type of a function marked async* is not a supertype of Stream<T> for some type T.

> asyncとマークされた関数の宣言された戻り値の型が、ある型Tに対してFuture<T>のスーパータイプではない場合、コンパイル時エラーとなります。

> sync*とマークされた関数の宣言された戻り値の型が、ある種の型Tに対して反復可能<T>のスーパータイプでない場合、コンパイル時エラーとなります。

> async*とマークされた関数の宣言された戻り値の型が、いくつかの型Tに対してStream<T>のスーパータイプではない場合、コンパイル時エラーとなります。



コンパイルエラーになるからそういうもんってことで。



```dart
void main() async {
  final ft1 = timeAfter1();
  print("ft1=$ft1");
  ft1.then((t1) {
    print("t1=$t1");
  });

  final ft2 = timeAfter2a();
  print("ft2=$ft2");
  ft2.then((t2) {
    print("t2=$t2");
  });

  final fft3 = timeAfter3b();
  print("fft3=$fft3");
  fft3.then((ft) {
    print("ft=$ft");
    ft.then((t) {
      print("t=$t");
    });
  });
}

Future<String> timeAfter1() {
  Future<String> ft = Future.delayed(Duration(seconds: 1), () {
    return DateTime.now().toIso8601String();
  });
  return ft;
}

Future<String> timeAfter2a() async {
  String t = DateTime.now().toIso8601String();
  return t; // 返り値の型はFuture<String>だけどreturnしている型はString。自動でFuture<T>にラップされる。
}

/*
Future<String> timeAfter2b() {
  String t = DateTime.now().toIso8601String();
  return t; // asyncつけないともちろんだめ
}
*/

/*
Future<Future<String>> timeAfter3a() async {
  Future<String> ft = Future.delayed(Duration(seconds: 1), () {
    return DateTime.now().toIso8601String();
  });

  return ft; // Future<String> -> Future<Future<String>> のようにラップされることはない。
}
*/

Future<Future<String>> timeAfter3b() async {
  Future<Future<String>> fft = Future.delayed(Duration(seconds: 1), () {
    Future<String> ft = Future.delayed(Duration(seconds: 1), () {
      return DateTime.now().toIso8601String();
    });
    return ft;
  });

  return fft;
}
```

```
% dart dart_async.dart
ft1=Instance of 'Future<String>'
ft2=Instance of 'Future<String>'
fft3=Instance of 'Future<Future<String>>'
t2=2020-12-17T09:03:22.237512
t1=2020-12-17T09:03:23.243016
ft=Instance of 'Future<String>'
t=2020-12-17T09:03:24.256934
```
Go: Cloud Firestore のデータを更新 (Update)

```go:firestore_update.go
// ---------------------------------------------------------------
//
//	firestore_update.go
//
//					Dec/16/2020
//
// ---------------------------------------------------------------
package main
 
import (
	"context"
	"fmt"
	"log"
	"os"
	"strconv"
	"time"
 
	firebase "firebase.google.com/go"
	"google.golang.org/api/option"
)
 
// ---------------------------------------------------------------
func get_current_date_proc () string {
	now := time.Now ()
	fmt.Printf ("%s\t" ,now)
	fmt.Printf ("%d-%d-%d\n" ,now.Year (),now.Month(),now.Day())
	today := strconv.Itoa (now.Year()) + "-" +
		fmt.Sprintf ("%d",now.Month()) + "-" +
		strconv.Itoa (now.Day())

	return	today
}

// ---------------------------------------------------------------
func main() {
	fmt.Fprintf (os.Stderr,"*** 開始 ***\n")
	key_in := os.Args[1]
	population_in,_ := strconv.Atoi (os.Args[2])
	fmt.Printf ("key_in = %s\t" , key_in)
	fmt.Printf ("population_in = %d\n" , population_in)
	// 初期化
	ctx := context.Background()
	sa := option.WithCredentialsFile("./application_default_credentials.json")
	app, err := firebase.NewApp(ctx, nil, sa)
	if err != nil {
		log.Fatalln(err)
	}
 
	client, err := app.Firestore(ctx)
	if err != nil {
		log.Fatalln(err)
	}

dsnap, err := client.Collection("cities").Doc(key_in).Get(ctx)
if err != nil {
        log.Fatalf("Failed : %v", err)
}

mm := dsnap.Data()
fmt.Printf("Document data: %#v\n", mm)

name_aa := dsnap.Data()["name"]

today := get_current_date_proc ()


 _, err = client.Collection("cities").Doc(key_in).Set(ctx, map[string]interface{}{
	"name":  name_aa,
	"population": population_in,
	"date_mod": today,
    })
    if err != nil {
        log.Fatalf("Failed adding alovelace: %v", err)
    }

	// 切断
	defer client.Close()

	fmt.Fprintf (os.Stderr,"*** 終了 ***\n")
}

// ---------------------------------------------------------------
```

実行コマンド

```bash
project_id="project-dec16-2020"
echo $project_id
export GOOGLE_CLOUD_PROJECT=$project_id
#
go run firestore_update.go t0926 5134900
```
Go: Cloud Firestore のデータを読む (Read)

```go:firestore_read.go
// ---------------------------------------------------------------
//	firestore_read.go
//
//					Dec/16/2020
//
// ---------------------------------------------------------------
package main
 
import (
	"context"
	"fmt"
	"log"
	"os"
	"strconv"
 
	firebase "firebase.google.com/go"
	"google.golang.org/api/iterator"
	"google.golang.org/api/option"
)
 
// ---------------------------------------------------------------
func main() {
	fmt.Fprintf (os.Stderr,"*** 開始 ***\n")
	// 初期化
	ctx := context.Background()
	sa := option.WithCredentialsFile("./application_default_credentials.json")
	app, err := firebase.NewApp(ctx, nil, sa)
	if err != nil {
		log.Fatalln(err)
	}
 
	client, err := app.Firestore(ctx)
	if err != nil {
		log.Fatalln(err)
	}
 
	// データ読み取り
	iter := client.Collection("cities").Documents(ctx)
	for {
		doc, err := iter.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			log.Fatalf("Failed to iterate: %v", err)
		}
//		fmt.Println(doc.Ref.ID)
//		fmt.Println(doc.Data())
		fmt.Printf("%s\t",doc.Ref.ID)
		fmt.Printf("%s\t",doc.Data()["name"])
		population := doc.Data()["population"].(int64)
		str_population := strconv.FormatInt(population,10)
		fmt.Printf("%s\t",str_population)
		fmt.Println(doc.Data()["date_mod"])
	}
 
	// 切断
	defer client.Close()

	fmt.Fprintf (os.Stderr,"*** 終了 ***\n")
}

// ---------------------------------------------------------------

実行コマンド

```bash
project_id="project-dec16-2020"
echo $project_id
export GOOGLE_CLOUD_PROJECT=$project_id
#
go run firestore_read.go
```
Go: Cloud Firestore のデータを作成 (Create)

ライブラリーのインストール

```text
go get firebase.google.com/go
```

```go:firestore_create.go
// ---------------------------------------------------------------
//
//	firestore_create.go
//
//					Dec/16/2020
//
// ---------------------------------------------------------------
package main
 
import (
	"context"
	"fmt"
	"log"
	"os"
	"reflect"

	"cloud.google.com/go/firestore" 
	firebase "firebase.google.com/go"
	"google.golang.org/api/option"
)

// ---------------------------------------------------------------
func data_set_proc(client *firestore.Client,ctx context.Context,
	key_in string, name_in string, population_in int, date_mod string) {
 _, err := client.Collection("cities").Doc(key_in).Set(ctx, map[string]interface{}{
	"name":  name_in,
	"population": population_in,
	"date_mod": date_mod,
    })
    if err != nil {
        log.Fatalf("Failed adding alovelace: %v", err)
    }

}

// ---------------------------------------------------------------
func main() {
	fmt.Fprintf (os.Stderr,"*** 開始 ***\n")
	// 初期化
	ctx := context.Background()
	sa := option.WithCredentialsFile("./application_default_credentials.json")
	app, err := firebase.NewApp(ctx, nil, sa)
	if err != nil {
		log.Fatalln(err)
	}
 
	client, err := app.Firestore(ctx)
	if err != nil {
		log.Fatalln(err)
	}

	fmt.Printf("%T\n", client)
	fmt.Printf("%T\n", ctx)

	fmt.Println(reflect.TypeOf(client))
	fmt.Println(reflect.TypeOf(ctx))

	data_set_proc(client,ctx,"t0921","宇都宮",49572,"1921-7-19")
	data_set_proc(client,ctx,"t0922","小山",63452,"1921-7-19")
	data_set_proc(client,ctx,"t0923","佐野",63452,"1921-7-19")
	data_set_proc(client,ctx,"t0924","足利",63452,"1921-7-19")
	data_set_proc(client,ctx,"t0925","日光",63452,"1921-7-19")
	data_set_proc(client,ctx,"t0926","下野",41528,"1921-7-19")

	// 切断
	defer client.Close()

	fmt.Fprintf (os.Stderr,"*** 終了 ***\n")
}

// ---------------------------------------------------------------
```

実行コマンド

```bash
project_id="project-dec16-2020"
echo $project_id
export GOOGLE_CLOUD_PROJECT=$project_id
#
go run firestore_create.go
```
よく聞くEBSってなに？

## 勉強前イメージ

EC2インスタンス作るときにストレージになるやつ
SSDタイプとかHDDタイプとかあった気がする。
あんまり意識して見たことはなかった

## 調査

### Amazon EBS とは？

Amazon Elastic Block Store の略で、
EC2インスタンスにアタッチして使われるAWSのストレージサービスになります。

### EBSの特徴

- 高い可用性

EBSボリュームは 99.999% の可用性を持つように設定されています。
1年間使用したとして、5分15秒の停止まで許容するという数字になっています。

- ディスクサイズが2タイプ存在する

SSDタイプとHDDタイプの2種類が存在します。
使用するシステムによってEBSを適するタイプに変更することが出来ます。

- DLMでのスケジューリングされたスナップショットの作成

データサイクルマネージャーを使用して、EBSのスナップショットをスケジューリングして自動で撮ることが出来ます。
自分自身でデータのバックアップや保存期間を設定でき、ポリシーに沿ったバックアップを行うことが出来ます。

### EC2とどう違うの？

EC2とEBSは以下のような関係性です。

- EC2 : 仮想サーバ
- EBS : HDD

なので、作成したEC2インスタンスにはEBSがアタッチされています。

下記はEC2インスタンスのストレージを表示させたものです。
ルートデバイスタイプにはEBSと記載され、下にはアタッチされたボリュームが記載されています。

![無題 - ペイント 2020-12-15 22.37.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/ab1dca22-d3d4-83bf-f564-a19c39ec4465.png)

### EBSのコンソールはどこにあるの？

EC2のコンソールの左の欄をみると `Elastic Block Store` があり、これがEBSのコンソールになります。

![EBSインスタンス _ EC2 Management Console - Google Chrome 20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/bb46daf0-69fb-5ec0-dc89-7298cc0ab4f1.png)

### EBSボリュームの種類

EBSのリュームの種類は以下の4種類あります。

- 汎用 SSD (gp2)
- プロビジョンド IOPS SSD (io1)
- スループット最適化 HDD (st1)
- Cold HDD (sc1)

#### 汎用 SSD (gp2)

Amazon EC2インスタンスが利用するデフォルトのEBSボリュームで、
コストと性能のバランスがよく、開発環境やテスト環境など幅広い用途に利用されています

#### プロビジョンド IOPS SSD (io1)

高いパフォーマンスを提供するEBSストレージです。
アクセス頻度が高く、ディスクI/Oが多くなるデータベースやアプリケーションなどに適しています。
他の種類のボリュームに比べて費用は割高に設定されています。

#### スループット最適化 HDD (st1)

高速なHDDを基盤としており、安定したスループットを必要とするシステムに適しているボリュームです。
ログ管理やビッグデータ向けのデータストアなどアクセス頻度が高いシステムに適しています。

#### Cold HDD (sc1)

EBSボリュームタイプの中でも低コストなボリュームになります。
SSDより大容量のデータの保存に適しているため、バックアップやアクセス頻度の少ないものに向いています。
ただし、EC2インスタンスのブートボリュームには設定できません。

## 勉強後イメージ

イメージ合ってたけど、4種類もあるって知らなかった...
デフォルトのやつしか触ったことないかも...変更したことないし。。
高アクセスとかされるもの作るんだったら変更した方が良さそう。

## 参考

- [Amazon EBS](https://qiita.com/leomaro7/items/0134935bb916f508da52)
- [AWS EBSとは？8つの特徴とEBSボリュームについても解説](https://www.fenet.jp/aws/column/aws-beginner/33/)
- [ブロックストレージサービスとは？Amazon Elastic Block Store (EBS)を紹介](https://business.ntt-east.co.jp/content/cloudsolution/column-67.html)
- [Amazon EBS (Elastic Block Store)とは？ブロックストレージの特徴と共に紹介！](https://www.acrovision.jp/service/aws/?p=2472)
prometheus のPV使用量に異常なオーバーヘッドがあるとき


## 症状

画像のように、PrometheusのPV使用量に異常なオーバーヘッドが確認されました。
起動時で70GBほど消費しています。

prometheus version: 2.18.2

![Inkedimage_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221423/5d191819-22b8-84e0-88eb-1fa3583f7005.jpeg)

## 原因

kubectl exec でprometheus containerに入ってみると、

```bash
k exec -it prometheus-kube-prometheus-stack-prometheus-0 -n monitoring -c prometheus sh
```

`01EN4ZAY5H2KD172GTD9X7JJC3.tmp` のようなディレクトリがたくさんありました。
作成された日付を見てみると、明らかに設定した retention date を過ぎていました。

消してみると、下記のようにPV使用量は低下し、妥当な数値になりました。

![pv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221423/5430a615-b8f2-5ec1-12b8-50132866f4a4.png)

## これはいったい何？

調べてみると、この `.tmp` というディレクトリはメトリクスの圧縮やretentionが上手く行かなかった際にできると報告されています。

Issue: https://github.com/prometheus/prometheus/issues/8180

> We face TSDB storage filling up because of .tmp directories that are left. We understand that these tmp directories result from failed compaction or retention, but even though the Prometheus pods are healthy the left tmp dirs are not rotated / removed at any time later.

実質的な要因はメモリ不足だと。

> The actual issue is that Prometheus did not have enough memory.

そういえばメモリ不足で何回か落ちたな :thinking:

どうやら8月中旬のバージョン2.21で、起動時に自動的に`.tmp`ディレクトリを削除してくれる機能がマージされたみたいです。

PR: https://github.com/prometheus/prometheus/pull/7772

それ以前のバージョンサポートの話が続いているのか、Issue status は未だ Openですね。

ということで、取り急ぎprometheus更新せねば！
特定のcolumn 以外を一括でコピーする

##list(df_b.columns[~df_b.columns.isin(["val4","val5"]) ]) でval4,val5以外の全ての列を選択出来ます。
#テストデータ
```python
import pandas as pd

a={"idx" :[10,20,30],
   "val1":[11,12,13]}
b={"idx" :[10,20,30],
   "val2":[21,22,23],
   "val3":[31,32,33],
   "val4":[41,42,43],
   "val5":[51,52,53],
   }

df_a=pd.DataFrame(a)
df_a.set_index(["idx"],inplace=True)

df_b=pd.DataFrame(b)
df_b.set_index(["idx"],inplace=True)
print(df_a.to_markdown()) 
print(df_b.to_markdown()) 
```
df_a

|   idx |   val1 |
|------:|-------:|
|    10 |     11 |
|    20 |     12 |
|    30 |     13 |

df_b

|   idx |   val2 |   val3 |   val4 |   val5 |
|------:|-------:|-------:|-------:|-------:|
|    10 |     21 |     31 |     41 |     51 |
|    20 |     22 |     32 |     42 |     52 |
|    30 |     23 |     33 |     43 |     53 |

#コピー(val4、Va15以外)
```python
cols=list(df_b.columns[~df_b.columns.isin(["val4","val5"]) ])
df_a[cols]=df_b[cols]
print(df_a.to_markdown()) 
```
df_a

|   idx |   val1 |   val2 |   val3 |
|------:|-------:|-------:|-------:|
|    10 |     11 |     21 |     31 |
|    20 |     12 |     22 |     32 |
|    30 |     13 |     23 |     33 |
【Stereo Depth】SegStereo : Semantic Segmentaionもwarpしてlossを計算

<h1>SegStereo: Exploiting Semantic Information for Disparity Estimation</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/ad95269d-b0c4-c66b-90d6-66c8b3a3e29d.png)

今までSemantic SegmentationをDepthの推定に使う事でEdge周辺のDisparityの推定精度をあげる事などが行われてきた。

この論文では右のSemantic Segmentationの推定の結果をDisparityを用いることで左のSemantic Segmentationにwarpする。左のSemantic SegmentationのGround Truthと比較する事でLsegを計算する事が出来る。


この手法のメリットはDisparityのErrorを色の違い(Photometric Loss)以外にもClassの違いを計算出来る事で多様化している事。


<h1>結論</h1>
・DisparityにSemantic Segmentaionを使う場合には試してみたい

<h1>参考文献</h1>
SegStereo: Exploiting Semantic Information for Disparity Estimation
https://arxiv.org/pdf/1807.11699.pdf
MySQLが起動しなくなったときの対処法まとめ

#MySQLが起動しなくなったときの対処法まとめ

###使用環境
windows 10 Home(COREi7)
XAMPP 7.3.18

##背景
いつも通りに開発を行おうとしたところ、突如としてMySQLが起動しなくなってしまった。いろいろ解決方法を探すも解決には至らず再インストールすることに...最終手段の再インストールに至るまでに試したことをまとめる。
出たエラーはこちら。よくあることらしい。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615830/0b030465-5635-590b-8426-c2d147eced55.png)

エラー文以下

Error: MySQL shutdown unexpectedly.
This may be due to a blocked port, missing dependencies, 
improper privileges, a crash, or a shutdown by another method. Press the Logs button to view error logs and check the Windows Event Viewer for more clues If you need more help, copy and post this entire log window on the forums

##試したこと
* Apacheの再起動
* PC再起動
* ポートの競合確認
* エラーログ確認
* 異常があった際に発生するごみファイルib_***ファイルの削除
* ```C:\xampp\mysql\data```内のデータをbackup内のデータに上書き
* ユーザー認証を飛ばしてMySQLを起動

###Apacheの再起動
とりあえずやってみた。
**まるで意味なし**

###PC再起動
こちらもとりあえずやってみた。
**同じく意味なし**

###ポートの競合確認
まずはポートが競合している可能性を考え、ポートの確認。

XAMPP右欄のNetstatをクリックする。
こんな感じで一覧が表示されるので被っているポートがないか確認。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615830/ed49c061-22c8-63d1-3551-a400e13e3117.png)


**結果、競合するものはなかった**

###エラーログ確認
MySQLのLogsからmysql_error.logを開き、エラーが出ていないか確認。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615830/f965e4c4-db3e-f98c-6604-94f6a0f69408.png)
**結果、特にエラーログは記述されていなかった。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615830/3adad756-3ef5-9fe0-c332-3f3672508fc1.png)

###異常があった際に発生するごみファイルib_***ファイルの削除
ごみファイルとされるものが邪魔している可能性があることから```C:\xampp\mysql\data```内のib_logfile0とかib_logfile1みたいなファイルを削除。

[XAMPPでMySQLが起動しないときにすべきこと(参考)](https://rishuntrading.co.jp/archives/blog/20201005)
**結果、MySQLは起動できず**

###```C:\xampp\mysql\data```内のデータをbackup内のデータに上書き

```C:\xampp\mysql\data```内の次のフォルダ```mysql, performance_schema, phpmyadmin, test```をどこかにコピーしておいて、backupフォルダから同じフォルダをコピーしてくる。

[xamppのMySQLがshutdownエラーで起動できない、タスクキルでもport変えても直らないのをようやく解決できた話](https://y-a-d.hatenablog.jp/entry/2020/01/28/183000)
**結果、MySQLは起動せず**

###ユーザー認証を飛ばしてMySQLを起動
ユーザー認証のユーザーテーブル自体が壊れている可能性を考え(という風に教えていただき)ユーザー認証をスキップして起動する方法をとる

```C:\xampp\mysql\bin``` フォルダ内のmy.iniを開き、[mysqld]の欄に```skip-grant-tables``` の一文を加える。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615830/3acaaff3-4dd1-2364-7cb3-2b38bc6d90e2.png)
**結果、MySQLは起動せず...**

**恐らくできる限りの対処は尽くした...！
が、MySQLは起動してくれない。
諦めてXAMPPの再インストールをしようと思う**
SalesforceからLineworksに通知を送ろうと思った話（構築編）

# SalesforceからLineworksに通知を送信する
Salesforceで承認プロセスを作るにあたり、その通知をメールだけではなく、Lineworksにも送りたいと思ったので、その時に参考にした情報を記載していきます。

## 設計概要
すごくざっくりした概要図ですが、こんな感じで構築することにしました。
![SFtoLW通知.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912424/e0e298c9-d108-16a8-d511-97eb19a2fd67.jpeg)

## 進め方
ネットで調べたら以前TerakoyaforceでLineworks連携の紹介をしていたのでこちらの記事を参考にして構築しました。
https://terakoyaforce.connpass.com/event/106960/

2年前の記事なので手順書通り進めるといくつかうまくいかないケースに当たります。
そこでSalesforceでデバッグログを有効にして、出力されたログを見ながら修正していきます。
Lineworksの[APIリファレンス](https://developers.worksmobile.com/jp/document/1005002?lang=ja)を参考にしながらトークBotの登録から、メッセージ送信のRequest URLや、Requestのパラメータ、Responseの処理を修正していきます。

その過程で今後の機能改修に必要な知識も入ってくるので直し切ってしまうことをおススメします。

バグだけ潰せばいいなら、以下を修正すればうまくいきます。

``` LW_Utils.cls
//19行目
//public static String LW_REGIST_BOT_TENANT_URI = 'https://apis.worksmobile.com/'+ API_ID+'/message/registerBot/v4';
public static String LW_REGIST_BOT_TENANT_URI = 'https://apis.worksmobile.com/r/'+ API_ID+'/message/v1/bot';
```

```LW_BotEntryController.cls
//30行目
//bots.put('managerList', manageUser);
bots.put('managers', manageUser); 

//45行目
//if( (Integer)botRes.getStatusCode() != 200 ){
if( (Integer)botRes.getStatusCode() != 200 ){
```

実装が終わると、SalesforceのChatterにメンション付きで投稿されるとこんな感じでLineworksにも通知がされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912424/0403fe7e-7b9b-9cbb-dd72-0e884c9e7a35.png)
※今回は承認プロセスから、Chatter投稿しているので、その承認リンクが送信されるように別途設定しています。

## 実装後フロー図
最終的にはこんな感じの動作になりました。
例外処理は実際はもっと多いですが全体像だけ。
![描画1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912424/f45d843d-31c1-2d6a-cc1b-b9bb250fe4d2.png)

## 最後に
この話にはオチがあります…
ぜひこちらの記事もご覧ください！
https://note.com/iitsuki/n/n616afab7556b
Google IMEで顔文字の絵文字を変換で出さないようにする

標準設定だと、機種依存文字というのが出てしまい一部のツールで入力をするときに不具合が発生する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213689/4dafb29f-1c9e-926c-f2a2-1a161f90c1a5.png)

顔文字の機種依存文字を出さなくする方法

1.GoogleIMEのプロパティを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213689/510b0c7e-3511-1b7b-3bde-b035baef369c.png)

2.「辞書」タブで「絵文字変換」のチェックを外します。
　　はずしたら適用、OKを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213689/8c12068a-3e40-f7f4-2db1-e78f27fdbb69.png)



3.でなくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213689/e276516a-afd1-fa5d-bbf4-978298f8a8e9.png)
※メモ帳などで「かお」で変換して試してください。

意外と簡単だった。
迷惑機能なので、標準からは外してほしいですよGoogleさん。
（無料で利用してる立場としては発言権もないのかもしれません。）
Slackのwebhookにエラーログに特定の文字が含まれるかを送るスクリプト

健忘録的メモ。ここでは、 `cron_daily.log` にエラーがerrという文字列が含まれるかを確認して先頭100バイトをcurlでslackのwebhookに送っている。 `head -c 100` がないとcurlが失敗するので要注意。チャンネル名やwebhookのURLはダミー。

```sh
#!/bin/bash

ERROR_CONTENT=`cat cron_daily.log | grep -i err | head -c 100`
ERROR_BYTE=`echo $ERROR_CONTENT | wc -c`

echo $ERROR_BYTE

if [ $ERROR_BYTE -gt 1 ]; then
  echo "エラーがありました。"
  curl -X POST --data-urlencode "payload={\"channel\": \"#sifue_bot_dev\", \"username\": \"botのエラー報告\", \"text\": \"$ERROR_CONTENT\", \"icon_emoji\": \":exclamation:\"}" https://hooks.slack.com/services/T99999999/B99999999/xxxxxxxxxxxxxxxx
else
  echo "エラーはありませんでした。"
fi
```

これをcrontab -eとかで

```
0 7 * * * /home/sifue/cron_daily_log_report.sh
```

こんな感じでcronを仕込んでおけば毎朝7時にログにエラーがあったかを報告してくれる。便利。
3.React公式ドキュメント ~React 要素を DOM に変換するとは？~

まだ記事は未完成です。。

#要素のレンダー
要素とは React アプリケーションの最小単位の構成ブロックです。

要素は画面上に表示したいものの説明書きです：

```typescript

const element = <h1>Hello, world</h1>;
```

ブラウザの DOM 要素とは異なり、React 要素はプレーンなオブジェクトであり、安価に作成できます。React DOM が React 要素に合致するように DOM を更新する作業を担当します。

##要素を DOM として描画する


HTML ファイルの中に <div> 要素があったとしましょう：

<div id="root"></div>
この中にあるもの全てが React DOM によって管理されることになるので、“ルート” DOM ノードと呼ぶことにしましょう。

React だけで構築されたアプリケーションは、通常ルート DOM ノードをひとつだけ持ちます。既存のアプリに React を統合しようとしている場合は、独立したルート DOM ノードを好きなだけ持つことができます。

React 要素をルート DOM ノードにレンダーするには、その 2 つを ReactDOM.render() に渡します：

```typescript

const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));
```

このコードはページに “Hello, world” を表示します。


##レンダーされた要素の更新
React 要素はイミュータブル(不変)です。
※※一度要素を作成すると、その子要素もしくは属性を変更することはできません。
要素は映画の中のひとつのフレームのようなものであり、それは特定のある時点の UI を表します。

ここまでで分かる通り、UI を更新する唯一の方法は、
新しい要素を作成して ReactDOM.render() に渡すことです。


以下の秒刻みで動く時計の例について考えます：

```typescript

function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(element, document.getElementById('root'));
}

setInterval(tick, 1000);
```

上記のコードでは setInterval() のコールバックから ReactDOM.render() を毎秒呼び出しています。


補足:
実際には大抵の React アプリケーションは
 ReactDOM.render() を一度しか呼び出しません。



#React は必要な箇所のみを更新する




#DOMとは？
##DOM

「HTML や XML 文書を操作するための、たくさんの機能や規則のこと。」
つまり、DOMとは、機能や規則の集合体であり、シンプルに、～という規則である、とか、～の機能という類のものではなくて、様々な取り決めが詰まっているものです。

##DOMの分類
>Core DOM：すべてのドキュメントタイプの基本となるモデル
XML DOM：XMLドキュメントの基本となるモデル
HTML DOM：HTMLドキュメントの基本となるモデル



うHTML DOMが定義しているものを列挙します。他も２つも概念的には同じで、操作する対象が変わるだけです。

HTML要素をオブジェクトとして表現する
全てのHTML要素のプロパティ
全てのHTML要素にアクセスしうるためのメソッド
全てのHTML要素のためのイベント


というように、DOMが定義しているものは広範囲に渡りますが、一文で上記の定義を言い換えると下記のようになります。

「HTML DOMとは、HTML要素を取得したり、変更したり、挿入したり、削除したりするための基準である。」
2.React公式ドキュメント ~必須なJSXの知識~


#JSX の導入
```
const element = <h1>Hello, world!</h1>;
```

このおかしなタグ構文は文字列でも HTML でもありません。
これは JSX と呼ばれる JavaScript の構文の拡張です。


JSXはJavaScript の機能を全て備えたもので
UI がどのような見た目かを記述するために使用されます。


JSX は React “要素” を生成します。
次の記事で 『React 要素を DOM に変換する方法』について書きます。
＞

以下では、JSX を使い始めるのに必要な基礎を学びましょう。




#前置き：JSXを使う理由
表示のためのロジックは、
>・イベントへの応答や経時的な状態の変化、
・画面表示のためのデータを準備する方法

といった、他の UI ロジックと本質的に結合したものであり、
React はその事実を受け入れます。

マークアップとロジックを別々のファイルに書いて人為的に技術を分離するのではなく、
React はマークアップとロジックを両方含む疎結合の「コンポーネント」という単位を用いて関心を分離します。

現時点で JavaScript にマークアップを書くことが気にくわない場合、
こちらの議論で考えが改まるかもしれません。


React で JSX を使うことは必須ではありませんが、
ほとんどの人は JavaScript コード中で UI を扱う際に、
JSX を見た目に有用なものだと感じています。
また、JSX があるために
 React は有用なエラーや警告をより多く表示することができます。






JSX はインジェクション攻撃を防ぐ
JSX にユーザの入力を埋め込むことは安全です：

```typescript

const title = response.potentiallyMaliciousInput;
// This is safe:
const element = <h1>{title}</h1>;
```

デフォルトでは、React DOM は JSX に埋め込まれた値をレンダー前にエスケープします。
このため、自分のアプリケーションで明示的に書かれたものではないあらゆるコードは、注入できないことが保証されます。

レンダーの前に全てが文字列に変換されます。
これは XSS (cross-site-scripting) 攻撃の防止に役立ちます。



>ヒント:
利用したいエディタで “Babel” 言語定義を使用して、ES6 と JSX が適切にハイライトされるようにしておくことをお勧めしま
す。
1.React公式ドキュメント

公式ドキュメント：https://reactjs.org/



#Reactのいいところ
・既存のプロジェクトに徐々に追加していけるようなデザイン
・一度学習すれば、どこでも使える（新しい機能を追加する際に、既存のソースコードを書き換える必要はなし）
・React は HTML ページにすぐに追加可能（ビルドツールは必要なし）


##もし、React の公式ドキュメントのペースが早すぎる時は？
Tania Rascia 氏によって書かれた React の概要を読もう。
https://www.taniarascia.com/getting-started-with-react/

#JavaScript 資料
React の公式ドキュメントはあなたがある程度 JavaScript について知っていることが前提。

JavaScript の達人である必要は全くないが、
JavaScript と React を同時に習得するのは難しい

どれだけ知っているかを知るために
以下の概要を30~1時間ほど読んでおきましょう。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript



>ヒント
もし JavaScript で何か詰まった時は、
・MDN 
https://developer.mozilla.org/en-US/docs/Web/JavaScript

>・javascript.info 
https://javascript.info/
を確認すると良い。


#実践チュートリアル
実際に手を動かしながら学びたい人はチュートリアルから。
https://ja.reactjs.org/tutorial/tutorial.html
三目並べゲームを作成しますが、興味が無い方は飛ばそうと思うかもしれません。
ですが、試してみてください。
ここで学ぶテクニックは全ての React アプリの基礎となることであり、
習得することで React に関する深い理解が得られます。




#一歩づつ進めるためのガイド
コンセプトからひとつひとつ学んでいきたい人はこちらのガイドから。
https://ja.reactjs.org/docs/hello-world.html

のガイドは章ごとに分かれていて、
各章がそれまでに習ったことを上乗せする知識となっているため、
余すことなく学ぶことができます。




#React 的な考え方
多くの React のユーザは 「React の流儀」を読んだ時に 
React についてピンときたと高く評価しています。

この世に存在する一番古い React に関する資料ですが、
今でも現役で使えます。
【React の流儀】https://ja.reactjs.org/docs/thinking-in-react.html


#用語集
ドキュメントにてよく使われる単語等が記載されています。
https://ja.reactjs.org/docs/glossary.html


#最新の情報を追いたい人へ
■React ブログ：https://ja.reactjs.org/blog/2020/10/20/react-v17.html

React チームからのアップデートが記載されている公式ブログです。
リリースノートや機能の非推奨化の告知など、
何か大事な発表がある時にはこのブログに真っ先に記載されます。


■ツイッターアカウント：@reactjs 
公式ブログを追っていれば大事なことを見落とすことはない
railsTutorial AWS Cloud9 空き容量不足 ターミナルが動作しない時の解決方法


##はじめに
railsTutorialを進めていく途中で空き容量不足になりました
エラー文でググってみるとrailsチュートリアルの途中で自分のように

容量不足によりIDEが動作しない。エラー文は以下
*Your environment is running out of disk space. Please free up space or resize your EBS volume
can't create socket: No space left on device*
↓
railsチュートリアルの「困った時のヒント集」を参照し、EBS Volumeを増加する
↓
AWS上でvolumeを増加させても、パーティションの拡張は勝手に行ってくれないので、
ターミナルからコマンドでパーティション拡張させないといけない。
しかし、IDEを開いてもターミナルがうんともすんともいわず、コマンド入力ができない

このように困っている人がいくつかいました

調べても技術的解決方法はヒットせず、しょうがないので備忘として解決方法を残します。
やってることは単純なので残す必要があるかどうか微妙ですが、どなたかの解決に役立てれば幸いです。
もしもっとしっかりした解決方法があればコメントで教えてください。


※当方法以外にも下記のようにワークスペースを作り直す方法があります。
安全に行いたい方、当方法でできなかった場合は作り直しを行ってみてください
[cloud9でgit cloneしrailsチュートリアルを再開する流れ](https://qiita.com/saya9875/items/f6e9eca646db7e3fec47) 


##①sample_appバックアップ
トグルツリーにあるsample_appディレクトリを右クリックし、[Download]をクリック
sample_app.zipがダウンロードされます。

##②sample_app削除
sample_appを右クリックし、[delete]をクリック

##③IDE更新
約150MB程度のディレクトリが削除されたことにより、
サイトを更新もしくはインスタンスを再起動することで通常通りIDEが起動、
すなわちターミナルが使用できるようになるはずです。
(ディレクトリ削除してもxvda1のファイル占有が100%であればできないかもしれないです）


```
$ df -h
..
/dev/xvda1      9.7G  9.5G  187M  99% /
```


##④パーティションザイズ拡張
あとはrailsチュートリアルのヘルプ通りに

```
$ sudo growpart /dev/xvda 1
$ sudo resize2fs /dev/xvda1
```

を実行すれば、パーティション及びファイルシステムのサイズが拡張したサイズに変わっていると思います。
(自分は20GBにしました。)

```
$ df -h
..
/dev/xvda1       20G  9.5G  9.9G  49% /
```


##⑤sample_appアップロード
①でバックアップをとっていたsample_app.zipを解凍し
トグルツリーに元あった場所にドラッグアンドドロップでアップロードします。
(追記:ファイル解凍してからアップするとアップロードに膨大な時間がかかるため、
zipファイルのままアップロードしたのち、下記コマンドで解凍するほうが手っ取り早いです。）

```
$ unzip sample_app.zip
```

以上となります。






----
また、なぜ100数MB程度のアプリケーションファイルでファイルがいっぱいになるかは
ログファイルなどが影響しているようです。

[ディスク空き容量が不足してきた件](https://www.souichi.club/aws/out-of-disk-space/)

logファイルなどを削除することで空きをつくることができそうです。
「分かる」が増えると「分からない」が増えるのは『当たり前』のこと

#「分かる」が増えると「分からない」は増える
「分からない」は自然なので怖くない
	この「分からない」領域の外側にある部分は「想像不能領域」だと思っています。
想像不能領域も「分からない」ではあるんですが、
まずうまく知覚できないので領域の広さを自分で把握することができません。

なので最初は100くらいの広さかな？と思っていたけど、後から分かってみたら2359283759832473929352328くらいの広さがあったことに気付いたりします。なので分かる前からあまり深く考えてもしょうがない領域になります。

想像不能領域にある「分からない」であってもアプローチの方法さえ把握しておけばそんなに怖がる必要はない と思うようになりました。


#想像不能領域の「分からない」であっても、アプローチ方法さえ分かっておけばそんなに怖くない
##1.ゴールが分かっている場合
![e9517136e0f86224717ac085c7a5c026.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684145/9e2f7653-ae9f-6113-7617-3c7e31ddc354.png)

###A. 先駆者や類似物を調査する
![479411c248020494d49b1c23f5f941db.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684145/aae3e9cd-0031-5e86-5c80-961031f4e72c.png)

###B. 仮説検証を繰り返す
![b5ff6e1e3123d2ffe953d3a639cbf709.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684145/34b507c6-0fd9-0095-9f60-cf48c63b6fe7.png)

ただし、 想像不能領域にあるゴールは実現できるかも分からないので、仮説検証を繰り返しても辿り着けない場合もあります。 その時は「できないことが分かった」と諦めるか、新たなアプローチの探索などが必要になると思います。

このプロセスで何より大事なのは、想像不能領域にあるゴールはやってみる前からどれくらい大変なのか分からないし、それが実現できるかも分からないということを認識しておくことだと思います。
##2. ゴールが分かっていない場合 
いちばん大変な「分からない」で、クリエイティブパワーが最も必要な過程だと思います。
![1523c895beb4e104bd2776a077a3e603.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684145/be6dbd4b-ef2b-d26b-feb9-ade04c85653c.png)



#「分からない」を理解するカギは「共感」
何かを見るとき、何かを読むとき、何かを聴くとき、誰かと話すとき、誰かの話を聞くとき。どんな時でも「あれ？これどうなってるんだろう」と思うタイミングはそこかしこにあるはずです。そうしたあらゆる場面で何かを理解する際に最も重要なのが 相手の立場に立って考えて共感しようとすること だと思います。


#コードをかくときにいしきしてほしいこと
https://qiita.com/11295/items/23a5338a0ef26d3dca9a
結論：1メソッド(or関数)に1機能を意識



#そんなちょこっと先輩エンジニアからおすすめツールの紹介
「同時編集出来るツール(GoogleDocs等)で議事録を取り
それを先輩にリアルタイムレビューしていただくことで、
MTGにおける誤解を防いだり議事録のとり方を向上させる」や

「開発にのめり込んで他タスクをスルーしないようにリマインダーを設定する」など、
ツールやテクニックを試しながら仕事を行うといいよ！！
https://qiita.com/testMenta339/items/e8dcaab3fe5a7178c129
【TypeScript】のコ↑コ↓がイイ！！

#長期運用するならTypeScript!
長期にわたってメンテナンスしたいプロジェクトで作業するのなら、TypeScriptで書くべきです。
TypeScriptではコードを書いている間に何が間違っているのかを教えてくれます。
TypeScriptはコードベース全体の自己ドキュメント化を支援し、コードリーディングの体験を改善します。TypeScriptは開発者がお互いのコードを理解しやすくするのに役立ちます。

#自動テストにおいて
https://qiita.com/Yametaro/items/2eaa6fd75255c8c2a2bb

「JSのプログラムも自動テストが用意されとるからな」
「想定通りの挙動をせん場合はコミットできひんねや」
「ワイのようなザコーダーがウンコミットをせんように、」
「ちゃんとシステムがチェックしてくれるんやな」
「要は、変なコードを書くとコミットすらできへんいうことや」

ちょっと面倒くさいでんな・・・」
「いやいや、ちゃうで」
「コミット前に必ずテストが走ることで、防げる事故が沢山あんねん」
「例えば」
「新しい機能を追加したことによって逆に以前からある機能がバグってしまったり」
「そういう事故を最小限に抑えられんねん」
「デグレ1が起こらん事を自動テストが保証してくれるおかげで」
以前した不具合やバグが再発・復活すること。 ?
「思いっきり追加機能のプログラミングに集中できる言うことや」

自動テストで、ザコーダーによるウンコミットが防止されてたりする


#エディタ面
■設定便利vscide
https://qiita.com/Yametaro/items/40b6c37437056f2a3ed5

なんていってもVSCodeが神ってる
=>https://qiita.com/testMenta339/items/7911fe6dfe29c1c8f42d
ライブラリとフレームワークの違いとは…？　～技術選定の観点から考える～

#ライブラリとは？
ライブラリは、「あなたのアプリケーション」の一部に組み込まれる
「あなたのコード<b>”が”</b>呼び出す」ことをして機能を果たすものです。

#フレームワークとは？
それに対して、フレームワークは、
「あなたのアプリケーション」の一部に組み込まれて、
「あなたのコード<b>”を”</b>呼び出す」ものです。

一般にフレームワークは、あなたのコードに特定のインタフェースを持つことを強制することで、ある種のアプリケーションを簡単・高速・安全に作成することを手助けします。当然、フレームワークは最終的にはあなたのアプリケーションとして、あなたのコードから呼び出されることがありますので、ライブラリとしても機能していることも多くあります。

#運用や選定の際に気を付ける観点
一般にフレームワークのほうが長期のライフサイクルでの意思決定になりますが、
ライブラリは交換可能性が高い事が多いのです。

>たとえば、より高速なJSON Parserライブラリが出たという際に、
交換が非常に難しくなるということは少ないでしょう。

<br>
一方、フレームワークの交換可能性は、
呼び出される自分たちのコードが増えるにつれて交換しにくくなっていきます。

>たとえば、CakePHPで記述されたソフトウェアをLaravelに移植するのは簡単ではありません。これは高速なアプリケーション開発のツケのともいえます。
jQueryとReactの設計、開発上の違い

# 0. それぞれの利点

##（１）jQuery

- HTMLを分割、加工せずに動的な処理を設定できる。
- HTML/CSSのコーダーからプログラマーへの作業が単線的になる。

## （２）React

- Javascript(Typescript)はデータ（状態）の読み取り・加工のみを行い、DOMについては意識しない。(DOMはJSX内にて記述）
- コンポーネントのルールによりコードが単純になり、コードの統一化が図りやすい。

# １．構造上の違い

## （１）既存のHTML（実DOM）を"外側"から"操作"するjQuery

jQueryは、すでに作られたHTMLの画面があり、その中の部品をセレクタを通して外からDOMを操作します。

```txt
画面：HTML(実DOM)　 ⇐ セレクタ=  jQuery　
```

## （２）仮想DOMにより"内側"から振る舞いを"定義"するReact

Reactは、DOM自体をJsにより作成し、DOM自体の状態、振る舞いを内側から定義します。これがコンポーネントとなります。
そして、このコンポーネントを組み合わせて画面を作ります。

```txt
React   = コンポーネント（仮想DOM）⇒  画面
```

#２．コード上の違い

## （１）jQuery

- DOMの操作、状態の操作をJavascript(Typescript）内で行う。
- 部品ごとのソース分割、コンポーネントなどの制約はライブラリとしてないので、１つのソース内に複数のDOMの操作を書くこともできる。
- **DOMと状態の異なるコンテキストが混在しわかりにくくなる**可能性がある。
- アーキテクチャ（構造）やデータの流れなどの**設計を制約しないので書き手によってコードが異なる**。

## （２）React

- 特定のDOMについて1クラスで定義し、対象DOM以外についてクラス内に記載しない。
- DOMの操作は、Javascript内ではなくJSXなどにおいて記述する。
- Javascript内では、状態(State/Store）に関する記述のみ行う。
- jQueryが行うDOMの操作を、データと仮想DOMのバインディングを隠蔽しながらライブラリが行うので、ReactのユーザーはDOM自体への意識、DOMの操作をすることが少ない（皆無に近いかも）。
- **DOMと状態のコンテキストが別れている**ので、それぞれの**関心・コードがシンプル**になる。
- **構造やデータの流れの設計が決まっている**ため、書き手による**コードの違いがあまりない**。

# ３．工程

## （１）jQuery

- 1.HTML・CSSで画面を作る。
- 2.処理する部位にセレクタを割り当てる。
- 3.セレクタを使い、DOMの操作を記述。

## （２）React

- 1.モック、または、HTMLで分割前の画面を作る。
- 2.コンポーネントの相互関係を踏まえて状態データ（Store）の構造、そして、Storeとコンポーネントのやり取りを定義する。Storeとコンポーネントの流れはReduxに従う。
- 3.処理する部位をコンポーネントに分割して実装する。コンポーネントのは自分のDOMと状態、そして、Storeの更新についてのみ記載。他のDOMの処理は記載しない。
- 4.コンポーネント（仮想DOM）を組み合わせて画面を作成。


# ４．工数

## （１）jQuery

- 工程上、画面の分割、Storeの分割がない分だけ工数は少ない。
- どのように構造や処理を定義するのかの設計が必要となり、ここの工数は増える。
- 設計次第だが、DOMと状態のコードが複雑化し、バグが多くなったりすることで工数が増える可能性がある。

## （２）React

- 画面の分割、Storeの作成などを分割し、コンポーネントの確認環境の構築などの工数が増える。
- 分割し個々のコンポーネントのロジックが単純に近いため、バグの数が少なくなりこの分の工数が少なくなる可能性が高い。

#５．開発規模

## （１）小規模

- **モックや少機能**であれば、**jQuery**の方が工程が短く、工数が少なくなるのでよいかもしれない。
- 個人開発であっても、機能が増える可能性があるとReactを検討した方がよい。

## （２）大規模
- **複数人**での開発、部位の協調性、ロジックの複雑性、**コードの統一化**を考えると**React**の方が良い。
- Reactの構造、データの流れ、コードの役割が小さく区切られ、**コードが単純化するので複数人開発に最適**。

#６．設計上の注意点

## （１）jQuery

- 構造やコードの分割などの指針は書き手に委ねられるため、Reactを参考にコンポーネントごとにソースをわけて、クラスを作り、その中でjQueryによるDOMの操作を行う。
- DOMの操作部分と状態の部分をできるだけ分ける。
- コンポーネントのソースにおいては、できるだけ他のDOMの操作は行わない。
- １ソース、１クラス、１コンポーネント、1DOM、状態分割などを意識する。

##（２）React

- コンポーネント分割、データの流れなどは一般的な設計に従う。設計コストの削減、コードの統一化が目的のため、できるだけ一般化したものを採用する。
- **画面全体の状態(Store）を先に設計**し、それを踏まえてコンポーネントを設計する。
- たえず、状態（State、Store）を意識しながら設計する。
- **画面全体の状態、データの流れをアーキテクチャ（設計者）は意識**する。
- コンポーネントの実装者はできるだけ、**他のコンポーネントを意識せず、Storeと対象DOMの関係のみに意識**するように設計しておく。
nlコマンドの論理ページを無効化する



これは驚くべき事実なのですが、`nl`には論理ページを無効にする方法が定義されていません。ほとんどの人が論理ページを意識しない使い方をしているにもかかわらずです。

（前提とする知識）

- [nlコマンドの論理ページ](https://qiita.com/Carol_815/items/d1f52df36b0d39b374b0)
- [セクションの区切り文字列を変更するnlコマンドのdオプション](https://qiita.com/Carol_815/items/401c327a1dbc7c63b7bb)
- [論理ページごとに行番号をリセットしないnlコマンドのpオプション](https://qiita.com/Carol_815/items/ac3efeb363c6edb32bba)

# 論理ページの不都合な真実

`nl`の論理ページ機能は、`\:`など特定のパターン行からセクションを識別しているため入力データに依存しています。そして`nl`に論理ページを無効にする機能がないということは、ユーザーは入力するデータに意図しない区切り文字列（デフォルト`\:`）が出現しないことを常に保証しなければなりません。データに意図しない区切り文字列が含まれることが判明した場合、セクションの区切りとして認識されることを回避するために、データ中に含まれない任意の文字列（BSD系の`nl`なら最大2文字）を特定し-dオプションに指定する必要があります。

実際の影響としては、入力データに区切り文字列が発生した時点で、行番号がリセットされてしまいます。この影響は-pオプションを利用すればセクション区切りでリセットされないようにできるので、影響を小さくすることができます。しかし、区切り文字が削除あるいは空行に変換される分、行番号に誤りが発生すること、そして区切り文字列そのものの消失を防ぐことはできません。

特に、入力データがユーザーの制御下にない場合はどうすることもできません。区切り文字列が入力されないことをただ祈るのみです。~~ていうか誰がそこまで行番号つけるのに本気出すんだよ~~


# 論理ページの無効化戦略

## BSD系の`nl`

残念ですが諦めてください。区切り文字列は2文字に限定されていますので、その範囲内で最も出現しなさそうな2文字の順列を選ぶ以外にありません。

## busyboxの`nl`

busyboxは論理ページに対応していません。つまりこの`nl`を利用することで論理ページを無効化することができます。やったー！

## GNU coreutilsの`nl`

### 長いユニークな文字列を区切り文字列に設定する

[`-d`のGNU拡張を用いれば長い文字列を区切り文字列に設定できる](https://qiita.com/Carol_815/items/401c327a1dbc7c63b7bb#coreutils%E3%81%AEnl%E3%81%AEd%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%BB%95%E6%A7%98)ので、ユニークな区切り文字列を設定することはできそうです。しかし確率を下げる長い文字列にする以外ありません。以下のようにランダムな長い文字列を生成して利用する感じになりそうです。

```console:coreutils
$ cat /dev/urandom | tr -dc '0-z' | fold -w 64 | head -n 1
jp9NgI3a7Hx][wmk[qlMgmCoOcuhbm9Sx>W:ZC2e:rd^bsI]at95u0JkAUokZv2Q
$ echo -e 'a\n\:\nb' | nl -d 'jp9NgI3a7Hx][wmk[qlMgmCoOcuhbm9Sx>W:ZC2e:rd^bsI]at95u0JkAUokZv2Q'
     1	a
     2	\:
     3	b
```

これはちょっと嫌ですね。ランダム文字列の生成にシェルのコマンド置換を用いたほうがわかりやすくなります。

```console:coreutils
$ echo -e 'a\n\:\nb' | nl -d $(cat /dev/urandom | tr -dc '0-z' | fold -w 64 | head -n 1)
     1	a
     2	\:
     3	b
```

しかしこれだと毎回文字列が変わってしまうので、万が一セクション区切りが発生した場合には、原因追求が難しくなりそうです。


### 空文字列を区切り文字列に設定する

現時点でこれは完全にバグ技です。[この不具合](https://qiita.com/Carol_815/items/401c327a1dbc7c63b7bb#coreutils%E3%81%AEnl%E3%81%AEd%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%B8%8D%E5%85%B7%E5%90%88)を利用します。

```conole:coreutils
$ echo -e 'a\n\:\nb' | nl -d ''
     1	a
     2	\:
     3	b
```

非常にシンプルに書けますね。次版（v8.33？）からは不具合が修正され正式なGNU拡張としてTexinfoにも記載されるようになりますので、この方法が正攻法になります。

>As a GNU extension more than two characters can be specified,
and also if CD is empty (-d ''), then section matching is disabled.

# 余談

[上記の不具合修正ならびにドキュメント化の対応](https://qiita.com/Carol_815/items/401c327a1dbc7c63b7bb#coreutils%E3%81%AEnl%E3%81%AEd%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%B8%8D%E5%85%B7%E5%90%88)にあたっては、空文字を与えた場合の動作仕様についてしかるべき議論はなされたと思います。空文字の場合はデフォルトの`\:`としたほうが一貫性があるという意見もありましたが、最終的に論理ページを無効にできる方法をGNU拡張として用意すべきだということでまとまりました。
JavaScript入門　DOM操作とは

#はじめに
今回は、Youtubeでトラハックのエンジニア学習ゼミを参考にして
勉強と復習のためにJavaScriptのDOM操作について記事にしていこうと思います。

#DOMとは
* Document Object Modelの略
* JavaScriptからHTMLにアクセスする窓口
* HTML要素の値を取得したり変更する　→　DOM操作

#なぜDOM操作が必要なのか
JavaScriptはWebページの「振る舞い」を決める　→　振る舞いを変えるためにHTMLを変更する

### ユーザの望む操作を行うには...
1. 入力したデータを取得する
2. 新しいデータを表示する
3. データを送信する

#取得する方法１　( id指定 )

```HTML:HTML
<div id="hoge">
hogeっていうidが指定されている
</div>
```

```JavaScript:JavaScript
const element = document.getElementById("hoge")
console.log(element.innerText)
```
#取得する方法２　( class指定 )

```HTML:HTML
<div class="foo">fooっていうclassが指定されているdiv要素１</div>
<div class="foo">fooっていうclassが指定されているdiv要素２</div>
<div class="bar">barっていうclassが指定されているdiv要素１</div>
```

```JavaScript:JavaScript
const classes = document.getElementsByClassName("foo")
for (const classNode of classes) {
console.log(classNode.innerText)
}
```
getElementsBy...で要素を複数指定し。classesには配列を代入。
そして、For文で配列を回して表示をする

#取得する方法３　( form要素取得 )


```HTML:HTML
<form name="demoForm">
 <div>
  <label for="title-id">タイトル</label>
  <input id="title-id" name="title" type="text" />
 </div>
</form>
```

```JavaScript:JavaScript
const forms = document.forms.demoForm

// 値を取得したいinput要素のnameを指定
const title = forms.title.value
console.log(title)
```

#参考
[DOM操作できなきゃJS使う意味がない【分かりすぎて怖いJavaScript入門】](https://www.youtube.com/watch?v=dZyYqVOnrBg)
【Portfolio】laravelでサイトを管理APP実装（Docker環境構築）

##成果物
[★こちらクリック! →　Go To "WebApp"★](http://laraveltask.ap-northeast-1.elasticbeanstalk.com)
[★こちらクリック! →　Go To GitHub★](https://github.com/Yuchan-He/adminPanel)

##機能一覧
・ログイン機能
・CRUD処理
・部分検索機能
・レスポンシブ対応(bootstrapなど)
・dockerを使用しての環境構築（docker-compose.ymlをGitHubにご参照）

##機能詳細
####・ログイン機能
<strong>※検証しやすくために、入力欄に先にデータを入れておきました。</strong>
ユーザー名（テスト用）：坂本　学
初期パスワードは：12345678（登録後、個人情報で変更可能）

####・CRUD処理
<strong>※下記のボタンにCRUD機能を実装されています。<strong>
ーーーーーーーーーーーーーーーーーーーーーーー
(1)Create（生成）
補足：フロント側にも検証機能追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704481/bfe73662-fd9c-2494-eab5-206165dea989.png)
ーーーーーーーーーーーーーーーーーーーーーーー
(2)Read（読み取り）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704481/a4050f4f-9121-c92a-f62d-8aa03ac8122b.png)
ーーーーーーーーーーーーーーーーーーーーーーー
(3)Update（更新）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704481/861f5b89-0ffb-fd82-1254-22127f8a617a.png)
ーーーーーーーーーーーーーーーーーーーーーーー
(4)Delete（削除）
補足：論理削除と物理削除を分けていく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704481/927cbc50-ca6f-4ea1-c971-96dcb2017fc9.png)
ーーーーーーーーーーーーーーーーーーーーーーー
####・部分検索機能
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704481/d6e938bd-1d03-db09-0279-125fae0c60f6.png)

####・レスポンシブ対応(bootstrapなど)　
[サイトにご参照](http://laraveltask.ap-northeast-1.elasticbeanstalk.com)
####・dockerを使用しての環境構築（docker-compose.ymlをGitHubにご参照）
[GitHubにご参照](https://github.com/Yuchan-He/adminPanel)