OmniAICreator/Qiita-1.07M huggingface dataset:
C#のstringとbyteの相互変換

shift-jisは可変長だから、自分で勝手に2バイト区切りにしては駄目

```C#
            {
                string sOriginal = "ユニＣｏｄｅのbyte変換";
                byte[] arrBytes = Encoding.Unicode.GetBytes(sOriginal);
                //foreach (byte b in bytesData) Debug.WriteLine(b);
                Debug.WriteLine(BitConverter.ToString(arrBytes));
                string hexString = BitConverter.ToString(arrBytes).Replace("-", "");
                Debug.WriteLine(hexString);

                byte[] repack = new byte[hexString.Length / 2];
                for (var i = 0; i < hexString.Length / 2; i++)
                {
                    var hexChar = hexString.Substring(2 * i, 2);
                    repack[i] = Convert.ToByte(hexChar, 16);
                }
                Debug.WriteLine(Encoding.Unicode.GetString(repack));

                //2バイトずつもどす
                byte[] tmp = new byte[2];
                for (int i = 0; i < arrBytes.Length / 2; i++)
                {
                    tmp[0] = arrBytes[2 * i + 0];
                    tmp[1] = arrBytes[2 * i + 1];
                    Debug.WriteLine(Encoding.Unicode.GetString(tmp));
                }
            }
            Debug.WriteLine("---");
            {
                string sOriginal = "シフトjisのbyte変換";
                byte[] arrBytes = Encoding.GetEncoding("Shift_JIS").GetBytes(sOriginal);
                //foreach (byte b in bytesData) Debug.WriteLine(b);
                Debug.WriteLine(BitConverter.ToString(arrBytes));
                string hexString = BitConverter.ToString(arrBytes).Replace("-", "");
                Debug.WriteLine(hexString);

                byte[] repack = new byte[hexString.Length / 2];
                for (var i = 0; i < hexString.Length / 2; i++)
                {
                    var hexChar = hexString.Substring(2 * i, 2);
                    repack[i] = Convert.ToByte(hexChar, 16);
                }
                Debug.WriteLine(Encoding.GetEncoding("Shift_JIS").GetString(repack));

                //shiftjisは可変長なので、2バイトで区切るとくしゃくしゃになる
                byte[] tmp = new byte[2];
                for (int i = 0; i < arrBytes.Length / 2; i++)
                {
                    tmp[0] = arrBytes[2 * i + 0];
                    tmp[1] = arrBytes[2 * i + 1];
                    Debug.WriteLine(Encoding.GetEncoding("Shift_JIS").GetString(tmp));
                }
            }
```

実行結果

```
E6-30-CB-30-23-FF-4F-FF-44-FF-45-FF-6E-30-62-00-79-00-74-00-65-00-09-59-DB-63
E630CB3023FF4FFF44FF45FF6E3062007900740065000959DB63
ユニＣｏｄｅのbyte変換
ユ
ニ
Ｃ
ｏ
ｄ
ｅ
の
b
y
t
e
変
換
---
83-56-83-74-83-67-6A-69-73-82-CC-62-79-74-65-95-CF-8A-B7
8356837483676A697382CC6279746595CF8AB7
シフトjisのbyte変換
シ
フ
ト
ji
s・
ﾌb
yt
e・
ﾏ・
```
Windows・macOS完全対応GitLab開発環境最終版 (2020年12月)


