OmniAICreator/Qiita-1.07M huggingface dataset:
統計検定準1級の勉強は機械学習に役立つ

こんにちは。スキルアップAI編集部です。
本ブログでは、機械学習をする上で統計検定準1級の勉強が役立つ理由について解説します。

＜目次＞
1.統計学と機械学習の関係性
2.統計検定とは
3.準1級について
4.統計学の試験なのになぜ機械学習に役立つのか
5.おわりに

# 1.統計学と機械学習の関係性
統計学はデータを要約したり解釈したりする上での『説明』を目的としています。一方で、機械学習はデータを用いた『予測』を目的としています。この二分野はともにデータを活用して目的を果たす学問であるため、親和性が非常に高いです。回帰分析のように、統計的手法を機械学習に持ち込んだ例もあります。機械学習は統計学の応用分野的な立ち位置であると考えることもできます。

# 2.統計検定とは
「統計検定」は、統計に関する知識や活用力を評価する全国統一試験、とされています。統計検定2級は大学1、2年教養レベルであり、統計検定1級は大学専門課程(3,4年次）修了レベルです。1級があまりにも難しく、2級と1級のレベル差が大きいため、その中間の準1級が橋渡し的な役割で2015年に新たに登場しました。

# 3.準1級について
準1級の合格率は20%ほどで、やや難しい試験であることがわかります。統計検定公式サイトによると、「統計検定準1級は、2級までの基礎知識をもとに、実社会の様々な問題に対して適切な統計学の諸手法を応用できる能力を問うもの」とされています。この文言の通り、難解な積分計算が多く専門的で深い理解が必要な一級と比べ、準一級は幅広い知識を必要とし、実社会への応用に重点を置いた問題が多いです。

![statistics_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889700/f833d2f6-4613-6137-b390-4a4428102a69.jpeg)
（出典：[統計検定公式サイト](https://www.toukei-kentei.jp/about/grade1semi/)）

# 4.統計学の試験なのになぜ機械学習に役立つのか
- 準1級は特に応用力を重視しているため、統計学の応用分野とも言える機械学習領域の出題が多い傾向にあります。
- 出題範囲が広いため普段あまり使ってこなかった統計的手法、機械学習手法にも触れることができ、機械学習を行う際の視野が広がります。
- 今までpythonやRなどの既存ライブラリに任せていた計算を自分の手で行うことで、曖昧だった理解が鮮明になります。

![statistics_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889700/9e79795a-6554-b861-c947-0825c5d00b31.png)

![statistics_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889700/578dfee4-8f5f-222d-f38c-3c826be2cde7.png)
自己符号化器やPCAなどの機械学習領域の出題例
（ 統計検定準一級試験内容 出典：[統計検定公式サイト](https://www.toukei-kentei.jp/about/grade1semi/)）

以上の理由から、統計検定準1級の勉強は機械学習に役立ちます。

# 5.おわりに
統計検定準1級は最近CBT化され、様々な地域でいつでも受験できるようになりました。また、公式の過去問集やワークブックも発売され、対策がしやすい環境になってきています。ぜひ受験してみてください。

スキルアップAIでは、「[統計検定2級®対応 統計分析基礎講座](https://bit.ly/3tiaI9M)」を開講中です。本講座では、データから現状を把握するための可視化手法・各種統計量の確認方法、適切なデータの収集方法および仮説の構築と検証を行うための基礎理論について学びます。是非ご検討ください。

参考サイト
統計検定公式サイト：[https://www.toukei-kentei.jp/](https://www.toukei-kentei.jp/)

# 25卒向け！AIエンジニアになるための長期インターンプログラム参加者募集中！
25卒学生向けに、AIの基礎を学びながら就活も一括サポートする無料カリキュラムを提供しています。
修了するとE資格の受験資格も獲得できるプログラムとなっています！

<img width="700" alt="長期インターン" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889700/bfce4c26-1ebe-c54d-bacb-e804048a7a08.png">

**特長①AIエンジニアやデータサイエンティストの基礎が身に付く**
AIジェネラリスト基礎講座や機械学習のためのPython入門講座など、市場価値向上のための基礎を習得。

**特長②AI・データ分析領域の優良求人を紹介**
非公開求人や選考直結型インターンをご紹介し、早期内定の獲得をサポート。

**特長③長期インターンプログラム専用の学生コミュニティ参加可**
学生同士で就活情報をシェアしたり、学習を進めるうえでアドバイスをしあったりできるコミュニティに参加可能。

＞＞[長期インターン詳細](https://bit.ly/3pXW5JM)

☆☆☆
スキルアップAIのメールマガジンでは会社のお知らせや講座に関するお得な情報を配信しています。
配信を希望される方は[こちら](https://share.hsforms.com/1_XlReV-4Te-zcxCl9lhffA2mtef)

また、SNSでも様々なコンテンツをお届けしています。興味を持った方は是非チェックしてください♪
Twitterは[こちら](https://twitter.com/SkillupAi)
Facebookは[こちら](https://www.facebook.com/skillupai)
LinkedInは[こちら](https://www.linkedin.com/company/skillup-ai)
スキルアップAI公式YouTube AIビジネスチャンネルは[こちら](https://www.youtube.com/AIBusinessChannel)
Git Hubにてcherry-pick

## 概要
一度pushしたものをrevertにて取り消した。
しかしそれを取り消すことになった。
logが汚れてしまう気がしてどうにかならないかなーと思いcherry-pickで対応しました！

## 対応方法
現ブランチからmain(master)に戻りブランチを切ってcherry-pickを使用する流れです。
```
git log
```
をターミナルにて打ち込むとcommitの履歴が出てきます。

```
git cherry-pick [git logでpushしたいcommitのUUIDの様な英数字の文字列を指定]
```

commitはされた状態なのでpushを行います。
```
git push origin [ブランチ名]
```

## 結果
logから無駄なrevertが無くなりました。
色々と汎用性がありそうです。
railsのform_withにおけるselectメソッドの初期値設定方法

## 概要

form_withにおけるselectメソッドの初期値の設定方法が地味に迷ったのでまとめます。

## 初期値設定方法について

初期値設定方法は大きく２つあります。

### options_for_selectを使う方法

```ruby
# bが選択される
= f.select :hoge, options_for_select(["a","b","c"], selected: "b")
```

### options_for_select を使わない方法
```ruby
# bが選択される
= f.select :hoge, ["a","b","c"], { selected: "b" }
```

## 注意点

### 失敗例

これだと失敗する。

```ruby
# aが選択される
= f.select :hoge, [["a", 1],["b", 2],["c", 3]], { selected: "b" }
```

### 解決策

選択肢が二次元配列で渡されている場合（１つの選択肢が複数の要素を持っている場合）、最初の要素がページ上に出力され、最後の要素がoptionタグのvalueに設定されるため、最後の要素で指定する必要がある。（2~n-1番目(n >= 3)の要素はどこにも使われない）

```ruby
# bが選択される
= f.select :hoge, [["a", 1],["b", 2],["c", 3]], { selected: 2 }
```

```ruby
# bが選択される
= f.select :hoge, [["a", 2, 1],["b", 3, 2],["c",　1, 3]], { selected: 2 }
```

## おまけ
クラスを付与する場合は以下のようになる
```ruby
# bが選択される
= f.select :hoge, [["a", 1],["b", 2],["c", 3]], { selected: 2 }, { class: ['hoge'] }
```
ローカル開発で通信中の状態を再現したい

ajax通信を行うWebサイトやアプリケーションの開発中に、ローカルのモックだとレスポンスが早すぎてネットワーク通信中のUIなどを確認できないという問題があったので、ローカルで通信中を再現するときに個人的にやっていることを書きます。

# Chrome DevToolsを使う

Chrome DevToolsのNetworkタブで3G回線やオフラインの状態を再現できるのは有名だと思います。
ネットワークの設定をカスタムから自分で設定することができ、設定の中にLatencyという項目に1000を入力すれば1秒間の遅延を再現できます。

![PixelSnap 2022-05-31 at 10.12.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531/df8a5f90-2d0f-afa5-3e86-46300b3471b8.png)
![PixelSnap 2022-05-31 at 10.13.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531/2ae26387-2021-b229-5ceb-9c0c357852f8.png)
この画面から追加すると以下のように使えるようになります。
![PixelSnap 2022-05-31 at 10.18.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531/8a81cdf8-78a3-6ac2-4a71-44e37f595f49.png)

タイムアウトのテストなどもやりやすいです。

後で紹介する方法と比べて、ソースコードをいじる必要がないので個人的にはおすすめです。
ただ、全ての通信に時間がかかるようになります。

他のブラウザの開発ツールでもできそうですが試していないのでわかりません。すみません。

# プログラム側で設定する

フロントエンドでもバックエンドでも、プログラムのどこかに遅延処理を入れることで再現できます。

例として、フロントエンドでsetTimeoutを使って再現する場合は以下のような感じです。

``` js
// API通信用のラッパー関数
const client = async (url, method = 'GET') => {
    await new Promise((resolve) => setTimeout(resolve, 1000))

    return await fetch(url, {
        method: method,
    })
        .then((response) => response.json())
        .then((data) => data)
}

const fetchData = async (url) => {
    // ローディングのUIを表示する処理
    const data = await client(url)
    // ローディングのUIを非表示にする処理
    console.log(data)
}

fetchData(`${testUrl}`)
```

ソースコードに書き込むので間違ってそのまま本番環境にデプロイしないように注意が必要です。
トランスパイルができる環境であれば、環境変数を使って出しわけするのが良いです。

``` js
if (process.env.NODE_ENV === 'develop') {
 await new Promise((resolve) => setTimeout(resolve, 1000))
}
```

モックを使って開発する時などは本番のコードを意識しなくても良いので、このようにソースコード内に書いてしまうことも多いです。
unittest Mockの使い方をメモ

# 背景
pythonのunittest.Mockの使い方をまとめておく

# 実装

## mockを引数経由で渡せる場合

#### 対象の実装

```py:domain/hoge.py
# obj.execute() が例外投げる場合、retry_countの回数だけ再実行するメソッド

class Hoge:
    def retry_with_error(self, obj, retry_count: int = 2) -> None:
        count = 0

        while True:
            try:
                obj.execute()
                return
            except Exception as e:
                count += 1
                if count > retry_count:
                    raise e
```

#### テストの実装


```py:tests/hoge_test.py
from domain import Hoge
import unittest
from unittest.mock import MagicMock


class TestHoge(unittest.TestCase):

    def test_retry_with_error(self):

        # execute()が1回だけ呼ばれることを確認
        mock = MagicMock()
        Hoge().retry_with_error(mock)
        mock.execute.assert_called_with() # 実行されることを確認

        # 初回のexecuteでException発生する場合は、retryする
        # 2回目のexecuteは例外を投げずに終了する
        # side_effectを使って動作を制御する
        mock2 = MagicMock()
        mock2.execute = MagicMock(side_effect=[Exception('first error'), None])
        Hoge().retry_with_error(mock2)
        self.assertEqual(mock2.execute.call_count, 2)

        # executeで毎回Exception発生する場合は、3回実行して例外投げる
        with self.assertRaises(Exception):
            mock3 = MagicMock()
            mock3.execute = MagicMock(side_effect=Exception('every time error'))
            Hoge().retry_with_error(mock3)
            self.assertEqual(mock3.execute.call_count, 3)


if __name__ == '__main__':
    unittest.main()
```

## クラスをMockする場合

#### 対象の実装

```py:app/fuga.py
from domain

# domain.Slackオブジェクトを呼び出す実装
class Fuga:
    def notify(self) -> None:
        domain.Slack().notify('title', 'text')
```

#### テストの実装

```py
from app import Fuga
import unittest
from unittest.mock import patch

class TestFuga(unittest.TestCase):

    def test_notify(self):
        # patch 定義で内部生成されるオブジェクトをmock化できる
        with patch('domain.Slack.notify', return_value=None) as mock:
            Fuga().notify()
            self.assertEqual(mock.call_count, 1)
```

# 参照

https://docs.python.org/ja/3/library/unittest.html

https://docs.python.org/ja/3/library/unittest.mock-examples.html

https://docs.python.org/ja/3/library/unittest.mock.html
Flow Troubleshooting  


元の質問 : [ヘルプ これが質問](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000HDX7ESAX)

# Fix Access Issues in a Flow

何もしないでいきなりチェックボタン。パッケージがないのかな？
違いました。

Sign up for a special Developer Edition (DE) org　特別版があるみたいです。

**We can't find the pre-installed flow named 'Alert Acct Owner of New Case Added'. Make sure you sign up for a special Developer Edition org, connect it to Trailhead, and use it for this challenge.**

特別版を作成して　チェックを押すと何もしないでも通過できました。

**We can't find the debug logs for the flow named 'Create a Case' associated with the user Mario Cruz. Make sure you enable the 'Let admins debug flows as other users' option and debug the flow with that user.**
次になにもしないで検証するとこのメッセージが出ます。

手順に従ってハンズオン Challengeの前まで実施しましたが、このエラーのままです。

------------------------------------------------------

Create CaseのパーミッションセットにMario Cruzを追加しただけの状態

**We couldn't find a new case with the subject 'Broken Laptop' generated by the flow. Make sure the flow is running successfully according to the requirements.**

# We can't find the debug logs for the flow named 'Create a Case' associated with the user Mario Cruz. Make sure you enable the 'Let admins debug flows as other users' option and debug the flow with that user.

+ [Trailhead - Fix Access Issues in a Flow](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000JgAME)

:::note
Weird workaround here but got it. The reason we are getting the "We can't find the debug logs for the flow named 'Create a Case' associated with the user Mario Cruz. Make sure you enable the 'Let admins debug flows as other users' option and debug the flow with that user." is because for some reason the debug log in Setup is not capturing the failed flow. All the challenge is looking for is someone called "Mario Cruz" to fail the flow. In order to do that:

-change your user name to Mario Cruz
-create a new required field on Case
-add Create Case flow to your homepage
-try to complete the flow signed in as yourself (now named Mario Cruz)
-intentionally do not add your new required field causing the flow to fail
:::

+ [Flows Troubleshooting > Fix Access Issues in a Flow: after following the steps in the challenge I am met with this error](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000JgAgjSAF)

:::note
I got it! rs, it was not the recommended way but it worked.

I followed this steps:

1 - I created a button that call the Create Case flow
2-  I logged as Mario Cruz 
3-  I created a Case by this new button
4-  Checked the Challenge with success.

https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000JgAMESA3
:::


# Fix Issues Caused by a Null Value in a Flow


:::note alert
We can't find the activated version of the flow named 'Alert Acct Owner of New Case Added'. Make sure the flow is activated according to the requirements.


「追加された新しいケースのアラート アカウント所有者」という名前のフローのアクティブ化されたバージョンが見つかりません。フローが要件に従ってアクティブ化されていることを確認してください。
:::

違うプレイグランドでチェックしてました。
interfaceとtypeの違いについて

# 概要
TypeScriptの超初心者の私が、チュートリアルで実際に簡単なアプリケーション制作する際に、型定義の方法として大きく2つあることを知りました。（※直書きを除く）
「interface」と、「type」になります。
初心者の私からすると、「何が違うんだ！？」という印象を持ちました。
なので、今回「interface」と「type」の違いについてまとめました。

# interface

interfaceは、***構造を定義するもの***になります。

```ts
interface Sample {
  name: string;
  age: number;
  isAdult: boolean;
}
const user: Samle{
  name: "taro";
  age: 10;
  isAdult: false;
}
```

# type（型エイリアス）

typeは、***型に対して名前をつけるもの***です。

```ts
type Sample　= {
  name: string;
  age: number;
  isAdult: boolean;
}
const user: Samle{
  name: "taro";
  age: 10;
  isAdult: false;
}
```

# interfaceとtypeの違い

|  違い  |  interface  |  type  |
| ---- | ---- | ---- |
|  拡張（上書きできるか）  |  ◯  |  ×  |
|  継承  |  ◯  |  ×  |


## ①拡張
interfaceでは、拡張することができますがtypeは拡張することはできないです。

### interfaceの場合

interfaceでは、拡張することが可能です。

```ts
interface Window {
  title: string
}

interface Window {
  ts: TypeScriptAPI
}

const src = 'const a = "Hello World"';
window.ts.transpileModule(src, {});
```

### typeの場合

typeを作成後に、型を追加することはできません。

```ts
type Window = {
  title: string
}

type Window = {
  ts: TypeScriptAPI
}

 // Error: Duplicate identifier 'Window'.
```

### ②継承
interfaceでは、interfaceやtypeから継承することができます。
一方typeは、継承することができません。

#### interfaceの場合

```ts
interface User{
  name: string;
  age: number;
}
interface Test extends User{
  English: number;
  Math: number;
}
const Student: Test{
  name: taro;
  age: 10;
  English: 50;
  Math: 80;
}
```

ただtypeも交差型を使用することで、継承に似たことは実現することは可能です。
ただ交差型では、型の矛盾があった場合でもコンパイルエラーにならないので、注意が必要です。

```ts
type User = {
  name: string;
  age: number;  //number型で定義
};

type Test =  User & {
  age: string;  //string型で定義
  English: number;
  Math: number;
};

type Test = {
  name: string;
  age: string; //string型になる
  English: number;
  Math: number;
};
```

## ③定義できる型
最後に、interfaceとtypeの定義できる方の違いについて説明します。
interfaceは、「構造を定義するもの」なので、オブジェクトとクラスの型だけ定義することができます。
一方typeは、オブジェクトとクラス以外の他の型も宣言することができます。

```ts
type ID = number | string;
//union型も定義可能
```


# 結論

[公式ドキュメント](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types)によると、

「TypeScriptは他の種類の宣言が必要かどうかを教えてくれます。ヒューリスティックが必要な場合は、タイプの機能を使用する必要があるまでインターフェイスを使用してください。」だそうです。

>For the most part, you can choose based on personal preference, and TypeScript will tell you if it needs something to be the other kind of declaration. If you would like a heuristic, use interface until you need to use features from type.

interfaceの方が使ってほしそうですが、場合を見てinterfaceとtypeを使い分けてください。ということでした。

interface、typeの仕様の違いを理解した上で使い分けをすることが重要だと思いました。


### 参考記事
https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#differences-between-type-aliases-and-interfaces

https://typescriptbook.jp/reference/object-oriented/interface/interface-vs-type-alias

https://zenn.dev/luvmini511/articles/6c6f69481c2d17

https://zenn.dev/seya/articles/aa94166c977280
セッションマネージャーがリモートホストのポートフォワードに対応した件

# 背景
AWS Summit Japan 2022 の興奮冷めやらぬ間にしれっとAWSが次ような発表をしました。
[AWS Systems Manager announces support for port forwarding to remote hosts using Session Manager](https://aws.amazon.com/jp/about-aws/whats-new/2022/05/aws-systems-manager-support-port-forwarding-remote-hosts-using-session-manager/)

詰まるところ今まではローカルホストのポートフォワードしか対応できていなかったので、外部からRDSへ接続する為の踏み台に対して SSH アカウントを個別に発行する必要がありました。
SSH アカウントの管理ではキーペアの登録等で運用が面倒でしたが、それが一切不要になりました。

# 課題
一部の運用では「セッションマネージャーを許可したいだけだったのに RDS に接続できてしまう」というのが不都合だということで、この機能を制限してみる。

# 解決
今回の機能のメリットは「IAMだけで集中管理ができる」ことなので、リモートホストに対するポートフォワード機能をIAMポリシーで制限してしまえば良い。

具体的な制限には若干の特徴があるので注意してください。

## 基本形
```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Deny",
            "Action": "ssm:StartSession",
            "Resource": "arn:aws:ssm:{region}:{account_id}:document/AWS-StartPortForwardingSessionToRemoteHost"
        }
    ]
}
```

## 結果
{account_id} を接続先のAWSアカウントIDにしてしまうと、繋がってしまうので、拒否したい場合はアスタリスクにしておくべし。

### 繋がらない（OK）
```
"Resource": "arn:aws:ssm:*:*:document/AWS-StartPortForwardingSessionToRemoteHost"
"Resource": "arn:aws:ssm:ap-northeast-1:*:document/AWS-StartPortForwardingSessionToRemoteHost"
```
### 繋がる（NG）
```
"Resource": "arn:aws:ssm:*:111111111111:document/AWS-StartPortForwardingSessionToRemoteHost"
"Resource": "arn:aws:ssm:ap-northeast-1:111111111111:document/AWS-StartPortForwardingSessionToRemoteHost"
```

# 一言
この挙動はどこか別のAWSアカウントと通信しているということか。

それと、RDSへの接続情報知っていれば、SSMだろうがSSHだろうが接続出来てしまうよね。セッションマネージャーのリモートホストポートフォワードは困るというのはそもそもの運用に問題は無いだろうか。

最後にインフラエンジニアは「SSHしたら負け」だと信じてます。

って「一言」どころじゃなくなってるし。

# さらに一言
そもそも接続のやり方どうなってるん？な説明も簡潔に。

## ポートフォワード

```shell
# aws ssm start-session \
--target {instance_id} \
--document-name AWS-StartPortForwardingSessionToRemoteHost \
--parameters '{"host":["{rds_endpoint"],"portNumber":["3306"], "localPortNumber":["3306"]}' \
--profile {profile} &
```

## 接続

```shell
# mysql -u {user} -p -h 127.0.0.1 -P 3306
Enter password:
```

& を使ってバックグラウンド実行させておけば同じ shell で接続できます。
但し、作業後は一応バックグラウンドプロセスを kill しておきましょう。
【Flutter】Flutterのプロジェクトファイルは英数字+小文字+アンダーバーのみにしないと面倒だぞ！

# 発生した経緯
「MyProject-Pyoject」のような英語+大文字+ハイフンのプロジェクトのiOSだけを作り直そうとしたところ以下のようなエラーが発生した。
```
"xxxxx-xxxxxx" is not a valid Dart package name.

See https://dart.dev/tools/pub/pubspec#name for more information.
```

調べたところとしてはこちらがありました。

https://github.com/flutter/flutter/issues/53106

**プロジェクトを作成する際は、英数字+小文字+アンダーバーのみにしようね！！後々面倒だよ！!**

# 理由はこちら
https://dart.dev/tools/pub/pubspec#name
RustでgRPCのHello World!

## 概要

RustでgRPCのHello World!をするまでの手順のメモです。
コードの意味などは理解できていないですが、まずは動かしてみることを目的にしています。

下記のページを参考にしています。
https://github.com/hyperium/tonic/blob/master/examples/helloworld-tutorial.md

## プロジェクト作成

```console
% cargo new grpc_hello_world
% cd grpc_hello_world
```


## protoファイルの配置

`proto/helloworld.proto` を次のように作成する。

```proto
syntax = "proto3";

package helloworld;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}
```

## Cargo.tomlに設定追加

```toml
[package]
name = "grpc_hello_world"
version = "0.1.0"
edition = "2021"

[[bin]]
name = "helloworld-server"
path = "src/server.rs"

[dependencies]
tonic = "0.7"
prost = "0.10"
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }

[build-dependencies]
tonic-build = "0.7"
```



## protoからコード生成するためのプログラムの追加

プロジェクト直下に `build.rs` というファイルを下記のように作成。

```rs
fn main() -> Result<(), Box<dyn std::error::Error>> {
    tonic_build::compile_protos("proto/helloworld.proto")?;
    Ok(())
}
```

## サーバのプログラムを追加

参考ページに従い、 `src/server.rs` を下記のように作成。
```rs
use tonic::{transport::Server, Request, Response, Status};

use hello_world::greeter_server::{Greeter, GreeterServer};
use hello_world::{HelloReply, HelloRequest};

pub mod hello_world {
    tonic::include_proto!("helloworld");
}

#[derive(Debug, Default)]
pub struct MyGreeter {}

#[tonic::async_trait]
impl Greeter for MyGreeter {
    async fn say_hello(
        &self,
        request: Request<HelloRequest>,
    ) -> Result<Response<HelloReply>, Status> {
        println!("Got a request: {:?}", request);

        let reply = hello_world::HelloReply {
            message: format!("Hello {}!", request.into_inner().name).into(),
        };

        Ok(Response::new(reply))
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let addr = "[::1]:50051".parse()?;
    let greeter = MyGreeter::default();

    Server::builder()
        .add_service(GreeterServer::new(greeter))
        .serve(addr)
        .await?;

    Ok(())
}
```

## gRPCサーバの起動

依存packageのコンパイルの後、サーバが起動する。
```
% cargo run --bin helloworld-server
    ...
    Finished dev [unoptimized + debuginfo] target(s) in 0.09s
     Running `target/debug/helloworld-server`
```


## grpcurlでRPCを叩いてみる

```console
% grpcurl -plaintext -import-path ./proto -proto helloworld.proto -d '{"name": "World"}' '[::]:50051' helloworld.Greeter/SayHello 
{
  "message": "Hello World!"
}
```
【海外イベント紹介】 The COVID Tracking Project: 0 to 2M API Requests in 3 Months

今回は、「Jamstackカンファレンス Virtual May　2020」で行われたプレゼンテーションから、「The COVID Tracking Project: 0 to 2M　API Requests in 3 Months」の内容をご紹介します:loudspeaker:

>目次
>― プロジェクト結成の経緯 ―
>1. 母数（検査数）の欠如
>2. 感染状況追跡プロジェクト
>3. 社会のニーズに応える
>― プロジェクトのサイトをJamstackで構築した理由 ―
>4. サイトのリニューアル
>5. サイトの堅牢性
>6. まとめ

10年以上の歴史を持つ「**Jamstackカンファレンス**」は、Jamstackの生みの親であるクラウドコンピューティング企業「Netlify」が主催。世界中の開発者が集い、Jamstackをコンセプトとした最新のWebサイトの設計、開発などについて話し合います。プレゼンテーションの言語は英語ですが、本ブログでは日本語でご紹介します。

日本ではまだまだ知名度が低いJamstack。日本の皆さんに、Jamstackをより身近に感じてもらえることを期待しています！

コロナウイルスのパンデミックが本格化しつつあった2020年。

アメリカである問題が発生しました。

アメリカ疾病予防管理センター（CDC）が発出する情報の精度が、統計学的に使い物にならなくなってきたのです。そのため、「各州の保険所が個別に出している統計情報を一つにまとめよう！」と、有志のメンバーでプロジェクトが結成されました。

今回の記事では、

・プロジェクト結成の経緯
・プロジェクトのサイトをJamstackで構築した理由

について解説していきます。

## ― プロジェクト結成の経緯 ―
### 1. 母数（検査数）の欠如

陽性率は、ある地域の人口を母数とするのではなく、検査数を母数とすることで算出できます。例えば、人口1,000人の村で陽性者が2名だったとしても、検査数が10件であれば20％の陽性率ということになります。

アメリカ疾病予防管理センター（CDC）は、当初は検査数と陽性者数を発表していました。しかし、途中から検査数の発表を取りやめてしまいました。つまり、母数がわからないため、陽性率を知ることができなくなったのです。

一方で、各検査機関には、州の保険当局に陽性率を報告する義務がありました。そのため、手分けをして、米国内にあるすべての保健所のサイトから検査数のデータを収集、スプレッドシートにまとめて公開しました。そこから、国内の感染の広がりや陽性率を推し量ろうとしたのです。

### 2. 感染状況追跡プロジェクト

このことがメディアで報じられるようになると、本腰を入れて行うためにボランティアが募集されました。本講演者のエリン・キセイン氏は、その呼びかけに応えた一人です。

一刻でも早い対応が必要だと考えた彼女は・・・

友人の優秀な開発者に連絡し、**4日後**にはサイトをリリース
**その後1カ月間**でサイトのデザインを強化

由緒ある国家機関であるCDCがデータを提供できないまま、自然発足した民間のプロジェクトが、米国における包括的な感染率を図る唯一のデータ供給源となったのです。

### 3. 社会のニーズに応える
![img-30451_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242415/a8488cf5-e2dc-10de-a2ea-728a108a66a9.png)

やがて、さらに多くのメディアや地方局が、このデータを頼りに、コロナウイルス感染の社会的なインパクトや地元への影響、ほかの州との比較状況などを把握するように。プロジェクトは、いつの間にか「公共データレスキュー」という大きな意義を担うようになっていました。

そして、最終的には数百名のスタッフが参加。そのなかには、公衆衛生の専門家、データサイエンティスト、デザイナーなどの専門職のほか、「これといったスキルは無いがぜひとも協力したい！」と、データの発掘や入力に時間を割いた一般の方々もいます。

## ― プロジェクトのサイトをJamstackで構築した理由 ―
### 4. サイトのリニューアル

サイト立ち上げから急速に人材と注目が集まった結果、1ヶ月後にはよりプロフェッショナルなサイトに作り変えることになりました。それが現在でも稼働している以下のサイトです。

https://covidtracking.com/

このサイトは、以下の技術で作られています。
>ホスティング：Netlify
>構築：Gatsby
>データ：Google Sheet
>CMS：Contentful

結果として、**APIリクエストが1日に200万を超えるサービスを、わずか3ヶ月で安定的に稼働**できるようになりました。

### 5. サイトの堅牢性
![img-30451_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242415/996d0d19-ad7e-9ea2-fc2a-7ea7a5d6e16b.png)

4月29日に**サイトのトラフィックが極端に増加**しているのがわかります。この日、ホワイトハウスが本プロジェクトのデータに言及し、政策を発表しました。

特筆すべきは、このとき、**プロジェクト関係者がサイトに何の異変も感じなかった**ということです。トラフィック激増の影響を受けることなく、**サイトはいつものように稼働**したのです。

なお、2021年3月7日を持って、このプロジェクトは役割を終えました。現在は、「政府が提供するデータを参照するように」とのメッセージが表示されています。

### 6. まとめ
**社会的意義のあるサイトを、わずか3カ月で安定して運用できるまでに構築**できた本実例は貴重です。

彼女は、講演の中で**「Jamstackが無ければ実現しなかった」**と述べています。

いかがだったでしょうか？

今回は技術的な学びというより、本講演者であるエリン・キセイン氏の当時の回顧録から、以下の事実が裏付けられたのではないでしょうか？

Jamstackには、

**・スピード
・安定性
・トラフィックの処理**
 
の面で、ほかでは決して見いだせない**優位性がある**ということです！

最後まで読んでくださり、ありがとうございました:bow_tone1:

株式会社ヒューマンサイエンスは、他社にはない、「ドキュメント制作のノウハウ」×「最新のWeb開発技術（Jamstack）」を用いて、Webコンテンツとプラットフォームのソリューションをご提供します。

関心がある方は、ぜひこちらまでお問い合わせください！
**株式会社ヒューマンサイエンス
https://www.science.co.jp/document/jamstack.html**
 
本文書の出典元：https://www.youtube.com/watch?v=ryngYoHXNfQ
Perl 5.36リリース - 2022年5月28日

2022年5月28日にPerlの最新バージョンPerl 5.36がリリースされました。

詳しくは以下で解説しています。

<a href="https://perlzemi.com/blog/20220530161828.html">Perl 5.36がリリース - warningsの有効化、サブルーチンシグネチャ、try-catch-finally文、Unicode 14サポート</a>
法人登記とバーチャルオフィス

web関係の仕事やっていれば、法人登記する機会も出てくる。

# 法人登記を調べるには？

https://www.houjin-bangou.nta.go.jp/

# どこに登記する？

・賃貸マンション
 → 80%でNG (下手に聞くと借りれなくなる)

・登記OKと記載のあるマンション
 → 家賃高く古い

・分譲マンション
 → これも無理なのあるみたい

・事務所用のビルを借りる
 → 高すぎる

・バーチャルオフィス
→ 口座が作れない
→ 郵便物が面倒
→ 事業許認可が降りない場合も

・GMOオフィスサポート
→ https://www.gmo-office.com/

これはいいけど、東京しか住所がないので訴訟とか届け出とかが面倒くさそう

# じゃあどうすりゃいいの？

・自分の土地を買って家を建て登記
→ 非現実的

# 勝手に登記

国土交通省が定める住居用マンションの定義では「専ら居住者の生活の本拠があるか否か」「利用方法は生活の本拠であるために必要な平穏さを有するか」を判断基準

賃貸借契約を解除して立退を請求できるのは、借主の行為によって家主と借主の信頼関係が破壊された場合。・基本的に外で仕事をしており・来客等も無い、信頼関係が破壊されるほどの事情があるとは言えず、立ち退く必要は無い

# 移転しろと言われた判決も
東京高裁平成23年11月24日判決では、税理士事務所に利用されていたケースで、管理組合からの使用禁止を求める訴えが認容されました
http://kanrikyo.or.jp/oyakudachi/pdf/vol12_04.pdf


解説
https://www.zennichi.or.jp/law_faq/%E4%BD%8F%E5%B1%85%E5%B0%82%E7%94%A8%E3%83%9E%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%BA%8B%E5%8B%99%E6%89%80%E4%BD%BF%E7%94%A8/

>昭和58 年に住居専用規定が設けられた当時、本件マンションの2 階以上の階において、皮膚科医院及び歯科医院として使用されていた区分所有建物が各1戸あったが、いずれも遅くとも平成6 年ころまでに業務を廃止

皮膚科と歯科もあるんだからいいだろ？
だから税理士事務所もやめなさい。

って判決なんだろうね。
あと税理士が人数を主張していない点から見てもけっこうな規模でやってたんだろうな。

まぁ判決文を見ても損害賠償までは認容されていないし。
SOHOレベルなら出てけと訴訟されりゃ認諾して出てく位でいいのかな。

# 上記を踏まえて

名古屋市中区栄5丁目○番地X号 ころころビル307
→ ビル名でググられると管理会社にバレる

名古屋市中区栄5丁目○番地X号 ころころビル3F
→ ビル名でググられると管理会社にバレる

名古屋市中区栄5丁目○番地X号
→ ポストに会社名を書かないと郵便が届かない。
書いた時点で管理会社にバレる

名古屋市中区栄5ー○ーX(307)
→これならググられてもまぁ、なんとかなりそう。
【初心者】dokcerfile 書き方

# はじめに
真面目に dockerfile を書く機会があったのでちゃんと理解します

# 進め方
1. まずは公式ドキュメントでざっと理解(http://docs.docker.jp/develop/develop-images/dockerfile_best-practices.html)
1. サンプルをいくつか検証
1. ベストプラクティスを踏まえる
1. 実際に書く

### まずは公式ドキュメントでざっと理解
```dockerfile
# syntax=docker/dockerfile:1
FROM ubuntu:18.04        // Docker イメージからレイヤ作成
COPY . /app              // クライアント側からファイル移動
RUN make /app            // RUN はアプリケーションを make で構築？
CMD python /app/app.py   // コンテナ内の実行コマンド指定
```
仕組み的には、元のレイヤ(イメージ?)上に新しい書き込み可能なレイヤ(writable layer)を追加する。
その追加した writable layer に実行中コンテナの操作(新規ファイル追加、編集)を実行する。

#### ビルド・コンテクストの理解
- dcoker build コマンドはカレントディレクトリをビルド・コンテクストと呼ぶ
- -f オプションで docker file パスを指定可能

```shell
$ mkdir myproject && cd myproject
$ echo "hello" > hello
$ echo -e "FROM busybox\nCOPY /hello /\nRUN cat /hello" > Dockerfile // dockerfile 作成
$ docker build -t helloapp:v1 // docker build
```


#### stdin を通して Dockerfile　をパイプ
- Dockerfile　をディスクに書き込まない。一回限りの構築を行う場合に役立つ
- Dcokerfile　が生成された場所が後で残らない状況(?)でも役立つ

```shell
echo -e 'FROM busybox\nRUN echo "hello world"' | docker build -
または
docker build -<<EOF
FROM busybox
RUN echo "hello world"
EOF
```


#### ビルド・コンテクストを送信せず、stdin からの Dockerfile　を使ってイメージ構築
- Dokcerfile をイメージの中にコピーする必要がない状況や構築速度を改善する
- ビルド・コンテクストが必要な copy や add コマンドは実行不可


#### 不要なパッケージのインストール禁止
- 不要なパッケージは一切インストールしない


#### アプリケーションを切り離す
- 各コンテナは一つ "だけ" の用途を持つべき
- アプリケーションを複数コンテナに切り離し、水平スケールやコンテナの再利用がより簡単になる


#### レイヤ数を最小に
- レイヤ数を最小にするべき
- マルチステージ・ビルドの使用も検討するべき


#### 複数行にわたる引数は並びを適切に
- 引数はアルファベット順、かつ、バックスラッシュ前に半角空白を含める

```dockerfile
RUN apt-get update && apt-get install -y \
  bzr \
  cvs \
  git \
  mercurial \
  subversion \
  && rm -rf /var/lib/apt/lists/*
```


#### ビルド・キャッシュの利用
- docker build コマンド時にキャッシュ利用有無を制御可能(--no-chache=true)
- 親イメージからコマンドが同じか？等、キャッシュ利用可否を判断するルールが存在する


#### Dockerfile 命令
- FROM: 推奨は最新の公式イメージ利用
- LABEL: 管理用のラベル。複数付与も可能
- RUN: コマンド実行。キャッシュ観点から、apt-get update と install は RUN 命令内で同時実行すべき
- CMD: イメージ内に含まれる S/W を実行する(ex: CMD ["apache2", "-DFOREGROUND"]
- EXPOSE: コンテナがリッスンするポート指定
- ENV: 環境変数を指定
- ADD と COPY: 一般的には、機能が明確な COPY を使用する。ADD はローカルの tar ファイルを自動展開してイメージに書き込む際に使用
- ENTRYPOINT: イメージに対してメインとなるコマンドの設定
- VOLUME: データベース・ストレージ領域、設定用ストレージ、Docker コンテナによって作成されるファイルやフォルダの公開に使用
- USER: 実行ユーザの指定
- WORKDIR: 作業ディレクトリ指定?
- ONBUILD: 親の Dcokerfile から子供の Dockerfile へ与える命令


残件は多いですが、一旦ここで終わりにします。


# 参考文献
[Dockerfile のベスト・プラクティス](http://docs.docker.jp/develop/develop-images/dockerfile_best-practices.html)
※ 日本語化している有志の方々に深く感謝します
RKE2で任意のマニフェストをNodeデプロイ時に適用する際の注意事項

## 前提

RKE2： v1.23.6+rke2r2

## TL;DR

* `/var/lib/rancher/rke2/server/manifests` 以下配置したものをファイルソート順にapplayしてくれる
* `manifests/`以下にディレクトリを作成して配置するのはNG

## 詳細

RKE2でServer Nodeをデプロイする際に任意のマニフェストをapplayする方法。

`/var/lib/rancher/rke2/server/manifests` 以下にマニフェストを配置するとファイルソート順に適用します。

つまり、以下の様にファイルを配置した場合は、hoge01.yaml → hoge02.yaml の順で適用します

* /var/lib/rancher/rke2/server/manifests/hoge01.yaml
* /var/lib/rancher/rke2/server/manifests/hoge02.yaml

ただし、`manifests/` 以下にディレクトリを作成して配置した場合は対象外なので注意。  
つまり、以下のように何かの意味単位でディレクトリを作成して配置するのはNG

NG例
* /var/lib/rancher/rke2/server/manifests/hoge1/hoge01.yaml
* /var/lib/rancher/rke2/server/manifests/hoge2/hoge01.yaml

## 参考

[Auto-Deploying Manifests - Advanced Options and Configuration | RKE2](https://docs.rke2.io/advanced/#auto-deploying-manifests)

Helmの場合は以下が参考になります。
[Helm Integration | RKE2](https://docs.rke2.io/helm)
AWS認定試験の受験と勉強記録

## はじめに
現在、私は7冠AWS資格を取得しました。
取得時期と当時苦労したことなど勉強方法などを記載します。
勉強方法は個人差はありますので、参考程度にして頂けたら幸いです。

## 受験時期

|No.  |試験名  |受験時期  |点数|合否  |
|---|---|---|---|---|
|1 |AWSクラウドプラクティショナー |2019-09-21|785点|不合格 |
|2 |AWSクラウドプラクティショナー |2019-11-02|656点|合格|
|3 |AWS Certified Solutions Architect - Associate |2020-08-11|660|不合格|
|4 |AWS Certified Solutions Architect - Associate |2020-09-26|680|不合格|
|5 |AWS Certified Solutions Architect - Associate |2020-11-07|753|合格|
|6 |AWS Certified SysOps Administrator - Associate |2020-11-30|745|合格|
|7 |AWS Certified Developer - Associate |2021-05-17|748|合格|
|8 |AWS Certified Database - Specialty |2021-07-10|730|不合格|
|9 |AWS Certified Database - Specialty |2021-08-07|786|合格|
|10 |AWS Certified Security - Specialty |2021-10-06|822|合格|
|11 |AWS Certified Solutions Architect - Professional |2021-11-19|777|合格|

## 試験の感想
最初AWSを勉強したときは分からないことが多くプラクティショナーでも勉強に半年かかりました。
特にSAAが２回落ちて、もうAWS試験は取得できないのではという不安もありましたが、
勉強を継続した結果、7冠まで取得できました。

プラクティショナー受験したときは、AWS経験は半年でした。
現在はAWS経験は3年目になります。主に運用保守の業務のため、かかわるサービスの幅が狭いため、日々勉強が必要です。

#### 一番大事なのは、AWSの勉強を途中で辞めないことです。継続することです。

## AWSクラウドプラクティショナー 

以下の書籍で勉強しました。問題集は解いていないです。
「AWS認定資格試験テキスト AWS認定 クラウドプラクティショナー 単行本 – 2019/4/20」
https://www.amazon.co.jp/dp/4797397403

## AWS Certified Solutions Architect
以下で勉強しました。
この１冊で合格！　AWS認定ソリューションアーキテクト - アソシエイト テキスト&問題集
https://www.amazon.co.jp/dp/B07VFFX6V1

AWS認定資格試験テキスト AWS認定 ソリューションアーキテクト-アソシエイト
https://www.amazon.co.jp/dp/479739739X
Udemy模擬問題集
https://www.udemy.com/share/1064nS3@gxWwhE3HY5r-fg4vnbpzGI39q2lYmhhnH2ozkdeLwsZaWMiQoeZjX4hQdEtnpwblHQ==/

## AWS Certified SysOps Administrator - Associate
当時試験にハンズオンがなかったため、Udemyの模擬問題集のみ勉強しました。
【SOA-C02版】AWS 認定SysOpsアドミニストレーター アソシエイト模擬試験問題集（全4回分294問）
https://www.udemy.com/share/102NCE3@iCIAG0uUsKbYuqpJNnzKZHZfm2VUw9otKDgSgX1hQG3catGbolJL36KBSehDb33jfA==/

## AWS Certified Developer - Associate
以下の本をメインで勉強しました。
ポケットスタディ AWS認定 デベロッパーアソシエイト (アソシエイト試験ポケットスタディ) 単行本 – 2021/3/9
https://www.amazon.co.jp/dp/4798063401

AWS WEB問題集
https://aws.koiwaclub.com/

YoutubeでCodeシリーズのハンズオン動画をみてイメージを付けました。

## AWS Certified Database - Specialty
以下の本をメインで勉強しました。
要点整理から攻略する『AWS認定 データベース-専門知識』 (Compass Booksシリーズ)
https://www.amazon.co.jp/dp/4839975078

Udemy動画　英語ですが勉強になりました。
https://www.udemy.com/share/103o6K3@mMQx3wMOgeWqP6Nj8FEa4YmWR7DdVImIoKBo5AMsb8PKfpx9Ckl09oWjGZ_ex4l9ww==/
Udemy模擬問題集
https://www.udemy.com/share/103t3o3@yJKpN35Ft7r9dJRFNR9AVu64YSpaoUM3TBwXe2_Hq3PXTsrWd65IocIV1grjTyxkvA==/

## AWS Certified Security - Specialty
以下の本で勉強しました。要点整理から攻略する『AWS認定 セキュリティ-専門知識
https://www.amazon.co.jp/dp/4839970947
whizlabs　海外のWEB問題集で勉強しました。
https://www.whizlabs.com

## AWS Certified Solutions Architect - Professional

以下の本を一冊しっかり理解して受験しました
「AWS認定ソリューションアーキテクト-プロフェッショナル ~試験特性から導き出した演習問題と詳細解説」
https://www.amazon.co.jp/dp/4865942483/

以下の本を一冊しっかり理解して受験しました
AWS認定資格試験テキスト&問題集 AWS認定ソリューションアーキテクト - プロフェッショナル
https://www.amazon.co.jp/dp/4815609063

WEB問題集を少し解きましたが、知識不足で挫折しました。
【Salesforce】指定のリストビュー画面へ遷移

# はじめに
　詳細画面にて、LWCのボタン押下時で値を更新し、指定のリストビュー画面へ遷移する処理を実装する。
　なお、リストビュー画面遷移時点で、更新後の値を表示する。

前提
　下記は、処理の流れのイメージ図である。
　本記事では、下記の赤字箇所の実装方法について記載する。
![ListView_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1255237/1f600ad0-eefd-ee68-be78-69bb1b63539c.png)

# 目次
[1. 遷移先リストビューのURL生成](https://qiita.com/drafts/22d7ab2cdbaf3f373f96/edit#1-%E9%81%B7%E7%A7%BB%E5%85%88%E3%83%AA%E3%82%B9%E3%83%88%E3%83%93%E3%83%A5%E3%83%BC%E3%81%AEurl%E7%94%9F%E6%88%90)
[2. 作成したURLへ遷移](https://qiita.com/drafts/22d7ab2cdbaf3f373f96/edit#2-%E4%BD%9C%E6%88%90%E3%81%97%E3%81%9Furl%E3%81%B8%E9%81%B7%E7%A7%BB)
[参考](https://qiita.com/drafts/22d7ab2cdbaf3f373f96/edit#%E5%8F%82%E8%80%83)

# 1. 遷移先リストビューのURL生成
### 1-1. 指定するリストビュー ＋ フィルタのNameを取得
　1. Apexクラスの処理実行後に、**遷移させたいリストビュー画面**を表示する。
　2. リストビュー画面にて、①のリストから**表示させたいフィルタ**を設定する。
　3. URLの「**オブジェクトApi名**」「**フィルタ名**」をメモしておく。
![ListView_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1255237/dacfcfb1-752f-570b-11b1-c948317059dc.png)


### 1-2. 遷移先リストビューのURL生成処理を実装
　下記ソースコードをもとに、遷移先リストビューのURL生成処理を実装する。
```javascript:dataUpdate.js
import { NavigationMixin } from 'lightning/navigation';

export default class dataUpdate extends NavigationMixin(LightningElement) {

  //visual force + Apexクラス実行処理 （割愛）

  //遷移先リストビューのURL生成
  this.accountHomePageRef = {
    type: 'standard__objectPage',
    attributes: {
      // 「ステータス更新」オブジェクト指定
      // 1-1で取得したオブジェクトApi名を指定
      objectApiName: 'TestObject__c',
      // リストビュー画面指定
      actionName: 'list'
    },
    state: {
      // リストビュー種別指定
      // 1-1で取得したフィルタ名を指定
      filterName : '00XXXXXXXXXXXXXXXX'
    }
  };
}
```

### 注意点
　「**フィルタ名**」は、各環境ごとに異なる。
　そのため、開発環境から本番環境へリリースする際などは、本番環境にて「フィルタ名」を取得し（手順1-1）、1-2の設定値を変更する必要がある。
　　必要に応じて、設定値を[カスタム表示ラベル](https://help.salesforce.com/s/articleView?id=sf.cl_about.htm&type=5)で管理すると柔軟に設定値の変更を行うことができる。

# 2. 作成したURLへ遷移
### 2-1. 作成したURLへ遷移する処理を実装
　下記ソースコードをもとに、作成したURLへ遷移する処理を実装する。
　なお、1-2で実装した「this.accountHomePageRef = {・・・};」の下部へ記載すること。
```javascript:dataUpdate.js
  //作成したURLへ遷移
  this[NavigationMixin.GenerateUrl](this.accountHomePageRef)
    .then(url => {
      // 1000ミリ秒後、指定URLへ遷移
      window.setTimeout(function(){
        window.location.href = url;
      },
      1000);
  });
```

### 注意点
　2-1のソースコードでは、1000ミリ秒後に画面遷移を行なっている。
　遅延処理がないと、画面遷移後にデータ更新前の値が表示される場合がある。
　遅延処理の有無や遅延時間は、Apexクラス行う処理内容に応じて、調整すると良い。

# 参考
[【Lightning Web Component】ページ遷移の実装方法](https://keneloper.com/how-to-implement-page-transition/)
[基本的なナビゲーション](https://developer.salesforce.com/docs/component-library/documentation/ja-jp/lwc/lwc.use_navigate_basic)
[さまざまなページ種別への移動](https://developer.salesforce.com/docs/component-library/documentation/ja-jp/lwc/lwc.use_navigate_page_types)
[Navigate to List View in LWC](https://blog.salesforcecasts.com/navigate-to-list-view-in-lwc/)
[JavaScriptでsetTimeoutを使う方法【初心者向け】現役エンジニアが解説](https://techacademy.jp/magazine/5541)
Arduino 動作速度の（より）正確な測定方法

```for(){}``` と ```micros()``` 関数を組み合わせることで、Arduino の動作速度の簡易的な測定が可能です。ただし、高速な処理の測定を行う場合、かなり不正確な値が得られることがあります。より正確な測定のために気をつける点と計測方法により結果の違いをまとめました。

## 簡易的な測定方法
最も簡単な測定方法は ```micros()``` 関数で測定対象の処理を挟んでやって、その差分から処理時間を求めます。ただし、16 MHz 動作の Arduino Uno の場合、```micros()``` 関数は 4 us の分解能しかありませんので、複数回処理を行ってその合計の処理時間から 1 回当たりの処理時間を求めます。

```c
unsigned long ts, te;

ts = micros();
for (int i; i=1000; i++) {
  // 測定したい処理
}
te = micros();

Serial.println(te - ts); // ns
```

測定対象の処理がそれなりに時間がかかる場合（例えば 100 us 以上かかる ```analogRead()``` とか）はこの方法で問題ありませんが、処理時間が短い場合（```digitalWrite(13, HIGH)``` の代わりに ```PORTB |= _BV(5)``` を使う場合とか）は ```for(){}``` 部分にかかる時間を考慮する必要があります。


## より正確な測定方法

より正確に測定対象部分のみにかかる時間を測定するためには、以下のようなコードを使います。

```c
unsigned long ts1, te1, dt1;
unsigned long ts2, te2, dt2;

ts1 = micros();
for (int i; i=1000; i++) {
  // 測定したい処理 1 回だけ
}
te1 = micros();
dt1 = te1 - ts1; // 1 回だけの処理時間 + for(){}

ts2 = micros();
for (int i; i=1000; i++) {
  // 測定したい処理 1 回目
  // 測定したい処理 2 回目
}
te2 = micros();
dt2 = te2 - ts2; // 2 回分の処理時間 + for(){}

Serial.println(dt2 - dt1); // 1 回分の処理時間
```

```for(){}``` の中で測定したい処理を一度だけ行う場合と 2 回行う場合で時間を計測し、その差分を取ります。
こうすることで ```for(){}``` 部分に必要な処理時間が相殺されますので、より正確に測定したい処理部分だけの時間が得られます。

## 測定例

いくつかの処理の測定結果です。使用ボードは Arduino Uno、Arduino IDEを使用しています。
コンパイルオプションは -Os で行いました。

### analogRead()
dt1 = 112000 us
dt2 = 224004 us
dt2 - dt1 = 112004 us
```analogRead()``` 1 回当たりの処理時間 112 us

### digitalWrite()
dt1 = 3208 us
dt2 = 6164 us
dt2 - dt1 = 2956 us
```digitalWrite()``` 1 回当たりの処理時間 2.956 us

### PORTB |= _BV(5)
dt1 = 384 us
dt2 = 504 us
dt2 - dt1 = 120 us
```PORTB |= _BV(5)``` 1 回当たりの処理時間 0.12 us (120 ns)


```digitalWrite()``` ぐらいなら大丈夫かなと思いましたが、```digitalWrite()``` でも 10 % ぐらいの差が出ました。予想していたよりも気を付けないといけないなという印象です。
より良い Arduino ライフを！
【Flutter】extendBodyBehindAppBarを有効にすると生まれる謎の空白【GridView】

# 問題点

AppBarのextendBodyBehindAppBarを有効にすると、スクロールしたときにbodyがAppBarの下に入っていくような挙動になる。
ただ、これを設定するとListViewやGridViewの上に謎の空白が生まれてしまっていた。

# 解決策

ListViewやGridViewのpaddingを0にするだけ。

```dart
GridView.builder(
    padding: EdgeInsets.zero,
)
```

多分`only`にして`top: 0`でもうまくいくはず。

# まとめ

- GridViewやListViewの上に謎の空白が生まれてたら、AppBar.extendBodyBehindAppBarがtrueになってるか確認してみるといい。
- topのpaddingを0にすると綺麗になる。
- そもそもこの空白　is 何？
shellでもファイル探し

## 経緯

ICTSCやCTFでかなり使って便利だったので共有

## ファイル名
```
find [検索対象フォルダのパス] -name "*[検索したい文字列]*"
```

## 内容
```
grep [検索したい文字列] -rl [検索対象フォルダのパス]
```
IIS＋SQLSERVERでLaravelを構築

Windows10に構築したIIS10でPHP Laravelを動かすまでの手順を残します。


まずは、<https://windows.php.net/download/>から
Non Thread SafeのZIPファイルをダウンロードして、
所定のフォルダに展開します。
※システムドライブ直下に展開した

PHPインストールフォルダを右クリックしてプロパティを表示し、適切なACLを付与するため、セキュリティタブからアクセス可能なユーザーを確認。
IISで稼働するユーザーはデフォルトでは「IIS_IUSERS」です。
「IIS_IUSERS」がアクセス権を持っていないようでしたら、追加してください。

SQLSRVのドライバをMicrosoftのサイトからダウンロードし、PHPインストールディレクトリ内のextフォルダにdllをコピーしてください。

composerを使って、プロジェクト作成
・コマンドプロンプトを管理者モードで起動
・c:\inetpub\wwwroot　に移動し、以下のコマンドを発行
　composer create-project laravel/laravel --prefer-dist プロジェクト名

※すでにcomposerを導入済で、バージョンが一致していない場合、次のコマンドで最新にアップデートを行います。
composer self-update
※Composer¥Exception¥NoSslExceptonが出たら[php.ini]の編集が必要。
　・extension_dir = "ext"  ←この行を有効化
　・extension = openssl    ←この行を有効化

ここまでやったら一度、管理者権限のコマンドプロンプトでプロジェクト直下に移動し
php -S localhost:8000 -t public
をたたいてみましょう。

ブラウザから
http://localhost:8000
をたたいてみて、Laravelのデフォルト画面が表示されればOKです。
一度、アプリケーションサーバーを停止して後続の処理を続けます。

プロジェクト内の「.env」ファイルを開いてDB接続を変更します。

DB_CONNECTION=sqlsrv
DB_HOST=127.0.0.1
DB_PORT=1433
DB_DATABASE=データベース名
DB_USERNAME=接続ユーザー
DB_PASSWORD=接続パスワード

次に[config/database.php]を開いて
'default' => env('DB_CONNECTION', 'mysql'),
を
'default' => env('DB_CONNECTION', 'sqlsrv'),
と修正します。

次に「Database Connections」の
'connections' => [
以降に記載された「'sqlsrv' => [」を見つけ、

		'sqlsrv' => [
            'driver' => 'sqlsrv',
            'host' => env('DB_HOST', 'localhost'),
            'port' => env('DB_PORT', '1433'),
            'database' => env('DB_DATABASE', データベース),
            'username' => env('DB_USERNAME', 接続ユーザ),
            'password' => env('DB_PASSWORD', 接続パスワード),
            'charset' => 'utf8',
            'prefix' => '',
        ],

更に、php -S localhost:8000 -t publicで動作確認してみましょう。

これで、構築は完了です。
rubyの配列で、同じ値の個数を数える

# group_byを使うやり方

group_byメソッドで、同じ値のグループを作成し、
`key value`形式で、
mapメソッドの中で集計する
最後に`to_h`で見やすく出来る

```rb
ary = [1, 1, 1, 2, 3, 3]

p ary.group_by(&:itself).map{ |key,value| [key, value.count] }.to_h

=> {1=>3, 2=>1, 3=>2}
```

`to_h`抜きだと見にくい
![スクリーンショット 2022-05-31 8.55.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492674/049361c8-f637-4f63-1a71-466a1bc27704.png)


# 参考文献
https://techacademy.jp/magazine/19771

`group_by`
こんな感じで、デフォルトではハッシュが作成される。

```rb
ary = [1, 1, 1, 2, 3, 3]

p ary.group_by(&:itself)
p ary.group_by(&:itself).to_a

=> {1=>[1, 1, 1], 2=>[2], 3=>[3, 3]}
=> [[1, [1, 1, 1]], [2, [2]], [3, [3, 3]]]
```
# [追記]

Ruby 2.7 以降をご利用の方は、
このやり方を使うと良いです。

`tally`メソッドが追加されているので、こちらの方がスッキリ
https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/tally.html

```rb
% ruby --version
ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin20]

irb(main):001:0> ary = [1, 1, 1, 2, 3, 3]
irb(main):002:0> ary.tally
=> {1=>3, 2=>1, 3=>2}
```
100日後くらいに個人開発するぞ！day036

## 今日もレスポンシブデザインを実装してみた！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632394/6318f821-1752-e6a5-0a93-e624ea139d54.png)

## HTML＆CSSの上級編レッスンを修了！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632394/a80007af-4d3b-82be-d0b5-481185bd9ef7.png)


## 今日の学び

### 画面幅が拡大しても要素の幅の上限を固定させる方法
* CSSで`max-width:〇〇px`と指定すると画面幅が拡大しても要素の幅の上限を固定できる


### 要素を表示/非表示する方法
* CSSで`display:none`を用いると要素を非表示にできる
* 非表示にした要素を表示させる場合は`display:block`を用いる
【VTL】Velocity Template Languageで日時を加算・減算する 

# 概要
VTLで日時を加算・減算するのにハマったので備忘録として記載しておきます。

**VTL(Velocity Template Language)とは？**
　Apache Velocityで使用できる言語です。
　AWS AppSyncのResolverテンプレートで使用されています。

# やりたいこと
今日日付の文字列を１日減算して昨日日付の文字列を生成したい！　
※フォーマットは「yyyyMMdd」形式

# コードと解説
#### 簡単に説明するとやっていることはこうだ！！
1. 減算したいyyyyMMdd形式の日時をミリ秒に変換する
2. 変換された日時から1日(=86,400,000ミリ秒)分を減算する
3. 減算した日時をミリ秒からyyyyMMdd形式に変換しなおす

```velocity
#set($jstToday = $util.time.parseFormattedToEpochMilliSeconds("$today 00:00:00+0900", "yyyyMMdd HH:mm:ssZ"))
#set($jstYesterday = $jstToday - 86400000)
#set($yesterday = $util.time.epochMilliSecondsToFormatted($jstYesterday, "yyyyMMdd", "+09:00"))
```
※$todayにはyyyyMMdd形式の日付文字列をセットしている。

#### 詳しく見ていこう！！！
##### 1. 減算したい日時をミリ秒単位の日本標準時(JST)に変換する
下記の関数を使用して、yyyyMMdd形式からミリ秒単位の日本標準時(JST)にする。
$todayは`yyyyMMdd`なので、指定した形式`yyyyMMdd HH:mm:ssZ`に合わせる。
>*`$util.time.parseFormattedToEpochMilliSeconds(String, String) : Long`*
>文字列型として渡されたタイムスタンプと形式を解析し、エポックからのミリ秒単位のタイムスタンプを返す関数。

##### 2. ミリ秒単位の日本標準時(JST)から減算する
1日(=24時間)をミリ秒に変換すると86,400,000ミリ秒
ステップ1で算出したミリ秒単位の日本標準時(JST)から86,400,000ミリ秒を減算する。

##### 3. 減算されたミリ秒単位の日本標準時(JST)を指定した形式に変換する
下記の関数を使用して、ミリ秒単位の日本標準時(JST)からyyyyMMdd形式の日本時間(+09:00)に変換する。
>*`$util.time.epochMilliSecondsToFormatted(long, String, String) : String`*
>long型として渡されたエポックからのミリ秒単位のタイムスタンプを、文字列型で指定された形式と時差に合わせて、タイムスタンプに変換する関数。

これで年跨ぎ、月跨ぎの日時計算もできます！
上記では減算していますが、加算するときは＋すればよいだけです。

> 参考
１時間‥3,600,000ミリ秒
１日‥86,400,000ミリ秒
１ヶ月‥2,629,800,000ミリ秒
１年‥31,557,600,000ミリ秒

# おまけ雑談
AWS AppSyncのResolverテンプレートでVTLを初めて使いました。
「日付の加算・減算の関数くらい用意されているだろう」と探しましたが見つからず…
悩みに悩んだ末、見つけたのがこの方法です。
実はAWS AppSyncの開発者ガイドに書いてあったのです！！
公式はよく読むのが大事だと身をもって学びました。

# 参考リンク
https://docs.aws.amazon.com/appsync/latest/devguide/time-helpers-in-util-time.html
AWS公式資料で挑むMLS認定(15)-データ前処理の基礎知識

##### [前回] [AWS公式資料で挑むMLS認定(14)-データラベリング(データ準備)](https://qiita.com/mingchun_zhao/items/bfb34416ccbc468a5598)

## はじめに

今回は、データ前処理の基礎知識です。
`機械学習はデータ前処理が8割`、と言われるほどですので。

## 機械学習ワークフローにおける、データ前処理の位置づけ

- 1\. データ準備
- 2\. **データ前処理**
- 3\. モデルトレーニング(学習)
- 4\. モデルテスト(評価)
- 5\. モデルチューニング(改善)

## データ前処理とは

- 事前に得られた生のデータを機械学習アルゴリズムに与える前に、何かしら加工を行うこと
- 生のデータを、構造や関係性がつかみやすく、かつ機械学習アルゴリズムが学習しやすくなるように形を整える

## 生のデータの特徴

- データの型が揃っていない
- データのフォーマットが揃っていない
- 重複データが削除されていない
- データ入力が徹底されず欠損が存在する
- 共有キーがないため、他システムのデータと連携できない

## データ前処理の必要性

- 入手したデータは、大抵欠損、ノイズ、エラー値などが存在
    - データ欠損を適切な値で埋めたり
    - 好ましくないデータ値を取り除く必要あり
- 生のデータそのままでは、データの内部構造や関係性を表せない
    - 最大限にデータ活用するには、統計的処理を施す必要あり
- 機械学習アルゴリズムによって、データフォーマットとの相性が異なる
    - ニューラルネットワークで使用する画像サイズは固定なので、画像のリサイズが必要
    - ランダムフォレストは欠損値をそのまま扱えないので補完が必要

## データ前処理のタスク

- データクレンジング(データクリーニング)
    - データから、入力ミス/文字化け/欠落/不要データを特定し、一定基準でデータを修正すること
- データ統合
    - 異なるタイプのデータ、複数システムにまたがって存在するデータを結びつけること

いずれも、目的は機械学習の精度を高めること。

## データ前処理方法

### 欠損値処理

- 欠損値とは、何らかの理由で記載されず、欠落した値
    - 欠損値が多いデータ項目から、全体の分布や平均値など特徴の調査分析は困難
- 欠損値の発生原因
    - 入力の際、必須項目でなかったので
    - 担当者のミスで未入力になっている
- 欠損値の対処
    - 欠損値の割合や分析の目的などによって補完か除外かを判断
        - 欠損値を含むデータを除外したら、学習に必要なデータ量が確保できない場合
            - 平均値や最頻値などで補完
        - 欠損値を除外しても分析結果に大きな影響を与えない場合
            - 欠損値が含まれる行ごとまたは列ごと除外
        - 欠損値の割合が高い行や列があるデータ
            - 情報量が少なく分析に耐えられないので除外

### 外れ値処理

- 外れ値とは、他の多くの値から大きく外れている値
    - 外れ値が残ったまま学習データとして使用すると、全体の結果がゆがんでしまう
    - 極端に大きな値や小さな値を学習データに含めると、結果が外れ値に引っ張られてしまう
- データの分布から外れ値の有無を確認
    - データをヒストグラムや箱ひげ図などにしてチェック
- 外れ値の発生原因
    - データ入力の誤り
    - 値そのものは正しいが、偶然外れが生じた
- 外れ値の対処法
    - 発生原因が、入力ミスやシステムエラーなどと判明した場合
        - 正しい値に修正
    - 発生原因不明、または外れ具合が大きい場合
        - データを行ごと除外
    - 発生原因判明し、かつ分析結果に大きな影響がない場合
        - そのまま使用

### ダミー変数化

- ダミー変数とは、`ある状態であるか否か`を`0/1`で表すもの
    - ダミー変数化によって数字ではないデータを数字に変換して扱える
- 質的データからダミー変数への変換例
    - 男性: `1`、女性: `0`

## 多重共線性問題の回避

- 多重共線性問題とは
    - 関連性が高い変数を同時にモデルに組み込むと、正しい結果が得られないこと
- 確認方法
    - データ間の相関係数が大きい場合、多重共線性が疑われる
- 対処法
    - 関連性が高い変数が2つある場合は、どちらかを除外してから使用

## おわりに

信頼できるMLモデル生成には、データ前処理が欠かせない。
データ前処理、奥深いですね。
次回も続きます。お楽しみに。

##### [次回] [AWS公式資料で挑むMLS認定(16)-特徴量エンジニアリング(データ前処理)](https://qiita.com/mingchun_zhao/items/b082e8a07e6abd1e460b)
Windows に Yarn (Yarn Classic) をインストールする方法

Windows10 のPCにパッケージ管理システム Yarn をインストールして確認するまでの手順を備忘録としてまとめました。参考にして頂ければ幸いです。

- 前提条件（動作環境）
- yarnのインストール
- インストール完了の確認

なお、[modenバージョン](https://yarnpkg.com/) と[classicバージョン](https://classic.yarnpkg.com)がありますが、今回は[classicバージョン](https://classic.yarnpkg.com) インストールです。

# 前提条件（動作環境）

公式ページに Windows 用に用意されているのは次の３つ。

- npm 経由でインストールする
- インストーラをダウンロードする
- Chocolatey 経由でインストールする
- Scoop 経由でインストールする

Node.js にされている npm経由でインストールすることが推奨とのことですが、うまくいかなかったので（詳細は省略）、今回は、とりえす、「インストーラをダウンロードする」を選択しました。
そのための前提条件は次の通りです。

- Node.js がインストールされ、動作すること
- npm がインストールされ、動作すること

これらの前提がまだ満たせていない場合はまずは次の記事を参考に前提部分の環境構築を完了させてください。

https://qiita.com/gahoh/items/8444da99a1f93b6493b4


なお、検証した動作環境は次の通りです。

- OS: Windows 10 Pro 21H2
- Node.js: v16.15.0
- npm: 8.5.5

# yarnのインストール

yarnの [公式ページ](https://yarnpkg.com/)

![image.png](https://raw.githubusercontent.com/gahoh/articles-qiita/main/Install-yarn-winodws/images/screen1.PNG) <br>

 [Yarn 1 (Classic)](https://classic.yarnpkg.com) のサイト へ移動。

![image.png](https://raw.githubusercontent.com/gahoh/articles-qiita/main/Install-yarn-winodws/images/screen3.PNG) <br>

[INSTALL YARN] をクリック

![image.png](https://raw.githubusercontent.com/gahoh/articles-qiita/main/Install-yarn-winodws/images/screen4.PNG) <br>

[▶ Click to expand / collapse]  をクリック

![image.png](https://raw.githubusercontent.com/gahoh/articles-qiita/main/Install-yarn-winodws/images/screen6.PNG) <br>

[Download Installer] をクリック

![image.png](https://raw.githubusercontent.com/gahoh/articles-qiita/main/Install-yarn-winodws/images/screen7.PNG) <br>

インストーラをダブルクリックすると、次のような画面が表示されインストールの実行が開始されます。<br>

[Next] をクリックする。

![image.png](https://raw.githubusercontent.com/gahoh/articles-qiita/main/Install-yarn-winodws/images/screen10.PNG) <br>

[Next] をクリックする。

![image.png](https://raw.githubusercontent.com/gahoh/articles-qiita/main/Install-yarn-winodws/images/screen11.PNG) <br>

[I accept the term in the Licence Agreement] にチェック。

![image.png](https://raw.githubusercontent.com/gahoh/articles-qiita/main/Install-yarn-winodws/images/screen12.PNG) <br>

[Next] をクリックする。

![image.png](https://raw.githubusercontent.com/gahoh/articles-qiita/main/Install-yarn-winodws/images/screen13.PNG) <br>

インストール先を選択し、[Next] をクリックする。

![image.png](https://raw.githubusercontent.com/gahoh/articles-qiita/main/Install-yarn-winodws/images/screen14.PNG) <br>

[Install] をクリックし、インストールを開始する。

![image.png](https://raw.githubusercontent.com/gahoh/articles-qiita/main/Install-yarn-winodws/images/screen15.PNG) <br>

インストールは数十秒～1分程で終了したと思います。

![image.png](https://raw.githubusercontent.com/gahoh/articles-qiita/main/Install-yarn-winodws/images/screen16.PNG) <br>

インストールが完了。最後に [Finish] をクリックすれば、インストール作業は終わりです。。

# インストール完了の確認

引き続き、ちゃんとインストールされたかの確認も行っていきます。

Yarn のインストールを確認するには、コマンドプロンプトで次のコマンドを実行します。

```
> yarn -v
1.22.19
>
```

これで、Windows に Yarn (Yarn Classic) のインストールは完了です。

---
Chrome の Shortkeys 拡張機能で快適キーボード生活

# ブラウザーを使う作業を効率化したい

日常的に利用するシステムは、マウスを動かさずできるだけキーボードだけで操作したいですよね。
しかし Web アプリケーションだと、ブラウザーのショートカットキーに頼らざるをえないのでキーボードでできることに限界があります。そんなときに便利なのが、 Chrome に好きなショートカットキーを割り当てることができる Shortkeys という拡張機能です。

# Shortkeys の導入

Shortkeysは [Shortkeys 拡張機能のページ](https://chrome.google.com/webstore/detail/shortkeys-custom-keyboard/logpjaacgmcbpdkdchjiaagddngobkck) からインストールすることができます。
ページ右上の「Chrome に追加」をクリックしてインストールします。
デニムのショーパンのようなアイコンが特徴です。

![shortkeys.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/926617/3643eacc-ecae-d1e4-ba6f-e99d6b3dd1fe.png)

# Shortkeys の設定

![shortkeys-menu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/926617/f5e78859-a3b3-ddeb-dc68-b1d9e1b145bd.png)


Shortkeys 機能拡張をインストールて有効にしたら、Shortkeys の「オプション」メニューを選択し、設定画面を開きます。「Shortcuts」タブで、ショートカットキーを設定していきます。

![shortkeys-options.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/926617/4a45bd3e-e2ff-aa3a-cb8a-686fc5ba6712.png)

「Shortcut」にはショートカットキーの組み合わせを記述します。同時に押すキーを「+」でつなげます。

モディファイアキーはそれぞれ以下のように記述します。(Macの場合)
|  モディファイアキー  |  記述  |
| ---- | ---- |
|  コマンドキー  |  command  |
|  コントロールキー |  ctrl  |
|  オプションキー |  option  |
| シフトキー | shift |



例えば、コマンドキーとコントロールキーを同時に押しながら「/」(スラッシュ)を押す場合は、以下のように記述します。

```
command+ctrl+/
```

Label にはショートカットキーによる操作の名前を入力し、 Behavior では操作する内容をプルダウンから選択します。現在開いているタブで、ブックマークやブックマークレットを開く場合は「Open bookmark/bookmarklet in current tab」を選択します。

Shortcut settings では、ブックマークの一覧が Bookmark プルダウンに表示されるので、起動したいブックマークを選択します。

Activation settings では、以下の設定があります。

(1). Active while in inputs
入力フォームへの入力中もショートカットを発動させたい場合はこれを ON にします。

(2). 対象の Web サイト
[All sites] [All sites except ...] [Only on specific sites] から選びます。
All sites except ... では一部のサイトだけ対象外にできます。
Only on specific sites では特定のサイトだけを対象にできます。
`https://www.example.com/*` のようにワイルドカードを記述することができます。

# Redmine での利用例

Shortkeys を利用して、Redmine での操作にショートカットキーを割り当ててみます。

## Redmine チケットで編集モードに入る

チケットのページで編集を行う場合は、以下のようなブックマークレットを用意し、ショートカットキーを割り当てます。
```
javascript:location.href+='/edit';
```

## 優先度を高めにする

編集中のチケットのページで優先度を高めにするには、以下のブックマークレットを割り当てます。

```
javascript:;f=document.getElementById("issue_priority_id");f.focus();f.options[2].selected=true;
```

## 編集したチケットを保存する

編集中のチケットを保存するには、「送信」ボタンをクリックする動作を記述すればいいのですが、うっかり間違えて保存しないように、確認のダイアログを挟んでいます。 (window.confirmによるダイアログは Enter キーだけで操作できます。)

```
javascript:f=document.querySelector("#issue-form%20input[name='commit']%22);if(window.confirm(%22OK?%22))f.click();
```

Redmine での利用例を挙げてみましたが、ほかの Webアプリケーションでもブックマークレットを割り当てることで、作業の効率化が図れるところが随所にあると思います。ぜひご活用ください。