OmniAICreator/Qiita-1.07M huggingface dataset:
テスト計画について②

# テスト要求分析
## 計画を立案する前にすべきこと
そのテストが成功するか失敗してしまうのか、多くはテスト計画で決まると言って過言ではありません。そのテストを計画する前に、行うべきものがあります。
- 要求を整理し、正しく理解しする
- 状況を整理し、正しく理解する
- 未決事項・課題・リスクを整理し、戦略を練る

## 要求を整理し、正しく理解する
いかに技術的に秀でたテストを実施しても、顧客から求められるものに沿ったものでなければ、意味はありません。そのため、さまざまな計画を検討する前に、まず、顧客やステーホルダから「何に対し、どんなテストを実施するよう求められているか」を確認します。

- テスト対象は何か
- テスト範囲は何か（特に他システムと関連する部分）
- テストの規模はどの程度か（機能数やが画面数や開発量など）
- テストレベルは何か
- 求められているテストタイプや観点（テスト条件）は何か
- 顧客・ステークホルダーが時に重視して売るのかは何か
- テストの期間・コストはどれくらいか
上記の「テストへの要求」を明らかにする際には、なぜそれが要求されているのか、理由や背景も理解するようにします。理由や背景を理解することで、開発プロジェクトが置かれた状況をより深く理解できます。ひいては、未決事項・課題・リスクの抽出に役立ちます。

## 状況を整理し、正しく理解
テスト計画を策定するためには、テストへの要求だけでなく、ソフトウェアの開発状況や顧客・ステークホルダの状況なども整理していきます。
主な確認事項。

開発規模(プログラムStep数など)
開発難易度(スクラッチ開発、中核部分に大規模改修、新しい要素技術など)
開発スタイル(ウォーターフォール型開発、アジャイル開発など)
仕様の明瞭さ（仕様書は揃っているか、曖昧でないかなど）
開発でのレビューの実施状況、前工程でのテストの実施状況
開発プロジェクトの進捗（何がオンスケジュールで、何が遅れているのか、およびその理由）

## 状況を整理し、正しく理解する
テスト計画を策定するためには、テストへの要求だけでなく、ソフトウェアの開発状況や顧客・ステークホルダーの状況なども整理していきます。
確認事項は以下の通りです。
- 開発規模(プログラムStep数など)
- 開発難易度(スクラッチ開発、中核部分に大規模改修、新しい要素技術など)
- 開発スタイル（ウォーターフォール型開発、アジャイル型開発など）
- 仕様の明瞭さ（仕様書は揃っているか、曖昧でないかなど）
- 開発でのレビューの実施状況、前工程でのテストの実施状況
- 開発プロジェクトの進捗（何がオンスケジュールで、何が遅れているのか、及びその理由）

これらを確認するのは、以下を検討し、計画に反映するためです。

- テストはどんなものが必要で、どのように進めるか
- 使用理解など、テストの設計・準備・実施の他に必要な作業は、何がどの程度か
- 品質の良い・悪はどの程度か、各タスクはどの程度の工数が必要か
- 未決事項・課題・リスクは何か

## 未決事項・課題・リスクを整理し、戦略を練る
テストに求められているもの、開発の状況を整理したら、更に未決事項・課題・リスクの整理を行います。

### <未決事項>
まだ正式決定されていない、合意されていないものを指す。
何が決定事項か未決事項か、意外に曖昧なことが多い。
一つひとつを確認し、未決事項であれば、その影響範囲、重要度によって、対処の優先順位を設定する。

### <課題・リスク>
課題とリスクの違いは、以下の通り。
課題　：すでに何か問題が発生しており、それをいかに解決するか
リスク　：まだ問題は発生していないが、未来に発生することが危ぶまれているもの

上記を踏まえて、計画を練っていく中で行いたいことは以下の二点です。

- ミケ事項や課題には、早朝に適切に対策し、それを計画に盛り込む。
- リスクを管理かに置き、問題そのものを起こさせないようにする。または問題が発生してもダメージがより小さくなるようにする。

## まとめ
そのテストが成功するか失敗してしまうのか、多くはテスト計画で決まると言って過言ではありません。
そのテストを計画する前に、行うべきものがあります。
- 要求を整理し、正しく理解する
- 状況を整理し、正しく理解する
- 未決事項・課題・リスクを整理し、戦略を練る
上記によって、要求と状況に沿ったテストを的確に推進できるようにします。
「問題が起きてから対策する」のような「問題の後追い」をせず、未決事項や課題には計画的に対処していきます。更に、リスクを管理下において問題そのものが発生しないように、マネジメントします。
これらの整理をした上で計画を策定すると、考慮のもれぬ怪我防止でき、細かいところまで気を配り、マネジメント力を強化することができるのです。
[Dart] staticとは

# staticの使い方

```static``` はクラスのプロパティ・メソッドはクラスをインスタンス化せずに使用できるようにするもの。

```dart:具体例
void main() {
  print(Car().wheelNum); //Car()でインスタンスを作成している。
  print(Bike.wheelNum); //Bikeなのでインスタンスを作成していない。
}

class Car {
  int wheelNum = 4;
}

class Bike {
  static int wheelNum = 2;  
}
```

# まとめ
インスタンスを作成しない方が、メモリ的にも良いことが多そう。
```const```と合わせてうまく使うようにしていきたい。
warning: constant Gem::ConfigMap is deprecated

# warning: constant Gem::ConfigMap is deprecated

## 初めに
先日他の人のrubyのプロジェクトと`git clone`でクローンしコードをレビューする機会があり、その際に表示されたエラーについて書いていこうと思います。

## 原因
rubygemのバージョンが遅れていることによって起きるエラー

## 解決方法

rubygemを入れ直してあげてバージョンを変えてあげればok
``` 
$ gem uninstall rubygems-update
$ gem install rubygems-update -v=2.7.6
$ update_rubygems
```
Go言語でCUIベースのテキスト型アドベンチャーゲームを作りました

Go言語はモダーンなプログラミング文法を持ち、マルチスレッド処理が得意な
「ハイ・エンド」なコンピュータ言語なのに、CUIベースのテキスト型
アドベンチャーゲームを作りました。

下記のURLからZIPファイルをダウンロードできます
（実行には Goコンパイラが必要です。verは多分、1.13以上であれば大丈夫）

https://github.com/new-doumeishi/travel_to_search_X.git

このゲームは主人公の「たかし」が東京の街を移動して「たい焼き器」を探す
というゲームです。
各街で「探す」コマンドで探せますが、誤って爆弾を引いてしまうことが
あります。
「たかし」は無事に「たい焼き器」を探すことができるでしょうか。
Xmingでrqtが開けなかった話

# はじめに
ros2の勉強をwsl2で始めようとしたとき、なぜかXmingではrqtが出ませんでした。
具体的には以下のエラーが、
```shell
X server does not support XInput 2
failed to get the current screen resources
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-ubuntu'
libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
The X11 connection broke: I/O error (code 1)
XIO:  fatal IO error 0 (Success) on X server "172.18.16.1:0.0"
      after 366 requests (366 known processed) with 0 events remaining
```
しょうがないのでVcXsrvを使ってみたら成功したので、セットアップを記述します。
特に変わったことはしていません。

過去にXmingをセットアップした時の記事はこちら
https://qiita.com/kaerun/items/fb8ff6295e82bdea0c45
# 環境
- WSL2
    - Ubuntu 20.04.4 LTS
- VcXsrv-64.1.20
# 方法
## VcXsrvの準備
公式からinstaller.exeをダウンロード、インストール

設定は参考記事通りに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2260202/c6f48254-bb24-8ea1-a81f-250759a45b5f.png)
## .bashrcの変更
以下をたたく
起動毎にたたくのも面倒なので.bashrcに書いておくとよき
```shell
export DISPLAY=$(ipconfig.exe | grep IPv4 | grep 192 | awk -F'[ ]' '{print $17}' | tr -dc 0-9.):0.0
```
<details><summary>コマンドの解説</summary>

参考サイトに書いてある通り以下の設定をする必要がある
```shell
export DISPLAY=aaa.bbb.c.dd:0.0
```
aaa.bbb.c.ddはwslを起動しているパソコンのipアドレス
0.0はVcXsrvを起動している時のアイコンにカーソルを合わせた時に出る番号

aaa.bbb.c.dd:0.0の部分を渡すコマンドを作りたいのでパイプでつないでいく
awkを叩いた時点で完成しているように見えるが、改行などの制御文字が末尾に入っているため、trをする
</details>

# 参考
https://blog.goo.ne.jp/yoossh/e/bc577e16f12bee1ecd860f61f3ff594e
Salesforce オブジェクトのカスタマイズ  選択リストと項目の連動関係の作成


