OmniAICreator/Qiita-1.07M huggingface dataset:
Data Portal の AppSheet データソースを軽く試してみた

Data Portal の データに接続画面を見ていると、見慣れたアイコンが。

「あれ？こいつ、いたっけ？いつの間に...」
![スクリーンショット 2022-09-09 0.00.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/62a7fb80-3e5a-7c59-4c76-a5c8b684148d.png)
AppSheet の テンプレートから Kanban Board アプリを作成して、データを利用してみました。
![スクリーンショット 2022-09-09 0.00.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/22320d0f-23db-0af1-b57a-5ae63d515e3a.png)
Data Portal でのデータの追加は、アプリケーションとテーブルを指定する事で取り込めました。
![スクリーンショット 2022-09-09 0.01.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/e12eff60-3f9c-9d0e-1cb1-96cde6296248.png)
テーブルの選択肢は、テーブルだけではなく AppSheet で定義したスライスも対象になっていました。
![スクリーンショット 2022-09-09 0.24.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/9aa9e0c4-14f9-2d4d-d16d-7139aa67f3b2.png)
AppSheet データソースを利用して、簡単に Data Portal のレポートを作成する事ができました。
AppSheet で定義したバーチャルカラムも、そのまま利用できました。
![スクリーンショット 2022-09-09 0.25.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/10cdc470-94c2-7f9f-d17e-3556deff71d4.png)
データの更新頻度がスプレッドシートの場合と若干違っており、スプレッドシート側には無い30分ごとがありました。
![スクリーンショット 2022-09-09 0.27.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/8eb522a9-9f55-b0da-1dbd-88b3c6e84183.png)
AppSheet で作成したデータの保存先がスプレッドシートなのであれば、AppSheet をデータソースとしてしまった方が便利そうです。
バビロニア数学における平方根の近似計算を再帰的に求める関数として表現した

## はじめに

JSのMath.sqrt関数が存在しない場合、自然数nの平方根はどうやって求められるか？

```math
\sqrt{n}
```

バビロニア数学における平方根の近似計算方法をアルゴリズムとして利用すれば解けるらしい。

https://www.jstage.jst.go.jp/article/jhsj/25/157/25_50/_article/-char/ja/

## 解いてみる

例えば、2の平方根を求めたい場合。

一旦1.5だとして見積もってみましょう。（実際には`1.41421356`と知りつつ）


```math
\sqrt{1}<\sqrt{2}<\sqrt{4}\\
1<\sqrt{2}<2\\
```

2の平方根は、1と2の間であることはわかる。

同じ方法を小数点第一位まで求めてみる

```math
1.0^2=1.00 \\
1.1^2=1.21 \\
1.2^2=1.44 \\
1.3^2=1.69 \\
1.4^2=1.96 \\
1.5^2=2.25 \\
```

2の平方根は 1.4 と 1.5 の間にあることがわかります。

どちらかといえば1.4の2乗 に近いので、近似値を 1.4 とします。

同様に小数点第二位、三位と繰り返えせば近似値はどんどん性が高まりますが計算量が多くなりそうです。

そこで、バビロニア数学を使えば、計算量を抑えて近似値を求められます。やってみます。

自然数 2 の平方根の近似値を仮にxとすると

```math
x^{2}≒2\\
x ≒ \frac{2}{x}
```

近似値は1.4なので

```math
x ≒ \frac{2}{x}\\
1.4  ≒ \frac{2}{1.4}\\
1.4  ≒ 1.42857142857\\
```

バビロニア数学における平方根の近似計算方法は、

**平方根の正しい値は、上記の２つの値の間にあるはずで、その平均値を推定値として何度か求めると、だんだん正確な値が推定できる**という考え方です。


```math
x と \frac{2}{x}　の平均
```

つまり

```math
\frac{x+\frac{2}{x}}{2}
```

が近似値であると言えます。

この近似値の推定値を再帰的に計算し続ければ限りなく2の平方根はもとまるだろうというのがバビロニア数学の平方根の求め方です。ベースケースでは相対誤差0.1%のズレがなければ、それを回答として出力するようにします（プログラムでは）。

相対誤差 0.01% 未満なら、

```math
x_{n}
```

を返す。

相対誤差 0.01% 以上なら、新たな推定値（Sは推定値）

```math
\frac{x_{n-1}+\frac{S}{x_{n-1}}}{2}
```

## JSで書くとこんな感じ

再帰的な処理を使って求めようとしています。

```js
// 相対誤差：　誤差を理論値で割ったもの（理論値と測定値がどれほど離れているかを％で表す）
// ベースケース: 相対誤差が 0.01% 未満に収まるように設定
const isSquareRootCloseEnough = (a,b) => 100 * Math.abs((a-b)/b) < 0.01

const squareRootHelper = (x, guess) => {
    // バビロンの数学者は平方根の正しい値は guess と x/guess の平均（newGuess）である説
    let newGuess = (guess + x/guess)/2
    // ベースケース
    if(isSquareRootCloseEnough(newGuess, guess)) return guess
    // xが第一引数はintSquareRootのと変わらず。第二引数は newGuessで
    return squareRootHelper(x, newGuess)
}

// 平方根の近似値を返してくれる
const intSquareRoot = (x) => squareRootHelper(x, 1)
```

4回目まで手計算した結果も一致しているので間違いなさそう。

仮に、引数を12としたら...

```
intSquareRoot(12) で実行したら
return 28.63564310305401512
と返ってくる予定
```

手計算してみる。

![IMG_9D98605187C3-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/ce232c27-315c-4031-5b44-010684044dbd.jpeg)

あってそう。

結構シンプルなロジックなのに、平方根の近似値を計算できるなんて、すごいですね。

以上です。
FlutterでiOSのselectionHandleColorを設定する方法

## 概要
iOSにおいて、テキスト選択時のハンドルカラーを`textSelectionTheme`で変更することができず、つまずいたので方法を紹介します。

<img width="400" alt="スクリーンショット 2022-09-09 0.07.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328421/8d1b4b39-a31f-65ab-24bc-10b54d8eb05f.png">


## Androidの場合
テキスト選択時の設定は全て`textSelectionTheme`で設定できます。
```dart
ThemeData(
  // ...省略...
  textSelectionTheme: TextSelectionThemeData(
    selectionColor: selectionColor,
    cursorColor: cursorColor,
    selectionHandleColor: selectionHandleColor,
  ),
  // ...省略...
);
```

## iOSの場合
`selectionColor`と`cursorColor`は`textSelectionTheme`で設定することができますが、セレクト時のハンドルカラーについては、`selectionHandleColor`を設定しても`primarySwatch`の色のままになってしまいます。
iOSでは、selectionHandleの色を変更するために、`cupertinoOverrideTheme`を用いる必要があります。

```dart
ThemeData(
  // ...省略...
  textSelectionTheme: TextSelectionThemeData(
    selectionColor: selectionColor,
    cursorColor: cursorColor,
    selectionHandleColor: selectionHandleColor,
  ),
  cupertinoOverrideTheme: CupertinoThemeData(
    primaryColor: selectionHandleColor,
  ),
  // ...省略...
);
```

## 参考文献
https://github.com/flutter/flutter/issues/43887#issuecomment-716818180
Vi Editor

# はじめに
Vi コマンドについてまとめる。
# Vi Editor
|command|Explain|
|-|-|
|vi file|Edit file|
|vim file|Same as vi, but more features|
|view file|Starts vim in read-only mode|
</br>

|command|Explain|
|-|-|
|k|Up one line|
|j|Down one line|
|h|Left one character|
|l|Right one character|
|w|Right one word|
|b|Left one word|
|^|Go to the beginning of the line|
|$|Go to the end of the line|

</br>

|command|Explain|
|-|-|
|i|Insert at the cursor position|
|I|Insert at the beginning of the line|
|a|Append after the cursor position|
|A|Append at the end of the line|

</br>

|command|Explain|
|-|-|
|:w|Writes the file|
|:w!|Forces the file to be saved|
|:q|Quit|
|:q!|Quit without saving changes|
|:wq!|Write and quit|
|:x|Same as :wq|

</br>

|command|Explain|
|-|-|
|:n|Positions the cursor at line n|
|:$|Positions the cursor on the last line|
|:set nu|Turn on line numbering|
|:set nonu|Turn off line numbering|
|:help|Get help|

</br>

|**Mode**|**Key**|
|-|-|
|Command|Esc|
|Insert|i I a A|
|Line|:|

</br>

|**Repeating Commands**||
|-|-|
|5k|Move up a line 5 times|
|80i Text Esc|Insert Text 80 times|
|80i_Esc|Insert 80 "_" characters|

</br>

|command|Explain|
|-|-|
|x|Delete a character|
|dw|Delete a word|
|dd|Delete a line|
|D|Delete from the current position|

</br>

|command|Explain|
|-|-|
|r|Replace the current character|
|cw|Change the current word|
|cc|Change the current line|
|c$|Change the text from the current position|
|C|Same as c$|
|~|Reverses the case of a character|

</br>

