OmniAICreator/Qiita-1.07M huggingface dataset:
【Rails】gemとbundleについてまとめてみた

### 1.はじめに
Rubyには様々なライブラリが用意されており、Railsもその1つです。
Railsではライブラリをパッケージ化したgemというものを使用します。
今回はgemとbundleについて概念的なところをまとめてみました。

### 2.使用環境
- mac.os バージョン10.15.6
- Ruby 2.7.2
- Rails 6.1.3.1
- psql (PostgreSQL) 12.6

### 3.gemとは
**ライブラリ**をパッケージ化したもの。
※ライブラリ：汎用性の高いプログラムを再利用できる形でまとめたもの。利用することで素早く生産的にプログラミングをすることができます。

#### 3.1どんなgemがインストールされているか確認したい
`gem list`で確認できます。

```ruby
#プロジェクト内で確認したい場合
project_name % gem list

*** LOCAL GEMS ***

# gem名 (カッコ内はバージョン名) が表示される
...
```
#### 3.2gemを追加したい
①`Gemfile`というファイル(を作成し、)記述します。

```ruby
# Gemfile(アプリケーション直下)上に記述
gem '追加したいgemの名前', 'バージョン（バージョンも指定する場合は入れる）'

# 例
gem 'rails', '~> 6.1.1'
```
②`bundle install(もしくはbundle)`コマンドを入力すると`Gemfile.lock`というファイルが作成され、gemを使用することができます。
※サーバー起動中の場合はインストールされたgemを利用するためにサーバーの再起動が必要になります。

### 4.bundle（bundler）とは
bundleとは「束、かたまり」という意味です。プロジェクト内ではどのgemをどのバージョンで利用するのかが大事ですが、gemコマンドでは管理しきれません。
そこで`Bundler`というツールを利用します。
Bundlerはプロジェクトで使うgemを束ねて、どのgemのどのバージョンが必要か明示する仕組みです。
先ほどの`bundle install(もしくはbundle)`はBundlerのコマンドです。
コマンドの一部を下記に示します。

```ruby
#Bundlerを利用するにはインストールが必要
$ gem install bundler

#以後Gemfileにgemを追加した際はbundle installを行う
$ bundle install

# –path vendor/bundleをつけると特定のプロジェクト（ディレクトリ）にのみ導入される
$ bundle install –path vendor/bundle

# Bundlerが管理するgemを利用できる状態でコマンドを実行する
# Gemfile.lockに書かれているバージョンのgemが動き、その状態でコマンドの内容が実行される
$ bundle exec [コマンド]

# 初期状態のGemfileをカレントディレクトリに作成する
$ bundle init

# Bundlerが管理するgemのバージョンを更新する
$ bundle update
```
### 5.調べてみて
なんとなく使用していたgemとbundleについて整理することができました。
現在共同開発を行なっており、バージョン管理は重要だと感じているので、引き続き理解を深めていきたいと思います。

### 6.参考
書籍：大場寧子他, 現場で使えるRuby on Rails5速修実践ガイド, マイナビ出版, 2018.

https://tech-camp.in/note/technology/55305/

https://www.eiji56.com/2018/08/bundle-exec/

https://qiita.com/d0ne1s/items/fa2dafcee02e963fe997

### 7.最後に
記事の感想や意見、ご指摘等あれば伝えていただけるとありがたいです。
読んでいただき、ありがとうございました。
多重ループで指定された文字が文字列に含まれているかどうかチェックするプログラム

多重ループで指定された文字が文字列に含まれているかどうかチェックするプログラムを作成いたしました。

```C++
/* 作成日 2021/5/19
   作成者 nogizakapython
*/

#include <iostream>
#include <vector>
using namespace std;

int main() {
    int m; 
    cin >> m;
// 指定された文字を配列cに格納するフィールド定義
    vector<char> c(m);

    for (int i = 0; i < m; i++) {
        cin >> c[i];
    }

    int n; 
    cin >> n;
//　文字列を配列sに格納するフィールド定義
    vector<string> s(n);

    for (int i = 0; i < n; i++) {
        cin >> s[i];
    }

    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            //文字が含まれているかを判定するフラグ(boolean型の変数を定義しても良い)
            int yes_flag = 0;
            for (int k = 0; k < s[j].length(); k++) {
            //配列0の文字列の1文字目から順に指定された文字が含まれるかチェックする
　　　　　　 // 一致した場合、yes_flagを1にする(boolear型の変数をfalseからTrueにしても良い）
                if (s[j][k] == c[i]) {
                    yes_flag = 1;
                }
            }
            //文字列が含まれていれば「YES」含まれていなければ「NO」を画面に出力する。
            if (yes_flag == 1) {
                cout << "YES" << endl;
            } else {
                cout << "NO" << endl;
            }
        }
    }
}
```

以上の処理になります
Googleマップをレスポンシブに対応させるタグ テンプレ

#html
```
<div class="googlemap">
<!--ここにgooglemapの埋め込みタグ挿入　下記は例-->
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d1620.4218482046147!2d139.76625067604036!3d35.680850473725954!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x60188bfbd89f700b%3A0x277c49ba34ed38!2z5p2x5Lqs6aeF!5e0!3m2!1sja!2sjp!4v1621378058031!5m2!1sja!2sjp" width="600" height="450" style="border:0;" allowfullscreen="" loading="lazy"></iframe>
<div>
```
#scss,sass
```
.googlemap {
height: 0;
overflow: hidden;
padding-bottom: 56.25%;
position: relative;
iframe {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
}
}
```

#css
```
.googlemap {
height: 0;
overflow: hidden;
padding-bottom: 56.25%;
position: relative;
}
.googlemap iframe {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
}
```
Rails メソッドを定義する（引数・戻り値・ストロングパラメーター の設定方法）

#メソッドとは何か？
　メソッド【method】の意味を調べてみると、「目的を達成するために決められたやり方。方法。方式」「オブジェクト指向プログラミングにおいて、オブジェクトに対する操作を定義した手続き」とあります。

#メソッドを定義する方法

メソッドを定義するには、実行する処理内容をdef ～ end 内に記述します。
基本の書き方は以下のようになります。

```
def メソッド名(引数)  # 引数は任意
  # 実行する処理内容
end
```
#2種類（引数・戻り値）を使うとは？
**「引数」**とは、関数に何らかの処理をする際に渡す値のことを指します。

**「戻り値（返り値）」**は、メソッドが呼ばれたときに返ってくる値のことです。def ～ end 処理内の最終結果が戻り値になります。



#メソッドの実例

```csharp
def communication(name)
  "Hello, #{name}"  # 戻り値
end
puts communication('Taro')  # 'Taro'を引数として渡す
```
【意味】communicationというメソッドで、nameという引数を受け取る。そして "Hello, #{name}!"にnameという引数を渡して、表示することができる。

【詳細】
①引数を作成：puts communication('Taro') 
②メソッドを設定：def communication(name)~ end
③引数('Taro') ⇒(name)へ入る
④メソッドで定義された動作を行う戻り値を設定：**"Hello, #{name}"**
流れ：('Taro') ⇒(name)⇒"Hello, #{name}" ⇒Hello,Taro

#投稿フォームなどを使用する場合

```csharp:〇〇_controller.rb
  def create
    @book = Book.new(book_params)
    @book.save
      redirect_to book_path(@book)
  end

  private
  # ストロングパラメータ

  def book_params
    params.require(:book).permit(:title, :body)
  end
```
【**各部説明**】
  **privateストロングパラメータとは**
 ストロングパラメーターとは、指定したキーを持つパラメーターのみを受け取るように制限するもの。※今回permit(:title, :body)に絞った。

 ストロングパラメーターを使用する理由は、受け取るパラメーターを制限しなければ、仕様以外のパラメーターも使われてしまうため。この状態だと、意図しないデータの更新をされる可能性が発生しまう。

 たとえば、他人のログインパスワードを変更するパラメーターを追加で送信すれば、勝手にパスワードを変更できてしまう。これを回避するために、ストロングパラメーターを使用し、パラメーターを制限する必要がある。
この仕組みがprivateの行から下のコード。

**book_paramsの定義**
book_paramsではフォームで入力されたデータを受け取っている。
paramsはRailsで送られてきた値を受け取るためのメソッドです。
requireでデータのオブジェクト名(ここでは:book)を指定し、permitでキー（:title,:body）を指定。
これにより、book_paramsの中にフォームで入力されたデータが格納される。

**require(:モデル名)の意味**
登録するのはどのテーブルなのか？ということを指定するために必要です。今回は、require(:book)となるのでbookのテーブルへ登録したい！ということです。

【**流れ**】
①ストロングパラメータで入力する内容と保存先を設定する

②createアクションでストロングパラメータ（入力フォームや保存先を設定したもの）を引数として入れる。

```
 def create
    @book = Book.new(book_params)
```
⇒book_paramsを使うと入力内容・保存先を設定・指定することができる。

③遷移先で入力した人のshowページへ移動する場合

```
    @book = Book.new(book_params)
    @book.save
      redirect_to book_path(@book)
```
⇒@bookの変数で@book =Book.new(book_params)と新規で入力した方を設定。
遷移先redirect_to book_path(**@book**)の
**@book**は**Book.new(book_params)**を示す。そのため投稿者のページへ遷移することができる。

