OmniAICreator/Qiita-1.07M huggingface dataset:
4つの入力値を取得して処理し、結果を表示するコード

```Python
from tkinter import *

# 入力値を取得して結果を表示する関数
def get_inputs():
    inputs = [entry1.get(), entry2.get(), entry3.get(), entry4.get()]
    formatted_inputs = ' '.join(f'"{i}"' for i in inputs)
    result_text.delete(1.0, END)  # 以前の結果を削除します
    result_text.insert(END, formatted_inputs)  # 新しい結果を表示します

root = Tk()

Label(root, text="4つの値を入力してください：").grid(row=0, column=0, columnspan=2)

Label(root, text="値1：").grid(row=1, column=0)
entry1 = Entry(root)
entry1.grid(row=1, column=1)

Label(root, text="値2：").grid(row=2, column=0)
entry2 = Entry(root)
entry2.grid(row=2, column=1)

Label(root, text="値3：").grid(row=3, column=0)
entry3 = Entry(root)
entry3.grid(row=3, column=1)

Label(root, text="値4：").grid(row=4, column=0)
entry4 = Entry(root)
entry4.grid(row=4, column=1)

Button(root, text="提出", command=get_inputs).grid(row=5, column=0, columnspan=2)

# 結果を表示するためのテキストウィジェットを追加します
result_text = Text(root, height=2, width=30)
result_text.grid(row=6, column=0, columnspan=2)

root.mainloop()
```
以下は、Windows PCで上記のPythonコードを実行する手順です：

1. Pythonのインストール：まだお持ちでない場合は、Pythonの公式ウェブサイト (https://www.python.org/) からダウンロードしてインストールできます。インストール時に「Add Python 3.x to PATH」のオプションを選択することを忘れないでください。これにより、Pythonがシステムパスに追加され、コマンドラインからアクセスできます。

2. テキストエディタの使用：コードを書くためにはテキストエディタが必要です。Notepad++やSublime Text、またはPython専用のIDE（統合開発環境）であるPyCharmなどを利用することができます。

3. コードの保存：テキストエディタで上記のPythonコードを書き、Pythonファイルとして保存します（拡張子が.py）。たとえば、「gui_input.py」という名前で保存することができます。

4. コマンドプロンプトの使用：スタートメニューを開き、「cmd」と入力してコマンドプロンプトを開きます。そこで「cd」コマンドを使用してPythonファイルを保存したディレクトリに移動します。例えば、「cd C:\Users\YourName\Documents」。

5. Pythonコードの実行：Pythonファイルのあるディレクトリに移動したら、以下のコマンドを入力してPythonコードを実行します：「python gui_input.py」

これにより、上記のPythonコードが実行され、GUIアプリケーションが開始されます。
【ChatGPT無とBardとBing】で逆並べしてみた


　どうも、カーブミラーです。

　今回は、タイトルどおりです。

　OpenAIのChatGPTと
　　GoogleのBardと
　　　MicrosoftのBingで、
　　　　与えた文章を
　　　　　うしろから
　　　　　　読ませました。

　どうぞ。
***
>「かえるのこ」を逆に並べて

　と指示すると、

　ChatGPT:　「このるえか」
　Bard:　「おこねけら」
　　　　「こねろかえ」
　　　　「こねこけ」
　Bing:　創造的「このえら」
　　　　バランス「このかえる」
　　　　厳密「このるえか」

　OpenAI ChatGPT（無料版）は、正解！

　Google Bardは……、
　　どうも、
　　　ひらがなをローマ字に直して、
　　　　ローマ字を逆に並べて、
　　　　　それをひらがな読みに
　　　　　　したみたい。
　　　最後のひとつは、
　　　　意味ある言葉だと
　　　　　考えたようね。

　Microsoft Bingは、
　　厳密が正解したけど、
　　　創造的、バランスは、
　　　　どうしたの？
***
　なんで、
　　こんなことを
　　　していたか、
　　　　と言いますと、

　Bardが
　　「内部的にバックグラウンドで計算している」
　　　というニュースが
　　　　ありまして、
　　その中で「Lollipop」を
　　　逆に並べることが
　　　　できるようになった、
　　　　　という部分が
　　　　　　あったのです。


「Googleの対話型AI「Bard」がバックグラウンドでコードを実行できるようにする「暗黙的なコード実行」を導入（以下略）」
　というタイトルで、
　　以下がリンクです。
[2023年06月08日のニュース](https://gigazine.net/news/20230608-google-bard-implicit-code-execution/ "2023年06月08日のニュース")

　　それで、
　　　ひらがなで
　　　　やってみたわけですが、
　　　　　結果は、
　　　　　　上記のとおりです。
　　　　　　　残念。

　　いや、
　　　なんとなく、
　　　　「できないだろうな」とは、
　　　　　思っていましたけどね。

　　でも、
　　　Google Bardは、
　　　　日本語をローマ字にして
　　　　　扱っているんですかねぇ？

　　それとも、
　　　カッコ内が
　　　　ひらがな文章だから、
　　　　　そうしたのかしら？
***
　ちなみに、
　　Google Bardに
>逆に並べたルーチンをJavaScriptで記述してください。

　　　と言ったところ、
　　　　以下のコードが示されました。
```JavaScript:Google Bard
const text = "かえるのこ";

// 文字列を配列に変換
const array = text.split('');

// 配列を逆順に並べ替え
array.reverse();

// 配列を文字列に変換
const reversedText = array.join('');

// 結果を出力
console.log(reversedText);
```
　えっと、
　　文字列を配列に
　　　ひと文字ずつ入れて、
　　逆順に並べ替え、
　　配列を文字列化する、と。
　　それをログに書き出す。

　ううむ、
　　単純に見て、
　　　正しいんだけど……。

　おそらく、
　　英単語も
　　　同じコードで
　　　　いけるはず。

　でも、
　　出力からすると、
　　　このコードとは違うロジックで、
　　　　処理しているんでしょうね。

　ではでは。
priceのバリデーションを半角数字で設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/b289494c-d454-1153-b21f-090f62b54149.png)
　１：priceのバリデーションの設定
　validates :price, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 9_999_999 },format: { with: /\A[0-9]+\z/}と記述することでpriceのバリデーションを半角数字で設定ができます。
Swiftで解くAtCoder（ABC291）