わずか3ヶ月前に[macOSにGitLab開発環境セットアップ (GDK) (2020年9月)](https://qiita.com/tnir/items/ec704a58a7b54949cf7f)という記事を書きました。が、1四半期が経過し状況も変化したので新たに書くことになりました。

**tl; dr:** GitLab本体やGitaly（バックエンド）をmacOSやWindows、Linuxの各種環境で開発する環境を用意する。

### GitLab Development Kit
GitLab Development Kitと呼ばれるGitLab本体を手元のコンピュータで開発できるツールがGitLab開発開始直後より存在していました。
一方、AWSが3年前の今日2017年12月1日（日本時間）に発表した[AWS Cloud 9](https://aws.amazon.com/cloud9/)、マイクロソフト傘下GitHubの[GitHub Codespaces](https://github.com/features/codespaces) (現在Early access program中）（旧マイクロソフトVisual Studio Codespaces）（[移行ニュースリリース](https://devblogs.microsoft.com/visualstudio/visual-studio-codespaces-is-consolidating-into-github-codespaces/)）、そして2020年10月、Google Cloudから発表された[新Cloud Shell Editor](https://cloud.google.com/blog/products/application-development/introducing-cloud-shell-editor)に代表されるトレンドがありました。
この四半期の間にGDKがクラウドIDEプラットフォームに対応しました。対応しているクラウドIDEはGitpodというサービスです。

### Gitpod
https://www.gitpod.io/
![](https://www.gitpod.io/static/screenshot-500034efe425da10cf38587a9294a4d8.png)
GitpodはGitHub(.com)、GitLab(.com)およびBitbucket(.org)に対応するクラウドIDEサービスです。Eclipse Foundation参加のオープンソースプロジェクトEclipse Theiaをベースにしています。2020年8月にはGitpodそのものもオープンソース化されました。Gitpodクラウド版のユーザとしては、無料から始めることができ、無料プランではパブリックリポジトリであれば月50時間までワークスペースを利用できます。

USおよびEUのregionにあるGCP上のKubernetes (GKEなのではないかと推測) に構築されており、ユーザーは16vCPU、59GBメモリの利用ができるようです。なお、以前にあった（そしてドキュメントに記載されている）Asiaのクラスターは既に削除されていて利用できないとのこと。

### 手順
ここを読むほとんどの人は以下の作業が必要になる。例外はGitLab team memberおよび過去にGitLabへコード貢献があった人（過去のGitLab Hackathon参加者も該当する可能性が高い）。

1. https://gitlab.com にログインする。アカウントがない場合はSign upから作成する。
2. https://gitpod.io にログインする。アカウントがない場合はGitLabアカウントでアカウント作成＆ログインする。
3. https://gitlab.com/gitlab-org/gitlab を開いて、Forkボタンを押したのち、自分のユーザ名の右にあるSelectボタンを押す。そして、しばらく待つ（2-10分くらい？）。
4. 完了したら、表示されたページのWeb IDEの右にある▽を押し、プルダウンメニューからGitpodを選ぶ。そして、もう一度Gitpodを押す。
5. 7-8分待つ。

![](https://gitlab.com/gitlab-org/gitlab-development-kit/-/raw/master/doc/howto/img/gitpod-button-repository.png)

![](https://gitlab.com/gitlab-org/gitlab-development-kit/-/raw/master/doc/howto/img/gdk-in-gitpod.png)

### Gitpodに関する注意
GitLabログインを通じて、Gitpod側にはクレデンシャルが設定済みなので、git fetch/push/pullの操作が可能になります。gpコマンドとして利用可能です。
GDKターミナルでは `/workspace/gitlab-development-kit` がカレントディレクトリとして指定されており、`gdk` コマンドが利用できます。
GitLabターミナルでは `/workspace/gitlab` がカレントディレクトリとして指定されており、（通常のGDKセットアップと異なり） `gdk` コマンドが利用できませんので、注意してください。


その他は https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/master/doc/howto/gitpod.md を見てください。

### まとめ
すぐにGitLabの開発に参加できるGitLab Development Kit powered by Gitpodについて説明しました。一人でも多くのコードコントリビュータが増えることを願っています。

### すぐに試したい？
GitLab Tokyoコミュニティは12月2〜3日Hackathonイベントを日本語・オンラインで実施します。参加するには、こちらの記事に書かれたセットアップが必要となります。開催時間中にセットアップすることも可能です。ぜひご参加ください。

- 2020-12-02 (水) https://gitlab-jp.connpass.com/event/189496/
- 2020-12-03 (木) https://gitlab-jp.connpass.com/event/189683/

### Qiitaの先人たちによる同種の記事
- 2020年9月 https://qiita.com/tnir/items/ec704a58a7b54949cf7f
- 2018年10月 https://qiita.com/jb-vasseur/items/9f7691c39a0d8baa335a
- 2017年12月 https://qiita.com/ogomr/items/cc404bf9373408663b11
- 2015年6月 https://qiita.com/hiroponz/items/b36bb521551f94eb4fc1
Pythonで一元配置分散分析

# 分散分析の概要

以下のような問題を考えます。

```:【例題】
因子Aについて4つの水準A1~A4があり、それぞれの水準で以下のような観測が得られた。
水準間に違いはあると言えるか、有意水準5%で検定せよ。
```

|level \ n| 1 | 2 | 3 | 4 | 5 |
|:--------|:--|:--|:--|:--|:--|
|   **A1**| 15| 13| 15| 16| 14| 
|   **A2**| 18| 17| 16| 15| 18| 
|   **A3**| 19| 16| 17| 18|   | 
|   **A4**| 17| 15| 16|   |   |　


2標本の平均値の差の検定にはt検定が用いられますが、上記の問題のように3群以上からなるデータの場合には「**分散分析**」を行います。この場合、因子がAのみであるため「**一元配置分散分析**」です。

帰無仮説$H_0$は「各水準の母平均は等しい」、対立仮説$H_0$「少なくとも一つの水準について母平均が異なる」となります。


# 分散分析の実装

パッケージを利用して分散分析を行う場合には `statsmodels.stats.anova` などが用いられますが、今回はパッケージを利用せずに実施します。全体の流れとしては次の通りです。

* **Step1**. 総平方和を求める
* **Step2**. 水準間平方和、誤差平方和を求める
* **Step3**. F統計量を求める
* **Step4**. F分布から棄却域を決定する
* **Step5**. 帰無仮説を棄却するかどうか判断する

```python:In
import numpy as np
from scipy.stats import f

Y = [
    [15, 13, 15, 16, 14], 
    [18, 17, 16, 15, 18], 
    [19, 16, 17, 18], 
    [17, 15, 16]
]
```

## Step1. 総平方和を求める

まず、データ全体のデータの個数と平均値を求めます。

```python:In
n_instances = 0
total = 0
for y_A in Y:
    n_instances += len(y_A)
    total += sum(y_A)

total_mean = total / n_instances
print('データの個数: {}\nデータ全体の平均値: {}'.format(n_instances, total_mean))
```

```r:Out
データの個数: 17
データ全体の平均値: 16.176470588235293
```

応答yについて、全体の平均値からの偏差について二乗和をとり、総平方和$S_T$を次のように求めます。

$$S_T=\sum_{i=1}^{a}\sum_{j=1}^{n}(y_{ij}-\bar{y})^2$$

```python:In
S_T = 0
for i, y_A in enumerate(Y):
    for j in range(len(y_A)):
        S_T += (Y[i][j] - total_mean)**2

print('S_T = {}'.format(S_T))
```

```r:Out
S_T = 40.47058823529411
```

## Step2. 水準間平方和、誤差平方和を求める

続いて水準間平方和$S_A$を次のように求めます。水準ごとの平均のばらつきが大きいほど$S_A$が大きくなります。

$$S_A=\sum_{i=1}^{a}\sum_{j=1}^{n}(\bar{y}_{A_i}-\bar{y})^2$$

```python:In
means = []
for y_A in Y:
    mean_A = sum(y_A)/len(y_A)
    means.append(mean_A)

S_A = 0
for i, mean_A in enumerate(means):
    S_A += (mean_A - total_mean)**2 * len(data[i])

print('S_A = {}'.format(S_A))
```

```r:Out
S_A = 21.47058823529413
```

総平方和$S_T$から水準間平方和$S_A$を引くと、誤差平方和$S_E$に等しくなります。

```python:In
S_E = S_T - S_A
print('S_E = {}'.format(S_E))
```

```r:Out
S_E = 18.99999999999998
```

## Step3. F統計量を求める

総平方和, 水準間平方和, 誤差平方和の自由度$\phi_T, \phi_A, \phi_E$はそれぞれ以下のように求められます。

```python:In
phi_T = n_instances - 1
phi_A = len(Y) - 1
phi_E = phi_T - phi_A

print(phi_T, phi_A, phi_E)
```

```r:Out
16 3 13
```

平方和$S_A, S_E$を自由度$\phi_A, \phi_E$で割り、水準間の変動$V_A=S_A/\phi_A$、および誤差による変動$V_E=S_E/\phi_E$を求めます。

帰無仮説が成り立つ場合には、次のF統計量は自由度 ($\phi_A, \phi_E$) のF分布に従います。

$$F=\frac{V_A}{V_E}=\frac{S_A/\phi_A}{S_E/\phi_E}$$

```python:In
F = V_A / V_E
print('F = {}'.format(F))
```

```r:Out
F = 4.896800825593403
```

## Step4. F分布から棄却域を決定する

自由度 (3, 13) のF分布の上側5%点を求めます。

```python:In
f_distribution = f(phi_A, phi_E)
f_distribution.ppf(0.95)
```

```r:Out
3.4105336446278476
```

よって棄却域は $F \geq 3.411$ となります。

## Step5. 帰無仮説を棄却するかどうか判断する

Step3で求めたF統計量は棄却域に含まれるので、帰無仮説は棄却されます。
すなわち、「水準間の母平均には違いがあるといえる」と結論づけられます。

# 参考

* [日本統計学会公式認定 統計検定準1級対応 統計学実践ワークブック](https://www.amazon.co.jp/dp/478060852X/)
* [29-1. 分散分析とは - 統計WEB](https://bellcurve.jp/statistics/course/10006.html)
レガシーなVisualStudioでNuGetして四苦八苦した話

お仕事のなかでレガシーなVisualStudio（2013や2015）を利用するケースが多く、NuGetを利用した依存性解決を行おうとしたときに四苦八苦した事例を紹介します。

# 発生条件

古いバージョンのVisualStudio、とくにVisualStudio 2013を利用している。

# 発生事象1

NuGet.exeによるパッケージの復元を行うとき（VSでビルドを行ったときなどが該当）、System.MissingMethodException例外がスローされビルドが中断してしまう。

VS2013の出力内容：

```
エラー 1 ハンドルされていない例外: System.MissingMethodException: メソッドが見つかりません: '!!0[] System.Array.Empty()' ConsoleApplication1
エラー 2 場所 NuGet.Common.CommandLineResponseFile.ParseArgsResponseFiles(String[] args, Int32 parseArgsResponseFileRecursionDepth) ConsoleApplication1
エラー 3 場所 NuGet.CommandLine.Program.Main(String[] args) ConsoleApplication1
エラー 4 コマンド ""c:\users\mizukyf\documents\visual studio 2013\Projects\ConsoleApplication1\.nuget\NuGet.exe" install "c:\users\mizukyf\documents\visual studio 2013\Projects\ConsoleApplication1\ConsoleApplication1\packages.config" -source "" -NonInteractive -RequireConsent -solutionDir "c:\users\mizukyf\documents\visual studio 2013\Projects\ConsoleApplication1\ "" はコード -532462766 で終了しました。 ConsoleApplication1
```

事象発生時のVS2013画面の例：
![3279343280image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/7d4bd992-452e-67a7-1fca-ffa2f882cab5.png)

# 発生事象1 - 原因

NuGet.exeが想定する.NET Frameworkのバージョンと、開発マシンにインストールされている.NET Frameworkのバージョンの齟齬。

とくにVisual Studio 2013（以降、VS2013）を利用している場合この事象が起きやすいです。VS 2013までNuGet.exeとVSとの統合が中途半端で、新規ソリューションで「NuGetによるパッケージの復元」を有効化するたび、当該ソリューション内にその時点で最新のNuGet.exeがWeb上からダウンロードされ利用されるからです。

# 発生事象1 - 対策

Microsoft社のWebサイトから最新の.NET Framework（v4.6以上）をダウンロードして開発PCにインストールする。

# 発生事象2

NuGet.exeによるパッケージの復元を行うとき（VSでビルドを行ったときなどが該当）、エラーが発生「Unable to find version...」「コード 1 で終了しました」という出力とともにビルドが中断してしまう。

VS2013の出力内容：

```
エラー	6	Unable to find version '3.2.0.0' of package 'NLog'.	(project name)
エラー	7	Unable to find version '12.1.022' of package 'Oracle.ManagedDataAccess'.	(project name)
エラー	8	Unable to find version '12.1.022' of package 'Oracle.ManagedDataAccess.EntityFramework'.	(project name)
エラー	9	コマンド ""C:\path\to\solution\.nuget\NuGet.exe" install "C:\path\to\solution\project\packages.config" -source ""  -NonInteractive -RequireConsent -solutionDir "C:\path\to\solution\ "" はコード 1 で終了しました。	(project name)
```

# 発生事象2 - 原因

NuGet.exeのバージョンが古く、パッケージリポジトリNuGet Galleryにアクセスして依存性解決する際のプロトコルがNuGet Galleryサポート対象外となってしまっている。

これもとくにVisual Studio 2013（以降、VS2013）を利用している場合発生しやすいです。理由は事象1と同様です。

# 発生事象2 - 対策

NuGetの公式サイトから新しいバージョンのNuGetを取得してインストールする。
とくにVS2013の場合は、ソリューションフォルダ直下の.nugetフォルダに格納されたEXEを上書きする。
Reactのドラッグ&ドロップを使ったソート

おすすめはreact-sortable-hocです。
https://mebee.info/2020/05/03/post-7246/


ちなみに、複数選択して同時にドラッグ&ドロップすることもできました。(hooksでは書き直せない。別記事参考)
https://github.com/clauderic/react-sortable-hoc/issues/318
Windows10のドライブレーターの変更方法とエラーが出た時の対処法

昨日HDDのドライブレターをFからDに変更しようとしたらエラーが出たので解決方法についての備忘です。

#イメージ
最終的にこのような形にしていきます。
![デバイスとDrive](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759440/4f06782c-a798-bae6-3d9e-fa15b213e84d.png)

#ドライブレターの変更方法
注意として、ドライブレターを変更すると一部のアプリが動作しなくなる可能性があります。

タスクバーの検索ボックスで「ディスクの管理」と検索し開きます。
そして変更したいドライブを右クリックし「ドライブ名とパスの変更」をクリックします。

これで好きなドライブ文字を割り当ててOKをクリックしたら成功です。

![ドライブ文字またはパスを変更](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759440/dc59ddc2-885e-afe7-db11-b0b087cb38ac.png)

##エラーが出る場合

ここまではググればよくでる内容ですが自分の環境の場合「パラメーターが間違っています」とエラーが出ました。
検索するとHDDを接続し直すなどの記事がヒットしましたがこれはページファイルが原因のようです。

設定を開いて「システム」→「詳細情報」→関連情報から「システムの詳細設定」→「パフォーマンスの設定」→「詳細設定」→「仮想メモリの変更」をクリックします。

そしたら「自動的に管理する」のチェックを外しドライブレターを変更したいドライブを選択してページファイルなしを選択して保存し再起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759440/aebe4eb5-702e-92e2-b44b-2bfa85bda154.png)

するとドライブレターが変更できるはずです。
変更した後は仮想メモリの設定を戻してOKです。

参考にしたサイトはこちらです。
2013年の記事ですが大変参考になりました。
https://ch.nicovideo.jp/muk/blomaga/ar361043
クラスコンポーネントのtips

hooksに書き直せないパターンに初めて出会って、クラスコンポーネントで書かなければならず、まともにやってなかったのでいろいろ忘れないようにメモしておく。

##ちなみにhooksに書き直せないパターン

```js
handleUpdateBeforeSortStart = ({index}) => {
    return new Promise((resolve) =>
      this.setState(
        ({items}) => ({
          sortingItemKey: items[index],
          isSorting: true,
        }),
        resolve,
      ),
    );
  };
```

PromiseのなかでsetStateして、第二引数のコールバックにresolveを指定している場合。
hooksのuseStateではコールバックを指定できず、大抵の場合はuseEffectの中で書くが、promiseのresolveはむり？みたい

##tips

- クラスコンポーネント内ではletやconstなどは書かない
- クラス内で定義した変数にはthisでアクセス
- 子コンポーネントからstateを変更したい場合には親コンポーネントでstateを変更する関数を作ってそれを子コンポーネントに渡す
基本情報（FE)対策

<html lang="ja">

<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="styl.css">
</head>
<body>
        <div class="head">
            <h1>私の基本情報技術者試験(FE)対策</h1>
            <p>こんにちわ！突然ですが、皆さんは基本情報技術者(FE)の資格を何歳で取りましたか？またいつ頃取る予定ですか？
                私は今年度受験する予定です。それにあたって今回は私流のFE対策を紹介します。</p>
        </div>
        <div class="box">
            <div class="first">
                <h1>なぜFEを受けるのか</h1>
                <p>まず、なぜ私がFEを受けようと思ったのかをお話ししようと思います。<br>
                私は今19歳で、県立の短大に通っています。来年度には就活が迫っている状態です。私が志望する企業はIT企業です。そこでIT系の資格って
            何があるんだろうと思い調べていたところ、基本情報技術者という資格を知りました。</p>
            </div>
            <div class="second">
                <h1>対策の仕方</h1>
                <p>まず私が使っているFE対策サイトを紹介します。有名なので皆さん知ってると思います。
                    「基本情報技術者試験ドットコム　過去問道場」です。教科書はいろいろ買ったんですが、
                    正直僕はどれでもいい気がするので、おススメは「イメージ＆クレバー方式でよくわかる柏木先生の基本情報技術者教室」です。
                    手っ取り早く覚えられるからおススメです。
                </p>
                <li><a href="https://www.fe-siken.com/fekakomon.php" target="_blank">基本情報技術者試験ドットコム　過去問道場</a></li>
                <li><a href="https://www.amazon.co.jp/%E4%BB%A4%E5%92%8C02%E5%B9%B4-%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8-%E3%82%AF%E3%83%AC%E3%83%90%E3%83%BC%E6%96%B9%E5%BC%8F%E3%81%A7%E3%82%88%E3%81%8F%E3%82%8F%E3%81%8B%E3%82%8B-%E6%A0%A2%E6%9C%A8%E5%85%88%E7%94%9F%E3%81%AE%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85%E6%95%99%E5%AE%A4-%E6%A0%A2%E6%9C%A8/dp/4297110113" target="_blank">イメージ＆クレバー方式でよくわかる柏木先生の基本情報技術者教室</a></li>
                <p></p>
            </div>
    </div>
</body>
</html>
ターミナル で文字化けしたら Git Bash を使おう

# はじめに
初心者ですが、Rails Girls Japan Advent Calendar 2020 の初日を書きます。

記事内容とは直接関係ないのですが、今年は [Ruby技術者認定試験 Silver 合格](https://qiita.com/superrino130/items/0b22c639bacc43ec9282)、[Ruby技術者認定試験 Gold 合格](https://qiita.com/superrino130/items/328854a699658ed72d30) とRuby漬けの年でした。

しかしながら、こんなショボい失敗を続けています。~~自責の念~~
良い子の皆さんは真似をしないように。
# VSCode で文字化け
```cmd.exe
C:\Users\user\Documents\GitHub\baukis2>bundle exec rails db:create
FATAL:  ���[�U"superrino"�̃p�X���[�h�F�؂Ɏ��s���܂���
Couldn't create 'baukis2_development' database. Please check your configuration.
```
`rails db:create`しようとしただけなのにエラー、しかも文字化け。
# 文字コード確認
```cmd.exe
C:\Users\user\Documents\GitHub\baukis2>chcp
現在のコード ページ: 932
```
`chcp`で文字コードの確認及び変更ができます。

|文字コード番号|文字コード|
|:--:|:--:|
|932|Shift_JIS|
|65001|UTF-8|
# 文字化け治らず
```cmd.exe
C:\Users\user\Documents\GitHub\baukis2>chcp 65001
Active code page: 65001

C:\Users\user\Documents\GitHub\baukis2>bundle exec rails db:create
FATAL:  ���[�U"superrino"�̃p�X���[�h�F�؂Ɏ��s���܂���
```
あれれ、`Ruby`って内部コードが`UTF-8`じゃなかったっけ。
# Git Bash で解決
`rails` をやっている方は`Git` 入っていると思います。

```Git.Bash
user@DESKTOP-JJHPP4A MINGW64 ~/Documents/GitHub/baukis2 (master)
$ bundle exec rails db:create
FATAL:  ユーザ"superrino"のパスワード認証に失敗しました
```
ちゃんと表示されました。
# まとめ
皆さん、よいクリスマス、よいお年をお過ごしください
[react-native]FlatListの使い方

###目的
App.jsに<FlatList>を表示する。レンダーする要素は別コンポーネント化。

###App.js

```
import React, { useState } from 'react';
import { 
  StyleSheet, 
  View, 
  FlatList 
} from 'react-native';

import GoalItem from './components/GoalItem';

export default function App() {

  const [courseGoals, setCourseGoals] = useState([]);

  //courseGoalsには以下のような配列が入っている。
　Array [
 　 Object {
   　 "id": "0.1283113872926156",
   　 "value": "Aaa",
  　},
 　 Object {
   　 "id": "0.1515628656002196",
   　 "value": "Aaa",
  　},
　]
　//

  return (
    <View style={styles.screen} >
      <FlatList 
        keyExtractor={(item, index) => item.id } //デフォルト値なので省略可
        data={courseGoals}   //　ここに繰り返したい配列をいれる。※要素はstringである必要がある
        renderItem={itemData => <GoalItem id={itemData.item.id} title={itemData.item.value} />} 
　　　　　// viewの部分　引数itemDataの.itemプロパティに配列の要素が一つづつ繰り返し入ってくるような感じ
      />
    </View>
  );
}
```

###GoalItem.js
レイアウトは任意

```
import React from 'react';
import { View, Text, StyleSheet,TouchableOpacity } from 'react-native';

const GoalItem = props => {
  return (
  <TouchableOpacity>
    <View>
      <Text>{props.title}</Text>
    </View>
  </TouchableOpacity>
  );
};


export default GoalItem;
```
###所感
意外と癖が強い。
繰り返しの部分はそれぞれにユニークなkeyを指定しないとreact nativeが警告を出す。
特定のリストを消す時にfilterメソッドを使ったりする時にも使える。
【Java】web.xmlについてメモ


#  web.xmlについて

「*Webアプリケーションに関する様々な設定を、xml形式で定義するためのもの*」

## 【説明】
web.xmlは

- アクセスされたURLに対して呼び出すクラス
- エラー時に実行する処理の指定

などの設定をします。

<!-- 使用場面 「いつつかうか？」「どこで、つかうか？」-->
## 【配置箇所】(結論: WEB-INF直下)

**web.xmlは 「WEB-INF」ディレクトリ直下 に配置し、Webアプリケーション毎に作成**します。
（※「web.xml デプロイメント記述子の生成」にチェックして作成した場合は、デフォルトで作成されます。

## 【読み込みのタイミング】
Webサーバ（HTTPサーバ）の起動時にWebアプリケーション毎にweb.xmlが読み込まれます。

## 【web.xmlの基本構造】
「XML宣言」、「DTD宣言」、「本体」の順で構成されています。

<!-- 基本構文など -->
## 【書き方】

```java
<?xml version="1.0" encoding="ISO-8859-1"?> // XML宣言
<!DOCTYPE web-app
   PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"  //DTD宣言
  "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
  ･･･       // 本体の記述
</web-app>
```

web.xmlは、Webサーバの起動時に読み込まれ構文チェックが行われます。

- 正しく記述されてない場合は、 「致命的エラー」扱いとなりそのコンテナは動きません。
- 正しく記述されていれば、「**本体にどのURLで、どのサーブレットを動かすかという定義必要**」となります。

（※サーブレットが上手く機能しない場合は、 web.xmlの設定や書き方に間違いがないかチェックしましょう


### 【サーブレットの命名の仕方】

```
<web-app>

  <servlet>
    <servlet-name>サーブレットの命名</servlet-name>
    <servlet-class>パッケージ名.サーブレット名</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>サーブレットの命名</servlet-name>
    <url-pattern>/URLのパターン名</url-pattern>
  </servlet-mapping>

</web-app>
```

### 【サンプル】ユーザーに情報を返すサーブレットの場合

```java
<servlet>
    <servlet-name>userInfo</servlet-name>
    <servlet-class>UserInfoServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>userInfo</servlet-name>
    <url-pattern>/user</url-pattern>
</servlet-mapping>
```

### web-app タグ
サーブレットの命名には「任意の名前」を付与
（ ※日本語は付けられません
#### 命名規則
`servletタグ`内 と `servlet-mappingタグ`内 の2つで実施し、
上記「**2つのタグにおけるサーブレットの命名は 同一でなくてはならない。**」 

#### servletタグ
servletタグには、`servlet-classタグ` があります。記述方法に関しては以下です。

- 「**動かしたいサーブレット名を記述**」します。
- パッケージ化されている場合は、 `helloPackage.HelloServlet`のように「パッケージ込みのサーブレット名を記述」します。
	
#### servlet-mapping タグ と url-pattern タグ
このタグ内に記述された文字列で、ブラウザのURL（アドレス）などで指定した場合、
先ほどの動かしたいサーブレットが動作する仕組みとなります。

#### サーブレットマッピング
上記  `servlet-mapping` における設定は、<font color="Red">必須</font> となり、この設定を「 **サーブレットマッピング** 」と呼びます。

マッピングは「 **可読性 と サーブレットの紐づけの親和性** 」が高まるようなその機能に合った意味を持つ文言を記述するようにすること。


<!-- 今後どうするかなどを有れば記述 -->

## 参考文献・記事

<!-- 参考にした資料のリンクを貼る -->

<!-- 以下リンク -->
MacでG703を使ってみたらスクロール方向が逆になった

#はじめに
プライベートではWindows+G703ゲーミングマウス、仕事ではMacBookのみで作業をしていました。
ちょうどこの記事が公開される日に誕生日を迎えるので、自分への誕生日プレゼントとしてWinとMac両対応のワイヤレスキーボードを購入しました。<br>自分は20年新卒入社の若輩者ですが、形から入るタイプです。<br><br>ゆえにプライベートで使っているG703もMacBookで使えるようにして、ワイヤレスキーボード＆マウスをブリブリに使うエンジニアになろう！ということで設定したことをまとめました。
#環境
<ul><li>MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)</li><li>macOS Catalina 10.15.7</li><li>Logicool G703</ul>
#スクロール方向が逆になる
Macでマウスを使うのはこれが初めてなんですが、G703を接続するとトラックパッドとマウスでのページスクロール方向が逆になってました。
「システム環境設定」→「マウス」→「スクロールの方向:ナチュラル」 にチェックを入れると通常通りのスクロール方向になりますが、今度はトラックパッドのスクロール方向が逆になってしまいます。
#Scroll Reverserのインストール
<a pref="https://pilotmoon.com/scrollreverser/">Scroll Reverser</a>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695545/7e780577-0338-f5c0-0102-86623eff6929.png)
設定画面で「マウスを逆にする」にチェックを入れましょう。これで理想のスクロール方向にできます。
#G HUBのインストール
<a href="https://gaming.logicool.co.jp/ja-jp/innovation/g-hub.html">こちら</a>からLogicool G HUBをインストールします。
G703を接続していると自動で認識してくれるので、特にドライバーとかのインストールは必要ないです。
このMacBookはUSB-typeCポートしかないので、<a href="https://www.amazon.co.jp/gp/product/B07Z5Y44FX/ref=ppx_yo_dt_b_asin_title_o09_s00?ie=UTF8&psc=1">Anker PowerExpand Direct 7-in-2</a>を使っています。
#ショートカット設定
Mission Controlや各種ショートカットを使うためにGHUBでショートカットを設定しましょう。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695545/67f51b07-837c-cbfb-711c-35673c761220.png)左のメニューから「割り当て」を選択します。
コマンドのタブにCtrlがないので、自分で各ショートカットのマクロを組みましょう。
自分は上から「Ctrl+↑」「Ctrl+→」「Ctrl+←」に設定しています。
普段はゲーム用にオンボードのメモリを使っているので、プロファイルの切り替えは設定しませんでした。
その代わりに、Gシフトキーを設定して、Gシフトを押している間別のショートカットを使えるようにしています。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695545/d740c1f5-c436-9e9b-fcf4-75a302603664.png)Gシフト+右クリックで前のページに戻るマクロを追加しました。
今の所この設定で問題なく仕事ができています。
#さいごに
ゲーマーの方はこれでMac用のマウス代節約！
おすすめのショートカット設定とかあれば教えていただけると幸いです〜
#余談
今回購入したキーボードは<a href="https://www.keychron.com/products/keychron-k8-tenkeyless-wireless-mechanical-keyboard?variant=32018252693593">Keychron K8 Aluminum Frame optical switch 茶軸</a>です。
かわいい。
RGBバックライトが付いてるのでゲーミングデバイスっぽい光り方をしますが、あまり好きじゃないので白ライト設定で運用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695545/c9d81ff9-0034-090e-7e35-f6250d6dd721.png)
最低限のMarkdown記法備忘録

# 見出し
 #を1~6個つける
### `記述`
![スクリーンショット 2020-12-01 14.29.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922003/4118a814-bdd1-90bc-a073-322773dc3495.png)

### `表示`
# 見出し1
## 見出し2
### 見出し3
#### 見出し4
##### 見出し5
###### 見出し6

# 引用
　>を先頭につける
### `記述`
![スクリーンショット 2020-12-01 14.39.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922003/9738fd20-9975-ce4b-72b1-3dd55ae15b1b.png)



### `表示`
>
>こんにちは
>
>私は元気です
>
>あなたはいかがですか
>

# code記法
　``で囲む
### `記述`
![スクリーンショット 2020-12-01 14.45.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922003/2a328af4-fdcf-a362-2ef1-3ac8482ad1c5.png)

### `表示`
`rails db:migrate`を実行してください

# 斜体
*か_で囲む
### `記述`
![スクリーンショット 2020-12-01 14.49.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922003/46fc67e4-add0-71e0-27f1-18aecdd77de9.png)


### `表示`

私は*ラーメン*が好きです

私は_ラーメン_が好きです

# 太字
**か__で囲む
### `記述`
![スクリーンショット 2020-12-01 14.52.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922003/2af0eaff-8f3b-94ac-8f86-c368b2b40f81.png)


### `表示`


私は**ラーメン**が好きです

私は__ラーメン__が好きです
【Laravel8.16】ORMで指定したカラムだけ取得する方法



Laravel歴2日の初心者です。
間違えてたらごめんなさい。


指定したカラムだけ取って来たい！！どないすんねん！！ってなったときの備忘録です。
公式マニュアルにも書いておらず、ググっても答えが出てこなかったのでソース直読みすることに。


# クエリビルダとORMでの全件取得方法

```php:クエリビルダ
$users = DB::table('users')->get();
```

```php:ORM
$users= App\Models\Users::all();
```

# 指定したカラムだけ取得する方法

```php:クエリビルダ
$users = DB::table('users')->select('name', 'email as user_email')->get();
```

```php:ORM
$users= App\Models\Users::all('name', 'email as user_email');
```

# ソース

```php:Model.php
    public static function all($columns = ['*'])
    {
        return static::query()->get(
            is_array($columns) ? $columns : func_get_args()
        );
    }
```
CPUSurplusCreditBalanceの課金額は60クレジットで5円

CPUSurplusCreditBalanceの課金額の計算方法をAWSサポートに問い合わせてみた。

### CPUSurplusCreditBalanceの課金額は約5円/時間

サポートに問い合わせた結果、「インスタンスタイプによらず、1時間あたり60クレジット」で「0.05USDが課金額」ということが分かった。

つまり、CPUSurplusCreditBalanceが60クレジットのインスタンスを即座に停止すると、下記の計算式で約5円が課金額になる。

```
60クレジットの超過 * 0.05 USD = 約5円
```

上記の計算式は、Linux系のインスタンスを仮定している。Windowsの場合は0.096USDで計算することになる。


### 参考リンク

[T2/T3/T4g Unlimited モードの料金](https://aws.amazon.com/jp/ec2/pricing/on-demand/#T2.2FT3.2FT4g_Unlimited_Mode_Pricing)
RHEL NASマウント 関連

#シンボリックリンク作成手順
```
## シンボリックリンク作成手順
# fstabの確認：nasのマウント設定がされているか確認
cat /etc/fstab

# ディレクトリ直下の確認：対象がシンボリックリンクされているか確認
ls -l /lv

# nasの空き容量を確認
df -khT

# シンボリックリンクの作成
ln -s /nas/xxx /lv/nas_xxx

# ディレクトリ直下の確認：対象がシンボリックリンクされたか確認
ls -l /lv

```


#NASマウント手順
```
## NASマウント手順
# fstabの更新：nasのマウント設定を記述
echo 'xxx.xxx.xxx.xxx:/lv_nas /nas/xxx nfs defaults 0 0' >> /etc/fstab

# fstabの内容表示
cat /etc/fstab

# hosts.allow で許可設定 ※例
echo 'xxx:xxx.xxx.xxx.xxx' >> /etc/hosts.allow
echo 'xxx:xxx.xxx.xxx.xxx' >> /etc/hosts.allow
echo 'xxx:xxx.xxx.xxx.xxx' >> /etc/hosts.allow
echo 'xxx:xxx.xxx.xxx.xxx' >> /etc/hosts.allow

# /etc/hosts.allowの確認
cat /etc/hosts.allow

# マウント先のディレクトリを作成
mkdir -p -m 777 /nas/xxx
# 対象ディレクトリが作成されたか確認
ls -l /nas

# マウントの実施
mount /nas/xxx
df -khT

# シンボリックリンクの作成
ln -s /nas/xxx /lv/nas_xxx
ls -ld /lv/nas*/

```
Why 43% of Indian organisations will adopt the Hybrid cloud by 2020?

Cloud Hosting has proved to be a stepping stone in the transition of the Information Technology market and digital India in 2018.  Cloud Hosting has progressively transformed India with the rapid growth of It industry and organisations allocating shares from their revenues for cloud innovations.  Though cloud hosting was highly accepted in India data security and cost has always been a significant concern with the use of public and private cloud respectively. It looks like Organisations have found that the Hybrid Cloud is the best solution to these raised concerns. The Indian enterprises have started adopting Hybrid Cloud to gain the combined benefits of both Public and Private Cloud.
![cloud model.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277629/fafc044c-a894-4e59-7fbf-62f56c01e2e1.jpeg)

A survey report of 2018 indicates that 43% of Indian organisations will adopt the Hybrid cloud by 2020 with 50% of Indian enterprises using Hybrid clouds, especially in telecommunications and Healthcare Industries. According to the study done by the experts, India is all set to lead the world regarding Hybrid Cloud usage over the next two years.

The increasing use of Hybrid clouds is likely to boost the Indian economy as its adoption benefits the organisations thus, becoming more flexible and straightforward with enhanced data security.  Since, the private clouds are not meeting the desired goals its use is expected to drop in the coming years thus, resulting in rapid adoption of Hybrid Cloud in India.

Read More>> https://www.esds.co.in/blog/hybrid-cloud-2020/
PowerAutomateを使用して、outlookからteamsに通知させる

2020年新卒です。温かい目でお願いいたします:hatching_chick::sparkles:
outlookで予定が更新されたら、teamsで通知する方法です。
朝10時までに入っているoutlookの予定を、teamsで通知させます！

#PowerAutomateで設定をする
自動フローを使用します。
![スクリーンショット 2020-11-26 19.22.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/877722/e58a8716-460b-252c-2f09-45668e0aa6ea.png)

##繰り返しの設定をする
まず最初のトリガーを選択します。
毎朝10時に通知をさせたいので、スケジュールの「繰り返し」というトリガーを使用します。
設定は以下のようにします。
![スクリーンショット 2020-11-26 19.47.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/877722/506a77e5-3874-b098-af9a-1df316a4daf1.png)
タイムゾーンは日本時間にし、通知の頻度と時間を設定します。

##カレンダーを取得する
Office365 Outlookの「イベントのカレンダービューを取得(V3)」というアクションを追加します。
設定は以下のようにします。
![スクリーンショット 2020-11-27 13.09.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/877722/3273dc37-eaf7-ab5b-d837-dc39be9bbb34.png)
カレンダーIDは、通知させたいカレンダーを選びます。
開始時刻と終了時刻には formatDateTime(utcNow(), 'yyyy-MM-dd 00:00:00') と書きます。
formatDateTime関数にutcNow()で現在の時間を指定し、取りたい日付と時間を指定します。
朝10時に通知しますが、１日の予定を取得したいので、00:00から23:59に設定しました。

##時間の設定をする
Date Timeの「タイムゾーンの変換」というアクションを追加します。
設定は以下のようにします。
![スクリーンショット 2020-11-27 17.25.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/877722/f96ff6be-f2ce-c51c-d5f5-97af70c550e7.png)
「タイムゾーンの変換」を追加すると、勝手にApply to eachが追加されますが、気にしなくて大丈夫です。
基準時間には、時間に変更したいものを選択します。
書式設定文字列は、カスタム値で入力をしてください。
終了時間には、「タイムゾーンの変換」をもう一つ追加して、同様に設定をします。

##Teamsに通知をさせる
MicrosoftTeamsの「メッセージをフローボットとしてチャンネルに投稿する」というアクションを追加します。
設定は以下のようにします。
![スクリーンショット 2020-11-27 18.28.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/877722/b9ff34f4-c06f-36e9-4311-538c2e4eaa90.png)
チームとチャネルには、通知させたい場所を指定します。
メッセージは、通知したいことを書きましょう。
文字に装飾を加えたり、改行などをする場合は、htmlで書く必要があります。

以上の設定で保存をします。

#フロー
フロー全体はこんな感じになります。
![スクリーンショット 2020-11-30 16.03.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/877722/17ecd50e-05a6-9411-6171-9a15edeeda05.png)

#通知がくる！
これで朝10:00になると通知がくるようになります:sparkles:
![スクリーンショット 2020-11-30 16.23.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/877722/9b85eeff-72b5-e45f-f0fe-f92d5001a364.png)
このようにFlowbotから、通知されます！
10:00に設定したはずですが、ラグがあるのか1分ほど遅れてしまっていますね笑
9:59に設定すれば良いのかもしれません。

#まとめ
PowerAutomateで自動でメールや通知を送ることができるので、とっても便利ですね！

ただ、この通知は時系列に並びません！！！！！
時系列に並べる方法があれば教えてください:pray_tone1:

全然関係ないですが、明日の12月19日は、誕生日なので祝ってくださると嬉しいです:sparkles:
teeでリアルタイムでログ出力をする


- 普通に呼ぶと、コマンド終了後にteeに渡させるので、リアルタイムでみることはできない
- scriptコマンドから呼ぶといいみたい


```bash
script -c "./apply.sh aaa /dev/null" | tee out.log
```
日付セルを月ごとにまとめていい感じの積み上げグラフを作りたい

この記事は移行しました！[最新の内容はこちら](https://naoqoo2.github.io/blog/%E6%97%A5%E4%BB%98%E3%82%BB%E3%83%AB%E3%82%92%E6%9C%88%E3%81%94%E3%81%A8%E3%81%AB%E3%81%BE%E3%81%A8%E3%82%81%E3%81%A6%E3%81%84%E3%81%84%E6%84%9F%E3%81%98%E3%81%AE%E7%A9%8D%E3%81%BF%E4%B8%8A%E3%81%92%E3%82%B0%E3%83%A9%E3%83%95%E3%82%92%E4%BD%9C%E3%82%8A%E3%81%9F%E3%81%84/)をご覧ください😀


これは[SOUSEI Technology アドベントカレンダー](https://qiita.com/advent-calendar/2020/st) 1日目の記事です。
念願の企業アドベントカレンダー🎉 はりきっていきましょう！

# はじめに

スプレッドシートでタスク管理してると、
半期に1回とか年1で集計してみたくなること、あるよねー！
そして良い感じにグラフ化したいよねー！
でもたまにしかやらない作業だから、どうやるんだっけ？？ってなったときのメモです。

# 結論！

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">日付セルを月ごとにまとめていい感じの積み上げグラフを作りたい。<br>→ピボットテーブル作って、日付セルを右クリックしてグループを作成するといい感じにできる！</p>&mdash; naoqoo2 (@naoqoo2) <a href="https://twitter.com/naoqoo2/status/1289087747609640960?ref_src=twsrc%5Etfw">July 31, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 手順

### 1. ピボットテーブルを作る

データ→ピボットテーブル を選択し、新しいシートにピボットテーブルを作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56789/e64fd468-7975-fe60-0531-0ea64648e862.png)

### 2. ピボットテーブルエディタで行、列、値をセットする

行：分類したい項目（タスクの種類とか）
列：日付セル （タスクの完了日）
値：確認したい値（タスクの消化数を見たいなら完了日のCOUNTAなど）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56789/3943e7a7-bd13-e4ee-b6e1-365ee2c2d358.png)

### 3. 日付セルをグループ化

日付セルを右クリック→ピボット日付グループを作成→年-月 を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56789/36244f98-409b-bc6b-8bd8-998cdba0a0fd.png)

### 4. グラフを作成

挿入→グラフ で積み上げ縦棒グラフを選べば完成です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56789/b8838476-7c26-8563-d872-88c721bde9c8.png)