#ストロングパラメータではprivate・protected2種類の設定がある

**private**は、自分のコントローラ内でしか参照できません。

```csharp
  private
  def book_params
    params.require(:book).permit(:title, :body)
  end
```

**protected**は呼び出された他のコントローラからも参照できます。
⇒主に、application_controller.rbで使用することが多い。

```csharp
  protected
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
  end
```


#まとめ
引数や戻り値を設定することで、値を代入し効率的に表示をできる。
Wordpress 同じカテゴリの記事を関連記事として出すタグのテンプレ

コピペでどうぞ

```
<?php
$categories = get_the_category($post->ID);
$category_ID = array();
foreach($categories as $category):
	array_push( $category_ID, $category -> cat_ID);
endforeach ;
$args = array(	
	'post__not_in' => array($post -> ID),//現在の記事を除く
	'posts_per_page'=> 10,//件数指定
	'category__in' => $category_ID,//現在の記事と同じカテゴリ
	'orderby' => 'rand',//ランダムに記事を選ぶ
);
$query = new WP_Query($args);
if( $query -> have_posts() ):
	while ($query -> have_posts()) :
	$query -> the_post();
?>
<!--ループ-->
<a href="<?php the_permalink(); ?>"><?php the_post_thumbnail('thumbnail'); ?><?php the_title(); ?></a>
<?php endwhile; endif; ?>
<?php wp_reset_postdata(); ?> 
```
チームでZoomライセンスを効率よく使う方法

# この記事の目的

チームでZoomのライセンスを効率よく（かつ、規約に抵触せずに）使う方法を考える

# 結論としては

何を重視するかにより選択肢は変わるがおおむね以下の通りのお勧め度になる

**（前提として「ライセンス数」は必要最小限度にする）**



<dl>
  <dt>1．有料アカウントのオーナーがZoomミーティングを開催し、進行役の人を「ホスト（または共同ホスト）」にする
</dt>
  <dd>デメリットは、オーナーが少なくともZoomミーティングの冒頭には立ち会わないといけない（ただし、技術的に難しくはない）</dd>
  <dt>2．オーナーがアカウントに紐づくユーザーを追加し、必要な都度、ユーザーにライセンスを付与する</dt>
  <dd>事前にZoomの設定が必要であり、比較的難易度が高い（ITリテラシーが一定以上無いと困難）</dd>
  <dt>3．有料Zoomをやりそうな人の数分ライセンスを購入して予め付与しておく</dt>
  <dd>デメリットは、ライセンス数が最小化できないので、Zoomのライセンス料がかさむこと</dd>
</dl>

なお、オーナーのアカウントごと貸し出すのは、規約上微妙なのと、セキュリティーリスクがあるため、お勧めしない。


# 用語の説明など

Zoomの場合には、「アカウント」、「ユーザー」、「役割」、「ライセンス」というものが絡み合っている。
通常は、ある個人が、有償のアカウントを保持した場合には、
その個人が、アカウントの役割としてオーナーとなり、1つのライセンスが紐づく。

また、「アカウント」に対して「ユーザー」を追加することが可能（mailでinviteする）
その後に、紐づいているライセンスをユーザーに割り当てたり、追加購入したライセンスをユーザーに割り当てたりということが出来る。
前述の、2．3．はこの機能を利用することを前提としている。
Rails Flashの表示方法

#Flashの作成方法
出来上がりイメージ
![図11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1514036/4ed6a1a3-53d4-efc7-e5b3-091d7c954d7b.png)
自分で好きな文字をアクション成功時に入れられる！


#使用箇所
・〇〇〇_controller.rb（表示設定をする）
⇒（例）flash[:notice] = "You have created book successfully."
・〇〇〇.html.erb（Viewを表示するところ）
⇒（例）<%= flash[:notice] %>

#作り方
**1.**表示したいViewのあるコントローラーのアクションを探す。
（create.destroy.updateなど）

**2.**コントローラーのアクションに以下の内容を記述する。

```csharp:〇〇_controller.rb
flash[:notice] = "You have created book successfully."
```
またFlashを何かアクションが起きた時に発生させたい。以下では投稿を保存できた時に発生させています。

```csharp:〇〇_controller.rb
    book.save
    flash[:notice] = "You have created book successfully."
```
**3.**表示したいViewファイルに記述を追加する

```csharp:〇〇〇.html.erb
<%= flash[:notice] %>
```

#まとめ
　flashとは、ユーザーに対してページ遷移した時に簡単なメッセージを一時的に表示させる機能。投稿に成功や失敗したときにメッセージを表示するのはとても丁寧です。
並列処理プログラミングを用いた仮想通貨マイニングの実装プロジェクト

#プロジェクトの目的
仮想通貨のマイニングを行うために、既存のマイニングツールのソースコードの分析や、GPUを使用した並列プログラミング、FPGAの開発を行い、低リソースで高い性能（高いハッシュレート）を獲得するにはどのようにすればよいかを研究開発します。

##プロジェクトの成果
下記のフェーズでマイルストーンを設定し、プロジェクトの進捗状況を評価します。

###フェーズ１
仮想通貨マイニング等の基本知識を把握しどのような方法で収益化ができるのかを調査し、実証実験を行って成果を確認します。

###フェーズ２
マイニングツールやマイニングプールなどの仕組みを理解します。

###フェーズ３
GPUの並列化処理を理解し、自らマイニングコードを実装して低リソースでの高速化を図ります。

###フェーズ４
FPGAの開発を行い、自らマイニングコードを実装して低リソースでの高速化を図ります。

##低リソースでの高速化について
「低リソース」の定義として下記の２つの要件を満たすものとします。

###計算資源の価格
GPUボード等は高価な金額で購入すれば高性能なものを入手可能ですが、低性能なGPUで上位モデルと同等の性能を出力することで、低リソース化を実現できます。

###低電力による演算
GPUボード等で高速な演算を行うと大量な電力消費が必要となります。同じ演算性能であっても消費電力が少ない方が低リソース化を実現できていると言えます。


以上のことを踏まえてプロジェクトの成果を記録・発表していきます。
STM32L010のシリアルでHello Worldと出力 (RawSerial)


目的
動きそうだから動かしてみた


x mbedのリビジョンは、125

忙しい人よう


https://os.mbed.com/users/caa45040/code/serial_raw_test_010/


```c++


#include "mbed.h"

//Serial pc(USBTX, USBRX); // tx, rx
//Serial pc(SERIAL_TX, SERIAL_RX); //767
RawSerial pc(PA_2, PA_3); //010

int main() {

    char *ss1; //文字のポインター
    int ii; //ループカウンター

    //無限ループ
    while(1) {

        ss1="Hello World !\r\n";
        ii=0; //ループカウンター
        while(ss1[ii]!=0){
            
            //一文字出力
            pc.putc(ss1[ii]);ii++;
                        
        } //while

        //1秒の待ち
        wait_ms(1000);
        
    } //while
} //main

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

```

![serial_test_010_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/b93e5c8a-45ea-03b9-1f25-9e09046226f8.jpeg)

![serial_test_010_2_3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/6026efe5-e614-e538-a1bc-0bf22e964c40.jpeg)

![serial_test_010_2_4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/349dcbe8-4bcd-18f7-7375-95bcaa8147a4.jpeg)

![serial_test_010_2_5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/2ac3a0a1-22b7-2c41-056b-cd8a58fa41a9.jpeg)

![serial_test_p1_4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/57b83e05-9573-a174-dfca-8d74069fab75.jpeg)

![serial_test_p1_5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f6470ea4-b5f4-831d-de37-c531ee710394.jpeg)
LightGBMカスタムメトリクスのサンプル

毎回リファレンス確認しながら書いてるカスタムメトリクス。
ローカルにソース転がってたので、備忘録として挙げておく。

＃ サンプルコード

```py
from sklearn.metrics import roc_auc_score
from sklearn.metrics import average_precision_score

def calc_accuracy(y_pred, y_true):
    metric = np.mean(y_true == y_pred)
    return 'accuracy', metric, True

def calc_precision(y_pred, y_true):
    metric = precision_score(y_true, y_pred)
    return 'precison', metric, True

def calc_recall(y_pred, y_true):
    metric = recall_score(y_true, y_pred)
    return 'recall', metric, True

def calc_fscore(fscores):
    metric = np.max(fscores)
    return 'fscore', metric, True

def calc_auc(y_pred, y_true):
    metric = roc_auc_score(y_true, y_pred)
    return 'auc', metric, True

def calc_prauc(y_pred, y_true):
    metric = average_precision_score(y_true, y_pred)
    return 'prauc', metric, True

# CV用評価関数算出メソッド
def acquire_custom_metircs(preds ,data):
    precisions, recalls, thresholds = precision_recall_curve(data.get_label(), preds, pos_label=1)
    thresholds = np.append(thresholds, 1)
    fscores = 2 * precisions * recalls / (precisions + recalls)
    threshold_max_fscore = thresholds[np.argmax(fscores)]

    y_true = data.get_label()
    y_pred = np.where(preds > 0.5, 1, 0)

    return [
        calc_accuracy(y_pred, y_true),  ＃ Accuracy
        calc_precision(y_pred, y_true),  ＃ Precision
        calc_recall(y_pred, y_true),  # Recall
        calc_fscore(fscores),  # F1 score
        calc_auc(y_pred, y_true),  # ROC AUC
        calc_prauc(y_pred, y_true)  # PR AUC
    ]

# CV
histroy = lgb.cv(
    best,
    dtrain, 
    folds=StratifiedShuffleSplit(n_splits=5, test_size=0.2, random_state=0), 
    feval=acquire_custom_metircs,  ＃ CVで使う評価関数に自作関数を指定
    num_boost_round=cons_val_num_boost_round, 
    early_stopping_rounds=cons_val_early_stopping_rounds, 
    verbose_eval=cons_val_verbose_eval, 
    show_stdv=False, 
    seed=0
)
```
spotify x LINEで音楽をタイマー替わりにするLINEBOT作った