[選択リストと項目の連動関係の作成](https://trailhead.salesforce.com/ja/content/learn/projects/customize-a-salesforce-object/picklists-field-dependencies)

エラーメッセージ

# We couldn't find a dependency between two picklists.

まだ、商談の連動関係を作成してない状態。

+ [Create Picklists and Field Dependencies](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000NFau7)


+ [Create Picklists and Field Dependencies](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000O95Gb)

:::note
In the Custom Field "Close Reason" under the "Opportunity" Object in the "object manager" section, I had the "Field Label" correcty set as "Close Reason", but the auto-filled "Field Name" was simply "Close".

Edit this so that the "Field Name" is listed as "Close_Reason" instead of the auto-filled "Close".  Once I did that my challenge was completed.  (I also deleted and recreated the Close Reason field dependency after doing this, not sure if that was necessary)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/1eae8db1-7190-7710-8177-6a1b053372a3.png)

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


「オブジェクト マネージャー」セクションの「商談」オブジェクトの下にあるカスタム フィールドの「クローズ理由」で、「フィールド ラベル」を「クローズ理由」として正しく設定しましたが、自動入力された「フィールド名」は単に「クローズ」でした。 "。

これを編集して、「フィールド名」が自動入力された「Close」ではなく「Close_Reason」としてリストされるようにします。それができたら、私の挑戦は完了しました。 （これを行った後、クローズ理由フィールドの依存関係も削除して再作成しましたが、それが必要かどうかはわかりません）
:::




+ [Create Picklists and Field Dependencies](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000O95GbSAJ)

:::note
I deleted and recreated the region and zone field dependencies. I completed this picklist and field dependencies module.


リージョン フィールドとゾーン フィールドの依存関係を削除して再作成しました。この選択リストと項目の依存関係モジュールを完了しました。
:::