# 余談

弊社は「マイホームアプリknot」を運営しているのですが、
昨日（11/30）はリニューアル版 knot の1歳の誕生日でした！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56789/f27d483b-f3d2-1612-8d6e-70903e30db3d.png)

この1年でknotは、
大小さまざまな新機能や改善を 326個 リリースし、
大小さまざまな不具合を 113個 解消しました！
おめでとうknot 🎉🎂
【2020年版】モダンなフロントエンド環境を構築する手順

# TL;DR
新規サービス・プロダクト開発を行う部署に所属しているため、業務で新たに環境構築を行うことが頻繁にあります。そのため、自分がいつも行う手順をまとめたいと思います。この記事では手順の列挙のみでやり方には言及しませんので、詳細はリンクをご確認ください。

# Gatsbyを利用される方はこれ1つ
これから説明する手順の1~3をコマンド1つで行うことができます。
Reactのフレームワークの1つである[Gatsby](https://www.gatsbyjs.com/)（Reactの公式ページもこのフレームワークが用いられています）には、starterというパッケージが存在します。そのパッケージを使ってコマンド1つで環境構築が可能です。

1~3の手順による環境を構築するstarterを作成しました
[gatsby-starter-typescript-sass](https://www.gatsbyjs.com/starters/pkino/gatsby-starter-typescript-sass)


# 手順
ReactやVueなどのライブラリや、Sassの使用をおすすめしますが、そうでなくても以下の手順は適用できるかと思います。

1. Gitリポジトリの作成
2. TypeScriptの導入
3. ESLint・Prettierの導入
4. VSCodeの各種設定を行い、設定ファイルを保存
5. CI/CDの設定

## 各ステップの必要性
### 2. TypeScriptの導入
型によって無用なエラーを防げたり、補完が便利に使えます。

### 3. ESLint・Prettierの導入
コード作成のルールやフォーマットを自動でしてくれます。人間がやらなくてもいいことはとことん減らしたいので導入します。Linterが走るタイミングは、実際のその変更を確認できるため`onSave`がおすすめです。（VSCodeの場合設定できます。）ただ確実にLinterが走ることを担保するため、huskyを使ってprecommitでLinterを走らせます。

[ESLint - Prettier連携のやり方と仕組み](https://qiita.com/ikngtty/items/4df2e13d2fa1c4c47528)
[Prettier 入門 ～ESLintとの違いを理解して併用する～](https://qiita.com/soarflat/items/06377f3b96964964a65d)
[ESLint と Prettier の共存設定とその根拠について](https://blog.ojisan.io/eslint-prettier)

### 4. VSCodeの各種設定を行い、設定ファイルを保存
前述したように、Linterなどを`onSave`などで走らせるために設定を行います。またその際にワークスペースに設定を保存すると、設定が書かれたファイルが保存されるので他の開発者と共有することができます。

[vscodeの利用に必須な”ワークスペース”の概念](https://prius.cc/itya/20181218_vscode-workspace)

### 5. CI/CDの設定
GitHubなどにcommitしたタイミングでビルド・デプロイできるような仕組みを導入しておくことで、開発するたびにそれらのことを行う手間が省けます。

[heroku 中級編 - 1分で実現するCI/CDをHeroku Pipelinesで](https://qiita.com/sho7650/items/a7d25f838b99bc5ba833)


## 注意点
- 上記は手順の概要なので、1つ1つの具体的なやり方については以下の記事が分かりやすそうでした。[Reactを使ったモダンなフロントエンド開発の環境構築](https://qiita.com/toshi-toma/items/8ee55304f09b5840b9a4)
- ライブラリなどを使わずビルドが必要な場合は、percelなどのツールを活用する必要があります
Steinの仕様メモ 条件にハマる行が複数あっても1行だけ対応。どうやらLookUpみたい


削除するメソッド

今日の

```javascript
await store
.delete(tranSheet, {
    search: { date: today, user_id: event.source.userId }
})
.then(res => {
    console.log(res);
});

```

削除前
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737206/97205d6e-9fcf-f7d2-d112-d0269474bf75.png)


削除後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737206/112c8ee7-fd33-0748-6efd-d8d2894ac427.png)

一番上が消えただけ！！笑

同じ日に同じIDの人が参加することはないから、
仕様上は大丈夫だけど、SQLのDELETE文とは違うということを意識しておこう。
思ってた挙動と違ったよ。
Lookupするイメージなのね。

いや、でも公式ドキュメントを見る感じ。Rowsと書いてある。何か変な動きをしているようだ。
⇒他の方にも確認していただいたが、やっぱり一番上の1行しか消えないみたい。
　条件を1つにしても同じ結果だった。
Unityでカメラの向き(ベクトル)を参考に移動するソースコード

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [SerializeField]
    Transform mainCamera;

    float scale = 0.1f;

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKey(KeyCode.W))
        {
            var direction = Quaternion.Euler(mainCamera.eulerAngles) * Vector3.forward;
            transform.position += new Vector3(direction.x, 0, direction.z) * scale;
        }
        if (Input.GetKey(KeyCode.S))
        {
            var direction = Quaternion.Euler(mainCamera.transform.eulerAngles) * Vector3.back;
            transform.localPosition += new Vector3(direction.x, 0, direction.z) * scale;
        }
        if (Input.GetKey(KeyCode.A))
        {
            var direction = Quaternion.Euler(mainCamera.transform.eulerAngles) * Vector3.left;
            transform.localPosition += new Vector3(direction.x, 0, direction.z) * scale;
        }
        if (Input.GetKey(KeyCode.D))
        {
            var direction = Quaternion.Euler(mainCamera.transform.eulerAngles) * Vector3.right;
            transform.localPosition += new Vector3(direction.x, 0, direction.z) * scale;
        }
    }
}
```
git cloneする際、pub keyを渡してアクセス許可してもらった後にする設定

過去やったのにまた忘れてたのでメモです。

#githubにpub keyを登録した後にすること

**事象：**
先方のリポジトリに、パブリックキーでアクセス許可していただいたけれど、接続できなかった。
接続してリポジトリをcloneしたい

#やったこと
~/.ssh/config というテキストファイルを作成し、以下の設定を行う。

```
$ cd ~/.ssh
$ touch config
```

作成された config ファルを編集。

```
host xxxxxxxxxxxx.xxx
 HostName xxxxxxxxxxxx.com
 IdentityFile ~/.ssh/xxxxx（登録したキーのファイル名）
 User git
```

無事つなげました🙌
Java　文字列の一部を切り出すためのメソッド！

#はじめに
学習用のメモになります。

#substringメソッドとは？
`substring`とは文字列の一部を切り出すために使えるメソッドになります。

#文字列の一部を切り取る（substring）
```
文字列.substring( int biginIndex)
```
biginIndex　→　開始インデックス（この位置にある文字は含まれる）

##サンプルコード

```Main.java
public class Main {
    public static void main(String[] args) {
        // Scanner sc = new Scanner(System.in);
        // String s = sc.next();
        
        String message ; //[1]
        message = "おはようございます。";//[2]
        String result = message.substring(4);
        
        System.out.println(result);
        
    }
}
```
出力結果

```
ございます
```
substringを使用して変数messageの4文字目から最後までを取得し、変数resultへ代入し、`println`で出力する


#substringで間を取得する方法
「○文字目から最後」という設定だけではなく、「○文字目から○文字目」という取得もできます。

```
文字列.substring( int biginIndex,int endIndex)
```
biginIndex　→　開始インデックス（この位置にある文字は含まれる）
endIndex　→　終了インデックス（この位置にある文字は含まれない）

##サンプルコード

```Main.java
public class Main {
    public static void main(String[] args) {
        String message ; 
        message = "おはようございます。";
        String result = message.substring(2,5);
        
        System.out.println(result);
        
    }
}
```
出力結果

```
ようご
```
DNS over TLS(unbound)

[IIJ Public DNSサービス（ベータ版）](https://public.dns.iij.jp)
IIJさんが、DoT,DoHを試験サービスとして提供してくれています。
2022年3月31日までの予定だそうです。
DoT,DoHの普及へ向けた、大事なテストですね。
Androidでも利用させていただいています。

今回はLaptopでWifiのみの接続での利用です。
ルーター経由でインターネットに接続しています。
Linux Mint 20 "Ulyana" - MATE (64-bit) をインストールしたところから始まります。
インストール直後の起動では、grubのメニューが立ち上がらず、

```
set root=(hd0,gpt6)
set prefix=(hd0,gpt6)/boot/grub
insmod normal
normal
```

これでgrubメニューが表示され、無事に立ち上がりました。
次回からも無事立ち上がるように、grubを再インストールします。
UEFIなので、下記のような感じになりました。

```
sudo grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=Mint --recheck
sudo update-grub
```

シャットダウンして、電源入れ直し。LaptopでLinux Mintが無事、立ち上がりました。

さて本題。
DNS over TLSをクライアントとして利用するために、unboundを用いました。

```
sudo apt install unbound
```
インストールされたunboundには2つの設定ファイルが用意されていました。

>
qname-minimisation.conf
root-auto-trust-anchor-file.conf
>

そこに設定ファイルを１つ追加します。

```dns-over-tls.conf
server:
        tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt

forward-zone:
        name: "."
        forward-tls-upstream: yes  #DoT

        #IIJ DoT 
        forward-addr: 2001:300::5@853#public.dns.iij.jp
        forward-addr: 2001:300::6@853#public.dns.iij.jp
        forward-addr: 103.2.57.5@853#public.dns.iij.jp
        forward-addr: 103.2.57.6@853#public.dns.iij.jp
```

tls-cert-bundleに、ca-certificatesパッケージのca-certificates.crtを指定します。(memo: dpkg -L ca-certificates)
@でdomain-sのポート853を指定しています。
\#public.dns.iij.jpでtlsで認証証明書のチェックをするドメイン名を指定しています。
※設定しているIPアドレスは、2020/12/01時点でのpublic.dns.iij.jpのアドレスです。

```
sudo cp dns-over-tls.conf /etc/unbound/unbound.d/
service unbound restart
```

設定ファイルを追加後、unboundを再起動。
これで名前解決にDNS over TLSを利用できる状態になりました。
ただWifi接続のみのため、DHCPで付与されたルーターのDNSがおそらくそのまま使われます。
そこでwifi接続の設定でDNSにローカルアドレスを追加します。

Mintのメニューだと
[コントロールセンター]
[インターネットとネットワーク]
[高度なネットワーク設定]
から設定できます。

ipv4設定、ipv6設定の「追加のDNS」にローカルリンクアドレスを追加します。

|ipv4|ipv6|
|:-:|:-:|
|127.0.0.1|::1|

これでwifi接続のみのlaptopから、IIJさんへDNS over TLSで名前解決リクエストを送って、tls handshakeを経て、名前解決がされている、と思います。
syslogにはtls handshakeのエラーもなく、無効なドメインの場合には、NXDOMAINが通知されています。

もし、おかしな点、間違っているところなどありましたら、ご指摘いただけると助かります。

参考サイト。
https://www.ctrl.blog/entry/unbound-tls-forwarding.html
https://nlnetlabs.nl/documentation/unbound/unbound.conf/


その２
[knot-resolver](https://www.knot-resolver.cz/)へ移行しました。
パッケージは公式サイトのものを使いました。
公式サイトの最新ドキュメントと参考サイトの情報を合わせて、必要な機能だけをオンにしました。
今の所、問題なく動作してくれています。

https://www.ctrl.blog/entry/knot-dns-resolver-tutorial.html
[PHP] エラー解決 npm 脆弱性の解決

前回のエラーを解決する際に脆弱性が2つあるよというエラーに初遭遇。
前回の記事のURLは[こちら]になります。
[こちら]:https://qiita.com/yutarou/items/5cca5b252d67c80a9bc0

```
(省略)
found 2 vulnerabilities (1 low, 1 high)
run `npm audit fix` to fix them, or `npm audit` for details
(省略)
```
上記のエラーを突破しましたのでその備忘録として投稿します。

#解説
まず何が脆弱性なのかを確認するためターミナルで`npm audit`を実行する

```
//ターミナルにて
npm audit  
```
すると下記のようなリストがターミナルで出現します。
![“スクリーンショット” 2020-12-01 13.45.10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698439/65cc84b1-b450-6f81-dcdf-de74ef62c7bb.jpeg)

今回は`SEMVER WARNING: Recommended action is a potentially breaking change`
というエラーが2つ出てきました。ここでターミナルで`npm audit fix `を実行しましょう。

```
//ターミナルにて
npm audit fix 
```

しかし、下記の画像のようにまだエラーを修復できませんでした。
![“スクリーンショット” 2020-12-01 13.56.07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698439/18f1704a-1414-670f-e7c8-c6fc786ee064.jpeg)
これでも突破できる方法が`npm audit fix --force`というものがあります。
--forceはオプションになり強制的に修復させるというやり方です。

```
//ターミナルにて
npm audit fix --force 
```
これを実行したら無事に下記の画像のように脆弱性がなくなりました。
![“スクリーンショット” 2020-12-01 14.03.05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698439/b4be1804-63b1-37f6-4714-f10edb86c68a.jpeg)
自己紹介

こんにちは、初めまして。mochicoと申します。

# 経歴
* 工業大学情報工学部を卒業し、SIerに就職
* ウェブ制作会社に転職
* 激務だったため妊娠を機に退職
* 3年ブランクを抱えながら2019年になんとか再就職

子供を産むまではJavaエンジニアでウェブアプリやAndroidアプリを作っていました。
今は、子育てしながら在宅でアプリへのFirebase Analyticsの導入サポートエンジニアをやっています。FirebaseもGoogle Analyticsも触ったことがなく手探り状態でここ1年ほど常にテンパっていましたが、やっと慣れてきたためアウトプットして知識を整理しようと思いQiitaを始めました。

## Qiitaに書きたいこと
* Firebaseの諸々
* Firebase Analytics / Google Analytics(GA4)の活用や注意点
* マーケティング用語
* ママエンジニアの苦悩

業務で学んだ知識を、自分の言葉でアウトプットして理解を深めることを第一の目的としていますが、同じようにエンジニア職の方がGAやFAの設定を求められたときに助けになれるような記事を目指していきたいです。
また、子育てで一度エンジニアとしてのキャリアを断たれた経験から、女性のキャリア形成について思うことなども綴れたらいいなと思っています。

## 目指すところ
稼げるエンジニアになること。
デジタルマーケティングのコンサルができるエンジニアを目指します。追々は企業に所属せず自分で稼いで行きたいなーと思っています。
どうぞよろしくお願いします！
Flutterで環境変数を利用する方法

# はじめに

APIキーなど、Gitで管理したくない場合や、環境によって値が変わる情報は、環境変数で管理するのがベターです。今回はその方法をご紹介します。

IDEはVSCode、CI/CDにGithubActionsの利用を想定しています。

# パターン

環境変数を取得する場合、取得する場所によって定義方法が変わります。
取得するパターンとしては以下の通り。

- Dartから利用する場合
- Android、iOSで利用する場合

# 前準備

- Github Actionsで利用する環境変数をリポジトリの「Settings」→「Secrets」で登録しておきます。

## Dartで利用する

### 設定編

#### ローカル環境（VSCode）で設定する

```json:.vscode/launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "flutter_mobile",
            "program": "lib/main.dart",
            "request": "launch",
            "type": "dart",
            "args": [
               "--dart-define=API_KEY=<値>"
            ]
        }
    ]
}
```

#### Github Actionsで設定する

「Secrets」で登録した変数は、 ```${{secrets.<変数名>}}``` で取得できます。

```yaml:.github/workflows/deploy.yml（抜粋）
steps:
  - name: build
    run: flutter build apk --dart-define=API_KEY=${{secrets.API_KEY}}
