OmniAICreator/Qiita-1.07M huggingface dataset:
「アジャイルサムライ」をアジャイル開発ではないエンジニアが読んだ感想

# 書籍

https://www.amazon.co.jp/%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E3%82%B5%E3%83%A0%E3%83%A9%E3%82%A4%E2%88%92%E9%81%94%E4%BA%BA%E9%96%8B%E7%99%BA%E8%80%85%E3%81%B8%E3%81%AE%E9%81%93%E2%88%92-Jonathan-Rasmusson/dp/4274068560


# 全体を通した感想

* ソフトウェア開発において、目をそらしがちな事実を真っ向から受け止めている

* その上で「どう改善していくか」の考え方について書かれているため、
アジャイル開発ではない環境で働いている自分でも、「どう改善していくか」の考え方を取り入れることができそう

* 挿絵や実例が多く、また軽快なテンションの文調なので、重たい内容のはずなのに、するすると読めてしまう

* ソフトウェア開発が、もっとわくわく、楽しい仕事にできるのではないか、と思わせてくれた


# 本文中で気になったトピック

### ソフトウェア開発の３つの真実

>P13
> 1. プロジェクト開発時点に
すべての要求を集めることはできない
>
> 2. 集めたところで、要求はそれも
必ずといっていいほど変わる
>
> 3. やるべきことはいつだって、
与えられた時間と資金よりも多い

これまで内心そうではないか、とぼんやり疑っていたことを、本書では序盤に認めてしまっている。
このことを事実と受け入れることで、変化に対応できる仕組みや、これまで向き合っていなかった課題へと取り組んでいけるようになる。

### 荒ぶる四天王

> P86
> 太古の昔より、あらゆるプロジェクトは4つの固く結びついたフォースによって統治されておる。
> それが荒ぶる四天王、すなわち時間、予算、品質そしてスコープだ。

> 時間、予算、品質。アジャイルサムライはこの三者のいずれも固定する。
> するとたった1つだけ、動かすことのできるフォースが残る。
> それがスコープだ。

プロジェクトとして成果をあげるというゴールを達成するために、スコープのみを柔軟に扱う。

### スコープを柔軟に

> P152
> スコープを柔軟にしておくこと。
これこそがアジャイルプロジェクトで 計画を誠実なものに保ち続けるための秘訣だ。

3つの真実であったように、要求は必ず変わる。
だから最初から要求が変わることを歓迎して、変更するためのルールを決めておく。
スコープに新しいストーリーを追加するときは、必ず既存のストーリーを削ってもらうこと。

やれることには限度がある。
気まずくても、顧客にその事実を共有することで、プロジェクトを健全に進めることができる。

### 概算見積りなんて当てずっぽうだ

> P126
> 見積りをどうしても間違えてしまうことが問題なんじゃない(まあ実際、間違えてしまうわけだし)。
問題は、見積りから本来そこにありもしないものを読み取ってしまうこと
―――つまり、見積りを未来の正確な予測だと思い込んでしまうことにあるんだ。

私も見積りを行った当初は、「大体で見積もったもの」と覚えている気がするが、
時間が経つにつれて、その感覚が薄れ、見積りが正確な予測だと思いがち。

実際の開発速度を計測して、前倒しで進んでいるのか、見積りよりも遅れそうなのかを判断して、
どれくらいで完了しそうかを予測していくべき。

### 何も価値を生み出せなかったイテレーション

> P218
> プロジェクトの状況が芳しくないからといって、そこから目を背けてはならない。
その状況自体が素晴らしい教師となることがある。
失敗を受け入れ、その教訓をチームメンバーと分かちあい、前へ進んでいくのだ。

顧客を前にして何も成果を披露できない惨めな経験によって、チームは同じことを2度と繰り返そうとはしないはず。
その失敗を当たり前のものとして受け入れず、どうにか改善しようとすることで成長できる。

### アジャイルであるかなんて気にしない

> P287
> いいかい、アジャイル開発とは旅そのものであって、目的地じゃないんだ。この旅に終わりはない。
肝に銘じてほしい。アジャイルで「あること」なんてどうでもいいんだ。
大切なのは素晴らしいプロダクトを作ることと、それを君のお客さんにちゃんと届けることなんだ。

成果を顧客に届けること、そして目をそらさずに改善のために努力をおしまないこと。

これらを続けるのは大変だと思うが、そんな風にきちんと顧客へ成果を届けることができたら、開発に対してストレスなく、やりがいのある仕事ができると思う。
LINE WORKSからのcallbackメッセージを判定するExpressミドルウェア

