OmniAICreator/Qiita-1.07M huggingface dataset:
Azure DevOps Serverのライセンスについて

# 概要

Azure DevOps Serverについて、Visual Studio サブスクリプションに含まれるライセンス、またクライアントアクセスライセンス（CAL）が不要な「利害関係者（Stakeholders）」について関連資料を記載しています。

「利害関係者（Stakeholders）」については、Azure DevOps Servicesも同様のようです。

最新、正確な情報は公式資料をご確認ください。

# (1) Visual Studio サブスクリプションに含まれるライセンス

https://azure.microsoft.com/ja-jp/pricing/details/devops/server/

> Visual Studio サブスクリプションには、1 つのサーバー ライセンスに加えて、サブスクライバー用のユーザー CAL が含まれています。

## 💡(2024年2月26日追加）アクセス レベルについて

下記資料が、各ライセンス（利害関係者含め）でアクセス可能な機能が詳細に記載されています。

https://learn.microsoft.com/ja-jp/azure/devops/organizations/security/access-levels?view=azure-devops-2022


# (2) クライアントアクセスライセンス（CAL）が不要な「利害関係者（Stakeholders）」

Azure DevOps Serverは「利害関係者（Stakeholders）」については、一部の項目をCALなしで利用することができるようにライセンスに記載されています。

https://ja.wikipedia.org/wiki/Team_Foundation_Server
Wikipedia では「関係者ユーザ（ワークアイテムやカンバンなどの管理・利用のみできる限定ユーザ）」と記載されている部分です。

## (2-1) 資料：ライセンス

Visual Studio 2019のライセンス
https://visualstudio.microsoft.com/wp-content/uploads/2020/03/Visual-Studio-Licensing-Whitepaper-Mar-2020.pdf

25ページの「An Azure DevOps Server CAL is not required in the following scenarios」の部分

また、バージョンが古いですが、Visual Studio 2017は日本語の利用規約があり同様の記載がありました。
https://visualstudio.microsoft.com/wp-content/uploads/2016/11/VS_2017_TFS_RTW_JPN_Eula.1041.pdf

## (2-2) 資料：設定方法

### (2-2-1) "Stakeholder"のグループへの追加手順

https://docs.microsoft.com/en-us/azure/devops/organizations/security/get-started-stakeholder?view=azure-devops-2020

https://docs.microsoft.com/en-us/azure/devops/organizations/security/change-access-levels?view=azure-devops-2020

## (2-3) 資料：アクセスレベル

### (2-3-1) サポートされているアクセス レベル

https://docs.microsoft.com/en-us/azure/devops/organizations/security/access-levels?view=azure-devops-2020#supported-access-levels

> Stakeholder: Provides partial access, can be assigned to unlimited users for free. Assign to users with no license or subscriptions who need access to a limited set of features.

### (2-3-2) ステークホルダー（利害関係者）アクセス

https://docs.microsoft.com/en-us/azure/devops/organizations/security/access-levels?view=azure-devops-2020#stakeholder-access

### (2-3-3) Wiki

WikiもProject Wikiならば閲覧できるようです。

https://docs.microsoft.com/ja-jp/azure/devops/project/wiki/wiki-readme-permissions?view=azure-devops

Project Wiki、Code Wikiについて日本語でまとめられた資料については以下をご参照ください。

https://qiita.com/KoKeCross/items/f00eddcc8a82f6e694d0
WSL2でDocker buildをすると止まる問題("docker-credential-desktop.exe": executable file not found in $PATH, out: ``)

# はじめに

```Docker build -f ./Dockerfile -t ~~ . ``` をしていて，エラーで止まって色々ググった結果を載せておきます．
初心者なりの試行錯誤なので的外れ感ありますが，優しくみてください．
やるまえに参考文献の方をみてからやることをお勧めします．

# 環境
- cpu : Intel Core i9 9900k
- gpu : Nvidia RTX2080 Super
- ram : 32GB
- Docker Desktop使用

# エラー文
Ubuntu18.04のビルドをしたかった．

```
~~~@MyComputer:~/dock$ docker build -f ./Dockerfile -t ubuntu .
[+] Building 0.8s (3/3) FINISHED                                                                                                                                                                                  
 => [internal] load build definition from Dockerfile                                                                                                                                                         0.0s
 => => transferring dockerfile: 1.53kB                                                                                                                                                                       0.0s
 => [internal] load .dockerignore                                                                                                                                                                            0.0s
 => => transferring context: 2B                                                                                                                                                                              0.0s
 => ERROR [internal] load metadata for docker.io/library/ubuntu:18.04                                                                                                                                        0.8s
------
 > [internal] load metadata for docker.io/library/ubuntu:18.04:
------
failed to solve with frontend dockerfile.v0: failed to create LLB definition: rpc error: code = Unknown desc = error getting credentials - err: exec: "docker-credential-desktop.exe": executable file not found in $PATH, out: ``
```

なにこれ．

# 解決
``` .docker ```のディレクトリに```config.json```があると思います．

```
~~@MyComputer:~/.docker$ ls
config.json  contexts  run  scan
```

ありましたね．
```config.json```の中身をみると，

```
{
  "credsStore": "desktop.exe"
}
```

とだけあると思います．
サイトをみる感じだと，

```
{
  "credStore": "desktop.exe"
}
```

と`credsStore`から`credStore`へsを消すと動くらしい．

```
~~@MyComputer:~/dock$ docker build -f ./Dockerfile -t ubuntu .
[+] Building 148.7s (25/25) FINISHED     
```

動いちゃった．
なんでこうやると動くんでしょうか．
また，何かあったら追加しておきます．


# 参考文献
https://forums.docker.com/t/docker-credential-desktop-exe-executable-file-not-found-in-path-using-wsl2/100225
ユーザ管理 ⇒ ユーザがアクセスできる情報の管理

１．項目レベルセキュリティでは何ができますか?
２．組織のレコードレベルアクセス権を管理するとき、何を使用できますか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/500c95f9-c80f-a2a7-4220-ddc8293cf709.png)
[改良]SSHログイン監視（ログインがあったら通知/自IPは通知除外）

`/etc/ssh/sshrc`というファイルを作成します。
このファイルはすべてのユーザがSSHログインした際に自動的に実行されます。

このファイル内でmailxコマンド（存在しない場合は `yum install mailx`）を使って、メール送信します。

## 全てのSSHログインを通知する

```bash:/etc/ssh/sshrc
MAIL_TO=to@example.com
echo ""$USER" has logged in from [$SSH_CLIENT] at `date +"%Y/%m/%d %H:%M:%S"` " | mail -s "[$HOSTNAME ]sshd login alert" $MAIL_TO
```

### 認知しているIPアドレスは通知しない

`IPS`変数に指定します。（複数指定したい場合は空白で区切ります）

```bash:/etc/ssh/sshrc
MAIL_TO=to@example.com

FOUND=0
IPS="123.456.78.901"
DETECT_IP=
for ip in $IPS
do
  if [ "${SSH_CLIENT:0:${#ip}}" = "$ip" ]; then
    FOUND=1
    DETECT_IP=$ip
  fi
done

if [ $FOUND = 0 ]; then
  echo ""$USER" has logged in from [$SSH_CLIENT] at `date +"%Y/%m/%d %H:%M:%S"` " | mail -s "[$HOSTNAME ]sshd login alert" $MAIL_TO
# else
#  echo "detect defined ip [$DETECT_IP]" | mail -s "[$HOSTNAME ]sshd login alert" $MAIL_TO
fi
```

※`$SSH_CLIENT`と`$HOSTNAME`は環境変数です。

## 付録/届くメール

上記コードだと以下の様なメールが届きます。