|command|Explain|
|-|-|
|yy|Yank(copy) the current line
|y[position]|Yank the [position]||
|p|Paste the most recent deleted or yanked text|

</br>

|command|Explain|
|-|-|
|/[pattern]|Start a forward search|
|?[pattern]|Start a reverse search|
||n/N move|
Javascript入門

# Javascript超基礎文法
Javascriptを勉強し始めたので自分用にまとめていきます。
***

## Hello World
```javascript
cosole.log("Hello World"); // Hello World
```
- console.log
出力命令

- 文字列
文字列にはシングルクォーテーションかダブルクォーテーションをつける
数値には不要

## 変数
```Javascript
var num = 1;　// 再宣言、再代入可能
let number = 2; // 再代入可能
const name = "Taro";　// 定数

```
- 変数
let 英単語の形
数字スタート・ローマ字不可

- 変数更新
後に書かれたコードが優先される
+=や++など利用可能

```javascript
let hello = 'こんにちわ'；
let name = 'イチロー'；
console.log(hello + name); //　こんにちわイチロー
name += 'さん'; //イチローさん
console.log(`こんにちわ${name}`) //こんにちわイチローさん
```
- 文字列の結合
ドットを用いることで文字列を連結可能

- 変数展開
文字列内に変数を挿入する場合はバッククォートで囲む

## 条件分岐
```javascript
let num = 50;

if(num > 40){
 console.log('40より大きい');
}else if(num >= 30){
 console.log('30以上');
}else{
　　console.log('30より小さい');
}　//４０より大きい

 let remainder = $num % 3;

switch (remainder) {
　case 0:
　　console.log('大吉');
　　break;
        
　case 1:
　　console.log('中吉');
　　break;
      
　case 2:
　　console.log('小吉');
　　break;
        
　default:
　　console.log('凶');
　　break;
}
```
- 条件分岐 if
if（条件式） ~ elseif（条件式） ~ else　の形

- 条件分岐 switch
switch(式) ~ case ~ default　の形。
式がcaseの値に一致した時、該当のcaseが実行される。（該当なしの時はdefaultが実行）
break命令がないと後ろのcaseブロックが続けて実行される。

## 配列
```javascript
let titles = ['aaa','bbb','ccc']
titles[3] = 'ddd'; //インデックス番号が3の位置に値を追加する
titles[1] = 'eee'; //bbbがeeeに値更新
titles.push('fff'); //配列の最後尾に値を追加する

let titles = {
           'a' : 'aaa', 
           'b' : 'bbb',
           'c' : 'ccc'
          }; // キー : 値
console.log(titles['a']); // 結果:aaa
console.log(titles.a); // 結果:aaa
titles['d'] = 'ddd'; // 値の追加
```
- 配列
['aaa','bbb','ccc'] 　の形

- 連想配列
'キー' : '値'
キーによって値を呼び出せる

## 繰り返し処理
```javascript
for(let i = 1; i <= 100; i++){
 console.log(i);
}
```
- 繰り返し処理 for

1.変数の初期化 let i = 1;

2.ループの条件 i <= 100;

3.繰り返す処理 console.log(i);

4.変数の更新 i++

```javascript
let i = 1;
while(i <= 100){
 console.log(i);
 i += 1;
}
```

- 繰り返し処理 while

1.変数の初期化 let i = 1

2.ループの条件 i <= 100

3.繰り返す処理 console.log(i);

4.変数の更新 i+=1

```javascript
let names = ['Taro','Ichiro','Jiro'];
//アロー関数
names.forEach((value, index, names) => {
 console.log(value);
})
// 普通のfunction
names.forEach(function(value, index, names){
 console.log(value);
})

// ハッシュ
let names = {
 'Tanaka' : 'Taro',
 'Suzuki' : 'Ichiro',
 'Yamada' : 'Jiro'
};
Object.keys(names).forEach(function(key) { //Object.keys(names)でキーの配列を作る
  console.log(key, obj[key]);
});

```
- 配列の繰り返し処理　forEach

配列`names`の要素を順番に代入する　`(value, key, array)`　←key,array省略可

ハッシュにそのまま使ってもエラーになる


## 関数
```javascript
function hello(world){
 console.log(`hello,${world}`);
}

hello("Tokyo"); //結果：hello,Tokyo

//　アロー関数
let hello = (world) => {
    console.log(`hello,${world}`);
};
hell("Osaka"); //helll,Osaka
```
- 関数の定義
function 関数（仮引数）{処理}　　の形で定義する
アロー関数で簡潔に記述することもできる
RaspberryPi i2c 設定/有効化



RaspberryPi i2c 設定


# 便利ツール

```
# i2cdetectを使うのに必要
sudo apt install -y i2c-tools
```

# 有効化

現状確認
1なら無効 / 0なら有効
```
raspi-config nonint get_i2c
```

有効化
```

sudo raspi-config nonint do_i2c 0
# Camera 設定 有効
sudo raspi-config nonint do_camera 1

# 反映のため再起動
sudo reboot
```

# 使用アドレスの確認

```
sudo i2cdetect -y 1
```
CM4 emmc 書き込み Mac


# 参考

https://www.jeffgeerling.com/blog/2020/how-flash-raspberry-pi-os-compute-module-4-emmc-usbboot


# 手順
usbboot を使用して eMMC ストレージをマウントする
次のステップでは、Raspberry Pi usbboot リポジトリをダウンロードし、必要な USB ライブラリをコンピューターにインストールして、コンピューターにrpibootストレージをマウントするために使用する実行可能ファイルをビルドします。これはすべて、Mac のターミナル アプリケーションで行いました。

まず、libusbライブラリがインストールされていることを確認します。

私の Mac にはHomebrewがインストールされているので、以下を実行しました。
`brew install pkgconfig libusb`
Linux (別の Raspberry Pi など) では、次を実行します。
`sudo apt install libusb-1.0-0-dev`
次に、usbboot リポジトリをコンピュータにクローンします。

```
git clone --depth=1 https://github.com/raspberrypi/usbboot
```

3番目cdに、usbbootディレクトリに移動してビルドしrpibootます:

```
cd usbboot
make
```

rpibootこれで、ディレクトリに実行可能ファイルが存在するはずです。eMMC ストレージをマウントするには、次を実行します。

```
sudo ./rpiboot
```

数秒後、作業が完了すると、bootボリュームが Mac (または使用している Linux コンピューター) にマウントされていることがわかります。また、D2 LED が点灯していることに気付くかもしれません。これは、eMMC でディスクの読み取り/書き込みアクティビティがあることを意味します。

# 書き込み

RaspberryPi Imagerを使って書き込み
相手にキモチを伝えるなら「手紙」か「完全コンストラクターパターン」なんだよな

自分の気持ちを相手に伝えるのって中々に難しいのですが、人づてに伝言ゲームみたいになっちゃうともう絶望的。
途中である事ない事吹き込まれたり、真意は伝わりません。
それはデータも同じで、途中で書き換えられてしまってはいけません。
そうです。完全コンストラクターパターンを使いましょう。

```csharp
internal sealed class Kimochi
{
    public string Kisama { get; }

    public string Ore { get; }

    public string Kotoba { get; }

    public Kimochi(string kisama, string ore, string kotoba)
    {
        Kisama = kisama;
        Ore = ore;
        Kotoba = kotoba;
    }
}
```

```csharp
Kimochi kimochi = new("きみ", "ぼく", "スシです！");

// どんな処理が挿入されたって、キモチはその通りに伝わる！　

Console.WriteLine($"{kimochi.Kisama}に伝えたい{kimochi.Ore}のこのキモチ：{kimochi.Kotoba}");
// きみに伝えたいぼくのこのキモチ：スシです！
```

うん、伝えたい言葉を間違えたら目も当てられないんですけどね。

init を実装して初期化子を使う事もできますが、どうも忘れちゃう気がするんですよね。
コンストラクタで初期化するようにしておけば確実に全てのプロパティが初期化されるようにできます。
パラメーター多すぎて長くなっちゃうよ、って場合はそもそもクラスのメンバーが多すぎたりして。再考の余地あり。

ああ、気持ちのこもった手紙もらいたい。。。
リモートのWSL2へSSH接続

# 概要
リモートマシン(Windows)で稼働するWSL2へローカルマシン(Mac)からSSH接続する。

# 環境
## Machine
- Win(リモートマシン)
  - Microsoft Windows 11 Pro Build 10.0.22000
  - WSL2 - Ubuntu-20.04
  - OpenSSH_8.2p1 Ubuntu-4ubuntu0.5, OpenSSL 1.1.1f  31 Mar 2020
- Mac(ローカルマシン)
  - macOS 12.5.1 Build 21G83
  - OpenSSH_8.6p1, LibreSSL 3.3.6

## Network
Mac(192.168.10.5)からWSL2(172.28.219.185)へSSH接続したい。
```plantuml
@startuml
nwdiag {
  group {
    color = "#AAFFFF";
    
    Win;
    WSL2;
  }
    
  network home {
      address = "192.168.10.0/24"

      Mac [address = "192.168.10.5"];
      Win [address = "192.168.10.10"];
  }
  network internal {
      address = "172.28.208.0/20";

      Win [address = "172.28.208.1"];
      WSL2 [address = "172.28.219.185"];      
  }
}
@enduml
```

# 設定
## Win
### Windowsファイアウォールの設定
コマンドプロンプトを管理者として実行して、下記のコマンドを実行して、ファイアウォール規則を設定する。
```shell-session
> netsh advfirewall firewall add rule name="WSL2" dir=in action=allow protocol=TCP localport=10022
```
home LAN側から192.168.10.10:10022へ接続できるようになる。
### Windows Defenderファイアウォールの設定の確認
下記のコマンドを実行して設定を確認する。
```shell-session
> netsh advfirewall firewall show rule name="WSL2" verbose

規則名:                               WSL2
----------------------------------------------------------------------
有効:                                 はい
方向:                                 入力
プロファイル:                         ドメイン,プライベート,パブリック
グループ:
ローカル IP:                          任意
リモート IP:                          任意
プロトコル:                           TCP
ローカル ポート:                      10022
リモート ポート:                      任意
エッジ トラバーサル:                  いいえ
インターフェイスの種類:               任意
セキュリティ:                         NotRequired
規則のソース:                          ローカル設定
操作:                                 許可
```

### ポートプロキシの設定
コマンドプロンプトを管理者として実行して、下記のコマンドを実行して、ポートプロキシを設定する。
```shell-session
> $wslipaddr = wsl -e hostname -I  # WSL2側のアドレスを取得 172.28.219.185が入る 
> netsh interface portproxy add v4tov4 listenport=10022 connectaddress=$wslipaddr connectport=22
```
192.168.10.10の10022ポートに接続すると、172.28.219.185の22ポートへフォワードされる。
#### 補足
WSL2で複数のネットワークインタフェースを構成していると、`hostname -I`コマンドの実行結果として複数のIPアドレスが返ってくる場合がある。その場合は、WSL2内で`ip addr show`などを実行してWSL2側のアドレスを確認して、`netsh`コマンドの`connectaddress`引数にアドレスを指定する必要がある。

### ポートプロキシの設定の確認
下記のコマンドを実行して設定を確認する。
```shell-session
> netsh interface portproxy show all

ipv4 をリッスンする:         ipv4 に接続する:
Address         Port        Address         Port
--------------- ----------  --------------- ----------
*               10022       172.28.219.185  22
```

## Mac
fooは接続先(WSL2)のユーザ
```config:~/.ssh/config
Host wsl2
     Hostname 192.168.10.10
     User foo
     Port 10022
```

## WSL2
前提：sshdが起動している

# 接続
Macから```ssh wsl2```を実行して、WSL2へ接続する。

# 残件
WSL2のIPアドレスは起動ごとに変わるので、上記の設定方法だと、netshでポートプロキシを設定し直す必要がある。自動設定のスクリプトなどで対応したい。

# 参考情報
https://docs.microsoft.com/ja-jp/windows/wsl/networking#accessing-a-wsl-2-distribution-from-your-local-area-network-lan

https://docs.microsoft.com/ja-jp/troubleshoot/windows-server/networking/netsh-advfirewall-firewall-control-firewall-behavior

https://docs.microsoft.com/ja-jp/windows-server/networking/technologies/netsh/netsh-interface-portproxy
Flutterで半透明のBottomSheetを実装

## Flutterで半透明BottomSheetを実装しよう！

背景を透かしたBottomSheetを実装しようと思いましたが、なかなか情報がない中実装してみたので備忘録として記録します。

いい感じに使えたら少しおしゃれなボトムシートが実装できるかも？しれないので参考になれば幸いです。

### 完成コード
https://github.com/kurogoma-flutter/transparent_bottom_sheet

### コード（主要部分）
まずは、ボトムシートを出し入れするクラスの作成です
```dart
class AppRouter {
  static final AppRouter _singleton = AppRouter._internal();
  factory AppRouter() {
    return _singleton;
  }
  AppRouter._internal();

  Future<dynamic> showCustomBottomSheet(BuildContext context, Widget body) {
    return showModalBottomSheet(
      backgroundColor: Colors.transparent,
      context: context,
      isScrollControlled: true,
      builder: (context) {
        return CustomBottomSheet( // <= 後述で説明します
          body: body,
        );
      },
    );
  }
}

```
#### 使い方
```dart
AppRouter().showCustomBottomSheet(
    context,
    Container( // <= シート本体に入れたいウィジェット
      ...
    ),
);
```

次に、ボトムシートのウィジェット部分についてです。
デフォルトのウィジェットではなく
```dart
/// ボトムシートの土台となるウィジェット
class CustomBottomSheet extends StatelessWidget {
  const CustomBottomSheet({
    super.key,
    required this.body,
  });

  final Widget body;

  static const cornerRadius = 20.0;
  static Color maskColor = Colors.black45.withOpacity(0.5); // 透過した背景
  static ImageFilter filter = ImageFilter.blur(sigmaX: 20, sigmaY: 20); // 背景ぼかし

  @override
  Widget build(BuildContext context) {
    // 
    return ClipRRect(
      borderRadius: const BorderRadius.vertical(
        top: Radius.circular(cornerRadius),
      ),
      child: Container(
        padding: const EdgeInsets.only(top: 5.0),
        decoration: BoxDecoration(
          color: maskColor,
          borderRadius: const BorderRadius.vertical(
            top: Radius.circular(cornerRadius),
          ),
        ),
        child: Stack(
          children: [
            // シート上部のインディケーター
            const Positioned.fill(
              child: Align(
                alignment: Alignment.topCenter,
                child: _DragIndicator(),
              ),
            ),
            body,
          ],
        ),
      ),
    );
  }
}

/// シート上部に設置したドラッグインジケーター
class _DragIndicator extends StatelessWidget {
  const _DragIndicator({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 35,
      height: 4,
      decoration: BoxDecoration(
        color: Colors.white54,
        borderRadius: BorderRadius.circular(2),
      ),
    );
  }
}
```

### 実装後イメージ
Githubのコードを実行していただくと以下のようにサンプルが閲覧できます。

![sample_capture.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/735195/4a0f4971-7f71-dbea-186d-6d905e77eefb.gif)


以上です！
【Slack】Bot User OAuth Tokenの取得方法

# 目的
GAS（Google App Script）でSlack APIを利用するにはSlackアプリAPIの  Token　が必要です。
Tokenを発行する手順を案内します。


## Slackアプリの作成
1．Slackにログインする
https://slack.com/intl/ja-jp/get-started#/createnew
![slack0サインインする.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640876/9d0f75cf-e291-de6d-e207-5e3cd8066250.png)



2．Slack APIのページにアクセスします。
https://api.Slack.com/apps
![SlackアプリのAPI利用手順１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640876/61c2794d-1a47-d97d-1ec7-bc11f8642b1c.png)


3．右上の、「Create an App」    をクリックします。
※すでに作成済みの場合は、右上に表示される「Create New App」をクリックします)
![SlackアプリのAPI利用手順3 .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640876/7d8113d4-2640-f022-0926-d02b1151813a.png)


4．[From scratch]をクリックします。
![SlackアプリのAPI利用手順3-2 .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640876/2aa9671d-ff12-97be-6368-e806e3030b76.png)




5.「アプリ名　(App Name)」を入力し「利用するSlack
    ワークスペース名(Development Slack Workspace)」を選択し、「Create App」ボタンをクリックします。
    アプリ名(App Name)：何でもよい
    ワークスペース名(Development Slack Workspace)：ワークスペース名　

![slack１－2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640876/36d14d2c-405c-e024-0f45-86f04d2c6bcc.png)




# Slack APIのスコープ＆パーミッション設定
Slackアプリの操作ができる権限を追加します。
操作する内容によって権限が変わります。


1．SlackアプリのSettingメニューにある「OAuth & Permissons」を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640876/080508e9-86a3-8fea-96c3-98694f7373fe.png)


2．[Scopes]メニュー配下の[User Tocken Scopes] から「Add an OAuth Scope」ボタンをクリックします。
    Slackボットで必要なとなる権限を追加します
![oauth-scope0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640876/0649d108-c771-6c9e-b53e-b87a8804ea9a.png)
![oauth-scope2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640876/627cdf87-1f33-35f9-f435-6d7d323bba9c.png)

今回追加する権限
「channels:write」
「files:read」
「groups:history」
「groups:read」
「groups:write」
「im:history」
「im:read」
「im:write」
「mpim:history」
「mpim:read」
「mpim:write」
「usergroups:read」
「channels:read」
「channels:history」
「users:read」
　


# Slack APIのUSER用トークンを発行
※すべて「OAuth & Permissons」での作業

1．画面を上にスクロールし「Install to Workspace」をクリックする
![slack4-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640876/029363f8-b644-d82a-f0ad-67b999b00936.png)


2．認証画面が表示されるので「許可する」をクリックする
![slackapp9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640876/79627933-5e3d-e215-ab8c-d07ff74b1227.png)


3．User OAuth Token に表示されたトークンをコピーする
![token.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640876/e939a023-b3c0-6dd2-d8a3-80ec088df12e.png)
int を符号付き文字列で表示したいけど書式指定覚えられないから拡張メソッドにしておくか

# やりたいこと
int の数値を表示するときに正の数にはプラス、負の数にはマイナス、ゼロにはプラスをつけたい。

# カスタム数値形式文字列
`int.ToString()` で書式指定すればできそう。

こんな感じに書いてみる。
```csharp
string plus = 1000.ToString("+#;-#;+0");
Console.WriteLine(plus); // +1000

string minus = (-1000).ToString("+#;-#;+0");
Console.WriteLine(minus); // -1000

string zero = 0.ToString("+#;-#;+0");
Console.WriteLine(zero); // +0
```
セミコロンで書式指定を区切ることで、前から順番に正の数・負の数・ゼロの場合に適用される。

### 参考

https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/formatting-types

https://ninagreen.hatenablog.com/entry/2015/10/29/025644

# う～ん、覚えられない笑
なので、拡張メソッドで定義してしまおう。
```csharp
public static class IntExtensions
{
    public static string ToSignedString(this int src)
    {
        return src.ToString("+#;-#;+0");
    }
}
```

あれ、ゼロにプラスって変かな。。。
IAPを有効にしたCloudRunにアクセスする

# はじめに

CloudRunで構えるAPIのセキュリティを強固にするために
何が出来るか考えて、その一環でやってみました。

## 補足
PublicPreviewの機能になるため、GA後には最新情報をご確認ください。

# IAPによるWebアクセス制御とは

GoogleCloudの機能でGoogleのIAMを利用した認証が実装できる機能です。
https://cloud.google.com/blog/ja/products/gcp/control-access-your-web-sites-identity-aware-proxy

# 実施する

## CloudRun
対象のサービスを選択して、以下2点設定する。
- 内部トラフィックとCLBからのトラフィックを許可する
- トリガーの認証にて「認証が必要」を選択する
![スクリーンショット 2022-09-08 21.55.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1720034/82efda3e-d0f5-78a6-2dc1-fefd02397f11.png)

## CloudLoadBalancing
HTTPSの口を用意する
![スクリーンショット 2022-09-08 21.56.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1720034/1f774382-49b3-a619-4a3b-9c7aff135b8e.png)


## IAPを有効化する
IAPの画面から対象のリソースで有効化します。
対象リソース(LB)配下のバックエンド側でIAPを受け入れる準備ができていない場合、
先にIAPを有効化しても、しばらく、想定動作にならないため、先にバックエンド側を整わせたほうがスムースです。
![スクリーンショット 2022-09-08 21.56.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1720034/e83db4e5-b515-c6ac-83d7-621056eb5e29.png)

### 注意事項
OAuthの同意が終わっていない場合、同意しておく必要があります。
https://cloud.google.com/iap/docs/enabling-compute-howto?hl=ja#oauth-configure

## 認証で利用するIAMに権限をつける
IAMの画面から認証で利用したい対象IAMで「IAP で保護されたウェブアプリ ユーザー」の権限をつける

# 結果確認
対象URLにアクセスすると認証がでてくるようになる。
![スクリーンショット 2022-09-08 21.56.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1720034/a10a6c94-daa6-af52-1189-55b952acef63.png)


記事のお陰もあり、簡単にできました。


# 所感
認証って苦手意識を持っていましたが、IAPが優秀で認証の仕組みを簡単に準備できました。
色々と機能があると思うので、よくある他のIAPも試してみようかなと思いました。

# 手順参考
https://zenn.dev/ww24/articles/19099c85febe0d
初等技術者のための応用数学 ＜エンジニア夏休み企画>【読書感想文】

＜エンジニア夏休み企画>【読書感想文】
https://qiita.com/official-events/6d31965c499a69377c0b

参加記事です。　

# 初等技術者のための応用数学
初等技術者のための応用数学 上・下
https://www.amazon.co.jp/dp/product/4339060615/
https://www.amazon.co.jp/dp/B000JA2BYE/
https://booklog.jp/item/1/4339060615
https://booklog.jp/item/1/B000JA2BYE
https://bookmeter.com/books/725865

>工業大学の３年に編入した際に、自習と補習を薦めらました。上下の２分冊でした。３ヶ月くらいでなんとか上下とも問題を解きました。電気基礎講座と合わせて演習しました。電気回路の問題も解けるようになりました。ありがとうございました。

https://bookmeter.com/books/999400

>#感想歌　数学は物理・工学勉強の道具だ実験して確かめて　プログラム組んで計算してみれば数学・計算機は道具だと 工学部電気工学科の３年に編入した際に、補習と自習を薦めらました。上下の２分冊でした。 ３ヶ月くらいでなんとか上下をやり、松下の電気基礎講座をやったら、電気回路の問題が解けるようになりました。 ありがとうございました。

補講を担当してくださった佐治教授に感謝します。

## ラプラス変換　
人生で影響を受けた本100冊。
https://qiita.com/kaizen_nagoya/items/16af53acbb147a94172e

### 69. 詳解LAPLACE変換演習
>学校で教材の提示の順番が、疑問に思うことがある。
回路や制御に興味を持った人間なら、回路や制御に使うLaplace変換を具体的に解くのは、それなりに楽しい。
微分や積分をやる前に、物理現象の描写や、物理的な制御の考え方を示してもらえれば、もっと真剣に勉強したかもしれないと悔やんでいる。
興味を持ったことに使う技術は、それほど苦もなく勉強できる。
ただし、P2の式（１．６）推移定理のようなものは、その意味を説明してもらえる人がいると嬉しい。
工業数学については、佐治先生に補講をしてもらったので、なんとかついていけたと思う。

## 電磁気学　
### 67. 詳解電磁気学演習
>演習問題を解いていって、全部正解してしまうような天才はおいておいて、一般人は、演習問題を沢山やってみて、間違える問題の傾向を知ることが大切です。９９％正解する人でも、１％の間違いの傾向を掴むことができれば万々歳です。
一生の間で、その間違いの傾向を知っていることで、自分または他人を救うことができるかもしれません。
学生の間は演習問題を沢山解くか、実験をたくさんするかのどちらかだと思います。
私は実験が苦手だったので、演習問題を沢山解きました。
名工大の松井信行先生が、大学でないと電磁気の勉強をする余裕はないので、大学生の間に電磁気はちゃんと勉強しておくようにと言われました。
そのおかげで、大学を出てから、無線技術士の試験の際に、最大限役に立ちました。

そして、卒業研究の連立微分方程式のPade近似にいたるまで、自分の研究室の岩住教授の出身大学の京都大学の学生の中央値以上の勉強量はこなしたと思う。　

### 68. プログラム学習による基礎電気工学 直流編
>電気工学科の３年に編入する際に、このシリーズと工業数学の本を読むように薦められました。
当時は、オームの法則も記憶していないほど、電気工学の知識が抜けていました。
半年くらいで、電気基礎講座を読んで、残りの半年で制御基礎講座を勉強しました。
無事、規定の年数で卒業できたのは、この講座のシリーズと工業数学の本のおかげだと思っています。
電気科を卒業していない人が、電気の勉強を始めるのには最適の本だと思っています。
松下からソフトウェアのプログラムの基礎講座がでるのを期待しています。

### 70. アンテナ・電波伝搬
>東北大学の八木門下の著作。
アンテナに関して体系的に学ぶことができる。
電磁気学の英文の書籍が適切に引用してあり、amazon.comで参照できる。
個々のアンテナについても詳細に説明がある。
WEBにも貴重な情報がある。
自分では、ホーンアンテナは電気科の学生実験で測定したことがあります。
パラボラアンテナは無線技術士の試験ででることを予測し、 マクスウェルの方程式から導出する訓練をしました。
無線技術士の試験の９ヶ月前から勉強しはじめた記録が残っています。
出てきた式で、わからないところがありました。ちょうどマスプロ電工の方がおみえだったので、お聞きしたら間違いで訂正式を教えてくださいました。出版社にも連絡しました。

Qiita(0)Qiita関連記事一覧（自分）
https://qiita.com/kaizen_nagoya/items/58db5fbf036b28e9dfa6

プログラマが知っていると良い「公序良俗」
https://qiita.com/kaizen_nagoya/items/9fe7c0dfac2fbd77a945

一覧の一覧( The directory of directories of mine.) Qiita(100)
https://qiita.com/kaizen_nagoya/items/7eb0e006543886138f39

＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently belong.
# 文書履歴(document history)
ver. 0.01 URL変更。20220928
ver. 0.01 ありがとう追記。20230525
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
pdfに海苔貼りたくなった(Vue 3 + TypeScript + Vite)



# PDFに海苔貼りたくなる時あるよねぇ

というわけで作ってみました

pdfファイルを選択して

![スクリーンショット 2022-09-08 20.53.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329559/f151d350-3569-20ba-5ddc-e678b0e898bb.png)

PDFが表示されて

![スクリーンショット 2022-09-08 20.53.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329559/18a77aec-6d33-cef3-f47b-4b5c4942edb0.png)

ドラッグで海苔を貼っていくぅ

![スクリーンショット 2022-09-08 20.54.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329559/091934b1-018c-003a-a7b4-799cd614591b.png)

「to png」を押してpngに変換するぅ

![スクリーンショット 2022-09-08 20.54.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329559/50d98e35-f1dd-0030-1fca-26e077200d3a.png)

あとはDLでもしてもらえれば・・・

# ソースとサイト

https://github.com/babu-ch/noriben

https://babu-ch.github.io/noriben/


# 解説

環境はVue 3 + TypeScript + Vite

pdfjsでcanvasに出力したpdfにお絵描きしています

バグはあるかもしれません

## つまった所と解決策

### 毎フレームawait page.renderしてチラついた

render後の画像を持っておく

### canvasを画像化する時にクリックイベントでやると不完全な画像になる

画像化用の変数を用意してcanvasの描画処理の最後で出力する

### pdfの日本語が表示されない時がある

cmapsを指定する

### 本番でcmap読めない

cmapsをコピる


# おわり

JSのセミコロン省略したいけどつい書いちゃいますね

Vue3のsetupいいですねぇ
【 Azure App Service 】デプロイを GitHub Actions で行う方法

Azure Web App へのデプロイ方法はいくつか種類があるんですが、
本記事では GitHub Actions を使った方法について設定手順をまとめておきます。

# 前提条件
- Azure App Service プラン と Web App をデプロイ済みであること
- アプリケーションのコードを GitHub で管理していること
( 当該リポジトリで Owner 権限を持っていること )

# Azure Portal からデプロイ方法を選択する
まず、Azure Portal からデプロイ対象の Azure Web App リソースを開きます。

<img width="796.8" alt="image.png (238.5 kB)" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/8c25fd8a-2650-8aaf-fe4b-ec30d2b52691.png">

設定タブ > ソース から **GitHub** を選択します。

<img width="466" alt="image.png (41.3 kB)" src="https://img.esa.io/uploads/production/attachments/3505/2022/09/08/10862/a2216d66-864e-4f41-91ca-268afbfa13db.png">

GitHub を選択すると、以下の画面が表示されます。
(※初回選択時は、GitHub のサインインが必要になります。)

| プロパティ | 説明 |
| --- | --- |
| 組織 | リポジトリを管理する組織 (個人/会社) |
| リポジトリ | ソースコードを管理するリポジトリ |
| ブランチ | ビルド&デプロイのトリガーとなるブランチ |

<img width="588.5" alt="image.png (137.5 kB)" src="https://img.esa.io/uploads/production/attachments/3505/2022/09/08/10862/618f6913-f258-4242-82e4-d59845d9e0bb.png">

入力完了後、ページ上部の **保存** ボタンを押すと、
``プロジェクトルート/.github/workflows/ブランチ名_WebApp名.yaml``
ファイルが生成されます。

```yml
# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
# More GitHub Actions for Azure: https://github.com/Azure/actions

name: Build and deploy Node.js app to Azure Web App

on:
  push:
    branches:
      - dev
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2

      - name: Set up Node.js version
        uses: actions/setup-node@v1
        with:
          node-version: '16.x'

      - name: npm install, build, and test
        run: |
          npm install
          npm run build --if-present
          npm run test --if-present

      - name: Upload artifact for deployment job
        uses: actions/upload-artifact@v2
        with:
          name: node-app
          path: .

  deploy:
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: 'Production'
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}

    steps:
      - name: Download artifact from build job
        uses: actions/download-artifact@v2
        with:
          name: node-app

      - name: 'Deploy to Azure Web App'
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v2
        with:
          app-name: '<AppServiceName>'
          slot-name: 'Production'
          publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_xxxx }}
          package: .
```

``dev`` ブランチ に新しい変更が Commit されると、GitHub Actions ワークフローが自動的に開始され、ビルド & デプロイ が実行されます。ワークフローの実行有無/ステータスは、**GitHub の Actions タブ** もしくは、**Azure Portal のデプロイセンター** より確認することができます。

<img width="940.8" alt="image.png (309.3 kB)" src="https://img.esa.io/uploads/production/attachments/3505/2022/09/08/10862/ca487d43-9e50-4f70-9f5d-fe20d6d691d5.png">