# 背景
LINE WORKSのbotサーバを開発する際，受信したユーザからの応答（callback）が正しくLINE WORKS側から送信されたものなのか（改竄されていないか）を判定する必要があります。[LINE WORKSの公式ページ](https://developers.worksmobile.com/jp/reference/bot-callback?lang=ja)にはJavaのサンプルコードはあるのですが，JavaScriptのものは無かったため自分で実装しました。さらにこれをExpressのミドルウェアとして利用できるようにしましたので共有します。

# 環境
* Node v16.13.0
* npm 8.1.4
* Express 4.15.2

# 公式ページから
上述の公式ページには以下のような記述があります。

> Bot サーバーが受信した HTTP POST リクエストは、LINE WORKS プラットフォームから送信されていない危険なリクエストの可能性があります。 必ず署名を検証してから、イベントオブジェクトを処理してください。

> メッセージサーバーから送信されたメッセージの改ざん有無を確認するには、ヘッダーに含まれる X-WORKS-Signature を用います。 確認プロセスは以下を参照してください。
>
> 1. 「Developers Console > Bot」Botの詳細情報画面でBot Secretを取得します。
> 
> 2. Bot Secretを秘密鍵として利用し、メッセージサーバーから送られた body の内容を HMAC-SHA256 アルゴリズムでエンコードします。
> 
> 3. 上記の HMAC-SHA256 アルゴリズムでエンコードした結果を BASE64 エンコードします。
> 
> 4. X-WORKS-Signature のヘッダー値と比較し、同一であればメッセージは改ざんされていないと判断できます。

では，Node.jsのデフォルトモジュールである`crypto`モジュールを利用してコードを実装していきます。

# コード
まずbotのidとsecretをまとめたJSONを用意しておきます。
```javascript
const botSecrets = {
  12345678: 'abcdefghijklmn',
  23456789: 'opqrstuvwxyz'
}
```
実際にはこのようにハードコーティングするのでなく，`.env`ファイル等で管理した方が良いでしょう。

実際のミドルウェアのコードがこちらです。
```javascript
const crypto = require('crypto')

const worksHeaderCheck = function (req, res, next) {
  const body = JSON.stringify(req.body)
  const botId = req.header('X-WORKS-BotId')
  const signature = req.header('X-WORKS-Signature')
  if (!botId || !signature) return next(new CustomError('Header malformed.', 400))
  const secret = botSecrets[botId]
  if (secret === undefined) return next(new CustomError('Bot secret is undefined', 500))
  const hash = crypto.createHmac('sha256', secret).update(body).digest('base64')
  if (signature !== hash) return next(new CustomError('Signature is altered.', 401))
  next()
}
```
まずヘッダの`X-WORKS-BotId`および`X-WORKS-Signature`に含まれるbotのidと署名を取り出します。どちらかが欠損していればヘッダ情報不良として`400`エラーを返します。

次にbotのsecretが登録されているか判定し，登録がなければ`500`エラーを返します。

最後に送信されたbodyと登録されていたbot secretからハッシュを計算し，送信されたsignatureと比較します。ハッシュ計算の際には最初からbase64形式で求めることに注意しましょう。合致しなければ改竄されていることになりますので，`401`エラーを返します。

なお`CustomError`はエラーハンドリングをシンプルにするためのカスタムエラークラスです。[azujuuuuuun様のエントリ](https://qiita.com/azujuuuuuun/items/f0be4a71aca2d92036aa)を参考にさせて頂きました。

```javascript
// エラーハンドリング用カスタムクラス
class CustomError extends Error {
  constructor(message, statusCode) {
    super(message)
    this.statusCode = statusCode
  }
}

// エラーハンドリング用ミドルウェア
const errorHandler = function (err, req, res, next) {
  console.error(err.message)
  res.status(err.statusCode || 500).send(err.message)
}
```

# 使用法
```javascript
express()
  .use(express.urlencoded({ extended: true }))
  .use(express.json())
  .get('/hoge', worksHeaderCheck, (req, res) => {
    // 処理
  })
  .use(errorHandler)
  .listen(PORT, () => console.log(`Server started and listening on ${ PORT }`))
```
Laravelのバリデーションルールで、新規登録と更新で処理を分けたい

# やりたいこと
Laravelの保存（store）、更新時（update）のメソッドで、バリデーションルールを追加すると思いますが、uniqueなどを使うときに、新規登録時と更新時で振り分けたい場合があります。
その場合に、必須チェックなど共有したいルールもあり、別のバリデーションを用意するのはちょっとなぁ...というときに使えます。

# 現在のルーティングによって分岐する方法
```php
public function rules() {
    $route = $this->route()->getName();

    \Log::info($route);
}
```

`user.store`などが返ってきます。

# フォームの入力値を取得する
ついでに、rulesの中でフォームの入力値を見たいとき

```php
public function rules() {
    $userId = $this->user_id;
}
```

`$this`で取れます！
【JAVA→Python】JAVAで書いた特定の文字をカウントするコードをPythonに書き換えてもらう【新人教育】

# JAVA研修を終えた新卒の子にPythonを教える
入社後研修が終わった新卒の子にとりあえず会社としてはわんぱくにもDjangoの本を渡して学習してもらおうという感じだったので（私の入社時もそうだった）Python自体を学んでもらってDjangoに取り組んでもらおうと思い独断で新人教育の機会をいただきました。
私自身が学習で文章題を解いた時にJAVAでコードを作成したので、せっかくなら新卒の子にPythonに変換してみてもらおうと思いコードを渡してみました。

# 目次
1.[実際に渡したコード（JAVA)](#1-実際に渡したコード（JAVA)
2.[そう、それはDjango](#2-そう、それはDjango)
3.[あれこれ話しがあとに返ってきた解答](#3-あれこれ話しがあとに返ってきた解答)
4.[おわりに](#4-おわりに)

# 1.実際に渡したコード（JAVA)
```java:JAVA
import java.util.*;


public class Main {
    public static void main(String[] args) {

        String exampleString = "AZURE PLUS";

        int totalCharacters = 0;
        char temp;
        for (int s = 0; s < exampleString.length(); s++) {

            temp = exampleString.charAt(s);
            if (temp == 'U')
                totalCharacters++;
        }

        System.out.println(totalCharacters);
    }
}
```
## コード自体は文字列から特定の文字をカウントし、２が出力されるようになってます。
:::note info
コードを書き換える時の条件
・最低限の記述法については連携済み
・WEBなどで調べて書いてもいい
:::
この条件でやってもらうことにしました。

# ２．そう、それはDjango
早速返ってきた解答
## まずは皆さんに見てもらいましょう。
```python:python
String exampleString = "AZUREPLUS"

int totalCharacters = 0

char temp

{% for num in range(len(exampleString)) %}
    temp = exampleString[num]
    if temp == 'U': 
        totalCharacters += 1
{% endfor %}
print(totalCharacters)
```
こ、、、これは、、、！
いきなりDjangoで解答が返ってきました。
（これちゃんと見るためにはプロジェクト作らないとダメなやつやん。。。）
## 無視してそのまま実行すると、もちろんこうなります。
```zsh:ターミナル
  File "<ipython-input-4-a1c9e3d2ce5e>", line 1
    String exampleString = "AZUREPLUS"
                       ^
SyntaxError: invalid syntax
```
Djangoとして実行できるかは後ほど調査しますが、「DjangoではなくてPythonの書き方があるんだよ」という話と、Django以外でのPythonとしての実行の仕方について連携しました。
そう、彼は悪くない。いきなりDjangoの本を渡されたらそうなる。



# 3.あれこれ話したあとに返ってきた解答

```python:python
exampleString = "AZUREPLUS"

totalCharacters = 0

temp = ""

for num in range(len(exampleString)):
 temp = exampleString[num]
 if temp == 'U': 
        totalCharacters += 1
print(totalCharacters)
```
お！よかった！
これよこれ！

かくいう私はまだ書き換えてなかったんですが（ごめんね）、実行したらこうなりました。

```zsh:ターミナル
2
```
無事にインデントや変数の書き方などを確認できてよかったです。
伝わらなかったらどうしようかと思ってました。

# 4.おわりに
今回は初めての試みでJAVAでからPythonに書き換えてもらいましたが、いきなりフレームワークを触るというよりJAVAでを学習してたならPythonに書き換えるとどうなるかを学んでもらい、今までの学習を活かしつつ他の言語の理解を深めてもらえたらと思いました。

私もJAVAからPythonに書き換えるのはやってこなかったので一緒に学べたらと思います。
今後もこの活動を続けてみようと思います。
（まずは今回の問題のフィードバックをもらってからになりますが）
Rustでのデバッグ環境構築（Windows+VisualStudioCode+rust-analyzer）

# 概要

* Windows環境+Visual Studio CodeでHello,Worldでデバッグをやる際に必要な設定等を記述しています。
* 「Rust for Visual Studio Code」が非推奨となり「rust-analyzer」を使うようお勧めされるようになりました。

# 前提条件

* ある程度Visual Studio Codeの扱いになれていること。

# 環境

* Windows 10 Pro 21H2
* rustc 1.62.0 (a8314ef7d 2022-06-27)
* cargo 1.62.0 (a748cf5a3 2022-06-08)
* Visual Studio Code 1.68.1

# 環境構築

## Rustインストール

* [Rustをインストール](https://www.rust-lang.org/ja/tools/install)から「RUSTUP-INIT.EXE(64-BIT)」をダウンロード。
* `rustup-init.exe`を実行。

## Visual Studio Build Tools 2019インストール

* 「C++によるデスクトップ開発」をチェック→右下の「インストール」をクリック。
    * 「Visual Studio」の「C++によるデスクトップ開発」でも代替可能です。

## Visual Studio Codeインストール

* [Visual Studio Code](https://azure.microsoft.com/ja-jp/products/visual-studio-code/)からダウンロードページへ遷移。
* 「Windows 8, 10, 11」をダウンロード。
* `VSCodeUserSetup-x64-1.68.1.exe`を実行。(バージョン違ってても大丈夫だと思います。)
    * 初回起動時に言語パックをインストールするよう促されますのでそのままインストールしてください。

### rust-analyzerインストール

* 拡張機能：「rust-analyzer」をインストールする
    * コードアシスト、フォーマット等に使用します。

### CodeLLDBインストール

* 拡張機能：「CodeLLDB」をインストールする
    * デバッグ時に使用します。

# 基本的な操作

## プロジェクト作成

* PowerShellを開き以下を入力し実行する。

```
cargo new cargo_hello
```

## プロジェクトを開く

* 先程作成したプロジェクトフォルダを「Visual Studio Code」で開いてください。
![mainrs - hello_cargo - Visual Studio Code_2022-7-4_12-51-12_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113377/638ef4c2-31c6-d997-70a9-0fb931f24430.png)

## 実行時の構成設定

* メニュ→実行→構成の追加→「Cargo.toml has been detected in ...」→Yes

# 実行/デバッグ方法

## 実行例

* 「デバッグなしで実行」を行う。


## デバッグ例

* 「println」行のブレイクポイントを有効にする。
![mainrs - hello_cargo - Visual Studio Code_2022-7-4_12-58-40_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113377/9a9378c5-d388-4379-3369-73b49cfae708.png)
* 「デバッグの開始」でブレイクポイントで止まるようになる。
![mainrs - hello_cargo - Visual Studio Code_2022-7-4_13-0-57_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113377/3f16e873-a787-353d-e3e3-5f1785000973.png)

# 参考文献

* [The Rust Programming Language 日本語版](https://doc.rust-jp.rs/book-ja/)
* [Rust in Visual Studio Code](https://code.visualstudio.com/docs/languages/rust)

# つまずいたところ

* 「Visual Studio Build Tools」いれずにコンパイルエラーが出た。
* 「cargo」パッケージ管理を使わずにコンパイルしたソースをデバッグしようとしてはまった。
新卒はアソシエイトを取りたい


## 自分のスペック
とある会社に新卒で入社し、データ基盤エンジニアの開発や運用などやってます。（今は2年目)
受験時は、実務経験は数ヶ月程度でサーバレス系のサービスとデータ系を知ってる感じでした。
テストはec2などが多いので結局、一部は初心者とさほど変わりません。

## 何でAWS認定ソリューションアーキテクト　アソシエイトを取ろうと思ったか？

業務でawsを使うことが多いのと、新卒で取れたらかっこいいなと思ったので挑戦しました。
他にも知らないサービスを知ってた方が何かと便利で良いかなぐらいで勉強しました。

## 勉強期間
基本は以下の感じで、業務後や休日カフェで勉強したりしてました。
期間：3週間
平日：1-2時間
土日：5-7時間
トータル：45時間

## 利用教材
AWS認定資格試験テキスト AWS認定ソリューションアーキテクト - アソシエイト 改訂第2版
→人によってawsの各サービス知識が0の方にはおすすめ、ある程度知ってる人はblackbeltやclassmethodさんの記事で十分かも
https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-AWS%E8%AA%8D%E5%AE%9A%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88-%E6%94%B9%E8%A8%82%E7%AC%AC2%E7%89%88-NRI%E3%83%8D%E3%83%83%E3%83%88%E3%82%B3%E3%83%A0%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE/dp/4815607389/ref=sr_1_5?crid=M2OW5SJ2A53A&keywords=aws+%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88+%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88&qid=1656898563&sprefix=aws+%2Caps%2C282&sr=8-5

udemy
→だいぶ、助かったし試験に慣れるのによかった、9割取れるまでやりこんだ
https://www.udemy.com/course/aws-knan/

ネットの問題集
→数問といたがもっと早くやっておけばよかった、情報が古いのもあるが基本コメント欄でユーザーが会話してるのでそれも勉強になった
https://aws-exam.net/saa/saa_question.php


## 勉強法
勉強は以下の手順で行っていきました。
⓪まずは、どんな試験か他の方の合格体験記をひたすら読む
①本を2周ぐらい読む(情報が古いのもあった)
②わからないのはclassmethodさんの記事でサービス毎の特徴を再度確認する
③それでも理解が足りてない場合はBLACK BELT読む
④udemyで6回分のテストをひたすら解く(合計5回は繰り返しやりました)
⑤webの問題を解く
あとは、間違ったところはなぜ間違ったのか理由を理解し、復習ノートも作ってました。
基本は夜寝る前にそのノートを見返して覚えるようにもしてました。

## 本番
いきなりスタート、、
難しい
日本語が読めない
トイレ行きたい
って思ってました。
受けるときのコツは基本、日本語が自動翻訳だと思うので読みづらい部分があったので英語に切り替えるのもありだと思います。
また、迷ったらとりあえず後に見返す用のフラグを付けられるのでやっておくとよかったと思います。


## 結果
<h4>合格！</h4>
ただ、二つ目の目標として9割目指したんですが、800点ちょいで思ったより取れませんでした。。
<br>また、試験終了後はアンケートに答えて結果が出るんですが、結構あっさり合格って出てきて本当かメールが来るまで疑ってました。

## まとめ
合格はできましたがもう少し対策できるところもあったかなと思います。
特にwebとudemyの問題集は全部解くとかなり力がつくと思います。
業務上、使えるかと言われたら今使ってる技術のおさらいぐらいと知らないサービスの触りを知れたかなと思います。
あとは、awsでの開発におけるポイントも勉強になり、コストやセキュリティ、耐久性などは意識できるようになっと感じます。
次は、データ系のspecialityを取ります！
WordPress REST API、カスタムフィールドの値で絞り込む

# はじめに
WordPress REST APIでカスタムフィールドの値で検索（絞り込み）することがあったので、そのときのメモです。

こちらの記事も参考にしました。
[WordPress REST APIで記事検索に使うオプションを全て調べた](https://dev.ore-shika.com/post/wp-rest-search/)

# コード
```php
<?php
add_action( 'rest_api_init', 'add_meta_field_at_product' );
function add_meta_field_at_product()
{
    register_rest_field( 'product',
        'meta_data', 
        [
            'get_callback'  => 'get_callback_for_add_meta_field',
            'update_callback' => null,
            'schema'          => null,
        ]
    );
}

function get_callback_for_add_meta_field($object, $field_name, $request)
{
    _log($request);

    $meta = [];
    $title = $object['title']['rendered'];

    $products = get_fields($object['id']);
    foreach($products as $details) {
        foreach($details as $d) {
            $d['title'] = $title;
            $meta[] = $d;
        }
    }

    return $meta;
}
```

`_log`の関数については、[こちら](https://qiita.com/shima0218/items/fe67e80d257648ce2673#%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E3%83%AD%E3%82%B0%E5%87%BA%E5%8A%9B)参照してください。

callback関数の$requestの中身に検索条件が入ってきます。（後日、サンプル出したいと思います）

条件に合うものだけ、returnすると、絞り込んだものだけが取得できます。

そのうち、ちゃんと解説書きたいと思います！
kerasの学習済みモデルをpbファイルで出力する

# パッケージ
tensorflow 2.6.0  
keras 2.6.0  

# コード
```python:convert.py
import tensorflow as tf
from tensorflow.python.framework.convert_to_constants import convert_variables_to_constants_v2

model = tf.keras.applications.vgg16.VGG16(weights='imagenet')
model.save("tf_vgg16", save_format='tf')

new_model = tf.keras.models.load_model('tf_vgg16')

full_model = tf.function(lambda inputs: new_model(inputs, training=False))
# カスタムレイヤーがある場合は、例えば以下のように書く
# new_model = tf.keras.models.load_model(model_path,  custom_objects={"DogsAndCatsModel": DogsAndCatsModel})

# inputsのshape/dtypeをセットする
frozen_inputs = []
for in_ in new_model.inputs:
    frozen_inputs.append(tf.TensorSpec(in_.shape, in_.dtype))

full_model = full_model.get_concrete_function(*frozen_inputs)
frozen_func = convert_variables_to_constants_v2(full_model)

tf.io.write_graph(graph_or_graph_def=frozen_func.graph, logdir='log', name='tf_vgg16.pb', as_text=False)
```

※convert.pyと同じディレクトリに空のlog ディレクトリを用意しておく
【GAS】スプレッドシートのセル番地を定数として指定するときの方法まとめメモ

## まえがき
GASを書くときに、SpreadSheetでシート「config」とかを作って、GAS内で使いたい文言やファイルIDなどをGAS外に溜める事が多いが、
その際に、GAS内でセル番地を指定して読み込ませる方法が一定してなくて面倒だったので、自分用にメモっておく

## 参考URL

## 基本ルールと例

### シートの例

※送付状を差し込み印刷で作りたい、とかの場合に、例えばこんなシートを作成して、(内容はフィクションです
| シート「config」 | A | B | C | D | E | F |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| 1 | 年度 | 対象月 | 書類名 | 書類説明 | 送付状文言 | デフォルト送付部数 |
| 2 | 2021 | 1 | 見積書 | サービス申込時の見積書や、請求書発行時に申請される見積書 | 御見積書をお送りいたしますので、ご査収ください。 |  |
| 3 | 2022 | 4 | 申込書 | サービス申込書 | 御申込書をお送りいたしますので、必要事項を御記入の上ご返送ください。 | 1 |
| 4 | 2023 | 7 | 契約書 | 相手が法人の場合、契約書になる | 御契約書をお送りいたしますので、必要事項を御記入の上、押印した1部をご返送ください。 | 2 |
| 5 | 2024 | 10 | 変更契約書 | サービス内容変更時とか | 変更契約書をお送りいたしますので、必要事項を御記入の上、押印した1部をご返送ください。 | 2 |
| 6 | 2025 |   | 請求書 | 定期の請求および、臨時で請求書を出す場合 | 御請求書をお送りいたしますので、期日までに記載の口座までお支払いください。 |   |
| 7 |  |  | その他 | 上記に当てはまらない書類 | 下記の書類をお送りいたしますので、ご査収ください。 |  |

### コードの例
オブジェクトでセル番地を設定する。
```javascript:config.gs
const RangeValue ={
  config:{
    fiscalYear:{row:2, column:1, height:5},
    invoiceMonth:{row:2, column:2, height:4},
    documentType:{row:2, column:3, height:6, width:3,innerColumn:{documentType:1, coverLetterText:2, defaultSendingNum:3}}
  }  
}
```

### コードの説明(ルール)

RangeValue…セル番地を登録するオブジェクト。グローバルに置いて、セル番地は全部この中に収めておく。
シートごとに更にオブジェクト化する

セル番地の記載方法
``<セル名>:{row:r, column:c, height:h, width:w}``
rowとcolumn…シート内でのセル番地を入力(配列みたいに-1しないほうがいい
heightとwidth…セル範囲のときは、heightとwidthで範囲を定義する ※範囲の長さが不定のときはgetLastRowを使ったほうがいいかも
``innerColumn:{a:1, b:2, c:3}``
表のときは、innerRowとかinnnerColumnを作って、名前と順序を定義する

### 使い方サンプル

こんな感じで使う。
```javascript:test.gs
const RangeValue ={
  config:{
    fiscalYear:{row:2, column:1, height:5},
    invoiceMonth:{row:2, column:2, height:4},
    documentType:{row:2, column:3, height:6, width:3,innerColumn:{documentType:1, coverLetterText:2, defaultSendingNum:3}}
  }
  main:{
    documentType:{row:2, column:2}
  }
}

const name_Sheet ={
  config: "config",
  main: "マスタ"
}

function test(){
  const Ss = SpreadSheetApp.getActiveSpreadSheet();
  const Sheet_config = Ss.getSheetByName(name_sheet.config);
  const Sheet_main = Ss.getSheetByName(name_sheet.main);

  //たとえばシート「マスタ」内の対象列にデータの入力規則を設定する
  const array_documentType = Sheet_main.getRange(RangeValue.config.documentType.row,
                                                 RangeValue.config.documentType.column,
                                                 RangeValue.config.documentType.height).getValues().flat(); //シート「config」>書類名の列の値を配列として保存
  let cellRule_documentType = SpreadSheetApp.newDataValidation()
        .setAllowInvalid(false)
        .requireValueInList(array_documentType, true); //入力規則を作成
  Sheet_main.getRange(RangeValue.main.documentType.row,
                      RangeValue.main.documentType.column,
                      Sheet_main.getLastRow() -RangeValue.main.documentType.row +1)
               .setDataValidation(cellRule_documentType); //対象範囲に入力規則を設定
}
```
関数内にマジックナンバーがなくなって、グローバル側の定義(引いて言えばシート「config」)だけを弄るだけでよくなった。

## その他

GAS×SpreadSheetって特にマジックナンバーが入りがちな言語なので、こういう方法でできるだけマジックナンバーを減らしていきたい。
slack連携とかの文言も、こういう風にSpreadSheet内に文言一覧を作れば定数文字列化を回避できそう。
【小ネタ】PowerAppsでログインユーザーにより表示/非表示を切り替えるボタンを配置する

PowerAppsのアプリでこのボタンは、管理者には表示したいけど、一般ユーザーには表示したくないということがあったので、
SharePointのリストにログインユーザーのデータがある場合にのみ表示するボタンを設置しました。
この記事ではそのような特定のユーザーに対しての専用ボタンを設置する方法について説明します。
![001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/a08dd485-4906-074f-a347-5ee5c1236215.jpeg)
## SharePointのリストを用意する
まずはボタンを表示したいユーザーのみを登録したリストを作ります。
今回はユーザーの名前があるかで判定しますが、
同名被りがあるのでメールアドレスで判定する、
または、ボタンを表示するか非表示にするかの項目を作りそこから判定するといった判定方法もあります。
![002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/4aeefbd3-c302-3cd8-c578-f1b279fb1a13.jpeg)
## PowerAppsとSharePointを連携する
PowerAppsのアプリでSharePointのリストを参照する前にデータを連携する必要があります。
データ連携の手順は以下の通りです。

↓データの追加からSharePointを選択します。
![003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/3106e473-d156-cca6-a8c8-33152e9c4c2f.jpeg)
![004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/df8550ff-7071-ba1d-5ff1-974292fe21df.jpeg)
![005.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/80e749b1-b574-69fe-4d60-b30b8f5ba934.jpeg)
↓使用するSharePointのサイトを選択します。
![006.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/30dd89c5-34ec-8e39-2b79-edf958466d2a.jpeg)
↓使用するリストを選択します。
![007.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/d87ec6ed-43fe-2135-c922-53b1b81892cc.jpeg)
## 専用ボタンの設定をする
データ連携を行い、リストが使えるようになったので、専用ボタンの設定を行います。
専用ボタンのVisibleプロパティを以下の通り設定します。
```
!IsBlank(
    LookUp(
        PowerApps管理者,
        Title = User().FullName,
        Title
    )
)
```
これでリストに名前があるユーザーのみに表示するボタンの完成です。
「PowerApps管理者」の部分はリスト名なので、使用するリスト名に変更する必要があります。
![008.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/f305028c-7719-eba1-0a30-335c8c157c5f.jpeg)
## 別の使用例
専用ボタンをログインユーザーの名前で判定する方法とは別の使用例を紹介します。
#### ログインユーザーのメールアドレスで判定する
「User().FullName」を「User().Email」とすることでログインユーザーのメールアドレスを取得することもできます。
```
!IsBlank(
    LookUp(
        PowerApps管理者,
        Title = User().Email,
        Title
    )
)
```
#### 表示/非表示の項目で判定する
以下の画像の通り、リストにボタンを表示するかしないかの項目を作り、それを取得して判定します。
![010.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/5187365b-d6a4-81f8-9d22-56fae003470f.jpeg)
```
If(
    !IsBlank(
        LookUp(
            PowerApps管理者,
            Title = User().FullName,
            Title
        )
    ),
    If(
        "表示する" = LookUp(
            PowerApps管理者,
            Title = User().FullName,
            button
        ),
        true,
        false
    ),
    false
)
```
この通り、設定を操作することで自由に応用できるので、色々試してみてください。
UI Automator Viewerが動かなくなった（Mac）

Appiumでテストを書くことになり、レイアウトのIDなどを確認するため、久々にUI Automator Viewerを起動してみたところ…

```
$ uiautomatorviewer
-Djava.ext.dirs=/Users/<UserName>/Android/sdk/tools/lib/x86_64:/Users/<UserName>/Android/sdk/tools/lib is not supported.  Use -classpath instead.
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
```

動かない。



調べてみたところ、Java 11にしたことが原因のよう。

https://stackoverflow.com/a/54492335

リンクのコメントを参考に以下のようにスクリプトを書いた。

```
uiautomator() {
  JAVA_HOME=`/usr/libexec/java_home -v 1.8` uiautomatorviewer
}
```

これで画面は起動するようになったものの、今度は画面が何のイベントも受け付けない。

https://github.com/android/android-test/issues/911

どうやら`swt.jar`なるものの新しいバージョンを落とし、`Android/sdk/tools/lib/x86_64/`に`swt2.jar`として置けば良いらしい。

- 上書きではなく、別名保存
- 4.20をDownloadする（最新の4.24では動かなかった）

https://archive.eclipse.org/eclipse/downloads/drops4/R-4.20-202106111600/

これにて解決。無事動くようになりました。
土日で見つけた学習教材

こんにちは。
長野県のとあるA型事業所でプログラミングをしています。

土日を使っていくつかプログラミングの学習教材を見つけてみました。
あ、その前にですが、Twitterのアカウントを作成しました。

Twitter @toivokitahara

よろしければ、見てみてください。
情報と出会うツールとしてはTwitterは優秀ですね。


・ぷよぷよプログラミング
https://puyo.sega.jp/program_2020/

いつの間にかぷよぷよでプログラミングを学べるようになっていてびっくりしました。
写経といいますが、ソースコードを気合いで書き写すようなコースもあるようです。
HTMLやJavaScriptの講座があるみたいです。

スタバでMacを広げていらっしゃるエンジニアさんのつぶやきで知りました。
元のつぶやきがどれだったか覚えてないのですが、Twitterで情報収集しました。



・Web制作、Web開発の歩き方
https://baapuro.com/

こちらもTwitter経由で得た情報でした。
まだ使い方がよくわかってませんが、有用なサイトのように感じます。
書籍の情報が多いようです。

初心者がいきなり厚い本を買っても挫折すると思うので、慎重に見ています。

・freecodecamp
https://www.freecodecamp.org/japanese/learn/

引き続きこちらをやっています。
こちらですが、認定証の申請に必要な各講座の最後の課題については飛ばすことにしました。
いまはJavaScriptをやっています。
JavaScriptの講座が終わったら実際のコーディングに入っていく予定です。

・「Learning to Fly」
https://www.youtube.com/watch?v=CkcvVZZEsJE&list=PLjxrf2q8roU3X18pAQWLyCJaa79RpqWnn

Flutterの講習動画です。英語ですいません。
字幕をオンにすると日本語で見れますので、そちらも参考にしてみてください。
アプリを開発するためのFlutterについていろいろと学べるチャンネルのようです。
でも実際に実装するとなったら、Googleさまでいろいろと検索してやるんですね。
勉強になりました。

サイトなどの紹介は以上です。

来週から、月曜日、木曜日、金曜日の出勤になる予定です。
今週は残り、金曜日に出勤します。

今日は出勤日ではじめて雨が降っていました。
雨だと体調がいまいちなんですが、こういう時ほど出勤したほうがよさそうですね。
雨なので、自転車ではなく、電車を使って出勤しました。

もう何件か案件の打診が事業所にあるようです。
着実に一件ずつこなしていくと良いかなと思いますので、体調と相談しながらやっていきます。
良い感じに仕事のリズムに体が慣れてきていますので、引き続きうまくリズムを作りながらやっていこうと思います。

それでは、今回はこの辺で。
英語版WindowsでVimが文字化けしたときの対処

# 問題
英語版Windowsで文字コードがcp932なテキストファイルを編集したところ、以下のように文字化けしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548333/9b9372a7-17a3-6b46-fda4-5f27ceb222c7.png)
`:e ++enc=cp932`を叩いても改善しないので困っていたのですが、Twitter のコミュニティに投稿したところ解決策を教えていただきました。

# 原因
英語OS上でvimを開いた際に`enc=latin1`となっていたためです。（vimrcに出てくる`enc`はvim内部処理に関連するエンコーディングの設定）
`:set enc` と打つと現在の設定が確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548333/cfd2f880-146b-68fc-d1f2-d660f7bc2922.png)
日本語OSだとデフォルトが`enc=cp932`となっているので、普段は問題なかったんですね。

# 解決策
`vimrc` に以下の設定を追加します。
```
set enc=utf-8
set fileencodings=utf-8,cp932
```

設定を追加したところ、以下のように表示することができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548333/33302342-fe0f-657f-f802-2bf74d4d4abe.png)

今回のように問題になるケースは稀かもしれませんが、基本的に `set enc=utf-8` は設定しといたほうが良いみたいです。

# 謝辞
[@k_takata](https://twitter.com/k_takata) さん、設定を教えていただきありがとうございました！
【react-chartjs-2】レーダーチャートの目盛り線のオプションで詰まった話

### 左のようにしたいけど、右のようにしかならなくて詰まった
![レーダー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639188/d20e9cbd-b9a6-0783-d739-6ac1c8f9a687.png)


### 環境
|react           |18.2.0  |
|----------------|--------|
|chart.js        |3.8.0   |
|react-chartjs-2 |4.2.0   |


### 結論
オプションをこう記述したらいけた
```
const options = {
  scales: {
    r: {
      min: 0,
      max: 5,
      stepSize: 1,
    },
  },
};
```

### 
[全ソース(GitHub)](https://github.com/corock510/chart-test/blob/master/src/App.tsx)
東京の6月は平年に対して”有意”に暑かった？～平均分析法による考察 ～

増川 直裕

先週初め（6月27日）に、九州南部、東海、関東甲信で、あまりにも早い梅雨明けとなりました。今年は6月でも真夏、もしくは真夏以上？の暑さで、体にこたえます。

筆者は、ずっと東京近郊に住んでいますが、こんなに暑かった6月は過去にあったような、なかったような？　あまり記憶にありません。ただ忘れているだけかもしれませんので、気象庁のページで東京の過去30年（1993年～2022年）の気温データを取得し、6月の日ごとのデータを取得して分析してみました。

**■東京の6月、過去の6月と比べてみると**
以下のグラフは、東京について、各年の6月の最高気温（赤色）、平均気温（緑色）を折れ線グラフにしたものです。グラフの上に表示されている数字（27.6, 23.7）は、それぞれ最高気温、平均気温について、最も値が大きかった年の値です。
![pic1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/0d67caae-03ee-01f8-6992-a37d16b725ee.png)
**対象地域**：東京（東京都にある“東京”の観測地点）
**縦軸の値**：各年における1日ごとの最高気温、平均気温を6月に対して平均をとった値

最高気温（赤色）については、年ごとに上昇している傾向が見てとれ、<font color="Red">今年（2022年）が過去30年での最も高く（27.6℃）なりました。</font>

平均気温も若干の上昇傾向が見てとれますが、最高気温ほど顕著ではなく、最も高くなったのは今年でなく、2004年の23.7℃です。

**■”平年” との比較**
天気予報などでは、”明日の天気は、平年より3度高いでしょう”　とか　“平年より降水量は少ない”　といったように
平年と比較するケースが良く出てきます。ここで言う “平年”　とはいつを示すのでしょうか？

データの引用元である気象庁のページには、気象用語の説明として<font color="Red"> “平年” とは、30年間の平均値を用いる</font>と記載があります。要は過去30年の平均的な気温や降水量と比較して、今年は暑くなる、雨が多くなるなどを報じているわけです。近年は、平年より気温が高くなる、暑くなるといった予報を良く聞くようになりましたが…

JMPでは、平均分析法という、グループの平均を全体の平均と比較する機能があります。今度は、この機能を用いて、東京の6月における平年と各年の気温を比較してみます。

**■平均分析法**
それでは、平均分析法のレポートについて見ていきましょう。

最初は、<font color="Red">”東京の6月の平均気温” </font>に対する平均分析法のレポートです。
![pic2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/1a7da88d-6c24-926b-3819-7b65e7f29bd5.png)
グラフを見ると、水色で囲われた領域があり、領域の真ん中に平均を示す線があります。この平均がいわゆる”平年” に相当します。この平年に対し、各年が有意に高いか低いかを調べるのが平均分析法です。

平均に対し有意に高い場合は水色の領域より上側に点がプロットされ、逆に有意に低い場合は水色の領域より下側に点がプロットされます。グラフの右側には”LDL”と”UDL”の値が記載されており、これが下側と上側の（有意水準 = 0.05 に対する）限界値です。

※平均分析法の詳細につきましては、以下のページをご参照ください。
[**平均分析法 (jmp.com)**](https://www.jmp.com/support/help/ja/16.2/?os=win&source=application#page/jmp/analysis-of-means-methods.shtml#867756)

グラフに戻ると、1995年が平年に対し有意に低かった以外は、すべて、水色の領域に収まっており、平年より有意に高い年はありませんでした。過去3年（2020,2021,2022年）は平均より上側に位置しますが2000年以降の値が大きい年である04年や10年、14年より下側にプロットされていることがわかります。
	
今度は、<font color="Red">”東京の6月の最高気温に対する平均分析法” </font>のレポートです。
![pic3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/5f270a14-d8fb-a71b-37c0-4e456766050a.png)
平均気温と同様に、1995年が下に有意であり、それ以外は水色の領域に収まっています。しかし、直近である2020年、2021年、2022年と連続して値が大きくなっていることが分かります。来年は、領域を上に突き抜けますかね？

6月というと梅雨のイメージが強いですが、今後は、暑さが始まる月としてみなされるかもしれません。

**■平均分析法の利用**
今回は気温のデータで平均分析法を説明しましたが、“あるクラスにおけるテストの平均点”と”学年全体の平均点”を比較するといったように、<font color="Red">日常では平均を一種のベンチマークとして、自分のグループを比較するといったケースが多かったりします。</font>そのようなとき、今回紹介した「平均分析法」は、有用な分析方法になるでしょう。

**■JMPについて**
JMP（ジャンプ）は世界中のエンジニア、データアナリストに選ばれているインタラクティブで可視的なデータ分析ツールです。

**＜ SNSで様々な情報をお届けしています ＞**
**[Facebook](https://www.facebook.com/JMPjpn)**

**[Twitter](https://twitter.com/JMP_Japan)**
AWS Redshiftの用語要点まとめ（自分用メモ

Amazon Redshift
AWSが提供するデータベースサービスの一つでペタバイトを扱えるデータウェアハウス。大量のデータを高速で扱えるため分析用途で使う。


データウェアハウス（DWH：Data WareHouse）とは、複数のシステムからデータを収集・統合・蓄積し、分析に使用するデータベース。蓄積したデータは、例えば時系列や顧客のデータに基づいて分析され、結果はシステム効率化や経営改善などの意思決定に利用。このように、大容量データを分析し経営に役立てることを「BI：Business Intelligence」といい、RedshiftはBIの分野で活用。
DWHでは、基本的にデータの削除・更新は行わずに追加（蓄積）されていきますので通常のデータベースよりも多くの容量が必要になります。RedshiftではPB（ペタバイト、TB：テラバイトの上の単位）級のストレージに対応しており、大量のデータを扱うことができます。
Amazon Kinesisと連携すると、ストリーミングデータをKinesisで収集しRedshiftで分析を行う、というようなことが可能。

●Redshiftのアーキテクチャ
Redshiftでは以下の構成でデータを管理。
Redshiftは大量のリクエストを分散させ並列で処理するクラスタ構成になっています。

・Leaderノード（リーダーノード）
各クラスタに一台だけ存在する司令塔（Leader）となるノード。
アプリケーションなどからのリクエストを受け付けて各Computeノードへ割り振り、またその結果を取りまとめてアプリケーションへ返す役割を果たします。

・Computeノード（コンピュートノード）
Leaderノードからの命令を処理するノード。
一つのComputeノードはCPU、メモリ、ストレージを搭載しており、Computeノードを増やすことでパフォーマンスを向上させることができます。

・ノードスライス（スライス）
Computeノードのリソースを更に細分化した単位をノードスライスと呼びます。スライスの数はComputeノードのインスタンスタイプによって異なります。

●カラムナ（Columnar:列指向）データベース
通常のデータベース管理システムでは「行」が中心に考えられていますが、カラムナデータベースでは「列」の単位でデータが管理されています。例えば「売り上げを集計する」といった集計作業では各日・各月の「売り上げ列」を集計しますから、行単位でデータがまとめられている（＝列データが散在している）よりも、列単位のデータがまとまっている方が効率的にアクセスできる、という仕組みです。
Redshiftはカラムナデータベースの構造により、大容量のデータを蓄積していても、高速のパフォーマンスを維持したまま集計処理などができるようになっています。

●データのロード・エクスポート
Redshiftでは、Amazon S3上のデータファイルのロード（読み込み）や、S3へのエクスポート（保存）を行うことができます。
扱うことのできるファイル形式は「構造化データ形式（CSVなど）」「半構造化データ形式（ParquetやORC、JSONなど）」と、これらのファイルを圧縮した形式（gzip、bzip2など）があります。
「構造化データ」とはRDBMSで利用されている形式のことで、行・列の概念があるデータをいいます。逆に行・列の概念を持たないデータ形式を「非構造化データ」といい、そのうちある規則性を持ったデータ型（XMLやJSONなど）を「半構造化データ」と呼びます。
RedshiftではS3上にある構造化データや半構造化データをロードしてクエリすることができ、またデータを追加・更新したテーブルは上述のファイル形式でS3へエクスポートできます。これによりS3上のデータをAmazon Athenaなど他サービスで活用することも可能です。
なお、S3のように構造化・非構造化に関わらずデータを一元管理する場所を「データレイク」と呼びます。

●Redshiftのバックアップ
Redshiftでは、スナップショットを採取することでバックアップをとります。スナップショットは、RedshiftのディスクイメージをAmazon S3へ保存します。
バックアップを行うスケジュール（8時間ごと、12時間ごとなど）は自分で設定することもできます。なお、スナップショットは一定時間を経過すると削除されます。
スナップショットは手動で採取することもでき、手動で採取したスナップショットは、保存期間を無期限にすることもできます。
また、スナップショットは異なるリージョンへ保存することもできます。これを「クロスリージョンスナップショット」と呼びます。
リージョンをまたがるためデータの転送費用が別途発生しますが、災害時に備える場合や、また異なるリージョンでRedshiftクラスタを再構築したいような場合に利用するのがよいでしょう。

【Amazon Redshift Spectrum】
旧来のRedshiftでは、データが蓄積され大容量化するとS3にあるデータをRedshiftへロードする際に時間がかかっていました。この問題を解決したのがRedshift Spectrumです。
Redshift Spectrumは、S3にあるデータをRedshiftへ取り込むのではなく、S3上のデータを外部テーブルとして参照できるようにした機能
S3上のデータ（外部テーブル）には複数のRedshiftクラスタからアクセスできたり、Redshift内のデータとS3上のデータに対してクエリを実行することもできます。また、利用頻度の低いデータをS3上に保持しておくことでRedshiftのディスクスペースを節約できるという利点もあります。
現在時刻を表示し続けるコマンド（自作コマンド）


コマンド練習のサンプル第三回目？
何気にテストしてると「あ～サーバの現在時刻あと40秒、あと32秒...」ってdateコマンド連打する事ありますよね。（いや余りないかも。）ただ自作コマンドって作れるようになると便利なのでサンプルだと思って読んでもらえればの第3弾。

##### 過去の自作コマンドやコマンドのサンプルは以下
[企業で使われている文字の一覧を作成してみた（文字列変換処理のサンプル）](https://qiita.com/taclose/items/81d4189fe4846c3e0154)
[tailコマンドとかでも強調表示する自作コマンド](https://qiita.com/taclose/items/a1fae3e99d60443c7cbb)

##### 結論（今回のサンプル）

```bash
#!/usr/bin/env bash
while true; do
  printf "\r`date "$@"`だよ！！"
  sleep 1
done
```
このコマンドを/usr/local/bin/datef って名前で保存して、chmod +x datefって実行権限付与。

```bash
$ ll /usr/local/bin/datef
-rwxr-xr-x 1 root root 75  7月  4 10:32 /usr/local/bin/datef
```

こんな感じにして使いましょう。

使った時のサンプル
```bash
$ datef "+%Y%m%d-%H%M%S"　　←dateコマンドのOptionは全て使えます。無しでもOK
20220704-104241だよ！！  ←ここの行が更新され続ける。
```

##### コマンドの解説
while true : どこにもbreakがないので永遠ループですね！tail -f コマンド的な雰囲気で作ったdatefコマンドなのでCtrl＋Cとかで終了してください。

printf "\rxxxxxxx" : printf は頭にある\rこれがミソですね。後で解説

sleep 1 : 1秒待ってね。

##### \rとは何か？
ｒはリターンの略で、正式にはキャリッジリターンと言われています。
バイオハザードとかでしか私は見た事ないですが、[タイポライター](https://ja.wikipedia.org/wiki/%E3%82%BF%E3%82%A4%E3%83%97%E3%83%A9%E3%82%A4%E3%82%BF%E3%83%BC)という昔の手紙を印刷する機械の入力カーソルを先頭に「ガチャコンッ！」って戻す作業をパソコンの世界になっても使い続けてるんですね。なんか素敵。
つまり **```printf "\rhoge"```とすれば、カーソルを先頭に移動してhogeと入力せよ！という意味になる。**
例題でいうなら、 ```printf "ho\rge"``` とすればどうなるか？ hoと入力して先頭に移動してgeと入力するので画面上にはgeしか残りません。
同様に ```printf "1234\r**"```とすればどうか？答えは"**34"
私のサンプルが「だよ！！」をつけているのもdateの出力文字数が0埋めの関係で崩れるのを心配してつけていたりします。

ではでは！
sidekickのブックマークをchromeでインポートする

# 目的

sidekickは、chromeのアカウントでログインすることができるがブックマークは自動同期されない。
chromeはインターネットサーフィン用、sidekickは仕事用で分ければ良いのだが何となく同じアカウントでログインしているのにブックマークが異なるのが違和感があるのでsidekickのブックマークをchromeに取り込む。


## sidekick

1. sidekickのブックマークマネージャーを開く
1. ブックマークをエクスポートする


## chrome

1. chromeのブックマークマネージャーを開く
1. sidekickでエクスポートしたhtmlファイルをインポートする
Mysql2::Error: Duplicate column name 'xxxx'が出たときは既にあるカラムを消そう

# 背景
あるテーブルに3つのカラム追加する実装。

## 一度migrateでエラー
```zsh
$ rails db:migrate
Mysql2::Error: Unknown column 'xxx' in 'zzz': ALTER TABLE `zzz` ADD `xxx` varchar(255) COMMENT 'xxx' AFTER `xxx`
```

原因としてあるカラムを追加する際に、afterを使用してカラム位置を指定したが、その指定したカラム名を間違っていたためエラーを吐いていた。

再度、カラム名を修正してmigrateすると

```zsh
$ rails db:migrate
Mysql2::Error: Duplicate column name 'xxx': ALTER TABLE `zzz` ADD `xxx` varchar(255) COMMENT 'xxx' AFTER `zzz`
```

エラーを吐いていたが、エラー前に実行されたadd_columnでカラム追加されていた様で
同じカラムが存在していると再度エラーになった。

# 対処法
まず、Duplicate column nameが出ているので、テーブルを確認してカラムが追加されているか確認。

確認ができたら、migrateファイル自体は実行されずにdownになっているので空のファイルにしてupにする。

```ruby
class XXXXXXXXXXX < ActiveRecord::Migration[5.2]
  def change
  end
end
```

```zsh
$ rails db:migrate
```

そしたら、追加されてしまっていたカラムだけを追記してrollback
```ruby
class XXXXXXXXXXX < ActiveRecord::Migration[5.2]
  def change
    add_column :zzz, :xxx, :string, after: :sss, comment: "コメント"
    add_column :zzz, :xxx, :string, after: :ddd, comment: "使った方が良い"
  end
end
```

```zsh
$ rails db:rollback
```

するとテーブルがmigrateする前の綺麗な状態に戻るので、再度全てのカラムを記載してmigrate
```ruby
class XXXXXXXXXXX < ActiveRecord::Migration[5.2]
  def change
    add_column :zzz, :xxx, :string, after: :sss, comment: "コメント"
    add_column :zzz, :xxx, :string, after: :ddd, comment: "使った方が良い"
    add_column :zzz, :xxx, :string, after: :ddd, comment: "後から分かる"
  end
end
```

```zsh
$ rails db:migrate
```
UWPをgitlabで自動テストするときのTips

# UWPをgitlabで自動テストするときのTips

## Yamlの正当性の事前チェック
* gitlabのCI/CD->Editorで事前確認が可能

## コマンドはPowerShell上から実行される。
* PowerShellが古いと動かないので[更新](https://github.com/PowerShell/PowerShell/releases)する。
* MSBuildはフルパスで入力するか、PowerShellでパスが通っている状態になっている必要がある。
* デフォルトログがCP932で出力されるので以下を  
「.gitlab-ci.yml」に追加しておくとログが文字化けしない
```
- "& chcp 65001"
```
* 空白を含む実行ファイルは頭に```&```をつける。
```
  - '& ''C:\Program Files\xxxxx\MSBuild.exe'' ''test.sln'' -t:Rebuild -p:Configuration=Release
    -p:Platform="x64"

'
```
* Nugetの復元を手動で指定しないとxamlのコンパイルで引っかかる。
```
  - '& ''C:\Program Files\xxxxx\MSBuild.exe'' /t:restore'
```

## ステージ間でのファイルの引継ぎ
artifactsを設定する必要があるが、UWPのファイルはデカすぎるので
gitlab側の設定を変更しないとファイルの引継ぎが出来ない。

自前で立てている場合は

Admin area -> Settings -> Continuout Integration and Deployment
の Maximum artifacts sizeを変更する。

参考：https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2584
【備忘録】デフォルトで表示されるfirebaseapp.comを変更する

## 概要
Firebase Authenticationを利用してGoogleログイン機能を実装する際、デフォルトではexample.firebaseapp.comのような文字列が表示される。これを独自のドメインに変更する手順を書き残しておく。

![image3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657374/2ccb8881-b796-480b-6194-c443817532dc.png)


## 手順
### 1. 承認済みのリダイレクトURIを追加する
まず、GCPコンソールから「APIとサービス > 認証情報」に移動する。OAuth 2.0 クライアント IDの一覧に「Web client (auto created by Google Service)」が存在すると思うので、編集アイコンをクリックする。承認済みのリダイレクト URIに https://hoge.com/__/auth/handler のような独自ドメインのURIを追加する(※__/auth/handlerの部分は固定)。

### 2. Firebase Hostingに静的サイトをデプロイする
FirebaseでGoogleログイン機能を実装する場合は、必ずこの手順が必要になるらしい。テキトーで良いので何かデプロイしておく。

### 3. Firebase Hostingにカスタムドメインを追加する
先ほど、承認済みのリダイレクト URIに追加したドメイン(例: hoge.com)を追加する。モーダルが表示されると思うので、書かれている手順に従って、AレコードをDNSに追加する。しばらくすると、ステータスが保留中になるはず。

### 4. Firebase configのauthDomainを書き換える
Firebase接続クライアントのconfigにある`authDomain`パラメータを独自ドメインに書き換える。


## 参考URL
- https://firebase.google.com/docs/auth/web/google-signin?hl=ja#expandable-4
- https://stackoverflow.com/questions/44815580/how-to-replace-the-myapp-123-firebaseapp-com-with-my-custom-domain-myapp-com
AWS ElasticBeanstalkでeb-engin.logにはSUCCESSと出るが、WEBコンソールではERRORになる

# 状況
## eb-engin.log
![Image from Gyazo](https://i.gyazo.com/f4b6e1a70d2f2c5d5af30050d37f0d66.png)
ちゃんとSUCCESS！と出てます。

## WEBコンソール
![Image from Gyazo](https://i.gyazo.com/750928fd6d092db4998350ad742b4931.png)
ERRORが出ています。（訳：デプロイが中止してる間に、新しいバージョンがデプロイされたっぽいよ。もう一回デプロイしてね）

# 原因
EB > 設定 > ローリング更新とデプロイ > コマンドタイムアウト
が短いから

# 対処
EB > 設定 > ローリング更新とデプロイ > コマンドタイムアウト
を3600秒に変更したら成功しました。
![Image from Gyazo](https://i.gyazo.com/6e81740bda3bf94406c4f0da147427fd.png)
【Flutter】ランダムな色を返したい

今までリストに色情報を格納して、ランダムなインデックスを計算して返す。みたいな無駄なことをやっていたんですが、下記コードでランダムな色を返してくれるみたいです。

## コード

```dart
Color((Random().nextDouble() * 0xFFFFFF).toInt() << 0,).withOpacity(1.0)
```

## サンプル

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2466417/3b9dd727-8ae6-e260-db5c-128e4c290753.gif' width='250'>

```dart
class _RandomColorState extends State<RandomColor> {
  var randomColor = const Color(0xffffffff);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: Center(
        child: Text(
          'Random',
          style: TextStyle(
            color: randomColor,
            fontSize: 30,
            fontWeight: FontWeight.bold,
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            randomColor = Color(
              (Random().nextDouble() * 0xFFFFFF).toInt() << 0,
            ).withOpacity(1.0);
          });
        },
      ),
    );
  }
}


```

以上です！

## 参考
https://www.web-dev-qa-db-ja.com/ja/dart/flutter%EF%BC%9A%E3%83%A9%E3%83%B3%E3%83%80%E3%83%A0%E3%82%AB%E3%83%A9%E3%83%BC%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AC%E3%83%BC%E3%82%BF%E3%83%BC%E3%81%AE%E8%83%8C%E6%99%AF%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/806102336/
IntelliJ→CodeSpace移行メモ　SpringBoot

# 概要
IntelliJからCodeSpaceに移行したので、投稿します。
移行する理由としては、端末のローカル環境を汚すことなくIDEを使いたいからです。
CodeSpaceはブラウザで使えるIDEなので選択しました。
普通にvsCodeの感覚で操作できますね。ブラウザでこれができることに感動しました。

# 動作環境
IDE:CodeSpace
SpringBootバージョン：2.7.0
Java：17
Test:Junit5
ビルドツール：maven
github :https://github.com/RYA234/spring_boot_memo/tree/thymeleaf
branch「thymeleaf」で確認。CodeSpaceからクローンできます。

# CodeSpaceでやりたいこと
・実行できる
・デバッグできる
・Git機能
・テストコード書ける
（※データベースとかの接続はやらないです…）

# 詰まった場所
## URLがわからない（ｈttp://localhost:5000/に相当するURLがわからない）
### 内容
ローカル環境で動作するときに相当するURL（ｈttp://localhost:5000/）がわからない

### 対処方法
1.PORTタブを選択して、Foward a Portボタンを押す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/3fadad92-ba2d-ddda-1d38-80c5f3e7b0a6.png)


2.ポート番号を入力する。今回は5000を入力する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/f5270cd1-f0b0-209f-bd6b-ec685b929b31.png)

3.カーソル上にある「Open in a Browser」を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/0b8db375-695b-5e21-23ad-8b6fbb8ba0c9.png)

表示結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/b40e1eb3-384d-e797-0a32-aff4d847ce72.png)


URLはｈttps://username-repository-????????? **-5000.githubpreview.dev/**
になるみたいですね


## テストの結果が失敗になる。
### 内容
テスト結果がNGになり以下のようなエラーコードが出る。
``` Error.
java.lang.AssertionError: Unexpected binding/validation errors: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'staff' on field 'name': rejected value [null]; codes [NotEmpty.staff.name,NotEmpty.name,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [staff.name,name]; arguments []; default message [name]]; default message [スタッフ名を入力してください]
 at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:37)
 at org.springframework.test.util.AssertionErrors.assertFalse(AssertionErrors.java:83)
 at org.springframework.test.web.servlet.result.ModelResultMatchers.lambda$hasNoErrors$12(ModelResultMatchers.java:218)
 at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:212)
 at com.example.spring_boot_memo.ValidationTest.Case3_name_ASBA_NG_id_100_OK(ValidationTest.java:74)
 at java.base/java.util.ArrayList.forEach(Unknown Source)
 at java.base/java.util.ArrayList.forEach(Unknown Source)

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/474552a3-239f-54f7-e0a1-c0cad57b57f5.png)

URLでも以下のようなエラーが表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/c6cd730c-8188-ed51-24ef-ce587a3678c5.png)

### 原因
コンパイルされていなかった。

### 対処方法
以下コマンドを実行
``` 
mvn compile
```
結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/164aff11-9a57-466e-644d-d2a9b0d6b3c0.png)


テスト結果は問題なくOKになりました。
WordPressのエディターから入力した記事の内容のcss

# はじめに
WordPressのエディターから入力した記事の表示のスタイルシートのテンプレートです。
（毎回使うので、前やってたプロジェクトからコピペしてた...）

# scss
```scss
.content_area {
        letter-spacing: 0.05em;

        p {
            margin-bottom: 2rem;
            line-height: 1.8;
    
            @include MQ-MAX(500px) {
                font-size: 14px;
                line-height: 2.3;
            }
        }
    
        h2, h3, h4, h5, h6 {
            margin-bottom: 2rem;
            line-height: 1.8;
            font-weight: 600;
    
            @include MQ-MAX(500px) {
                margin-bottom: 1rem;
            }
        }
    
        h2 {
            margin-top: 4rem;
            font-size: 30px;
            // color: $orange;
    
            @include MQ-MAX(600px) {
                font-size: 22px;
            }
        }
    
        h3 {
            margin-top: 4rem;
            font-size: 20px;
    
            @include MQ-MAX(600px) {
                font-size: 18px;
            }
        }
    
        img {
            height: auto;
            max-width: 100%;
            margin-bottom: 2rem;
            vertical-align: middle;
        }
    
        ul {
            margin-bottom: 2rem;
            padding-left: 1rem;
            li {
                list-style: disc;
                line-height: 1.8;
    
                @include MQ-MAX(500px) {
                    font-size: 14px;
                    line-height: 2.3;
                }
            }
        }
    
        ol {
            margin-bottom: 2rem;
            padding-left: 1rem;
    
            li {
                list-style: decimal;
                line-height: 1.8;
    
                @include MQ-MAX(500px) {
                    font-size: 14px;
                    line-height: 2.3;
                }
            }
        }
    
        a {
            // color: $orange;
            text-decoration: underline;
        }
    }
```
C++でRCP.dllを利用するプログラムで例外が発生することがあった

# 概要

- Visual Studio 2015のRCP.dllを利用するC++のプログラムで、プロジェクトの出力先のパスによっては例外が表示されることがあった。

# エラー内容

## エラーメッセージ

```
0x03479E52 (RCP.dll) で例外がスローされました (hogehoge.exe 内): 0xC0000005: 場所 0x0400306E の読み取り中にアクセス違反が発生しました
```

## 発生個所

以下の`return pDlg->OnInitDialog();`の個所でエラーが発生する

```c++:dlgcore.cpp
/////////////////////////////////////////////////////////////////////////////
// AfxDlgProc - does nothing since all messages are handled via AfxWndProc

INT_PTR CALLBACK AfxDlgProc(HWND hWnd, UINT message, WPARAM, LPARAM)
{
	if (message == WM_INITDIALOG)
	{
		// special case for WM_INITDIALOG
		CDialog* pDlg = DYNAMIC_DOWNCAST(CDialog, CWnd::FromHandlePermanent(hWnd));
		if (pDlg != NULL)
			return pDlg->OnInitDialog();
		else
			return 1;
	}
	return 0;
}
```

# 発生条件

次の条件を満たす場合にエラーが発生する

- アセンブリの出力先を既定値の`$(SolutionDir)$(Configuration)\`としている
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204150/87606ca3-9ee0-dd5b-4595-2d4ec418c5e8.png)
- 出力先の階層が深い（パスが長い？）場合。
    - 次の例は極端な例となる。パスの階層が原因なのか、長さが原因となるかは調査していない
    - 例:`C:\Users\user123.domain\source\repos\gitserver\workfolder\projectA\projectA\projectA\projectA\projectA\projectA\projectA\projectA\projectA`

# 対処

## 方法1

- アセンブリの出力先を変更する（例：`.\execute\VS2015\$(Configuration)\`）

## 方法2

- ソリューション、プロジェクトの配置場所を浅くする
dataclassesの使い方

公式サイトはこちら
[dataclasses - Data Classes - Python 3.10.5 documentation](https://docs.python.org/ja/3.10/library/dataclasses.html)

# 使用するメリット

- ①可読性が高い
- ②型指定いないとエラーがでる
- ③特殊メソッドが定義される

## ①可読性が高い

通常のコンストラクタを使うと

```python
class InventoryItem:
    """Class for keeping track of an item in inventory."""
    def __init__(self, name: str, unit_price: float, quantity_on_hand: int = 0):
        self.name = name
        self.unit_price = unit_price
        self.quantity_on_hand = quantity_on_hand

    def total_cost(self) -> float:
        return self.unit_price * self.quantity_on_hand
```

これがdataclassを使用すると下記の用にかける。

```python
from dataclasses import dataclass

@dataclass
class InventoryItem:
    """Class for keeping track of an item in inventory."""
    name: str
    unit_price: float
    quantity_on_hand: int = 0

    def total_cost(self) -> float:
        return self.unit_price * self.quantity_on_hand
```

コンストラクタの中でのアノテーションやデフォルト引数と
インスタンス変数と2回書かなくてよいし、アノテーションも見やすいと思います。

## ②型指定いないとエラーがでる

アノテーションをつけないと下記のエラーがでます。
残念ながらアノテーションなのでバリデーションチェックの機能はもっていないです。

```bash
NameError: name 'unit_price' is not defined
```

## ③特殊メソッドが定義される

- repr
- eq
- `__lt__()`, `__le__()`, `__gt__()`, `__ge__()`

dataclassデコレータの引数として `order=True```

```python
from dataclasses import dataclass

@dataclass(order=True)
class InventoryItem:
    """Class for keeping track of an item in inventory."""
    number1: int
    number2: int

item1 = InventoryItem(10, 20)
item2 = InventoryItem(15, 15)

item1 > item2  # False
```

上記での比較はインスタンス変数のタプルを比較している状態となっています。
なので下記と同義です。

```python
(10, 20) > (15, 15)
```

タプル同士の比較は第一引数同士の比較、
第一引数が同じであれば第二引数の比較、…
といった動きになります。

少し触って感じたメリットは以上です。


## 空辞書、空リストを用意する場合はfiled(default_factory)を使用

このようにデフォルト引数を指定してインスタンス使用しようとするとエラーがでてしまいます。

```python
from dataclasses import dataclass

@dataclass()
class InventoryItem:
    """Class for keeping track of an item in inventory."""
    data: dict = {}

item = InventoryItem()
```

エラー内容

```python
ValueError: mutable default <class 'dict'> for field data is not allowed: use default_factory
```

デフォルト引数でNoneの指定はできるようですが、空辞書、空リストを用意する場合はエラーにも記載があるdefault_factoryを使用します。

```python
from dataclasses import dataclass, field

@dataclass()
class InventoryItem:
    """Class for keeping track of an item in inventory."""
    data1: dict = None
    data2: dict = field(default_factory=dict)
    data3: list = field(default_factory=list)

item = InventoryItem()
item  # InventoryItem(data1=None, data2={}, data3=[])
```

## dataclasses_json

インスタンス後にto_json, to_dictで辞書型でデータを取り出すことができます。

```python
from dataclasses import dataclass, field
from dataclasses_json import dataclass_json

@dataclass_json  # 必ずdataclass_jsonが上にくる必要がある
@dataclass
class InventoryItem:
    """Class for keeping track of an item in inventory."""
    data1: dict = None
    data2: dict = field(default_factory=dict)
    data3: list = field(default_factory=list)

item = InventoryItem({'a': 1}, {'b': 3}, [1, 24])
item.to_json()  # {"data1": {"a": 1}, "data2": {"b": 3}, "data3": [1, 24]}
```
scikit-learnとMLflowを用いたハイパーパラメーターチューニングの並列化

[Parallelize hyperparameter tuning with scikit\-learn and MLflow \| Databricks on AWS](https://docs.databricks.com/applications/machine-learning/automl-hyperparam-tuning/hyperopt-spark-mlflow-integration.html) [2021/3/22時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

このノートブックでは、ハイパーパラメーターチューニングの計算処理を並列化するためにどのようにHyperoptを使用するのかを説明します。クラスターのワーカーに計算処理を自動で分散させるために`SparkTrials`クラスを使用します。また、後で活用できるように結果を保存するために、Hyperoptに対する自動化MLflowトラッキングも説明します。

# MLflowを用いたハイパーパラメーターチューニングの並列化ノートブック

https://github.com/taka-yayoi/public_repo/tree/main/hyperopt_sparktrial

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
【個人開発】４月入社の新米エンジニアが２ヶ月で制作したサービスの話

こんにちは、都内の受託開発会社で働いているまさやと申します。
ReviewHubというサイトを公開し、運営しています。
今回はこのReviewHubを皆様に知っていただきたく記事を書きました。
最後まで読んでいただけると幸いです。
よろしくお願いします！！

## 自己紹介
２０２２年４月、都内の受託開発会社に未経験で入社しました。
前職は保険の営業マンです。
現在は案件にてバックエンド・フロントエンドともに携わっています。

## 使用技術
バックエンド : Vue.js3.2/TypeScript4.7.3
フロントエンド : PHP8.1.5/Laravel9.9.0
データベース : MySQL8.0
インフラ : AWS(EC2/AMI/Route53/LoadBalancer)
バージョン管理 : Git/GitHub


## アプリ紹介
タイトル　**ReviewHub**
https://reviewhub.jp
一言で言えば、IT業界に関するReviewが集まる口コミサイト。
制作期間は２ヶ月です。

![ReviewHub.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729857/6bcc9a1a-b79a-a593-56f1-d9b25db0a7dc.png)



Reviewの対象は大きく４つ『企業・スクール・イベント・記事』に分かれていて、それぞれに対してReviewを投稿することができます。
また**GR(GreateReview)** というイイねボタンを押すことができ、GR数に応じたランキングを表示しています。

**現在、各ページの広告を募集しています!
ご興味が有る方はReviewHubのお問い合わせからご連絡ください！**

## 開発背景
IT業界は複雑な業界であるからこそ、正しい情報がエンジニアを志している方々に届いていないのではないかという問題意識がありました。
その情報格差を埋めたいと考え、IT業界に特化した口コミサイトを作るに至りました。

今やReviewは判断を大きく左右する要因の一つという側面に加え、Reviewを楽しむという娯楽の一つにもなっていると思います。ユーザーに適切な情報を届け、Reviewという娯楽を楽しんでもらえるようになれば嬉しいです。

そのためにReview系サイトの弱点である誹謗中傷や信憑性のない情報を排除する努力を行っていきます。既に通報ボタンを設置しているように、今後もできる限りの対策を取っていきたいと考えています。

## 実装内容
- CRUD処理
- ユーザー認証機能
- メールアドレスによる二要素認証
- GoogleApiを用いたGoogleアカウントでのログイン
- SlackApiを用いた通知機能
- SuperVisorによるプロセス管理システムの導入
- async/await axiosによる非同期通信
- 部分検索、あいまい検索の実装
- InterventionImageを使用した画像のリサイズ・保存処理
- ドメインの取得/SSL化
- リポジトリパターンの実装
- スライドショーの実装
- AWS(EC2/AMI/Route53/LoadBalancer)/Dockerによるインフラ構築

## 実装予定
- PWA
- CircleCIによりデプロイ・テストの自動化
- セッションを利用した動的コンテンツ