```

### 取得編

```dart:dart
String.fromEnvironment("API_KEY");
```

## Android、iOSで利用する

### 設定編

#### ローカル環境（VSCode）で設定する

```json:.vscode/launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "flutter_mobile",
            "program": "lib/main.dart",
            "request": "launch",
            "type": "dart",
            "env":{
                "API_KEY": "<値>"
            },
        }
    ]
}
```

#### Github Actionsで設定する

```yaml:.github/workflows/deploy.yml（抜粋）
steps:
  - name: build
    env:
      API_KEY: ${{secrets.API_KEY}}
    run: flutter build apk
```

### 取得編

#### Androidで取得する

```gradle:build.gradle
System.getenv('API_KEY')
```

AndroidManifest.xmlで取得したい場合、build.gradleにビルド変数を定義し、そこから取得する必要があります。

```gradle:build.gradle
android {
  ・・・
  defaultConfig {
    ・・・
    // manifestPlaceholdersを利用して、環境変数から取得した値を任意の変数で定義する
    // ビルド変数名と環境変数名は同じになっていますが、異なっていても問題ないです。
    manifestPlaceholders = [API_KEY: System.getenv('API_KEY')]
  }
```

次にAndroidManifest.xmlにbuild.gradleに定義したビルド変数を取得します。

```xml:AndroidManifest.xml
<application
        android:name="io.flutter.app.FlutterApplication"
        android:label="flutter_mobile"
        android:icon="@mipmap/ic_launcher">

        <meta-data
        android:name="API_KEY"
        android:value="${API_KEY}"/> <!-- ${ビルド変数名}でビルド変数の値を取得できる -->
```

#### iOSで取得する

```swift:swift
ProcessInfo.processInfo.environment["API_KEY"]
```
フォルダの中のサブフォルダ、ファイルを丸ごと消去

超個人的なメモです。
この時代にvbsを使ってファイル操作を行うことが多くなってきたのでメモ。

```vb:DeletefolderAndFiles.vbs
DeletefolderAndFiles("C:\xxx\yyy\gomi") ' 削除したいフォルダのパスを指定する。

'指定したフォルダの中身をすべて削除する。
Sub DeletefolderAndFiles(DirectoryPath)
    Dim objFile
    Set objFile = CreateObject( "Scripting.FileSystemObject" )

    Dim objFolder
    Set objFolder = objFile.GetFolder(DirectoryPath)

    Dim objSubFolder
    
    ' サブフォルダを取得して再起呼び出し。
    For each objSubFolder in objFolder.SubFolders
        DeletefolderAndFiles(DirectoryPath & "\" & objSubFolder.Name)
        objFile.DeleteFolder DirectoryPath & "\" & objSubFolder.Name, True
    Next

    Dim fileName
    ' フォルダ内のファイルを取得し、削除する。
    For each fileName in objFolder.files
        objFile.DeleteFile DirectoryPath & "\" & fileName.Name, True
    Next
    
End Sub
```
超簡単にbotを作りたい！！

## Bot開発を簡単にしたい

社内で使っているチャットサービス(SlackやTeamsなど)で何かしらのBotを開発する方へ向けて

Botを開発する際にお勧めのツールがあります!!

### <strong>Node-RED</strong>

#### Node-REDとは？
https://nodered.org/

簡単に説明すると、ローコードのフレームワークです。
線と線を繋いでプログラミングをしていけます。

よく使われている分野として、IoT などをよく聞きますが、
自分はBot開発にも向いていると思っています。


### おうむ返しBotを爆速で作る。

長々と説明するより作った方がわかりやすいと思います。( 百聞は一見になんたらですね )
今回は例として、Slack向けにおうむ返しBotを作成します！！

まず、Slack上にアプリを作成します。

Slashコマンドにおうむ返しコマンドを作成します。
![スクリーンショット 2020-12-01 13.34.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430353/b5dff645-bd68-4063-639c-87decbfe8df4.png)

ngrok 等を使うとlocalで開発をして実際に試すことが可能です。

![スクリーンショット 2020-12-01 13.36.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430353/1cb2fd4d-614b-572c-d12e-7b6eaafe76a3.png)

Node-REDでコードを書きます。( 後述で簡単さがわかります！！ )

実際に動作を見ます。
/repeat testと入力すると以下のように帰ってきます。

![スクリーンショット 2020-12-01 13.39.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430353/dc937eb6-fc62-5476-7602-5b394262caa5.png)

## どの程度簡単か。。

まず、Node-RED上でのコードを見てみましょう。

![スクリーンショット 2020-12-01 13.41.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430353/0e50c084-0315-eea1-709d-25efa6f2a5c6.png)

はい。Node-RED上には、3つのフローしかありません。。これが全てです。
`[post]/repeat`は、slackからのrequestを受ける部分。
`slackへ返却`は、おうむ返しするためのコーディング部分。
`http`は、前工程で設定した内容をslackへ返しています。

>`slackへ返却`は、おうむ返しするためのコーディング部分。

ここでは本当に簡単なコーディングをしています。

ここの中身は以下です。
![スクリーンショット 2020-12-01 13.44.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430353/3403325b-84b3-9143-9786-87287e9fd6e8.png)

はい。これだけです。。
変数に一旦データを置くなどしなければ実際3行でかけてしまいます。。

簡単ですよねww

## 最後に

実際にBotを開発する際には`slackへ返却`の部分でもっとゴニョゴニョすれば目的のBotが作成可能です。
今回は、簡単さを見せるために省略してますが、
Slackには、requestを受けてから3秒以内に返却できない場合Messaging APIで返す必要があったり、request時にsignatureの検証などが必要です。
また、当然Slack以外のTeamsやその他APIがあるチャットツールだと同様にbot作成できます。

Node-REDを使用することでとても簡単にBotを開発出来ることが雰囲気だけでも伝われば幸いですw
第5回

\![Mac OS X-10.15.7](<https://img.shields.io/badge/MacOSX-10.15.7-brightgreen>) \![ruby-2.7.1p83](<https://img.shields.io/badge/ruby-2.7.1p83-brightgreen>) 


# 出力

print..普通の出力，要改行

puts..普通の出力，自動改行

p..デバッグ出力

pp..デバッグ出力

printf..cと同じ



------
 - **source** ~/grad_members_20f/members/Kenny0704/c5.org
チャットで行うふりかえりの例

# この記事について

この記事は、[aslead Agile](https://aslead.nri.co.jp/solution/aslead_agile.html)の開発チーム「[オキザリス](https://speakerdeck.com/viva_tweet_x/huesudeyong-qi-wode-taxin-gui-timugashi-yan-wozao-rifan-sitejin-nizhi-rumadefalsewu-yu)」にて行っているアウトプット企画である
「[チーム「オキザリス」Advent Calendar](https://qiita.com/advent-calendar/2020/oxalis)」の1日目の記事です。

# チーム「オキザリス」でのふりかえり

この記事では、チーム「オキザリス」で行っているふりかえりを紹介します。

## 30分スプリントでのふりかえり

チーム「[オキザリス](https://speakerdeck.com/viva_tweet_x/huesudeyong-qi-wode-taxin-gui-timugashi-yan-wozao-rifan-sitejin-nizhi-rumadefalsewu-yu)」では、現在「[30分フラクタルスプリント](https://qiita.com/viva_tweet_x/items/3b796be727ad3bd3dfc0)」を取り入れて日々の開発を進めています。

このチームでは、ふりかえりは30分に1分のペースで行っています。

過去には1時間スプリントを行っていたころには[Blokus](https://qiita.com/viva_tweet_x/items/4249d32931007dde1851)などを使ったふりかえりを行っていましたが、1分という時間の都合上、ふりかえりはより簡単に書ける形へと進化していきました。

Mattermostのチャット[^1]に、以下のようにそのスプリントでの活動や感想など、なんでもいいので書き込んでいく形式になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221788/bf77eeb4-d2c6-e361-24a8-dcd3230eb258.png)

[^1]: SlackライクなOSSのチャットソリューション。asleadにてサービス提供している。

ふりかえりの中でコミュニケーションも発生しますし、スプリントに参加していない人も、ふりかえりを見ればなんとなく何が行われていたのか分かるようになります。

オキザリスチームでは、アジャイルチーム（5名）とマーケティングチーム（2名）の複合チームとなっており、普段の活動はバラバラです。マーケティングチームでも、30分スプリントになってからはチャットでふりかえりを発信する形になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221788/843b496e-c53e-9793-a862-246f47ceb086.png)

マーケティングチームでは、2人のメンバーが不定期に活動する形となっているため、ふりかえりの最初に活動時刻を書くようにしています。ただ、チームが別々に活動していても、定期的にふりかえりの発信があるため、状況もすぐ分かるようになっています。

## 1週間スプリントでのふりかえり

1週間に一度、30分の時間を使って、1週間のふりかえりも実施しています。
このふりかえりは、全員で雑談をベースとした、Confluenceに共同編集しながら書き込んでいくふりかえりです。
チームメンバー全員が[ふりかえりチートシート](https://qiita.com/viva_tweet_x/items/b06f56ce83038fc2bb8f)を手元に持っているため、どの手法をやりたいか最初に決めてから行います。

形式は[Blokus](https://qiita.com/viva_tweet_x/items/4249d32931007dde1851)の表形式を使うこともあれば、箇条書きで書いていったりすることもあったりとバラバラです。
次のスプリントで行う実験内容や、アクションなどを決めていきます。

Blokusで行った例。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221788/a38d8cf6-28bf-bcbb-7218-131bd7e36b67.png)

箇条書きで行った例。なお、このふりかえりがきっかけで[30分フラクタルスプリント](https://qiita.com/viva_tweet_x/items/3b796be727ad3bd3dfc0)が始まりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221788/7f3b04b1-eb55-5184-7fd8-152b7a0d0103.png)

# ふりかえりの形は様々

ふりかえりの形は、その時によって異なります。
チームの現状に合った形で、そして好きな形を作り上げていけることがふりかえりを効果的で、かつ楽しくするコツです。
是非、色んなふりかえりを探してみてくださいね。