OmniAICreator/Qiita-1.07M huggingface dataset:
【mac/Ruby】csvファイルの文字化けを解消する

### 1.背景
ポートフォリオ作成にあたり、csvファイルからデータを取り込みたいと考えました。
ダウンロードしたcsvファイルをクリックした時には（`Numbers`でファイルを開きました。 ※`このアプリケーションで開く`で設定していたため。）
問題なかったのですが、いざ該当のディレクトリに入れてクリックしたら文字化けが凄かったです。

※画像はイメージです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689555/f107c37c-6d06-eca0-383f-bc1ef37d900d.png" width=80%>

これじゃ使えない！と思い解消方法を探しました。

### 2.環境

- mac.os バージョン10.15.6
- Ruby 2.7.3

### 3.実際やった方法
[こちら](https://support.freee.co.jp/hc/ja/articles/115002727126-CSV%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%8C%E6%96%87%E5%AD%97%E5%8C%96%E3%81%91%E3%81%97%E3%81%9F%E5%A0%B4%E5%90%88%E3%81%AE%E5%AF%BE%E5%87%A6%E6%96%B9%E6%B3%95)のMacの場合を参考に進めました。

①csvファイルを右クリックし、「このアプリケーションで開く」を「テキストエディット」にします。
②「command + shift + S」キーでファイルを複製します。
③「command + S」キーでファイルを保存します。
　　　　名前を最初のcsvファイルと別名にして拡張子を`.csv`にして、
「標準テキストのエンコーディング」を「UTF-8」にします。　※ここはサイトと異なります。
④該当のディレクトリに入れてクリックし、文字化けが解消したことを確認します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689555/3ee9782d-1872-d29b-7d1d-a20174c21d0e.png" width=80%>

### 4.最後に
記事の感想や意見、ご指摘等あれば伝えていただけるとありがたいです。
読んでいただき、ありがとうございました。
WebAPI設計におけるHTTPメソッドの決め方（GET, POST, PUT, PATCH, DELETE）

## URIの基本
URIは**リソース**を示すもの。
メソッドはリソースに対する**操作**を示すもの。
以下に、Twitterの「いいね」に関するAPIエンドポイントを挙げる。

「いいね」関連のAPI
参考：[TwitternのAPIドキュメント](https://developer.twitter.com/en/docs/twitter-api/tweets/likes/api-reference/post-users-id-likes)

``GET /2/users/:id/liked_tweets ``
⇒ ユーザーが「いいね」しているツイートを**取得**する

``POST /2/users/:id/likes``
⇒ 特定のツイートに「いいね」する ⇒ 「いいね」を**新規作成**する

``DELETE /2/users/:id/likes/:tweet_id``
⇒ 特定のツイートの「いいね」を**削除**する

それでは、ひとつずつメソッドについて見ていこう。

## GET
リソースを**取得**する際に利用する。
例えば、SNSで「投稿一覧を取得する」APIを考えると、以下のようになる。

``GET /posts``

## POST
リソースを**新規追加**する際に利用する。
リソースの更新や一部変更は、別のメソッドを利用するのが好ましい。
SNSで「投稿を行う」APIを考えると、以下のようになる。

``POST /post``
※紛らわしいが、URIの/postは「投稿」の意味で使っている。

## PUT
リソースを**上書き/変更**する際に利用する。
PATCHはリソースを一部変更する際に利用し、PUTと明確に使い分けが出来る。
SNSで「投稿を修正する」APIを考えると、以下のようになる。

``PUT /post/:post_id``

## PATCH
リソースを**一部変更**する際に利用する。
PUTはリソースを上書きする際に利用し、PATCHとは明確に使い分けが出来る。
SNSで、「自身のユーザー情報の中の自己紹介文を変更する」APIを考えると、以下のようになる。

``PATCH /:user_id/profile``
たとえば、リクエストボディは以下のようになる。

```javascript
{"introduction": "私の名前は津本です"}
```

すると、プロフィールの**一部**が変更される。

```javascript
{
    "first_name": "津本",
    "last_name": "敏男"
    "introduction": "私の名前はツモトです"
    "image": "https://example.com/tsumoto.png"
}
↓
{
    "first_name": "津本",
    "last_name": "敏男"
    "introduction": "私の名前は津本です"
    "image": "https://example.com/tsumoto.png"
}
```

## DELETE
リソースを**削除**する際に利用する。
例えば、SNSで「投稿を削除する」APIを考えると、以下のようになる。

`` DELETE /post/:post_id``

## この記事の注意点
**メソッドの決め方**と題していますが、正しく言えば[RFC7231](https://datatracker.ietf.org/doc/html/rfc7231#section-4)と[RFC5789](https://datatracker.ietf.org/doc/html/rfc5789#section-2)に従ったHTTPメソッドの決め方です。
実際に使われている大手のAPIでは、PATCHが使われていないこともあります。
RESTAPIではなくGraphQLのみをサポートすることも増えています。

実際に設計する際は原則を基本にしつつ、現在のデファクトスタンダードも調べて設計するようにしましょう。
cv2.VideoCapture(0)をしても内蔵カメラの動画が取得できない時の対処法



## やりたいこと
 macの内蔵カメラの動画を取得したい

## コード

```
capture = cv2.VideoCapture(0)

while(True):
    # フレームのキャプチャ
    ret, frame = cap.read()

    # 結果のフレームを表示
    cv2.imshow('frame',frame)
```
## 問題

```
Traceback (most recent call last):
    cv2.imshow('frame',frame)
cv2.error: OpenCV(4.5.3) 
error: (-215:Assertion failed) size.width>0 && size.height>0 in function 'imshow'
```

ネットの記事などを探し回ったところ、どうやらcv2.VideoCaptureがうまくいいっていないらしい。
これはopenCVで画像取得をしようとして、URL誤字をしたなどでも同じエラーになる。


## 解決方法


openCVのdocを見たところ、 デフォルトのデバイス番号は０か-１になるらしいが、
外付けカメラなどだとそれ以上の番号になると

snap cameraを利用していたのでもしかしたら外付け扱いにされた？と思い、番号を変更してみると、、、


できた。。。！



```
capture = cv2..VideoCapture(1)
```

## 参考
http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_gui/py_video_display/py_video_display.html
【GCP認定資格】Associate Cloud Engineerに合格しました

GCP認定資格のAssociate Cloud Engineerを取得したので、備忘録的に記載しておきます。

#試験内容
Associate Cloud Engineer 認定試験では、以下に関する能力が評価されます。

・クラウド ソリューション環境の設定
・クラウド ソリューションの計画と構成
・クラウド ソリューションのデプロイと実装
・クラウド ソリューションの安定稼働の実現
・アクセスとセキュリティの構成

GCPで提供される各サービス(GCE, GKE, BigQuery,IAMなど）の基本的なことがわかってるかどうかを評価されます。
ネットワーク、サーバーなどの基本的な知識も必要です。
正式には[公式サイト](https://cloud.google.com/certification/cloud-engineer)でご確認ください。

#私のスペック
保有資格は以下の通り。
・ネットワークスペシャリスト試験（かなり前に取得）
・AWS Solution Architect Associate（2年前に取得）
・Alibaba Cloud Associate(Cloud Computing)（1年前に取得）

実務経験はほどほどですが、
ネットワークの知識は多少あること、
AWSのサービスは多少把握していること、
Alibaba Cloudの実務経験は1年程度あること
から、一から覚えないといけないレベルではないといったところでしょうか。
GCP以外のパブリッククラウドと比較しながら学習することができたので、クラウドの知識があったのは大きかったです。

#勉強日数
勉強に要した日数は1ヶ月間程度。
平日は業務終了後に1時間程度、休日は2〜3時間程度、勉強時間に充てました。

#勉強方法
AWSと違い、資格取得のための参考書的なものは皆無なので、以下の勉強方法で学習しました。

###書籍でGCPのサービスを把握する
[Google Cloud Platform エンタープライズ設計ガイド](https://cloud.google.com/certification/cloud-engineer)
を読みました。GCPのサービスがわからないことには話にならないので。
GCPの各サービスが広く浅くまとめられていてわかりやすいです。

###Udemyでハンズオン
[現役エンジニアが教える、手を動かして学ぶGoogle Cloud Platform(GCP) 入門](https://www.udemy.com/share/1024VC3@zn2JLEsxQmel-s23jtZhfpKqI-zFZqyEd0ugM0vpSpCdD5h6fZhKvBgg3b-a5j6k/)
でハンズオンしました。
GCE、GCS、SQL、インスタンスグループ、Load Balancing、Cloud Functions、GAPなどの操作を一通り体験。
ただし、試験の範囲であるGKE、IAM等はこの講座の範囲外なので自習が必要です。

###模擬試験
[公式の模擬試験](https://docs.google.com/forms/d/e/1FAIpQLSc7bkUHpDbFShBI5xE4u8OO2vl99DrP0htnswa-la9DQynToA/viewform?hl=ja&fbzx=-799126281318317265)（25問）
Udemyの[【GCP認定資格】Google Cloud Platform Associate Cloud Engineer模擬問題集](https://www.udemy.com/share/103f4Y3@AkZQFs8H_1P0ggQekg7W126P0b95u2rU-wZn_NsifLpEsULSiy7Ea38crIvr1oKG/)（40問×3セット）
同じくUdemyの[GCP：Google Cloudアソシエイトクラウドエンジニア模擬試験問題集](https://www.udemy.com/share/104WZQ3@Y28Bg4Xb1aGNGKkuVIC_7Mw_8TACMqvU05c0wx6Vqe6oIU-tf3rCqAM9BAncPvYq/)（50問×4セット）
は、ほぼ100%正答になるまで繰り返し実施しました。

###その他
・Cloud SDKのコマンドは全部覚えるのは難しいのですが、構文とよく使いそうなものは覚えました。
・IAM等の権限まわりはクラウドのアーキテクトには重要な要素なので重点的に覚えましょう。

#試験の感想
受験する前に思っていたレベルより難しかった印象です。

一見、何を言ってんのかわからん！という問題でも、落ち着いて読み解くと意外とシンプルなことを問われていることに気付き、四択→二択くらいまでは絞れると思います。
もっと実機をいじっておけば、より早く、より確実に、最終的な答えを導けたなーと言うのが反省点です。

試験時間は2時間ですが、一通り問題を問くのに1時間30分、見直しに30分と、2時間目一杯使いました。

元々そうなのか、コロナ感染対策なのかわかりませんが、手元にメモ用紙が無かったので、頭の中に構成を描かなくてならず、そこが結構苦労しました。

#次の目標
次は年内にProfessional Cloud Architect資格取得を目指しています。
（実は、Associate試験はProfessional試験のための前哨戦的な意味合いで受けてたりします）

以上。
私のIPアドレスについて調べてみた

<h1>前書き</h1>
- ifconfig

叩いてみて「ふーん」で終わらせてしまっていたため、
記事を書く練習も兼ねて私のIPアドレスについてまとめることにした。

<h1>私のIPアドレス</h1>
コマンドを打って取得できたもの

```
~ % ifconfig |grep inet
	inet 127.0.0.1 netmask 0xff000000 
	inet6 〜〜〜〜
	〜〜〜
	inet 192.168.1.21 netmask 0xffffff00 broadcast 192.168.1.255
```
- 127.0.0.1 ・・・ローカルループバックアドレス
    - 0xff000000 ・・・サブネットマスク

- 192.168.1.21 ・・・私のPCのIPアドレス
    - 　0xffffff00　・・・サブネットマスク
- 192.168.1.255　・・・ブロードキャストアドレス　

####サブネットマスクがまさかの１６進数表記だったので、１０進数に変換する。

```
127.0.0.1 ・・・ローカルループバックアドレス
255.0.0.0 ・・・サブネットマスク
127.0.0.1　/8 ・・・CIDR表記

192.168.1.21 ・・・私のPCのIPアドレス 
255.255.255.0 ・・・サブネットマスク
192.168.1.21　/24 ・・・・・・CIDR表記
```
####ネットワークアドレスを求める
ネットワークアドレスを求めるためにそれぞれ２進数に変換してAND演算する

```
011111111 00000000 00000000 00000001 ・・・ローカルループバックアドレス
111111111 00000000 00000000 00000000 ・・・サブネットマスク
↓AND演算
011111111 00000000 00000000 00000000
↓
127.0.0.0 ・・・ネットワークアドレス

11000000 10101000 00000001 00010101　　・・・私のPCのIPアドレス
11111111 11111111 11111111 00000000 ・・・サブネットマスク
↓AND演算
11000000 10101000 00000001 00000000
↓
192.168.1.0 ・・・ネットワークアドレス
```

###ちなみに

>クラスフルアドレスでは、IPアドレスはA〜Eの5種類のクラスに分類されている。
IPアドレスの先頭1~4ビットまでのビット列の組み合わせによって、どのクラスに属するかを判別することができる。
5つのクラスのうち、ユーザに割り当てられるクラスはA~Cの3つだけ。
参照：(https://qiita.com/mogulla3/items/efb4c9328d82d24d98e6)

こちらのサイトによるとクラスフルアドレスに該当するので、上記の面倒な計算をしなくても簡単にネットワークアドレスが求められた模様・・・。

<h1>感想</h1>
ふーんで終わらせていた自分のPCのIPアドレスをよくみてみることでより理解が深まった。
サブネットマスクを１６進数で表すことがあるのは初めて知った；；
navigationItemにUISearchControllerを表示させる

#今回の内容
<img width="150" alt="2D75E1DB-C77D-438E-8019-E3BCD31C712D_1_201_a.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/3443da28-610c-f51e-aa4f-0a5281a313b4.jpeg"> <img width="151" alt="334CD544-F9DA-475B-A4B3-C1F727270C47_1_201_a.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/5b07bf43-a766-9fa7-2059-0888b0951e80.jpeg">


# コードと簡単解説

* `navigationItem.searchController`に`UISearchController()`を設定します。

* `title`には好きな文字列を表示できます。

```Swift:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let searchbar = UISearchController() 
        
        navigationItem.searchController = searchbar
        title = "AlertLesson"
        
    }

```

# 終わり
ご指摘、ご質問などありましたら、コメントまでお願い致します。
Java再入門 ～Java11 ジェネリクス、ダイアモンド演算子

# ジェネリクス

ジェネリクスは型をパラメータ化することができる仕組みで、Java11どころかJava5からあります。
使わないとListとかMapとかを使えないに等しいような状態になるので、まったく知らないという人もいないと思いますが、自分で型パラメータの宣言をしたことはなかったり、extendsやsuperが出てくると自信がなくなったりする人は少なくないのではないでしょうか。

自分で宣言して利用しようとしたときに、まず悩むのはどこに書いたらいいのかです。以下の3パターンあります。

1. クラスに宣言する
2. メソッドに宣言する
3. コンストラクタに宣言する

個人的にコンストラクタに宣言したくなったことは一度もないのですが、できるかどうかでいうとできます。
クラスやコンストラクタに宣言する場合の例は以下です。

```java
public class GenericsClass <T, A extends Piyo> {

    T obj;

    A piyo;

    Huga huga;

    public <B extends Huga> GenericsClass(B b) {
        this.huga = b;
    }

    public void setT(T obj) {
        this.obj = obj;
    }

    public T getT() {
        return obj;
    }

    public void setPiyo(A piyo) {
        this.piyo = piyo;
    }

    public A getPiyo() {
        return piyo;
    }
}
```

メソッドに宣言する場合の例は以下です。

```java
public class GenericsMethod {

    public static <T> void inputT(T obj) {
        System.out.println(obj + ":T");
    }

    public static <T extends Piyo> void inputT(T obj) {
        System.out.println(obj + ":T extends Piyo");
    }

    public static <T> T returnT(T obj) {
        return obj;
    }

    public static <T> void copy(List<? extends T> from, List<? super T> to) {
        for (int i = 0; i < from.size(); i++) {
            to.add(from.get(i));
        }
    }
}
```

知らないと混乱する、主な注意点は以下です。

* `T extends Number`は「TはNumber型もしくはそのサブクラス」という意味
* `? extends T`は「T型もしくはそのサブクラス」という意味
* `? super T`は「T型もしくはそのスーパークラス」という意味
* `new T()`とか`new T[]`とかはできない
* コンパイル時に型情報は消去される。そのままObject型扱うになるか、`<T extends Number>`みたいになっていた場合はNumber型扱いになる
* 素の状態だと共変性がない。`List<Number> list = new ArrayList<Integer>();`とかはできない。`List<? extends Number> list = new ArrayList<Integer>();`とすればOK

いつ使うのかよく分からないのは`? super T`じゃないでしょうか。
これはたとえば以下のような場面で使います。

```java
    public static <T> void copy(List<? extends T> from, List<? super T> to) {
        for (int i = 0; i < from.size(); i++) {
            to.add(from.get(i));
        }
    }
```

こうしておくと、以下はエラーになりません。

```java
GenericsMethod.copy(Arrays.asList(1 , 2, 3, 4, 5), new ArrayList<Number>());
```

# ダイアモンド演算子

ダイアモンド演算子の追加で二回書かなくても推論してくれるようになりました。

```java
List<Number> list = new ArrayList<>();
```

このダイアモンド演算子は型推論と相性が悪いというか両立しないようなところがあります。

```java
// 以下は書けるけれどvar list = new ArrayList<Object>();と同じ意味になってしまう
var list = new ArrayList<>();
```

多くの場合は結局、以下のように書く必要があります。

```java
var list = new ArrayList<Number>();
```

# シリーズJava再入門

いまからJava8にしよう！だってJava11よりサポート長いし！という判断もあると思いますが、11に引っ越そうとしている方や、11の次のLTSになることを予定されている17への移行を目指している方向けのJava再入門です。

1. [Java7以降の歴史 機能追加とサポート期間](https://qiita.com/yyukawa/items/e1a027bcbfbb3d39958e)
1. [モジュールシステムとクラスパス、Gradle](https://qiita.com/yyukawa/items/44ef24f51649e6c5e299)
1. [Java再入門 JVMオプション](https://qiita.com/yyukawa/items/96f667c7f0c06f97ed3e)
1. [Java再入門 ～Java11 ジェネリクス、ダイアモンド演算子](https://qiita.com/yyukawa/items/d5a5ab8d4846c0b70479)
1. [Java再入門 ～Java11 日付時刻API](https://qiita.com/yyukawa/items/d4159506da46bbd6b651)
1. ～Java11 リソース付きtry文
1. ～Java11 ラムダ式、メソッド参照、Stream、Optional、ローカル変数型推論
1. ～Java11 ExecutorService/Future、Fork/Join
1. 今後：テキストブロック
1. 今後：switch式、パターンマッチングinstanceof
1. 今後：record
勉強会用のJavaの資料を作った話

# まとめ

勉強会用の資料を作ったので、共有を楽にするためにアップロードしておいたという話。

# 勉強会について

現在の自分の職場にて新しく勉強会を開くことになり、自分が先陣を切ることにした。
ただし、SESで単独で派遣されている身なので、他の社員の技術レベルは一切わからない。
そのため、下記のような思考で勉強会用の資料を作成した。

* すくなくとも、文法を調べる資料は社内にある
* 相手の技術レベルはわからない
  * 低いレベルの人でもわかる課題を作りたい
    * できるだけ、次回に「良い設計とはなにか」を伝えられるような課題にしたい
  * できる人用の内容も盛り込んでおきたい
* どこにでもありそうなかんたんな課題を比較的高度な設計方法によって作成すると新規性が出そう

# 資料

そうした結果できたのが、下記の資料である。

<iframe src="//www.slideshare.net/slideshow/embed_code/key/qkCFp5RMErg3BR" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/ssuser331f24/java-250243216" title="勉強会用資料：Javaアプリ作成" target="_blank">勉強会用資料：Javaアプリ作成</a></strong> </div>

下記はスライドのソース。

https://github.com/mickie895/swing_calc_for_education/blob/starter_kit/documents/%E3%83%AC%E3%82%B8%E3%83%A5%E3%83%A1%231.md

そしてスライド内で書かれている「スターターキット」は下記のアドレス。

https://github.com/mickie895/swing_calc_for_education

# 勉強会時に感じた課題

## プロジェクトインポート時に事故発生

次のような展開で盛大に事故を起こした。

1. 自環境ではEclipseにプリインストールされていたJDKが相性悪かったらしく、UTF-16でないと動作しなかった
2. 仕方ないからUTF-16でクラスを作成し、githubにプッシュした
3. githubはUTF-16エンコードのテキストファイルはバイナリとみなした(事故1)
4. EclipseでgithubのコードをプロジェクトとしてインポートしたらUTF-8としてエンコードされた
5. 日本語が文字化けし、余計な文字コードが紛れ込んだのかビルドもできなくなった(事故2)

いくつかの環境で実際に動かせるかどうか確認したほうがよかった。

## 勉強会の構成の不備

とりあえず資料を作るところにだけ目が行っていて、実際に実技があることを考慮に入れていなかった。

また、見ればある程度わかるよね、というレベルを目標にしていたが、
そのレベルまで行くにも自分の技量はもちろん、相手にもある程度の経験が必要であることを認識していなかった。

次があれば少しづつ改善していこう。

# 今後について

この勉強会スライドの課題の電卓づくりを、TDDを使って実装し、また、その際に考えていたことをまとめる予定。
日記に近いものになるからnoteにでも書くかな。
【AWS】 S3アップロード Rails CarrierWave

#目標
s3に画像をアップロードする

#前提
* 画像投稿機能実装済
* AWSアカウント作成済
* CarrierWave使用

# やりた方
####AWSでIAMユーザを作成していきます
①IAMにアクセス→ユーザー追加するを選択
②ユーザー名をきめる
③AWS認証情報タイプの選択で、アクセスキー−プログラムによるアクセスにチェックを入れる→次へ
④既存のポリシーにアッタチを選択
⑤ポリシー検索でS3を入力→ AmazonS3FullAccessを選択
⑥キーとタグは作成せず→次のスッテプ：確認
⑦管理ポリシーがAmazonS3FullAccessになっていることを確認して→ユーザーの作成
⑧アクセスキーIDとシークレットアクセスキーが出てくるので必ずメモするか、csvのダウンロードをしておく→閉じる
これでIAMユーザーが作成できたので、次にS3を作成

####S3バケットの作成

①S3にアクセス　S3を選択→バッケット作成選択
②バケット名を選択→他と被らない名前を記入してください
③リージョンはそのままの（東京）ap-northeast-1で
④パブリックアクセスの全てをブロックのチェックを外します
⑤下の2つにチェックを入れて→作成
![スクリーンショット 2021-09-19 22.43.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927584/bff0a213-673d-e6a5-c744-b6a7be7ed16b.png)
⑥バケットが作成されたら作成したバケットを選択してアクセス許可を選択
⑦先程のブロックパブリックアクセスを確認して→バケットポリシーの編集を選択
⑧先ほど作成したIAMユーザーのARNをコピーして⑨に貼り付ける→（ARNはIAMにアクセスして→ユーザー→先程作ったものを選択すれば表示されます）
⑩にバケット名を入力

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt000001",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::⑨ARNをここに貼り付ける"
            },
            "Action": "s3*",
            "Resource": "arn:aws:s3:::⑩バケット名"
        }
    ]
}
```

⑪入力できたら保存しましょう
できたらS3バッケととIAMユーザーができたのでOKです。

###Gemfileにfog-awsを追加していきます
awsをつけなくても普通に起動できる環境もあるようですが自分の場合awsがないと他の場面でエラーが発生しました。

```ruby:Gemfile
gem 'fog-aws'
```
`bundle install`します。

###アップローダーにfogを記述していきます

```ruby:app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
  if Rails.env.production?
    storage :fog # 本番環境のみ
  else
    storage :file # 本番環境以外
  end

```

###carrierwave.rbのファイルを作成

```:ターミナル
$ touch config/initializers/carrierwave.rb

```
またはvimで直接入力。

```:ターミナル
$ vi config/initializers/carrierwave.rb
```
バケット名だけ記述してください。
漏洩すると悪用される危険性があるので、直接記述せず環境変数を使います。

```ruby:config/initializers/carrierwave.rb
require 'carrierwave/storage/abstract'
require 'carrierwave/storage/file'
require 'carrierwave/storage/fog'

CarrierWave.configure do |config|
    config.storage :fog
    config.fog_provider = 'fog/aws'
    config.fog_directory  = 'バケット名' # 作成したバケット名を記述
    config.fog_public = false
    config.fog_credentials = {
      provider: 'AWS',
      aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'], # 環境変数
      aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'], # 環境変数
      region: 'ap-northeast-1',   # アジアパシフィック(東京)を選択した場合
      path_style: true
    }
end

```
###環境変数の設定
ここでIAMユーザーを作成したときのアクセスキーIDとシークレットアクセスキーを入力します。
環境変数の定義の仕方がいくつかあるようです、自分の場合は`sudo vi /etc/environment`vimで設定しました。
他にも方法あるので、環境変数について参考にさせて頂いた記事を貼っておきます。
https://qiita.com/yuichir43705457/items/7cfcae6546876086b849

```:/etc/environment
AWS_ACCESS_KEY_ID = 'IAMユーザー作成時のアクセスキーIDをここに記述'
AWS_SECRET_ACCESS_KEY = 'IAMユーザー作成時のシークレットアクセスキーをここに記述'

```

記述したら一度exitして再起動し反映されているか確認します。

```
$ env | grep AWS_ACCESS_KEY_ID
$ env | grep AWS_SECRET_ACCESS_KEY
```
読み込まれていたら先程入力したIDとシークレットアクセスキーが表示されるはずです。
これでブラウザを確認したら、アップロードされているはずです。
AWSのS3バッケットを確認したらにアップロードに画像が追加されています。

####※エラーが出たりしたら、まず、IDとシークレットアクセスキーが逆になってないか確認してみてください。
##【エラー対処】
エラーの対処で参考にさせて頂いた記事。
https://qiita.com/siruku6/items/a3a9021913749247d92b
https://qiita.com/aocattleya/items/f655ceb71922edc90a0b
チーム開発でアプリ作ろうとしたけど失敗した


メンバー
- ゆうすけ→自分（[@t_yusuke_jp](https://twitter.com/t_yusuke_jp)）
- トガリアミガサタケ（[@FyUKmR0iwcKRULK](https://twitter.com/FyUKmR0iwcKRULK)）
- あすや（[@asuyasuyasuya](https://twitter.com/asuyasuyasuya)）

インターン先で知り合った仲間とチーム開発でアプリを作ることになりました。

元々1からアプリを作り上げて、世に出したいといった思いがありました。
今まで数人で集まってアプリ開発をした経験があるのですが、どれも途中で終わってしまったので、まずはちゃんと完成させることを目標にスモールスケールなアプリを設計しました。
また、チュートリアルでよくあるToDoアプリのような、あるあるアプリにしたくなかったので、ユニークな機能も付けました。

しかし、結果は失敗に終わってしまいました。

## 記事を書いた理由
理由は複数あって、

1. 今まで数人のチームで開発をしたけれど途中で終わってしまった経験があったので今回は成功しても失敗しても何かの形として残したかったから。
2. ネット上で流れてくる記事自体、成功した話などがほとんどですが、失敗した話もあえて紹介することで僕たちをより知ることができる機会にもなれたら良いなと思ったからです。

## どんなアプリ？
指定した時刻にアラームが鳴り、1分以内に操作しなければ連絡先の中からランダムに選ばれた相手に自動で電話がかかるアプリです。
必ず起きることができるようなアプリを作りたいと思ってこのようなアプリを作ろうと思いました。
アプリ紹介記事リンク
GitHub: [Stickers-hackathon/mezamashi-denwa](https://github.com/Stickers-hackathon/mezamashi-denwa) 

## どうやってチーム開発を行なった？
みなさん学校や仕事で平日は埋まっていたので、集まれない時はdiscord, 集まれる時はファミレスや大学の空き教室などに集まって開発などやったりしていました。
安くてwifiがあって、かつエアコンが効いていて涼しい場所を候補に探していました。
他の候補としては自習室や公民館などがありました。

## なぜ失敗した？
元々開発期間として１ヶ月を目安に開発していました。しかし、開発が進むにつれ予期していない技術的な壁などが出てきた結果、気づけば2ヶ月ほどかかってしまっていて、当初考えていなかったチームメンバーの他の予定なども入ってきたりした結果、これ以上ずるずる引きずってももったいないなと思い、一旦終わることにしました。

技術的にできなかった話は別の記事で書いてますのでぜひご覧ください。

## 失敗したけどよかったこと
技術面で言うとFlutterを触れたことです。
今までFlutterの実態がわからなかったので少しハードルを感じていましたが、いざ触ってみるとSwiftやKotlinに比べてコードからUIがわかりやすいのでコードレビューがしやすいことに気づけました。

チーム面で言うと、みんなで話し合えたことです。
どんなサービスを作るか、MTG場所はどうするかを話し合って決めました。
そうすると当初、一人では思ってもいなかったアイデアが出てくるので最適な答えに割と早く辿り着けることが多かったです。

## 今後は？
今後も開発を続ける計画で、現在新型コロナウイルスの感染者アプリを作ろうと設計しています。
![スクリーンショット 2021-09-20 22.41.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600371/463db888-504a-e938-66d4-821f8d0200dc.png)

完成するとまた記事で共有したいので今後の活動に乞うご期待を！
0からVue.jsについて勉強する（随時更新）

# 概要
Vue.jsについて勉強する必要に駆られたので，勉強ログとしてまとめていきます
web開発の経験どころか，Javascriptフレームワーク自体ほとんど触れたことがないので，気長にやっていきます。
本まとめに際して，参考にさせて頂いた書籍はこちらです

 - [たった1日で基本が身に付く！Vue.js 超入門](https://www.amazon.co.jp/o/ASIN/4297113775/gihyojp-22)

# 目次　
1. そもそもVueとは？
2. Vueの特徴  
3. Vueの基本


# 1. そもそもVueとは？
Vue.jsとは，フロントエンド領域で人気のあるJavascriptフレームワークのことで，**プログレッシブフレームワーク**，**コンポーネント指向**といった特徴を持つ。

、、、と言われてもよく分からないので，次の章にかけて一語ずつ噛み砕いていきます。


- Javascriptフレームワーク
フレームワークとは「骨組み」のことで，アプリ内で共通する処理を予め定めておくことで,開発・保守が容易になる


# 2. Vueの特徴
Vue.jsならではの特徴がいくつかあるので取り上げます。

- #### 学習コストの低さ
Vue.jsアプリケーションは基本的にHTMLを拡張したテンプレートと，Javascriptのコードから構成されるため，この2つに馴染みがあればすぐに扱うことができます

- #### コンポーネント指向
UIパーツを部品とみなし，それらを組み合わせてアプリケーションを構築する考えのこと
例えば，「勤め先，氏名，メールアドレス」など，単語を入力するフォームは共通の部品で，「備考欄やメッセージ」など，文章を入力するフォームは先に取り上げたものとは別の部品で考える
- #### SPA開発ができる
SPAとは,**Single Page Application**の略で単一のページで複数の機能や表示を実現するwebアプリケーションの仕組みのこと
コンテンツ切り替えにおけるサーバ通信を減らすことができるため，読み込み速度の向上を図ることができます

- #### Vueを中心としたエコシステム
Vue.jsのために作られた周辺ツールやライブラリを公式がまとめて公開しているため，ツールやライブラリの導入時に選定で悩む必要がありません

他のフレームワークではなく，Vueを使うメリットはかなり大きそうですね

# 3. Vueの基本
この章では，Vueを使う上で必須となる記法について触れていきます。

- #### idの付与  
Vueではjavascriptと結びつけるためdivタグにidを付与する

```
<div id="app>
```

付与されたid情報はjsファイルで読み込み，対応させる

- #### Vueインスタンスについて
Vue.jsの様々な機能をまとめたVueクラスを元に実体化したオブジェクトのこと
Vue.jsでは，Vueクラスを**インスタンス化**することで初めて使用可能になります
以下はインスタンス化の例です


```
new Vue({
el: '#app'
});
```


# 4. v-bind, v-if
Webシステムのセキュリティ対策まとめ　-暗号化-

#Webシステムの暗号化
Webシステムにおいて、通信の盗聴や不正侵入のリスクは常に考慮する必要がある。
その対策となるのが暗号化です。

#暗号化とは
暗号化とは、元のデータ（平文）を暗号化の手段で第三者が読み取れないデータ（暗号化）にすることが必要。
受信者は暗号化を利用するために平文に戻すことを復号と呼ぶ。

#共通鍵暗号方式
共通鍵暗号方式とは、暗号化と復号化の両方で同じ鍵を使う暗号化方式のことです。暗号化アルゴリズムとしては

* DES
* RC4
* AES

共通鍵暗号方式では暗号化と復号化をする人物以外に鍵が知られないように管理する必要がある。

#公開鍵暗号方式
公開鍵暗号方式とは、暗号化と復号化で異なる鍵を使う暗号化方式のことです。
この方式では「暗号化に使う鍵は公開されている鍵」を使い「復号化に使う鍵は秘密の鍵」を使用。
暗号化に使う鍵は公開されているため、誰でも暗号化できますが、復号化に使う鍵は暗号化されたデータの受信者しか所有していないため、復号化は受信者しか行うことができません。公開鍵暗号方式ではこのような方法で安全にデータをやり取りします。

# ハッシュ化
ハッシュ化とは元のデータに対してハッシュ関数による処理を加えて、固定長のデータに変換する技術。
ハッシュ関数と呼ばれる計算式によって任意の長さのの文字列をハッシュ値に変換する。
同じハッシュ値を持つデータを生成するすることは難しく、認証の際は送信されてきたパスワードのハッシュ値をを比較することでパスワードが正しいかどうか判定できる。
また、ハッシュ値から元の文字列を割り出すことは非常に困難で、万が一ハッシュ値が盗まれても元のパスワードが漏洩することはない。
CakePHP2のfindでサブクエリ

https://book.cakephp.org/2/ja/models/retrieving-your-data.html#id6
CakePHP2でサブクエリを使う方法については、ちゃんと公式ドキュメントに書いてある。フレームワーク的な方法があるわけではなく、単純に文字列としてのSQL文を渡すだけ。

公式ドキュメントはあまり参考にならなかった。そう思うに至った顛末を当記事にまとめてみた。

# whereでサブクエリ

公式ドキュメントではただ「サブクエリ」としか書かれてないけど、サブクエリにもいろいろある。具体的には「conditionsでサブクエリを扱う方法」が解説されている。

```php
$conditionsSubQuery['User2.status'] = 'B';

$db = $this->User->getDataSource();
$subQuery = $db->buildStatement(
    array(
        'fields'     => array('User2.id'),
        'table'      => $db->fullTableName($this->User),
        'alias'      => 'User2',
        'limit'      => null,
        'offset'     => null,
        'joins'      => array(),
        'conditions' => $conditionsSubQuery,
        'order'      => null,
        'group'      => null
    ),
    $this->User
);
$subQuery = 'User.id NOT IN (' . $subQuery . ') ';
$subQueryExpression = $db->expression($subQuery);

$conditions[] = $subQueryExpression;

$this->User->find('all', compact('conditions'));
```

上記は公式サイトのサンプルコード。最後の4行がなんとなく素人っぽい。そもそもこのサンプルってコントローラ側に書く前提なのかな？ 理解を促すためのサンプルコードとしてはツッコミどころが多い気がする。

```php
$sub = $this->User->getDataSource();
$this->User->find(
	'all',
	[
		'conditions' => [
			$sub->expression(
				sprintf(
					'User.id NOT IN (%s) ',
					$sub->buildStatement([
							'fields'     => array('id'),
							'table'      => $sub->fullTableName($this->User),
							'alias'      => $this->User->alias,
							'conditions' => [
								'status' => $sub->value('B')
							]
						],
						$this->User
					)
				)
			)
		]
	]
);
```

書き直してみた。

> そのためにはまず、モデルのデータソースを取得して、クエリを組み立てます。 find メソッドを呼ぶような感じですが、これは SQL 文字列を返します。 その後、expression を呼び出し、その戻り値を conditions 配列に追加します。

ポイントは、少し複雑な条件をconditionsに渡すために `expression()` を使うということ。その他は余計な情報のように思う。

```php
$this->User->find(
    'all',
    [
        'conditions' => [
            $this->User->getDataSource()->expression(
                "User.id NOT IN (SELECT id FROM user WHERE status='8')"
            )
        ]
    ]
);
```

サブクエリ句はオブジェクトとかじゃなくてSQL文を渡しているだけなので、簡単なSQL文なら割り切って上記のように。buildStatement()は仕様が中途半端なので、使わずに済むなら使わない。

```php
$this->find(
    'all',
    [
        'conditions' => [
            $this->getDataSource()->expression(
                "User.id NOT IN (SELECT id FROM user WHERE status='8')"
            )
        ]
    ]
);
```

行儀よくモデルに書く場合は上記のように書ける。

```php
$this->find(
    'all',
    [
        'conditions' => [
            "User.id NOT IN (SELECT id FROM user WHERE status='8')"
        ]
    ]
);
```

実はこれでも動作する・・・覚えることなんて何もない。

`buildStatement()` がもう少し実用的なら生SQL書いたりしないんだけど。


# from・joinでサブクエリ

```php
$this->getDataSource()->buildStatement(
	[
		'table' => "(SELECT id, name FROM user WHERE status='active')",
		'alias' => 'u'
	],
	$this
);
```

buildStatement()の使い方の話になるけど、両端をカッコで囲めばサブクエリとして認識してくれる。カッコがないとテーブル名として認識してしまうため、DB名が追加されたりクォートで囲まれたりする。この書き方は公式ドキュメントで見つけることができなかった。

これもbuildStatement()を使わなくてすむなら使わないほうがいい気がする・・
`'alias' => 'u'` とか第２引数の`$this`とか、必要なくても書かないとエラーになったり、イケてない感じなので。
非同期関数のループ処理 - Part3（forLoop + 非同期関数内部でthenメソッド使用）

##他の処理方法との違い
Part1ではforEach + async/await、Part2ではforLoop + async/awaitを使いましたが、今回は、async/awaitなしでforLoopを実行します。ただし、その際にループ処理の対象となる関数fakeDatabaseQuery内部では、promise + thenメソッドを使用します。

Part2との違いは、async/awaitなしでforLoopを回している点、および、フェイク非同期関数内部でpromiseとthenメソッドを使い連続した非同期の処理を行っている点となります。

また、今回はasync/awaitなどの逐次処理を実施する仕組みがなく、アウトプットの順番がランダムになるため、ファンクションarraySorterによって、元の順番に戻しています。

##ループ処理の内容
フェイク非同期関数（fakeDatabaseQuery）を作成し、forLoopでこの非同期関数を100回実行します。

ループ処理によって、promiseオブジェクトが連続的に作成されますが、それぞれのpromiseはresolveされた順番で次の.thenの中のプロセスに渡され、処理されていきます。

ただし、promiseを生成する段階で、わざとsetTimeoutが、Math.random()によって生成されたelapseの値を使って、resolveする際の遅延を作り出していますので、当然、次の.thenの中で実施されるアレイfakeSearchResultに結果を詰め込んでいく作業についても、そのelapseの値に影響を受けて順番がバラバラになります。

##まとめ
今回は、async/awaitなしで、forLoopによりフェイク非同期関数（fakeDatabaseQuery）を実行していますが、そのフェイク非同期関数内部ではpromiseとthenメソッドを使用した処理が行われます。
Part2のようなサスペンドされた状態が生じないため、結果として非常に高速な処理を実現しています。

##その他
下記のサンプルコードは、Node.js v14.15.5でテストしたものです。また、私が利用している環境（Ubuntu + Node.js）では、処理時間は110ms ~ 120msとなりました。

##サンプルコード

```JavaScript
console.time();

//整数が1～100まで並んでいるarrayを作ります
let arrayN = [];
const arrayLength = 100;
for (let i = 0; i < arrayLength; i++) {
    arrayN[i] = i + 1;
}

let fakeSearchResult = [];

function arraySorter(array){
    array.sort(function(a, b) {
        return a.index - b.index;
    });
}

//fakeDatabaseQuery内部で、プロミスとthenメソッドを利用した連続した非同期の処理を行います。
function fakeDatabaseQuery(item, length) {
    //ランダムナンバーにより2桁の整数を生成
    const elapse = Math.floor(Math.random() * 100);
    const promise = new Promise(function(resolve, reject) {
        const obj = {index:item, elapse: elapse};
        //setTimeoutを使い、意図的に遅延を作りだしています
        setTimeout(() => resolve(obj), elapse);
    });

    promise.then((obj) => {
        fakeSearchResult.push(obj);
        let fsrLength = fakeSearchResult.length;
        if (fsrLength === length){
            console.log('fakeSearchResult-1:',fakeSearchResult);
            arraySorter(fakeSearchResult);
            console.log('fakeSearchResult-2:',fakeSearchResult);
            console.log('Yeah!');
            console.timeEnd();
        }
    })
}

function processArray(array) {
    const length = array.length;
    for (let i = 0; i < array.length; i++) {
        fakeDatabaseQuery(array[i], length);
    }
    console.log('Donatta?');
}

processArray(arrayN);

```

https://qiita.com/soichirowada/items/894be5a2532b477c4b29

https://qiita.com/soichirowada/items/77d358ea64f85d21667b

https://qiita.com/soichirowada/items/7f0ad6c55075252ee012

https://qiita.com/soichirowada/items/263ee198c3d793be6f59
総当たり攻撃されやすいファイル名まとめ

定期的にWebサイトにURLの総当たり攻撃がくるので、そのURLをまとめてみました。

この記事を見た皆さんは、誰でもアクセスできる場所に機密情報を置かないこと、どうしても置く場合は下記リストに含まれているファイル名にしないこと、にご注意ください。

```
[サイト名].sql.gz
[サイト名].com.sql.gz
0.sql.gz
01.sql.gz
02.sql.gz
12.sql.gz
123.sql.gz
1234.sql.gz
12345.sql.gz
1234567.sql.gz
2020.sql.gz
_db.sql.gz
a.sql.gz
access.sql.gz
account.sql.gz
adminer.sql.gz
affiliates.sql.gz
api-v1.sql.gz
api.sql.gz
apiv1.sql.gz
apps.sql.gz
april.sql.gz
archive.sql.gz
asd.sql.gz
august.sql.gz
b.sql.gz
backup.sql.gz
base.sql.gz
beta.sql.gz
bigdump.sql.gz
billing.sql.gz
checkout_payment.sql.gz
clients.sql.gz
customers.sql.gz
database.sql.gz
db.sql.gz
db_mysql.sql.gz
default.sql.gz
dev.sql.gz
download.sql.gz
dummy.sql.gz
dump.sql.gz
dumps.sql.gz
e-shop.sql.gz
e_order.sql.gz
e_user.sql.gz
eshop.sql.gz
export_db.sql.gz
february.sql.gz
files.sql.gz
forum.sql.gz
forumbackup.sql.gz
fuck.sql.gz
fuckoff.sql.gz
hack.sql.gz
january.sql.gz
july.sql.gz
june.sql.gz
local.sql.gz
management.sql.gz
march.sql.gz
market.sql.gz
marketplace.sql.gz
mobile.sql.gz
mysql.sql.gz
mysqldump.sql.gz
mysqldumper.sql.gz
mysqldumper2.sql.gz
new.sql.gz
newdump.sql.gz
old.sql.gz
orders.sql.gz
paypal.sql.gz
personal.sql.gz
private.sql.gz
psql.sql.gz
sales.sql.gz
sample.sql.gz
sql-dump.sql.gz
sql.sql.gz
sql2019.sql.gz
sql2020.sql.gz
sql_dumps.sql.gz
store.sql.gz
support.sql.gz
survey.sql.gz
surveys.sql.gz
test.sql.gz
testdata.sql.gz
thursday.sql.gz
tuesday.sql.gz
upload.sql.gz
users.sql.gz
v1.sql.gz
web.sql.gz
web1.sql.gz
wizard.sql.gz
www.sql.gz
xdb.sql.gz
xf.sql.gz
yearly.sql.gz
yes.sql.gz
yesterday.sql.gz
zero.sql.gz
zone.sql.gz
```
はんだごてを Hack - 格安T12はんだごてを試してみる 

(夏休み企画 13/20)
はんだごてを Hack していろいろ楽しいことをしようとしています。Hack のベースとなるはんだごてをいろいろ試してみました。


![IMG_20210920_213044.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d3d278e4-2213-51ae-fcd9-1070bb9825a4.jpeg)


今回は、格安な T12 はんだごてセットを Taobao から買ってみました。

https://item.taobao.com/item.htm?spm=a1z09.2.0.0.690d2e8duGSIyi&id=600544741552&_u=e1ieqpngefee
これの、T12+24V电源+KU[送Y型烙铁架海绵] と T12+24V电源+BC3[送Y型烙铁架海绵] 各68元 送料含めなければ、約1500円ぐらいです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/9ba18116-059f-32a8-6c9c-85372a45142d.png)



取扱説明書です。
![IMG_20210920_192726.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/bf8fa0f4-7b93-8857-14ce-5b2321adfe4c.jpeg)

簡易コテ台がついてきています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/fb917ccc-df38-e4a0-2ee1-276f65faff7d.png)


やってきたACアダプタは日本仕様のものではありません。敢えてデフォルトのまま購入しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/b2d80db8-1514-774b-3ac9-cebb53e4f65c.png)


コテ先はT12タイプ。いろいろ選べます。今回は CF4 と KUタイプを購入。T12というのはコテ先とヒーターが一体になっているタイプです。クイックなレスポンスと、ヒーターの不具合時に交換しやすいというメリットがあります。
![IMG_20210920_193155.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/5e360cbf-3a35-3565-fb5f-a3b38b8bf2d6.jpeg)



分解して制御基板を取り出してみました。

![IMG_20210920_192837.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/1a999b90-d004-a1ae-700c-22d13c64277a.jpeg)
拡大。LM358はオペアンプ。4409 
BA9H13 と書いてあるのは MOSFET らしいです。

![IMG_20210920_192901.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/bbe8877f-2a60-ee8d-35fa-1b9dc512e3f1.jpeg)

CPU は入っておらず、アナログ制御ぽいです。このバリエーションで、マイコンを結線し、内部に NeoPixel などを入れてみようかと思っていました。

組戻してコテ先取り付けたところ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a54ac485-5d84-06cc-4976-2fb6f0414871.png)


ACアダプタを使うタイプは、ここがモゲやすいです。この製品は筐体ネジ止めなので、ジャック部分は大丈夫かな。しかしプラグは抜けやすいのが気になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/6a7bf311-7e7c-680d-4a59-01af19d59807.png)

ダイヤルは温度表示無いですが、青LEDがヒートモニターとなっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/134689b3-c510-5797-9a72-3e83a551cd26.png)

仕様を止める時はACアダプタを抜けばいいのは安全対策の点で使いやすいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/e3e93427-972f-d091-1786-10ebdbc33645.png)

24Vで使うとかなりクイックな使用感が得られます。さすがに T12 です。キッズに使ってもらう時に、AC IN 方式だとコードのモーメントが大きいのが気になっていました。これは ACアダプタ式なのでコードは重くないのがいいです。でも重いACモジュールに引っ張られないようにに気をつけるのがいいかも知れません。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/5436ee93-02d5-e5e9-d1f6-e6a56ddf8e09.png)、


また小ナイフタイプである KUタイプは使いやすく、当たりでした。ノーブランドのT12コテ先ですが、最初の使用感は上々です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a78fbc06-880c-bcec-cd62-95b461060dfe.png)

# Hack ベースとしての考察

マイコンのチップオフなどのアグレッシブなHackにも使えるようにしたいと考えているのですが、そのような用途には アース が必須となります。
このタイプはACアダプタをGND対応のものを選ぶとアース対応はんだごてにできるかなと思いましたが、ACアダプタのGNDとコテ先は電気的に絶縁されていました。これをもっと作り変えればどうにかなりそうですが、今回はその方向はあきらめてこのはんだごてを素材にするのはミ告りました。
データサイエンス領域のPoCでもGitHub Flowで引き継ぎやすいコードを開発しよう

# はじめに
データサイエンス領域のPoCを実施するときに、「検証だからコードはとりあえず動けばOK」という考え方で、ソースコードが汚い状態のまま放置されていたりしないでしょうか？
PoCの間はそれでいいのでしょうが、後にシステム化する際や、別の人に引き継ぐときに、引き継ぐ側の人が大変苦労します（私は実際に苦労しました）
そんな悲劇を防ぐために、データサイエンス領域のPoCでもGitHub Flowに沿って開発したほうがいいのではという記事です。

# プロジェクトで起こっていた問題
私はこれまでにいくつかのPoCプロジェクトの引き継ぎ（引き継ぐ側）を経験しました。
そして、ほぼ全ての案件で次のことが起こっていました

- 複数の開発者がそれぞれの作業ディレクトリにコードを残していてどれが最終バージョンかわからない
- 手順書通りに動かしても、ソースコードが動かない

ということで、引き継ぎにはかなり苦労しました。
GitHubを導入していないのか！？と思われるかもしれないですが、導入しています。
導入しているのですが、開発途中のものをpushして終わっていたり、「GitHubにはAさんのディレクトリがpushされているが、一部Bさんが書いたコードを使わないといけない（BさんのコードはGitHubにはない）」みたいなことが起こっていました。

信じられないと思う方もいるでしょうが、エンジニアのバックグラウンドなしにデータサイエンティストになっていたりすると、こんなことはよくある話なのかなと思いました。
そこで、私が推奨している方法は、PoCでもGitHub Flowを使うことです。
これによって、上記の問題はある程度軽減されるのではないかと考えています。

# GitHub Flowとは？
GitHubが推奨している開発フローです。
公式ガイドはこちらにあります
→https://guides.github.com/introduction/flow/

大まかに言うと、次の流れになります
1. gitのブランチを切ってブランチ上で機能開発をする（ブランチは機能ごとに切る）
2. 開発が終わったらPull Requestを送る
3. 第三者がコードレビューを行う
4. コードレビュー完了後にmasterブランチに変更をマージする

# GitHub Flowを使うとなぜ問題が解決されるか
では、いまご紹介したGitHub Flowを使うとなぜ冒頭の問題が解決されるのでしょうか。
まず、1つめの課題

- 複数の開発者がそれぞれの作業ディレクトリにコードを残していてどれが最終バージョンかわからない

に対しては、GitHub Flowを適切に運用すれば各個人の変更内容は順次masterブランチに統合されていき、masterブランチが全員の変更が反映された最新バージョンになります。なので、引き継いだ人はGitHubにアップされているmasterブランチだけ確認すれば良いということになります。

また、2つめの課題

- 手順書通りに動かしても、ソースコードが動かない

については、GitHub Flowのコードレビューを途中で挟むプロセスで一定軽減できると考えます。
データサイエンス領域でよくある事例は、「自分の環境では動くが、環境設定や必要なファイル準備の手順が抜けていて他の人の環境では動かない」ということかと思います。
このような場合、コードレビュー時に動作確認しようとすると動かないので、その時点でコードを書いた人が修正することになります。
見落としもあるかとは思いますが、ある程度この課題は軽減できると思っています。

# 実際にGitHub Flowをプロジェクトで導入した結果
実際に私が携わるプロジェクトではGitHub Flowを導入してみました。
そうすると、引き継ぎ時の問題はほとんどなくなり、gitレポジトリをそのまま渡せばスムーズに動作確認が取れ、引き継ぎが完了するようになりました。
また、「コードレビューによって自分の書いたデータ処理、アルゴリズムが間違っていないと自信を持った上で次のタスクに進める」といった意見もあり、チームメンバーからも大変好評でした。

# よくある質問
### Q. Jupyter Notebook形式で開発しているのでgit管理には向かない
A. はじめはJupyter Notebook形式で実験的に開発していたとしても、ある程度内容が固まってきたら.py形式に変換してgit管理すればよいのではないかと思います。
参考として、もしVSCodeを使っているとしたら、.py形式のファイルをインタラクティブに実行する方法もあります。
→https://code.visualstudio.com/docs/python/jupyter-support-py

### Q. レビューでは何を確認すればよいか
A. まずは動作確認をしたほうが良いと思います。動作確認はテストコードで担保すべきという意見もあるかとは思いますが、データサイエンス領域のPoC段階だとそのままシステム化するわけではないですし、実験的にコードも変わっていくので手動で確認してもいいかと思います。
そのうえで、コードの中身を確認し、データ処理やアルゴリズムに間違いがないかをチェックしていきます。
意外と、よく読むとソースコードが間違っていることはよくあります。（一見ちゃんと動いているので厄介です。これもデータサイエンス領域特有かもしれないです）

# まとめ
以上、私が引き継ぎで感じた課題と、GitHub Flowで開発するとその課題が軽減されると考える理由を紹介しました。
同じ悩みを抱えている方がいらっしゃれば、ぜひ一度GitHub Flowを試していただきたいと思います。
また、もし別の解決策をご存知でしたら教えていただけると幸いです。
embulk-input-bigqueryをインストールするときにERROR:  Error installing embulk-input-bigquery:が出たときにやったこと

# 症状
embulk-bigquery-inputをインストールするときにハマってしまった。（embulk verison: 0.9.23）

```shell
embulk gem install embulk-input-bigquery -v 0.0.9
ERROR:  Error installing embulk-input-bigquery:
	google-cloud-errors requires Ruby version >= 2.5.
```

# 解決
google-cloud-env、google-cloud-coreの順番でバージョン指定でインストール操作したところ入りました。

```shell
embulk gem install google-cloud-env -v 1.2.1
embulk gem install google-cloud-core -v 1.3.2
embulk gem install embulk-input-bigquery -v 0.0.9
```

# 参考
- [embulkのgem installでRuby version >= 2.4.0と出た時は](https://zenn.dev/hiroysato/articles/35a26bbe466f0b)
- [Embulk gem install fail: google-cloud-errors requires Ruby version >= 2.4.](https://github.com/medjed/embulk-input-bigquery/issues/33)
【Jest】テストのスキップ

# はじめに
Jestを使っていて、処理が重い処理のテストを一時的にスキップしたい場合、skipを追加することで回避することができます。
[公式ドキュメント](https://jestjs.io/ja/docs/api#describeskipname-fn)

#  検証

* ```describe```、```test```、```it```関数に```.skip```追加するとテストの実行をスキップすることができます。


```javascript:sum.js
export const sum = (a,b)=> a + b;
```

```javascript:sum.test.js
import { sum } from "./sum";

//skipを追加した。
test.skip(`add 10 + 20 to equal 30`, () => {
  expect(sum(10, 20)).toBe(30);
});

```

実際にテストを実行すると、テストがスキップされていることが確認できます。

```sh
yarn test /Users/jest-basic/src/sum.test.js
yarn run v1.22.11
$ jest /Users/jest-basic/src/sum.test.js
Test Suites: 1 skipped, 0 of 1 total
Tests:       1 skipped, 1 total
Snapshots:   0 total
Time:        0.514 s, estimated 4 s

✨  Done in 1.86s.
```
はんだごてを Hack  - RISC-V はんだごて PINECIL 

(夏休み企画 12/20)


Pinecil という RISC-V CPU の ハンダゴテを購入しました。
https://www.pine64.org/pinecil/


![IMG_20210920_183906.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c09c1b38-01e6-3d80-4340-7728bb39431b.jpeg)


- GigaDevice GD32VF103TB chipset 32-bit RV32IMAC RISC-V “Bumblebee Core” @ 108 MHz
- 電源USB-C PD および ACアダプタ入力12V-20V 3A
- 0.69″ OLED 白ディスプレイ 96x16ピクセル
- $24.99 この種類のハンダゴテとして値段安め
- コテ先 Type B2

# 注文

- 本体 x 1
- 透明筐体 x 1
- ブレークアウトボード x 2

2021/8/26 に注文、
2021/9/1 CHINA 発で
2021/9/16 に自宅の郵便受けに投函されてました。

送料が以下の選択だったので、「Standard Shipping Method」を使用しています。

- Courier Shipping Method – 30: $30.00
- Standard Shipping Method: $11.99

# ケース交換

オプションで透明ケースを購入しました。$5.99 今回はこれに交換してみます。

![IMG_20210920_183916.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/9edb95a2-c6c0-b627-ce61-a2a4830a7365.jpeg)



ワリバシをカッターで削ったドライバーを使って、ここから取り外すとキズをつけずに殻割りできます。

![IMG_20210920_185023.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/8d926cb7-6fce-9faf-6c04-73209676b324.jpeg)


この位置の電極を外します
![IMG_20210920_185155.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/691eaf44-6773-350c-b017-5fc9d4d98aef.jpeg)
外した電極

![IMG_20210920_185221.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/f194ed54-4042-db47-6a98-6be9c3ec1d0d.jpeg)




カバーを交換して組み上げたところです。

![IMG_20210920_191947.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/722d693b-89c1-7173-fd57-bd3cc76ee10b.jpeg)

# I/Oボード

Paincil GPIO break-out through USB-C port


![IMG_20210920_184050.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/204ff2bc-a696-0a8b-7808-5220ba2d3647.jpeg)

1セット $3.99 でした。
本体とUSB Type C で接続してI/Oが使えるようになるそうです。
PowerAppsでTeams投稿アプリを作成する①

#選択したチャンネルへの投稿機能の作成

##作成するもの
PowerAppsの画面上で選択したチーム・チャンネルに、任意のメッセージをサブジェクト付きで投稿するアプリ。ひとまずポカよけとかは考えず最低限動くだけの処理を実装する。

アプリの操作イメージはこんな感じ↓

1. コンボボックス１にチーム一覧を表示させ、投稿したいチームを選択する
1. コンボボックス２に、↑で選択したチーム内のチャンネル一覧を表示させ、投稿したいチャンネルを選択する
1. 投稿のタイトル（サブジェクト）を入力する
1. 投稿したい内容（本文）を入力する
1. 投稿ボタンを押し、選択したチャンネルに投稿する

##1.Teamsコネクタの追加
キャンパスアプリを新規作成し、データからTeamsコネクタを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307669/1d2cd590-3850-4702-2783-d0e971f2edf9.png)

##2.コントロールの配置
下図の通り5つのコントロールを配置し、コントロール名を図のとおり変更します。
コンボボックスは2つ作成しますが、上が` ComboBox_Team` ,下が` ComboBox_Channel`です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307669/3b0e1634-8461-76ea-b0a4-0c0373c07da5.png)

##3.チーム一覧の取得
` ComboBox_Team`の`item`プロパティを下記のように変更します。

```:ComboBox_Teamのitem
MicrosoftTeams.GetAllTeams().value
```
実際の画面ではこんな感じ↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307669/9883068e-0f78-d9e8-353e-54167bb50972.png)

次に` ComboBox_Team`のプロパティのフィールド 編集をクリックし、` 主要なテキスト`と` SearchField`を両方とも` displayName`に変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307669/95eb4b0e-b763-6ce7-41a0-3e22abf1485e.png)
また、`複数選択の許可` はオフにしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307669/433120ce-47eb-311e-a970-13b03fe41a3e.png)



これで` ComboBox_Team`をクリックすると、Teamsで登録しているチーム一覧が表示されるようになりました。

##4.チャンネル一覧の取得
次に` ComboBox_Channel`コンボボックスでチャンネル一覧を表示できるようにします。
Teamsのチャンネル一覧は[GetChannelsForGroup](https://docs.microsoft.com/ja-jp/connectors/teams/#%E3%83%81%E3%83%A3%E3%83%8D%E3%83%AB%E4%B8%80%E8%A6%A7-(%E3%83%97%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC))コマンドで取得できますが、引数にチームIDを指定する必要があります。

ここでは、` ComboBox_Team`コンボボックスで選択したチームのチャンネル一覧を表示させるため、` ComboBox_Channel`の`item`プロパティを下記のように変更します。

```:ComboBox_Channelのitem
MicrosoftTeams.GetChannelsForGroup(ComboBox_Team.Selected.id).value
```
また、` ComboBox_Team`のときと同様にプロパティのフィールド 編集をクリックし、` 主要なテキスト`と` SearchField`を両方とも` displayName`に変更し、`複数選択の許可` はオフにしておきます。

##5.投稿ボタンの処理作成
` Button_Send`ボタンを押すとメッセージが投稿されるよう、`OnSelect`プロパティを下記のように変更します。

```:Button_SendのOnSelect
MicrosoftTeams.PostMessageToChannelV3(
         ComboBox_Team.Selected.id,
         ComboBox_Channel.Selected.id,
            {
                content: RichTextEditor_Message,
                contentType: "html"
            },
            {subject: TextInput_Subject.Text}
        )
```
これで、` ComboBox_Team` で選択したチーム内の` ComboBox_Channel` で選択したチャンネルにメッセージが投稿されます。メッセージのサブジェクトは` Textinput_Subject` に入力した文字列、本文は` RichTextEditor_Message` に入力した内容となります。

##6.ラベルの作成
5までで機能としては実現済みですが、分かりやすいようにラベルを付け、ボタンの表示を変更して完成！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307669/31592292-ea05-2b20-7875-9f93d674194f.png)

##関連記事
[PowerAppsでTeams投稿アプリを作成する②](https://qiita.com/zaki_001/items/2d0cc21e4e555e086912)
プログラミング初心者が書いたオブジェクト指向について①

はじめに
-------------
今までPHP/Laravelと学習を進めてきたのですが、そもそもコードの内容をあまり理解しきれていない現状に気づき
色々ありまして現在はJavaの学習を進めています。

Javaではオブジェクト指向という考えが非常に重要であり、またその考え方は他の言語にも
共通していくというのを知ったのでアウトプットとして基礎的なことをまとめていきたいと思います。

オブジェクト指向とは
-----------
**プログラムの機能や役割を区別し、それぞれを部品（オブジェクト）として組み合わせることで1つのプログラムを作ること。**

こうやって書くとふーんって感じですが、**現実の世界でも色んな物体が存在して組み合わさっている**と考えると僕は腹落ちしました！

例えば...

・車
→タイヤ、ハンドル、アクセル、ブレーキなどなど
・家
→屋根、扉、壁、床などなど
・人間
→手、足、頭、胴体などなど

**現実の世界と同じようにプログラミングの世界も考えた方がわかりやすいね！的な発想がオブジェクト指向なのかなぁと感じました。**

オブジェクト指向の専門用語
-----------
- **オブジェクト指向　→ 機能や役割を区別し、オブジェクト（部品）を組み合わせてプログラムする考え方**
- **オブジェクト　→ モノの総称**
- **クラス　→ 設計書**
- **フィールド　→ モノの情報**
- **メソッド　→ モノの振る舞い**
- **インスタンス化　→ 設計書を元に作った物体**

Javaのコードでオブジェクト指向を書く
---------
**1.まずは「自転車」という設計書を作ります。**

```Bycycle.java
class Bycycle {

}
```
※class Bycycleにて「Bycycle」というクラス名を宣言します。

**2.設計書のフィールドに情報を記述する**

```Bycycle.java
class Bycycle {
     String bycycleName = "A自転車";
     String color = "red";
}
```
※車の名前を表す文字列型のbycycleName
※車の色を表す文字列型のcolor

**3.設計書のメソッドに自転車の動作を記述する**

```Bycycle.java
class Bycycle {
     String bycycleName = "A自転車";
     String color = "red";

     void start(){
          System.out.println("発進します");
     }

     void stop(){
          System.out.println("停止します")
     }
}
```
※自転車の発進動作を表すstartメソッド
※自転車の停止動作を表すstopメソッド

**4.自転車の設計書をもとにし自転車を作る。**

```BycycleTest.java
class BycycleTest {
     public static void main(String[] args){
            Bycycle bycycle = new Bycycle();
     }
}
```
※ クラス名 変数名 = new クラス名();にてCarクラスをインスタンス化(実体化)して左辺のbycycleという変数に代入します。

**5.インスタンス化したオブジェクトにてメソッドを実行する

```BycycleTest.java
class BycycleTest {
     public static void main(String[] args){
            Bycycle bycycle = new Bycycle();
            bycycle.start(); //発信します
            bycycle.stop(); //停止します
     }
}
```

※変数名.メソッド名();と記述することによりBycycleクラスの中のstartメソッドとstopメソッドを呼び出すことができます！

まとめ
-----
- オブジェクト指向は複数の部品の組み合わせだということを意識すれば理解しやすい
- 設計書だけあっても動かせないため、必ずインスタンス化(実体化)して使えるようにする。
- クラスによって細分化すれば後からの変更があっても対応しやすい→柔軟化
- コンストラクタ・継承・オーバライド・オーバーロード・ポリモーフィズムなどについてはまた知識を定着させてから纏めたい。

参考記事
----
https://qiita.com/snyt45/items/55363a7a0634f38158d2
https://qiita.com/snyt45/items/c0164e409d7f54501060
→ほぼほぼ参考にしてしまい感謝です。。。
Unity SetActiveとenabledの違い

##0.0 はじめに
GameObjectやコンポーネントのアクティブ、非アクティブ状態をスクリプトからコントロールするためによくつかうSetActiveとenabledの違いの説明です。





##1.0 SetActiveの特徴
SetActiveはgameObject(オブジェクト)のアクティブ、非アクティブ化に使用します。
親オブジェクトを非アクティブにすると子オブジェクトも非アクティブになります。
gameObjectが非アクティブの場合はコンポーネントがアクティブになっていても何もイベントは動きません。




####1.1 使い方
()内のtrue/falseでアクティブ、非アクティブ状態をコントロールします。

```C#:Test.cs
gameObject.SetActive(false); // gameObjectを非アクティブ化
```

👍**ポイント**
gameObjectが非アクティブだとGameObject.Find()関数でgameObjectを見つけることができません。




##2.0 enabledの特徴
enabledはgameObjectにアタッチされている**コンポーネント**のアクティブ、非アクティブ化に使用します。

####2.1 使い方
直接.enabledにtrueもしくはfalseを代入します。

```C#:Test.cs
gameObject.GetComponent<Image>().enabled = false; // gameObjectのImageコンポーネントを非アクティブ化
```



##3.0 アクティブ、非アクティブの調べ方
gameObjectのアクティブ、非アクティブはactiveSelf と activeInHierarchy で調べることができます。

**activeSelf**：自身が有効であればTrueを返す。（親の非アクティブ化でHierarchy上で非アクティブとなっていても自身がアクティブならTure）
**activeInHierarchy**：親子関係に依存、親が非アクティブならFalseとなる。
Next.jsとは？ CSR/SSR/SSG/ISRについて

# はじめに
Next.jsについて、SSR/SSG、それと最近追加されたISRについて、最終的にどれを使うべきか自分なりにまとめました。既に多くの分かりやすい記事があり、参考にさせて頂きました。間違いがありましたら、ご指摘よろしくお願いします！

参考：
https://tech.012grp.co.jp/entry/2021/03/25/125014
https://qiita.com/jagaapple/items/faf125e28f8c2860269c

# Next.jsとは？
**元々はSSRを特徴とする**Reactベースのフロントエンドフレームワーク。
ページ毎に、レンダリング方法をCSR、SSR、SSG、ISRを選ぶことができる。

※元々はSSRが特徴であるが、現在では、webpackやBabelなどのビルド周りの最適化や、
Chunks、Code Split、リンク先ページのプリフェッチ等、最大限のパフォーマンス最適化、
ファイルシステムに沿ったルーティングによる開発体験の向上等、
様々な恩恵を受けられるフレームワークになっている。

# CSR/SSR/SSG/ISRについて
### CSR(Client Side Rendering)
**リクエスト時**に、JavaScript のソースと必要最小限で空っぽのHTML を返す。その後、クライアント側でページを構築。Reactはこれ。

- メリット
    - ページ遷移によるユーザーストレス軽減。必要な部分のみ更新すれば良いため。 

- デメリット
    - 初回アクセスが遅い。
    - パフォーマンスがクライアント依存。

### SSR(Server Side Rendering)
**リクエスト時**に、サーバ側でレンダリングして、クライアント側に描画。

- メリット
    - 初回アクセスが早い
    - パフォーマンスがクライアントに依存しない
    
- デメリット
    - Webサーバが必要、負荷が高い
    - サーバサイドのセキュリティの危険性

### SSG(Static Site Generator)
**アプリケーションをビルド時**に**DBやAPIからデータを取得し**、HTMLを生成しておく。

- メリット
    - SEOに強い
    - SSRよりも高速

- デメリット
    - 頻繁にデータ更新があるサイトには向かない
    - ページの数やコンテンツの数が多くなるとビルド時間が長くなる

### ISR
事前に生成せずに、**初回アクセス時**にHTMLを生成する。
尚且つ、一定期間ごとに静的ページの再生成をサーバ側で行う。
例えば、users/10に誰かがアクセスした際に、ページがない場合は、users/10.htmlみたいなページが作成され、以降は同様のアクセスがあった際は10.htmlを参照する。

- メリット
    - SEOに強い
    - SSGのBuild時間を短縮できる
    
- デメリット
    - ISRに対応したサーバ(Vercel)を使わなければいけない

# どれを使うのが良いのか
- 公式ではSSGが推奨されている。
- SSRは使わない方がいいという記事が散見される。
   （SSR用のサーバを用意しなければいけないことや、セキュリティの面が面倒。 ）

以上を踏まえると、
**完全に静的なページ、または動的コンテンツ（データ）が少ないページはSSG**
**動的コンテンツが多い場合は、ISR、CSR**
【Git】リベースの使い方と注意点

##リベースとは
ブランチの基点となるコミット（親コミット）を、別のコミットに移動すること。
コミットの履歴を一直線にしつつ、他のブランチの変更分を取り込む。

##リベースの使い方
【例】masterブランチにfeatureブランチを取り込みたい場合。

* 通常のmergeならば

```
//masterブランチにいる状態でmergeする
$ git merge feature
```

* rebaseを使ってからmergeするならば

```
//まずはfeatureブランチに移動する
$ git checkout feature

//featureブランチにいる状態でrebaseする
$ git rebase master

//ここでmasterブランチに切り替えて
$ git checkout master

//masterブランチにいる状態でmergeする
$ git merge feature
```

rebaseを行ってからmergeを行うとファストフォワードが起こり、mergeコミットは発生しない。

##リベースでのNG
`GitHubにプッシュしたコミットをリベースする`のは絶対にNG。

プッシュしたコミットをリベースして、それをまたプッシュしようとすると、プッシュ出来ないようになっている。
`$ git push -f`で強制的にプッシュすると、Gitの履歴が完全に壊れてしまうので、行ってはいけない。

##マージとリベースの比較

####マージ
* メリット…コンフリクトが1回しか生じない。
* デメリット…マージコミットがたくさんあると、履歴が複雑化する。

####リベース
* メリット…履歴を綺麗に（一直線に）保つことができる。
* デメリット…コミットそれぞれに、コンフリクトの解消が必要。

####使い分けのコツ
プッシュしていないローカルの変更にはリベースを使い、プッシュした後はマージを使う。
コンフリクトしそうならマージを使う。

またPush前にコミットをきれいに整えたり、コミットメッセージを書き換えたいときには、リベースが使える。
※GitHubにPushしていないコミットはリベースしてはいけない。

##リベースで変更履歴を変更する
###直前のコミットをやり直す
今のステージの状態で、コミットを上書きする。

```
//コミットしたい内容で、git addを済ませておく
$ git commit --amend
//commitした時のコミットメッセージが立ち上がり、書き直すことができる
```

###複数のコミットをやり直す

```
$ git rebase -i コミットiD

//直前3つのコミットをやり直す
$ git rebase -i HEAD~3
```

###コミットを修正する手順
1. 上記コマンドを実行し、対話的リベースモードに入る。するとエディタが立ち上がり、`pick コミットiD コミットメッセージ`の情報が指定した件数表示される。
2. 修正したいコミットの`pick`という文字を`edit`と書き直し、コミットエディタを閉じる。
3. editのコミットの内容を修正できるようになっているので、ローカルでファイルを編集し、`git add`したうえで、`git commit --amend`を実行する。
4. `git rebase --continue`コマンドを実行して、リベースを完了する。
※この際、`pick`のコミットはそのままのコミット内容を適用して次へ進む。

###コミットの指定方法
* HEAD
最新のコミットのこと。

* HEAD~
最新のコミットの親コミットを指定する。

* HEAD~数字
HEADを基点にして、数値分の親コミットまで指定する。

* HEAD^（数字）
マージした場合の親を指定する。
数字については同上。

<br><br>
##参考教材

https://www.udemy.com/course/unscared_git/
Unity Vector3/Vector2の変数　まとめ

##0.0 はじめに
座標や方向を表すVector3やVector2のベクトルでよく使う変数をまとめました。

##1.0 Static変数
forwardとback以外はVector2も同じStatic変数を持っています。
下記はVector3での例です。

|  変数  |  　　使い方  |  　　　意味  |
|:----:|:----|:----|
|zero|　Vector3.zero|　Vector3(0, 0, 0)|
|one|　Vector3.one|　Vector3(1, 1, 1)|
|up|　Vector3.up|　Vector3(0, 1, 0)|
|down|　Vector3.down|　Vector3(0, -1, 0)|
|right|　Vector3.right|　Vector3(1, 0, 0)|
|left|　Vector3.left|　Vector3(-1, 0, 0)|
|forward|　Vector3.forward　|　Vector3(0, 0, 1)　|
|back|　Vector3.back|　Vector3(0, 0, -1)|


 
##2.0 変数
magnitudeは速さなどの大きさを取得するときに使われます。
normalizedは大きさを１にするので正規化と呼ばれています。

|  変数  |  使い方  |  意味  |
|:----:|:----:|:----|
|magnitude|vector.magnitude|ベクトルの長さ（読み取り専用）| 
|normalized|vector.normalized|magnitude を 1 としたベクトル（読み取り専用）|
|sqrMagnitude|vector.sqrMagnitude|ベクトルの 2 乗の長さを返します（読み取り専用）|
|this[int]|vector.this[int]|[0]、[1]、[2] を使用して x や y や z 成分にアクセス|
全EC2のタグ情報を取得しJSON形式にするメモ

## はじめに

AWS EC2 のタグ情報を取得し、JSON形式にするPython3.9スクリプト
EC2タグ情報を、SDK(boto3)の `describe_instances()` で取得しました。

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.describe_instances

`describe_instances()`で一度に取得できる情報は最大1000のようで、1001以降の情報を取得するには、`NextToken` を使用するようです。

## スクリプト

- 処理概要
    - 全てのEC2タグ情報を取得するため`NextToken`の処理を記載
    - 取得した情報を変数 `ec2tagsjson` にJSON形式で格納
    - ただし、タグキーが `aws:` から始まる情報は、取得対象から除外

```python:getEc2TagsInfo.py
import boto3
import sys

# python バージョン確認
if sys.version_info >= (3,8):
    print('Python Version Check [OK] : {0}'.format(sys.version_info) )
else:
    print('Python Version Check [NG] : {0}'.format(sys.version_info) )
    exit()

client = boto3.client('ec2')

ec2tagsjson = {}
NextToken = None
while True:
    if NextToken is None:
        ec2_info = client.describe_instances()
    else:
        ec2_info = client.describe_instances(NextToken=NextToken)

    for Reservations in ec2_info['Reservations']:
        for instances in Reservations['Instances']:
            tagsjson = {}
            for tag in instances['Tags']:
                if tag["Key"].find('aws:') != 0:
                    tagsjson[ tag["Key"] ] = tag["Value"]
            ec2tagsjson[ str(instances['InstanceId']) ] = tagsjson

    if not 'NextToken' in ec2_info:
        break
    NextToken = ec2_info['NextToken']

print(ec2tagsjson)
```

## 実行結果例

JSON形式で、インスタンスIDごとにタグ情報をまとめた情報が表示されます。

```console
$ python getEc2TagsInfo.py
Python Version Check [OK] : sys.version_info(major=3, minor=9, micro=4, releaselevel='final', serial=0)
{'i-00000000000000001': {'test2': 'test2Val', 'Name': 'HOGE', 'test1': 'test1Val'}}
```

インスタンスIDが、`i-00000000000000001` のEC2に付与された3つのタグの情報をJSON形式で表示しています。

---