+ [Error We couldn't find a dependency between two picklists](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007BEwvz)

:::note
 I repeat the "Close Reason" field, but it doesn't work... I repeat the entire challenge and I can't find the mistake, I saw a video on youtube and the difference between the video and my challenge is that de dependency between two picklist in the video is in Account object and mine is developed in opportunity object.
:::

# よく理解できない

+ [No STAGE in the Controlling Field for the Create Picklists and Field Dependencies.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000EndV6)
【Windows】BitbacketにSourcetreeでSSH接続する方法

いつもどおりにSourcetreeでpushしようと思ったらエラーで止まるようになってしまった。
よく読むと、SSH接続じゃないとダメになったとのこと。
同じことで困ってる方がいたらご参考にどうぞ。

ただ私はエンジニアではなく、仕事でGitが必要なデザイナーなので、
何か間違っていることがあっても見逃してください。

Bitbacket公式の説明ページもあるんだけど、
https://support.atlassian.com/ja/bitbucket-cloud/docs/set-up-an-ssh-key/
中途半端に日本語で見にくいので、
https://support.atlassian.com/bitbucket-cloud/docs/set-up-an-ssh-key/
この英語のほうが見やすかった。

～以下の【】の中は自分の環境に合わせて変えてください。～

## なんでこんなことに？
BitbacketがSSH接続じゃないといけないように2022/03に変わったらしい。


## まずはSourcetreeで設定を確認する。

 メニューの
ツール　＞　オプション　＞　認証タブ　＞ 編集ボタン
ホスティングサービス：Bitabacket
ホストURL：https://bitbacket.org/
優先するプロトコル:SSH

認証：OAuth
ユーザー名：【ユーザー名】
OAuthトークンを読み込み（※よくわかってないけどこっちにしてみた）

 ☑認証に成功
となっているので問題なさそう。

### リモートの設定
メニューの　リポジトリ　＞　リポジトリ設定　
パスを選択して編集ボタンを押す
URL/パス：　git@bitbucket.org:【ユーザー名】/【リポジトリ名】.git
の形式にする（https://~だったら変更する！）
ここがhttps接続のままだとうまくいかない

## Gitbashをインストールする
コマンドプロンプトだとだめな場合があるらしいからインストールする
（最近Macが壊れてWindowsを使ってるからインストールしてなかった）

公式サイトからDLしてくる
Gitをインストールすると一緒についてきてるから、windowsのスタートメニューをクリックしたところで入力して検索してみる

## SSH鍵を作る
（以下の作業はWindows Powr Shellとかコマンドプロンプトではできない）
Gitbash開いて、場所はホームそのままで
`$ ssh-keygen`
すると
```
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/【ユーザー名】/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /c/Users/【ユーザー名】/.ssh/id_rsa
Your public key has been saved in /c/Users/【ユーザー名】/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:ほにゃほにゃほにゃほにゃほにゃほにゃほにゃほにゃほにゃ
The key's randomart image is:
+---[RSA 3072]----+
| .      E.o.     |
|o. .   o ++      |
|+ + + +  =       |
|.+ = X .o o      |
|+.+ * = So       |
|o++* o .         |
|==o.o            |
|O oo             |
|oBoo             |
+----[SHA256]-----+

```
ってことで、
`【ユーザーフォルダ】/.ssh`ってフォルダができている
（windowsのユーザー名のフォルダの直下にある）

そのままGitbashで下記コマンド実行
```
$ eval $(ssh-agent)
```
すると
`Agent pid 267`
とか出てくる。よくわからないけど。

次に、パスを追加？してあげる
```
$ ssh-add ~/.ssh/id_rsa
```
すると、
```
Identity added: /c/Users/【ユーザー名】/.ssh/id_rsa (【ユーザー名】@X【ユーザー名】R)
```
とかなって成功！

## Bitbacketにキーを登録する
画面左下の自分のアイコンのところクリック
Personal Settings ＞　セキュリティ　＞SSH鍵　を開く
鍵を追加ボタンを押す
Labelは好きな言葉を入れる
Keyはさきほど作成した
`【ユーザーフォルダ】/.ssh`　フォルダに入っている
id_rsa.pubをメモ帳とかで開いて全部選択→コピペする
鍵を追加ボタンを押す

以上で完了

## SourceTreeでsshキーを変換する
ツール > SSHキーの作成/インポート
Loadボタンから先程作成したid_rsa.ppkを開く
Save private keyで拡張子を.ppkにしたものを~/.ssh/配下に保存する
（元々あるファイルはid_rsaで拡張子がない）


## Pageantにsshキーを追加する
アイコン右クリック＞Add Key
前の項目で作成したid_rsa.ppkを登録する
（拡張子ない方は、ファイル形式がwindowsにあってないのか、無効な形式です、とエラーがでてしまって登録ができない）

## これでやっとpushできた！


Gitbachにもどり、
```
$ git push origin master
```
とやったら久しぶりにpushできました！！！

はぁ～すごい時間かかった。
【備忘録】Shift-JISで書かれたファイルをUTF-8に変換する

# 目的
```
error_code='999' message='��������'
```
CurlコマンドでAPIのテストを行い、エラーが発生したためエラー文を確認しようとしたところ。
上記のように文字化けしてしまっていた。

このファイルがShift-JISで書かれているからだ。
そこでlinux上でiconvというものを利用してutf-8に変換してみた

# 結論
```bash
iconv -f sjis -t utf-8 <file_name> >test.utf8
```

# 経緯
"utf-8"の部分を"utf8"と記述している記事を多く見かけて、試してみると下記のようなエラーが
```
iconv -f sjis -t utf-8 ValueCharge.sh.log >ValueCharge.utf8
```
表示された。

バージョンによっては"utf8"でよかったのかもしれないが、自分の場合は"utf-8"に変更することで無事urf-8へ変更することができた。


# 参考
[Shift-JISのソースをiconvでUtf-8に変換してclangでエラー](https://qiita.com/kjunichi/items/518e337d29cc5bf6a70b)
【NestJS】環境変数を設定してグローバルモジュールで読み込む方法

# 概要
環境変数を設定して各モジュールで読み込む方法をまとめる

https://docs.nestjs.com/techniques/configuration

# 依存関係をインストール

```bash
npm i --save @nestjs/config
```

# カスタム構成ファイルを定義

```typescript:config/configuration.ts
export default () => ({
  nodeEnv: process.env.NODE_ENV || 'development',
  server: {
    port: parseInt(process.env.PORT) || 3000,
    hostName: process.env.hostname || 'localhost:3000',
  },
  database: {
    host: process.env.DB_HOST || 'localhost',
    port: parseInt(process.env.DB_PORT) || 5432,
    user: process.env.DB_USERNAME || 'root',
    pass: process.env.DB_PASSWORD || 'password',
    name: process.env.DB_NAME || 'sample',
  },
  auth: {
    jwt_secret_key:
      'Bearer xxxxx',
    hashSalt: 10,
  },
})
```

# メインモジュールで読み込む

```ts:src/app.module.ts
@Module({
  imports: [
    ConfigModule.forRoot({
      // グルーバルモジュールにする
      isGlobal: true,
      
      // カスタム構成ファイルを読み込み 
      load: [configuration],
    }),
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (configService: ConfigService) => ({
        type: 'mysql',
        host: configService.get('database.host'),
        port: Number(configService.get('database.port')),
        username: configService.get('database.user'),
        password: configService.get('database.pass'),
        database: configService.get('database.name'),
        entities: [join(__dirname + '/domain/entities/*.entity{.ts,.js}')],
        extra: {},
      }),
      inject: [ConfigService],
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(LoggerMiddleware, OemSettingMiddleware).forRoutes('')
  }
}

```
Admin Beginner > Data Modeling > Create Object Relationships

[Trailhead関係　個別の課題別に戻る](https://qiita.com/Keiji_otsubo/items/56eb7a90bb72138ece1f)

+ [Admin Beginner > Data Modeling > Create Object Relationships](https://qiita.com/Keiji_otsubo/items/b785fdf343cc63ea0bcf)
+ [Create Master-Detail Relationship for Challenge in Create Object Relationships course](https://qiita.com/Keiji_otsubo/items/fe5b2a74c6cba088bd6e)


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

このチャレンジは結構質問が多いです。

チャレンジはこれ
[Create Object Relationships](https://trailhead.salesforce.com/en/content/learn/modules/data_modeling/object_relationships?trail_id=force_com_admin_beginner)

# 質問

+ [オファーオブジェクトがありません](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000FTTlc)

+ [Data Modeling training module, Master-Detail relationships.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007JAFOy)

:::note
Please select Favorite object

Create a Lookup Relationship
We’re going to create two custom relationship fields on the Favorite object. First, let’s create a lookup relationship that lists the users who select Favorite for a property. 

https://trailhead.salesforce.com/content/learn/modules/data_modeling/object_relationships
:::


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

+ [Module 2 issue with adding "Property" to a Master-Detail Relationship](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000J5tNq0AJ)

FavoriteでなくOffer objectに設定する

Create a custom Master-Detail field on the Offer object
+ Data Type: Master-Detail
+ Related To: Property
+ Field Label: Property
+ Field Name: Property

Create a custom Lookup Relationship field on the Offer object
+ Data Type: Lookup Relationship
+ Related To: Contact
+ Field Label: Contact
+ Field Name: Contact
[js] 非同期処理のdone, failを卒業する


非同期処理を普段どう書いていますか？
僕はdone-failを用いて書いています。実はこの書き方保守性の面であまり良くない。
*jqueryを使用

```js
$.ajax({
　  url: 'https://zipcloud.ibsnet.co.jp/api/search?zipcode=7830060'
　})
　.done(function(res) { 
   console.log(res);
　})
　.fail(function(res){ 
   console.log(res);
　});
// =>
// {
//   'message': null,
//   'results': [{ ... }],
//   'status': 200
// }
```

*以下ajaxの中は簡略化します。

# 問題1. errorキャッチができない
doneの中でエラーが出たときにfailがキャッチしそうですが実はキャッチできません。

もしdoneの中でエラーハンドリングを行いたい場合はtry-catchを毎回書く必要があります。
さらにtry-catchでネストが深くなるのも嬉しくない。

```js
$.ajax()
　.done(function(res) { 
   throw 'error';
   console.log(res);
　})
　.fail(function(e) { 
   // キャッチできない
   console.log(e);
　});

// Uncaught error 
```



# 問題2. コールバック地獄
例えば「ajax通信を複数使いたいが同期的に行いたい時」や「スコープ外の変数へのアクセスのためにコールバックを用いたい時」にネストを深くするスパイラルから抜け出せなくなります。

所謂コールバック地獄。

```js
function successFunc(data) {
  // ...
}

function fetch(callback) {
  $.ajax()
  .done(function(res1) { 
    $.ajax()
    .done(function(res2) { 
      // 終了時の処理
      callback(res2);
     })
    .fail(function(res) { ... }) 
　  })
　  .fail(function(res) { ... })
})

fetch(successFunc)
```

# 解決策
コールバックを防ぐ手段として[Promise](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise)で制御する方法があります。
Promiseに続くthenは同期的に処理を行うことを示しています。したがってコールバック地獄から抜け出せる。また、then-catchを用いることでエラーハンドリングも可能。

少し今風の書き方に変えてこんな感じで書ける。
```js
const fetch = () => {
  return new Promise((resolve, reject) => {
    $.ajax()
    .done(res => {
      // ...
      resolve(res)
    })
    .fail(res => reject(res));
  });
}

// then-catch
fetch().then(res => ... ).catch(e => )
```

さらにjQueryの$.ajaxはPromiseを内包したDeferredオブジェクトが返ってくるので、より簡潔に書ける。
参考：[爆速でわかるjQuery.Deferred超入門](https://techblog.yahoo.co.jp/programming/jquery-deferred/)

```js
const fetch = () => {
  return $.ajax();
}

fetch().then(res => {
    // ...
    return var
  }).then(var => {
    // ...
    throw 'error'
  }).catch(e => console.log(e))
// => error
```

ここで注目すべきところはdone-failは連結できないがthenは連結できるというところ。

理由はthenがPromiseオブジェクトを返すから。
参考：[Promiseチェーン](https://ja.javascript.info/promise-chaining)

# async/await
さてPromiseオブジェクトを返しthen-catchを使うことでdone-failを卒業できそうな気がします。

ただ毎回resolve,rejectを書くのは忘れてしまいそうですしthenの見通しが少し悪い気もします。

もっと直感的な書き方はできないのか。。。

ありました！
その名も[async-await](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function)！

asyncはPromiseを返し、resolveやrejectを明示的に使わずthenチェーンがかけます。
また、asyncの中でawaitをつけた関数がある場合、awaitの関数が終了するまで後続の処理は実行されません。

```js
const fetch = () => {
  return $.ajax(...)
}

const timer2Seconds =　res => {
  return new Promise(resolve => {
    setTimeout( () => {
      console.log(res);
      resolve('timeout');
    }, 2000);
  });
}

const main = async () => {
  const res = await fetch();
  const timer = await timer2Seconds(res);
  return timer
}

main().then(message => {throw message}).catch(e => console.log(e));
// => timeout
```

メリットはこちらの記事がわかりやすいです。
[JavaScriptのasync/awaitがPromiseよりもっと良い](https://qiita.com/Anders/items/dfcb48d8b27ceaffb443)
【備忘録】自分向け爆速でAzure deployment.jsonを作成する 

# 爆速でAzure deployment.jsonを作成する 

### 方法１：コンテナinspectで作成

deployment.jsonの対象となるコンテナを以下のコマンドで確認

```
docker inspect <コンテナID>
```

以下をcreateOptionsに記載。記載方法はjson形式ではない。一文にする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908963/2b8b8def-0330-6dd8-e99e-a2a5c0255bf5.png)


以下を参考に
https://docs.microsoft.com/ja-jp/azure/iot-edge/how-to-use-create-options?view=iotedge-2020-11


### 方法2：docker-compose.ymlを活用


- VScodeをAzureと連携させる
- docker-compose.ymlを作成する
- 「iotedge-compose」をpip installし、deployment.jsonを自動生成する

以下を参考に
https://devblogs.microsoft.com/iotdev/convert-your-docker-compose-project-to-azure-iot-edge-solution/
AWS CDK - Lambda への Layer（ARN）のアタッチ


# デプロイ済の Layer 構成

```
  └─ nodejs/
      ├─ @layer/
      │     └─ util/
      │          ├─ index.js
      │          ├─ package.json
      │          └─ package-lock.json
      │
      ├─ node_modules/
      ├─ package.json
      └─ package-lock.json
```

# デプロイ済の Layer 実装

```javascript:index.js
module.exports = {
  sample: value => {
    return value;
  },
};
```

# Layer（ARN）をアタッチした Lambda 定義

※ Layer（ARN）を SSM に格納しておいた場合

```typescript:stack.ts
import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';
import * as lambdaNodejs from '@aws-cdk/aws-lambda-nodejs'
import * as ssm from '@aws-cdk/aws-ssm';
export class AwsCdkTsStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const utilLayerArnParamName = '/layer/utilLayerArn';
    const utilLayerArn = ssm.StringParameter.valueForStringParameter(this, utilLayerArnParamName);
    const utilLayer = lambda.LayerVersion.fromLayerVersionArn(this, 'utilLayer', utilLayerArn);

    new lambdaNodejs.NodejsFunction(this, 'api', {
      layers: [utilLayer],
      bundling: {
        externalModules: ['@layer/util']
      },
    })
  }
}
```

# Layer を使用する Lambda 実装

```typescript:stack.api.ts
import { Handler } from 'aws-lambda'
const util = require('@layer/util');

export const handler: Handler = async () => {

  const result = util.sample(100);
}
```
Dockerのボリュームのマウントとは【個人的なお勉強アウトプット】

## ボリュームとは
PCからみたときのストレージの1領域を区切ったもの。

### わかりやすい記事
https://wa3.i-3-i.info/word11885.html

## マウントとは
取り付ける、の意味通り対象を接続してOSやソフトウェアの支配下に置くこと。

## Dockerのライフサイクル
Dockerは作って消す、のライフサイクルがある。
なぜライフサイクルがあるかはDockerのメリットと運用方法にある。
Dockerはコンテナをアップデートしながら大事に使うのではなく、アップデートされたソフトウェア入の新しいコンテナを使う。
コンテナを使う状況として、一般的には複数のコンテナを同時かどうすることを想定しているため。
ひとつずつコンテナをアップデートさせるのは大変。構築より保守のほうが大変。
なので古いコンテナは捨てて、新たにイメージから新しいコンテナを作り直す。

## データの保存
コンテナを破棄するときに消すたくないファイルもある。
それらをマウントし、保存し、残しておけるようにする。

### マウントには2種類ある
- ボリュームマウント
- バインドマウント

#### ボリュームマウント
DockerEnginの中に置く
触りづらかったり、バックアップが取りづらいので、あまり触らないファイルの場合選ばれる。
#### バインドマウント
ホストのPCのどこかに置く。
頻繁に触りたいファイルをマウントする場合選ばれる。

## マウント方法
コンテナの中の特定の場所にあるように見せかけて、実は違う場所（DockerEngin or ホストのPC）に置く。
デスクトップのショートカットをつくるようなイメージ。

## 参考図書
https://www.amazon.co.jp/dp/B08T961HKP/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1
本日の基礎練習問題(22/3/17)

**問題**
以下の要件を満たすlone_sumメソッドを実装しましょう。
配列に格納された3つの数値の合計を出力する
ただし、同じ数値が2つ以上含まれている場合、その数値は合計する要素に含めない
```雛形
def lone_sum(ary)
  # 処理を記述
end
```
*呼び出し例
lone_sum([1, 2, 3])
*出力例
lone_sum([1, 2, 3]) → 6
lone_sum([3, 2, 3]) → 2
lone_sum([3, 3, 3]) → 0

# 私の回答
```
def lone_sum(ary)
 newary = ary.uniq!
 puts newary.sum
end

# 呼び出し例
lone_sum([1, 2, 3])
```
# 解説
まずuniq!メソッドで配列内の重複している数値を取り除く。
その後配列の合計値を出力する。

# 模範回答
```
def lone_sum(ary)
  # 配列から、重複しない要素のみ取り出す
  uniq_nums = []
  ary.each do |num|
    count = 0
    ary.each do |i|
      if num == i
        count += 1
      end
    end
    if count < 2
      uniq_nums << num
    end
  end

  # uniq_nums配列内の合計
  sum = 0
  uniq_nums.each do |unique_num|
    sum += unique_num
  end
  puts sum
end

# 呼び出し例
lone_sum([1, 2, 3])
```

# 模範回答
```
3〜14行目で重複しない値のみ取り出す処理を、17〜20行目で重複しない値のみになった配列内の合計を求める処理を行っています。以下具体的に見てみましょう。

たとえば、lone_sum([3, 2, 3])でメソッドを呼び出した場合を考えてみましょう。

この場合、4行目で最初にnum=3となります。その後6行目でi=3, 2, 3となり、それぞれに対してnum=iとなったとき、つまり重複したときにcountが増えるようになっています。
そして、11行目では重複した値が1つのときだけ、uniq_nums配列に値を追加しています。num=3のときはcount=2となるので、uniq_nums配列に値は追加されません。
これを後2回繰り返した結果、uniq_nums配列には2だけが追加されます。

そして17行目以下でuniq_nums配列内の合計を求めます。
この場合はsum = sum + 2、つまりsum = 0 + 2となります。
その結果、合計は2と出力されます。
```

# 感じたこと
正直難しく模範回答を見てもあまり理解できなかった。
しかし1つ1つ丁寧に見たら少しづつ理解することができた。
eachの入れ子構造に苦戦したが今回の問題で理解を深められたので
当てはまる処理の場合は使用したい。
plotly.jsの日付を日本語にし微調整する

# コード
```html
<!-- 抜粋 -->
<script src="https://cdn.plot.ly/plotly-locale-ja-2.11.1.js"></script>
```

```javascript
// 抜粋
window.locale.format.dayMonthYear = "%B %d日"; // ←微調整
const layout = { xaxis: { type: 'date' } }
const config = { locale: 'ja' };
Plotly.newPlot(id, data, layout, config);
```

# 参考
https://plotly.com/javascript/configuration-options/#change-the-default-locale

https://github.com/plotly/plotly.js/blob/master/dist/README.md#to-include-localization

https://cdn.plot.ly/plotly-locale-ja-2.11.1.js
Sprockets::ArgumentError at / link_tree argument must be a directory

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1717562/902ce827-5956-3086-b35b-e055e21f8d57.png)

## 初めに
今回は上記の写真のエラーについて、解説をしていこうと思います。
他の人のリポジトリから、railsのプロジェクトを引っ張ってきた際に出てきたエラーになります。

## 原因
まずSporoketsに対してエラーが吐かれているので、画像の読み込みらへんでエラーが吐かれているのかなと推測しました。そこで、`rails assets:precompile`を実行しエラーを確認しました。
そこで出力されたのが、`Sprockets::ArgumentError: link_tree argument must be a directory
/Users/hibiki/Desktop/Submission2-bookers_app/app/assets/config/manifest.js:1
Tasks: TOP => assets:precompile
(See full trace by running task with --trace)`という内容のエラーが出力されました。
そこで、manifest.jsを確認してみると
```
## manifest.js

//= link_tree ../images
//= link_directory ../stylesheets .css
```
このように記述されており、このコンパイルした際にこの一行目に対してエラーが吐かれていたので、みてみると`../images`でimagesのフォルダを探しているのがわかります。
そこで、manifest.jsの一つ上の階層をみてみると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1717562/b6e7eba0-09c9-2bbe-c27d-cb1089ca4deb.png)
このようなファイル構成になっており、link_treeで指定されていたimagesのフォルダがないように見えます。ここで、imagesのフォルダが消えてしまっていることに気づきます。
そのため今回の原因としては、assets配下にimagesのフォルダがないことが原因でした。

## 解決方法
imagesnのフォルダを作成してあげれば解決とのことなので、imagesのフォルダを作成してあげましょう。
```
## assetsの配下にimagesのフォルダを作成したいので移動する
$ cd app/assets

## フォルダを作成する
$ mkdir images

## gitで管理するために、imagesフォルダの中に.keepのファイルを作成する
$ cd images
$ touch .keep
```

## 最後に
なかなかお目にかかれないエラーになるかと思いますので、このエラー記事を参考記事にされる方は多くないと思いますが、もし一人でもこのエラー記事が参考になれば幸いです。
【AWS】EC2インスタンスの自動起動・自動停止設定方法 (22/03)

業務上でインスタンスの自動起動と停止(以下自動処理)を設定することがあったので備忘録として記録します。

## はじめに
EC2インスタンスの自動処理はそれぞれで設定します。
他にも再起動かけたり色々できそう(?)

参考にした記事は下記です。
[EC2 の自動起動と自動停止](https://blog.mori-soft.com/entry/2021/04/19/105832)

## I AMロールの作成
自動処理を行うロールの作成をします。
※ロールは起動・停止で共有できます。

- AWS⇒IAM⇒ロール⇒ロールの作成を選択
![role.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2291250/58b7aa3a-0ce6-b3ac-ba61-826ad96ebe9a.png)

- ユースケースは「他のAWSのサービスのユースケース」を選択
※後々ポリシー変更するので不要かも(?)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2291250/df3f6852-68e7-3d31-a460-79883680b681.png)

- ロール名・説明は任意。今回は`ec2-auto-event-role`としました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2291250/4d87075f-86e6-8fbf-a2a2-4854e48a20d5.png)

- 作成したロールを選択し、「許可」タブを以下のように変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2291250/cbaf3866-7ac3-c43e-dcc2-f2b2b1602b4e.png)

- 「信頼関係」タブの信頼されたエンティティを下記のように変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2291250/f2cb3598-7368-959d-aa26-cacd19ba632d.png)

ロールの作成は以上です。

## 自動処理の設定

自動処理の設定はAmazon EventBridgeで行います。

- EventBridge⇒ルール⇒ルールの作成を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2291250/4b2692f7-5673-4830-3fbe-7350a0004480.png)

- 名前・説明を入力し、ルールタイプはスケジュールを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2291250/288c45dd-1430-2faf-1ff9-1a6dc1baf69e.png)

- スケジュールパターンにcron式を入力
[Cron expressions](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule-schedule.html#eb-cron-expressions)
今回の例では毎日22:50分に起動する設定にしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2291250/fb6c6074-149e-f74f-d43d-d3a3dd53b930.png)

- ターゲット1の入力は下記の表通り

|項目|入力値|
|:---:|:--|
|ターゲット|System Manager オートメーション|
|ドキュメント|AWS-StartEC2Instance または AWS-StopEC2Instance|
|InstanceId|設定するインスタンスID`i-******`複数の場合は["i-*****","i-XXXXXX"]と記述|
|実行ロール|既存のロールを使用を選択して作成したI AMロールを選択|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2291250/29a0ac10-f863-920a-1b1f-5f5b74532e99.png)