## はじめに
https://qiita.com/inoue2002/items/7e47283ba9affa0fac82

こちらの記事を見て、音楽をタイマーとして使いたいと思ったのがBOT作成のきっかけです。

## 作成したBOTの使い方

:::note warn
BOTは現在稼働していません
:::

以下のQRコードから友達追加
![947sybkb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435661/a835cfee-1063-8fcf-cc69-0df3a6cfc0b0.png)


1.メニューから「get music!!」をタップ
2.「1分、2分、3分」といった選択肢が表示されるので、再生したい曲の長さを指定します。
3.SpotifyのURLが返されます。
**※Spotify Freeプランの場合、URLをタップしてもすぐに曲が再生できないことがあります。**

![ezgif-2-e1a8c0c8a3f7.gif](https://user-images.githubusercontent.com/39284992/123392604-32fc9b80-d5d8-11eb-8089-fb30e3cc1a01.gif)


このBOTは、ユーザーからリクエストされた曲のURLを返却するシンプルな構成にしました。
最初は曲のジャンル指定ができたらと思いましたが、機能を追加すると曲を取得するまでの手順が増えて操作が面倒になるかもしれないと思い、今回は実装を見送ることにしました。
パスタを茹でるときなどにご活用いただければ幸いです！

## ソースコード
https://github.com/pp9009/line-bot-3minute-music

## 使用技術
### SpotifyAPI
Spotify APIを使って**指定した約n分の曲を取得**したいと考えましたが、一度で実現するのは難しそうでした。そのため、**ランダムに曲を取得し、その中から約1分、2分、3分などの曲のURLをDBに保存する**方法を選びました。

具体的には、
**[SearchAPI](https://developer.spotify.com/documentation/web-api/reference/#category-search)を使用してランダムに曲を取得し、レスポンスから約1分、2分、3分（±5秒）の曲情報をDBに保存する**
というバッチ処理を定期的に実行しています。

ランダムに曲を取得する部分については、こちらの記事を参考にしました。
[Getting random tracks using the Spotify API](https://medium.com/@perryjanssen/getting-random-tracks-using-the-spotify-api-61889b0c0c27)

使用したライブラリ

https://github.com/jwilsson/spotify-web-api-php

### LINE Messaging API
使用したメッセージオブジェクト
・[テキストメッセージ](https://developers.line.biz/ja/reference/messaging-api/#text-message)
・[クイックリプライ](https://developers.line.biz/ja/reference/messaging-api/#quick-reply)

使用したライブラリ

https://developers.line.biz/ja/docs/messaging-api/line-bot-sdk/#official-sdks

https://github.com/line/line-bot-sdk-php


### ちょっとした工夫
動作確認をすると、海外のよくわからない曲ばかり返ってきて微妙な結果になりました。
曲の人気度を示す「popularity」を高く設定しても、結果は改善されませんでした。

そこで、少しでも馴染みのある日本の曲のみを返すように工夫しました。結果、ほぼ日本の曲だけを返せるようになりました。具体的には、ISRCに「JP」が含まれる曲のみを返すという方法です。ISRCについての詳細は、こちらを参照してください。
https://isrc.jmd.ne.jp/about/pattern.html

### 終わりに
作成したBOTがどこかで誰かの役にたてば嬉しいです:blush:
Neo4jのサンプルをdocker-composeでセットアップしてみた

#概要
GOのサンプルアプリコンテナ+neo4jコンテナをセットアップしてみました。

#ソース
###Github
サンプルソースは以下に公開してます。
https://github.com/takaahii/neo4j

###docker-compose
docker-composeは以下のようにしました。
あくまで簡易版です。

```
version: '3'

services: 
  app: 
    build: . 
    tty: true 
    volumes:
        - ./app:/go/src/app
    ports:
      - 80:${PORT}
    environment:
      - PORT=${PORT}
      - GO111MODULE=${GO111MODULE}
      - GO_ENV=${GO_ENV}
  neo4j:
    image: neo4j
    restart: always
    ports: 
      - 57474:7474
      - 57687:7687
    volumes: 
      - ./volumes/neo4j/data:/data
```

##セットアップ
###起動

```
docker-compose up -d
```


###neo4jに接続する
http://localhost:57474/
にアクセスして初期ログインをします。
![2021-05-19_02h43_19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222041/fc9e7f07-0b10-3d25-dbb1-cb88805d1bc0.png)
パスワードはneo4jです。


###データ投入
neo4jに用意されているMovie GraghのCreateをそのまま実行します。
![2021-05-19_01h52_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222041/d82affa7-5999-5d58-0d70-b24429ed33e7.png)


###構築確認
http://localhost/
でアプリを確認します。
![2021-05-19_01h56_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222041/0e0ac66f-6387-531c-bc80-7ff834ba7fa7.png)
マトリクスの映画情報が入っているのが確認できました。

neo4j側でデータを見てみるとこんな感じです。
![2021-05-19_01h59_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222041/b910a129-a902-a36d-6331-5a7f8fb13aff.png)
見ただけじゃ何のことやら。。ですが、グラフDBが最短経路検索やリコメンデーションに使われる理由が何となく感じれました。

##参考
参考にさせて頂いたサイトはこちらです。
https://neo4j.com/developer/example-project/
こちらの内容が外部のNeo4jに接続する形だったの気になってdocker-compose作りました。
GOからneo4jにseedのSQLの入れ方わからず、手動でデータ投入する形です。。

neo4j側のdockerはこちらのサイトを参考にさせて頂きました。
https://mlog.wlaboratory.com/entry/category/tools/db/neo4j/setup-neo4j-with-docker

#感想
・GOからのデータ投入方法が分からなかった
・GOは.envはモジュールを追加しないといけなかった(godotenvをimportした)
・GOってモジュールの管理がすごく楽
ということでGOの感想になってしまいました。
Git ブランチ機能とマージについて

##Gitのブランチと使い方

そもそもブランチというのはどういう仕組みでできているのか
分かっていないと、自分の意図しない動きをしてしまうので
よく理解しておきたい。

ブランチというのは、同時並行で複数人で開発するための機能であって
ブランチを分岐をさせることによって、他の方影響を受けないで、
開発を進められるという利点がある。

ブランチとは、コミットファイルを指し示した、リンク機能みたいなもので
a タグのようなシンプルな機能でしかないことに注意するべき、
HEADはどこを指しているのかも重要な観点

###ブランチを新規作成コマンド

```ruby:branch
git branch <ブランチ名>
# git branch feature
# ブランチの作成をするだけでブランチの切り替えまでは行わない
```

####現在のブランチの一覧表示するためのコマンド

```ruby:branch
git branch
# 現在、存在するブランチ名だけを表示

git branch -a
# リモートブランチも含めて全て表示してくれる
```

それぞれのブランチがどのコミットを指しているのかを知りたい時に
使用してみるといいコマンド
`--oneline`コマンドは単純に一行で表示してくれるコマンドで、
`--decorate`コマンドが実際の情報を表示してくれるコマンド

```ruby:log
git log --oneline --decorate
```

###ブランチを切り替える

```ruby:checkout
git checkout <既存のブランチ名>
# git checkout feature

git checkout -b feature
# ブランチの新規作成と切り替えを同時に行ってくれる
```

##マージの使い方
マージというのは、他の人の変更内容を取り込む作業のことであって
gitの中で怖い:scream:とされる作業の一つ
しっかりと使いこなしていきたい

```ruby:merge
git merge <ブランチ名>
git merge <リモート名/ブランチ名>
# git merge origin/master
```

**注意としては、統合（merge）したいブランチに移動してから、コマンドを実行すること**:bangbang:

###マージには三種類ある

1. Fast Foward　ブランチが枝分かれしてない時に、ブランチのポインタを前に進めただけ
1. Auto Merge　一般的にイメージされるマージで、ブランチが複数に枝分かれしている時に、統合する時に行われる
1. Conflict　同じファイルの同じ行に対して、複数人が異なる変更を行なった時に起こる現象

コンフリクトは起きてしまっても焦らず、どんな変更があったのかを見て
適切に変更すれば処理できるので、とにかく焦らないこと。

注意点としては、以下
1. 複数人で同じファイルを変更しない
2. pullやmergeをする前に変更中の状態をなくしておく（commitやstashを実行しておく）
3. pullする時は、pullするブランチに移動してからpullする
4. とにかく慌てない

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

```ruby:ブランチ名を変更したい時
git branch -m <ブランチ名>
# git branch -m new_branch
```

```ruby:ブランチを削除したい時
git branch -d <ブランチ名>
# git branch -d feature

git branch -D <ブランチ名>
# 強制的に削除したい時に使えるコマンド
```

例えば、ブランチがmasterとfeatureの二つが存在した時に
上の小文字の"-d"での削除コマンドを押した時には、
もし、masterにfeatureの変更をmergeしてない時に
エラーメッセージを出してくれる、とても頼もしいコマンド

##おまけ　~> ブランチの運用ルール

masterブランチはあくまで、リリース用のブランチとして使い、
開発は、別のブランチを作成して進めるのが基本の型
【Nuxt.js】動的ルーティング

はじめに
---
先日初めて`動的なルーティング`という言葉を耳にし、扱う機会がありましたので自身の備忘録としてまとめておきたいと思います。
今回の記事の主な内容としましては、動的なルーティングファイルの作成方法と、扱い方について簡単にまとめたものとなっております。
 <br>

動的なルーティングとは
---
pagesディレクトリの直下に作成されるファイルに関しては、そのファイル名で自動的にルーティングに生成されます。
一覧ページには、一般的にindex.vueが使用されますが、この詳細ページを作成したい場合には、URLに個別のIDや名前を入れる必要があります。このように、個別にURLが変わるもののことを`動的ルーティング`と表現します。
例） https://(アプリ名)/users/1
<br>

動的ルーティングの導入方法
---
ファイル構成は以下のようになります。
動的ルーティングを作成したい場合は、`_(取得するパラメータ名).vue`のファイル名で作成ができます。
今回の例ですと、userのIDで識別したいので、`_id.vue`としています。

```
pages
├ users
│　├ index.vue (一覧ページ)
│　└ _id.vue   (詳細ページ)
└ index.vue
```
<br>

パラメータの渡し方
---
- `this.$route.params.（取得するパラメータ名）`   
ルートオブジェクトのparamsを参照して、パラメータを取得しています。  
idの値を取得後に、その値を定数idに格納して、HTTPリクエストを送信しています。

```javascript:users/_id.vue
const id = this.$route.params.id
  this.$axios.get(`users/${id}`)
```
<br>

終わり
---
今回は以上になります。
まだまだ学習中の身ですが、同じ様な立場の方に少しでも参考になればと思っています。
また、もし内容に誤りなどがございましたら、ご指摘いただけますと幸いです。
聞いたことがある程度だったNode.jsについてふわっとまとめる

# はじめに
Node.jsってふわっと聞いたことありましたが、何かよくわかっていなかったので個人的にふわっとまとめます。
間違っている箇所があったらお手数ですが教えていただけると嬉しいです。
＊「Node.js超入門[第３版]」を参考にしています。

# Node.jsって何だろ
> Node.jsとは、JavaScriptのプログラムを実行するための環境(ランタイム環境)。

ということなのですが、個人的に正直ピンときていませんでした。

でも以下のような説明を見て、だからNode.jsって必要なんだなぁ、と。
以下、Node.jsの説明の要約です。

>以前はWebブラウザの中だけでJavaScriptは動いていた。
でもNode.jsでJavaScriptで更に以下のことが可能になった。

> #####１.JavaScriptのプログラムがそのまま動く
サーバー側とクライアント側で２つの言語を組み合わせて開発するのが普通だった。
でも、Node.jsだとサーバー側もクライアント側も同じ言語であるJavaScriptで動かせるようになる！

> ##### ２. Webサーバープログラムも作れる
一般的なWeb開発のためのフレームワークはWebサーバーにアップロードして動かす。
プログラミング言語を実行できるようにするプラグインなどをWebサーバーに追加して、Webサーバーの中でフレームワークのプログラムが動くようにしている。
でも、Node.jsだとWebサーバープログラムそのものも全て作る！

> ##### ３. JavaScript開発のフレームワークが使える
Node.jsはフレームワークではなく、あくまでランタイム環境。
でも、Node.jsにはNode.js上で動作する便利なフレームワークが揃っている！

ってことは、Node.jsがなかったら

* JavaScriptだけでプログラムを動かすことができない
* Webサーバープログラムを自分で組み立てなきゃいけない
* JavaScriptのフレームワークを自分で取り揃えなきゃいけない

ってことですよね。
Node.jsってすごい…。

# 終わりに
サーバーでもクライアントでもJavaScript使っていたので
環境構築の際にそうとは知らずにNode.jsを入れていたんだと思います。
こういうことを知ると、ありがたみを知らずに使ってる機能が他にも沢山あるんだろうな、と。
Node.jsの技術書を基に、Node.jsの利点をちゃんと活かせるように勉強していきます。
草野球の出欠確認Webアプリを作ろう！　part.8

これから作っていく簡単なWebアプリの作成メモ（自分の備忘）です。
自分用なのであまり凝りすぎないように書いていきたい。

[<<前回の記事](https://qiita.com/tomodachi_uec/items/fa13d5ee05071654d4ad)

##今回やったこと

###ユーザーの新規登録

スケジュールでひと通りやったので、それと同じ仕組みをユーザーのデータにも実装していく。

```rb:app/controllers/users_controller.rb
（略）
def show
  @users = User.find(params[:id])
end

def new
  @users = User.new
end

def create
  @users = User.new(users_params)
  if @users.save
    redirect_to user_path(@users), notice: "ユーザーを新規作成しました。"
  else
    render :new
  end
end
（略）
private
def users_params
  params.require(:user).permit(
                                :name,
                                :email,
                                :password,
                                :password_confirmation
                              )
end
（略）
```

```erb:app/views/users/new.html.erb
<h1>ユーザーの新規作成</h1>
<div class="row_line">
  <%= link_to 'ユーザー一覧へ', users_path, class: 'btn btn-primary' %>
</div>

<%= form_for @users, url: {action: "create"} do |f| %>
  <div class="row_line">
    <label>ユーザー名：</label>
    <%= f.text_field :name %>
  </div>
  <div class="row_line">
    <label>メールアドレス：</label>
    <%= f.email_field :email, size: "40" %>
  </div>
  <div class="row_line">
    <label>パスワード：</label>
    <%= f.password_field :password %>
  </div>
  <div class="row_line">
    <label>パスワード（確認欄）：</label>
    <%= f.password_field :password_confirmation %>
  </div>

  <div class="row_line">
    <%= f.submit "新規作成する" %>
  </div>
<% end %>
```

```erb:app/views/users/index.html.erb
<h1>メンバーの一覧</h1>
<div class="row_line">
  <%= link_to '新規作成', new_user_path, class: 'btn btn-primary' %>
</div>
（略）
```

```erb:app/views/users/show.html.erb
<h1>ユーザーの詳細</h1>
<div class="row_line">
  <%= link_to 'ユーザー一覧へ', users_path, class: 'btn btn-primary' %>
</div>

<div class="row_line">
  <label>ユーザー名：</label>
  <%= @users.name %>
</div>
<div class="row_line">
  <label>メールアドレス：</label>
  <%= @users.email %>
</div>
<div class="row_line">
  <label>パスワード：</label>
  <%= "（セキュリティに配慮し、パスワードは非表示です）" %>
</div>

<div class="row_line">
  <%= link_to '編集', edit_user_path(@users.id), class: 'btn btn-primary' %>
  <%= link_to '削除', user_path(@users.id), method: :delete, class: 'btn btn-danger' %>
</div>
```

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534558/ab7d509a-1df2-441f-514d-575ea2b8a771.png)


![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534558/0606da44-eddb-f400-fb7d-5c816b4e918a.png)

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534558/e92ab463-6dab-4182-759c-acf76d48fe22.png)

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534558/7716d6de-1762-d3dd-5546-465c95216b91.png)

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534558/9ab97222-4b4d-952a-3fa6-be1a0a3d269e.png)

このようになった。
とくに新しいことはできていないが、次回もユーザーのデータについてできることを増やしていく。

今回はここまで。

[次回の記事>>](https://qiita.com/tomodachi_uec/items/b78bf0acabe8f0bf23de)
Usersリソースを作成する

Railsチュートリアルの２章を勉強した。

```
rails generate scaffold User name:string email:string
```
いろんなファイルが作られたり、既存のデータに追加されたりする

```
c9　ファイル名
```
ファイルを開くことができる

```
rails db:migrate
```

単にデータベースを更新し、usersデータモデルを作成するためのもの

```
rails routes
```
どこにアクセスすれば何があるのかを教えてくれる

####ユーザーページを探索する
rails serverのurlにrails routesに書かれているルートを入力するとそのページに移動することができる。

###MVCの挙動
1,
ブラウザからurlのリクエストをRailsサーバーに送信する

2,
リクエストは、RailsのルータによってUsersコントローラ内にrails routesに書いてあるアクションindexに割り当てられる

3,
indexアクションが実行される。User.all (全てのユーザを取り出す)でUserモデルに問い合わせる。

4,
全てのuserモデルのユーザーのデータベースから取り出す

5,
indexアクションの＠userに返す

6,
indexビューが起動する　HTMLを生成する

7,
HTMLをブラウザに返す

gemfileとはバージョンを指定するファイル
Gemfileが変わったら必ずbundle install

間違っていたら申し訳ございません。
Failed to install gems via Bundlerの対処方法

#はじめに
作成したアプリに`git push heroku main`を実施した際に、

```
Failed to install gems via Bundler
```
が表示されてしまい、pushできないエラーに遭遇したので、その時の対処方法を記載します。

**学習環境**
macOS BigSur
ruby-2.6.5
Rails 6.0.3.6
stack heroku-18

###結論
```
$ bundle instal
$ git push origin "メインリポジトリ名"
$ git push heroku "メインリポジトリ名"
```

の順番で実行して、無事に`push`することができました。

####エラー解決までの流れ
まず、`git push heroku main`を行った際のログを確認したところ、

```
remote:        If this is a development machine, remove the /tmp/build_1fa59727/Gemfile freeze 
remote:        by running ``.
remote:        
remote:        You have deleted from the Gemfile:
remote:        * pg
remote:        Bundler Output: You are trying to install in deployment mode after changing
remote:        your Gemfile. Run `bundle install` elsewhere and add the
remote:        updated Gemfile.lock to version control.
remote:        
remote:        If this is a development machine, remove the /tmp/build_1fa59727/Gemfile freeze 
remote:        by running ``.
remote:        
remote:        You have deleted from the Gemfile:
remote:        * pg
```
 おそらく、これは`pg`というgemを削除してるみたいだけどその後に、ちゃんと`bundle install`しましたか？のようなことが書いてあると思ったので、実際に`bundle install`を行ったところ、gitの差分に`gemfile.lock`が出現し、削除されているはずの`ｐｇ`に関する差分が表示されました。
[git差分画像](https://gyazo.com/08042d6d77337fc2795f5f000a451df2)

`bundle install`を行うことで、bundlerがGemfileに列挙されたすべてのgemのバージョンを調べ、gem同士のバージョンによる依存関係を解決してくれます。
`bundle install`を実行するとGemfileに列挙したgemが依存関係を解決しながらインストールされるので、gemfileをいじったりした後は、`bundle install`を実行しないといけません。
さらに、`Gemfile.lock`はGemfileに記載されたGemに加え、依存関係にあるGemとそのバージョンが記載されたファイルであり、Gemは他のGemと結びついていることが多いため、gemfileに記載した目的のGem以外にも使用するのに必要な他のgemをインストールする必要があります。
よって、`bundle install`を実行すると依存関係にあるGemを自動でインストールしてくれるので、gemを削除する際にも`bundle install`を行って、gemfile.lockの更新をする必要があるということだと考えました。
[UE4] プロジェクト起動時にVR HMDをつないでいるとSteamVRが起動してしまう問題の対応

UE4でVRヘッドセットをつないでいると、プロジェクト起動時に毎回SteamVRも起動してしまう問題。

## 原因と対策

デフォルトで、プロジェクト作成時にSteamVRプラグインが有効になっているのが原因。

対策として、 `C://Program Files/Epic Games/UE_4.26/Engine/Plugins/Runtime/Steam/SteamVR.uplugin` の `EnabledByDefault` を `false` にする。
![EoKLEJFVoAEQFS-.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58251/1ac06009-b160-5b55-59f4-77a25ae7b1df.png)

Oculus VR の場合は `C:\bin\Epic Games\UE_4.26\Engine\Plugins\Runtime\Oculus\OculusVR\OculusVR.uplugin` 。
（たぶん。持っていないので確認できていない）

注意点として、UE4本体をアップデートするたびに実施する必要がある。

参考: https://answers.unrealengine.com/questions/791485/how-to-disable-auto-steamvr-launch-on-ue4-launch-f.html


## 代替策

プラグインウィンドウから、SteamVRを無効にする。（正攻法）
ただし新しくプロジェクトを作るたびに実施する必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58251/af50b3f7-1b9b-3d6b-ba2a-b762edd0fe99.png)


参考: https://answers.unrealengine.com/questions/660920/%E3%83%A9%E3%83%B3%E3%83%81%E3%83%A3%E3%83%BC%E8%B5%B7%E5%8B%95%E6%99%82%E3%81%ABvr%E3%82%92%E8%B5%B7%E5%8B%95%E3%81%97%E3%81%9F%E3%81%8F%E3%81%AA%E3%81%84.html?childToView=661223#answer-661223
AnimeGANをColaboratoryで試してみた（静止画のみ）

# はじめに
いまさらですが、Colaboratoryで[TachibanaYoshino さんのAnimeGAN](https://github.com/TachibanaYoshino/AnimeGAN)を試した時の記事を書きました。2020年の7月に動作をさせていましたが、１年近く放置状態でした。本記事は手っ取り早く試すための備忘録的なもので、理論に関しては触れていません。
Colaboratoryがわからない場合、[Webサービス](https://animegan.js.org/)がありますので簡単に試せます。

2021/5/18に久々に試してみましたが、プロジェクトの構成が変わっており当初エラーが生じましたが動作の確認ができました。
（提供されているtest.pyの内容をCellに展開していますので、オリジナルの構成の変更をもろに受けてしまいました。また事前学習済みのデータのリンク先がなくなっており、現状データはプロジェクト内に存在していますが、Hayaoのみとなっています。）

桜と列車
![anime_PXL_20210327_024814022_2048.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/975328/0bac2172-2889-290c-c212-c9441a26bbd1.jpeg)

## 事前準備
プロジェクトの取得

```
!git clone https://github.com/TachibanaYoshino/AnimeGAN
```
オリジナルは、tensorflow-gpu 1.15.0　なので、tensorflowのバージョンをダウングレードする必要があります

```
%tensorflow_version 1.x
import tensorflow as tf
print(tf.__version__)
```
## 実行
### 事前処理
読み込んだ画像データのサイズを32の倍数になるようリサイズしています。そのため結果の画像のサイズが若干異なる場合があります
なお、最小サイズは、256x256です
### 事後処理
明るさの補正をTrueにすると、処理後の画像の平均輝度をオリジナルの画像の平均輝度になるよう補正します。この処理はOpenCVで処理されています。
### メモ
連続して処理できるよう、パラメータを変更

```
 with tf.variable_scope("generator", reuse=tf.AUTO_REUSE): オリジナルでは、False  
```
### Issue
スタイルを適用させる画像のサイズが大きいとGPUのリソースの枯渇でエラーとなる可能性がある
2016x1512はOK 処理時間12秒
4032x3024はエラー
なお、割り当てられたマシンにより条件は変わる可能性あり。

##サンプル画像
富士山
![anime_PXL_20210424_010824944_2048.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/975328/8e7b5c80-b2cd-83a7-b754-4d32529a4b18.jpeg)
高尾山
![anime_高尾山s.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/975328/56c9bec7-b8da-f055-3e62-a3036965f3f1.jpeg)
ガムダム
![anime_gundam.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/975328/980cd3d7-5c89-909b-8efc-21bac3c16276.jpeg)
横浜夜景
![anime_PXL_20201220_082233027.NIGHT_2048.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/975328/90ca4ad1-45f9-e557-4501-25b097351a64.jpeg)

## 感想
学習画像は、風景を対象と推測され、人物、動物はあまり効果がないと思われる
乗り物は、それなりに変換されている印象

## 補足
オリジナルはv2が公開されています。近日中に動作確認予定
moduleについて

こんにちは、2021年4月から実務未経験でプレイライフに入社した熊﨑です！
現在Rubyの基礎知識を補填するために、チェリー本を読んでいるのですが、その際にmoduleを学んだのでmoduleについての記事を書いていきたいと思います。

## モジュールの役割
- 継承を使わずにクラスにメソッドを追加する
- 複数のクラスに対して共通のクラスメソッドを追加する
- クラス名の衝突を防ぐために名前空間を作る

一個ずつ説明していきます。

## 継承を使わずにクラスにメソッドを追加する

Rubyでは単一継承（一つのクラスには一つのスーパークラスしか持てない）を採用しているため、多重継承ができません。
しかし、複数のクラスに同様の機能が必要になるケースが存在します。

例えば以下のように、insectクラスとfishクラスという２つのクラスでそれぞれの名前を出力する機能が存在したとします。

```.rb
class Insect
  def initialize(name)
    @name = name
  end

  def name_output
    "#{@name}は生き物です"
  end
end

class Fish
  attr_accessor :name
  def initialize(name)
    @name = name
  end

  def name_output
    "#{@name}は生き物です"
  end
end
```

２つのクラス間でputs_nameというインスタンスメソッドが重複しています。
しかし、命名を見てもらうとわかると思いますが、昆虫クラスと魚クラスって、なんの関連性もないと思います。
基本的にこのようにis-aの関係（例えば、パンクラスと食パンクラスというものが存在し、食パンはパンの１種であるというように、読んでも違和感の無いような関係性）でない状態で安易に継承を行うと後々コードを読み返した時に両者の関係性が掴みづらく、非常に使いづらいクラスが出来上がってしまうので、継承を使うべきではありません。

このような時にモジュールを使用します。
モジュールの定義はクラスの時とほぼ同様に行います。

```.rb
module NameOutput
  def name_output
    "#{@name}は生き物です"
  end
end

class Insect
  include NameOutput

  attr_accessor :name

  include NameOutput

  def initialize(name)
    @name = name
  end
end

class Fish
  include NameOutput

  attr_accessor :name

  def initialize(name)
    @name = name
  end
end
```

## 複数のクラスに対して共通のクラスメソッドを追加する

以下のようにextendを使用することで、クラスメソッドを追加することもできます。

```.rb
module Output
  def output
    "生き物です"
  end
end

class Insect
  extend Output

  attr_accessor :name

  def initialize(name)
    @name = name
  end
end

class Fish
  extend Output

  attr_accessor :name

  def initialize(name)
    @name = name
  end
end
```

## クラス名の衝突を防ぐために名前空間を作る
例えば、管理者用のユーザーという意味合いでuserモデルを定義したとします。しかし、管理者だけじゃなくて一般ユーザー用のuserモデルも作成したいとします。
もし何らかの理由でこれら２つのクラスを同時に使用する場合、どうやって区別をすれば良いでしょうか？
このような時にもモジュールを使用できます。モジュールの中にクラスを定義するとそのモジュールの中に属するクラスという意味になるため、同名のクラスだとしても衝突が起こらなくなります。

```.rb
module Admin
  class User   
  end
end

class User
end
```

ちなみにadminモジュールに属するクラスを参照する際には以下のようにかく。

```.rb
Admin::User
```

このように名前空間でグループ分けがされていると、実際にコードを読んでいった際にも理解しやすく見やすいです。

名前空間として使用するモジュールが既に定義されている場合は、モジュールの中にクラスをネストさせなくても、以下のように記述するだけでクラスを定義できます。

```.rb
class Admin::User
end
```

## まとめ
- moduleを使用することで、継承をせずにクラスにメソッドを追加できる。
- extendを使用することで、クラスメソッドも追加できる。
- moduleを使用して名前空間を作ることで、クラス名の衝突を避けたり、ソースコードを読みやすくできる。

今回はmoduleについての記事でした！
次回は、クラスメソッドとインスタンスメソッドについて書いていこうと思います！
[Swift]Typealiasでコードの可読性を高める

# はじめに

本文は、以下の記事を参考に作成しています。
[Typealias usage in Swift](Typealias usage in Swift)

# Typealiasの用途
コードの可読性を上げることが主な用途です。
変数のデータ型を宣言する際に`Double`や`Int`などを使用すると思いますが、`typealias`を使用することで、`Double`や`Int`などと同じ機能を持った**エイリアスで宣言することができます。**

### 用途① データ型の代わりにエイリアスで宣言

```
//通常のデータ型の宣言
struct Receipt {
    let totalCosts: Double
}

//typealiasでDouble型を割り当てたエイリアスDollarを作成
typealias Dollar = Double

// エイリアス`Dollar`で変数を宣言
struct Receipt {
    let totalCosts: Dollar
}
```

### 用途② extensionで機能拡張

```
typealias Dollar = Double
typealias Euro = Double

struct Receipt {
    let totalCosts: Dollar
}

extension Dollar {
    func toEuro() -> Euro {
        return self * 0.896
    }
}

let receipt = Receipt(totalCosts: 10)
receipt.totalCosts.toEuro() // 8.96

let doubleNumber: Double = 10
doubleNumber.toEuro() // 8.96
```
その他の用途も[参考記事](https://www.avanderlee.com/swift/typealias-usage-swift/#:~:text=A%20typealias%20in%20Swift%20is,really%20useful%20in%20your%20codebase.)に記載されているので、気になる方は見てみてください!
Android：SHA-1のカンタンな確認方法

# SHA-1を手っ取り早く確認したいとき

- AndroidStudio開く
- AndroidStudioの一番したのバーの`Terminal`を選択
- 以下のコマンドを叩く

```
keytool -list -v \
-alias androiddebugkey -keystore ~/.android/debug.keystore
```
- パスワードの入力を求められるので`android`と入力

以上でSHA-1を簡単に取得できます！！ｲｪｲ
CDKでFargateにEFSをマウントする

2020/12に書こうと思って温めていたけど、生ぬるくなってしまった・・・が、せっかくなので書いておく。

# 概要
お仕事でFargate上で動かすアプリを開発中に、一時的にローカルに巨大なファイルを置く必要が生じました。
デフォルトのタスクストレージは20GBで、これでは不足します。
この時点（2020/11下旬)で既にFargateではEFSを利用可能となっていました。

https://dev.classmethod.jp/articles/efs-fargate/

さっさとやっつけてしまえそう。

# CDKでは・・・
アプリはCDKで構成しており、当然EFSマウントもCDKで実施したいのですが、どうやら雲行きが怪しく。

https://qiita.com/hrkmri/items/f712a5b72bc683c319c4

> CDK及びCloudformationではまだ、インフラコードからFargateとEFSの連携ができないため、手で作成する必要があります。

ええぇ。手動はイヤや。

https://caj.ms/writing/aws-fargate-with-efs

この記事でもCDKの"正規の"機能として対応されていないから、ということで、カスタムリソースでカスタムタスク定義を登録するようになっています。

上記ブログ著者のGist

https://gist.github.com/cajames/3daec680b1101c8358e2ff30dfadd52a

カスタムリソースもやりたくない。

CDKは開発が活発なので、ちょっと待てば対応されるだろうと期待し、一旦このタスクは保留とし、時々CDKの更新情報を眺めることにしました。
＃待ってないでコントリビュートしろ！

# 解決
2日おきぐらいに更新情報をチェックしていたのですが、バージョンは上がっていくけど、該当しそうな更新は見当たらない。
これは、やはりカスタムリソースしか残されてないのだろうか・・・

ところが、ある日APIリファレンスを眺めていた時(2020/12中旬)に、ふと気づいてしまいました。

「あ、これやん」

CDK v1.76の時点で、[前掲のGist]だと`customTaskDefinitionJson`として用意しているカスタムタスク定義を、普通に`ecs.FargateTaskDefinition`で作成できました。

```typescript
const taskDefinition = new ecs.FargateTaskDefinition(this, 'TaskDefinition', {
  cpu: 2048,
  family: fargateService.taskDefinition.family,
  memory: 8192,
  volumes: [volumeConfig]
})
```

多分、`volumes`に`efsVolumeConfiguration`があることに気づいていなかっただけ、もしくは、更新を見逃していたか、ってとこだと思われ。
＃前者が濃厚

デプロイして無事にマウントを確認できたので、オッケーです。
Rubyとは

# Rubyについて
学習したことを自分用のアウトプットとして書いていきます。
私なりの解釈ところどころに挟みますので、誤りもあるかと思いますが、おかしな部分あればご指摘ください。

## オブジェクト指向言語である                           
Rubyにおいては全てのオブジェクトは特定のクラスのインスタンスであり、ほぼ全てのクラスはObjectクラスの子孫クラスである。
「ほぼ」全てというのは、BasicObjectという真に全てのクラスの親クラスがあるため。
Rubyの中では全てのデータがオブジェクトであり、数値も文字列も、正規表現・入出力、データベースへの接続、そしてクラスそのものもオブジェクトである。
メソッドやコードブロックをオブジェクトとして扱うこともできる。
RubyにはC++やJavaのような「オブジェクトではないもの」は存在しない。
数値も文字列も全てのデータはオブジェクトである。

## Objectとは
- アイデンティティを持っている
- メッセージを受け取る
- 内部状態を持つ

**アイデンティティを持っている**
オブジェクトとは自分とそうでないものの区別ができるもの。
Rubyではobject_idメソッドによって、オブジェクトの一意な番号を得ることができる。

```ruby
str1 = "なにか"
str2 = "なにか"
str1.object_id #=> 12345
str2.object_id #=> 78912 （異なる文字列オブジェクト）
```

**メッセージを受け取る**
オブジェクトにはメッセージを送ることができる。
オブジェクトはそれを受け取ると対応するメソッド（手続き）を実行し、何らかの処理を行う。
この処理を「メソッド呼び出し」と呼ぶことができる。

**内部状態を持つ**
オブジェクトは内部状態を持つ。（0個以上）
内部状態はメソッドの実行によって変化することもある。
例えば文字列に文字を追加すると長さが変更になることなどがこれにあたる。

```ruby
str = "aaa"
str.length #=> 3
str << "bbbb"
str.length #=> 7
```

要するに簡単にまとめると、オブジェクトとは「何か」であり、「動作」が可能で「状態」を持つことができるものであるという理解をしている。
ちなみにRubyの文字列オブジェクトは変更可能だが、他言語には一度作った文字列オブジェクトは変更できないものもあるらしい。

## 高階関数を扱いやすい形にまとめた言語である
高階関数とは、関数を引数に取る関数のこと。プログラムのモジュール化を促進できる。
例えば

```ruby
3.times do
  puts "Hello World"
end
```
見覚えのあるこの形を理解してみる。
3.timesというのは、整数オブジェクトに対するメソッドの呼び出しである。
メソッドの呼び出しにdo ... endのコードブロック（コードのまとまり）を引き渡している。
つまり、メソッドに引数を渡すような作りになっている。

コードブロックを受け取るメソッドをRubyでは「ブロック付きメソッド」と呼ぶ。
また、上記の例のような、受け取ったブロックを繰り返し実行するためのブロック付きメソッドを「イテレータ」と呼ぶ。

## 言語内DSLである
DSL(Domain Specific Language)
ビルドや使用記述といった特定の分野の為に特化した言語のこと。汎用のプログラミング言語に対して、DSLと言う。
例えばMakefileはシェルスクリプトを含む独自の技術によって構成されるDSLである。
Rubyにおいては、ブロック付きメソッドなどを活用してRubyであると同時にDSLでもあるような言語を定義できる。
つまり自分で作ったブロック付きメソッドによって、Webプログラミングの領域でソフトウェアを書き上げることができるのがRubyの特徴である。

## メタプログラミング
Rubyは動的な言語（準備時ではなく実行時に行う言語）である。
自身で作成したメソッドによって制御する事ができる為、似たようなコードならば1箇所にまとめて、違う部分だけをパラメータにして繰り返し実行すればよい。
例えば以下である。

```ruby
class Duration
  %w[ days hours minutes seconds ].each do |name|
    attr_accessor name
  end
end

d = Duration.new  # Durationオブジェクトを作成
d.days = 3        # 属性daysを設定
d.hours = 5       # 属性hoursを設定
p d.days          #=>3  属性daysを出力
```
4つの属性名を保持する配列に対してイテレータを呼び出し、そのブロックの中で属性を定義している。

　

今日はここまで。別記事に続きます。

参考文献
Yugui, 初めてのRuby, 株式会社オライリー・ジャパン, 2008年
pythonインストール後：cmdからMicrosoftストアが開く


pythonインストール時にpathを設定せずに後で自身で追加したときにwindows10ではMicrosoftストアが開かれる設定になっている。
(インストール時にpathを設定するとMicrosoftストアが開かれる設定よりもpython実行の優先度が高くなる模様)

設定 → アプリと機能 → アプリ実行エイリアス を開く。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324641/1e17c1be-edfc-7223-90aa-a96b95838e27.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324641/87ef2293-d243-a6c8-90fc-a46e92d59818.png)

参考
https://docs.microsoft.com/ja-jp/windows/python/faqs
macでXampp 入れようとしたらProFTPD起動できなかった話

xampp起動したら、xamppターミナルに下記のエラーログが表示された

```2021-05-18 20:23:29,563 
〜〜〜〜〜〜〜MacBook-Air.local proftpd[1359]: warning: unable to determine IP address of '〜〜〜〜〜〜MacBook-Air.local'```

対応方法は下記リンク
https://ja.stackoverflow.com/questions/55530/apache%E3%81%8C%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%88%E3%81%97%E3%81%AA%E3%81%84

注：macのetcを編集する
```sudo vi /etc/hosts```
※管理者じゃないと書き込めない

対応後、　
```Checking syntax of configuration file
/Applications/XAMPP/xamppfiles/proftpd/scripts/ctl.sh : proftpd started```
無事起動できました。
「重要な処理」の際に混入する脆弱性

## クロスサイト・リクエストフォージェリ（CSRF)

- 発生箇所
    - クッキーのみでセッション管理が行われているサイト
    - HTTP認証、TLSクライアント証明書のみで利用者の識別が行われているサイト
- 根本的対策
    - CSRF対策の必要なページを区別する
    - 正規利用者の意図したリクエストを確認できるように実装
        - 秘密情報（トークン）の埋め込み
        - パスワード再入力
        - Refererのチェック
- 保険的対策
    - 重要な処理の実行後に登録済みのメールアドレスに通知メールを送信する


## クリックジャッキング

- 発生箇所
    - マウスなどポインティングデバイスの操作のみで重要な処理を実行でき、かつ認証を要するページ
- 対策
    - X-Frame-Options 
        - DENY iframe読み込まれない
        - SAMEORIGIN 
    - phpでは,header('X-Frame-Options: SAMEORIGIN);
    - Apache,nginxで設定しても
QtTestを試してみた

# 概要
guiアプリケーションをQtTestを使ってテストすることを試しにやってみました．

# 手順
## サブディレクトリプロジェクトを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237843/530e71c6-a983-efe2-8e85-6c403e5f0598.png)

## サブディレクトリプロジェクトにアプリケーションを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237843/27f8eb4d-56af-0c4e-1e15-fc1672853515.png)

## 適当にアプリケーションを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237843/4c991fab-3786-6ca0-8b15-2516ee367423.png)

## ボタンを押すと2つのスピンボックスの値を足した値をlineEditにセットする

```cpp:MainWindow.hpp
private slots:
    void on_pushButton_clicked();
```

```cpp:MainWindow.cpp
void MainWindow::on_pushButton_clicked()
{
    ui->lineEdit->setText(QString::number(ui->spinBox->value() + ui->spinBox_2->value()));
}
```

## テストプロジェクトのためにpriファイルを作成し，proファイルを修正する
priファイルはproファイルと同じディレクトリに置きます

```text:SampleGui.pri
INCLUDEPATH += $$PWD
VPATH += $$PWD

SOURCES += \
    MainWindow.cpp

HEADERS += \
    MainWindow.hpp

FORMS += \
    MainWindow.ui
```

```text:SampleGui.pro
SOURCES += \
    main.cpp

include(SampleGui.pri)
```

この時点でビルドして実行すると以下のような画面が出るはずです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237843/70c03a80-0136-184f-d0b0-f869c3914fca.png)

## テストプロジェクトを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237843/f99ec7db-b490-d410-30b2-148521b15f8c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237843/c80b05be-8958-3952-4864-6b19b9c1cbbc.png)

## テストプロジェクトのproファイルにアプリケーションのpriファイルを追加する

```text:TestGuiSample.pro
include(../SampleGui/SampleGui.pri)
```

## テストを記述する
スピンボックスに10と20を設定し，ボタンをクリックすることでラインエディットに30が格納されていることを確認する

```cpp:tst_testcase.cpp
void TestCase::test_case1()
{
    ui->findChild<QSpinBox*>("spinBox")->setValue(10);
    ui->findChild<QSpinBox*>("spinBox_2")->setValue(20);
    QTest::mouseClick(ui->findChild<QPushButton*>("pushButton"), Qt::LeftButton);
    QCOMPARE(ui->findChild<QLineEdit*>("lineEdit")->text(), "30");
}
```

## 実行する
ビルド後は
ツール -> Tests -> Run All Tests
からテストを実行できます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237843/5c964404-554b-07c8-a3c9-02acafa57842.png)

# 感想
思ったよりも簡単にテストができました．
もっと調べてみたいと思いました．

# 作ったプロジェクト
[okamoto950712/QtTestSample](https://github.com/okamoto950712/QtTestSample)

# 参考
[QTest Namespace | Qt Test 5.15.4](https://doc.qt.io/qt-5/qtest.html)
[Chapter 3: Simulating GUI Events | Qt Test 5.15.4](https://doc.qt.io/qt-5/qttestlib-tutorial3-example.html)
PostmanでJSONをPOSTし、DynamoDBに格納したときのメモ

# 概要
Postmanを用いてJSONをPOSTし、JSON内の情報をDynamoDBに格納するための環境を構築したためメモを残します。

# １．DynamoDBのテーブル作成
パーティションキーとソートキーは以下のように設定しました。右下の青い作成ボタンを押すとテーブルが作成されます。
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1516301/d18c0a13-717d-dd56-63b3-024cd26b76bd.png)

# ２．Lambda関数の作成
JSONの情報をDynamoDBに格納する仕事をしてくれるLambda関数を作成します。ランタイムはPython 3.7を用いました。
IAMでLambdaがDynamoDBに書き込みできるようにロールを作成し、適用してください。

```python:data-store.py
import boto3
from decimal import Decimal

dynamodb = boto3.resource('dynamodb')

def fill_empty_item(event):
    for key in event:
        if event[key] == "":
            event[key] = "(null)"
    return event
    
def put_item(event, table_name):
    table = dynamodb.Table(table_name)
    for key in event:
        if type(event[key]) is float:
            event[key] = Decimal(str(event[key]))
    table.put_item(
        Item = event
        )

def lambda_handler(event, context):
    fill_empty_item(event)
    put_item(event, "test-table")
```

# ３．APIを作成
API GatewayからAPIを作成します。REST APIのタイル上にある構築を押します。
アクションからdata-store-apiのリソースを作成し、POSTのメゾットを作成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1516301/2af4ab51-0668-3457-ec16-97cec77b7fd8.png)

POST-セットアップのLambda 関数の項目で２．で作成したLambda関数を選択します。
その後、/data-store-apiの階層を選択し、アクションからCORSの有効化及びAPIのデプロイを行います。
APIのデプロイが完了するとURLの呼び出しでURLが表示されますが、Postmanで用いるURLではありません。
Postmanで用いるURLはステージからPOSTのメゾットを選択したときに確認できます。

# ４．PostmanでJSONをPOST
ステージから確認できるPOSTのAPIにおけるURLをPostmanに貼り付けます。
BodyにJSONの情報を格納します。今回はrawを選択し、以下の情報を入力しました。
{
    "DeviceId": "001",
    "Timestamp": "2021-05-18",
    "SensorData": 0.05,
    "hoge":""
}

最後に右の青いボタン"Send"を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1516301/a49fbd94-608c-54f8-f09b-a6d0fc788c00.png)

すると、１．で作成したテーブルにアイテムが追加されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1516301/6a294366-76bf-11e8-84ff-4c2b15675279.png)


以上です。間違いに気づいたらご指摘をお願いします。
アプリケーションライフサイクルと開発モデル ⇒ 複雑さを増すリリースでの変更の管理

１．組織開発を使用すると、変更管理上の課題を抱える Zephyrus のチームにどのようなメリットがありますか?
２．組織開発と変更セット開発のどちらにも正しい記述はどれですか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/aefe8717-7ef8-fdbf-5670-c4e308156c60.png)
Celenium＋Eddgeでのページ移動とDLについて_後ドライバー詰まるとこ

#Web操作
・Webアプリなどから、業務用の処理やデータを取り出す。
・同名のデータは事前に削除しておく。

##Celenium＋Microsft EddgeでのWebからデータをDL
###やる事
1.eddgeのWebdriverをDLしてくる。
2.作成コードの下位フォルダへ格納する。
　例：コードにも反映する　

```python:python
browser = webdriver.Edge("./driver/msedgedriver.exe")
```

サンプルコード
サイトにログイン後、データをDLして更新する。

概要としては、
browser = webdriver.Edge("./driver/msedgedriver.exe")を用い、
el = browser.find_element_by_name('txtDomainName')　などのように、エレメントを指定し
el.send_keys('＊＊＊＊＊＊＊＊＊＊')　でテキストなどを入力したり
browser.find_element_by_id("mnuDataDownload").click()でクリックで大体は事足りると思える。

jsなどのアクションなども指定して実行させることができる。

```python:python
from selenium import webdriver
from datetime import datetime, date, timedelta
import time
from glob import glob
import os
from tkinter import messagebox
from selenium.webdriver.support.select import Select

browser = webdriver.Edge("./driver/msedgedriver.exe")
browser.implicitly_wait(10) # seconds
browser.get('https://........ログインしたいサイト')
```

##サイト表示後
ログインするためにはIDとPASSを入力すると思います。
こちらに関しては、eddgeですと、
　1.サイト上で右クリック
　2.検証
　3.色々とカーソルを動かして、htmlのどこが関わるかを調べる。

```
#ドメイン入力
el = browser.find_element_by_name('txtDomainName')
el.send_keys('＊＊＊＊＊＊＊')
#ログインID入力
el = browser.find_element_by_name('txtUserName')
el.send_keys('＊＊＊＊＊＊＊＊＊＊')
#パスワード入力
el = browser.find_element_by_name('txtPassword')
el.send_keys('＊＊＊＊＊＊＊＊＊')
#Loginボタンを押す
#browser.execute_script("javascript:__doPostBack('btnLogin','')")
browser.execute_script("__doPostBack('btnLogin','')")

browser.find_element_by_id("mnuDataDownload").click()

dropdown = browser.find_element_by_id('ctl00_ContentPlaceHolder1_mnuDataDownload_drpGroup')
select = Select(dropdown)
select.select_by_value('-1')

dropdown = browser.find_element_by_id('ctl00_ContentPlaceHolder1_mnuDataDownload_drpFileName')
select = Select(dropdown)
select.select_by_value("/User/10438/Private/＊＊＊＊＊＊＊.DataDownload")

#日付指定
browser.find_element_by_id("ctl00_ContentPlaceHolder1_mnuDataDownload_imgCalendarStart").click()
browser.find_element_by_id("ctl00_ContentPlaceHolder1_mnuDataDownload_calDateStart_today").click()
browser.find_element_by_id("ctl00_ContentPlaceHolder1_mnuDataDownload_btSubmit").click()

#Dlデータ事前削除
folda_path =r'C:\Users\＊＊＊＊＊\Downloads'

file = glob(r"C:\Users\＊＊＊＊＊＊\Downloads\＊＊＊＊＊.csv")
if file:
    filepath =file[0]
    print(filepath)
    os.remove(filepath)
    print("できたよ！")

#DL_Start
time.sleep(3)
browser.find_element_by_id("ctl00_ContentPlaceHolder1_lnkDownload").click()


#webブラウザ閉じる
time.sleep(3)
browser.close()
browser.quit()
```
ふりかえりの手法を実践してみる ～熱気球～

## はじめに

私はスクラムのイベントの一つであるレトロスペクティブを通じて、ふりかえりがチームにもたらす効果と手法の多さ、そしてその手法一つ一つがもたらす効果が違うことに気づくことができました。
この効果やふりかえりの楽しさをチームメンバーにも共感してもらいたく、毎週のふりかえり手法を変えてみようとしています。
ただ、チームに閉じたアクションにするのももったいないので、その手法をやってみた感想などを記事にすることで、 1 人でも多くの人に「ふりかえりをやってみたい！」とか「楽しそう！」と思ってもらえたらいいなと思い、実際にやってみたふりかえり手法について Qiita 記事にしてみることにしました。
記念すべき第 1 回目は「熱気球」です！

## このふりかえり手法について

チームが乗っていると例えた熱気球をホワイトボードに描き、その熱気球が

- 高く飛ぶための上昇気流となった要因
- 飛ぶのに妨げになった荷物となった要因
- 今後飛ぶのに影響が出そうな雲となる要因

の3つの観点からチームの状況を可視化し、今後更に高く飛ぶためのアイデアを出し合う方法です。

## 参考にした書籍・サイト

ふりかえりエバンジェリストである 森 一樹さんの著書「[アジャイルなチームをつくる ふりかえりガイドブック 始め方・ふりかえりの型・手法・マインドセット](https://www.shoeisha.co.jp/book/detail/9784798168791)」と[こちら](https://note.com/at__946/n/ndb3cb76127a5)の note 記事を参考にさせていただきました。

## タイムテーブル

- 前回アクションのふりかえり：10分
- 今回レトロ(熱気球) & miro の説明：10分
- 「上昇気流」付箋出し：5分
- 「上昇気流」の共有：7分
- 「荷物」付箋出し：5分
- 「荷物」の共有：7分
- 「雲」付箋出し：5分
- 「雲」の共有：7分
- 熱気球をより高く飛ばすためにフォーカスしたいものの決定 & アクション出し：20分

## 事前準備

miro を用いてチーム全員がアクセスできるホワイトボードを用意しました。
そのホワイトボードの中心にはチームが乗っていると例えた熱気球を描いておきます。

## 実際のふりかえりのホワイトボード

![レトロ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298729/c185f7ee-f1f0-1fa1-9248-383e8e9245ec.png)

※オープンにできない情報も多いのでモザイクを掛けてます

## ふりかえりの流れ

まず、このふりかえりについての説明とチームで miro を使うのが初めてだったメンバーもいたので、簡単に miro の使い方を説明しました。
その後実際にふりかえりを進めていきます。
まずは赤い付箋でこの気球が高く飛べる要因となった「上昇気流」を書いてもらいました。付箋を出したあとはチームで何を書いたか共有・深堀りをしていきました。
その次に気球が飛ぶのに妨げになった「荷物」、今後飛ぶのに妨げになりそうな「雲」についても同様に青と白で付箋出しと共有・深堀りをしていきます。

それらが終わったら、次はこの気球が今後更に高く飛ばすために勢いをつけたい「上昇気流」と取り除きたい「荷物」「雲」をチームで話しながら選択します。
そしてその選択したものについて、どうしたら「上昇気流」の勢いをつけられるか、どうしたら「荷物」「雲」を取り除くことができるかチームでアイデアを出し合い、実際のアクションプランを決定しました。

## ふりかえりをやってみた感想

代表的な KPT など他の手法と比べて、「雲」という今後チームの妨げになりそうなものを共有し、それに対するアクションを決めるというのは非常に特徴的だと感じました。チームが前進していく上で今後のリスクについてチームで共有し、それについてアクションを起こしていくのはすごくいい取り組みだと感じています。
また、気球の上昇というチームが前進する様子を例えられているのも、自分たちが前進している実感を得られる要素になるのがすごくいいと思いました。
今後のカイゼンとして挙げるのであれば、ただ付箋を共有するのではなく、メンバーで気球が上昇していく様子のイラストを描きながらふりかえりができれば、もっとこのふりかえりが楽しく感じることができたなと感じています。

## 最後に

今回は「熱気球」をやってみましたが、個人的にはすごく気に入ったふりかえり手法になりました。
文中に紹介した森さんの著書によると帆船やスピードカー、ロケットというメタファで同様に実施することもでき、このメタファを変えるだけで同じテーマでも別の結果が生まれるとのことだったので、次は変えてやってみようと思います！
リモートブランチ　作成方法

#ローカルのブランチからブランチを作成する！
1.ブランチを作りたいgitのディレクトリにcdで移動
cd ディレクトリパス

2.ブランチの一覧を確認する
git branch -a

3.masterブランチに移動
git checkout master

4.ブランチを作成
git checkout -b 作成するブランチ名

5.ブランチをリモートに登録
git push -u origin 作成したブランチ名


自分用のメモとして作成
簡単:v: