OmniAICreator/Qiita-1.07M huggingface dataset:
AWS S3とCloudFrontとCertificate ManagerとRoute53を使ってWebページをSSL化する

WebページをSSL化したのでそのやり方を残しておきます。

下記サイトが参考になりました！
https://twinkangaroos.com/how-to-setup-an-ssl-certificate-for-free-and-convert-to-https-with-s3-cloudfront.html

# CloudFrontでオリジンの作成と証明書のリクエスト
1. AWSにログインし、CloudFrontに入る
1. 「ディストリビューションを作成」をクリック
1. オリジンドメインはSSL化したいドメインを選択
1. ビューワーは「Redirect HTTP to HTTPS」を選択
1. 代替ドメイン名 (CNAME)に「ドメイン名」と「www.ドメイン名」の2つを追加
1. カスタム SSL 証明書の「証明書をリクエスト」をクリック

# Certificate Managerにて証明書の作成
1. 証明書タイプは「パブリック証明書をリクエスト」を選択し、次へをクリック
1. 完全修飾ドメイン名に「ドメイン名」を入力
1. 検証方法の選択にて、「DNS検証」を選択
1. リクエストをクリック
1. 証明書のページに戻るので、ドメイン名を選択
1. 「Route 53 でレコードを作成」をクリック
1. ドメインを選び、「レコードを作成」をクリック

以上で、証明書の作成は完了なので、再度設定中のCloudFrontの画面に戻る

# CloudFrontにて証明書を設定
1.　カスタムSSL証明書が選択できるようになってるので、「ドメイン名」を選択
2.　デフォルトルートオブジェクトに「index.html」と入力
3.　「ディストリビューションの作成」をクリック

これでCloudFrontの設定は終わり。

# Route53でAレコードの「値/トラフィックのルーティング先」を変更
1. Route53へ移動
1. 「ホストゾーン」をクリック
1. ドメイン名をクリック
1. Aレコードを選択し、「レコードの編集」をクリック
1. トラフィックのルーティング先で「CloudFront ディストリビューションへのエイリアス」を選択し、先ほど作成した「xxxx.cloudfront.net」を選択し保存をクリック
1. 「www.」の方も同様に実施

### 以上でSSL化が完了です！
シーザー暗号をpythonで実装

この投稿では、シーザー暗号について解説いたします。シーザー暗号と聞くとなんだか難しそうですが、実は非常に簡単な考え方の暗号なのです。

# シーザー暗号とは
### ＜シーザー暗号の名前の由来＞
ローマの紀元前1世紀頃、ジュリアス・シーザー（ユリウス・カエサル）が利用していた暗号といわれています。
シーザー暗号は、平文の各文字をアルファベット順的に特定の量だけシフトしたものを暗号文とする暗号になります。

暗号化前の誰にでも読むことができるデータを平文と呼びます。
一方で、その平文を何らかの手法で暗号化したデータを暗号文と呼びます。




### ＜シーザー暗号の例＞
・「**a**」は右に**5文字シフト**して「**f**」に変換する
・「**b**」は右に**3文字シフト**して「**e**」に変換する
・「**c**」は右に**23文字シフト**して「**z**」に変換する
このようにシフトすることでシーザー暗号となります。

### ・Pythonで実装
今回の平文は「**ugviumqakpcbism**」です。これだけ見ると訳の分からない文字列ですが、シーザー暗号で暗号化されていることが分かれば、簡単に復号化することができます。では、やってみましょう。

```python
def caesar(strInputText, intKey):
   strResult=[]
   for char in strInputText:
      if(ord(char)+intKey<=ord('z')):
         strResult.append(chr(ord(char)+intKey))
      else:
         strResult.append(chr((ord('a')-1)+(ord(char)+intKey-ord('z'))))

   print('key: '+str(intKey)+'>'+''.join(strResult))


for i in range(1,26):
   caesar('ugviumqakpcbism',i)
```
このコードの関数caesarは、シーザー暗号によって暗号化されたものを平文に復号化する関数です。
引数には暗号化された文と、シフトする回数の2つです。for文で繰り返し実行することで、平文を見つけます。アルファベットは全部で26文字ですので、25回繰り返します。

#### 実行結果
```
key: 1>vhwjvnrblqdcjtn
key: 2>wixkwoscmredkuo
key: 3>xjylxptdnsfelvp
key: 4>ykzmyqueotgfmwq
key: 5>zlanzrvfpuhgnxr
key: 6>amboaswgqvihoys
key: 7>bncpbtxhrwjipzt
key: 8>codqcuyisxkjqau
key: 9>dperdvzjtylkrbv
key: 10>eqfsewakuzmlscw
key: 11>frgtfxblvanmtdx
key: 12>gshugycmwbonuey
key: 13>htivhzdnxcpovfz
key: 14>iujwiaeoydqpwga
key: 15>jvkxjbfpzerqxhb
key: 16>kwlykcgqafsryic
key: 17>lxmzldhrbgtszjd
key: 18>mynameischutake
key: 19>nzobnfjtdivublf
key: 20>oapcogkuejwvcmg
key: 21>pbqdphlvfkxwdnh
key: 22>qcreqimwglyxeoi
key: 23>rdsfrjnxhmzyfpj
key: 24>setgskoyinazgqk
key: 25>tfuhtlpzjobahrl
```
この25個の実行結果の中で読むことができるのが **key:18** の **my name is chutake** です！

### さいごに
古い時代に使われていたシーザー暗号ですが、現代では簡単に破られてしまう暗号です。暗号解読は、はじめは頻度分析や単語パターンなどの、一般的な解読手法を使用します。ですがシーザー暗号は特徴的なアルゴリズムであるため、解読者はすぐに法則性に気づき、解読もしくは推測される可能性が高いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632237/51a383e8-2504-22e5-9e6f-324fbf1d2f23.png)
（図：https://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%BC%E3%82%B6%E3%83%BC%E6%9A%97%E5%8F%B7 より）
これは典型的な英語の文章における文字の出現頻度分布図です。英語の平文ではEやTが最も出現頻度が高く、QやZが最も出現頻度が低いといった特徴が図から読み取ることができます。英語の平文をシーザー暗号で暗号化するのは注意が必要ですね！
Arduino UNOとSSD1306に豆腐を召喚する(スペルは、「40-FF」...)


x OLED096UNO-Aです。
x Arduino UNO互換機

目的
OLEDのテスト


![o_con868.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f01b8137-302f-4893-ccb0-ad29a6e50ca9.jpeg)

o_con778.jpg

![o_con778.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/211a377e-89f4-b3b6-db5c-17d01fd9de90.jpeg)



NUCLEO-G071RBと完全に同じプログラム



```c++



//ssd1306_int_071_1

#include <Arduino.h>
#include <Wire.h>

void write_s(uint8_t *str1, uint8_t len1) {

  Wire.beginTransmission(   0x3c  );

  for (int ii = 0; ii < len1; ii++) {

    //一文字出力
    Wire.write(*str1 ++);

  }//for

  Wire.endTransmission();

}//eeprom_write_s

//初期化
void setup() {

  //I2Cの初期化
  Wire.begin(); //071
  delay(200);

  //0x80,0x8d,0x80,0x14,0x80,0xAF
  write_s( (uint8_t*) "\200\215\200\024\200\257", 6);
  delay(100);

#define DATA_MODE                  0x40

    uint8_t databytes[2] = {DATA_MODE,0xFF};
    for (int icount = 0; icount < 8; icount++) {
        write_s(databytes, 2);
    }//for


}//setup

//無限ループ
void loop() {
}//loop



```
【初学者向け】AndroidでPaletteを実装する方法

こんにちは。
Androidアプリ開発を勉強中のみのむしと申します。

今回は、Androidでpaletteを使用しようとしたところ
参考にした記事が古く、エラーが発生し苦労したので、
問題なく実行できた書き方を備忘録として残したいと思います。

<h1>詰まったポイント</h1>
参考書にはSupportライブラリのV7パッケージ使用すると書かれていたため、参考書通りに実装したがエラーが発生し、使用できない。

<h2>解決方法</h2>
従来、paletteはAndroidのサポートライブラリとして提供されているそうですが、AndroidXへ移行したため、書き方も変わったそうです。

そのため、以下ドキュメントを参考にしながら、書いたところ問題なく実行できました。

<h2>実装方法</h2>
Appのbuild.gradleに下記を加える

```java
dependencies {
implementation 'androidx.palette:palette:1.0.0'
}
```
右上のsync Nowを押して反映させる