上記で作成完了です。

## 注意点

[ターゲットの入力](#ターゲット1の入力は下記の表通り)時に設定するInstanceIdですが、フォーカスアウト時に勝手に変換されることがります。

`["i-01111111111111111","i-02222222222222222"]`と入力しているのに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2291250/7252d5ed-285c-f967-2974-3d6e532a4a5a.png)
↑の画像のようになってしまうことがあります。
再度フォーカスインして手動で直していると綺麗になりますので何度か試してみてください。

以上です。
Python 単一スレッド内で複数のスレッドを立ち上げてイベント制御したいときに読む (15秒で読めます)


```python
from threading import Thread, Event
import time
import random


class MyEvent():
    th1 = Event()
    th2 = Event()


def task1(event: MyEvent):
    while True:
        event.th1.wait()
        print('th1 run.')
        event.th1.clear()


def task2(event: MyEvent):
    while True:
        event.th2.wait()
        print('th2 run.')
        event.th2.clear()


# manage_thがth1とth2を立ち上げる
def manage_th(event: MyEvent):
    task_list = [task1, task2]
    for task in task_list:
        th = Thread(target=task, args=(event,), daemon=True)
        th.start()
    while True:
        # th1とth2のイベント制御を行う
        # n秒後にth1をsetして,n秒後にth2をsetする
        time.sleep(random.random())
        event.th1.set()
        time.sleep(random.random())
        event.th2.set()


# メインスレッド
def main_thread():
    while True:
        time.sleep(5)
        break


event = MyEvent()
th = Thread(target=manage_th, args=(event,), daemon=True)
th.start()

# 5秒後にメインスレッドを終了 → manage_th終了　→ th1,th2終了
main_thread()

```