[![Image from Gyazo](https://i.gyazo.com/73e5076a22c6484a0b03ff7a4b31094c.png)](https://gyazo.com/73e5076a22c6484a0b03ff7a4b31094c)
【Android】RecyclerView+RadioButtonの作成

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/0e7798c7-7817-deaf-06f0-2e7b673fddb9.gif" width=50%>
RadioGroupを使用せずに作成します。

# Mainレイアウト作成
RecyclerViewの配置

```activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="vertical"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:listitem="@layout/view_item" />

</androidx.constraintlayout.widget.ConstraintLayout>
```

# アイテム作成
RadioButtonを配置

```view_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RadioButton xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    tools:text="1" />
```

# Adapter作成
RecyclerView用のAdapter作成。
どのボタンを選択しているかを表す変数`checkPosition`を作成し、`onBindViewHolder`関数内でボタンタップ時に`notifyDataSetChanged()`を呼び出すのがポイント。

```ItemAdapter.kt
class ItemAdapter(private val items: List<String>) :
    RecyclerView.Adapter<ItemAdapter.ViewHolder>() {

    private var checkPosition = -1

    class ViewHolder(val binding: ViewItemBinding) : RecyclerView.ViewHolder(binding.root)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
        ViewHolder(ViewItemBinding.inflate(LayoutInflater.from(parent.context), parent, false))

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.binding.button.text = items[position]
        holder.binding.button.isChecked = position == checkPosition
        holder.binding.button.setOnClickListener {
            checkPosition = position
            notifyDataSetChanged()
        }
    }

    override fun getItemCount() = items.size
}
```

# MainActivityの作成
先ほど作成したAdapterをセット

```MainActivity.kt
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = ActivityMainBinding.inflate(layoutInflater)
        binding.recyclerView.adapter = ItemAdapter((1..20).map { it.toString() })
        setContentView(binding.root)
    }
}
```
【Excel 2016】設計書修正で便利な操作まとめ

#はじめに
Excel 2016（Windows）での設計書作成・修正に便利な操作をまとめました

#もくじ
* 複数セルに入力されている文字をまとめて削除
* 擬似ショートカットキー
* 図形の複製
* 複数の図形をグループ化する
* ドラッグして囲んだ図形や画像をまとめて選択
* 全ての図形を選択
* 複数選択した図形に含まれる文字色を変更

#複数セルに入力されている文字をまとめて削除
**文字が入力されているセルをみつけ出して毎回backspaceしなくてすむ**
削除したい文字（文字が入力されているセル）をドラッグで囲む
上部タブのホーム→右部にある"クリア"→"すべてクリア"を選択

#擬似ショートカットキー
**左上のアイコンから使いたい機能を呼び出せる**
**マウスをたくさん動かさないといけない操作を登録すると便利**
先ほどの"複数セルに入力されている文字を一括削除"を例にとると
"すべてクリア"右クリックで表示されるクイックアクセスツールバーに追加を選択
左上にアイコンが表示され、クリックで呼び出せる

#図形の複製
**コピペよりちょっと便利**
複製したい図形を選択して ctrl + D

#複数の図形をグループ化する
**図形とそれに付随する矢印などはグループ化しておくと修正の時に楽**
図形を Ctrl + クリック で複数選択
右クリックで表示されるメニューからグループ化を選択

#ドラッグして囲んだ図形や画像をまとめて選択
**感覚的に操作できて楽**
上部タブのホーム→検索と選択→オブジェクトの選択
図形をドラッグして囲むとまとめて選択できる

##全ての図形を選択
任意の図形をクリックして ctrl + A
(文字入りの図形の場合はもう一度場所をずらしてクリックして選択し直す
一度だけクリックして ctrl + A だと図形内の文字のみ選択される)

#複数選択した図形に含まれる文字色を変更
**他もオプションから設定変更が可能**
図形を選択
右クリックで表示されるメニューから図形の書式設定を選択
文字のオプションタブを選択
文字の塗りつぶしから変更したい色を選択
OracleApplicationExpress（APEX）をお試し利用してみる ～利用登録～

#はじめに
Oracle製品の周辺開発で画面開発をする必要があり、OracleApplicationExpress(APEX)を試しに使ってみようと思う。APEXはOracleDBの付属機能で、DBとの親和性が高いのが魅力的という個人的な印象がある。
APEXを無料で利用するには「<b>Oracle Cloud Free Tier</b>」なるものに登録が必要。今回は「Oracle Cloud Free Tier」への登録方法をメモ。

#登録手順

[Oracle Cloud Free TierのWebサイト](https://www.oracle.com/jp/cloud/free/)にアクセスして、「無料で始める」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632397/5a40eaff-32ce-3e95-0ed7-698f778dec28.png)

国、氏名、メールアドレスを入力して、Verify my emailをクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632397/88681247-3333-97a4-2f46-3697b6471f44.png)

受信したメール上のリンクをクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632397/4fdd3184-5bb3-fb2b-42f8-a645f24403da.png)

詳細なアカウント情報が聞かれるので入力して「Continue」をクリックする。
※Company Name, Alternate English Company Name, Department NameはOptional（任意）となっていますが、入れないと先に進めませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632397/c62b868a-d140-7c7f-326b-16d9ace34cc5.png)

住所情報が聞かれるので入力して「Continue」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632397/07ad32d2-e61a-76f1-9ef2-e01e2952e5c9.png)

電話番号を入力してSMSコードを発行・入力する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632397/0c253d12-84cc-e16a-d5ff-b00d9b736763.png)

支払カード情報を入力し、Agreementにチェックを入れてから「Start my free trial」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632397/b739f9ab-5656-bbc2-7893-68881de06c97.png)

こんな画面が表示されて利用できるようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632397/fd436dab-84c5-83e4-f807-5680b300ab86.png)

このあとAPEXの環境作成～画面開発をやってみる。
Docker用aliase

#Docker用aliase

## bash
```bash
alias dcu='docker-compose up -d'
alias dcs='docker-compose stop'
alias dcd='docker-compose down'
alias dp='docker ps'
alias dv='docker volume'
alias di='docker images'
alias dx='docker exec -it'
```

## power-shell
```powershell
Set-Alias wget Invoke-WebRequest
Set-Alias dc docker-compose
function dcu {
    docker-compose up -d $args
}
function dcs {
    docker-compose stop
}
function dcd {
    docker-compose down
}
function dp {
    docker ps $args
}
function dv {
    docker volume $args
}
function di {
    docker images $args
}
function dx {
    docker exec -it $args
}
```
python順序を保持したまま配列の要素をユニーク(一意)にする

# 配列要素をユニークにしたい
普通はこうするのだが、元データの順序性が崩れてしまう。
setの性質上仕方ない。

```python
>>> dat = [3,2,1,5,1,2]
>>> list(set(dat))
[1, 2, 3, 5]
```

# 元の順序は維持した状態でユニークにする

```python
>>> from more_itertools import unique_everseen
>>> list(unique_everseen(dat))

[3, 2, 1, 5]
# 元の順序が維持されかつユニークになった

```

# 一意判定条件がもうちょっと複雑なケース

```python
dat2 = [(3, "b"), (2, "a"), (1, "a"), (2, "b")]
# -> 例として2次元配列があり、"a","b","c"の値をキーとしたuniqなデータを取り出したいとする

>>> list(unique_everseen(dat2, key=lambda x: x[1]))
[(3, 'b'), (2, 'a')]
# みたいな感じ
```
結合テストコード ActiveHashの場合

オリジナルアプリの結合テストコードを書いている中、
ActiveHashを使用しているところのテストコードの書き方がわからず、
手こずってしまいました。
記事にして復習したいと思います。
FactoryBotとFakerは導入済みです。

## バージョン

・Ruby 2.6.5
・Rails 6.0.0

## 新規投稿の結合テストコード