# 1.はじめに
この記事では、[AtCoder（ABC291）](https://atcoder.jp/contests/abc291)のA~C問題をACしたコードの公開, 解説を行います。
Swiftを使ってコンテストに参加する方の参考になれば幸いです。

# 2.事前準備
標準入力を読み込むためのメソッドです。
コードの先頭に貼り付けて、適宜使用します。
```Swift
import Foundation

// 標準入力から整数を読み込む
func readInt() -> Int{
    return Int(readLine()!)!
}

// 標準入力から整数列を読み込む
func readInts() -> [Int]{
    return readLine()!.split(separator:  " ").map { Int(String($0))! }
}

// 標準入力から文字列を読み込む
func readString() -> String{
    return readLine()!
}

// 標準入力から文字列配列を読み込む
func readStrings() -> [String]{
    return readLine()!.split(separator:  " ").map { String($0) }
}
```

# 3.A - camel Case
問題文や制約は[こちら](https://atcoder.jp/contests/abc291/tasks/abc291_a)からご確認ください。
[AtCoder Problems](https://kenkoooo.com/atcoder/#/table/)によるDifficultyは8になります。
```Swift
let S = Array(readString())

for i in 0..<S.count {
    if S[i].isUppercase {
        print(i+1)
        break
    }
}
```

# 4.B - Trimmed Mean
問題文や制約は[こちら](https://atcoder.jp/contests/abc291/tasks/abc291_b)からご確認ください。
[AtCoder Problems](https://kenkoooo.com/atcoder/#/table/)によるDifficultyは32になります。
```Swift
let N = readInt()
var X = readInts()

X.sort { $0 < $1 }
X.removeFirst(N)
X.removeLast(N)
var sum = 0
for i in 0..<X.count {
    sum += X[i]
}
let average = Double(sum)/Double(X.count)

print(average)
```

# 5.C - LRUD Instructions 2
問題文や制約は[こちら](https://atcoder.jp/contests/abc291/tasks/abc291_c)からご確認ください。
[AtCoder Problems](https://kenkoooo.com/atcoder/#/table/)によるDifficultyは188になります。
```Swift
let N = readInt()
let S = Array(readString())

let moveData: [(direction: Character, dx: Int, dy: Int)] = [("R", 1, 0), ("L", -1, 0), ("U", 0, 1), ("D", 0, -1)]
var isVisited = false
var x = 0
var y = 0
var visitedPoints = Set<[Int]>()
visitedPoints.insert([x, y])
label: for i in 0..<N {
    for data in moveData {
        if data.direction == S[i] {
            x += data.dx
            y += data.dy
            if visitedPoints.contains([x, y]) {
                isVisited = true
                break label
            } else {
                visitedPoints.insert([x, y])
            }
            break
        }
    }
}

print(isVisited ? "Yes" : "No")
```

# 6.さいごに
間違いや改善点等あれば、ご指摘いただけると幸いです。
何卒よろしくお願いいたします。
AWS CDK（ver.2）PythonでEC2 instanceの自動起動・停止を実装してみる

AWS CDKを使ってEC2 instanceの自動起動・停止を実行するリソースを作成してみます。

全コードはGithubを参照してください。
[Githubはここ](https://github.com/ShinyaT1994/cdk-ec2-auto-stop-start.git)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660703/9b50371e-fa5c-5bf0-bf28-2d914a153054.png)


## 前提条件
- AWS CDK v.2 がインストールされていること
- Python 3.x がインストールされていること
- AWSアカウントがあり、AWS CLIが設定されていること

※Cloud9を使うとこの辺りがPassできるため、Cloud9を使って今回の記事の内容は作成しています。

## 構築手順
### 1. CDKアプリの初期化
先ずはCDKアプリの初期化を行います。

```bash
$ mkdir cdk-ec2-auto-stop-start
$ cd cdk-ec2-auto-stop-start
$ cdk init --language python
```

### 2.必要なパッケージをインストール

続いて必要パッケージのインストールになります。
ここでは、CDKアプリを初期化した際に作成された.venvを有効化しています。

```bash
$ source .venv/bin/activate
$ pip install -r requirements.txt
```

### 3. スタックの記述
```python
from aws_cdk import (
    Stack,
    aws_ec2 as ec2,
    aws_events as events,
    aws_events_targets as targets
)
from constructs import Construct

class CdkEc2AutoStopStartStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
        # VPC creation with private subnets
        vpc = ec2.Vpc(
            self, "VPC",
            max_azs=2,  # default is all AZs in the region
            subnet_configuration=[
                ec2.SubnetConfiguration(
                    subnet_type=ec2.SubnetType.PRIVATE_ISOLATED,
                    name="Private",
                    cidr_mask=24,
                )
            ],
        )

        # Create an EC2 instance
        instance = ec2.Instance(
            self, "Instance",
            instance_type=ec2.InstanceType("t3.micro"),
            machine_image=ec2.MachineImage.latest_amazon_linux2(),
            vpc=vpc,
            vpc_subnets=ec2.SubnetSelection(
                subnet_type=ec2.SubnetType.PRIVATE_ISOLATED
            ),
        )
        
        # Create stop rule
        stop_rule = events.Rule(
            self, 'StopRule',
            schedule=events.Schedule.cron(minute='0', hour='10'),   # 日本時間の19時
            targets=[
                targets.AwsApi(
                    service='EC2',
                    action='stopInstances',
                    parameters={
                        'InstanceIds': [instance.instance_id]
                    },
                )
            ],
        )
        
        # Create start rule
        stop_rule = events.Rule(
            self, 'StartRule',
            schedule=events.Schedule.cron(minute='0', hour='0'),   # 日本時間の9時
            targets=[
                targets.AwsApi(
                    service='EC2',
                    action='startInstances',
                    parameters={
                        'InstanceIds': [instance.instance_id]
                    },
                )
            ],
        )

```

### 4. CDKのデプロイ
```bash
cdk deploy
```

デプロイが完了すると、日本時間の9時に起動、19時に停止するリソースが作成されます。


## まとめ
この記事では、AWS CDK ver.2を用いて、PythonでEC2 instanceの自動起動・停止を実装する方法を紹介しました。
どなたかの参考となれば幸いです。
【Xcode ライブラリ】CLImageEditorの「if let」文版【コピペコード】

CLImageEditorの元々のコードは
```swift
if info[.originalImage] != nil {
```
となっているが「安全性」を考慮すると
以下のように「if let文」に書き換えた方がいい。

```swift
//     写真を撮影/選択したときに呼ばれるメソッド
    func imagePickerController(_ picker: UIImagePickerController,
                               didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        // UIImagePickerController画面を閉じる
        picker.dismiss(animated: true)
        // 画像加工処理
        if let originalImage = info[.originalImage] as? UIImage,
           let editor = CLImageEditor(image: originalImage) {
            editor.delegate = self
            self.present(editor, animated: true)
        }
    }
    
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        // UIImagePickerController画面を閉じる
        picker.dismiss(animated: true)
    }
    
    //     CLImageEditorで加工が終わったときに呼ばれるメソッド
    func imageEditor(_ editor: CLImageEditor!, didFinishEditingWith image: UIImage!) {
        // imageViewに画像を渡す
        imageView.image = image
        editor.dismiss(animated: true)
    }
    
    //     CLImageEditorの編集がキャンセルされた時に呼ばれるメソッド
    func imageEditorDidCancel(_ editor: CLImageEditor!) {
        // CLImageEditor画面を閉じる
        editor.dismiss(animated: true)
    }
```
cscの作法 その351

# 概要
cscの作法、調べてみた。
練習問題、やってみた。

# 練習問題
datagridviewの入力にDatetimePickerを使え。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/b1acc3fa-a6e5-49ef-a91e-206b9b2d255e.png)

# サンプルコード

```
using System;
using System.Windows.Forms;
using System.Drawing;

public partial class form1: Form {
	DateTimePicker cal1;
	DataGridView dg1;
	int row,
		coloum;
	public form1() {
		Text = "calender";
		ClientSize = new Size(600, 400);
		dg1 = new DataGridView();
		dg1.Location = new Point(50, 20);
		dg1.Width = 500;
    	dg1.Height = 300;
		Controls.AddRange(new Control[] {
			dg1
		});
		dg1.ColumnCount = 4;
		dg1.Columns[0].HeaderText = "ID";
		dg1.Columns[1].HeaderText = "日付";
		dg1.Columns[2].HeaderText = "商品";
		dg1.Columns[3].HeaderText = "個数";
		dg1.Rows.Add(new Object[] {1, "6/8/2023", "みかん", 100});
		dg1.Rows.Add(new Object[] {2, "6/8/2023", "りんご", 300});
		dg1.Rows.Add(new Object[] {3, "6/8/2023", "バナナ", 200});
		dg1.Rows.Add(new Object[] {4, "6/8/2023", "すいか", 300});
		dg1.Rows.Add(new Object[] {5, "6/8/2023", "いちご", 200});
		dg1.Rows.Add(new Object[] {6, "6/8/2023", "メロン", 100});
		dg1.Columns[0].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
		dg1.Columns[2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
		dg1.CellClick += new DataGridViewCellEventHandler(OnChanged);
	}
	private void OnChanged(object sender, DataGridViewCellEventArgs e) {
		if (e.ColumnIndex == 1)
		{
			cal1 = new System.Windows.Forms.DateTimePicker();
			Rectangle dgvRectangle = dg1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true);
			cal1.Location = new Point(dgvRectangle.X, dgvRectangle.Y);
			cal1.CloseUp += cal1_DateSelected;
			dg1.Controls.Add(cal1);
			cal1.Show();
			coloum = e.ColumnIndex;
			row = e.RowIndex;
		}
	}
	private void cal1_DateSelected(object sender, System.EventArgs e) {
		dg1[coloum, row].Value = cal1.Value.ToString("MM/dd/yyyy");
		(sender as DateTimePicker).Dispose();
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}



```


以上。
オラクルマスターシルバー合格体験記（16日間の戦い）

## 概要
正式名称：ORACLE MASTER Silver SQL 2019 (1Z0-071)
詳細は公式サイトをご覧ください。

https://education.oracle.com/ja/products/trackp_457

## 勉強時間 
期間：2023/1/11(水) ～ 2023/1/26(木)　
トータル：21時間15分 ※アプリを使って記録していました

## 勉強方法
主にオラクルマスターが出版している参考書を使って勉強しました。👉こちら
基本的にこれだけで学習できると思いますが、演習が少ないのでUdemyの予想問題も解きました。👉こちら

参考書を2周＋模擬試験5回分を終えて本番に臨みました。

## 試験結果
無事に合格しました。
個人的難易度は「中」です。（情報セキマネより難しく、基本情報より簡単って印象です）

## 感想
Udemyの模擬試験から似たような問題がたくさん出てきたので
アカウントを持っている方は模擬試験を解くことをオススメします。

ただUdemyの模擬試験の解説が分かりづらいので注意してください。。
※元々英語のドキュメントだったものを日本語に翻訳しているため分かりにくい解説になっていました

また試験の出題範囲がSQLと限られているため、
問題パターンがある程度決まっていて対策しやすかったです。
cscの作法 その350

# 概要
cscの作法、調べてみた。
練習問題、やってみた。

# 練習問題
datagridviewの入力にcomboboxを使え。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/64d80c0a-58ed-f116-5c0a-b394d6a9f6ad.png)

# サンプルコード

```
using System;
using System.Windows.Forms;
using System.Drawing;

public partial class form1: Form {
	ComboBox combo;
	DataGridView dg1;
	int row,
		coloum;
	public form1() {
		Text = "calender";
		ClientSize = new Size(600, 400);
		dg1 = new DataGridView();
		dg1.Location = new Point(50, 20);
		dg1.Width = 500;
    	dg1.Height = 300;
		Controls.AddRange(new Control[] {
			dg1
		});
		dg1.ColumnCount = 4;
		dg1.Columns[0].HeaderText = "ID";
		dg1.Columns[1].HeaderText = "日付";
		dg1.Columns[2].HeaderText = "商品";
		dg1.Columns[3].HeaderText = "個数";
		dg1.Rows.Add(new Object[] {1, "6/8/2023", "みかん", 100});
		dg1.Rows.Add(new Object[] {2, "6/8/2023", "りんご", 300});
		dg1.Rows.Add(new Object[] {3, "6/8/2023", "バナナ", 200});
		dg1.Rows.Add(new Object[] {4, "6/8/2023", "すいか", 300});
		dg1.Rows.Add(new Object[] {5, "6/8/2023", "いちご", 200});
		dg1.Rows.Add(new Object[] {6, "6/8/2023", "メロン", 100});
		dg1.Columns[0].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
		dg1.Columns[2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
		dg1.CellClick += new DataGridViewCellEventHandler(OnChanged);
	}
	private void OnChanged(object sender, DataGridViewCellEventArgs e) {
		if (combo != null)
		{
			combo.Dispose();
		}
		if (e.ColumnIndex == 2)
		{
			combo = new ComboBox();
			combo.Items.Add("みかん");
			combo.Items.Add("りんご");
			combo.Items.Add("バナナ");
			combo.Items.Add("すいか");
			combo.Items.Add("いちご");
			combo.Items.Add("メロン");
			combo.Width = 100;
			combo.Height = 25;
			Rectangle dgvRectangle = dg1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true);
			combo.Location = new Point(dgvRectangle.X, dgvRectangle.Y);
			combo.SelectedValueChanged += combo_changed;
			//combo.TextChanged += combo_changed;
			dg1.Controls.Add(combo);
			coloum = e.ColumnIndex;
			row = e.RowIndex;
		}
	}
	private void combo_changed(object sender, System.EventArgs e) {
		int n = combo.SelectedIndex;
		//Console.WriteLine(n);
		string str = combo.Text;
		//Console.WriteLine(str);
		dg1[coloum, row].Value = str;
		//Console.WriteLine("ok2");
		//sender.Dispose();
		//(sender as ComboBox).Dispose();
		//combo.Dispose();
		Console.WriteLine("ok3");
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}





```


以上。
プロになるためのWeb技術入門を読んで。

## はじめに
今回の内容は  
[書籍「プロになるためのWeb技術入門」（著）小森裕介](https://www.amazon.co.jp/%E3%80%8C%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AEWeb%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80%E3%80%8D-%E2%80%95%E2%80%95%E3%81%AA%E3%81%9C%E3%80%81%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AFWeb%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E9%96%8B%E7%99%BA%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E3%81%AE%E3%81%8B-%E5%B0%8F%E6%A3%AE-%E8%A3%95%E4%BB%8B/dp/4774142352/ref=sr_1_1?crid=29TBO7ITNA4PY&keywords=%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AEweb%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80&qid=1676288834&sprefix=%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%2Caps%2C199&sr=8-1)  
を読んで、ピックアップされた用語を自分なりに簡単に説明してみるアウトプット記事にしたいと思います。

## 用語
### ステートフル
状態を維持するプロトコルのこと。
ステートフルプロトコルとして`FTP`などがある。
分かりやすく例でいうと、美容室。  
美容室では来店したお客様の情報を記録しています。、  
「誰が対応したか」「どんな髪型にしたか」などを分かるようになっていますよね。　　
なので「この前と同じ髪型でお願いします」と言えばそれで通じるのです。
このように、FTPサーバーが前回のリクエスト結果を覚えていて、それを踏まえて次のリクエストを実行しています。

### ステートレス
状態を維持しないプロトコルのこと。
ステートレスなプロトコルとして、`HTTP`などがある。
こちらも分かりやすく例でいうと、1000円カット。
1000円カットではどんなお客さんがいつ来店して、どのような髪型にしたかは記録していないことが多いと思います。
なので、何度言っても毎回「どんな髪型にしますか？」ときかれてしまいます。　　
このように、サーバーは毎回リクエストを要求して、それに対してのリクエストを実行します。

### リクエスト
クライアントからサーバーに対する要求のこと。

### レスポンス
サーバーからクライアントに対する応答のこと。
　　
　　
![IMG_3FB8031505C5-1.JPEG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3335067/6242ef95-5607-7d0b-9033-4b7859200acc.jpeg)

リクエストとレスポンスを簡単に表してみました。


### Cookie（クッキー）
HTTPの仕様を拡張してWebアプリケーションとWebブラウザの間で情報を交換できるようにしたもの。
WebサーバーからWebブラウザへHTTPレスポンスのヘッダを利用して小さな情報を送り、この情報は「名前＝値」の組み合わせであらわされ、**Cookie**と呼ぶ。
WebアプリケーションはステートレスなHTTPで実現しているので、Cookieを使うことでWebブラウザに状態を持たせてステートフルのように通信ができる。
通信するサーバーごとにcookieが存在する。
![IMG_FF87E1D577C9-1 (1).JPEG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3335067/fd504445-3c21-fdfc-5652-2ab815fb5567.jpeg)

### プロトコル
どのような方法で情報をやり取りするかという取り決めのこと。
`HTTP` `HTTPS` `FTP` `SSH` などがある。

### ポート番号
TCP/IPで通信を行う際に用いられる番号でリクエストの宛先の住所のようなもの。
代表的なプロトコルには共通のポート番号が割り振られている。
例えば
HTTPプロトコルは80番ポートを宛先ポートとして設定される。

## 終わりに
今回アウトプットした用語はほんとに一部のみでまだまだたくさんの用語や説明がこの本に詰まっていました。　
今回の本を読んで少しはWebについて簡単な流れだったりは把握できたのかなと思うのでこれからしっかりと内容を踏まえて学習していきたいと思います。
Tableau Desktopでやった計算まとめ

平凡な計算でござるよ。

# １）簡易ランキング表示
そのへんのサイトにやり方書いてそう。
というかメモるほどのものでもないな…と言いながらメモる。

まず、「RANK」という計算フィールドを作成。
対象項目を昇順/降順に並べて採番。
```RANK
RANK_UNIQUE([販売金額],'asc')
```
次にパラメーター「ランク」を作成。
文字列型で「すべて」「上位下位5件」のリストをつくる。

その次に「ランク表示」という計算フィールドを作成。

```ランク表示
IF [ランク]='上位・下位5件'
THEN RANK(  [RANK] , 'asc' ) <=5 OR RANK(  [RANK] , 'desc' ) <=5
ELSEIF [ランク]='下位5件'
THEN RANK(  [RANK] , 'desc' ) <=5
ELSE true
END
```
あとはこの「ランク表示」をフィルタに入れて、カスタム値のリストで「真」に設定すればOK。

ポンコツなので、毎回採番する関数を忘れてしまう。


# ２）N以上の平均を求める
Prepでやったほうが早いかも。
例えば、データとしては200くらいあるけど、100個までの平均を求めたいとき。
残りの100個はNULLにする平均の計算です。

``` 
{FIXED[店],[種類]:AVG(IF[n]<=100 THEN [販売金額] ELSE NULL END)}
```
nは一意な連番。

実際の式で使っている列名を変えてみたけど、例えが悪すぎる。
100個までの販売金額平均してどうすんねん。



# ３）ExcelのProduct関数みたいなことをする
[SQLである列の要素すべての積を求める方法](https://qiita.com/shiozaki/items/68a94d7e049e49493a77)
↑ここを参考に。
なんで対数使うんだっけ…。

全部の値をを縦に掛け算するとき。

``` 
EXP(SUM(LN([売上率])))　
```

負の数来たら死にそう。
元の式を理解していないのでこれ以上説明できません。


店ごとの平均を求めて、それの掛け算するとき。

``` 
EXP(SUM(LN(
{FIXED[月],[県],[店] :AVG([売上率])}
)))
```

やってることは同じすな。

計算されている売上率が怪しいときは、計算前の項目を上記のようにFIXEDしてから、百分率の計算をすればいいと思います。
```
EXP(SUM(LN(
{FIXED[月],[県],[店] :SUM([販売数])}
)))

EXP(SUM(LN(
{FIXED[月],[県],[店] :SUM([仕入数])}
)))

[販売数]/[仕入数]
```
増殖する計算フィールドェ……。


# ４）デフォルトフィルタみたいなのを実装する
[アクションがクリアされたときのデフォルト フィルターの指定](
https://kb.tableau.com/articles/howto/specifying-a-default-filter-when-action-is-cleared?lang=ja-jp)
↑ここを参考に。
フィルタリセットしたときに、特定の値でフィルタをかけているようなフィルタを実装するもの。
ゲシュタルトフィルタ。

直訳されているので上記サイトでは計算式の「OR」も「または」に訳されています。
ビバ日本語の穴です。

```
MIN({EXCLUDE [県]: COUNTD([店])})=1
OR MIN([店])  = [リセット時の店名]
```

で、この式を書いた列をフィルタにいれて、カスタム値のリストで「真」に設定。

[リセット時の店名]はパラメータです。
動的にパラメータ変えたかったのでこうしたけど、URLのように固定値でも動きます。

EXCLUDEで絞り込みが考慮されているので、店で絞り込んでいればTRUE。
そうでなければ、[リセット時の店名]だけを表示するようにしている、というカラクリです。

なので店のフィルタ的には「すべて」で、データ数多いものではめちゃんこ読み込みます。
そこそこフィルタされてるものに使いませう。
あと真のときだけ表示形式使ってるので、複数実装はいばらの道な気がする。
検証してないので知らんけど。

# おしまい
Desktopも試行錯誤すりゃそこそこ出来るんやね。
コード可視化ツール Sourcetrail のインストール

Python強い人が書いた、複数のディレクトリや大量のクラスがあるコードの関係が可視化できないかなと思って調べてみた（複数フォルダとかあると、この関数このフォルダにあるんかい、みたいなことでやたら時間かかってしまうことがある・・・あとは見つけても構造が理解し辛いとか）

# インストーラーのダウンロード
既に開発は終了しているようだが、インストールはできる（Windows版をダウンロード）

https://github.com/CoatiSoftware/Sourcetrail/releases

# インストール
手抜きで申し訳ありませんが、以下サイトが分かり易かったです。
ありがとうございます。

恐らくバージョンが異なる為か、
「再度静的解析をより深くしてくれるらしいのでstart in-depth indexingを選択する」という部分はよくわからずやっていません。

createすると大量にエラーもでるけど、可視化は出来たみたいです。

https://zenn.dev/r2en/articles/9027f0e7290e2755d2b9


クリックすると色々表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460901/d6254fab-01b0-a920-0053-510fc1ba94b5.png)

以下はModulesをクリックして、その中の関数をクリックした結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460901/747b9c7e-5a20-2c70-74b2-f4adde028d7f.png)

これだけで理解できるのか、自分でも書かないと理解できないのかはこれから試行錯誤するつもり・・

以上
WSLで「デスクトップ」や「ダウンロード」へアクセスしたい

# 課題
wsl のホームディレクトリから「デスクトップ」や「ダウンロード」にアクセス方法が分からない

# 原因
何か問題があるわけではなく、パスを指定すると移動可能。
```shell-session
samenchi@Computer-Name:~$ pwd
/home/samenchi
samenchi@Computer-Name:~$
samenchi@Computer-Name:~$ ls -l /mnt/c/Users/samenchi/Downloads/
<snip>
samenchi@Computer-Name:~$
samenchi@Computer-Name:~$ cd /mnt/c/Users/samenchi/Downloads/
samenchi@Computer-Name:/mnt/c/Users/samenchi/Downloads$
samenchi@Computer-Name:/mnt/c/Users/samenchi/Downloads$ pwd
/mnt/c/Users/samenchi/Downloads
samenchi@Computer-Name:/mnt/c/Users/samenchi/Downloads$
```

# 解決方法
ホームディレクトリを変更する事でも対応可能ですが、今回は「デスクトップ」や「ダウンロード」へアクセス可能なシンボリックリンクを作成します。
```shell-session
samenchi@Computer-Name:~$ ln -s "/mnt/c/Users/samenchi/OneDrive - samenchi/デスクトップ" desktop
samenchi@Computer-Name:~$ ln -s /mnt/c/Users/samenchi/Downloads/ downloads
samenchi@Computer-Name:~$ ls -l
<snip>
lrwxrwxrwx 1 samenchi samenchi   32 May 23 13:10 downloads -> /mnt/c/Users/samenchi/Downloads/
lrwxrwxrwx 1 samenchi samenchi   61 Jun  9 10:31 desktop -> '/mnt/c/Users/samenchi/OneDrive - samenchi/デスクトップ'
samenchi@Computer-Name:~$
samenchi@Computer-Name:~$ cd downloads
samenchi@Computer-Name:~/downloads$ 
```
# オマケ
資料作成時に利用した画面キャプチャを一斉に削除するshスクリプト。

```shell_session
samenchi@Computer-Name:~$ cat rm_jpg.sh
#!/bin/bash

rm downloads/*jpg
rm downloads/*png
rm desktop/*jpg
rm desktop/*png
```
Falco Ruleを紹介するシリーズ - Launch Sensitive Mount Container

本シリーズでは、ランタイム脅威検知のデファクトスタンダードである<a href=https://falco.org/ target=new>Falco</a>の検知Ruleを、１つの記事で１つ簡単に紹介していきます。
ランタイムセキュリティやFalco自体の概要を知りたい方は<a href=https://sysdig.jp/blog/intro-runtime-security-falco/ target=new>こちらのブログ記事</a>をご参照ください。
今回ご紹介する検知Ruleは<b>「Launch Sensitive Mount Container」</b>です。
# Rule記述
```
- rule: Launch Sensitive Mount Container
  desc: >
    Detect the initial process started by a container that has a mount from a sensitive host directory
    (i.e. /proc). Exceptions are made for known trusted images.
  condition: >
    container_started and container
    and sensitive_mount
    and not falco_sensitive_mount_containers
    and not user_sensitive_mount_containers
  output: Container with sensitive mount started (user=%user.name command=%proc.cmdline %container.info image=%container.image.repository:%container.image.tag mounts=%container.mounts)
  priority: INFO
  tags: [container, cis, mitre_lateral_movement]
```
# Rule概要
コンテナ内で、ホストの要注意ディレクトリをマウントする初期プロセスが起動したことを検知します。
例として、ホストの/etcディレクトリをコンテナにマウントし、crontabを編集して悪意あるbashスクリプトの定期的なダウンロードと実行を試みることで、コンテナレベルアクセスからホストレベルアクセスを実現しようとする攻撃などが観測されています。詳細は<a href=https://sysdig.com/blog/detecting-cryptojacking/ target=new>こちらのブログ記事</a>をご参照ください。
このようなコンテナからホストへのエスケープにつながる振る舞いも、このRuleを使うことで検知可能です。

# Condition（条件）
`container_started and container`
コンテナが起動し、

`and sensitive_mount`
ホストの要注意ディレクトリをマウントし、

かつ

`and not falco_sensitive_mount_containers`
Falcoがあらかじめ定義したマウントではなく、

`and not user_sensitive_mount_containers`
ユーザーがあらかじめ定義したマウントでもない場合

---
`sensitive_mount`の対象ディレクトリはマクロとして以下のように定義されています。
```
- macro: sensitive_mount
  condition: (container.mount.dest[/proc*] != "N/A" or
              container.mount.dest[/var/run/docker.sock] != "N/A" or
              container.mount.dest[/var/run/crio/crio.sock] != "N/A" or
              container.mount.dest[/var/lib/kubelet] != "N/A" or
              container.mount.dest[/var/lib/kubelet/pki] != "N/A" or
              container.mount.dest[/] != "N/A" or
              container.mount.dest[/home/admin] != "N/A" or
              container.mount.dest[/etc] != "N/A" or
              container.mount.dest[/etc/kubernetes] != "N/A" or
              container.mount.dest[/etc/kubernetes/manifests] != "N/A" or
              container.mount.dest[/root*] != "N/A")
```
`container.mount.dest[] != "N/A"`
マウント対象ディレクトリが"N/A"ではない場合

# Output（出力）
要注意ディレクトリをマウントしたコンテナが起動しました。

`%user.name`
ユーザー名

`%proc.cmdline`
コマンドライン

`%container.info`
コンテナ情報

`%container.image.repository`
コンテナイメージリポジトリ

`%container.image.tag`
コンテナイメージタグ

`%container.mounts`
コンテナマウント
Roblox のサムネイルやアイコンに使えるデザインウェブサイト

このページが**おすすめ**デスッ！

https://www.hubpng.com/search?q=Roblox

![Screenshot 2023-06-09 at 10.47.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1900756/b5851b49-49ff-907f-ce1d-a6f87d9f2d8c.png)
RubyでAtCoder ABC247(A, B, C, D)を解いてみた

# はじめに
Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC247のA, B, C, Dを解きました。備忘録として解き方をまとめていきたいと思います。

# A - Move Right
https://atcoder.jp/contests/abc247/tasks/abc247_a
```ruby:a-247.rb
puts "0" + gets.chomp[0..2]
```

# B - Unique Nicknames
https://atcoder.jp/contests/abc247/tasks/abc247_b
```ruby:b-247.rb
n = gets.to_i
array = Array.new(n){ gets.split }
hash = array.flatten.tally

array.each do |s, t|
  if s != t && hash[s] != 1 && hash[t] != 1
    puts "No"
    exit
  end
end
puts "Yes"
```
## 解説
`flatten`メソッドと`tally`メソッドを使ってそれぞれの名前が何回現れたかを連想配列hashにもたせます。そして、問題文にある条件を満たしているかどうかを判定することで解くことができます。

# C - 1 2 1 3 1 2 1
https://atcoder.jp/contests/abc247/tasks/abc247_c
```ruby:c-247.rb
n = gets.to_i
ans = "1"
2.upto(n){ |i| ans = "#{ans} #{i} #{ans}" }
puts ans
```
## 解説
Nが16以下と小さいので、`"1"`で初期化した`ans`を順番に更新していけば答えが求まります。

# D - Cylinder
https://atcoder.jp/contests/abc247/tasks/abc247_d
```ruby:d-247.rb
q = gets.to_i
que = []
q.times do
  t, x, c = gets.split.map(&:to_i)
  case t
  when 1
    que << [x, c]
  when 2
    ans = 0
    while x > 0
      s, t = que.shift
      remove_count = [t, x].min
      ans += s * remove_count
      x -= remove_count
      t -= remove_count
      que.unshift([s, t]) if t > 0
    end
    puts ans
  end
end
```
## 解説
（他の方の提出結果を参考にしました）

１）1のとき
xと書かれたボールをc個右側に入れるので、配列queの末尾に`[x, c]`を追加します。   
２）２のとき
取り出したボールの数がxとなるまで、取り出したボールに書かれていた数字の総和を求めます。

https://qiita.com/shoya15/items/50fd17e37d7c64f2b166
Ctrl+Shift+P を押すと sfdx コマンドがコマンド パレットに表示されない



+ [sfdx Command missing in command palette by pressing Ctrl+Shift+P]()


This happens when you load the VS Code and immediately try to work. It takes a good 5+ mins sometimes for the VS Code to load the plugins like Salesforce CLI and SFDX.

To not have this issue, update your VS code and extensions to the latest version and restart it.
https://salesforce.stackexchange.com/questions/357082/not-seeing-sfdx-commands-in-vs-code


Issue has been resolved once I install the extension 'Salesforce CLI Integration' into VScode . I am bit confuse how it was worked early , may be I mistakenly uninstall  'Salesforce CLI Integration' . But anyhow good news is now its working and also able to run/execute Apex script from my VScode IDE.


拡張機能「Salesforce CLI Integration」を VScode にインストールすると、問題は解決しました。初期段階でどのように機能していたのか少し混乱しています。おそらく、誤って「Salesforce CLI Integration」をアンインストールしたのかもしれません。 VScode IDE から Apex スクリプトを実行/実行します。
なぜfrom matplotlib import pyplot as pltではなく、import matplotlib.pyplot as pltなのか

# 表題の疑問について
結論：import matplotlib.pyplot as pltとfrom matplotlib import pyplot as pltに違いはありません。
しかし、次のような場合は大きな違いが生まれます。

```py
import numpy.random # 1
```

```py
from numpy import random # 2
```

#1のコードはnumpyとnumpyの中のrandomモジュールがインポートされます。つまり下コードはエラーを吐きません。

```py
import numpy.random

temp = numpy.array([0, 1, 2])
```

しかし、上記#2のコードはnumpyの中のランダムモジュールのみがインポートされるので、次のコードは

```
NameError: name 'numpy' is not defined
```
が出力されます。
lightning-input-field がチェックボックスフィールドに対して機能しない


+ [lightning-input-field not working for Checkbox fields](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000QNtLd)


:::note
Actually this is not correct. Using the value attribute for a Checkbox results in a java script error b/c can't convert from String to Boolean. Spoke with SF support and there is a problem with the lightning-input-field in that there is no way to override the field's Boolean/checkbox value (i.e. no way to set to checked if the Boolean value is false). Can't believe this hasn't been reported before.....

Workaround is to manually set the field value using JS on form submit via setFormFieldValue (example: this.setFormFieldValue('Reserved_Timeslot__c', true); will set the Object's Reserved_Timeslot__c to true even though it is false in the DB.)

実はこれは正しくありません。チェックボックスに value 属性を使用すると、文字列からブール値に変換できないため、Java スクリプト エラーが発生します。SF サポートに問い合わせたところ、フィールドのブール値/チェックボックス値をオーバーライドする方法がない (つまり、ブール値が false の場合にチェック済みに設定する方法がない) という点で、lightning-input-field に問題があります。これまで報道されていなかったことが信じられない……。

回避策は、setFormFieldValue 経由でフォーム送信時に JS を使用してフィールド値を手動で設定することです (例: this.setFormFieldValue('Reserved_Timeslot__c', true); これにより、DB では false であっても、オブジェクトの Reserved_Timeslot__c が true に設定されます)。
:::
Enhanced Domain & TLS Version 1.3


+ [Enhanced Domain & TLS Version 1.3](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Pf6V7)

私はまだ1.3は機能していないと思っていますが... よくわかりませんね。何の話をしているんだろう。

[アイデア:Enable TLS 3 for Salesforce](https://ideas.salesforce.com/s/idea/a0B8W00000NKq3zUAD/enable-tls-3-for-salesforce)



API 接続は、 MyDomainName.my.site.comまたはExperienceCloudSubdomain.force.comのようなホスト名ですか? その場合、拡張ドメインは、TLS 1.2 と TLS 1.3 の両方が有効になっている CDN を使用するMyDomainName.my.site.comにリダイレクトされます。TLS 1.2 のみをサポートする API クライアントは動作すると予想されます。

ただし、Salesforce の CDN 構成で問題を引き起こす可能性がある側面の 1 つは、暗号スイートの選択です。Salesforce の CDN 設定は、特定の ECDHE 暗号スイートのみをサポートし、RSA キー交換を使用する暗号スイートはサポートしません。これについてはhttps://www.ssllabs.com/ssltest/analyze.html?d=tls1test.my.site.com&s=で確認できます。23.1.237.96。安全な ECDHE 暗号スイート、特に次の少なくとも 1 つを必ず有効にしてください。

# TLS 1.2 (サーバーの優先順にスイート)
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c) ECDH secp256r1 (3072 ビット RSA 相当) FS 256
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b) ECDH secp256r1 (3072 ビット RSA 相当) FS 128
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030) ECDH secp256r1 (3072 ビット RSA 相当) FS 256
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) ECDH secp256r1 (3072 ビット RSA 相当) FS 128
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9) ECDH secp256r1 (3072 ビット RSA 相当) FS 256P
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8) ECDH secp256r1 (3072 ビット RSA 相当) FS 256P

(P) このサーバーは、AES-NI を持たないクライアント (Android デバイスなど) を使用する ChaCha20 スイートを優先します。


TLS 1.3 をサポートしている場合、この投稿の時点で TLS 1.3 でサポートされている暗号スイートは次のとおりです。

# TLS 1.3 (サーバーの優先順にスイート)
TLS_AES_256_GCM_SHA384 (0x1302) ECDH x25519 (3​​072 ビット RSA 相当) FS 256
TLS_CHACHA20_POLY1305_SHA256 (0x1303) ECDH x25519 (3​​072 ビット RSA に相当) FS 256P
TLS_AES_128_GCM_SHA256 (0x1301) ECDH x25519 (3​​072 ビット RSA 相当) FS 128

Salesforce の他のエンドポイントは現在も RSA キー交換を最も優先度の低い暗号スイートとしてサポートしていますが、MyDomainName.my.site.comでは RSA キー交換のサポートがオフになっています。

必要に応じて、特定の組織に対してMyDomainName.my.site.comの CDN アクセラレーションをオフにするよう Salesforce サポートにリクエストすることが考えられます。これにより、Salesforce は通常、RSA キー交換をより一般的に段階的に廃止する予定であるため、一時的な措置として、MyDomainName.my.site.comで RSA キー交換を利用できるようになります。

https://learn.microsoft.com/en-us/windows/win32/secauthn/cipher-suites-in-schannel?redirectedfrom=MSDNから、古い Windows Server バージョンでは ECDHE 暗号スイートがサポートされていることがわかります。ただし、SHA-2 256 または SHA-2 384 のハッシュ強度と GCM または POLY1305 をサポートする必要があり、これらすべての組み合わせのサポートは Windows で開始されているようです。 Server 2016 および Windows 10 バージョン 1607。

Windows Server 2012 R2 では、サポートがかなり近づいていますが、RSA 証明書の代わりに ECDSA 証明書が使用され、*. my.site.com HTTPS 証明書は ECDSA ではなく RSA を使用します。
フローでの検証ルールにおける理解できない挙動



+ [How to create a pattern for phone component in flow?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Pf5N3)

Phone型なのでバリデーションルールが効かなかった？

:::note
 I have just opted to use a text component rather than a phone component and set a validation. Please comment if you have found documentation on using the pattern functionality and limitations.
:::


+ [API バージョン 59 では、リアクティブ画面での ADDMONTHS がサポートされるようになりました。サポートされていない API58 を使用していました](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007Id04D)
Goでメソッドの引数が同じ型である場合、省略して記述できる

今年の3月まで19ヶ月ほどGoを書いていたのですが、その際は何となく雰囲気でやっていたので。
Goを基礎から勉強しなおそうと思い、[A Tour of Go](https://go.dev/tour/list)をやっています。

## 事象

メソッドの引数が同じ型である場合、最後の型を残して省略出来る様子。

```go
func add(x, y int) int {
	return x + y
}
```

## 反省

知らなかったので、毎回省略せずに型を書いていました。
ただ、保守時の可読性を考えると、場合によっては省略せずに書いたほうが良いかもしれない🤔

他の言語が分かるとなんとなく、雰囲気で書けちゃうけど、
新しい言語をやる時は、公式や有名な教材をちゃんとやって基本を付けたほうが良さそうだね😅
受託開発メインだと、JavaやRuby・KotlinやPythonなど、
いろんな言語をやる事が多いので、一つの言語に労力を掛けにくいってのもあるんだけど…。

## 参考

https://go.dev/tour/basics/5
ExcelマクロでINIファイルからKEY-VALUEを変換する

# 1. はじめに
* Excelのセルの値をKEYにVALUEに変換したい

# 2. 開発環境
* Excel
* Excel VBA

# 3. Exclマクロ
```vb
' WSHオブジェクト
Dim WSH_OBJECT As Object
Set WSH_OBJECT = CreateObject("WScript.Shell")

' MyDocumentパス
Dim MYDOCUMENT_PATH As String
MYDOCUMENT_PATH = WSH_OBJECT.SpecialFolders("MyDocuments")
MYDOCUMENT_PATH = WSH_OBJECT.SpecialFolders(16)

' INIファイル取得
Dim KEY_VALUE As New Scripting.Dictionary
Set KEY_VALUE = GetMapFromIniFile(MYDOCUMENT_PATH & "\key-value.ini")

' KEY-VALUE変換
Public Sub KEY-VALUE変換()

    Dim startGyo As Long, endGyo As Long, startRetu As Long, endRetu As Long, Gyo As Long
    Dim wkMember As String, wkMeisyo As String
    
    If TypeName(Selection) = "Range" Then
        startGyo = Selection(1).Row
        endGyo = Selection(Selection.Count).Row
        startRetu = Selection(1).Column
        endRetu = Selection(Selection.Count).Column

        For Gyo = startGyo To endGyo
            DoEvents
            If Cells(Gyo, startRetu) <> "" Then
                wkMember = Trim(Cells(Gyo, startRetu))
                wkMeisyo = TABLE_DB.Item(wkMember)
                If wkMeisyo <> "NONE" Then
                    Cells(Gyo, startRetu + 1) = wkMeisyo
                End If
            End If
        Next Gyo
    End If
    
End Sub

' INIファイルからディクショナリを作成する
Public Function GetMapFromIniFile(iniPath As String) As Scripting.Dictionary

    Dim Map As New Scripting.Dictionary
    Dim GetMapFromIni As New Scripting.Dictionary
    Dim fso As Object, file As Object
    Set fso = New Scripting.FileSystemObject
    Set file = fso.OpenTextFile(iniPath, 1)
    
    Map.CompareMode = vbTextCompare
    
    Dim line As String, key As String, Value As String, arr
    Do Until file.AtEndOfStream
        line = file.ReadLine
        If InStr(line, "=") > 0 Then
            arr = Split(line, "=")
            key = arr(0)
            Value = arr(1)
            If Not Map.Exists(key) Then
                Map.Add key, Value
            End If
        End If
    Loop
    
    file.Close
    Set file = Nothing
    Set fso = Nothing
    
    Set GetMapFromIniFile = Map
    
End Function
```

# 4. 参考文献

https://vbabeginner.net/get-values-from-ini-files/
Typescriptで「全部未指定」または「どれか１つが指定されている」型を定義する

## この記事について
業務でタイトル通りの型を作りたいケースが発生し割と試行錯誤したのでその内容を共有をしたいと思います。
同じようなものが作りたくて困っている人のお役に立てたら幸いです。

## やりたかったこと
とある画面のオプションがあり、こんな感じの内容でした。
１つは「ログアウトしていても有効にする」というオプション
もう1つは「管理者権限でログインしているアカウントのみ有効」というオプションです。
```ts
{
  logout: 1 | 0; // ログアウトしてても有効にするオプション
  admin: 1 | 0; // 管理者権限でログインしているアカウントのみ有効にするオプション
}
```
見てもらうとわかると思いますが上記の２つは排他関係にありどちらかが有効な場合、もう一つは無効になっている必要があります。
なので「どちらか片方だけしか指定することはできない」が表現された型を作りたいと思っていました。
加えてシステム構築時にこれらのオプションは存在しておらず後から追加されたため、他の箇所に影響が出ないように「いずれも指定されていない」というのも型として表現したいなと思っていました。

## まずは結論
結果的に以下のようにすると上記の型を表現することができました！
```ts
// 全てのプロパティを持てなくする汎用型
type RejectAll<T> = { [P in keyof T]?: never };

// `定義されているプロパティの中でどれか１つは必須`を表現する汎用型
type OnlyOneOf<T> = {
  [P in keyof T]: RejectAll<Omit<T, P>> & Required<Pick<T, P>>;
}[keyof T];

// どれか１つは必須の対象となるプロパティ
type RequireWhichOneOptions = {
  logout: 1 | 0;
  admin: 1 | 0;
};

// いずれも指定されていない or どれか１つが指定されている 以外は許さない
type WhichOneOrNothing = OnlyOneOf<RequireWhichOneOptions> | RejectAll<RequireWhichOneOptions>;
```

## 解説
まず、以下の部分ですが [こちら](https://zenn.dev/pione30/articles/950e361b235ed4) の記事を参考にさせていただきました。（投稿者の方、本当に助かりました！！ありがとうございました！）
```ts
// 全てのプロパティを持てなくする汎用型
type RejectAll<T> = { [P in keyof T]?: never };

// `定義されているプロパティの中でどれか１つは必須`を表現する汎用型
type OnlyOneOf<T> = {
  [P in keyof T]: RejectAll<Omit<T, P>> & Required<Pick<T, P>>;
}[keyof T];
```

まずはジェネリクスで引き渡されたオブジェクトの全てのプロパティを持つことを不可とする型を作ります。
```ts
type RejectAll<T> = { [P in keyof T]?: never };
```
もし、以下の様にすると
```ts
type Hoge = RejectAll<{
  logout: 1 | 0;
  admin: 1 | 0;
}>;
```
「`logout` も `admin` もどちらも持てない」という型になります。

これだけだと「誰得...？」な状態になってしまうので次に上記を利用した別の型を定義します。
```ts
type OnlyOneOf<T> = {
  [P in keyof T]: RejectAll<Omit<T, P>> & Required<Pick<T, P>>;
}[keyof T];
```

`RejectAll<Omit<T, P>>` は「当該のプロパティ以外を定義不可能とする」
`Required<Pick<T, P>>` は「当該のプロパティを定義必須とする」となり、
上記を組み合わせた結果「当該のプロパティしか持てない」型になります。
```ts
RejectAll<Omit<T, P>> & Required<Pick<T, P>>
```
そして最後の `[keyof T]` の部分でUNION型にしている様です。
その結果以下のような型を直接指定した場合と同義の「いずれか１つは定義が必須」という型を作り出すことができます。
```ts
{ logout: 1 | 0; admin: never; } | { logout: never; admin: 1 | 0; }
```

ただし、今回のケースの場合、上記だけでは「いずれも定義されない場合」がカバーできていません。
なので、最初に定義した `RejectAll` を利用して「いずれも定義されていない」型を定義し上記の型とUNIONにします。
```ts
// いずれも指定されていない or どれか１つが指定されている 以外は許さない
type WhichOneOrNothing = OnlyOneOf<RequireWhichOneOptions> | RejectAll<RequireWhichOneOptions>;

// 多分こんな感じになってて「未定義かどれか１つを定義」以外はエラーになる
{ logout: 1 | 0; admin: never; } | 
{ logout: never; admin: 1 | 0; } | 
{ login: never; admin: never; }
```
こうすることでやりたいことが型で表現でき、処理に頼らずに正当性チェックをトランスパイラに任せることができる様になりました！

## まとめ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304462/5eb172c9-0b0c-fdc1-a7a1-ee8aba0deb66.png)


最後までお読みいただきありがとうございました。
iPhoneでメモリ不足でアプリが自然終了するときをデバックする

ユーザーがアプリを強制終了させたときはapplicationWillTerminateメソッドが呼ばれるけど、アプリがバックグラウンドに入ってユーザーが重たいアプリとか処理したときに終了するとapplicationWillTerminateは呼ばれません。これどうやってデバッグするのか。iPhoneの設定のデベロッパーの項目に「状態復元テスト」というのがある、これをオンにするとアプリがバックグラウンドで落ちやすくなってデバッグしやすくなります。(たぶんiOS16以降)下の文章は２０回読んでも意味がわからんかった、まだちゃんとローカライズされてない。
![IMG_4840.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117011/3f6ff3c6-1e25-8066-4fb3-9a8396ddf7cc.jpeg)
週一でPython勉強会やってみる⑧

前回の続き

https://qiita.com/Waddy675/items/be6f78c9726fe7c7a8cc

毎度牛歩のように進めている勉強会ももう8回目ですね。コードに触れるという大目標をクリアし続けてるのは良いことだと思います。（思いたいｗ）

# セルの取得方法
- 前提としてエクセルを触る。→セルを扱えるようにならないと始まらない。
- 扱い方はスプレッドシートと似ている。
- 3つも取得方法がある。

## その①～rangeとfor文でがんばる作戦～
縦と横方向（行と列）になるようにfor文を重ねることでセルを取得できる。
- メリット
for文なので何をやってるか初心者にはわかりやすい。
- デメリット
「Dは何列目か」など位置情報を正確に変換をしないと欲しい情報が得られない。
``` py
# A1～Z10まで
for y in range(1,11):
  for x in range(1,27):
    cell = sheet.cell(row=y, column=x)
```

## その②～左上と右下のセル名でラクラク指定～
左上と右下を選択すると範囲が選択できるのと同様に取得できる。
- メリット
コードを見れば範囲が一目でわかる。
- デメリット
動的な範囲指定には少しコツが必要。

``` py
for rows in sheet["B2:D4"]:
  for cell in rows:
    print(cell)

for rows in sheet["B2":"D4"]:
  for cell in rows:
    print(cell)
```
sheetのセルの範囲指定には2パターンの書き方がある。どちらでもよい。
- 全部文字列パターン（**"B2:D4"**）
- セル名だけ文字列パターン（**"B2"**:**"D4"）**

## その③～イテレータで繰り返し範囲から取得～
イテレータは基本的にfor文と組み合わせて使う前提で、特定の要素を反復して値を取り出せる。
今回はsheetのiter_rowsメソッドを使う。
- メリット
直接セル名指定ではなくなるので、どんな状況下でも扱いやすい。
- デメリット
メソッドの中身を理解していないと思った通りの範囲を取得できない。
``` py
# A1~Z10
it = sheet.iter_rows(1,10,1,26)
for row in it:
  print([c.value for c in row])
```
iter_rowsの引数は順番に「**最小行、最大行、最小列、最大列**」となる。

## リスト内包表記
その③でしれっと書いていたこのprintの中の部分を**リスト内包表記**という。
``` py
[c.value for c in row]
```
for文の前に変数が出てきてるのが~~とても気持ち悪い~~なんとも言えない。。。
とはいえ、これにより毎回空配列を準備してという手間がなくなるので楽になりそう。
こういうPythonの記法は学んでいかないとな・・・

## まとめ
- エクセルのセルを範囲指定してセルを取得する方法は3つある。
- その②とその③のやってることは左上と右下の把握なので、範囲が固定化されているならその②のセル名指定、柔軟に対応するならその③のイテレータを使うとよい。
- リスト内包記法というPythonの記法。
【AWS】【ハンズオン】NoSQL Workbenchで学ぶAmazon DynamoDB 

## はじめに
気がつけば6月?!
2023年も、あっという間ですね。

どーも、のぶこふです。

さて、先日、社内向けのハンズオンを実施したので、こちらでも資料を展開しようと思います。
と言っても、青い方なので、あまり推奨されないかもですが…

資料は青い方なので、コッチでは別の観点を書いていこうと思います。

## 資料
[青い方](https://zenn.dev/nobkovskii/books/d160fe953e0121)に書きました。

### 対象者
- DynamoDBのスキーマ設計をする事になったDynamoDBわからんの人

## 青い方の本との所感
青い方の本は、初めて見た時から「コレはハンズオンとかの資料に使えそうだな」と思っており、実際に書いてみての感想です。

### 構成
本という構成上、ある程度のまとまりでページ分け出来るのは良いな、と。
mainメソッドにゴリゴリ書いていくというより、privateメソッドで分割していくイメージでした。

### 書きやすさ
私は通勤時にスマホで書く事が多く、最適化されていないのは辛かったですね。反面、Qiitaは違和感なく書けて、今もスマホから書いてます。

### 読みやすさ
SEOとかわからんので、一読者としてですが、目的次第かな〜、と。
今回のハンズオンのように手順化出来るものは良いと思いつつ、調べ物してるときだと、前後ページも見ないと行けなかったりでピンポイントに情報にアクセスできないのは難しいです。

あ、単純に記事や本としての読みやすさは、両方とも好きです。

## 振り返り
改めてDynamoDBをまとめましたが、いやはややはり、RDB脳には「いや、RDBで良いじゃん」となることが、多々ありました。
そして、受講者も同じような思いがあるので、魅力を伝える日々…

スキーマ設計も、通勤時に「うーんうーん」とうなりながら考えてました。
ハンズオンということで、実際にスキーマ設計を考える時間を設けましたが、「まぁ、無理ですよね」という気持ちが90％。逆にすんなり出来たら、私のうなっていた時間を返してくれっ!!と叫びたくなりますが、交通整理が出来たと思えば100点か。
そもそも題材がRDBのほうが向いてそうなので、そういうミスはありそうです。

今回、（金銭的、作業的な）コスト面はほぼノータッチなので、実運用の際は、そこも見ていく必要があります。
ハンズオンでは、DynamoDB Localを使っているので、金銭的コストはゼロです。


## おわりに
今回は、弊社で実施したハンズオンの紹介と、ちょっとした裏話でした。

ありがとうございました。
Excelマクロでシート別にファイル分割保存する

# 1. はじめに
* Excelファイルをシート別に分割してExceelファイルに保存したい
* Excel VBAで一括で処理したい

# 2. 開発環境
* Excel for Microsoft 365 (バージョン：2304)
* Excel VBA 

# 3. 事前準備
* Excelのオプション> リボンのユーザー設定 で、開発をチェックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/d2ef17d2-f705-bc19-e938-43d703290f8a.png)

* 開発タブが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/874fb315-5e9b-5f9d-c572-ef76c1cb986b.png)

# 4. Excelマクロ
```vb: Module1.bas
'Excelマクロ
Sub SaveSheet()
    Dim shObj As Worksheet
    Dim newBook As Workbook
    Dim newBookName As String
    Dim folderParent As String
    
    'シートの保存先
    folderParent = ThisWorkbook.Path & "\"
    
    'ワークシート分
    For Each shObj In Worksheets
        
        'シートを新しいブックにコピー
        shObj.Copy
        
        '移動先のブック
        Set newBook = ActiveWorkbook
        
        'シート名
        newBookName = newBook.ActiveSheet.Range("A1") & "_" & shObj.Name & ".xlsx"
        
        '新しいブックを名前を保存
        newBook.SaveAs folderParent & newBookName
        
        '新しいブックを閉じる
        newBook.Close
    
    Next shObj
End Sub
```

# 5. 動作確認
## 5.1. サンプルExcelファイル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/57a26cc1-3ac7-bd7f-06d2-39be1649b52a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/f5459c7c-afde-9a45-f8b7-097851f83cf7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/13b0c12e-8d25-f68b-0170-5ed903423fde.png)

## 5.2. Excelマクロ実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/d131a141-db81-38da-665f-9c3118508d8f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/161b15d7-53ff-3942-09aa-e009c79ea4b6.png)

## 5.3. 実行結果
* 実行前
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/1dab802c-7b64-0eb2-8e87-c55690659e90.png)

* 実行後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/e53a9741-5374-9588-4c71-6dcfd248d2a7.png)

# 6. 参考文献

https://excelkamiwaza.com/sheets_save.html
Voice 及び MMS の認証機能が変更される件

# はじめに

みなさん、こんにちは。

今回は、本日Twilioから届いた以下のタイトルのメールについて、例の通り英語で分かりづらいので解説記事を書きました。
`[Breaking Change] Enforcing HTTP Authentication for Call Recordings and MMS Media, Effective July 31, 2023`

## 対象

Voice および MMS を使って、メディアファイル（録音データなど）を Twilio からダウンロードする際に、HTTP認証が必須になります。日本では MMS　は使えませんので、主に **Voice で録音をしているユーザーが対象** になります。

## 変更内容

現在、Voice で録音をすると、録音データはまず Twilio 上に保管されます。録音データにはそれぞれ`recordingUrl`が設定され、そのURLを使ってデータをダウンロードすることができます。
このとき、デフォルトの設定では認証機能が無効になっているため、URL を知っている第三者が録音データにアクセスすることが可能になっています。
そのため、URLアクセス時に HTTP 認証を強制することができるようになっており、強制するかどうかは、管理コンソール上のVoice設定画面で設定することができます。

Voice > Settings > General
![スクリーンショット 2023-06-09 6.49.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/9c219f51-fabd-5b2f-9f93-2b7b1b0e2751.png)


今回の変更で、2023年7月31日（日本時間だと8月1日午前9時）以降に作成される新規アカウントについては認証は必須となり、この設定を無効（Disabled）にすることができません。
すでにお持ちのアカウントで、この設定をすでに有効（Enabled）にしている方は、今後無効にすることができなくなります。また、同じくすでにアカウントをお持ちの方で、現在設定が無効になっている方は、設定自体は7月31日になっても**強制的に有効にはなりません。** ただし、セキュリティ上、有効にすることをおすすめします。

:::note info
認証方式は、ID/PassのBasin認証となります。
AccountSidとAuthTokenの組み合わせでもいいですが、API KeyとAPI Secretの組み合わせを使うことをおすすめします。
:::


## 影響範囲の確認

まずは現在の設定状況を確認してください。
その上で、設定が無効になっている方は、7月31日までに一度設定を有効にしていただき、現状のシステムで不具合が出ないことを確認してください。不具合が出ないようであれば、設定は有効のままにしておきます。

もし不具合が出るようであれば、ダウンロードのために認証機能を実装する必要があります。

axios を使った場合の例はこんな感じです。
```javascript
    try {
      // Download from Twilio
      const res = await axios({
        method: 'GET',
        url: `${recordingUrl}.wav`,
        responseType: 'blob',
        auth: {  // Basic認証
          username: TWILIO_API_KEY,
          password: TWILIO_API_SECRET,
        },
      ・・・
      });
    } catch (err) {
      // エラー処理
      ・・・
    }
```

もしくは、以下のように`recordingUrl`に認証情報を付加することもできます。

`https://<TWILIO_API_KEY>:<TWILIO_API_SECRET>@<recordingUrl>.wav`

# まとめ

今回の仕様変更では、既存のユーザーが設定を無効のままで使い続けることは可能ではありますが、新規アカウントでは強制的に有効となりますし、セキュリティ上も好ましくないので、設定は変更しておくことをおすすめします。

---
自己紹介|　
:--|:--
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/b51a8b88-abd5-ce5e-195a-de3564ba2ae6.png" height='200' width='150'/>|高橋克己（Katsumi Takahashi） 自称「<font color='red'>□い芸人</font>」<br />グローバル・インターネット・ジャパン株式会社　代表取締役<br />株式会社KDDIウェブコミュニケーションズ　コミュニケーションDX事業部エバンジェリスト<br /><br />2001年より大手通信事業者の法人サービスの教育に携わり、企業における電話のしくみや重要性を研究。2016年よりKWCにジョインし、Twilioを使ったスマートコミュニケーションの普及活動を精力的に行っている。<br />2015 Hall of Doers<br />2019 Twilio Champions
記事投稿者名前が表示されない？『.presence』で解決です。

Ruby on rails を学習中の方の参考にしてもらえたら嬉しいです。
アプリケーションを作成している時に出てくるエラーとその解決方法について掲載します。少しでも参考にしていただけると幸いです。
今回はエラーの解決方法ではなく、アプリ開発での新発見について備忘録として書き残しておく。

## 今回の事象を解説
今回は記事投稿アプリで記事作成した際に **ユーザーの名前が表示されない** と言う事象を解決していきます。今回はrailsでエラーが出ていたわけではなく、表示崩れが起きているという現象です。
私の当初の想定ではプロフィールを変更しなければ会員登録した際のメールアドレスの＠の前の文字列がユーザーネームとして表示される想定でした。
しかし、一度プロフィール編集画面を開き、保存ボタンを押してしまうとユーザーネームを編集していなくても空の文字列として編集されてしまいました。
こうなると下の画像のようにユーザーネームが空のまま保存され、記事投稿者の名前が何も表示されなくなります。
これでは使い勝手が悪いので、ユーザーネームが空の場合はメールアドレスの＠の前の文字列をユーザーネームとして表示させることにします。

▼本来は以下の画像のようにユーザー名に登録したメールアドレスの『＠』の前の文字列が表示されるはず。
![スクリーンショット 2023-06-09 6.34.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3356902/23ea7497-8a10-d086-95f6-1e933e0c1f05.png)


▼しかし、編集ページでユーザーネームの欄を空のまま保存すると以下のように名前がなくなってしまう。
![スクリーンショット 2023-06-09 6.37.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3356902/40227919-9172-9d42-ac82-e8618abc2fdb.png)


この事象を解決していきます。


## 結論から話します
![スクリーンショット 2023-06-09 5.59.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3356902/ee246a17-c678-a90c-f576-e7baf79516e2.png)
画像のように 『**.presence**』をつけると解決します。対象コードは以下に貼っておきます。
```html:model > user.rb
def display_name
  profile&.nickname.presence || self.email.split('@') .first
end
```
このコードは`display_name`と言うメソットを定義しています。内容はprofileのnicknameがあればそれを表示させるが、なければ登録したメールアドレスの@マークの前の文字列を表示します。と言う内容になっています。
そこに`.presence`を足しておくと解決します。

## 内容を解説します。
`.presence`をつければ良いということは分かったが、なぜ？ということが知りたい方はここから詳細を解説していきます。
例によってChatGPTを使って問題を特定していきます。
まずはこのメソッドの解説を求めます▼
![スクリーンショット 2023-06-09 6.25.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3356902/a7020f7d-fb5a-9140-1d68-7df31540a8c1.png)
解説の詳細は画像のとおりです。

そして、プロフィールページのnameを空で編集を保存しても空のままが表示されないように『**.presence**』をつけるように提案がされました▼
![スクリーンショット 2023-06-09 6.01.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3356902/b38e8e48-f6c7-47ef-ad9c-219bb04db278.png)

## 最後に
ということで、記事投稿者の名前を表示したいときは
```html:model > user.rb
def display_name
  profile&.nickname.presence || self.email.split('@') .first
end
```
と、メソッドを定義してあげれば良くて、編集ページのネーム欄を空で保存した場合にユーザーネームが表示されなくなってしまうという現象には`.presence`をつけてあげれば解決しました。

いかがでしたでしょうか？
他にも記事を発信していきますので、私の QiitaやTwitterをフォローしていただけると嬉しいです。
個別の質問もぜひ歓迎します。
私自身、初学者ではありますが、1歩先を行くものとして回答できたらと思います。
それでは。
おっ、 CSS でゲルフォントの定数が使えるじゃん

## この記事の概要

完全にネタです。
「CSS でそんな数が扱えるの？」と思われるような数を探していて、 1 つ見つけたので記事にしました。

## ゲルフォントの定数とは

Wikipedia より引用します。

> ゲルフォントの定数（ゲルフォントのていすう、英語: Gelfond's constant）は数学定数の一つで、ネイピア数 e と円周率 π を用いて e<sup>π</sup> と表される数である。

https://ja.wikipedia.org/wiki/%E3%82%B2%E3%83%AB%E3%83%95%E3%82%A9%E3%83%B3%E3%83%88%E3%81%AE%E5%AE%9A%E6%95%B0

## `calc` における数値定数

`calc`の中では、自然対数の底の `e` と円周率の `π (pi)` が使用できます。
ちゃんと仕様で定められています。

https://drafts.csswg.org/css-values/#calc-constants

## 冪乗を表す `pow()` 関数

`pow()` 関数には、カンマ区切りで2つの`<number>` A と B を入力します。
A を B の冪乗にした結果が `<number>` として帰ってきます。

:::note warn
2023/6/9 現在、 Safari と Firefox でしか使えません。
:::

## ゲルフォントの定数を表すためには

```css
.gelfond {
  width: calc(pow(e, pi) * 1px);
}
```

例では `width` を使っていますが、 `height` でも `border-radius` でもなんでも構いません。

単位なしの数値だけが返ってくるので `1px` を掛けていることに注意してください。
（ただし、 `line-height` に使うのであれば `calc(pow(e, pi))` だけで足ります）

## 最後に（そして、お詫び）

実用性は皆無です。
ご了承ください。

---

最後まで読んでくださってありがとうございます！
[Twitter](https://twitter.com/xrxoxcxox)でも情報を発信しているので、良かったらフォローお願いします！

[Devトーク](https://jobs.qiita.com/employers/qiita-inc/dev_talks/489)でお話してくださる方も募集中です！