# 感想
そろそろスレッド制御脱初心者したいですね。
【Laravel】AppServiceProviderにカスタムバリデーションを登録する。

自分用のメモとして残します。

AppServiceProviderのboot内に定義することで、暗黙的にインクルードされる。
そのため、フォームリクエスト内やコントローラ内でバリデーションで直ぐに使える。



# やり方

AppServiceProviderに任意のバリデーションルールValidator::extendで定義する。
下記の例は入力値を半角全角のカタカナ英数字を正規表現で判定します。
**katakana_or_number_or_abc** 呼び出せる。

```app\Providers\AppServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

use Illuminate\Support\Facades\Validator;


class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {

        Validator::extend('katakana_or_number_or_abc', function ($attribute, $value, $parameters, $validator) {
            $arr_regex= [
                '\-',//半角ハイフン
                'ー',//全角ハイフン
                '0-9' ,// 半角数字
                '０-９' ,//全角数字
                'ａ-ｚ' ,//全角英字（小文字）
                'Ａ-Ｚ' ,//全角英字（大文字）
                'a-z' ,//半角英字（小文字）
                'A-Z' ,//半角英字（大文字）
                'ァ-ヴ',// 全角カタカナ
                'ｦ-ﾟ' ,// 半角カタカナ
            ];
            $regex = '/^['.join('',$arr_regex).']+$/u';

            return preg_match($regex, $value);
        }, ':attributeはカナと英数字のみで入力してください。');

    }
}

```


以上です。
【Python3】ドラッグ＆ドロップしたファイルにタイムスタンプをつけてリネームする

# 概要

https://qiita.com/MakotoIshikawa/items/a9e31bc6f13ac203f98d

PowerShell の .ps1 ファイルには、直接ファイルをドラッグ＆ドロップできないので、ソースファイルとは別にショートカットを作成しなければなりませんでした。
ファイルだけで出来るように Python を使ってやってみました。

## 準備

まず、Python をインストールしておきます。

https://www.python.org/downloads/

## 手順

以下のファイルを作成します。

```python:Add-TimeStamp.py
import sys
import datetime
import pathlib
import os

daystr = datetime.date.today().strftime('%Y-%m-%d')
paths = sys.argv[1:]

for path in paths:
    file = pathlib.PurePath(path)
    new_file_path = os.path.join(file.parent, f"{file.stem}_{daystr}{file.suffix}")
    os.rename(path, new_file_path)
```

**Add-TimeStamp.py** ファイルとリネームしたいファイルを任意のフォルダに配置します。


## 使用方法

リネームしたいファイル (複数) を、作成した **Add-TimeStamp.py** ファイルにドラッグ＆ドロップします。

![Rename_Python.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/8f8e33e7-2311-d152-8003-be615eb1db00.gif)

# 参考サイト