**参考文献**
[AndroidX Tech](https://androidx.tech/artifacts/palette/palette/)
[Android デベロッパー](https://developer.android.com/jetpack/androidx/releases/palette)
【Panasonic Let's note】起動ログイン後、急にシャットダウンする対策

パナソニックさんの、Let's Noteのたまに起こる不具合

パソコン起動⇒ログイン入力後に、なぜかPCがシャットダウンする。
もう一度やっても、同じ。

つまり、パソコンが起動できない状態。

【有効かも？対策】
「Shift」ボタンを押しながら、シャットダウンする。
数分待ってから、パソコン起動する。

これで、なおったことがある。過去2回。
Flutter Hooks_Riverpodを使って、初期カウンターアプリの保存と読み込みをしてみる

初期に設定されている`Flutter`カウンターアプリを`hooks_riverpod`で書き換えて`SharedPreferences`でカウントした数字をシュミレーターのローカルストレージに保存して取り出してみました。
![スクリーンショット 2022-10-07 13.18.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/8517b935-f8a4-9054-058f-bfee2df1424c.png)
<details><summary>こちらのサンプルコードに詳細も乗せてあります。</summary>

```dart
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';

final countProvider =
    StateNotifierProvider<countState, Counter>((ref) => countState());

class countState extends StateNotifier<Counter> {
  countState() : super(const Counter());

  void countUp() async {
    // Shared preferencesのインスタンスを非同期で取得しprefsに入れる。
    final prefs = await SharedPreferences.getInstance();
    // Counterクラスのcountに取得したデータを入れる　初期時はnull
    state = Counter(count: (prefs.getInt(countPrefsKey) ?? 0) + 1);
    // setIntで(キーの,内容を)保存
    prefs.setInt(countPrefsKey, state.count);
  }
}

// SharedPreferences で使用する記憶用のキー
const countPrefsKey = 'counter';

// カウンタークラス　初期時は0
@immutable
class Counter {
  const Counter({this.count = 0});
  final int count;
}

class CountView extends HookConsumerWidget {
  const CountView({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final state = ref.watch(countProvider);
    final provider = ref.read((countProvider.notifier));
    // providerで取得してきたCounterのcountを初期値として設定
    final counter = useState(state.count);

    // シュミレーターをリセットかけても読み込むようにするメソッド
    Future loadCounter() async {
      final prefs = await SharedPreferences.getInstance();
      final loadCounter = Counter(count: prefs.getInt(countPrefsKey) ?? 0);
      return counter.value = loadCounter.count;
    }

    // シュミレーターのデバイスにセーブしてあるデータを消去
    Future deleteCounter() async {
      final prefs = await SharedPreferences.getInstance();
      prefs.remove(countPrefsKey);
      loadCounter();
    }

    // 状態管理で常に保存状況を読み込む
    useEffect(() {
      Future.microtask(() async {
        await loadCounter();
      });
      return;
    });

    return Scaffold(
      appBar: AppBar(title: Text('カウントデータの保存')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              '${counter.value}',
              style: Theme.of(context).textTheme.headline4,
            ),
            ElevatedButton(
              onPressed: deleteCounter,
              child: const Text('カウンターをリセット'),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: provider.countUp,
        child: const Icon(Icons.add),
      ),
    );
  }
}
```
</details>
住所正規化 REST APIサービスのAddressianを公開しました

## 目的

社内向けに開発した住所正規化ツールを<strong>Addressian</strong>と命名して一般公開するに至りました。
サービスの紹介を兼ねて、使い方を記事にしたいと思います。

## Addressianの特徴

https://addressian.netlify.app/

Addressianの住所正規化のベースになっているのは、[国土交通省の位置参照情報](https://nlftp.mlit.go.jp/cgi-bin/isj/dls/_choose_method.cgi)と[日本郵便の郵便番号データCSV（通称 KENALL）](https://www.post.japanpost.jp/zipcode/download.html)です。自社の顧客データで正常に動作することを目的にしましたので、全てのパターンというよりは人間がやりがちな表記揺れに対応するように作られています。

### 一般的な特徴

- 登録に必要なのはGoogleアカウントのみです。登録後すぐに使えます。
- FREEプランがあります。クレジットカード登録不要で、月100回リクエストまで無料です。
- REST APIで使えます。現在はREST APIのみ対応しています。
- お支払いはクレジットカードのみです。
- お問い合わせはサイト上のFORMからのみ対応しています。

### 技術的な特徴

- 一回のリクエストで最大100件同時に変換できます。無料枠で100回リクエストできるので、最大10,000件の住所を毎月変換可能です。
- EXCEL(2016以降)やGoogle Spread Sheetから呼び出せます。
- 丁目番地の表記揺れに対応しています。例えば百三号でも一〇三号でもアラビア数字の１０３に変換します。
- ビル名等を取得できます。番地以降の数字はビルの階数として取得します。
- 表記の好みに合わせられるようにtype1, type2,...を準備してます。(四丁目3-2、4-3-2等)
- 丁目あり住所と丁目なし＋地番が混在する地域でも、ほぼ正しく変換します。
- 新しく追加された地名や変更された地名にも対応してます。
- 旧地名には対応してません。

## 登録とAPIキーの取得

[Addressianの公式サイト](https://addressian.netlify.app/)から新規登録又はログインして、APIキーの確認からAPIキーを取得します。Googleアカウントがあれば数秒で登録できます。

## ブラウザで動作確認

curlで動作確認する方法については、[公式ページ](https://addressian.netlify.app/Doc#Top)に記載しておりますので確認してください。 とりあえずブラウザ(今回はGoogle Chrome)を使ってREST APIを投げて、APIキーが正しいか確認します。

下記のURLの{APIキー}をサイトからコピーしたAPIキーに置き換えて、アドレスバーに入力してください。

``` 
https://s32y6jl1f8.execute-api.ap-northeast-1.amazonaws.com/api/address_normalizer?key={APIキー}&address=新宿区西新宿2-1-1
```

`東京都新宿区西新宿二丁目1-1`が取得できれば成功です。
※ 古いブラウザやcurlを使う場合は、addressの`新宿区西新宿2-1-1`をURLエンコードする必要があります。

## Google Spread Sheetから呼び出す

Google Spread Sheetで、WEB情報を取得する方法はいくつかありますが、CSVをセルに展開できる`IMPORTDATA`メソッドを使用します。

![住所正規化デモ_単体.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670581/ab53da53-24cb-82ec-fc0a-f5f68641b07e.png)

住所は、`ENCODEURL`をつかってURLエンコードする必要があります。
画像の例では、わかりやすいようにURLを要素ごとにセルを分けて、最後に住所を結合しています。

セルB８を、長く記述するとこのようになります。
```shell
= IMPORTDATA(https://s32y6jl1f8.execute-api.ap-northeast-1.amazonaws.com/api/address_normalizer?key=APIキー&address=ENCODEURL("鹿児島県鹿児島市中央町１０"))
```
#### 取得する項目を指定する

取得する項目を選択するには、`target`を指定します。 [利用方法](https://addressian.netlify.app/Doc#Top)にあるレスポンスのキー値をカンマ区切りで指定します。レスポンスは、カンマ区切りで指定した順番に並びます。
今回は、zip_code(郵便番号7桁), normalized_address_type1(漢数字丁目タイプ), building(ビル名等）を設定しました。

### 複数の住所をまとめて変換する

Addressianは、POSTとGET両方とも１リクエストに100件までの住所を設定できます。
GETリクエストの場合は、URLのaddressパラメータに住所をカンマ区切りで設定します。
また住所に`,`が含まれる場合には、CSVと同様に`"`で囲むと一括りとして認識されます。

Google Spread Sheetでは、`JOIN`または`TEXTJOIN`を使えば簡単に指定範囲をデリミタ(区切り文字)でまとめることができるので便利です。

Spread SheetでJOINを使って住所を`"`で括り、まとめてREST APIに投げるには、下記のように記述します。

```shell
= IMPORTDATA($B$5 & ENCODEURL("""" & JOIN(""",""", A9:A38) & """"))
```

![住所正規化デモ_複数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670581/e476ab36-6838-5dc6-de58-821ebf1a8906.png)

このように複数住所をまとめて変換すると、リクエスト数を抑えることができます。
Google Spread Sheetでは、渡せる文字数に制限があります。実際に一度に変換できる住所は、30件程度が限界かと思います。その辺りは工夫していただければと思います。

## まとめ

住所正規化REST APIであるAddressianについてお伝えしました。
プログラミングに慣れていなくても、EXCELやSpread Sheetが使える方なら利用できるように作ったつもりです。
ぜひ、お試しいただければと思います。
また、自社で開発したAPIを公開するのは今回が初めてですので、至らない部分も多いかと思います。
ご意見やご感想をいただけると幸いです。
Leetcode 解いてみた 1480. Running Sum of 1d Array

1480. Running Sum of 1d Array
Rubyを勉強中なのでRubyで解きました。

問題
Given an array nums. We define a running sum of an array as runningSum[i] = sum(nums[0]…nums[i]).
Return the running sum of nums.

例1
Input: nums = [1,2,3,4]
Output: [1,3,6,10]
Explanation: Running sum is obtained as follows: [1, 1+2, 1+2+3, 1+2+3+4].

例2
Input: nums = [1,1,1,1,1]
Output: [1,2,3,4,5]
Explanation: Running sum is obtained as follows: [1, 1+1, 1+1+1, 1+1+1+1, 1+1+1+1+1].

例3
Input: nums = [3,1,2,10,1]
Output: [3,4,6,16,17]

制約
1 <= nums.length <= 1000
-10^6 <= nums[i] <= 10^6



【解いた】
要するに、アウトプットするべき配列の要素はインプットの数字のこれまでの数全てを合計したものを配列の１要素にしてますよね。
例）　output[3] = nums[0] + nums[1] + nums[2] + nums[3]

これをfor文を用いて解くとこうなりました。


```Ruby
def running_sum(nums)
    output=[]
    i=0
    for i in 0..nums.length-1 do
        output[i]= output[i-1].to_i + nums[i].to_i
    end
    return output
end
```







結果は・・・



![スクリーンショット 2022-10-07 13.32.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276575/8a4a34d9-8709-5b6e-9156-ec8fe1783391.png)



OK!



何かの参考になれば幸いです。
【Linux】シェル変数と環境変数

## はじめに
シェル変数と環境変数について自分なりにまとめてみました。

## シェル変数とは
シェル変数というのは、`現在使用しているシェルの内部だけで有効な変数`です。なので他のシェルを使っているユーザーは別のシェル変数を使用することはできません。
シェル変数を設定することで、シェルのさまざまなカスタマイズを行う事ができます。　
　
シェル変数の設定方法

```
$ var1='test variable'  
```
上記の例は、var1という変数にtest variableを設定するという意味になります。
設定した変数は、echoコマンドで中身を参照する事ができます。
```
$ echo $var1
tesat variable
```

## 環境変数とは
シェル変数は、現在のシェル内部でしか使用できないのに対して、環境変数は別のシェルを起動したり、コマンドを実行した場合にも使用できる変数のことです。
シェルからはさまざまなコマンドを起動しますが、このうち実行ファイルとして存在するコマンドを外部コマンドと言います。
これに対してシェル自体に内臓しているコマンドを組み込みコマンドと言います。
　
外部コマンドか組み込みコマンドかの判別方法

```
$ type set
set はシェル組み込み関数です　　⇦組み込みコマンド

$ type cat
cpはbin/catです  ⇦外部コマンドの場合フルパス表示
```
ここで出てきた外部コマンドというのは、シェルの外側で実行されます。そのため現在設定されているシェル変数の値を外部コマンドは参照する事ができません。
しかし、外部コマンドでも常に設定を反映させておきたい変数も多くあります。このような用途のために、外部コマンドからも値を参照できるようにした変数を環境変数と言います。

`シェル変数と環境変数の大きな違いは、使用できる範囲が違う`という事です。

例えば、LANGという環境変数があります。これは表示される言語を変更する変数です。
catコマンドを実行した時、まず初めに環境変数であるLANGの値を確認して、その内容によって表示する言語を決めています。
この他にも多くのコマンドは、環境変数の値を確認してから動作しています。
 
環境変数の設定

```
$ export シェル変数　　⇦シェル変数を環境変数へ
```

## bashの設定ファイル
シェルの設定を行なっても、シェルを終了すると設定は全て消えてしまいます。
なので次回以降ログインした時も同じ設定にするには、bashの設定ファイルを記述しなければいけません。

bashは、起動時に/etc/profile .bash_profile .bashrcという順番で設定ファイルを読み込んでいきます。
これはログインシェルの場合で、非ログインシェルの場合は.bashrcを読み込みます。

このようなファイルを記述するには、vimエディタを使用します。

ログイン時に一度だけ設定すればよい項目は.bash_profileに書き、それ以外のbashを起動するたびに毎回設定する必要のある項目は.bashrcに書きます。`基本的には、.bashrcに書いておけば問題ありません。`
車で子供がお歌を歌いやすいように歌詞カードを用意したくてスクレイピングしてみた(Python)

以下のページを参考にさせていただきました。
https://qiita.com/yuuuusuke1997/items/122ca7597c909e73aad5

# 悩んでいたこと
「ちいさなせかいの歌詞つくってー」
「アカシアの歌詞つくってー」
「トトロのうたもうたいたーい」
上記の要望に答えるため、日々歌詞カードを作っていた私はあるとき、一つのことに気づいた。

# 気づいたこと
私の歌詞カード作成は以下の手順で行われていたのだ。（そうだろうね・・・）
1. ブラウザを立ち上げ、歌詞名を検索する
2. 見つけた歌詞をコピーし、自作のドキュメントに貼り付ける
2. ついでに検索画面に表示された画像で、子供にあいそうな画像もドキュメントに貼り付ける
2. ある程度、歌詞カードのページが溜まってきたら、印刷して、子供に渡す

# 歌詞はスクレイピングしよう
わたしは歌詞はスクレイピングすることにした。

```
import requests
from bs4 import BeautifulSoup
import pandas as pd
import time

#曲ページ先頭アドレス
base_url = 'https://www.uta-net.com'

#歌詞一覧ページ
#url = 'https://www.uta-net.com/artist/4002/4/'童謡
#url = 'https://www.uta-net.com/artist/1194/4/'アリス
url = 'https://www.uta-net.com/artist/3979/4/'
response = requests.get(url)
soup = BeautifulSoup(response.content)

# getでリンク要素のhref属性の値を取得しtて出力
links = soup.find_all("a", class_='py-2 py-lg-0')
count = 0
for link in links:
    a = 'https://www.uta-net.com' + link.get('href','')
#    print(a)
    #歌詞詳細ページ
    response = requests.get(a)
    soup = BeautifulSoup(response.text)
    
    title = soup.find("h2", class_='ms-2 ms-md-3')
    topic = soup.find(class_="row pt-4 pe-2 ps-lg-3 pb-lg-4 kashi")
    songLyrics = soup.select("#kashi_area")
    
    print('\n')
    print(title.text)
    if(count == 2):
        break
#    print(songLyrics.text + '\n')
    for songLyric in songLyrics:
#    区切り'　'もしくは、'、'で改行が必要
        songLyricsplits_kugiri =songLyric.text.split("、")
        songLyricsplits_space =songLyric.text.split("　")
        if(len(songLyricsplits_kugiri) > 1):
            for songLyricsplit in songLyricsplits_kugiri:
                print(songLyricsplit)
        elif(len(songLyricsplits_space) > 1):
            for songLyricsplit in songLyricsplits_space:
                print(songLyricsplit)
        
        
#            print('\n')
        #サーバーに負荷を与えないため1秒待機
        time.sleep(1)
```

アーティストもしくは歌のカテゴリごとにひっぱてこれるように作った。
count = 0でカウントアップし、for文をbreakするように処理を入れているが動かないところがポイントかな！

# 頑張った点
歌詞の改行がある程度適切（読みやすい程度の文脈）であれば良いと思ったので、スペースもしくは句読点で開業を行うように対処した。
逆にスペース表記の多い歌詞だと改行地獄になった。さらなる考慮を欲しているがまぁいい。

# かかった時間
10/2にやりだしたよ。夜1~2時間で、3日目くらいに完成したよ。
Google Search Consoleを設定して検索結果に表示されるようにさせる

Webページの作成は一通り終わったので、次は検索結果に作成したWebページを表示させるようにしたい。

ごにょごにょと検索してみると「Google Search Console」とやらを使えばいいらしい。

# Google Search Consoleへの登録
下記サイトが参考になります！
https://prograshi.com/platform/aws/connecting-google-search-console-to-aws/

1. Google Search Consoleにアクセス
1. 「ドメイン」か「URLプレフィックス」を選択する画面が出てくるので、「ドメイン」を選び、URL欄にドメイン名を入力
1. 「ドメイン所有権」の確認画面が出るので③のTXTレコードをコピー
1. AWSにログインし「Route53」へ移動
1. Route53のレコードタイプTXTの編集欄において値に3でコピーした値を入力して保存
1. Google Serach Consoleに戻り確認をクリック
1. 無事に登録されることを確認

これより下は下記のページが参考になります！
https://seolaboratory.jp/29197/

# インデックス登録を送信する

1. Google Search Consoleにアクセス
1. 左のメニューから「URL検査」をクリック
1. 検索窓に登録したいページのURLを入力し、Enter
1. 「公開URLをテスト」をクリック
1. 「インデックス登録をリクエスト」ボタンをクリック

以上でインデックス登録は完了です。

# サイトマップを送信する

1. Google Search Consoleにアクセス
1. 左のメニューから「サイトマップ」をクリック
1. 新しいサイトマップの追加で、XMLサイトマップのURLを入力し、「送信ボタン」をクリック

以上でサイトマップの送信も完了です。

# 検索結果に表示されるか確認
#### ①URLで検索
1. Google検索エンジンの検索窓に確認したいページURLを入力して検索
1. 検索結果に、入力したページURLに該当するWebページが表示されればOK

#### ②「site:」で検索する
1. Google検索エンジンの検索窓に「site:https://〜〜.com」と入力して検索
1. 検索結果に、入力したページURLに該当するWebページが表示されればOK

#### ③URL検査ツールを使う
1. Google Search Consoleにログイン
1. 左のメニューから「URL検査」をクリック
1. 検索窓に登録したいページのURLを入力し、Enter
1. 「URLはGoogleに登録されています」といったステータスが表示されればOK


以上で、検索結果に表示されるようにする設定は終わりです！
PICO 4 VRアプリ開発 開発者モード設定

## PICO4でVRアプリを開発するために開発者モードになる方法

UnityでのVRアプリ開発についてはこちらを参照してください。

https://qiita.com/afjk/items/6b587034c9ff3afb9e5c

1. 設定＞一般＞ソフトウェアバージョンを複数回クリック
1. 「開発者」がメニューに現れるのでUSBデバッグを有効に
1. PCと繋いでapkインストール。SideQuestを使うと便利です。
1. アプリ一覧の「不明」から起動出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43734/afa2c941-69bf-d481-1e60-3193a15f03ed.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43734/01373259-da34-78d3-dae2-ac221bb66f41.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43734/c777656d-785a-a9d7-6164-4978d98bdbf3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43734/174ae139-699e-13e3-ffc9-5ad1d631854d.png)
リストのドラッグ&ドロップ終了時に通信をしたい

# 初めに
今回は、`epoxy`を使った`RecyclerView`でドラッグ&ドロップを実装する時に少しわかりづらかった部分を紹介していこうと思います
### 本文
やりたいこととしては、`RecyclerView`でドラッグ&ドロップが終わったタイミングで内部のデータの整理と通信処理を行いたいです。
この時に自分が詰まったのは意図せず通信が何度も走ってしまうという点でした。
原因としては`onModelMoved`は1個要素がずれるたびに呼び出されるので通信処理が何回も呼び出されてしまっていたのです。
そこで、調べてみると要素の入れ替えが終わり、指が離されたときに呼び出される`cliearView`というのがありました。
なので、そのタイミングで内部データと通信処理を行うようにしました。
多少省略はしてますが、コードは下記の通りになります。
```kotlin
EpoxyTouchHelper.initDragging(controller)
            .withRecyclerView(binding.recycler)
            .forGrid()
            .forAllModels()
            .andCallbacks(object : EpoxyTouchHelper.DragCallbacks<EpoxyModel<*>>() {
                override fun onModelMoved(
                    fromPosition: Int,
                    toPosition: Int,
                    modelBeingMoved: EpoxyModel<*>?,
                    itemView: View?
                ) {
                    viewModel.onImageMoved(fromPosition = fromPosition, toPosition = toPosition)
                }

                override fun clearView(model: EpoxyModel<*>?, itemView: View?) {
                    if (itemView != null) {
                        resetView()
                    }
                }
            })
```
### 最後に
名前的に`onModelMoved`が期待している関数なのかと思いましたが、よくよく考えてみると確かに`onModelMoved`という名前じゃないと、
1個ずつ動いたことを感知する関数に対しての名前に代替案がないなぁと思いました。
ただ`clearView`という関数名に納得いってないのも事実です。
慣れるしかないんでしょうかねぇ
Windows10でファイアウォール詳細設定へのショートカット作成方法

# 概要

下記画面をよく開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/d9fef612-4840-e164-4e32-352af7e1a2be.png)

毎回、コントロールパネル⇒システムとセキュリティ⇒…のようにマウスポチポチするのが面倒臭い。
ショートカットを作って即開けるようにしたい。

そんな時。


# やり方

右クリック⇒新規作成⇒ショートカット 。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/f45eec24-5009-f700-9ed0-b1c94fc507a0.png)

ショートカット先は下記。

```C:\Windows\System32\WF.msc```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/c6214236-b642-66b7-3908-afb8fabdf58a.png)

# バージョン

Windows 10 Pro 21H2 OSビルド 19044.2075
S3にポリシーを付与してもCloudFrontでAccessDeniedになりS3にアクセスできない

# はじめに

いままでCloudFormationであげていたフロントエンドがいきなりアクセスできなくなってしまった、○○さんはアクセスできるが私だけなぜかアクセスできない

などの現象が時々起きることがあります。
そのようなときは今回の内容が役に立つかと思いますので、まとめます

# 問題

いままでCloudFormationを利用して、CloudFront+S3の構成でフロントエンドをデプロイして、CloudFrontのディストリビューションドメイン名でアクセスできていたのですが、ある時に再度CloudFormationで環境構築したところ以下の画面がでました

![1665037048.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/0cb3cd55-0557-d855-a89d-e4f299998423.png)

このエラーはCloudFront→S3へのアクセス権限がないというものです

# 解決方法

まずはCloudFrontの`Origin Access Identity`が、S3バケットの許可で設定されているかを確認しました


```
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E2Q5PX59HB9ULE"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::project-test/*"
        }
    ]
```

許可はされていました
なぜだろうと思い調べていると以下の記事をみつけます

https://sashihara.jp/cloudfront-s3-accessdenied

ディストリビューションドメイン名でアクセスした際にURLが

```
https://cloud-test.s3-ap-northeast-1.amazonaws.com/index.html
```

のように、S3のURLのアクセスになっている場合はキャッシュが悪さをしているようでした

そこでブラウザを変えて(firefox)アクセスしたところ、問題なくアクセスができるようになりました

URLは以下のような形式になっていました

```
https://d1k02n6dgrtw8l.cloudfront.net/hello
```

アクセスした際にS3のURLになっている場合は、1-2時間キャッシュが消えるのを待つか、別ブラウザで試してみるとよいです

# おわりに

この現象が初めて環境構築するときに起きるとかなり困惑するだろうなと思いました
よくありそうな問題ですがネットにはあまり情報がなかったのでまとめました

# 参考

https://sashihara.jp/cloudfront-s3-accessdenied
CloudFormationのDBClusterのReadEndpoint.Address doesn't exitとなって作成失敗する

# はじめに

CloudFormationでIaCを進める中でAurolaを初めて扱いつまづいた箇所があったのでまとめます
AWSの公式では言及されていないようなので役に立てばと思います

# 問題

AurolaをCloudFormationで作成しました
そこでOutputに

```
Value: !GetAtt 'DBCluster.ReadEndpoint.Address'
```

と記するとそのような項目はないとエラーになってリソース作成に失敗しました


# 解決方法

以下の記事を発見しました

https://stackoverflow.com/questions/61194908/readendpoint-address-was-not-found-for-dbcluster

記事を和訳すると以下のようになります

```
Aurora Serverless は を必要としないことが判明したReadRecordSetため、セクション全体はプロビジョニングされた DB にのみ適用されるため、ReadEndpoint実際には存在しません。残念ながら、AWS のドキュメントには明示的に言及されていません。
```

ReadEndpointは実際には存在し内容でした
なので存在しないものをアウトプットすることはできなかったという結論になりました

# おわりに

AurolaのIaCはRDSよりもすこし複雑で難しかったですが、なんとか接続まで確認できるようになってよかったです

クラスターのみ作成すれば問題なしでした

# 参考

https://stackoverflow.com/questions/61194908/readendpoint-address-was-not-found-for-dbcluster

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-rds-dbcluster.html
[MacOS]ロリポップでFTPソフトを使う

# 概要
この記事は[ロリポップを使う前に必ずやるべきこと](https://qiita.com/LookUP/items/600d3aca7f7bed44af14)の関連記事になります。
ここではFTPソフト「Cyberduck」をロリポップサーバーで設定する方法について解説していきます。
# 環境
* ロリポップ　スタンダード
* FTP Cyberduck (8.4.4)
* Mac OS Monterey (12.3.1)
* Google Chrome 

# CyberDuckの設定
## ダウンロード
https://cyberduck.io/

こちらのページの下部にあるパッケージをダウンロードする。
インストール後起動する。

## 接続設定
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882936/b4612ac8-db00-1b03-3e81-eb042e941f98.png" width="400px" alt="起動画面">

起動するとこの画面が表示されると思います。

一度きりの接続の場合は上部の新規接続
情報を登録する際は画像左下にある＋(プラス)をクリックしてブックマーク画面で設定してください。


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882936/b585b123-40d1-6bc0-b75a-ac90d8a15d9a.png" width="500px" alt="FTP設定">

この画面で実際に設定していきます。

## 注意
最上部の設定をFTP-SSLに必ず選択してください。(デフォルトではFTP)
SFTPを選択すると接続エラーになります。

## 入力項目の場所
[ロリポップユーザー専用ページ](https://user.lolipop.jp/)の「ユーザー設定/アカウント情報」にあります。
使用する項目は以下の通りです。(コピペかメモで対応してください)

* サーバー (ftp.lolipop.jp)
* ユーザー名　(ＦＴＰ・WebDAVアカウント)
* パスワード (ＦＴＰ・WebDAVパスワード)

これでディレクトリが表示されていれば接続設定は以上になります。


# 使い方
ここからは基本的な使い方について解説していきます。
## ファイルのアップロード
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882936/58867992-4c33-c3da-664d-07e69a800444.png" width="500px" alt="ディレクトリ画面">

この画面にドラッグアンドドロップすることでファイルやフォルダにアップロードが行えます。

## パーミッション(権限設定)の変更
変更したいファイルを右クリックし、オプションから情報を選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882936/d87bfc0f-c490-f736-ff43-fdf4230f7faa.png" width="250px" alt="オプション画面">

そこからアクセス権に移動することで、パーミッションの変更が可能です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882936/f775d948-4783-5c7e-4a9e-e91cbaadbf4d.png" width="450px" alt="オプション画面">

# 参照
[ロリポップ Mac Cyberduckの設定](https://lolipop.jp/manual/hp/m-cyberduck/)
ロリポップを使う前に必ずやるべきこと

# 概要
自分が初めてロリポップサーバーでHPの構築を行った時にあまりにもロリポップ向けの資料が少なくて苦戦した記憶がありました。
Qiitaを書く機会があったので、SSL、URL正規化、.htaccesの設定方法を含めた構築をメモとして残しておきます。

# 環境
一応。
* ロリポップ　スタンダード
* FTP Cyberduck (8.4.4)
* Mac OS Monterey (12.3.1)
* Google Chrome (104.0.5112.101)
* Visual Studio Code(1.70.0)

# アップロード
今回は、
```html:index.html
<h1>Hello World</h1>
```
こちらのテストファイルをFTPの「Cyberduck」を使用してアップロードを行います。

詳しい導入方法や使い方は[こちら](https://qiita.com/LookUP/items/86c5fa68d319d5f30405)の記事にまとめてあるのでご覧ください。
今回はドキュメントルート(一番上のディレクトリ)にアップロードしたと仮定して進めていきます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882936/a9082a35-6267-b1b0-36e1-6a55e63cac45.png" width="450px" alt="ディレクトリ画面">
これでアップロード完了です。

## 反映確認
実際に確認していきたいと思います。
http ://自分のドメイン　をブラウザに入力しアクセスします。
(例http://qiita.com)
![スクリーンショット 2022-10-06 15.59.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882936/5aac54ac-1358-5b99-1d29-301fb80b5dfc.png)
このように表示されていたら成功です。

# サーバーを設定する
ファイルがアップロードできてもう完璧、**ではありません！**
まだサーバーの設定が終わっていないため、このままでは悲しいサイトになってしまいます。

ここからはと**SSLの設定**と**URLの正規化**を行っていきます。

## SSLの設定
https://lolipop.jp/manual/user/ssl-free-order/

こちらの設定を完了させてください。

## URLの正規化
ここから実際にコードを書いていきます。
URL正規化とは、同じ内容のページが複数ある場合に、Googleクローラーからの評価を受けるURLを1つに統合することです。
検索エンジンから正しい評価を受けるために、SEO対策に欠かせない対策の一つです。

ロリポップFTPから作成した方が個人的には好きですが、FTPソフトとVScodeの活用を踏まえて今回はVScodeから作成します。
先ほどSSL化によってhttpsが利用可能になりましたので、httpを使わずhttp**s**でユーザーに接続してもらうコードになります。
ここではhttpsについての解説は省略させていただきますが、この作業は通信の保護に必要なものだと思ってください。

```.htaccess
RewriteEngine on
RewriteCond %{ HTTPS} off
RewriteRule ^(.*)$ https://%{ HTTP_HOST}%{REQUEST_URI} [R=301,L]

```
これを先ほどの要領でアップロードできれば完了です。
## 注意
**.htaccessは最後に改行を入れないと動作しません**
とにかく改行して保存してください
**パーミッションの確認をしてください**
不備があると動作しない恐れがあります。

## 補足　.htaccessのパーミッションについて
ロリポップでは.htaccessファイルは604で指定することを推奨しています。
動作に問題があるときは一度確認してみてください。


# 参照
[パーミッションについて](https://lolipop.jp/manual/hp/permission/)
[htaccessリダイレクトの書き方](https://www.itti.jp/web-design/htaccess-redirect/#chapter-18)
Cloudformationで条件の真偽値を反転する

# 記述方法
AWS Cloudformationで条件の真偽値を反転する方法を記述します。
```yaml
!Not [ Condition: <Conditionの論理ID> ]
または
!Not [ !Condition <Conditionの論理ID> ]
```

```Fn::Not```関数の引数をリスト```Condition:```または```!Condition```を付けて論理IDを記述します。
# サンプル

```yaml:template.yaml
AWSTemplateFormatVersion: 2010-09-09
Description: sample template

Parameters:
  EnvType:
    Type: String
    Default: stg

Conditions:
  IsStaging: !Equals [ !Ref EnvType, stg ]
  IsProduct: !Not [ Condition: IsStaging ]
  IsProduct2: !Not [ !Condition IsStaging ]

Resources:
  SampleTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: !Sub ${EnvType}-sample-topic

Outputs:
  IsStaging:
    Value: [ Condition: IsStaging ]
  IsProduct:
    Value: [ Condition: IsProduct ]
  IsProduct2:
    Value: !Condition IsProduct2
```
```bash
$ aws cloudformation describe-stacks
...
            "Outputs": [
                {
                    "OutputKey": "IsStaging",
                    "OutputValue": "[True]"
                },
                {
                    "OutputKey": "IsProduct",
                    "OutputValue": "[False]"
                },
                {
                    "OutputKey": "IsProduct2",
                    "OutputValue": "False"
                }
            ],
...
```

# 参照

これがわかるまで結構時間が掛かったのですが、公式のドキュメントに条件の参照方法がありました。

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-condition.html
Windows10でコントロールパネル開いた時の表示方法設定

# 概要

タスクバーのショートカットでコントロールパネル開く…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/d98ed490-118f-c62b-eae9-3c01059083c5.png)

毎回下記の表示になってしまうので、コントロールパネル押してカテゴリ表示に戻している。
その作業が面倒臭い。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/47ec2853-27d1-eb39-4e22-1fb9700ba847.png)

# やり方

右上の ```表示方法``` を変更して、すぐコントロールパネル閉じる。
それだけ。
次回コントロールパネル開く時はその表示方法になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/d3248a7b-1ba8-5459-91e9-1a3128eb5ed6.png)

# バージョン

Windows 10 Pro 21H2 OSビルド 19044.2075
サイトが今朝いきなり動かなくなった？（AxiosのCDNが関係してるかも）

おはようございます。
お昼に起きたら**至急**と書かれたメールが大量に来てました。自社サイトのうちいくつかが動かないそうで...
調べてみたら、Axiosが読み込めてないようでエラーが出ていました。
~~**何もしてないのに壊れた！僕は悪くない!**~~
# 原因
Axiosは今朝、バージョン``1.1.0`` になりました。
この変更により、書き方が別物レベルで変わっています。（詳しくは[この記事を参照](https://zenn.dev/sa2knight/articles/axios-major-version)）

それによって、**CDNでバージョン指定をせずに読み込んだ場合**に最新版が適用されてしまい動かなくなるようです。
# 対処法
CDNをバージョン指定で貼り付けましょう。
https://cdnjs.com/libraries/axios/0.27.1
上のサイトからバージョンごとのCDNを取り出して付け替えると正常に動作するはずです。
```html:動かない(バージョン指定してない)
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
```
```html:動く（バージョン指定した）
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.27.1/axios.min.js"></script>
```
# 教訓
CDN貼る時はバージョン指定しようね！
VisualstudioCodeでDrowioを共有する方法

#  1.VisualStudioCodeで拡張機能をインストールする
######   VisualStudioCodeを起動し、「拡張機能」を開く
- 「Draw.io Integration」をインストールする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2893241/2d60be77-48f1-15c4-81c4-b73bd6f90654.png)
- もう一つ「Live Share」をインストールする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2893241/250102a4-393e-7933-1c9a-eb6eed3134c4.png)
######   インストールが完了したら次へ進む
#  ２.共有への参加方法
###### まずはログインを済ませておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2893241/df6b1eea-89f2-eb78-1367-47d0b3fd56ab.png)
左のバーにこのアイコンが表示されているのでクリック
そこから会員登録(今回の場合はMicrosoftを選択)
終了したら参加準備が可能になる
### 共有を始める方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2893241/51ea7628-0221-0e16-f273-1d39214e68d6.png)
-  「share」をクリックする
ー＞リンクがコピーされているので、共有したい相手に送信する

###### リンクを開いた後
ページの表示までが長いから、閉じないように要注意
### ※Mac OSの場合の画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2893241/c3e3e376-4c74-fe48-2f74-d6c2407b298b.png)
windowsの場合も同じように、ブラウザからVisualStudioCodeを起動してください
起動できたら接続完了です
# 最後に
ここまでざっくりとだけ記述しました
かなりわかりにくい記事になっていますが、助けになれば幸いです
もし分からなければ気軽にご相談ください
【C言語】各桁の合計が条件に合う範囲内の整数の和を求めるプログラムのミス修正【備忘録】

# 各桁の合計が条件範囲内である整数の和を求める

AtCoderで練習問題を解いたのでそのときのメモです。
サンプル入力では正解の値が出るのに、提出するとなぜかWA(Wrong Answer)となってしまい、どこが間違っているのか探すのに苦労しました。


>問題：
>1以上N以下の整数のうち、10進法で各桁の和がA以上B以下であるものの総和を求めてください。
>制約：
>・1 ≦ N ≦ 10^4
>・1 ≦ A ≦ B ≦ 36
>・入力はすべて整数
>
>（AtCoder ABC083B-Some Sums より引用）



### 方針1
・各桁を0～9に増やしていくループを桁ごとに入れ子にする
・ループ内で整数の値を求め、条件に合致するか判定する

始めに思いついたのはこちらの方針でした。
```diff_c
//方針1
//10000の位を追加し忘れたためWAになっていた
#include <stdio.h>
int main(void)
{
    //input
    int h, i, j ,k, l, answer;
    int n, a, b;
    scanf("%d %d %d", &n, &a, &b);
 
answer = 0;
for (h = 0; 2 > h; h++) { //ここのループ（1万の位）を忘れていた！
    for (i = 0; 10 > i; i++) {
        for (j = 0; 10 > j; j++) {
            for (k = 0; 10 > k; k++) {
                for (l = 0; 10 > l; l++) {
                    if (a <= h+i+j+k+l && i+j+k+l <= b) {
                        if (h*10000 + i*1000 + j*100 + k*10 + l <= n) {
                            answer += h*10000 + i*1000 + j*100 + k*10 + l;
                        }
                    }
                }
            }
        }
    }
}
 
    //output
    printf("%d\n", answer);
    return 0;
}
```

::: note info
10^4(10の4乗)は10000なので5桁になりうる
:::
制約にあるとおり範囲は1 ≦ N ≦ 10^4なのでn = 10000となることがありうるのですが、4桁の1000が最大だと思い込んでいたようです。
ループを追加すると解決しました。


### 方針2
・判定する整数を1～Nまで順に増やす一重のループにする
・ループ内で各桁の値を求めて条件に合致するか判定する

方針2の方がループも少なくて済むのでスムーズに見えます。

また、桁数の和を求めるときに`i/10000...`とすべきところを`n/10000...`と書き間違えており、ループの意味がないというミスがありました。nをiに書き直すと解決しました。

::: note info
整数Nの10のx乗の位は` (N%10^(x+1)/10^x `で求める
例） 千の位なら **(n%10000)/1000**
:::

```diff_c
#include <stdio.h>
int main(void)
{
    //input
    int n, a, b;
    int sum, i, keta;
    scanf("%d %d %d", &n, &a, &b);

    sum = 0;
    for (i = 0; n >= i; i++) {
        keta = i/10000 + (i%10000)/1000 + (i%1000)/100 + (i%100)/10 + i%10; 
        // ↑↑↑　書き間違えに注意！
        if (a <= keta && keta <= b) {
            sum += i;
        }
    }

    //output
    printf("%d", sum);
    return 0;
}
```
2022/10/6実施
2022/10/7修正
参照先：AtCoder

https://atcoder.jp/contests/abs/tasks/abc083_b

### 今後の課題
・出てくる変数が増えてきても落ち着いて把握すること
・制約をしっかり読み、漏れなく場合分けをすること
【備忘】"mach-o file, but is an incompatible architecture (have (x86_64), need (arm64e))"が出たときの対応

npm startすると以下のようなエラーが出ました。
エラーメッセージは消えてしまったので記憶のみで書いていきます。

dlopen
iconv.node' (mach-o file, but is an incompatible architecture (have (x86_64), need (arm64e))

みたいなことが出ました。

当方M1 Macを使用しているので、
>have (x86_64), need (arm64e)

ここが謎だったのですが、

```npm install iconv```

であっさり解決しました。チップ関係なく、iconvがなかった？か、古かったみたいです。


参考：
https://github.com/bnoordhuis/node-iconv/issues/34
『システム運用アンチパターン』輪読会 10章「情報のためこみ：ブレントだけが知っている」

## まえおき

* チームで『システム運用アンチパターン』の輪読会をしている
* 有料集客関連の開発だと、広告知識やデータ知識が必要で、一部のメンバーに知識が溜まってしまう傾向があるので、この章を読むことで対処方法を知りたかった
* 実際は「運用チームの権限集約をなんとかする」ような的な話が多くて、ヒントは多そうだが、そのままチーム内で参考になるわけでもなかった


---

* 意識しないとキーパーソン（『[The Phoenix Project](https://www.amazon.co.jp/DevOps-%E9%80%86%E8%BB%A2%E3%81%A0-%E3%82%B8%E3%83%BC%E3%83%B3%E3%83%BB%E3%82%AD%E3%83%A0/dp/4822285359)』の登場人物のブレント）に知識が集まる
* 情報を積極的に共有すればいい？→公開するだけでは興味を持てるわけではない
* ひどいと誰も全体を見なくなる

---

## 10.1 どのように情報がため込まれているのかを理解する

* 悪意があって管理者が情報をため込んでいるケースは少ない
* また、「意図的なため込み」も、インセンティブ設計が間違っていることが原因のことが多い


---

## 10.2 意図せずに情報をため込んでいる人を認識する

* ある人が概念検証のプロジェクトに関わってて、いろいろ試行錯誤して、変更が落ち着いたらPJを離れる
* その結果、「ドキュメントを書く」タスクはjiraの闇の中へ…
* （あとは想像どおりの内容ｗ）

---

### 10.2.1 ドキュメントを大切にしない

* ドキュメントの価値は、美辞麗句ではなく行動に根ざしている
* 例えば、経費精算のドキュメントがなくなると、我々がその作業ってできなくなるよね？
* 別PJに行くのは悪いことではなく、「情報の共有」を達成することが大事で、もっと楽な方法があれば代替していい

---

### 10.2.2 抽象化 vs. 難読化

* 抽象化されたレイヤを用意して、関心の分離を行うことがある（ピザのサイトで、普段は「注文処理」と「配送システム」を分けるとか）
* ただ、横断的な施策で「注文チームの変更が配送システムに影響がないか」を調べるときに困るようになる
* また、チーム間で壁を作って、一旦汚いコードで実装したときなど「住んでる人にしか状況が分からない」状態になりがち


---

### 10.2.3 アクセス制限

* 運用チームなどパスワード管理などが必要なことが多いチームでは、Wikiにアクセス制限をかけることが多い
* ただ、その範囲は広がりがち
* 大抵の人は「鍵のかかったドア」を見ると、「この中は自分には関係ない」と思いがち


---

### 10.2.4 ゲートキーパーの行動を評価する

* 良心に従っていても、ゲートキーパーになることがあるので、自分自身を振り返ろう
* ドキュメント化して、依頼者自身が作業を実施できるようにする必要がある
* 次の節でドキュメントを上手に扱う方法についてまとめる

---

## 10.3 コミュニケーションを適切に定義する

* 我々の文脈だとSlackでの告知に役立つ話
* 誰もが知識を伝えるスキルを持っていると考えがちだが、そんなことはない
* 4つの学習方法、視覚・聴覚・読み書き・体験（ハンズオン）があって、自分と違うスタイルを好む人もいるのを覚えておこう
* 次のコミュニケーションステップに従おう


---

1. トピックを定義する: 同じ「テレビ」がテーマでも、社会的影響をテーマにするのか、番組をテーマにするのかで違う
1. 対象者を定義する: 小学生に説明するときは「コンパイラ」は用語説明が必要。対象がエンジニアでも、文脈の違う人のためにリンクで補足しよう
1. キーポイントを説明する: 「絶対に伝えたいこと（コアポイント）」と「理解を深めるのに役立つこと（カラーポイント）」を区別できるようにしよう
1. 最後に行動を喚起する: 「自分のチームに共有」とか「アンケートの回答」とか、どういう行動をとってほしいのか説明しよう


---

## 10.4 知識を発見可能にする

* 情報を共有するプロセスは意図的に行う必要がある
* ナレッジストア（Wiki等）を管理して、その構造に関するガイドラインの策定には注意が必要
* 誰もが日常業務で行うべきことだが、明確な指示と優先順位付けがなければ劣後してしまう

---

### 10.4.1 ナレッジストアの構築

* 共通の辞書を使おう。著者によると、用語の違いだけで同じモジュールの話をしているのに10分気づかないこともあったらしい。プロジェクト名をそのままプロダクト名として使っちゃって混乱することもある
* ドキュメントを階層化しよう。例えば「請求書作成」のプロセスが担当部署ごとに分散していることがよくある（→具体的なフォーマットの話は割愛）
* 部門ではなくトピックを中心に

---

## 10.5 学習の習慣付け

* 組織が繰り替し行う活動やイベント（＝習慣）が文化の構築に大きな影響を及ぼしている
* ただ、SME（Subject Matter Experts、※専門性を持った人）は既に責務が多く、「ドキュメント作成」という新しいミッションを追加すると悪循環に陥りがち
* 負担もかけるし、人によって得意分野は違うので、チームメンバーと共有の仕方を議論しよう


---

習慣付けで紹介されている4つの方法

* ランチ&ラーン
* ライトニングトーク
* 外部イベントのホスト
* ブログ

---

## 10.5 チャットツールの有効活用

* チャットツールは情報共有のための素晴らしい手段
* ただ、適切に作法を定義しないと、猫の写真やカップケーキのレシピで埋め尽くされてしまう🐈

---

### 10.5.1 会社の作法を確立する

会社によってチャットツールの文化は違うが、次のような方法を明示するのはおすすめ

* 短命でトピックを絞ったチャンネルを使う
* スレッド機能を使う
* 定期的に自分のステータスを更新する。「話しかけていい時間」を明示する
* `@here` などを使いすぎないようにする

---


### 10.5.2 チャットだけではない

* 自動化などで強力なメリットがある
* チャットボットでシステム管理すれば、他にも障害対応の作業内容が他のメンバーにも明示できるというメリットもある
* チャットボットにより、特定のタスクを運用チーム以外にも権限を渡すこともできる
FlutterWebのUnsupported Platform系エラーの解決


## 環境
Flutter 3.3.1 
Dart 2.18.0

## エラー内容
The following UnsupportedError was thrown building Builder:
Unsupported operation: Platform._operatingSystem

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283248/3b4bda94-7b97-799f-f338-e933be988efd.png)

## 原因
iOSでもAndroidでもなく、Webで起動した場合、Platformオブジェクトを使うことができなくなるらしい。下記の部分をtry catchで囲んでしまえばよい。
```
import 'dart:io';
・・・
    // OS名を取得
    String os = Platform.operatingSystem;
    print("OS = $os");

    // OS判定
    bool isAndroid = Platform.isAndroid;
    print("isAndroid = $isAndroid");
```
Laravelで作ったアプリをECS Fargateにデプロイする際に躓いたこと

## はじめに
Laravelで作ったポートフォリオをFargateでデプロイする際に1,2週間かかってしまったので今回はデプロイするときに躓いた点をまとめてみようと思います。
下記の記事を参考に構築しました。

https://qiita.com/hirai-11/items/241df305a90af3ccf973

### 環境
|項目|情報|
|---|---|
|Laravel バージョン | 8.83 |
|PHP バージョン  |8.1.1   |

## 500 Server Errorになる
composer installをしてデプロイする
上記の参考にしたsrcディレクトリでは上手くいくのですが、自分が作ったアプリケーションでは上手くいかなかったのでsrcディレクトリに問題があるのではないかと思い、いろいろ試した結果composer installをすると上手くいきました。

## ECRリポジトリにpushする前に古いリポジトリを削除しないといけないと思っていた
ECRリポジトリに同一のタグ付けされたイメージがある時に新しくpushをすると下記のようにuntaggedなります。
しかし、タスクが実行されるコンテナのイメージは新しくpushしたイメージになります。
![スクリーンショット 2022-10-07 10.16.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/712442/567a00fc-7e47-8302-ea84-9dc3c869733a.png)
【ビルド不要】たった3行でpythonのインストールされていないDockerイメージにpythonをインストールする方法

# これ

```
COPY --from=python:3.8.14-slim-bullseye /usr/local/bin/ /usr/local/bin
COPY --from=python:3.8.14-slim-bullseye /usr/local/lib/ /usr/local/lib
RUN ln /usr/local/lib/libpython3.8.so.1.0 /lib64/libpython3.8.so.1.0 && ldconfig
```
windowsでDHCPサーバーを動かす

## 参考

* [Windows 10 に DHCP Server をインストールする](https://ez-net.jp/article/B7/ExsRC2pP/ZYG4VuOvaYjJ/)

## Download

* https://sourceforge.net/projects/dhcpserver/
    * OpenDHCPServerInstaller64bitV1.82.exe

## 設定

* C:\OpenDHCPServer\OpenDHCPServer.ini

192.168.1.11 : PCの有線LANの固定IP
192.168.1.128-192.168.1.254 : DHCP配布範囲

```go
[LISTEN_ON]
192.168.1.11

[LOGGING]
LogLevel=Normal

[HTTP_INTERFACE]
HTTPServer=192.168.1.11:6789

[RANGE_SET]
DHCPRange=192.168.1.128-192.168.1.254
SubnetMask=255.255.255.0
DomainServer=192.168.1.11
Router=192.168.1.1
AddressTime=36000
```

### ログ確認

* C:\OpenDHCPServer\log\

### 起動方法

`services.msc`でサービス一覧を表示し、

`Open DHCP Server`を起動させる。
Property WrapperとCodableを使ってJSON解析時のデータ型を変換する

### Property Wrapperとは
プロパティに対して制御を行う仕組み
[Swift Language Guide](https://docs.swift.org/swift-book/LanguageGuide/Properties.html)
### Codableとは
JSON形式を任意のデータ型に変換するプロトコル
[Appleのドキュメント](https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types)
### CodableとProperty Wrapperを連携して使う場面
例えばJSONではStringで定義されたが、実際アプリで使う際はIntになる場合など

Json File
```json
{
"id":"200"
"version":"100" //アプリ側は数値として使いたい
}
```
Swift Code
```swift
struct Hoge: Codable {
    let id: String
    @VersionValue
    let version: Int
}

@propertyWrapper
struct VersionValue: Codable {
    var wrappedValue: Int

    int(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let stringValue = try? container.decode(String.self), let intValue = Int(stringValue) {
            wrappedValue = intValue
        } else if let intValue = try? container.decode(Int.self) {
            wrappedValue = intValue
        } else {
            throw DecodingError.dataCorrupdateError(in: container, debugDescripition:"version invalid")
        }
    }
}

```
PHPによる特許情報取得APIのトークン取得

# 特許情報取得APIについて
日本国特許庁が提供するサービス。
特許情報を取得するためのRest-APIです。
本記事では、PHPで特許情報取得APIのトークンを取得する方法について、説明します。
特許情報取得APIについては、他の方がまとめてくれています。

https://qiita.com/kenichiro_ayaki/items/dde737d0d5561c5e4b4c

# PHPでトークンを取得する
特許情報取得 API 利用の手引きには、以下の形式でトークンが取得できるという記載がありますが、PHPでは取得時にエラーが発生しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2893056/44f4664d-d049-8bf1-d4e2-7019c5f94af0.png)

特許庁 総務部 総務課 情報技術統括室 特許情報企画調査班に問い合わせたところ、PHPやプログラミング言語によっては、Headerに"User-Agent"を追加する必要があるという回答をいただきました。
プログラミング言語によって、なぜ"User-Agent"を追加しなければいけないかは調査中とのことです。

```
<?php
$header = [
	'Content-Type: application/x-www-form-urlencoded',
	'User-Agent: (任意の文字列)'
];

$body = array(
	'grant_type' => 'password',
	'username' => 'ユーザ名（未エンコード）',
	'password' => 'パスワード（未エンコード）'
);

$body_data = http_build_query($body);

$ch = curl_init();
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_URL, 'https://ip-data.jpo.go.jp/(トークン取得パス)');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);
?>
```
コンポーネント原則(SAP)

# 安定度・抽象度等価の原則
これは安定しててほしいものは、それに伴って抽象度もあげましょ～て原則です。

これは様々なところから依存されてる本来安定しててほしいところにも
変更がどおしても入らざるを得ない場合、
具象なままだと、変更した影響がパッケージ内に閉じてなくて、他のパッケージにまで波紋しちゃいます。
これはパッケージレベルでのOCP開閉原則にのっとってないですね。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/d58f14da-c34f-6592-c0f2-05775501d492.png" width=60%>

図で言うと、本来安定していてほしい具象A1に、もしも変更が発生しうる場合、
このままだとB1にも影響出ちゃうし、B2にも。
下手したらB2が変更されたことで、C1にも変更しないといけなくなってしまい、
結果的にパッケージa内のたった１か所の変更がbにもcにも波紋してしまってる。

できればこんなことにならずに、A1を修正したい場合、
新しいA2なるものを付け足して、そのA1とA2の違いを　B1やB2には悟られずに(情報隠ぺいして)
切り替えられるようにしたい。
だからA1やA2から抽象概念をAを抽出して、それをB1やB2は参照するって風にしてあげたくなる。
そうすれば、A1からA2に切り替えたりしても、aとbの結合も疎結合なままで、その変更の影響はa内に閉じている。

以上のことから、
安定していてほしいものは、安定が保証されていない限り、
安定度合いに見合った抽象度合いすることで、開閉原則を満たしやすくするっていう原則でした。

ただ、最初っからこんな風に抽象をばかすか作ればいいってもんではなくて(複雑度が増すから)、
最初はあえて変更を受け入れてみる。そしてA1に変更が起きるようなことがあれば適切に抽象を新しく定義してあげる。
このようにあえて変化が起きるようにするためにも、変化を促すアジャイルな制作活動が有利なんですかね～～。
　

## 注意事項
これもなんでも安定しててほしいものは、抽象度をあげなさいってことではなく、
具象だけども安定しているものは、わざわざ抽象化しなくていい、ていうかしちゃうと
複雑度が増しちゃうからダメってこともこの原則には入っていると思います。

　

## 抽象度合いの計測
そのコンポーネントの抽象度は、以下の式で表せます。
コンポーネント内のinterfaceや抽象クラス、具象クラス含めた総数をNc。
コンポーネント内のinterfaceや抽象クラスなどの抽象的なものの総数をNaとすると、
コンポーネントの抽象度A ＝ Na / Nc

つまりこの数値が0ならそのコンポーネントには具象しかなく、1なら抽象なものしかない。

　

## 等価といえるゾーン（等価の原則にのっとってるかのチェックの指標）
![svx767wu790j7rg9efm6jbij3jm0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/3e9e4f4b-54e8-62c4-d687-a316109c8045.png)

横軸が不安程度 I、縦軸が抽象度 Aである。 
このとき、安定度と抽象度が等価かどうか見分ける指標として、 
安定度と抽象度が完全に一致する主系列から、どのくらいの距離までなら等価とみなせるのか？ を事前に定義して、
そこよりも離れているところはとても等価とは言えないから、
主系列からものすごく離れてるものから優先度付けてチェックすることが望ましい。
(望ましいていうのは具象なものがたくさんあるけど、とてもとても安定しているものもあるかもしれないから)

たとえば原点に近い苦痛ゾーン内にあるような場合は、
より安定的であるため変更しづらく、抽象度が低いから拡張しづらい。
これはだいぶ痛手、、、だから苦痛ゾーンてよばれてるんでしょうか？

逆に(1,1)に近い無駄ゾーンにあるような場合は、
結構抽象化されているにもかかわらず、不安定であるから変更されやすいてこと。
つまり、極端な話めちゃくちゃ変更の入るinterfaceみたいなもの。
それってなんのために抽象化されてるかわからないから複雑度が増すだけで無駄。
だから無駄ゾーンていわれてるんですね。
Azure Fundamentals(AZ-900)：Azure の基礎: Azure のアーキテクチャとサービスについて説明する「Azure管理インフラストラクチャ」

Microsoft Learnを用いたMicrosoft Azure Fundamentals(AZ-900)の試験内容をまとめる投稿です。
この投稿ではMicrosoft Learnで学ぶ内容をできるだけ簡潔にまとめております。
Azureの勉強を一から始める方の参考になれば幸いです。

## 今回の学習内容
**◆「Azure管理インフラストラクチャ」**
◇対応するMicrosoft Learn ラーニングパス
[Azure の基礎: Azure のアーキテクチャとサービスについて説明する](https://learn.microsoft.com/ja-jp/training/paths/azure-fundamentals-describe-azure-architecture-services/)
◇対応するモジュール
[Azure の管理インフラストラクチャについて説明する](https://learn.microsoft.com/ja-jp/training/modules/describe-core-architectural-components-of-azure/6-describe-azure-management-infrastructure)

※前回の投稿は下記から確認できます。
[Azure Fundamentals(AZ-900)：Azure のアーキテクチャとサービスについて説明する「Azure物理インフラストラクチャ」](https://qiita.com/fsd-jume/items/503268657c26a9b45749)

## Azure管理インフラストラクチャ
**◆リソース
Azureの基本的な構成要素であり、Azureが管理できるすべての対象**
実際にAzure環境上に構築する各サービス
・例)仮想マシン(VM)や仮想ネットワーク、データベース、Webアプリなど

**◆リソースグループ
各リソースをまとめてグループ単位で管理できるようにしたもの**
リソースグループに対して更新や削除、セキュリティ設定を行うとグループ内のすべてのリソースにも適用される
→ライフサイクルやセキュリティが同じリソース同士でグループに配属させることが推奨
・リソースは必ずリソースグループに属している必要がある
・1つのリソースは1度に1つのリソースグループのみに属することができる
・リソースグループ同士の入れ子構造は不可
(例：リソースグループBをリソースグループAの中に入れることはできない)

**◆サブスクリプション
リソースグループを論理的にまとめ、アクセス制御や課金を容易にするもの**
サブスクリプションごとにAzure使用料金の課金やアクセス制御を管理することができる
・1つのサブスクリプションに複数のリソースグループを属することができる
・サブスクリプションにアクセス管理ポリシーを適用すると、そのサブスクリプション内のすべてのリソースグループとリソースに適用される
・サブスクリプションによりAzureの製品とサービスへのアクセスが認証および承認される
・Azureアカウントに紐づいており、1つのアカウントに複数のサブスクリプションを含めることができる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851723/b88ae4c4-f4ae-3f69-29ee-a7391137b0a1.png)

**◆サブスクリプションの追加による管理
サブスクリプションを追加することでリソースへのアクセス制御や課金管理の目的に応じて個別に管理することができる**
・例)環境による個別管理：開発とテスト、セキュリティ、コンプライアンス上の理由でデータを分離したいとき
・例)組織構造による個別管理：部門によるリソースへのアクセス権限を制御したいとき
・例)課金管理による個別管理：運用と開発/テストでコストを分けて管理分析したいとき

**◆管理グループ
複数のサブスクリプションをまとめて、大きな規模で管理できるようにしたもの**
配下の管理グループやサブスクリプションに同一な管理ポリシーやアクセス制御を適用可能
・例)仮想マシン(VM)の作成に使えるリージョンを制限するポリシーを管理グループに適用
→その管理グループ配下のすべてのサブスクリプション、リソースに適用され、承認されたリージョンでのみVM作成が許可される
・管理グループ作成時に、最上位のルート管理グループが自動で作成される
・ルート管理グループにはすべての管理グループとサブスクリプションが属している(最大10,000個の管理グループをサポート)
・管理グループのツリーは最大6レベルの深さをサポート(ルート管理グループとサブスクリプションは含まない)
・各管理グループとサブスクリプションでは、1つの親のみサポート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851723/4b7aead4-c7e6-86ed-0e3d-95c6a0112def.png)

## 次の学習内容
**◆Azure Virtual Machines(VM)**

https://qiita.com/fsd-jume/items/2045fe8a3e9fad49c886

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/e4ec76959adb547ac5e8
Sentry (App Monitoring Service) でさくっと Web API のボトルネックを探せた感動を共有したい

# はじめに

エラー監視の文脈で紹介されることが多い Sentry (https://sentry.io/ 以降、Sentry) ですが、Performance  Monitoring の機能を利用してさくっと Web API の ボトルネックを探せた感動を共有したいです 🤗

"さくっと" には前提があります。
詐欺にならないように App Monitoring Service と記載しましたが、 OSS の紹介を期待して読み始めた皆さん、ごめんさい 🙇🙇‍♀️

# "さくっと" の前提 😈 

### Sentry の契約
プランは[こちら](https://sentry.io/pricing/)です。 
私の場合、自社で Team プランに入っていましたが、一番下のプランから Performance  Monitoring の機能が使えるみたいです。

### HTTP Frame Work が Sentry に対応しており、かつ モニタリングに対応したバージョンの SDK に対応している
対応言語・プラットフォームは[こちら](https://docs.sentry.io/platforms/)です。
私の場合 プロジェクトの FastAPI (Python Frame Work) のバージョンに依存した SDK だと Monitoring データの蓄積が始まらなかったので、FastAPI をバージョンアップする必要がありました。

### SDK を install してトラック用コードを埋め込む

FastAPI の場合は本当にこれだけのコードを書くだけで Monitoring データの蓄積が始まりました。

``` python
import sentry_sdk


sentry_sdk.init(
    dsn="https://examplePublicKey@o0.ingest.sentry.io/0",
    traces_sample_rate=1.0,
)
```

https://docs.sentry.io/platforms/python/guides/fastapi/

# ボトルネックをどのように探すのか

Performance  Monitoring の画面に表示されている event_id (リクエスト単位のid) をクリックすると以下のような画面が表示され、http 通信・DB のどこに時間がかかっているかのタイムラインを表示してくれます。

![スクリーンショット 2022-10-06 23.42.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110482/98d5359f-4eab-fab3-2652-7a4bc80c8c87.png)


上記スクリーンショットでわかるように、 ORM で 1 + N な問い合わせが速度低下の原因になっていることを確認できました。

# 所感

たった数行のコードを追加するだけで、発行されているSQLも含めた情報を出してくれることに驚きました。前提さえ揃っていればいればすぐにボトルネックの当てがつくので、是非試していただきたいです。

以上、共有でした。
Salesforce認定アドミニストレーター試験の公式練習問題を解説してみた-その046

こんにちは。本橋孝昭です。

Salesforce認定アドミニストレーター試験の公式練習問題があるのはご存じでしょうか。
Trailheadにフラッシュカードとして何度も解ける練習問題がございます。

今回はTrailhead
アドミニストレーター認定の準備: データと自動化
ワークフローと自動化の学習

にある練習問題2問目をご紹介します

なお今回の内容は動画でも紹介されています

https://www.youtube.com/watch?v=9XwZZHHnVDc

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




今回の内容はこちらです

https://trailhead.salesforce.com/ja/content/learn/modules/administrator-certification-prep-security-and-data-management/study-up-on-security-and-access?trail_id=administrator-certification-prep




![０２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/6d9576bc-418e-a3bf-2ae3-5dd4de826262.png)


今回の問題としては
・２日後に顧客にメールが飛ぶ
というプロセスビルダーの作成が前提としてあります

このプロセスビルダーを起動した際に、「２日後にメール送信」という状況をどこで確認するか　というのが今回の話です

これは正解のように「一時停止中のフローインタビュー」で確認することが可能です