[![Image from Gyazo](https://i.gyazo.com/3bea6b7f6092bae69d2f8a0d0a66adbe.jpg)](https://gyazo.com/3bea6b7f6092bae69d2f8a0d0a66adbe)

今回私が、結合テストコードを行う部分のページです。
「お題の投稿が上手く行く時」のコードを記述します。


```ruby
 context "お題が投稿できる時" do
    it "ログインしたユーザーは投稿できる" do
    # ログインする
    visit new_user_session_path
    fill_in "メールアドレス", with: @user.email
    fill_in "パスワード（半角英数混合6文字以上）", with: @user.password
    find('input[name="commit"]').click
    expect(current_path).to eq(root_path)
    # トップページに出題するボタンがあることを確認する
    expect(page).to have_content("出題する")
    # お題投稿ページに遷移する
    visit new_post_path
    # フォームを入力する
    select '文章問題', from: 'post[genre_id]'
    fill_in 'post[title]', with: @post.title
    fill_in 'post[sentence]', with: @post.sentence
    # 出題するボタンをクリックするとPostモデルのカウントが1つ上がる
    expect {
      find('input[name="commit"]') .click
    }.to change { Post.count }.by(1)
    # トップページへ遷移したことを確認する
    visit root_path
    # トップページに先ほどのお題が投稿されているか確認する
    expect(page).to have_content(@post.title)
    end
  end

```
この記述が、新規投稿ができる時の記述です。
前後の記述は割愛させていただきます。
これは、フォームに情報を正しく入力して上手く投稿されるかを
テストしています。

注目していただきたい箇所は、「#フォームを入力する」の部分です。
ここで、ActiveHashの部分で使用するのが、「select」です。
先ほどのページを検証ツールで見た時

[![Image from Gyazo](https://i.gyazo.com/4c1da17ad5b498e1e19e4bab4f99ab88.png)](https://gyazo.com/4c1da17ad5b498e1e19e4bab4f99ab88)

このようになります。
serectの引数には、option valueの部分を、fromの引数にはnameの部分を記述します。
これで無事テストコードが通りました。
フォームに情報を入力する際は、fill_inを使用していました。
何かを選択する場合は、selectを使用するということを学びました。

まだまだ、初心者のため記述に不備があるかもしれません。
その際は、お手数ですがコメントをいただければ幸いです。
UnityのBoxColliderの頂点を取得するスクリプト



すごく欲しい機能なのになぜか搭載されていないBoxColliderの頂点を取得するスクリプト。
親の回転や縮小にも対応しています。


```C#:ソース
   public static Vector3[] GetBoxCollideVertices(BoxCollider Col)
    {
        Transform trs = Col.transform;
        Vector3 sc = trs.lossyScale;

        sc.x *= Col.size.x;
        sc.y *= Col.size.y;
        sc.z *= Col.size.z;

        sc *= 0.5f;

        Vector3 cp = trs.TransformPoint(Col.center);

        Vector3 vx = trs.right * sc.x;
        Vector3 vy = trs.up * sc.y;
        Vector3 vz = trs.forward * sc.z;

        Vector3 p1 = -vx + vy + vz;
        Vector3 p2 = vx + vy + vz;
        Vector3 p3 = vx + -vy + vz;
        Vector3 p4 = -vx + -vy + vz;

        Vector3[] vertices = new Vector3[8];

        vertices[0] = cp + p1;
        vertices[1] = cp + p2;
        vertices[2] = cp + p3;
        vertices[3] = cp + p4;

        vertices[4] = cp - p1;
        vertices[5] = cp - p2;
        vertices[6] = cp - p3;
        vertices[7] = cp - p4;

        return vertices;
    }
```
ラズパイでタイムラプス作り

職場で近くの席にいるスーパーエンジニアと雑談していたときにラズパイで遊ぶ話題になり、
その勢いでうっかりラズパイとカメラモジュールを買ってしまいました。

せっかく買ったから何かやりたいなと、タイムラプスが簡単に作れそうなので挑戦してみることにしました！
手順は以下の通り、ラズパイで完結させてみようと思います。

1. ラズパイのカメラで定期的に写真を撮影
1. 写真をつなぎあわせて動画に変換

## 必要なもの
- Raspberry Pi 3 Model B（OSセットアップ済み）
- Raspberry Pi カメラモジュール V2
- USB電源アダプター 5V/3A 1.5m microUSB
- microSDカード 32GB
    - 後述の設定にもよるが画像一枚あたり約300〜400KB、合計5GB程にはなるので容量は16GB以上あると安心かもしれません

## ラズパイでの撮影準備
手順は公式のドキュメントを参考に進めます。
https://www.raspberrypi.org/documentation/usage/camera/installing.md
### カメラモジュールをラズパイに接続
平たいコネクタの部分にカメラモジュールを接続します。
端子の向きに注意して差し込みましょう。
![IMG_1272.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1139641/1a9f5d72-8343-bbbe-b4a8-9ecf3da5d1a7.jpeg)

### カメラを有効化
接続しただけではまだ使用することができません。
ラズパイを起動し、コンソールから以下のコマンドを実行します。

```
sudo raspi-config
```
すると設定画面がコンフィグ画面が表示されるので、
Interfacing Options ─ Camera ─ Yes を選択しましょう。
Finishでコンフィグ画面終了後、再起動すると設定が反映されます。

## 写真撮影実行
`raspistill` コマンドのオプションを使うことで一定時間、定期的に写真を撮影することができます。

やはり動きのある画が映えると思いますので、職場の窓から見下ろした道路風景を12時間夜通しで撮影してもらうことにしました。
がんばれ！

```
rasipistill -w 1280 -h 800 -q 30 -t 43200000 -tl 3000 -o %d.jpg
```
`-w 1280 -h 800` ：撮影する写真サイズ
`-q 30` ：jpg画像の品質（０〜100）
`-t 43200000` ：トータルの撮影時間・・・43200000ms（12時間）の間撮影
`-tl 3000` ：撮影間隔・・・3000ms（3秒）ごとに撮影
`-o %d.jpg` ：連番でjpgファイルを出力する

《余談》
カメラモジュールの向きを固定しておくための装置はレゴブロックで作りました。
遊び心が過ぎて不思議な物体になっていますw
![1549587356603.JPEG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1139641/7bd046d4-7a9d-099e-5750-f7ad7550d1df.jpeg)

## 撮影結果
翌日確認したところ14402枚の写真が撮影できていました。

![01415.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1139641/cf1f523a-5cad-f27e-d700-4b4d0bf087a2.jpeg)

次にこれらを動画に変換します。

## 動画への変換
変換には `avconv` を使用することにしました。
まずはインストールを行います。

```
sudo apt install avconv
```

インストールが完了したら、いよいよ動画変換を実行します。
動画のコマとなる画像の合計枚数は固定のため、フレームレートを上げると動画の長さが短くなります。
今回は１秒当たり20コマの設定にしてみることにしました。
以下のように実行し、しばらく待てば動画が出来上がります。

```
avconv -r 20 -i %d.jpg -s '1280x800' output.mp4
```
`-r 20` ：フレームレート（fps）を指定
`-i %d.jpg` ：連番のjpgファイルを読み込む
`-s '1280x800'` ：出力フレームサイズ
`output.mp4` ：出力ファイル名

## 完成したタイムラプス動画
<iframe width="560" height="315" src="https://www.youtube.com/embed/s0DGw5jd2gc" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

18時〜翌6時の12時間の撮影をぎゅっと12分の動画にしました。
思っていた通りのタイムラプスに仕上がりました。
※最初の1分ほどは部屋の明かりが反射していて失敗。。

## あとがき
動画への変換に時間がかかるので、撮影から動画変換までを自動化できると寝てる間に出来上がっていいなとか、カメラ＋他のセンサーで面白い事できないかなぁとか考えています。
浮かんだアイデアを自分で実現できると大きな達成感がありますよね。
この記事で興味を持たれた方もぜひ、ラズパイを勢いで買って触れてみてはいかがでしょうか？
エラーの時の私のルーティーン

初学者です。

エラーが出た際に心掛けていることや考え方をまとめます。

ちなみにまだ業務経験もないペーペーですので
正しいかどうかは分かりませんが私には合っているのでメモとして残します。


## ルーティーン

1. エラー文をそのままコピってググる。
2. 自分用のフォーマットに当てはめて思考を整理する
3. teratailやStackOverflowなどのQAサイトを利用する
4. どうしても分からなかったら有料のメンターさんと契約する

こんな感じです。
重要なのは1と2です。


## エラー分をそのままコピってググる

エラー画面って最初は英語でつらつら書いてあるので意味不明なんですけど、ちゃんとヒントが書いてあります。
焦らずにそのままコピーしてググるだけで同じエラーに直面した方の記事が出てくるのでその内容を読みます。

ここで注意なのが`間違った情報もたくさんある`ということです。

私も初心者でよく理解できていないまま記事を投稿してますし、記事のバージョンと自分のバージョンが違うだけでも答えが違ってきます。

なので`公式`の情報をきちんと見ることを忘れてはいけません。

私は公式の情報だけだとイマイチ理解できないことも多いのでたくさんの記事を見て、そのあと公式の情報を見ると「あーなるほど」と思うことがあります。

実際に実務にあたられているエンジニアさんも暗記しているわけじゃないようなので、焦らずにググりましょう。

そして忘れてはいけないのが`なぜエラーになっていたか、なぜ解決できたか`を振り返るようにしています。(分からないことも多いですが...）

私は何度もエラーにあったおかげでMVCの処理の流れが分かるようになってきました。
エラーは最高の学びなのでせっかくの機会を逃さず自分の成長につなげられるようにしています。


## 自分用のフォーマットに当てはめて思考を整理する

ググっても分からない時は一旦整理します。

①何を実装しようとしたのか
②どんなエラーが出たのか
③エラーを元に調べたこと
④調べたことを元に何が原因と考えたか
⑤考えた原因を元に何を試したか

これをメモに書いて自分で整理します。
そうすると「あ、この可能性もあるかな」とか「あ、まだ試してないことあった」と気付きます。

この整理は実務に入って分からないことを聞く際にも使えると思います。

「エラーが出ました！分かりません！教えてください！」って聞いたら教える方も嫌ですよね。
教えてくれる方の時間を奪うことになるという気持ちを忘れずに、でも自分だけで考えててもわからない事は聞いた方が早いだろうという気持ちで過ごしたいと思います。

## teratailやStackOverflowなどのQAサイトを利用する

いよいよ自分だけでは解決できなかったらQAサイトで質問します。
有名なのは下記ですかね？

[teratail](https://teratail.com/)
[StackOverflow](https://stackoverflow.com/)
[スタックオーバーフロー日本語版](https://ja.stackoverflow.com/)

ここで先ほど自分で思考を整理したフォーマットそのまま載せます。
私は最初「聞くの怖いな」と思ってたんですけど、まじで時間の無駄なので聞きます。
私の場合30分悩んでダメなら聞くというルールにしてます。
だって別に損しないですからね。

ただ、しっかり考えて整理してから、トライ&エラーをしてからじゃないと答えて頂けないので自分でやるべき事はしっかりやってからです。

## どうしても分からなかったら有料のメンターさんと契約する

私は[MENTA](https://menta.work/member/dash)というサービスを利用しています。
月額で契約したり、単発で契約したりいろいろありますが1回1000円とかで相談に乗ってくれる方もいるのでどうしても分からなかったら契約して聞きます。

私はとてもいいメンターさんと出会えましたが、自分に合う合わないはあるので口コミなどを見て判断しましょう。


## その他に

そもそもエラーにならない為に

`1つずつ機能を実装する`

というのを心掛けています。

バーっと書いてエラーだとどこが悪いのか判断に時間がかかってしまうので、細分化して実装するようにしています。


以上です。
manifest.json の Manifest: Line: 1, column: 1, Syntax error. エラーの解決方法

## 現象

`manifest.json` が `Manifest: Line: 1, column: 1, Syntax error.` というエラーを発生。

![manifestjson-error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492675/c63f6f71-2b2b-84e0-d8fa-6990a5bdec92.png)

`manifest.json` の構文エラーかと思い構文チェックを行ったがエラーなし…:weary:

## 原因

ベーシック認証がかかっていると発生。

## 解決方法

MDNのウェブアプリマニフェストページに以下の記載がありました。

https://developer.mozilla.org/ja/docs/Web/Manifest

> 注: マニフェストのアクセスに資格情報が必要な場合は、マニフェストファイルが現在のページと同じオリジンにあったとしても、 crossorigin 属性を use-credentials に設定する必要があります。

どうやらベーシック認証のせいで `manifest.json` へアクセスできないようです。

html の `manifest.json` を読み込んでいる `<link>` 要素に `crossorigin="use-credentials"` を追加する。

```html:html
<link rel="manifest" href="/manifest.json" crossorigin="use-credentials">
```

これでエラーが表示されなくなりました:blush:
React nativeでios/androidから発信する方法

##React nativeでios/androidから発信する方法

React nativeでios/androidから発信する方法を調べる機会がありましたので、調べた情報をここにまとめておこうと思います。

##参考にしたサイト
検索しましたが、今現在でQiitaで記載されている記事を見つけることができず、こちらの記事を中心に参考にしました。
[React Nativeで電話をかける方法](https://www.it-swarm.jp.net/ja/react-native/react-native%E3%81%A7%E9%9B%BB%E8%A9%B1%E3%82%92%E3%81%8B%E3%81%91%E3%82%8B%E6%96%B9%E6%B3%95/805783300/)

そこで２パターンの発信方法がありましたので、以下に記載します

##発信機能の構築　パターン①：Linkingを用いる方法
Linkingを用いて電話をかけます
まずは実際のコード例を以下に記載します。

```react:CallActivity.jsx
import { Linking } from 'react-native';
・・・
//変数「inputText」はTextInputを用いるなどして入力式にするか、固定値の場合はハードコーディングなどで置き換えて考えてください。
const inputText = '09012345678';
<TouchableOpacity
   style={}
   onPress={() => {
     const phoneNumber = `tel:${inputText}`;
     Linking.openURL(phoneNumber);
   }}
>
  <Text style={}>電話をかける</Text>
</TouchableOpacity>
・・・
```
###STEP1

Linkingをimportします。

###STEP2
電話番号の文字列の前に「tel:」を結合します。

※参考サイトではiosは「tel:」、androidは「telprompt:」になるよう端末のOSで条件分岐して記載しておりましたが、私の環境ではandroid側が「：telprompt」ではエラーになってしまいました。
android側でも「tel：」を利用したところ無事動作したので、今回はどちらのOSも「tel:」を採用しています。
皆さんも実装してみて、動作に合わせてご利用ください。

###STEP3

Linking.openURL(作成した文字列);で発信!!
これで発信されます!

###発信結果
iosの場合、発信確認のダイアログが出て、はいを選択後に発信されます。
androidの場合、発信画面(電話アプリの画面)が電話番号が表示された状態で開かれ、あとは通常通り発信ボタンを押すと発信されます。

##発信機能の構築　パターン②：react-native-phone-callパッケージを用いる方法
react-native-phone-callパッケージを用いて電話をかけます
まずは実際のコード例を以下に記載します。

```react:CallActivity.jsx
import call from 'react-native-phone-call';

const makeCall = (number) => {
  const args = {
    number: number,
    Prompt: true,
  };
  call(args).catch(console.error);
};

//変数「inputText」はTextInputを用いるなどして入力式にするか、固定値の場合はハードコーディングなどで置き換えて考えてください。
const inputText = '09012345678';

<TouchableOpacity
   style={}
   onPress={()=> this.makeCall(inputText)}
>
  <Text style={}>電話をかける</Text>
</TouchableOpacity>
```

#####STEP1:パッケージをインストール

```
$ npm install --save react-native-phone-call
```

#####STEP2:インポート+メソッドを作成
```react:CallActivity.jsx
import call from 'react-native-phone-call';

const makeCall = (number) => {
  const args = {
    number: number,
    Prompt: true,
  };
  call(args).catch(console.error);
};
```

#####STEP3:onPressメソッドで呼び出す
```react:CallActivity.jsx
//変数「inputText」はTextInputを用いるなどして入力式にするか、固定値の場合はハードコーディングなどで置き換えて考えてください。
const inputText = '09012345678';
<TouchableOpacity
   style={}
   onPress={()=> this.makeCall(inputText)}
>
  <Text style={}>電話をかける</Text>
</TouchableOpacity>
```
###発信結果
iosの場合、発信確認のダイアログが出て、はいを選択後に発信されます。
androidの場合、発信画面(電話アプリの画面)が電話番号が表示された状態で開かれ、あとは通常通り発信ボタンを押すと発信されます。

##困ったこと
本来は、onPressを呼んでから、すぐ発信するようにしたかったのですがその方法が今回見つかりませんでした。もしご存知の方がいらっしゃいましたらご教示いただけますと幸いです。

##実機でのデバッグ方法
こちらのサイトが参考になるかと思います!
[Expo環境構築](https://qiita.com/yacchi1123/items/5a3d16f0d92d3912e5c4)
※expと記載ありますが、私の場合はexpoで動作しました。

##まとめ
・パターン1,2どちらを使うか決めましょう
・パッケージをインストールしましょう
・発信したい電話番号を取得orハードコーディングしましょう
・onPressで電話をかけましょう
Raspberry Piでカメラが認識されないときに試したこと

# 始めに

`$ vcgencmd get_camera`コマンドを入力し，カメラモジュールが正しく認識されているか確認したところ，以下のように表示されました．

```
supported=1 detected=0
```

supportedはカメラが有効化されているかどうか（0：無効，1：有効）を表しています．
detectedはかカメラが認識されているか（0：無効，1：有効）を表しています．
どうやら，カメラがうまく認識されていないようです．
以下では，この問題を解決するために，試したことや確認したことをまとめます．

# １．カメラモジュールの有効化の確認

カメラモジュールが有効化されていない場合は，まずはカメラモジュールを有効にします．
「RaspberryPiの設定」を開き，カメラを有効にします．
![SharedScreenshot.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1125965/35759139-e454-d04f-6077-13846d9fb841.jpeg)


# ２．ケーブルの向き

まずは，カメラとRaspberryPi本体に接続されているケーブルの向きを確認します．
ケーブルの青い部分が，以下の写真の向きになっているか確認します．
（静電気に注意してください）  
RaspberryPi本体側（青い部分はUSBポート側）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1125965/5a79799d-5c2d-4015-7a7e-1f14203a7c2e.jpeg" width="250px">
カメラモジュール側（青い部分はカメラの裏側）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1125965/b18ae61e-ffd2-2bc6-635a-84362ae2f57b.jpeg" width="250px">

# ３．カメラ上部の金具

カメラ上部の金具がパカッと外れていました．
上からそっと押して直します．

# ４．パッケージの更新とアップグレード

`$ sudo apt-get update`と`$ sudo apt-get upgrade`コマンドを実行します．（結構時間がかかります）
その後，`$ sudo reboot`で再起動します．

# 最後に

カメラが認識されたかどうか確認するために，再度`$ vcgencmd get_camera`を行います．
下記のように表示されていれば成功です．

```
supported=1 detected=1
```
【iOS】シミュレータでPUSH通知を表示する

## 環境
- Xcode Version 12.3 (12C33)
- macOS Catalina 10.15.7
- Firebase/Messaging 7.1.0
    - **Firebase Cloud Messaging によるリモート通知受信環境を構築済み**


## 目的
- OSのバージョンごとに通知をタップして起動した際の挙動を確認したい

## 実現方法
1. プロジェクトの TARGET > Signing & Capabilities から Bundle Identifier を確認
2. 以下のようなファイルを作成し拡張子を「.apns」とし保存
3. 起動中のシミュレータにドラッグアンドドロップ

```json:test.apns
{
    "Simulator Target Bundle": "(アプリのバンドルID)",
    "aps": {
        "alert": {
            "title": "通知テストタイトル",
            "body": "通知テストメッセージ"
        }
    }
}
```

## 結果

![Simulator Screen Shot - iPhone SE (iOS 14.2.2nd generation) - 2021-02-24 at 11.48.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1045667/89335029-9091-c5b7-55cd-63950aaf3787.png)


## 注意点
- **`func application(_ application:didReceiveRemoteNotification userInfo:fetchCompletionHandler completionHandler:)` が呼ばれない**
    - `FIRMessagingRemoteNotificationsProxy` で Method Swizzling している影響？
    - このためサイレントPUSH通知での画面更新等は確認できなかった
- FirebaseCloudMessaging 利用中・シミュレータ上で通知関連メソッドが呼び出されるかどうかは以下のとおり

|メソッド|呼び出されるか|
|----|-----|
|func application(_ application:didFinishLaunchingWithOptions launchOptions:) -> Bool|○（launchOptionsに通知データが含まれる）|
|func application(_ application:didReceiveRemoteNotification userInfo:fetchCompletionHandler completionHandler:)|×|
|func userNotificationCenter(_ center:willPresent notification:withCompletionHandler completionHandler:)|○|
|func userNotificationCenter(_ center:didReceive response:withCompletionHandler completionHandler:)|○|
RSpecによるテスト実行中にエラー発生 〜Lost connection to MySQL server during query〜

# エラーの内容
Railsで開発中のアプリケーションのテストをRSpecで行っていたところ、急にテストが失敗するようになった。
ただし、結果を確認すると前半のテストは成功しており、後半のテストが全て失敗している。
![9f8e402a405920d2ff49c57039d80554.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/788596/4e27b676-ec72-e82a-8ea6-c23d7e681654.png)

そして、失敗した４つのテストのうち、エラー文は以下のとおり表示されていた。
① Mysql2::Error::ConnectionError: Lost connection to MySQL server during query
② Mysql2::Error: MySQL client is not connected
③ Mysql2::Error: MySQL client is not connected
④ Mysql2::Error: MySQL client is not connected

# エラー文の考察
１つ目のエラー文の内容は、**「クエリ（命令のこと。ここではテスト実行のこと。）の実行中にMySQLサーバーとの接続が失われた」**ということなので、２つ目以降のエラーは全てMySQLとの接続がないのでエラーになっていると考えられる。

# 原因
ググったところ、テスト用インスタンスを生成する際に複数のインスタンスを生成する記述をしていると、テストの実行中に何らかの負荷が生じ、テストが失敗することがあるみたい。
今回の場合は、**クエリを実行してから処理が終わるまでの間に、すべてのテストを実行できずに結果が返ってきてしまった**という感じでしょうか。

# 解決策
以下の一文をテストファイルに記述したら無事にテストが通りました。

```ruby:spec/models/order_shipping_spec.rb
require 'rails_helper'

RSpec.describe OrderShipping, type: :model do
  before do
    # 自分で関連付けを定義するためにuserインスタンスとitemインスタンスを生成
    user = FactoryBot.create(:user)
    item = FactoryBot.create(:item)
    # 関連付けを定義しながら@order_shippingを生成
    @order_shipping = FactoryBot.build(:order_shipping, user_id: user.id, item_id: item.id)
    # この一文を追加
    sleep 0.1
  end
```

sleepメソッドは、一定時間、rubyプログラムの実行をストップするメソッドです。
一定時間経過後、次の行からプログラムが再度開始されます。
（*この場所に記述したらテストが成功したということは、インスタンスをきちんと作り終えていなかったということ？*）

# 最後に
正直に言って今回のエラーの原因は特定できていない。
ただ、今回テストしているモデルは実はフォームオブジェクトパターンを利用して作成したクラスに対するテストで、Railsのモデルとは若干異なる。
なのでFactoryBotでアソシエーションの記述ができず、単体テストファイル内で自分で関連するインスタンスを作っているのだが、これが関係あるのかな？

原因解明できたらこの記事を修正したいと思います！
3省3ガイドライン→3省2ガイドライン

# 概要

- 厚生労働省 – 医療情報システムの安全管理に関するガイドライン 第5版
    - 対象：医療機関
    - https://www.mhlw.go.jp/file/05-Shingikai-12601000-Seisakutoukatsukan-Sanjikanshitsu_Shakaihoshoutantou/0000166260.pdf
- 経済産業省・総務省 – 医療情報を取り扱う情報システム・サービスの提供事業者における安全管理ガイドライン
    - 対象：クラウドサービス事業者
    - https://www.meti.go.jp/press/2020/08/20200821002/20200821002-3.pdf

これら2つのガイドラインを合わせて、**3省2ガイドライン**と呼ばれる。令和2年8月に経済産業省のガイドラインと総務省のガイドラインが統合されるまでは、3省3ガイドラインと呼ばれていた。

---

（以降追記予定）
ActiveModel::UnknownAttributeError

# きっかけ

![スクリーンショット 2021-02-24 11.45.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1003934/53e0004f-918e-92a3-a2c0-555158323f0f.png)

このエラーの解決法を共有するため。

# 結論
マイグレートした後に、マイグレーションファイルを変更してしまったため。

マイグレーションファイルには、カラム名や、どういうタイプのカラムにするのか、また、空っぽでも良いのか、などの記述をしていくが、そうした変更をした後は、必ず、マイグレートをしないと変更が反映されないので、注意。
そもそも、UnknownAttributeError　とは、そんな引数知らないですよ、ということ。

# 解決法
rails db:migrateをした後だった場合は、ロールバックをしなければならない。

```shell:ターミナル
rails db:rollback
```
これをした後に、

```shell:ターミナル
rails db:migrate:status
```
このコマンドを打つと

```shell:ターミナル
 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20210223092316  Devise create users
   up     20210223093607  Create articles
```

ここで、downになっていたら、ロールバックが成功しているので、これが確認できたら、マイグレーションすると間違いが起こりにくいと思います。
ChromeとSafariで見え方が崩れる場合の対処法

##はじめに

初めまして！Takumiです。
Qiita初投稿です。

LPを制作した際に、制作途中でつまづいたポイントを何記事かに分けて書いていきます。

同じような悩みを持っている方のヒントになれば嬉しいです！

それではご覧ください。

##Safariで崩れる問題

コーディングをしていて、ローカル環境ではきれいになっていたのにいざ本番環境(実機)で検証してみると、画像や文章が崩れていると言うことはありませんか？

私はポートフォリオを作っているときに、この壁にぶつかりました。

コーディングし終えて、本番環境にも上げて、Chromeで確認して「よし完成！」と思ったとき、Safariでも確認をすると...

画像が指定したCSS(widthとか)が効いていなくて、画面いっぱいに広がっていました:fearful:

#####「Chromeではきれいに見えているのに、Safariでは崩れている問題」

結論を最初に言っておくと、下記コードを入力することでSafariでもきれいに見えました。

``````:コード
_::-webkit-full-page-media,_:future,:root .CSSクラス名{
内容
}
```

画像の崩れも文章のフォントの乱れも、このコードを入力することで修正できました:raised_hands_tone1:

<hr>

####`ワンポイント`

上記のコードを記入すればいいだけなのですが、私はSassを使ってCSSを書いていたのでどのように打ち込めばいいのか少し悩みました。
<hr>

#####①Sassの中にそのまま入れてみた

```
A{
 &_::-webkit-full-page-media,_:future,:root .CSSクラス名{
 内容
 }
}
```
#####結果:効かない:no_good_tone1:
<hr>

#####②&の位置を変えてみた
```
A{
 _::-webkit-full-page-media,_:future,:root &CSSクラス名{
 内容
 }
}
※CSSクラス名の前に置いてみた
```
#####結果:これも効かない:no_good_tone1:
<hr>
#####③Sassの入れ子の外に出してみた
A{
&~{
   }
}
_::-webkit-full-page-media,_:future,:root .CSSクラス名{
 内容
 }
###結果:効いた:ok_woman_tone1::raised_hands_tone1:

他に方法はあったかもしれませんが、今回はこの方法でいきました。


##終わりに
以上です！
ブラウザごとに見え方が違うと焦りますが、対処法は用意されているので学んでいきましょう！この記事もプログラミングを勉強している人の手助けになれば嬉しいです！
AWS CLI 2.1.28 で 'ascii' codec can't encode characters

CodeBuild から AWS CLI の ```aws lambda update-function-code``` を実行したら、2 バイト文字に関するエラーがでました。

AWS CLI のバージョン 2.1.28 で発生しており、一つ前の 2.1.27 では発生していませんでした。

```
aws --version
aws-cli/2.1.28 Python/3.8.8 Linux/4.14.214-118.339.amzn1.x86_64 exec-env/AWS_ECS_EC2 exe/x86_64.amzn.2 prompt/off
```

```
aws lambda update-function-code --function-name $LAMBDA_FUNCTION_NAME --image-uri $REPOSITORY_URI:$CODEBUILD_RESOLVED_SOURCE_VERSION
{
    "FunctionName": "abcdefg",
    "FunctionArn": "arn:aws:lambda:ap-northeast-1:000000000000:function:abcdefg",
    "Role": "arn:aws:iam::000000000000:role/abcdefg",
    "CodeSize": 0,
    "Description": 
'ascii' codec can't encode characters in position 1-11: ordinal not in range(128)
```

Description には、日本語を入れているので、その扱いがうまくいってない様子。

差分をみてみると、依存する Python が 3.8 に変わったようです。
https://github.com/aws/aws-cli/compare/2.1.27...2.1.28

環境変数 Lang や PYTHONIOENCODING を設定してみたものの、効果なし。

```
export LANG=ja_JP.UTF-8
export PYTHONIOENCODING=utf-8
```

AWS CLI が今後対処してくれるかもしれないのと、この AWS CLI コマンドの出力に重要なものがなかったことから、--query オプションを追加して、Description を出力しないように回避しました。

```
aws lambda update-function-code --function-name $LAMBDA_FUNCTION_NAME --image-uri $REPOSITORY_URI:$CODEBUILD_RESOLVED_SOURCE_VERSION --query 'Configuration.{LastModified:LastModified}'
```
React.js material-uiでアニメーション@keyframesを設定する方法

# React.js material-uiでアニメーション@keyframesを設定する方法

自分が設定する時に資料を掘って少し面倒だったので、メモとして残しておきます。
選定として`React.js`のフレームワーク`material-ui`を使っています。

まずは下記コンポーネントを作成します。
今回はこの`<Box className={ classes.circle } />`をくるくる回転させるアニメーションを作成します。

```react
import { Box } from '@material-ui/core';

export default function SpliCircle(props) {
  const classes = useStyles(); // ここは後述します
  return (
		<Box>
			<Box className={ classes.circle } />
		</Box>
  );
}
```

## cssの設定

結果はこちらです。

```react
import { makeStyles } from '@material-ui/styles';

const useStyles = makeStyles((theme) => ({
	circle: {
		width: 100,
		height: 100,
		backgroundColor: theme.palette.primary.main,
		animation: `$spin infinite 200s`
	},
	'@keyframes spin': {
		'0%': { transform: 'rotate(0deg)' },
		'100%': { transform: 'rotate(360deg)' }
	}
}));
```

まずはアニメーションさせたい対象に

```
animation: `${animation名} infinite 200s` 
```
と `${animation名}`と書きます。(他は基本のcssと同じ書き方です)
その後アニメーションの詳細はクラス定義と同じように書きます。

```
'@keyframes {animation名}': {
  {animationの内容}
}
```


これだけです。
書き方が分かれば難しいことは一切ありませんので、これだけ覚えれば困りません。

## ちなみに
`<stle=''>`タグにアニメーション用cssを書き込んでしまう、という手もありますが、material-uiではそれを推奨していません。
（まぁ`makeStyles`を作っているんですから当然こっちを使ってほしいに決まっていますよね。＾＾；）
一応そのように記述しておきます。



「書き方ちゃうよー」などございましたら、ご指摘お待ちしておりますm(_ _)m
デバッグについての話　2021/2/23　

#Facebook APIのアクセストークンのタイプや有効期限を確認する方法

Facebook APIで使用するアクセストークンのタイプや有効期限を確認する方法についての話。

###アクセスデバッガーでタイプや有効期限を確認

Facebook開発者ツールの[アクセストークンデバッガー](https://developers.facebook.com/tools/debug/accesstoken/)を開き、対象のアクセストークンを入力して「デバッグ」を押すと、アクセストークンの取得者や有効期限、タイプ、紐付いたアプリIDなどの情報が確認できます。

アクセストークンを入力後デバッグを押すとこんな感じになります↓↓

![スクリーンショット 2021-02-24 11.08.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965206/7b0a7908-bbe5-4f6f-9819-62a1b7e3738d.png)
ユーザ管理 ⇒ 新規ユーザの追加

１．ユーザ名にはどのような要件がありますか?
２．ユーザを作成するときにできることは何ですか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/7a7c6071-58d5-84b9-cb77-264a1c7e5742.png)
PostgreSQL: レコードが無いときinsert、有るときupdateするにはon conflictを使う

PostgreSQLでprimary keyに該当するレコードがまだ無いときは`insert`し、すでに有る場合は`update`するクエリを紹介します。

MySQLでいうところの`INSERT ... ON DUPLICATE KEY UPDATE`です。

PostgreSQLで、 レコードが無いとき`insert`、有るとき`update`するには`on conflict`を使います:

```sql
insert into product (id, name) values (1, 'item 1')
on conflict on constraint product_pk
do update set name='item 1';
```

## ちょっとした説明

productテーブルには`id`カラムがあります。この`id`カラムにはprimary key制約がついていて、その制約名が「product_pk」です。`on conflict on constraint`は「制約に引っかかったとき」という意味です。ここでは、`product_pk`制約に引っかかったとき、つまり、`insert`しようとして`id`が重複していたときに、何かするという意味になります。この何かするの部分が`do`以降の`update`句の内容になります。その`update`句では`name`カラムだけ更新するようになっています。したがって、クエリの意味をまとめると、「IDを指定してレコードを追加するんだけど、もしIDがすでに存在するなら、nameだけ更新してね」ということになります。

## 豆知識

条件に応じて`insert`と`update`を使い分ける処理は、俗に`update`と`insert`の造語として「upsert」と呼ばれます。

## 実行例

```sql
-- テーブルを作ります。product_pk制約も同時に作れます。
create table product 
  (id serial not null constraint product_pk primary key, 
   name varchar);

-- 初回のinsert
insert into product (id, name) values (1, 'product name')
  on conflict on constraint product_pk
  do update set name='product name';

-- テーブルの中身を確認
select * from product;
--  id |  name
-- ----+--------
--   1 | product name
-- (1 row)

-- 二回目のクエリ
insert into product (id, name) values (1, 'new name')
  on conflict on constraint product_pk
  do update set name='new name';

-- テーブルの中身を確認
select * from product;
--  id |  name
-- ----+--------
--   1 | new name
-- (1 row)

-- エラーにならず、nameだけ変更され、行は増えてないことが分かります。
AWSのAI/MLサービス一覧（2021年2月現在） 


AWSに存在するAI、機械学習関連のサービス（2021年2月現在）を整理してみました。

## 自然言語
### Amazon Translate
深層学習技術による言語翻訳サービス。
55言語の間での翻訳をサポートしており、日本語にも対応している。カスタム用語集を使用することで、特定の組織や分野、業界における独自の用語も翻訳することが可能。

### Amazon Comprehend
自然言語のテキストファイルからキーフレーズ・場所・人物・ブランド・イベントの抽出や、テキストが肯定的か否定的かの判定、またテキストファイルをトピックごとに自動的に整理することが出来るサービス。
Amazon Comprehend AutoML機能を用いて、組織のニーズに合わせて独自にカスタマイズしたエンティティや分類モデルを構築することも可能。

### Amazon Comprehend Medical
自然言語の医療データから、健康状態や投薬、服用量など様々な情報を抽出するサービス。
医療情報のプライバシーやセキュリティについて定めたHIPAA法に対応している。

### Amazon Textract
高度なOCR機能を提供するサービス。
スキャンしたドキュメントから文字を自動抽出する。表やフォームを認識、理解するため高精度に抽出が可能。


## 音声
### Amazon Lex
音声やテキストによる対話型インターフェースをアプリケーションに組み込むサービス。
Amazon Alexaに採用されている深層学習技術を用いてチャットボットや音声アシスタント等の構築が可能。

### Amazon Polly
文書をリアルな音声に変換するサービス。
テキストの読み上げができるアプリケーションを構築できる。また、ブランド音声という機能を使うと独自の音声による読み上げが実現可能。日本語にも対応。

### Amazon Transcribe
深層学習技術により音声をテキストに変換するサービス。
カスタマーサービスの通話の文字起こしや、字幕の自動生成、メディアコンテンツの検索可能なメタデータの生成などに利用できる。


## 画像 ・ 動画
### Amazon Rekognition
深層学習技術により画像および動画の様々な分析を行うサービス。
画像や動画内の物体へのラベリングや、テキストの検出、不適切なコンテンツの検出などが可能。顔の分析においては、顔検出や顔認証、顔の検索、感情や性別・年齢・目の大きさ等の特徴の分析といった様々な機能が存在する。


## 時系列予測
### Amazon Forecast
時系列データとその他付加的なデータをもとに予測を行うサービス。
製品の需要、リソースのニーズ、財務業績といった将来のビジネス成果の予測に利用が出来る。


## 推薦
### Amazon Personalize
リアルタイムにパーソナライズされたレコメンデーションを実現するサービス。
独自にカスタマイズされた機械学習モデルのトレーニングやデプロイに加え、データ処理や特徴の識別といった機械学習パイプラインの全体を管理できる。


## 検索
### Amazon Kendra
企業内の複数のリポジトリに分散する様々なテキストデータをインテリジェントに検索するサービス。
自然言語での質問から適切な回答を見つけることが可能。


## 不正検知
### Amazon Fraud Detector
オンラインにおける不正行為を検知するサービス。
不正検出モデルの構築やトレーニング、デプロイのすべてを自動化する。独自データセットによりカスタマイズされた不正検知モデルの構築が可能。


## 開発支援
### Amazon CodeGuru
開発するアプリケーションのコードに潜むバグや脆弱性の発見、アプリケーションのパフォーマンス改善方法の提案を機械学習により自動的に行ってくれるサービス。


## MLワークフロー
### Amazon SageMaker
学習データの準備からモデルの構築、学習、デプロイといった機械学習のパイプライン全体で必要なあらゆる機能を提供する包括的なサービス。
SageMaker Studioという専用の統合開発環境（IDE）も存在し、SageMakerのあらゆる機能を統一したUIインターフェースで利用可能。

### Amazon SageMaker Ground Truth
学習用のデータセットを構築するために人よるデータのラベル付けワークフローを提供するサービス。
組み込み済みのワークフローには3D点群、動画、画像、テキストなど様々なユースケースがサポートされており、独自のワークフローを作成することも可能。自動のラベル付け機能も備えており、ラベル付けの負担を軽減することができる。

### Amazon SageMaker Neo
学習済みモデルのパフォーマンスをエッジデバイスやSageMaker環境に最適化するサービス。
エッジデバイスにおいてはハードウェアプラットフォームを選択し、そのハードウェアプラットフォームに対する最適化が行われる。SageMaker Neoの内部では機械学習コンパイラのApache TVMが利用されている。

### Amazon Augmented AI (Amazon A2I)
機械学習アプリケーションの予測結果に対して、人によるレビューのプロセスを組み込むためのサービス。
予測をランダムにサンプリングしてモデルのパフォーマンスを定期的にチェックしたり、信頼度の低い予測には人によるレビューを通してからクライアントアプリケーションに返答することが可能となる。
情報処理安全確保支援士試験のセキュアプログラミングの暗記事項

情報処理安全確保支援士試験では午後Ⅰの3問中1問は必ずセキュアプログラミングの問題が出題されます。しかし、セキュアプログラミングの問題は選択する人が少ない様で、あるIT資格系の書籍やセミナーで有名な方のセミナーで情報処理安全確保支援士試験(以下SC試験)の受験者の実に75％の受験者は選択しないと聞きました。言語はC++/Java/ECMAScript(JavaScript)のどれかが使われた問題が出題されることになっており、どの言語が出題されるかは試験に臨むまで分かりません。しかし、裏を返せば25％の人はセキュアプログラミングを選択して合格していることになります。実際に勉強してみると上記3つの言語の基本文法が分かっていれば問題を解くのに支障が無いことが分かりました。この点は基本情報技術者試験の言語問題とは異なります。また、出る脆弱性の内容も決まっている為、覚えなければならないことも他のセキュリティの分野と比較して少ないと言えます。故に暗記事項をまとめておこうと思います。

※ プログラミングの問題の難易度は
~~FEのアルゴリズム > FEの言語問題(選択) > SCのセキュアプログラミング > APのアルゴリズムと言うのが筆者の印象です。(研究中なので断定は出来ません)~~

2021/4/13修正:

FEのアルゴリズム > FEの言語問題(選択) > APのアルゴリズム > SCのセキュアプログラミング

研究の結果SCのセキュアプログラミングはCアレルギーやJavaアレルギーが無ければパターンを掴むだけで得点源に出来る可能性が有るというのが筆者の印象です。
(FE:基本情報、AP:応用情報、SC:安全確保支援士)


# 代表的な攻撃パターン
* XSS(Cross Site Script)脆弱性を突いた攻撃
    * 反射型XSS(Reflected XSS)、格納型XSS(Stored XSS)、DOMベースのXSS(DOM Based XSS)
    * 注意する箇所 : 動的にHTML文を生成する処理を行う部分
    * 対策 : SQL文中にプレースホルダを用いる
    * 対策2 : サニタイジング(出力文字列をエスケープ処理し無害化)
    * 対策3 : javascript://などの文字列の除去
* SQLインジェクション脆弱性を突いた攻撃
    * 注意する箇所 : 文字列連結などを使用して動的にSQL分を生成する処理を行う部分
    * 対策 : DBMSバインド機構を利用してSQL分を生成する方法が有効
* CSRF(Cross Site Request Forgery)脆弱性を突いた攻撃
    * 注意する箇所 : パラメタ(特に認証情報など)の受け渡しが伴う画面遷移
    * 対策 : POSTメソッドによるアクセスのみを用いる
    * 対策2 : 乱数などをHTMLフォーム内のhidden属性に埋め込み受信側で検証
    * 対策3 : CAPTCHAを用いる
* BOF(Buffer Over Flow)攻撃
    * 注意する箇所 : データサイズを指定せずに変数や配列に代入、コピーを実行する関数の呼び出し部分
        * 関数の例 : gets, sprintf, strcpy, strcat, etc...
    * 対策 : データサイズを明示的に指定する関数を用いる
        * 関数の例 : fgets, snprintf, strncpy, strncat, etc...
    * 対策2 : DEP(Data Execution Prevention), ASLR(Address Site Layout Randomization)を有効化
    * 対策3 : C/C++をそもそも使わない(他の言語を用いる)
* Return-to-libc攻撃
    * C/C++の標準ライブラリ関数system関数を用いて任意のOSコマンドを実行する攻撃
    * DEPによる対策では防げない
    * ASLRを有効化することで攻撃実行を困難に出来る

# 暗記事項

|用語|説明|
|---|---|
|スタック領域 / ヒープ領域 / テキスト領域|C/C++におけるメモリ上でのプログラムの管理領域<br>スタック領域 : ローカル変数、実引数、呼び出し元の番地などを格納<br>ヒープ領域 : 動的メモリ確保時に利用<br>テキスト領域 : 実行コードを格納<br>ヒープ領域はメモリの下位番地～上位番地に向かって、スタック領域は上位番地～下位番地という方向でメモリを利用|
|リトルエンディアン / ビッグエンディアン|プロセッサでの数値の扱い方<br>リトルエンディアン : メモリの上位アドレスを下位桁に格納(IntelのCPUはリトルエンディアン)<br>ビッグエンディアンはメモリの上位アドレスを上位桁に格納|
|DEP(Data Execution Prevention)|指定されたメモリ領域(ヒープ領域やスタック領域)でプログラムコードの実行を防止する技術(Return-to-libcには効果が無い)<br>DEPを有効にすることで得られる効果を問う出題が過去に数度有った|
|SSP(Stack Smashing Protection)|スタック領域でカナリア(canary)と呼ばれる値を利用してスタックBOFの有無を確認する技術<br>BOFが発生するとcanaryの値が書き変わってしまうため検知できる<br>コンパイラが対応していない場合は使えないということを問う出題が過去に有った(H30年秋問1)|
|ASLR(Address Space Layout Randomization|プログラム実行時にデータ領域、ヒープ領域、スタック領域およびライブラリをランダムにメモリ中に配置するOSの技術|
|PIE(Position Independent Executable)|プログラム実行時にASLRが対象とする領域に加えて、テキスト領域もランダムにメモリ中に配置する技術|
|Automatic Fortification|バッファオーバーフロー脆弱性の原因となりうる脆弱なライブラリ関数をコンパイル時に境界チェックを行う安全な関数に置き換える技術(但し対応しているコンパイラでのビルドが必要)|

# Reference
[1] 情報処理安全確保支援士 ALL IN ONE 2021 第5章
[2] 情報処理安全確保支援士午後問題の重点対策 2020 第7章
40代おっさんEC2を勉強してみた

#40代おっさんEC2を勉強してみた

##本記事について
本記事はAWS初学者の私が学習していく中でわからない単語や概要をなるべくわかりやすい様にまとめたものです。
もし誤りなどありましたらコメントにてお知らせいただけるとありがたいです。

##目標
EC2の理解を深める。


##EC2とは
Amazon Elastic Compute Cloud (Amazon EC2) は、安全でサイズ変更可能なコンピューティング性能をクラウド内で提供するウェブサービス
　わかりずらい・・・
つまりAWSの仮想サーバーサービスのことみたいです。

##EC2の前提知識
###仮想サーバーとは
まずはサーバーを説明します。
サービスを提供する側のコンピューターのことを指します。
これは簡単ですね
では仮想サーバーとはそのサーバーの上に仮想的にサーバーがあるものとして作り、仮想サーバーとして運用するもの見たいです。
つまり一つのコンピューターに仮想的にサーバーを何個も作ることができます。

###サーバーに必要なもの
*以下の各要素ですが、IPAが主催する情報処理技術者試験の基本情報項目でも出題される範囲
####OS
これは聞いたことがあるのでないでしょうか？
代表的なものとしてWindows,macOS,Linuxなどそれにあたります。
つまり、システム全体を管理し、さまざまなアプリケーションソフトを動かすための最も基本的なソフトウェアのことです。
####CPU
パソコン上のハードウェアやソフトウェアから受け取る全ての指示を処理するパーツのこと
####Memory
データを記憶する部品のことです。
気を付けないといけないのは記憶する部品は２つあり、
読み書き両方できるRAM（基本的にはRAMは電源が消えるとデータが消えます。作業領域を表す）
読み出し専用のROM（保存領域を表す）があります。
一般的にはRAMがMemoryにあたります。
####SSD
こちらは先ほどのROMの部分に当たります。SSDのほかにHDDがあり、SSDは読み込み速度が速く、高価、HDDはSSDより読み込み速度が遅いですが、大容量で安価であると言うメリットがあります。
####NIC
来ましたNICなぜか苦手意識が・・・・
ネットワークカード (NIC)インターネットをするときにパソコンにつなぐ線（LANケーブル）を挿す穴がくっついている、パソコンに合体させる部品のこと
あれ簡単？？
でもね・・・じつは・・・
NICにはパソコンとネットワークを送受信したデータを変換するといった大事な役割が・・・
ここらへんを説明するとたぶん一つの記事にしないといけないのですいませんがここは割愛させてください・・・

###仮想サーバー（AWSのサービス）
####OS　→　AMI
AMIとは
AMIはインスタンスの作成に必要な情報
Amazonマシンイメージで色々なOSパターンを選ぶことができます。
ちなみに色々とはOSだけでなくソフトウェアが搭載されたものあるみたいです。
これは実際に作りながら見たほうが良いと思います。
####CPU,Memory →　インスタンスタイプ
インスタンスタイプとは
インスタンスタイプはさまざまな CPU、メモリ、ストレージ、ネットワークキャパシティーの組み合わせによって構成されている。
つまり、自分のやりたいことに合わせて色々選べるみたいです。
例　t2.micro
tはファミリー名
数字は世代番号
microはインスタンスのサイズ
を表す
詳しくは
https://qiita.com/kou551121/items/5cb3e4b84ecd35d7580e

####SSD →　EBS
EBSとは
EC2の仮想的に外付けされるような記憶領域になります。
詳しくは
https://qiita.com/kou551121/items/64665b1804c1badd2f7a
####NIC →　ENI
ENIとは
AWSのネットワークインターフェースを設定するためのサービス
サーバーの役割にお応じてIPを振り分けたり、異なるセグメント間で1台のサーバーを動作させたりすることができるみたいです。（セブメントとは軽く言うとサブネットみたいなものだと認識してます。間違っていたらすいません。）
###ユーザーデータ
初回起動時する際に実行するスクリプト（再起動するときは実行されない）
実行権限はrootユーザー権限
ユーザーデータはシェルスクリプト形式（＃！で始まる）ものとcloud-init形式（#cloud-configで始まる)で書くことができる

###Instance Meta Data
インスタンスの中に埋め込まれデータを指します。
例）
　・EC2のIPアドレス
　・EC2のホストネーム
　・EC2が使用しているAMIのID番号
　　　　　　　　　　　　　　　等々

###キーペア
EC2へログインするために使用する秘密鍵、公開鍵のペアのこと

####公開鍵
公開鍵で暗号化したデータは秘密鍵でしかあけることができない
（EC2のログイン情報を公開鍵で暗号化する）
AWSでの公開鍵はAWSが保管している
####秘密鍵
公開鍵で暗号化したデータを開ける鍵（これが盗まれるとEC2にログインできてしまうので、外部からアクセスできないところに置く）
XXX.pemの形式ファイルになっている

##最後に
う～～ん、わかったようでわからないですよね・・・
たぶん作りながらでないとわからないと思います。
今度は実際にEC2を作成して記事に上げたいと思います。

またこの記事はAWS初学者を導く体系的な動画学習サービス「AWS CloudTech」の課題カリキュラムで作成しました。
https://aws-cloud-tech.com/
Kubernetes + Nginx Ingress Controller + Nextcloud で1MB以上のアップロードに失敗する場合

Nextcloudへのファイルアップロードで以下のエラーが発生
(管理画面のログから確認)

```
Exception: Call to undefined method OC\DB\ConnectionAdapter::getParams()
```

原因：nginxのアップロードサイズが1MBになっているため
解決方法：ingressのannotationに以下を追加

```diff
+　nginx.ingress.kubernetes.io/proxy-body-size: 1000m
```
FirebaseAuthentication.net 3.6.0 リリース

Google が提供するアプリのプラットフォーム Firebase のうち、認証機能を C# から利用できるようにした FirebaseAuthentication.net というプロジェクトがあります。Nuget からも取ってこれます。

https://github.com/step-up-labs/firebase-authentication-dotnet

```c#:sample
var authProvider = new FirebaseAuthProvider(new FirebaseConfig(FirebaseApiKey));
var facebookAccessToken = "<login with facebook and get oauth access token>";

var auth = await authProvider.SignInWithOAuthAsync(FirebaseAuthType.Facebook, facebookAccessToken);

var firebase = new FirebaseClient(
  "https://dinosaur-facts.firebaseio.com/",
  new FirebaseOptions
  {
    AuthTokenAsyncFactory = () => Task.FromResult(auth.FirebaseToken) 
  });

var dinos = await firebase
  .Child("dinosaurs")
  .OnceAsync<Dinosaur>();
  
foreach (var dino in dinos)
{
  Console.WriteLine($"{dino.Key} is {dino.Object.Height}m high.");
}
```


　C# のプログラム開発の際、認証機能を Firebase に任せて必要な機能に集中できるので、この FirebaseAuthentication.net は重宝していたのですが、先月末にリリースされた 3.5.0 には SignInWithEmailAndPasswordAsync 関数にバグが含まれていため、Email 認証が利用できませんでした。
　一つ前のバージョン 3.4.0 は正常に機能するため、このバージョン指定で動作させていたのですが、先週、2月19日に、このバグだけを Fix した FirebaseAuthentication.net 3.6.0 リリースされました。

https://github.com/step-up-labs/firebase-authentication-dotnet/pull/136

3.5.0 を使われていた方は 3.6.0 にアップデートしましょう。
【初学者向け】S3整合性モデルのアップデートについて【AWS SAA】

こんにちは。

現在、クラウドエンジニアもしくはクラウドサービスを利用したサービスに携わりたい一心で、目下AWS SAAの取得に向けて勉強中です。

最近になってようやく模擬試験を解き始めて、アウトプットとインプットを繰り返す毎日ですが、参考書の出版時から現在に至るまでにサービスの特性が変わっている事がよくあります。

今回は、AWSの主要サービスであるS3の整合性モデルについて備忘録的に書き記したいと思います。


<h1>〜結果整合性モデルから強い整合性モデルへ〜</h1>
従来のS3の整合性モデルは結果整合性モデルを採用しており、オブジェクトをアップロードしてもタイミングによっては古いデータを読み込んでしまう可能性がありました。

しかし、S3のアップデートが実施されたことにより、2020年12月3日より強い整合性モデルへと変更になりました。

これにより、今までと違ってアップロードをして書き込み処理で更新または削除を行った場合でも即時に結果が反映されるようになりました。

<h2>〜参考書ベースで勉強している方へ〜</h2>
Udemyやその他Webサービス上での学習ツールを使って勉強している方は、常に情報が更新されているためサービスのアップデート内容について把握している人が多いと思います。

しかし、紙の参考書をベースに勉強している方は中身が古い情報のままなので注意が必要です。
特に今回のアップデートは2020年末とまだ新しいため、都度AWSの公式サイトなどで情報を仕入れる事をオススメします。

以上、S3整合性モデルについての備忘録でした。

参考サイト
https://aws.amazon.com/jp/blogs/news/amazon-s3-update-strong-read-after-write-consistency/
jqコマンドで、JSON、JSONL形式をCSV形式に変換する

# はじめに
JSON形式(JSON,JSONL)からCSV形式への変換をたまに必要としますが、毎度忘れるのでまとめておこうと思いました。

## JSON形式からJSONL形式に変換
```bash
jq -c '.[]' input.json > output.jsonl
```

## JSONL形式からJSON形式に変換
```bash
jq -s '.' input.jsonl > output.json
```

## JSON形式からCSV形式に変換
```bash
cat output.json | jq -r '.[] | [.col1, .col2, .col3, .col4, .col5, .col6, .col7]|@csv' > json_to_csv.csv
```

## JSON形式からCSV（ヘッダー付き）形式に変換
```bash
cat output.json | jq -r '(map(keys) | add | unique) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $cols, $rows[] | @csv'  > json_to_csv_header.csv
```

# 参考
以下のサイトを参考にさせていただきました。問題ありましたらご連絡ください。

https://ex-ture.com/blog/2020/04/15/learn-jq-command-with-covid-19-data/

https://gist.github.com/sloanlance/c3bf746b6396f60d321f5535e1ced892
GASでトリガーを作成する際の注意点

#GASでトリガーを作成する際の注意点

GASで任意の日時にトリガーを作成するファンクションで
詰まったことがあったのでメモ。

任意の日付にトリガーを作成

```JavaScript:setTrigger.gs
function setTrigger(){
  var trigger = new Date();

  //トリガー設定時間
  trigger.setHours(10);
  trigger.setMinutes(00);
  
  //セットしたトリガーの時間を確認
  console.log(trigger);
  //起動させたいfunctionを設定
  ScriptApp.newTrigger('test_func').timeBased().at(trigger).create();    
}
```

実行した結果はこちら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1098816/331e05b4-9e9d-5493-db08-81fb578eddf6.png)


ふむ、見た感じは想定してる時間でログが出てる。


実際に作成されたトリガーがこちら。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1098816/332c455f-016a-6fe7-4ec5-d3228bb86e07.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1098816/26234cfa-c7af-bc47-f1e2-47a920b941d3.png)


むむ？トリガーの起動時間がおかしい。。。


まずは設定する前の現在時間をログに出してみよう。
※現在時刻 10:00

```JavaScript:setTrigger
function setTrigger(){
  var trigger = new Date();
  
  //とりあえず何も編集しない時間を確認
  console.log(trigger);  
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1098816/2a8aab2f-7385-66d3-aa43-b8f0dec2d7af.png)



あれ？全然違う時間が表示されたぞ。
というか右のタイムゾーンが日本時間になっていない。。。

appsscript.jsonをエディタで表示にチェックを入れてタイムゾーンを確認してみよう。
※プロジェクトの設定からチェックを入れることで確認できます

![図13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1098816/bf42fe3a-876b-fb0f-4aab-7ad01de40ca3.png)

やはりtimeZoneが日本時間になっていない。。

```json:appsscript.json
{
  "timeZone": "America/New_York",
  "dependencies": {
    "enabledAdvancedServices": [
      {
        "userSymbol": "Drive",
        "version": "v2",
        "serviceId": "drive"
      }
    ]
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8"
}
```

ということでタイムゾーンを以下のように日本時間に変更します

```
"timeZone": "Asia/Tokyo",
```


では実際にログを出力してみよう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1098816/d6440c3d-dc65-83e3-91ec-e168845cbc7a.png)

うん！想定通りで日本時間になってる！

では10:15に時間をセットして最初に記述したsetTrigger.gsを起動してみます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1098816/890da808-8e23-8d51-0f11-cec102edff48.png)

想定通りの時間でトリガーが作成されている。
あとは正常に起動するのを確認するだけ。

![図15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1098816/0208ee07-3e02-dc71-3e75-bfdb9c25d9ca.png)

よし！正常に稼働してる！
これで好きな時間に毎月任意の時間にファンクションを起動させる等が可能になります！

意図しない時間にトリガーが作成されたらまずはタイムゾーンを確認しましょう。