- [【Python入門】os.renameでファイル名を変更する方法を解説！ | 侍エンジニアブログ (sejuku.net)](https://www.sejuku.net/blog/63732)
- [Pythonプログラミングでファイルをドラッグ＆ドロップでフルパスを取得する | もぷるんの電気のお部屋 (mopurunelectronics.com)](https://mopurunelectronics.com/prog/py/pts-3/)
関連リスト「ファイル」を使用したレポートの作成


[関連リスト「ファイル」を使用したレポートの作成](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000FTeACSA1)

時間があれば、実際のApex　バッチを書いてみたいと思います。

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

このメモ & 添付ファイルはかなり厄介ですね。
オブジェクトのリファレンスに普通に紹介されていますが、SOQLのDML操作すら受付ません。やっかいなオブジェクトです。
試した結果

```
entity type NoteAndAttachment does not support query
 ```

[NoteAndAttachment](https://developer.salesforce.com/docs/atlas.ja-jp.object_reference.meta/object_reference/sforce_api_objects_noteandattachment.htm)

調べてみると回避策はそれぞれNoteとAttachmentを呼び出すとありますね。
https://stackoverflow.com/questions/4952379/salesforce-soql-query-for-notes-and-attachments-of-a-site

しかし、Note、Attachmentをだけで検索するとList変数として取得できそうです。
ParentIdが対象としているカスタムオブジェクトのIdの先頭３桁と一致していたら添付されていることが判断できます。

今回限りの処理なら 匿名ウィンドウで実行して結果をコピペするか、簡単なプログラムを書いてSOQLの結果のList変数をcsvファイルにするようなことをすれば対応できると思います。

何度も流す必要があるのなら、新しくカスタムオブジェクトを作ってそこに検索結果を吐き出すようなApexバッチを作って その新しく作ったカスタムオブジェクトをレポートで出力するような方法をすることも可能です。
concurrent.futures.ThreadPoolExecutor についての備忘録

# はじめに
複数の関数を同時に動かしたいとき、concurrent.futures.ThreadPoolExecutor を使うことがある。
引数についてメモ。

# コード
``` python
import concurrent.futures
import time

def aaa(a):
    print("3a=",a*3)
    time.sleep(3)
    print("a,3sec")


def bbb(b):
    print("3b=",b*3)
    time.sleep(2)
    print("b,2sec")


A = 1
B = 2
executor = concurrent.futures.ThreadPoolExecutor(max_workers=2)
executor.submit(aaa,A)
executor.submit(bbb,B)
```

# 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669608/14322f12-ca32-94ad-8635-267cd2210703.png)
aaa, bbb を同時に実行したため、このような結果になっている。

# 注意点
引数の使い方。引数（AおよびB）はカンマで区切る。
```python:良い例
executor.submit(aaa,A)
executor.submit(bbb,B)
```

もし以下のように括弧で引数を用いた場合、（理由はよく知らないが）先にsubmit した関数の実行が完了してから次の関数が実行される。
```python:悪い例
executor.submit(aaa(A))
executor.submit(bbb(B))
```
結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669608/177da42b-4c83-6b33-466a-4f15c6a99270.png)
aaaが完了してからbbbが実行されている（5秒以上かかっている）。
テスト計画について

# テスト計画全体像と、計画の重要性
- テスト計画プロセス：テスト計画の策定
- テスト設計プロセス：テスト設計
- テスト実装プロセス：テストケース、テストデータ、テスト環境などの準備
- テスト実行プロセス：テストケースの実行

## テスト計画が今後を左右する
テスト計画とは、テストの設計、実装、実施、管理といったテストのすべての指針を定めるものです。そのテストが成功するか、それとも失敗してしまうか、多くはテスト計画で決まると言って過言ではありません。テスト計画が確実に策定されれば、テストプロジェクトは円滑に遂行される可能性が高まります。
逆にテスト計画が不適切だったり、テスト計画が策定されてなかったりしたら、以下のようなトラブルが生じ、時には大問題に発展します。
- 考慮や作業の漏れ抜けでテストの設計と実行尾の質が低下し、致命的なバグを見逃す
- 突発時効が頻発して円滑にテストが進められない。

## テスト計画に記載する内容
テスト計画書に記載するものは大きわけて三つあります。
1. 要求の整理・分析
- テスト対象・範囲は何か
- テストの目的・目標、重点項目は何か
- テスト対象の開発状況はどうか
- どんな課題やリスクがあるか

2. 要求の実現方法
-　テストはどんな組み立てで行うか
-　ツールや環境はどんなものが必要か
-　テストプロセスで生成する成果物は何か
-　各種基準や目標の詳細
-　スケジュール
-　体制・役割分担・作業場所

3. 各種管理の計画
- 課題管理、リスク管理
- 不具合管理
- 文書やデータの管理
- 進捗管理・コミュニケーション
- テストの開始条件、テストの終了条件などの基準や目標
　
## 要求を正しく理科し、状況に適したテスト計画する
テストを行うにあたって、いきなりテスト設計に入っても、良質なテストを得るのは難しいものです。
テスト項目の大項目。
1. 要求の整理・分析
1. 要求の実現方法
1. 各種管理の計画
最初に行うべきは「1.　要求の整理・分析」です。テストについて誰から何が求められているか、何を実現したいのか、状況はどうか、課題やリスクはどんなものがあるか、これらを分析し、整理します。
その次に、課題やリスクを踏まえながら、どうやって要求を実現するか、「2. 要求の実現方法」と「3. 各種管理の計画」を検討するようにします。
正しく要求を理解し、その時の状況にあったテストを行うことで、後で以下のような問題が生じることになります。

- 求められたテスト設計せず、実施漏れとなる。
- 必要とされていないテスト実施してコストと時間を無駄にする。
- 課題やリスクに対処しないため、後々で壁に当たり、プロジェクトが難航する。

いきなり思いつまま無計画位にテスト実行してはなりません。また、何が求められているのか理解しないまま、いきなりテストの設計に入ってはいけないものです。

## 計画を策定することは、プロジェクトそのものを設計すること
計画を策定することは、事務作業ではありません。
計画を策定することは、プロジェクトそのものを設計することです。
- 出発地と目的地に定義する
- 目的地に至るまでの道のりを、プロジェクトをどう料理するかをデザインする
- デザインしたものを、計画書という形で表現する

目的地に至るまでには、さまざまな問題やリスクがあるはずです。それらの課題やリスクをピックアップし、その対処法を計画に盛り込みます。つまり、課題やリスクを見越して、問題を発生させないように、先手を打つということです。
品質管理の基本的な考え方は、問題が発生しないように事前に手を打つ「予防」です。計画を策定することは、このポリシーを含んでいるのです。

## 計画は使うためのもの
計画は、一度作成したらそれで役目を終えるわけではありません。
計画は使うためにあります。
- プロジェクトの運営方法を、関係者間で共有するため
- プロジェクトの目的地を見失わないようにするため
- 現在位置を知り、次の作業に備えるため

計画は、ポケットに入れた地図のようなものです。現在位置を知り、次に何の作業を行う必要があるのか、ポケットに入れた地図を要所要所で引っ張り出し、何回も見直します。
テスト計画も同じです。
Embeddeded Service Chat question



The Embedded Service Deployment (Chat) widget’s code snippet generation feature only uses *.force.com URLs at this time. When enhanced domains are enabled, instruct users to manually update the generated code snippet to use your *.my.site.com or *.salesforce-sites.com URL.


Embedded Service Deployment（Chat）ウィジェットのコードスニペット生成機能は、現時点では*.force.comURLのみを使用します。拡張ドメインが有効になっている場合は、生成されたコードスニペットを手動で更新して*.my.site.comまたは*.salesforce-sites.comのURLを使用するようにユーザーに指示します。

何を指示するんだろう？という質問。私もわからん。

回答

The phrase "instruct users to manually update" probably should instead say "update places that use", since end-users typically don't have access to modify such pages. Places that use the generated code snippet, however, can get updated by authorized administrators.

エンドユーザーは通常、そのようなページを変更するためのアクセス権を持っていないため、「ユーザーに手動で更新するように指示する」というフレーズは、おそらく「使用する場所を更新する」と言う必要があります。ただし、生成されたコードスニペットを使用する場所は、承認された管理者によって更新される可能性があります。

[エクスペリエンスサイトへのチャットウィンドウの追加](https://help.salesforce.com/s/articleView?id=sf.snapins_chat_communities.htm&type=5)

[Embeddeded Service Chat question](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000FuSnS)

# 無人チャット時のアバター画像の表示について

+ [Refused to load the image '表示したいアイコンのURL' because it violates the following Content Security Policy directive: "img-src 'self' data: blob: ](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007LokhJ)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/c17ba860-090f-26db-fdc2-3dba92f0cd05.png)


:::note
インラインのJava Scriptを使っていますか？

Inline JavaScript isn’t permitted 
https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/security_csp.htm

回避策があるみたいです。
https://salesforce.stackexchange.com/questions/237830/error-including-static-resource
:::

# embedded service deployment

+ [Not able to create new embedded service deployment in developer sandbox.](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000TihOG)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/634db1fa-d9ff-4e9b-b81e-bc47d0afbe1c.png)
PDF、オフライン、デジタル署名を同時に生成するのに適したツールはどれですか？


ちょっと興味深い質問。

[Which tools are suitable for generating PDF, offline and digital signature at the same time?](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000FuFT5)

+ DocuSign is brilliant as it can integrate with other systems outside of the Salesforce ecosystem. 
+ Conga is great for complex contract management.
+ PandaDoc offers the easiest interface to build great content
+ S-Docs is super easy to config
Bitnami redmine 再起動したら「Thin_redmineが起動しない」の解決方法

# 背景

Bitnami redmineを使用しているプロジェクトで、ある日マシンを再起動したらRedmineにアクセスできなくなってしまった。
Thin_redmineというサービスが起動しなくなってしまった。

原因を調べるときに「thin_redmine　起動しない」などで調べても、以降に記載する解決方法になかなかたどり着かず。
質問掲示板で質問しているけど諦めました、と書いている人がいたので、上記検索ワードで引っかかるように、記事に
まとめてみようと思いました。

# 解決方法

### 1.インストールフォルダ名を変更
[bitnami Redmineをインストールする際に気をつけるただ１つのこと](https://labo.ysreading.co.jp/2016/04/12/bitnami-redmine%e3%82%92%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%99%e3%82%8b%e9%9a%9b%e3%81%ab%e6%b0%97%e3%82%92%e3%81%a4%e3%81%91%e3%82%8b%e3%81%9f%e3%81%a0%ef%bc%91%e3%81%a4/)

という記事で、インストール時のフォルダを「C:\BitNami\redmine-4.x.x-0」から「C:\BitNami\redmine」にするとなおる。
と記載を発見。

私の場合は、データの移行も行いたかったので、ポート81番でRedmineをもう一つインストールしました。
何度再起動しても動いたので、原因はフォルダ名であることが判明。

### 2.データ移行(MySql)
動かない方のRedmineのデータをエクスポートして、動いている方のRedmineにインポート

### 3.移行確認
Redmineにユーザやプロジェクト、チケットが移行されていることを確認しました。

# おまけ（気になっていること）
なぜフォルダ名を変えると動くようになるのか、の原因がまだ追究出来ていません。
落ち着いてエラーメッセージちゃんと見たらすぐわかるのかもしれませんが、発生時は慌ててしまい
冷静ではなかったと思います。

今はフォルダ名が「redmine-4.x.x-0」だと、起動スクリプトのどっかのコマンドで失敗してしまうのではないかと想定
していますが、これ以上時間をさけず、原因追及作業は止めてしまっています。
【AWS Summit 2021】日立がチャレンジするクラウドネイティブな社会イノベーション！①

みなさんこんにちは。子育てしながらクラウド推進！日立のモフママです。
モフママのQiitaデビューが遅かったのでちょっと遅くなってしまいましたが，今回はAWS Summit Online Japan 2021 での日立セッションについてご紹介しようと思います。


![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/2fc1646e-754f-94a3-4b5b-0ce63c4c3194.png)


![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/af5d67b0-9c5c-dd0e-3c09-377526ffa32f.png)


![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/22eaaacc-d49e-20a4-f5fd-20d63dd2edd8.png)


![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/77e115e5-4cf2-a622-b096-1aa5bba48ddd.png)



![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/f5cd9623-7adc-7dcb-bfd7-4898f4e2ca83.png)



![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/ea985026-06b7-fa9e-5ad1-4effdfcf02aa.png)


![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/82f7b63c-4fcb-9d35-947b-093613e7259f.png)


![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/fa857f0a-7271-0971-9f11-c73fd6c0a3c2.png)



![09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/886c1ab0-5150-dbde-4c04-f4238c2bc2a6.png)



![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/1edc5b96-0eae-ff5b-441f-5a4c0693216f.png)



![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/52e81e49-c453-6f86-1907-60c95c64bd2d.png)


![simple.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/3be2b5ba-42a9-ec39-e5d6-a8f972a0b23d.png)



![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/22fa7e8e-8e7a-f98f-6b5b-d0403018e512.png)



https://docs.aws.amazon.com/ja_jp/athena/latest/ug/glue-best-practices.html

https://aws.amazon.com/jp/blogs/news/top-10-performance-tuning-tips-for-amazon-athena/


![12-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/a1c87ecc-d9d1-073a-aa53-f1d684964e25.png)


![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/bf53315e-1eba-aa8f-eba5-cd9285364004.png)


![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/60dc86a2-a553-33f0-b71f-c50a82c195a0.png)


<iframe width="560" height="315" src="https://www.youtube.com/embed/LLi1lzhpoto" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


***

+ AWS は、米国その他の諸国における Amazon.com, Inc. またはその関連会社の商標です。
+ その他、本資料に記述してある会社名、製品名は、各社の登録商品または商標です。
サロゲートペア文字を取り除く方法(Python)

# 概要
Pythonコード上で文字列からサロゲートペア文字を取り除く必要がありました。
サロゲートペア文字と、取り除いた対処法についてまとめます。

# 背景
「特定の条件を満たすメールを受信した場合に外部サービスに起票するシステム」を開発・運用していて、起票対象のメールにiOSの絵文字などサロゲートペア文字が含まれていると[Backlog](https://developer.nulab.com/ja/docs/backlog/)の起票に失敗※してしまいました。

サポートに問い合わせたところサロゲートペア文字に対応していないと回答いただいたので、[Backlog](https://developer.nulab.com/ja/docs/backlog/)へ起票する前にサロゲートペア文字を取り除く処理をいれることにしました。

※失敗時にはAPIからレスポンスとして「code:1 Incorrect String」が返ってきます。Web画面で直接課題を起票した場合は「Backlogがサポートしていない文字「🏣」が詳細に含まれています」といったメッセージが出ます。 

# サロゲートペア文字とは
通常文字は2バイトですが、サロゲートペア文字は4バイト（2文字分）あります。
Unicodeで「U+16進数5桁（U+10000 ～ U+1FFFFF）」の範囲になります。

iOSの絵文字の大半もサロゲートペア文字です。
下記サイトの「U+1F004」以降の絵文字が[Backlog](https://developer.nulab.com/ja/docs/backlog/)でサポートしていないサロゲートペア文字になります。
https://ja.wikipedia.org/wiki/Unicode%E3%81%AEEmoji%E3%81%AE%E4%B8%80%E8%A6%A7

絵文字以外のサロゲートペア文字の例
https://codezine.jp/article/detail/1592

# 対処方法
UTF-16 にエンコードした時に2バイトにならない文字を削除する処理を追加しました。
参考にしたQA: https://teratail.com/questions/113796#reply-173241

下記の例では、サロゲートペア文字を UTF-16 に変換すると4バイトになることを利用して削除しています。

```python
s = '「𠀋𡈽𡌛𡑮𡢽😄😃😀😊😉」'    
a = ''.join(filter(lambda c: len(c.encode('utf-16-be')) == 2, s))    
print(a)

## 出力結果
「」
```

# 結果
サロゲートペア文字を含んだテストコードを追加して、単体テストと結合テストでサロゲートペア文字が取り除かれることを確認しました。

# 補足情報
emojiモジュールを使用することも当初考えましたが、絵文字以外もサロゲートペア文字は存在するため、この方法は今回採用しませんでした。
参考にしたQA: https://qiita.com/yoshimo123/items/85331d881aed9ad41020

```python
import emoji

def remove_emoji(text):
    return emoji.replace_emoji(text, replace='')

emojis = '「𠀋𡈽𡌛𡑮𡢽😄😃😀😊😉」'
print(remove_emoji(emojis))

## 出力結果
「𠀋𡈽𡌛𡑮𡢽」
```
100日でSQLの達人になる@LeetCode! Day45 <要復習、処理速度が課題>

## 1225. Report Contiguous Dates （問題レベル: Hard）要課金
今日の問題はこれ。
1日1行のデータが接続が成功した日は成功テーブル、失敗した日は失敗テーブルと別々のテーブルに管理されている。
ここから、連続して成功した期間、連続して失敗した期間を順にリストアップするという問題。

中級までに学んだ、`WITH`句、連続が途切れるギャップを見つける方法、累積和を使うことで解ける問題であった。
ヒントなしで下記クエリを書いて、最初のサンプルデータには成功したが`submit`すると`Time Limit Exceeded`でなかなか`Accept`されない。
```:SQL
WITH cte AS (
SELECT 'failed'    AS period_state, fail_date 　　　　　　AS date FROM failed
UNION ALL
SELECT 'succeeded' AS period_state, success_date AS date FROM succeeded)
,
cte2 AS (
SELECT t1.period_state, t1.date, 
CASE WHEN t1.period_state　=　t2.period_state THEN 0 ELSE 1 END AS chg
FROM cte t1
LEFT JOIN cte t2
ON DATEDIFF(day, t2.date,t1.date)=1
WHERE t1.date BETWEEN '2019-01-01' AND '2019-12-31')


SELECT t5.period_state, MIN(t5.date) AS start_date, MAX(t5.date) AS end_date
FROM 
(
SELECT t3.period_state, t3.date, SUM(t4.chg) AS sum
FROM cte2 t3
LEFT JOIN cte2 t4
ON t3.date >= t4.date
GROUP BY t3.date, t3.period_state) t5
GROUP BY t5.sum, t5.period_state
ORDER BY MIN(t5.date)
```

`Discuss`を見て修正し最終的に成功したのが下記クエリ。
```:SQL
WITH cte AS (
SELECT 'failed'    AS period_state, fail_date 　　　　　　AS date FROM failed
UNION ALL
SELECT 'succeeded' AS period_state, success_date AS date FROM succeeded)
,
cte2 AS (
SELECT period_state, date, ROW_NUMBER() OVER(ORDER BY period_state, date ASC) AS num
FROM cte
WHERE date BETWEEN '2019-01-01' AND '2019-12-31')
 

SELECT period_state, MIN(date) AS start_date, MAX(date) AS end_date
FROM cte2
GROUP BY DATEADD(day, -num, date), period_state
ORDER BY start_date ASC
```
このクエリのポイントは`ROW_NUMBER() OVER(ORDER BY period_state, date ASC)`で、`period_state`を`ODER BY`に入れることで違うグループ分けをしているところ。
最初の失敗したクエリは累積和を算出するところでひと手間増える分遅くなってしまうのか。
なかなか`Hard`の壁は高い。

今日のポイントは`処理速度が課題`としておこう。

* [LeetCode](https://leetcode.com/)の問題は、`MS SQL Server`で解いています。
<備忘録>Herokuデプロイ時のbundler エラー

# Herokuへのデプロイ時にエラー発生
rails アプリをHerokuにデプロイしてHerokuを
開こうとしたが、開かず。


```
BUNDLED WITH
   2.2.17
```

gemfileのbundelerの記述を削除したら解決。

Herokuで使用するbundlerのバージョンと
開発環境で使用するbundlerのバージョンの
差異が原因？かも

以上
開発仕事において一番重要な５W１H


**＜５W１Hとは？＞**
---
- When：いつ
- Where：どこで
- Who：だれが
- What：何を
- Why：なぜ
- How：どのように

簡単に言うと**英単語の頭文字を取ったもの**。
何かをやる前に**目標に到達するためのマイルストーン**。

**＜何故重要なのか？＞**
---
考えてください。
答えはもう貴方の中にあるはずです。
この中でも **「Why：なぜ」** についてもうちょっと深く、、深く、、
マイクロサービス関連の覚えておきたいアーキテクチャキーワード集

# ご挨拶
皆さんこんにちは！
外資クラウドベンダーで働く、自分でも何が本職なのかわからない、Kazuyaです！
今日は、先日（といっても数か月前ですが・・）お話しした、某有名企業のスーパーエンジニアな方が
お話していた内容で自分でももう一度勉強しておきたいなぁと思ったキーワードが多数あったので、
覚書です！

# 1.ボトルネック解消のためのＡＰＩ構成
まず前段になっちゃいますが。
ＡＰＩといっても、ＥＣサイトなどの場合、複数のＡＰＩを呼び出さないと、
必要なデータが得られない。
フロント⇔サーバーのターンアラウンドが多いと、当然レンダリングが遅延する。

その遅延を減らすべく、１ＡＰＩでいくつかのＤＢアクセスなどをすることになるのですが。
そうなると、汎用性がなくなる。

でここで登場するのが、ＡＰＩをハイレベルとローレベルの分割。  

・ＤＢアクセスなどをローレベルに配置。
・ハイレベルＡＰＩは、それらのローレベルＡＰＩをいくつか呼び出し、フロントエンドにデータを返す役割。

うん。昔の３層構造の中間層みたいな。ビジネスロジックみたいな。
そんな役割がよみがえってきた感じですね。

# 2.サーキットブレーカー
上述1の構成だと、ローレベル側でＤＢアクセスを呼び出すＡＰＩを、ハイレベルＡＰＩが
たくさん呼んでしまうと、遅延が発生しやすい。

そうなると、API障害が発生して、わけのわからないことが起きる。
そうなると、連鎖障害が発生して、本来独立性の高いはずのＡＰＩが連鎖して障害やレイテンシー低下を起こす。
これでは「マイクロ」じゃないじゃん・・・と。

そのため、コアになるサービスのヘルスチェックを常時行い、
その障害が発生したローレベルＡＰＩへの通信を遮断し、
遮断した場合でも、サービスが継続できるようにする仕組みを前提にしたアーキテクチャを組んでおくことが
これに当たります。

当然障害が出たあと、復旧した場合は、ローレベルAPI（サービス）への通信を自動再開。
このあたりの継続的なヘルスチェックと、必要に応じて連鎖を防ぐためのサーキットブレーカーが、
マイクロサービスアーキテクチャでは重要ですね👌

# 3.スロットリング
いわゆる、流量制限。
F5アタックの抑止にもつながる（といっても、それは通常WAFなどで対応しますが）、
特定の操作に対して、送信できるリクエストの数を制限するプロセス。
リクエストが殺到しても、待機させ、制限を上回るリクエストがなされた際には、拒否してエラーコードを返す仕様にできる。
つまり、その仕様であるI/Fを公開しておけば、リクエスト量が多すぎたのでアクセスできなかったという、
アプリ挙動が実現可能、と。

こういった、「イレギュラー」や「レスポンス・レイテンシー」といったあたり。
単に「プログラムが組める」ではなくて、
実際の運用においては不可避の領域になってきます。

アプリを組むだけじゃなくて、
「どうしてその組み方にするのか」
「こうなったときどうするのか」といったあたりを、
気にしたプログラミングがしたいですね。

それでは本日はこの辺で！
See you next time!!
WIndows 11の英語版を日本語化するメリットとデメリット

# Windowsの英語版がセットアップされている状態
以下の場合にWindows 11 が標準でセットアップされている場合がある可能性がある、
+ 海外仕様のPCを並行輸入（購入)した場合
+ セットアップ時の言語をミスって選択した場合
+ Windows 365等のクラウド環境で初期にセットアップ（クローン）してあるOSが英語版である

以上の場合に下記の参考文献に示す方法で英語版のWindows 11を日本語版に直すことができる。

# 参考文献
http://www.vwnet.jp/windows/W11/2021120401/OtherLang2jaJPW11.htm

# メリット
+ 日本語版のWindowsを元に作成されているアプリケーションが動く
+ デフォルト言語が日本語になるので、アプリケーションが複数の言語に対応している場合に日本語を選択してくれる場合がある
+ 変なところで英語版のWindowsのバグに引っかかることが少なくなる

# デメリット
+ 日本語版に変更したことで適切なサポートが受けられない場合がある
+ 動かないアプリケーションは英語版のWindowsであろうと日本語版のWindowsであろうと動かない
+ 地域等の判別がされている場合にはやはり日本語をデフォルト言語扱いしてくれない場合があり、手動での変更が必要となる場合がある。
【Git＋GitHub】チーム開発のための環境構築〜プルリクエスト作成まで

# はじめに

こんにちは。
こちらの記事では、チーム開発でGitとGitHubの扱う方法を記しています。
誤っている点やアドバイスがございましたらコメントいただけると幸いです。


## 実装手順

* プロジェクトのリモートリポジトリを clone する
* 環境構築する
* リモートにあるブランチから作業ブランチを作成する
* リモートリポジトリに push してプルリクエストを作成する
* レビューを受ける

### 1. プロジェクトのリモートリポジトリを clone する

プロジェクトのリポジトリに参加して、そこからクローンを行う。
チーム開発だと、 https ではなく ssh からクローンすると思うので、

* 個人アクセストークンの発行
* SSHキーの追加
* SSOの有効化

などを事前に行なっておく。
※ https だと、大容量ファイルなどを正常にダウンロードできないななど、不具合が起こる可能性があるようです。

>参考リンク：
>* https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token
>* https://docs.github.com/ja/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account
>* https://docs.github.com/ja/enterprise-cloud@latest/authentication/authenticating-with-saml-single-sign-on/authorizing-an-ssh-key-for-use-with-saml-single-sign-on

公開鍵の設定ができたら、ターミナルで git clone します。

```
$ git clone git@github.com:~hogehoge~
```


### 2. 環境構築する

プロジェクトのリポジトリにあるREADMEやチームの方針に従って、言語や開発に使用するツールなどのインストール、データベースやDockerなどの環境構築をして、ローカル画面の表示確認（localhost:0000）まで行なってください。
（ここはチームによってそれぞれだと思うので割愛します）


### 3. リモートにあるブランチから作業ブランチを作成する

クローンした環境でブランチの確認を行います。

```
$ git branch
* main
develop
```

main や develop ではなく、リモートにあるブランチを親ブランチに指定して作業ブランチを作成したい場合は、下記コマンドを実行する。
（親ブランチを `sample`、作業ブランチを `future/sample`と仮定する）

```
// 最新のブランチ情報を取得する
$ git fetch -p

// リモートにあるすべてのブランチを一覧表示して、親ブランチを確認する
$ git branch -a                                    

// リモートブランチを親にして、ローカルに作業ブランチをcheckoutする
$ git checkout -b feature/sample origin/sample
```

>参考リンク：
>* https://noumenon-th.net/programming/2018/12/24/git-fetch/
>* https://qiita.com/YusukeSuzuki@github/items/3bd5752783fd2c2f8805

ブランチが作成できているか確認ができたら、そのブランチで作業を行う。

```
$ git branch
main
develop
* feature/sample
```


### 4. リモートリポジトリに push してプルリクエストを作成する

変更箇所をリモートリポジトリに push していく。
チームの方針によって様々だと思うが、コミットメッセージにプレフィックスをつけると、何が変更されたのかわかりやすい

>参考リンク：https://qiita.com/numanomanu/items/45dd285b286a1f7280ed

```
// ファイルの変更箇所を確認する
$ git status

// ファイルを指定する場合は、add の後ろに変更ファイルのディレクトリを記述する
$ git add .

// コミットメッセージも記述しておく
$ git commit -m "コミットメッセージ"        

// リモートリポジトリに push する
$ git push origin feature/sample
```

GitHubのリモートリポジトリにある`Pull requests`から、`New pull resuest`を押下して作成する。その際、どのブランチからどのブランチにマージを行うのか必ず指定する。

```
base:    sample
compare: future/sample
```


### 5. レビューを受ける

レビュアーを指定してレビューを受けてから、OKが出ればマージしていただく。

>参考リンク：https://www.udemy.com/course/unscared_git/

<br>


# おわりに
ここまでチーム開発でGitとGitHubの扱う方法についてまとめました。
以上、最後まで読んでいただきありがとうございました！
よければLGTMを押してくれると嬉しいです！