# Refs
- [GitHub Actions を使用した App Service へのデプロイ](https://docs.microsoft.com/ja-jp/azure/app-service/deploy-github-actions?tabs=applevel)
[資格]AWS CLF メモ

# 概要
AWS CLFの勉強用メモとして、暗記していきたい内容を箇条書きですがメモしていきます。

# 記録
- フォールトトレラント設計
    システム設計の手法の一つ。
    システムの一部ノードに障害が発生しても、全体が停止することなく動作し続ける設計。
    AWSでは、アベイラビリティゾーンをバラすことで可用性を上げている。

- コスト周りについて
    - AWS Cost Explorer
        過去の請求情報をグラフィカルに表示する機能。
        過去 12 か月までのデータを表示し、今後 12 か月間にどれくらい費やす可能性が高いかを予測し、リザーブドインスタンスを購入するための推奨事項を得ることができる。
    - AWS Budgets
        カスタム予算を設定し、設定値を超える又は超えそうな場合にアラートを発報する機能。
        月ごと、四半期ごと、年単位で追跡可能。

    - 監視周り
        - AWS CloudTrail
            AWSアカウントのガバナンス、コンプライアンス、運用監査、リスク監査を行うサービス。
            AWSインフラストラクチャ全体でアカウントアクティビティをログに記録し、継続的に監視、保持できる。
        - AWS CloudWatch
            AWSリソースと実行されているアプリケーションをモニタリングする機能。

- S3 バケット命名規則
        世界中全てのリージョンで一意、3~63文字以内に設定する必要がある。

- Amazon Simple Queue Service (SQS) 
    https://aws.amazon.com/jp/sqs/

- Amazon Simple Notification Service (SNS) 
   https://aws.amazon.com/jp/sns/?whats-new-cards.sort-by=item.additionalFields.postDateTime&whats-new-cards.sort-order=desc

- Amazon Simple Email Service (Amazon SES) 
    https://aws.amazon.com/jp/ses/

- AWS Data Pipeline
    https://aws.amazon.com/jp/datapipeline/
Treasure2022参加記

# はじめに

久しぶりの投稿です。
8月の3週間を使ってCARTA HOLDINGS（旧Voyage Group）のサマーインターン「Treasure」に参加してきたので、今回はその中で開発したサービスの内容などを振り返っていこうと思います。

実はここに書いてある以上に難所がたくさんあったのですがその辺はその部分の実装を担当した他のチームメンバーが参加記を書いてくれる...はず！

# 前提

- 開発期間は設計含め6日半（1日に使えるのは8時間。うち1時間は休憩）
- 使用技術は自由。AWSリソースも常識的な範囲で制限なく使える。
- 価値を創るプロダクトを作ること
- 社員サポーターの皆様が手厚くサポートに入ってくださる（基本的に「分からない」は言えば迅速かつ丁寧に拾ってもらえます。）

人事のさとみんさんが書かれた[こちらの記事](https://techblog.cartaholdings.co.jp/entry/treasure2022-planning)だとイメージが掴みやすいと思います

# どんなサービス作ったの？

短時間の筋トレをしたい人をリアルタイムでマッチングさせるサービスです。筋トレするマッチョとマッチングを合わせてサービスはMatchong（マッチョング）と名付けられました。やりたい筋トレメニューを選ぶと、同じメニューを選んでいるユーザーとマッチングしGoogle Meetのような部屋で筋トレを行うことができます。発表に使ったデモを含んだ資料を添付しておきます。

[発表資料のGoogle Slide](https://docs.google.com/presentation/d/1jDio8GgOExHaZjJBW_g2_zCIrUYTqGIDUUmhM401g3s/edit?usp=sharing)

# マッチング(Redis/Go)

MatchongはApexやSplatoonと同じ感覚で、同じメニューを選んでいる人同士をリアルタイムマッチングさせます。

チームで共有された[この記事](https://zenn.dev/yokojp/articles/f5080e3d4e94d9)を参考にとりあえずマッチング処理ならキューやろってことでRedisをキューに使って、様々な社員サポーターさんのFBも頂きつつ色々とチームで話し合いこんな感じの構成になりました。

![スクリーンショット 2022-09-06 9.10.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/893208/5aa67c1b-c385-b794-644c-5c6ca9d7a666.png)

処理の流れとしては
1. ユーザー(図右下)が筋トレメニューを指定してマッチングリクエストをアプリケーションマイクロサービス(AP)へ送信。同時にクライアントとAPとのWebsocketを開通する。
2. APはマッチングリクエストを送ってきたユーザの情報をキューに格納。キューにはマッチング待ちのユーザーが筋トレメニューごとに溜まっていく。
3. マッチングマイクロサービス(正確にはGo Routine)がキューをポーリングして、人数が集まったらマッチング情報をPostgreSQLに書き込む
4. マッチングしたらそのことをWebsocket経由でクライアントに通知し、Skywayでビデオ通話を開始する。

という感じです。(だいぶ端折ってます)

私は主に３のポーリングの実装、ElasticacheでRedisをセットアップするところやUIのスタイリングなどをメンバーと担当したのですがGoやElasticacheを本格的に触るのは初めてだったので非常に刺激的で面白い体験でした。

欲を言えばWebsocketも初体験だったので実装にもっと絡みたかったのですが実装日程は3日半だったので流石にそんな時間はありませんでした笑
これについては事後面談でも考えましたが実際の開発であれば自分の手元でPRをチェックアウトしてコードや動作を眺めてみるといった動きが癖になると今後はもっと良いなあと思っています。

# おわりに

スケジュール全体の流れとしては3週間のうち初めの1週間は講義や自習、次の1週間でプロダクト作りに向けたアイディア出しやその発表を行い、最後の1週間で開発を行って最終成果物を発表するという感じです。

そして3週間を終えてみるとTreasure2022は本当にあっという間で、チーム開発的にも技術的にも多すぎるほどの学びがありました。その中でも個人的に一番印象に残っているのは@t_wadaさんのDBモデリング講義で、著書である「SQLアンチパターン」を愛読していた私は改めてDB設計の奥深さや難しさを知ることになりました。

そしてTreasure応募から半年以上お世話になった人事の方々、全力でTreasure生をサポートしてくださった社員サポーターの皆様には本当に感謝してもしきれません。チームメンバーにも本当に恵まれて楽しく充実した3週間でした。合わせてチームメンバーにも感謝です。

もしこの記事を読んでいる学生で2023以降への参加を検討しているならば、ぜひ応募することをおすすめします。2022では2月には募集が始まっていたのでお早めに。
WEBスクレイピングを勉強してみた

WEBスクレイピングの勉強を久々に再開。




# 目次
[1.HTTPリクエストとは](#1-HTTPリクエストとは)
[2.User-Agentとは](#2-User-Agentとは)


# 1.HTTPリクエストとは

そもそもHTTPリクエストって何かわからなかったのでこちらのサイトを参考にしました。

https://wa3.i-3-i.info/word1452.html

簡単にいうとWEBブラウザからWEBサーバーに情報をリクエストするときのやりとりを『HTTP』といい、リクエストを送ることを『HTTPリクエスト』と呼ぶようです。
そしてそのHTTPリクエストの構成が、

リクエストライン→ヘッダー→メッセージボディ

という三層構造になっていて、その『ヘッダー』の中に含まれているのが

User-Agentになっています。

# 2.User-Agentとは
では『User-Agent』とは何者なのでしょうか？
User-AgentとはWEBブラウザにこの機械からアクセスしていますよーという情報です。
iPhoneでアクセスしてるよーとかMacbookでアクセスしてるよーとかそういった情報を文字化（？）したものっぽいです。


# 3.Requests
HTTP通信用のPythonのライブラリでHTMLファイルやXMLファイルなどからデータを取得する際に必要です。
Macにpyenv/Python3/pipのインストール

# はじめに
python3と関連モジュールをインストールするためのメモです。
まずタイトルのpyenv/Python3/pipを説明します。

## pyenvとは
Pythonのバージョンを管理するモジュールです。
これを使ってpythonをインストールします。

## pythonとは
Pythonはプログラミング言語の一つです。
機械学習や人工知能などのライブラリも豊富です。

## pipとは
Pythonのパッケージを管理するモジュールです。
Pythonと一緒によくインストールされます。

# 実行環境
macOS Monterey 12.3
Homebrew 3.5.10

# pyenvのインストール
まずはpyenvがインストールされているかの確認
```
$ pyenv -v
zsh: command not found: pyenv
```

ないのでbrewコマンドでインストール
brewコマンドのインストールは[こちら](https://qiita.com/ukei2021/items/51cdc9fbd53428708fea)
```
$ brew install pyenv
```

インストールされたかの確認
```
$ pyenv -v
pyenv 2.3.4
```
環境変数への追記
bashならbashrcへ追記、zshならzshrcへ追記します
（下の5行を全てコピーして貼り付けてください）
```
$ cat <<'EOD' >> ~/.$(basename $SHELL)rc
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
EOD
```
即時反映させます。
```
$ source ~/.zshrc
```

# Pythonのインストール

以下のコマンドでインストールできるPythonのバージョンを確認します。
```
$ pyenv install --list | grep '^\s\s[0-9]\+\.[0-9]\+\.[0-9]\+$'
  2.1.3
  2.2.3
  2.3.7
~~~~~~　中略 ~~~~~~
  3.10.4
  3.10.5
  3.10.6
```
特にバージョンの指定がないのであれば、一番下に表示されたものが最新っぽので、その数字を覚えておいてください。
ここでいうと3.10.6
覚えた数字のバージョンをインストールするコマンドは以下
```
$ pyenv install 3.10.6
```
インストール後、内在しているPythonを確認します。
```
$ pyenv versions
* system (set by /Users/macbookpro/.pyenv/version)
  3.10.6 
```
元から入っているPythonに向いているので、3.10.6に変更します。
以下のコマンドで3.10.6を使用できるようになります。
```
$ pyenv global 3.10.6
```
確認
```
$ pyenv versions
  system
* 3.10.6 (set by /Users/macbookpro/.pyenv/version)
```
3.10.6に*が付きましたね。

# pipインストール
まずpipダウンロード用のファイルをダウンロードします。
```
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
```
pythonで実行
```
$ python get-pip.py
```
ダウンロードしたファイルを削除
```
$ rm -f get-pip.py
```

これでpyenv/Python3/pipをMacにインストールできました！
以上！

# 参考文献
[Pythonの開発環境を用意しよう！（Mac）](https://prog-8.com/docs/python-env)
[【Python】macOSでpipを使えるようにする](https://qiita.com/ohbashunsuke/items/e7c673db606a6dced8a6)
【PHP基礎復習15】文字列の連結

［問題］
次の入力された2つの数字を「/」で区切って出力させなさい。

# コード
```PHP
$input1 = fgets(STDIN);
$input2 = fgets(STDIN);
echo trim($input1). "/" .$input2;
```

↓　11、12と入力

# 結果
```
11/12
```

☆trim()
→　文字列の先頭、末尾にある空白スペースを取り除く

☆'文字列A'.'文字列B'
→　「.」で文字列を連結させることができる
Macにhomebrewをインストール/アップグレード

homebrewをインストールしていきます。

# homebrewとは
「パッケージ管理ツール」らしいです。

パッケージ管理ツールとは
私の認識ではパッケージの依存関係を考慮しつつ、インストールやアンインストールなどができるもの

Redhut系でいうyum、Debian系でいうapt-get的なやつかと。

# homebrewの読み方
「ホームブルー」らしい。
「ホームブリュウ」って言ってました。

# なぜインストールするのか
Macに何かインストールするにあたって調べるときに、homebrewベースでのインストール手順が多いので。。。
入れとおかないとインストールもさせてくれない時があるので、入れるっきゃない！

# なぜ今なのか
自分自身はインストールしてたんですが、最近Mac初心者と一緒に作業することがあり、
改めてインストール方法の確認とその作業したメモを残すためです。
これからはこの記事見ながらインストールしてねって感じが良くて。。。

# なぜ
もうええわ！

# インストール手順
[homebrew](https://brew.sh/index_ja)にインストール手順が書いてあります。
![picture001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032988/bdfada36-6651-367b-55b3-bfe5c0f3707d.png)


赤枠のコマンドをターミナルで実行します。
小さいので下記に記載しておきます。
```
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
ターミナルの開き方は[こちら](https://qiita.com/ukei2021/items/af3b49a4dcae4840b760)


インストールが終わったら、brewコマンドが使えるかどうかバージョン確認してみましょう。
```
$ brew -v
Homebrew 3.5.10
Homebrew/homebrew-core (git revision b0dd4e755f7; last commit 2022-09-04)
```

こんな感じで表示できれば完成です。

# アップデート手順
バージョンを最新にしたい場合はこちらのコマンドでできます。
```
$ brew upgrade
```

以上！

# 参考文献
[homebrew](https://brew.sh/index_ja)
[Homebrew - Homebrew自身をアップデートする](https://zenn.dev/sawao/articles/e7e90d43f2c7f9)
[【完全版】Homebrewとはなんぞや](https://www.curict.com/item/bc/bcc0607.html)
Macでターミナルの開き方

ターミナルの開き方手順を紹介

# ターミナルとは
コマンドを使用し、Macを操作するものです。
Macに何かインストールしたり、操作するときの手順がターミナルを使う前提で書かれていることもあるので、開き方だけでも覚えておきましょう。

# ターミナルの開き方
Launchpadの
![picture002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032988/046c644d-708e-dad1-6517-89909e249be5.png)


その他の
![picture003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032988/f2182246-29d4-1248-a3c1-aa5b45eb6f9c.png)

ターミナルをクリック
![picture004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032988/785ed757-800f-61ec-c73b-6ecf02c6dfed.png)

そしたらこんな感じなものが開きます。
（設定によっては背景が白かったり違う色だったりもします。）
![picture005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032988/681f4ec4-e190-e51b-9a2e-ebd58b4bb9ac.png)

これがターミナルです。

以上！
ゲーム分析：SoulKnight

# どんなゲームか
ジャンル：ローグライクシューティングアドベンチャー
ダンジョンを攻略しながら現れた敵をシューティングで倒し、15階の先にあるゴールを目指すゲーム。ダンジョンを探索するローグライクアドベンチャーと、シューティングゲームがとても良い具合に噛み合っています。また、キャラクターの選択、バフの選択、武器の選択とシンプルながら戦略性の高いゲームです。
海外ゲームのためか、難易度は少々高めです。
また、協力プレイにも対応しており4人プレーにも対応しています。

# 動画
https://www.youtube.com/watch?v=wlwhoqT3NZA

# 操作方法
移動：画面左側でドラッグ操作
発射・スキル発動：画面右側をタップ（長押しで連写可能）

# ゲームの性質

## おもしろいの細分化
### はじめ
- プレイモード（協力・ソロプレイ）を選択
- スキルを選択
- 探索へ出発する

### 終わり
勝利条件：15あるステージ（5階ごとにラスボス）をクリアし、最上階に到達する
敗北条件：HPが0になる

### テーマ
ローグライク×アクション×シューティング

### コンセプト
 - キャラクターとジョブに種類を持たせ、アクションゲームの醍醐味であるキャラごとの立ち回りの違いや戦略の違いを生み出す
 - 道中ドロップする武器の種類の大半が銃など長射程系武器であり、弾幕を張って戦うシューティングの良さを取り入れている。また、近接型武器も数多く実装されており、よりアクションゲームのような動きも可能である。
 - 弾幕を避けながら隙をついて敵を撃つというシューティングゲームの良さはそのまま取り入れられている。

### システム
攻略性：ランダム生成されるダンジョンの中、キャラ、スキル、武器等の選択の余地が広く、その組み合わせによる攻略性がとても高い。特に他のシューティング・ローグライクゲームと違い、全キャラが全ての武器を装備可能、かつ２つまで武器を装備できるため、「攻撃系武器とバリア系武器」「近距離系武器と遠距離系武器」等様々な組み合わせを想定することが可能である。

成長性：攻略中にドロップするコインを用いてキャラクター自身、施設の強化が可能である。難易度の高いゲームであるため、繰り返しダンジョンに挑み、強化し、どんどん奥へ進めるようになることに面白さがある。

操作性：操作は『左手：移動、右手：発射・スキル』のみでありとてもシンプルにまとまっている。また、UIカスタマイズが素晴らしく、全てのボタンを好きな場所に設置可能であり、左利きの方にも優しい設計となっている。

競争性：本ゲームは競争性が少なく、他プレイヤーとの競争要素もない。しかしクリアタイムが表示されるため、タイムアタックが盛んである。

## サイクル
### 小さいサイクル
![１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2840730/4f4bcaa8-1c00-5ad7-f26a-11cee1786dec.png)

### 派生したサイクル
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2840730/de7b6de8-aa82-f7bf-dfbe-ddcf755ee4ea.png)

### 最後にできる大きなサイクル
![３.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2840730/97a47c26-4613-ce2e-6d38-2e6ccc7d3dfe.png)

# ダウンロードURL
ios:
https://apps.apple.com/jp/app/soul-knight/id1184159988

android:
https://play.google.com/store/apps/details?id=com.ChillyRoom.DungeonShooter&hl=ja&gl=US


# 感想
シューティング・アクションという要素が入っていながら、ゲーム自体はものすごくシンプルで、かなり好きなゲームです。日本語翻訳もされているのに、日本語の攻略情報が少なくて勿体無い！って思っています。私が書くかぁ。。。（
2018-2019年ごろに一番流行っていた気がします。高校の友人とよく遊んでいました。
現在ではアップデートが繰り返されて、チャレンジコンテンツも増えたのでローグライクを遊びたい方はぜひ！
vue.jsの@イベントハンドラが動かなかった原因メモ

# 目次
1. [前提条件](#Chapter1)
1. [問題](#Chapter2)
1. [原因](#Chapter3)
1. [解決方法](#Chapter4)
1. [参考文献](#reference)

<a id="#Chapter1"></a>
# 前提条件
・lineリッチメニューから遷移するページをvue.js（.vueファイル）で作成
・デバッグはスマホからしかできない（時間がなかったため仕方なく）
・docker環境

<a id="#Chapter2"></a>
# 問題
・vue.js機能のv:on=clickなどのイベントハンドラが動かない
（javascript純正のイベントハンドラ（onclick=）はなぜか動く）
（.vueファイル自体の表示とdataの値、v-modelは正常に反映されている）

packageが原因かと思い、packageをインストールし直したら以下エラーが発生
```
npm WARN using --force Recommended protections disabled.
npm WARN using --force Recommended protections disabled.
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: line@0.1.0
npm ERR! Found: @vue/cli-service@5.0.8
npm ERR! node_modules/@vue/cli-service
npm ERR!   dev @vue/cli-service@"^5.0.8" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer @vue/cli-service@"^3.0.0 || ^4.0.0-0" from @vue/cli-plugin-router@4.5.19
npm ERR! node_modules/@vue/cli-plugin-router
npm ERR!   dev @vue/cli-plugin-router@"~4.5.0" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR! 
npm ERR! See /root/.npm/eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2022-08-31T06_52_44_489Z-debug-0.log
```

<a id="#Chapter3"></a>
# 原因１
・vue/cli-serviceがインストールされていなかった
確認方法は以下でバージョンが出ればインストールOK
```
＄vue --version
```

# 原因２
・vue/cli-plugin-router
・vue/cli-plugin-babel
上記のバージョンがvue/cli-serviceのバージョンと合っていないという以下のエラーが出ていた
```
npm ERR! Could not resolve dependency:
```
以下、dependency（依存や互換の意？）が異なるパッケージのバージョン確認方法
```
＄npm outdated 
```

<a id="#Chapter4"></a>
# 解決方法
原因１
・vue/cli-serviceをインストール
```
npm install -g @vue/cli
```
原因２
・package.jsonファイルのvue/cli-plugin-routerとvue/cli-plugin-babelのバージョンを直接修正(npm outdatedでLatestになってたバージョンに)し、以下インストールし直し
```
$rm -rf node_modules && rm package-lock.json && npm cache clear --force && npm cache clean --force && npm i
$npm build
```

以下でも解決できるという記事があるが、未検証
```
$npm install --legacy-peer-deps
```

<a id="#Chapter5"></a>
# 番外編
・上記で動くようになったvueイベントハンドラがまた動かなくなった
```
@click="test"　←動かない
、
、
、
test () {
    alert('testOK')
}
```
・原因
→dataにtest: ''を定義していてそっちを見に行っていた
・testという名前にはご注意を

<a id="#reference"></a>
# 参考文献
- [CLI Service - Vue CLI](https://cli.vuejs.org/guide/cli-service.html#vue-cli-service-build)
- [Vue・VueCLIのバージョンが分からん！ - Qiita](https://qiita.com/BlueMountLab/items/f44c4925009c3f94565b)
- [npm install でModule not found: Error: Can't resolve～のエラーが起こった時 - Qiita](https://qiita.com/yummy_mm/items/81c2eec2578afad6f5f6)
- [vue.js - "Could not resolve dependency," error when running ... - stackOverFlow](https://stackoverflow.com/questions/68705211/could-not-resolve-dependency-error-when-running-vue-upgrade)
今一度、再認識しておこう、""と''の違い

## 環境
Ruby 2.6

## はじめに
文字列を囲む時、ダブルクォーテーションで囲む場合と、シングルコーテーションで囲む場合とがあります。基本的な使い方をする分には、どっちを使ってもいいし、どっちを使っても同じです。個人的には、ダブルクォーテーションをひいきしてよく使っています。しかし、時々ありがちなことがあります。ネット上からサンプルコードをコピペして引用したときのことです。サンプルコードにシングルコーテーションが使われていて、気にせずに、そのまま利用し続けるようなことがあります。なぜ、ダブルクォーテーションに置換しなかったのかと言えば、特に理由はありません。本当になんとなくだけです。しかし、シングルコーテーションを残しておいたことで、あるとき、思わぬところで、変な挙動を見かけてしまうことがあります。「あれ？　メッセージ名に変数が含まれている。」

そこで、ダブルクォーテーションとシングルコーテーションの違いについて、今一度、再確認しておきましょう。

## その１
単に、文字列だけを扱う場合であれば、ダブルクォーテーションでも、シングルコーテーションでも、どっちを使っても同じです。
```sample.rb
str1 = "次の停車駅は、米原です"
str2 = '次の停車駅は、米原です'

puts str1
puts str2
```

出力結果。
```
次の停車駅は、米原です
次の停車駅は、米原です
```

## その２
文字列の中に変数が含まれる場合、ダブルクォーテーションとシングルコーテーションとでは、挙動が変わってきます。文字列の中に変数が含まれる場合は、必ず、ダブルクォーテーションで囲む必要があります。シングルコーテーションで囲むと、変数がそのまま文字列として認識されてしまいます。
```sample.rb
station = "米原"

str1 = "次の停車駅は、#{station}です"
str2 = '次の停車駅は、#{station}です'

puts str1
puts str2
```

出力結果。
```
次の停車駅は、米原です
次の停車駅は、#{station}です
```

文字列の中に変数を含める場合、下記のように、文字列と変数を分離させて＋で繋げると、ダブルクォーテーションを使っても、シングルコーテーションを使っても同じ結果になります。他言語からRubyに移った人は、Ruby特有の#{変数}という書き方が、最初はなんとなく、気持ち悪いといった印象を持つかも分かりません。だが、慣れてくると、逆に#{変数}の書き方の方が、スマートな気がしてくるものです。慣れというのは不思議なものです。

```sample.rb
station = "米原"

str1 = "次の停車駅は、" + station + "です"
str2 = '次の停車駅は、' + station + 'です'

puts str1
puts str2
```

出力結果。
```
次の停車駅は、米原です
次の停車駅は、米原です
```

## その３
文字列の中に、変数だけでなく改行コードが含まれている場合でも、シングルコーテーションは使えません。シングルコーテーションを使うと、改行コードも文字列として認識してしまいます。あえて意図的に、文字列として認識させたい場合は、シングルコーテーションを使えばいいでしょう。しかし、そのようなケースが訪れることは、自身の経験上、あまりないような気がします。
```sample.rb
str1 = "次の停車駅は、米原です \n"
str2 = '次の停車駅は、米原です \n'

puts str1
puts str2
```

出力結果。
```
次の停車駅は、米原です
次の停車駅は、米原です \n
```

## その４
ダブルクォーテーションの中にシングルコーテーションを記述することはできます。逆に、シングルコーテーションの中にダブルクォーテーションを記述することもできます。しかし、このような書き方をすれば、後からコードを見直した時に、一瞬「おや？」と思ってしまうことになりかねません。このような書き方をするケースも、恐らくそうそうないかとは思います。

```sample.rb
str1 = "'次の停車駅は、米原です'"
str2 = '"次の停車駅は、米原です"'

puts str1
puts str2
```

出力結果。
```
'次の停車駅は、米原です'
"次の停車駅は、米原です"
```

## その５
ダブルクォーテーションの中にダブルクォーテーションを書く場合、また、シングルコーテーションの中にシングルコーテーションを書く場合は、エスケープする必要があります。
```sample.rb
str1 = "\"次の停車駅は、米原です\""
str2 = '\'次の停車駅は、米原です\''

puts str1
puts str2
```

出力結果。
```
"次の停車駅は、米原です"
'次の停車駅は、米原です'
```

データベースに、nilではなく、空白文字列（""または''）を更新する場合は、このような書き方をすることはよくあります。

```sample.rb
"\"\""
'\'\''
```
TRON系OSの図の表記について

＜TRON　OSを使う時の図表の一例＞
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1141527/6b910ab4-b13a-83fa-a92d-d109eee58688.png)

【タスク相関図】
例）
![task相関図.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1141527/f7ab6912-37ac-4831-2dc3-91bbacc44855.png)

【オブジェクト総括表】
![オブジェクト図.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1141527/0cc2d6e5-2b9a-dd16-1d98-08fe441f5049.png)

【イベントフラグ定義表】
![イベントフラグ定義表.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1141527/83935e18-6de0-ded1-fddd-433b44bb286e.png)

【周期ハンドラ定義表】
![周期ハンドラ定義表.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1141527/a3dafc6c-fdd0-727b-a969-edcdc96dfd05.png)

【プログラムワークシート】
![プログラムワークシート表.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1141527/42147835-3f11-83ff-ffd5-966bab6e820d.png)
Atcoder解いてみた ABC 059 C - Sequence

# ABC 059 C - Sequence 解いてみた
# 
問題は[こちら](https://atcoder.jp/contests/abc059/tasks/arc072_a)
[こちら](https://atcoder.jp/contests/abc059/submissions/3639768)の方が、スマートに解いていました。

## 方針
配列の最初の要素から値を更新していき、1つずつ条件*を満たすようにしていく。
→ ランダムな順番で要素の値を更新しても、1番目から順番に更新していっても、更新回数は変わらない。

### 条件*
a : 第 1 項から第 i 項までの和は 0 でない。
b : i 項までの和と i+1 項までの和の符号が異なる。

結局、以下のように、実装すればよい。
1. 最初(0番目)の要素が正と仮定して、偶数番目までの和が1以上、奇数番目までの和が-1以下になるように配列値を更新していく。更新回数は記録
2. 最初(0番目)の要素が負と仮定して、偶数番目までの和が-1以下、奇数番目までの和が1以上になるように配列値を更新していく。更新回数は記録
3. 1,2で求めた更新回数の小さい方を答えとして出す。

### 注意
問題文に記載の通り、+-1の値で少しずつ値を更新して、更新回数を一回ずつ記録しても、時間オーバーになってしまうため、以下ような工夫点が必要
例) 値を-2から1に変更したいとき、更新回数をabs(-2)+1で求める。

実装の都合上、配列内の値を直接更新するのではなく、i番目までの合計値に対して、何回、更新を行えばいいのか求めるように実装した。

## 回答
```C++
#include <iostream>
#include <cmath>
#include <algorithm>
 
using namespace std;
 
long long solve(long long* arr, int n, bool first_plus);
 
 
 
int main() {
	long long a[100000];
	int n;
 
	cin>>n;
	for (int i=0; i<n; i++) {
		cin >> a[i];
	}
 
	long long min = 100000;
	long long ans_1 = 0;
	long long ans_2 = 0;
 
	ans_1 = solve(a, n, true);
	ans_2 = solve(a, n, false);
 
	std::cout << std::min(ans_1, ans_2) << std::endl;
 
	return 0;
}
 
// first_plus : true →最初の数がプラス
// first_plus : false →最初の数がマイナス

long long solve(long long* arr, int n, bool first_plus) {
 
	long long count = 0;
	long long tmp_sum = 0;
 
	for (int i = 0; i<n; i++) {
		tmp_sum += arr[i];
 
			if (first_plus == true && i % 2 == 0 && tmp_sum <= 0) {
				count += abs(tmp_sum) + 1;
				tmp_sum = 1;   //count回の操作を行った後、合計値は、1になることが確定
			}
			else if (first_plus == true && i % 2 == 1 && tmp_sum >= 0) {
				count += tmp_sum + 1;
				tmp_sum = -1;  //count回の操作を行った後、合計値は、-1になることが確定
			}
			else if (first_plus == false && i % 2 == 0 && tmp_sum >= 0) {
				count += tmp_sum + 1;
				tmp_sum = -1;  //count回の操作を行った後、合計値は、-1になることが確定
			}
			else if (first_plus == false && i % 2 == 1 && tmp_sum <= 0) {
				count += abs(tmp_sum) + 1;
				tmp_sum = 1;   //count回の操作を行った後、合計値は、1になることが確定
			}
	}

	return count;
}

```
ひとつのAWSアカウントに複数のCDKをbootstrapする


cdk.json がなぜか効かずハマったのでメモです。コマンドのパラメータに指定するとちゃんと効いてくれました。

```bash:terminal
cdk bootstrap --profile {プロファイル} \
         --cloudformation-execution-policies 'arn:aws:iam::aws:policy/AdministratorAccess' \
         --qualifier {CDKを区別するための文字列}
```

`--qualifier` デフォルトは `hnb659fds` (この文字列自体に意味はない)。 CDK を分けたいときにこのオプションを付与する。この値が、S3バケット名に使われるため、 指定可能な文字列は [こちら](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/bucketnamingrules.html) を参考にしてください。

https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html#:~:text=%2D-,%2Dqualifier,-a%20string%20that

**2023/04/05 編集**
~~ちなみにダメだった cdk.json は以下の通り。~~
ターミナルで`--qualifier`を指定して実行後、`cdk.json`に下記を手動で追加する必要あります。`cdk deploy` したときに失敗するようです。

- "@aws-cdk/core:bootstrapQualifier": "文字列"

```json:cdk.json
{
  "app": "npx ts-node --prefer-ts-exts bin/hogehoge.ts",
  "context": {
    :
    "@aws-cdk/core:bootstrapQualifier": "文字列"
  },
  "toolkitStackName": "CDKToolKit〜"
}
```
【PHP基礎14】掛け算③

［問題］
ユキさんは最近、カフェインの摂りすぎで、体調を崩してしまいました。
そこで、1日に摂取していいカフェインの量を調べたところ、1日あたり5.7mg/kgでした。
体重Akgの人は何mgまで摂取してよいか求めよ。


# コード
```PHP
$input = fgets(STDIN);
echo 5.7*$input, PHP_EOL;
```

↓　62と入力

# 結果
```
353.4
```