OmniAICreator/Qiita-1.07M huggingface dataset:
AWS認定取得を目指す全人類の味方「CloudLicense」の勉強法！

:::note warn
2023年の9月に、`TechStock`から`CloudLicense`へと名称が変更されたようです。それに伴い、タイトルや記事の内容を修正しました。
:::

:::note warn
2025年6月追記：`CloudLicense`の信頼性を疑う文献がいくつか確認できたため、本記事のOrganization紐付けを解除いたしました。発言は個人のもので、所属組織などとは一切関係ございません。ご利用は自己判断でお願いします。
:::

# はじめに
AWS認定資格の取得に励む方々なら誰もが知っているであろう、AWS認定資格特化のWEB学習サイト「**CloudLicense**」（旧名：koiwa club、TechStock）。

私も受験のたびにお世話になっているのですが、実は最近色々と学習機能が追加されてきており、以前よりもこちらのサイトを活用した学習がしやすくなってきております。

対策としてはよく名前を挙げられている本サイトですが、その勉強法に関する記事は見たことがなかったので、今回はCloudLicenseでの勉強法について紹介したいと思います。

# 対象者
**AWS認定資格の取得を目指す全人類**

また、私の取得状況としては、
- Cloud Practitioner (CLF)
- Developer - Associate (DVA)
- Solutions Architect - Associate (SAA)
- DevOps Engineer - Professional (DOP)

の4つになります。
これらの学習を通じて、CloudLicenseは旧名時代から活用してきております。

# CloudLicenseとは？
冒頭でも軽く述べましたが、AWS認定資格に特化したオンライン学習サイトになります。
2022年の9月に「TechStock」へ名称が変わりましたが、以前は「koiwa club」の問題集と呼ばれておりました。
**※追記：2023年の9月に、`TechStock`から`CloudLicense`へと再度名称が変更されたようです。**

https://cloud-license.com/

扱われている問題の内容が非常に本番に近い印象で、対策としてこの問題集はかなり有用であると感じております。

質だけでなく問題の数も豊富であり、資格の種類にもよりますが一資格あたり500~1000問前後は解くことができます。

# 主な学習機能
実際に活用してきて便利だった機能をいくつか紹介します。
2023/7/17現在の機能になります。

## 間違った問題のみを表示
自分が過去に解いた問題は学習履歴から確認できるのですが、その中でも自分が間違えた問題のみを振り返ることができます。

ただ、**直前の一回で間違えた問題しか絞り込めない点には注意**が必要です（一回解き直して正解になったら絞り込めなくなる）。

## お気に入り登録
問題を解いた際に、自分でその問題をお気に入り登録することができます。お気に入りに登録した問題も学習履歴から絞り込みが可能です。

また、お気に入りの中にも種類があり、

- お気に入り①
- お気に入り②
- お気に入り③

の3カテゴリに分類して問題を管理することができます。
例えば、問題Aを「お気に入り①」に登録し、問題Bは「お気に入り②」に登録する、といったことが出来ます。
一つの問題を複数のお気に入りに登録することも可能です（例：問題Aを「お気に入り①」と「お気に入り③」に登録）。


## 本番形式モード
全ての問題の中から、本試験と同じ問題数をランダムに選択して出題してくれます。
本番と同じように制限時間も設けられるため、試験当日のリハーサルとして活用できます。

# 勉強法

直近で私が取得したのはSAAなのですが、以下のような流れで学習を行いました。

1. **新しく追加された側**の問題から1周目に取り組む（何問解くかは自分の学習期間と相談）。
    - 出題範囲がアップデートされるにつれて問題も追加されているため、新しい側から解いていく方が最新の出題範囲に対応できる。
    - **正解した問題のうち、もう一度解きたいと思った問題はお気に入り①に登録**しておく。
2. 間違えた問題のみを解き直す。
    - **正解した問題のうち、もう一度解きたいと思った問題はお気に入り②に登録**しておく。
3. お気に入り①に登録した問題を解き直す。
    - **見直し不要と判断した問題はお気に入りから解除**する。
4. お気に入り②に登録した問題を解き直す。
    - 一度間違えている問題なので内容は入念に確認する。
    - **見直し不要と判断した問題はお気に入りから解除**する。
5. 間違えた問題やお気に入りの問題が無くなるまで、2~4を繰り返す。
6. 本番形式モードで当日を想定したリハーサルを行う。

他にも公式の模擬試験を解いたりはしましたが、CloudLicenseを活用した勉強法は上記の通りです。

DVAやDOPの取得で元から知識がストックされていた面もあるとは思いますが、過去に取得した4つの中でも最も学習期間が短く済んでおり、それなりに効率的な勉強法に仕上がっているのではないかと思います。

# 最後に
今回はCloudLicenseでの勉強法について紹介してみました。
AWS認定資格の取得を目指す皆様の参考になれば幸いです。

また、DOPについては合格体験記も残しておりますので、興味があれば覗いてみてください。

https://qiita.com/jinto/items/99d9a93636816141099d

私はAWS6冠を目指して残りの2つも学習していきますので、一緒に頑張りましょう！

以上
Hyper-Vの仮想スイッチとは

## 仮想スイッチとは
仮想マシンが他のコンピュータと通信するために必要になるのが仮想スイッチです
仮想マシンのネットワークアダプターに対して1つの仮想スイッチを指定できます
仮想スイッチを設定することで、ネットワークに接続することが可能です

## スイッチとは
複数のコンピュータやLANの接続を行うネットワーク機器です
L2スイッチ、L3スイッチと呼ばれる2つのタイプのスイッチがあります

### L2スイッチ
OSI参照モデル第2層のデータリンク層で動作するスイッチです
MACアドレスを元にフレームの転送を行い、相互通信します

### L3スイッチ
第3層のネットーワーク層で動作するスイッチです
IPアドレスをもとにパケットを転送して、相互通信します

## 仮想スイッチの種類
| 接続の種類   | 説明                                                                                                                                                                                                                                                                                             | 
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | 
| 外部         | 物理ネットワークにアクセスして、外部ネットワーク上のサーバーやクライアントと通信するアクセス権を仮想マシンに付与します。 同じ Hyper-V サーバー上の仮想マシンの相互の通信を許可します。                                                                                                           | 
| 内部         | 同じ Hyper-V サーバー上の仮想マシン間、および仮想マシンと管理ホスト オペレーティング システム間の通信を許可します。                                                                                                                                                                              | 
| プライベート | 同じ Hyper-V サーバー上の仮想マシン間の通信のみを許可します。 プライベート ネットワークは、Hyper-V サーバー上のすべての外部ネットワーク トラフィックから分離されます。 この種類のネットワークは、分離されたテスト ドメインなど、分離されたネットワーク環境を作成する必要がある場合に役立ちます。 | 

引用：https://learn.microsoft.com/ja-jp/windows-server/virtualization/hyper-v/get-started/create-a-virtual-switch-for-hyper-v-virtual-machines

外部を選択した場合は、使用するネットワーク アダプター (NIC) を選択します

以上、Hyper-Vの仮想スイッチについてまとめました

## 参考文献
- [Microsoft. HYPER-V 仮想マシン用の仮想スイッチを作成します。.](https://learn.microsoft.com/ja-jp/windows-server/virtualization/hyper-v/get-started/create-a-virtual-switch-for-hyper-v-virtual-machines)
製造業で活躍するデータサイエンティストへの道：私のキャリアパスとスキルセット

# はじめに
この記事では、私がどのようにして製造業のデータサイエンティストになったのか、その経緯と日々の業務、そして自己研鑽について詳しく説明します。
私の経験が、これからデータサイエンティストを目指す方々の参考になれば幸いです。

# 大学院時代：画像解析の研究からスタート
私のデータサイエンティストとしてのキャリアは、大学院での研究から始まりました。
私は細胞を認識するための画像解析に取り組み、その経験が後のキャリアに大いに役立ちました。
この経験から、データを解析し、有用な情報を抽出する技術の重要性を学びました。

# 入社1年目：新商品開発と業務効率化
大学を卒業後、私は大手製造業の会社に入社しました。
この会社では医療・ヘルスケアの分野の新商品開発に力を入れており、その新商品開発部門に配属されました。
私が担当したのは、開発中の製品の社外実験のセンサデータ分析でした。
当初はデータの取得から分析までの工程が手動で非常に時間がかかりました。
しかし、Pythonを独学で学び、データ取得からグラフ作成、PDFまとめまでを自動化するツールを開発。
これにより業務の効率化を実現しました。
この経験から、プログラミングスキルが業務効率化に大いに貢献できることを実感しました。

# 入社2年目：リアルタイムデータ視覚化とアルゴリズム開発
2年目には、社内実験用のデモ製品のセンサデータをリアルタイムに視覚化するアプリケーションを作成しました。
これにより、社内実験の効率を大幅に向上させました。
また、自社製品のアルゴリズム開発を担当し、半年で新製品をリリースすることができました。
さらに、製品の精度を上げるためにAIの学習を始めました。
これらの経験から、技術の進歩が製品開発にどれほどの影響を与えるかを深く理解しました。

# 入社3年目：AIの学習とデータサイエンティストとしての成長
3年目には、大学のAIの研究室に通い、AIの座学と実装方法を学びました。
この時期からデータサイエンティストとして社内で呼ばれるようになり、AIアルゴリズムを搭載した自社製品のバージョンアップ版をリリースしました。
この経験から、理論と実践のバランスが重要であることを学びました。

# 入社4年目：製品の精度向上と社内教育
4年目は、さらなる製品の精度向上に向けた取り組みを主な業務としました。
AIプロジェクト(社内でのAI活用推進)の初期メンバーとして他部署の方がAIを導入したいという課題に対して、一緒になって導入の手助けを行う活動も行いました。
さらに、社内教育活動にも従事し、Pythonプログラミングやデータの分析の仕方についての若手向けの教育を行いました。

# 自己研鑽とスキルアップ
私はデータサイエンティストとして働いていますが、データサイエンティストは会社ごとに行う業務内容や必要な知識、使用するデータが異なるため、一般的なデータサイエンティストが持つべきスキルを学び直し(couseraなど)、Kaggleのコンペに参加して製造業では扱わないデータの分析も行うことで日々自己研鑽しています。

# 私が持つスキル
私がこれまでに習得したスキルは以下の通りです：
* Python
* R
* Jupyter Notebook の使用
* クラウドデータベース
* RDS(リレーショナルデータベース管理システム)
* SQL
* 予測モデリング
* データ分析
* データ可視化（DataViz）
* モデル選択
* ダッシュボードとチャート作成
* 機械学習
* ディープラーニング
* GitHub
これらのスキルは、業務の効率化、新製品の開発、データのリアルタイム視覚化、AIアルゴリズムの開発といった業務に活用されています。

# おわりに

私のキャリアパスは、大学院での研究から始まり、大手製造業の会社での新商品開発、データ分析、AIの学習といった経験を経て、現在のデータサイエンティストのポジションに至りました。
これまでの経験から学んだことは、新しい技術を学び、それを業務に活用することで、業務の効率化や製品の品質向上を実現できるということです。
これからも技術の進歩とともに自己研鑽を続け、より良い製品開発に貢献していきたいと思います。
webupapiを使用したバッチ処理その2

# 前回に引き続きWebuiをブラウザから使うと切り替えが面倒な処理をバッチ処理にしてみました。<br>今回はサンプリングメソッドの効果を確認するためのバッチ処理です
## 前提条件とか使い方のイメージは前回の記事を見てください
https://qiita.com/jsakamoto65535/items/3c7535f29ef98d13d165

## サンプルコード
画像の出力枚数は モデル数 x サンプリングメソッド数 x batchCount
TODOの個所を好みで変更してください。

~~~ python
# Stable diffusion Web UI をPythonから実行
# 注意点：エラー処理をまったく入れていないのでGUIで出力可能な設定を調べてから設定してください
import webuiapi
import datetime
import os

# -------------------------------------------------------------------------------------------------------------
# 
# - 生成条件 -
# TODO:ベースプロンプト:よく使うプロンプトを入れてください
myBasePrompt = "(masterpiece, best quality:1.2)" 
#TODO:追加プロンプト：よく切り替える部分を入れてください。プロンプトはベース+追加で指定されます
myPrompt="pretty face:1.3, glasses, anime, (makeup,lipstick,eyeliner,mascara,eyeshadow:1.1),dark skin,maid, maid apron, maid headdress,nipples, small boobs,spread legs,cum in mouth,cryingtears,facial,cum in pussy,excessive cum" 
# サンプリングメソッドの違いを見るにはseed固定がよいのではないか
mySeed = 65535
myNegativePrompt ="worst quality, low quality, normal quality, ugly, out of focus, blurry, bad anatomy, missing arms, deformed mutated disfigured, mutated hands, missing fingers, inaccurate limb, deformed eyes, disconnected limbs, animal ear, multiple legs, malformation, multiple arm, EasyNagative"
myHeight = 768
# TODO:インストール済みのモデルのうちどれを出すか定義する
executeModels=[
    'yabalMix_v5.safetensors [a21055baa2]',
    'AOM3.safetensors [d124fc18f0]', 
    'anything-v4.0-pruned.safetensors [69528490df]', 
    'bra_v5.safetensors [ac68270450]', 
    'majicmixRealistic_v4.safetensors [d819c8be6b]',
    'xeroxrealmix_v35.safetensors [d7700eac56]'
    ]
# TODO:好きな出力先フォルダを指定
outputPath="./"
# TODO:1つのモデルに対して出力するファイル数
batchCount = 3
# -------------------------------------------------------------------------------------------------------------

api = webuiapi.WebUIApi()

#現在のモデル取得→後で元に戻す
restoreModel = api.util_get_current_model()
print(restoreModel)

# 入っているモデルを調べるときにプリントしてみる
#myModels = api.util_get_model_names()
# print( executeModels )
# sampling methodは使えるものすべて試す
mySamplers = api.get_samplers()

# 全体スタート
#フォルダ作成
startTime = datetime.datetime.now()
imageFolder = outputPath + startTime.strftime("%Y%m%d_%H%M%S")
print( "Create Folder:" + imageFolder )
os.mkdir( imageFolder )



# モデルぶん回す
for currentModel in executeModels:
    # set model (use exact name)
    api.util_set_model( currentModel )
    # sampler数ぶん回す
    for mySampler in mySamplers:
        # バッチ数ぶん回す
        seqNo = 0
#        print("sampler=" + mySampler["name"])
        for outputCount in range( batchCount ):
            resultApi = api.txt2img( prompt= myBasePrompt + myPrompt,seed = mySeed, negative_prompt = myNegativePrompt, sampler_index = mySampler["name"],  height=myHeight )
            # ファイル名はモデル名+日時+連番→自由に
            curTime = datetime.datetime.now()
            imageName = imageFolder + "/" + currentModel + "_" + mySampler["name"] + "-" + str(seqNo) + ".png"
            seqNo = seqNo + 1
            print("Create File:" + imageName)
            resultApi.image.save( imageName.replace(' ','') )

# モデルを元に戻す
api.util_set_model( restoreModel )
~~~
2023/07 Glueについて〜１章〜（全体像の把握編）

# 執筆にあたって
弊社では、S3に保存されているデータをRDS（MySQL）にimportする際に、LambdaやECSを用いておりました。
この作業をAWSのサービスの一つである「Glue」で行うように変更することが決まりました。
それに伴って情報のキャッチアップを行なっていたのですが、Stepfinctionsと合わせて運用されている記事で、lambdaを使って実装されていたり（今回は直接実行をしたい）、古めの記事や内容のものが多かったので、新しい情報を纏めようと思いました。
また、これらの記事の全肯定はGlue crawlerの作成→実行、Connectorの作成、Jobの作成→実行の全行程を網羅的に記述していくつもりです。
初心者でもGlueの実行までができるようになることを目標としています！
コンソール上でJob実行まで出来ればいいよーって人は２章から読んでもらえたらと思います！
※現在は検証段階なので、記事の内容が「全て正しい」、あるいは「ベストプラクティスである」というわけではありません。
※以下、本記事においては、RDSはMySQLと同義とします。

# この記事におけるGlue活用の目標
S3に保存されているデータをRDSにimportする際に、lambdaやECSを使わずに、GlueとStepfunctionsだけを用いて完了させることを目標としています。
以下、具体的にimportに必要なGlueの操作をまとめます。

・Glue crawlerの作成
・Glue crawlerの実行
・Glue jobの作成
・Glue jobの実行

Glue crawlerはS3のファイルとRDSに対して実行するものであり、データの構造等の情報を取得し、データカタログを作成することです。crawlerの作成はコンソール画面やLambdaでも行うことができますが、今回はコンソール上で作成し、それをStepfunctionsでinputを渡し、直接実行していく方法をとります。

Glue jobの実行は、crawlerの作業で作成されたデータカタログをもとにS3ファイルを直接RDS内にimportします。crawler同様、jobはコンソール画面で作成・設定後、Stepfunctionsで直接実行していく形式を取ります。


# Stepfunctions上の設計図
![スクリーンショット 2023-07-16 23.25.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004597/85711bb6-169d-f494-e8fc-9198de3b4670.png)

上記は想定のイメージ図です。（実際はエラー時の切り分けを行いやすくするために、ちょこちょこ条件を追加します）
PassStateの部分は適宜変更を加えていきます。
以下、この設計に至った解説を行います。

・startCrawler→GetCrawler→is Runnning?→Wait for Crawler To Complete
すでに作成してあるcrawlerにinputを与え、startCrawlerで実行します。
それに対して、GetCrawlerで処理状況を確認していきます。
2023/07現在では、crawler作業は非同期でしか実行することができないため、処理中か否かで条件分岐を行い、「〜分待って、再び処理状況を確認する」の処理を加えます。

・Glue StartJobRun.sync→status
crawlerのoutput（データカタログ）を受け取り、GlueJobの実行を行います。
こちらは同期実行、非同期実行のどちらでも行うことができます。
（同期実行を行いたい時は、コードスニペットの"Resource": "arn:aws:states:::glue:startJobRun"の最後に「.sync」を加えれば良いです）
今回は同期実行で、Jobが終了したら処理を進めるように設計しています。
同期実行なので、timeoutの設定は忘れずに。

また実行ステータスはSTARTING、RUNNING、STOPPING、STOPPED、SUCCEEDED、FAILED、ERROR、WAITING、TIMEOUTがあります。

参考：https://aws.amazon.com/jp/blogs/news/orchestrating-aws-glue-crawlers-using-aws-step-functions/
実行ステータスについて：https://docs.aws.amazon.com/ja_jp/glue/latest/dg/job-run-statuses.html

また、余談ですが同期実行と非同期実行で処理遅延時間が異なってくるそうです。
詳しくは下記のQiita記事が参考になります。
【AWS】.syncを使わずにStep FunctionsからGlueJobを実行してみた【性能改善】
https://qiita.com/toru_yamashita/items/a2ecc1f29fbbce5e4344
非同期だと平均６sの処理が、同期だと平均41sぽいです。

次章では、Glue自体の検証や仕様についてのあれこれをまとめていきたいと思います。
新PCへのssh鍵お引越しメモ

## まえがき

個人の学習用に使っているリポジトリのssh鍵を新しい端末へ引き継いだので、作業内容をメモ書きとして残します。

## 手順1. ssh秘密鍵&公開鍵を移行先PCヘコピペ

移行元の `~/.ssh` にある `id_rsa` と `id_rsa.pub` をコピーし、移行先の `~/.ssh` にペーストします。

私はUSBメモリを利用してコピペしましたが、セキュリティ観点からインターネット経由でのコピペは控えた方が無難かと思います。

## 手順2. パーミッション変更

秘密鍵にはプロテクトがかかっている必要があるので、パーミッションを変更します。
`chmod` コマンドを使って `id_rsa` を `「所有者のみ読み書き可能」(600)`な状態にしましょう。

```bash
# 変更前のパーミッションを確認
% ls -l ~/.ssh/id_rsa
-rw-r--r--@ 1 UserName  staff  3430  7 16 23:44 id_rsa

# 所有者のみ読み書き可能なパーミッションへ変更
% chmod 600 ~/.ssh/id_rsa

# パーミッションの変更を確認
% ls -l ~/.ssh/id_rsa
-rw-------@ 1 UserName  staff  3430  7 16 23:45 id_rsa
```
AWS初心者こそ #AWSGameDay に参加しよう！

ジャーニーマン( @beajourneyman )です。

4年強寝かしていたQiitaを再始動しました。再始動1本目は「AWS Dev Day 2023 Tokyo」のゼネラルセッション、2本目は同ブレイクアウトセッション・クロージングセッションについてまとめました。

https://qiita.com/beajourneyman/items/04ce3b08ed358f7d4722

https://qiita.com/beajourneyman/items/55d1c562c39667758b8b

今回は AWS Summit Tokyo 2023 と　AWS Dev Day 2023 Tokyo で「AWS GameDay」に参加した経験から、経験1年未満の初心者だからこそ、オススメしたいポイントをまとめます。

# GameDay とは

> AWS GameDay は、ある課題に対して AWS サービスで解決するための対応力や実装スキルを試せる実践形式の人気ワークショップです。 3 – 4 名でチームを結成し、待ち受けるさまざまなトラブルやクエストをクリアしながら最終ミッション達成を目指します。

https://aws.amazon.com/jp/blogs/news/aws-gameday-at-aws-summit-2023/


# GameDay 初参加を決めた2つのきっかけ

AWS初心者ですが、GameDay に飛び込んでみました。AWS Summit 2023が初回でした。強く背中を押してくれたのはAWS HERO Shingoさんのre:Inventに参加する方に贈るブログです。全部で68項目あるうちの53番目が以下です。

> [53]GameDayは参加しろ：チケット代の半分以上はこれだと思え、テメーのできなさに心の底から打ちひしがれろ。それでもがむしゃらにあがけ。お前は打ちひしがれるかもしれないが実は結構スコアは出る。そう、そもそも求められるレベルが高くて難しいのだ。明日のお前の成長はここから始まる。

https://yoshidashingo.hatenablog.com/entry/2022/12/04/213746

もうひとつ背中を押してくれた報せがあります。ゆかりのある若手エンジニアが AWS　Summit 1日目の AWS Jam に参加して2位入賞したと聞いたからです。GameDay参加前日の懇親会の時に、知り合いのスタートアップCTOから伺いました。同じチームで戦っていたそうです。

実質AWS経験半年で歯が立たないであろうコトは容易に想像がつきましたが「いい年をこいて恥をかきたくない」が理由だとしたら情けないというかつまらないな、そう思いました。そして、初心者なのに学ぶコトから逃げていては成長はないとも思いました。

# 初回参加は突然に

初回は、AWS Summit 自体に参加できるか直前まで確定しなかったので、既に定員が満席でした。結果、待機列に並んで最後のひとりで滑り込んだ形でした。ひとつ前の順番の方がクラスメソッドさんの　AWS Top Engineer の方で、プロ野球の試合に素人が参戦している状態なのだなと自分自身の無鉄砲さに呆れたのを覚えています。待機列に並んでいる時に、何度かスタッフの方が人数を数えに来て、力不足なのに待機列に並び向き合えた自分と「待機列が自分のひとつ前で切れてしまえ」と思う逃げたい自分が入れ替わり立ち替わり現れていました。

開始時間間際になって、スタッフの方が「ご参加いただけますので会場にお入りください」と言った趣旨の声をかけてくれました。参加確定の瞬間「出番がきちゃったか」と、一気に不安が吹き出しました。

# 初参加の結果

* 「テメーのできなさに心の底から打ちひしがれろ。」
* 「それでもがむしゃらにあがけ。」

この言葉がずっと自分を鼓舞してくれました。4名の野良チームの自己紹介から始まり、呼称を決めて、対応するクエストをひとりずつ選びました。ファシリテーションは自分がしました。AWSの能力はないので、PM経験だけは長い自分だからできるコトで貢献しようと思ったからです。

クエストは、普段触らないサービスにすると決めていました(なまじ知っている内容で苦しまずに出来ては意味が半減するため)。詳細は口外できないので触れませんが、触りだけお伝えすると全く知見のないゴリゴリのML系でした。スタートから躓いて、太刀打ちできず、PCをタイプする手が小刻みに震えていました。まず、チームメンバーに聞きましたが全員知見がありませんでした。クエスト文の頭から知らない単語だらけだったので、検索しまくりました。調べても調べても1つ進むと躓くを繰り返していました。サポートSAさんの力を借りて、それこそ、がむしゃらにあがきました…。ここ数年で最も集中して取り組んだと思います。いわゆる"脳汁"が出る状態でした。

制限時間1時間弱を残して担当分がクリアできました。

チームはベテランのAさん、数年経験のBさん、同じくらいの初心者のCさんのチームで、結果は16チーム中5位でした。1クエストクリアできなかったのが結果に響きました。

「テメーのできなさに心の底から打ちひしがれろ。」まさにその通りでした。

# AWS Dev Day 2023 Tokyo では AWS GameDay Solo.version が登場！

初参加から約2ヶ月、あの"脳汁"体験に再び身を投じる日が来ました。今度はSolo.ver、ひとりです。新たな試練が与えられました。初日のゼネラルセッションが終わり、会場内で販売された弁当を食べたら、直行しました。受付番号は7番目だったと記憶しています。

> ゲーム感覚で楽しめるクエストクリア型ワークショップ 「AWS GameDay」。 AWS Dev Day では一人でも参加でき、空き時間にミッションをクリアできるおひとり様向けの「AWS GameDay Solo version」を開催します。

https://aws.amazon.com/jp/events/devday/japan/

# 2度目の挑戦と結果

今回はひとりで6クエストです。その中でも、また全く知見のない画像系のサービスのクエストを選びました。まずは AWS CLI をセットアップして、問題の趣旨を見読み違えてどんどんマイナスポイントが貯まったり、間違ったAPIを叩いたり、正しいサービスに辿り着いても、コードのデバックが1ステップクリアしてはCloudWatchでログを見て潰す繰り返しでした。結果、6時間戦って1クエストだけクリアしました。22人中18位でした。

またも「テメーのできなさに心の底から打ちひしがれろ。」まさにその通りでした。

# ふりかえりと今

単純に知的興奮に溢れています。少しでもエンジニアリングに関わったコトがある方なら分かるのではないでしょうか。そして、「それでもがむしゃらにあがけ。」の通り、1分1秒を大事にし集中する瞬間があります。まず、これだけで十分に参加する価値があると思います。

そして、AWSとがっぷり四つで向き合う体験は、意識を変えるには十分な濃度と密度があります。今、自分は、自社の取り組みで、個人個人でAWSの研鑽を積む社内コミュニティに参加しています。最後にもう一言、AWS HERO Shingoさんのエールを引用します。

「明日のお前の成長はここから始まる。」

以上です。
ReactでCSS Modulesを使う

## はじめに
これまでフロントエンドはSassとBEMを組み合わせてクラス設計していたのですが、BEMは`block__element--modifier`という風にクラス名が長くなりますし、個人的にBEMの運用で悩む場面がかなり多かったです。
そして今回Reactを学習する機会があり、`CSS Modules`がとても便利だったので記事に残そうと思います。

## 使い方
今回はSassを使うのでまずはインストールします。
```bash
npm install sass
```

末尾に`.module.scss (css)`を付与したファイルを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3340928/61481466-ec10-1ece-5b6c-e22cb33973c7.png)
コンポーネント内で先ほど作成したファイルをインポートします。
```js:App.js
import styles from "./App.module.scss";
```

`JSX`の中でクラス名を指定します。
```js:App.js
<div className={styles.container}>
...
```

`.scss`ファイルではいつも通りスタイルを指定します。
```scss:App.module.scss
.container {
...
```
ここまででブラウザの開発者ツールで確認してみると、下記の様なクラス名が付与されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3340928/d9dd498f-613c-1385-4be6-79e44c4cc410.png)
`ファイル名_クラス名_ハッシュ`というルールで命名されます。これでクラス名の衝突を防ぐことが出来るわけなんですね。クラス名で悩むことがぐっと減りそうです。

## あとがき
今回CSS Modulesを使うにあたって色々調べたのですが、他にも本当にたくさんのスタイリング方法があってどれを使うべきなのか悩ましいですね。他にお勧めの方法があればぜひ教えていただきたいです。
【Linux】一定期間経過したディレクトリやファイルを削除する方法


## ファイルの削除
以下のように`find`コマンドを使用して一定の期間が経過したファイルを削除します。

```zsh
find /path/to/dir -name '*.log' -mtime +30 -delete
```

上記を実行すると対象ディレクトリの`.log`ファイルのうち最終変更日から30日経過しているファイルを削除します。

`-mtime`の部分を変更することで期間の起算日を変更できます。
使用可能なオプションは以下のとおりです。


| オプション|説明|
|:-----------:|:------------|
| -mmin|最終変更日時から（分）|
| -mtime|最終変更日時から（日）|
| -amin|最終アクセス日時から（分）|
| -atime|最終アクセス日時から（日）|
| -cmin|データとステータスの最終変更日時から（分）|
| -ctime|データとステータスの最終変更日時から（日）|


また数字の前の`+`の部分には`-`を指定したり指定しないことができます。

| オプション|説明|
|:-----------:|:------------|
| + |過去から指定した数字までに|
| - |現在から指定した数字までに|
| 指定なし |指定した数字前に|

- 30日前までに変更された

```zsh
-mtime +30
```

- 現在から30分前までに変更された

```zsh
-mmin -30
```

- 30日前にアクセスされた
```zsh
-atime 30
```

## ディレクトリの削除
上記の方法では空ではないディレクトリを削除することができません。
中身のあるディレクトリを削除するには以下のように実行します。

```zsh
find /path/to/dir -type d -mtime +30 | xargs rm -fr
```

上記を実行すると最終変更日から30日経過しているディレクトリを削除できます。
Railsアプリケーションの環境変数を確認する方法

## 手順
### 1. rails console を起動
```shell_session
$ rails console
```

### 2. ENV オブジェクトを確認
```irb
# キーを指定して表示
irb(main):005:0> ENV['RAILS_ENV']
=> "development"
```

```irb
# 全て表示
irb(main):001:0> ENV
=>
{"BUNDLER_ORIG_BUNDLER_VERSION"=>"BUNDLER_ENVIRONMENT_PRESERVER_INTENTIONALLY_NIL",
 "BUNDLER_ORIG_BUNDLE_BIN_PATH"=>"BUNDLER_ENVIRONMENT_PRESERVER_INTENTIONALLY_NIL",
 "BUNDLER_ORIG_BUNDLE_GEMFILE"=>"BUNDLER_ENVIRONMENT_PRESERVER_INTENTIONALLY_NIL",
 "BUNDLER_ORIG_GEM_HOME"=>"BUNDLER_ENVIRONMENT_PRESERVER_INTENTIONALLY_NIL",
 "BUNDLER_ORIG_GEM_PATH"=>"BUNDLER_ENVIRONMENT_PRESERVER_INTENTIONALLY_NIL",
 "BUNDLER_ORIG_MANPATH"=>"BUNDLER_ENVIRONMENT_PRESERVER_INTENTIONALLY_NIL",
 "RAILS_ENV"=>"development"}
```

## 参考
https://railsguides.jp/command_line.html#bin-rails-console

https://railsdoc.com/page/rails_console

https://docs.ruby-lang.org/ja/latest/class/ENV.html
SAP Universal ID移行後にSAP Download Managerでこまった話

`SAP Universal ID`に移行（紐づけ）してしばらくたったアカウントで`SAP Download Manager`を使おうとした際にちょっとこまった話。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/8cb8907e-81d6-c9f4-bb1d-20c0c3a3921e.png)

2023年7月現在。　`SAP Download Manager`の接続設定の入力欄は`User namae`と`Password`となっています。

[3016110 - Software download issues while using SAP Universal ID - SAP Download Manager](https://me.sap.com/notes/3016110/E)

上記ノートを参照すると `SAP Download Manager`は`SAP Universal ID`にまだ対応しておらず、個別の`S-User`とパスワードを入力して接続する必要があるようです。

今回、利用したかった`S-User`とパスワードを入れれば接続できるはずですが。

今回のアカウントは`SAP Universal ID`と紐付けた段階で、パスワード管理しなくなっていたため今となっては当時のパスワードがわからなくなっていました。

個別の`S-User`のパスワードリセットをしたい場合どうするのか？　と思いましたが。　[3016110 - Software download issues while using SAP Universal ID - SAP Download Manager](https://me.sap.com/notes/3016110/E)　を読むと、パスワードリセット方法についても言及されていました。

## SAP Universal IDに紐づいている個別のS-Userパスワードをリセットする

[1808560 - How to reset an S-user ID password - SAP for Me](https://me.sap.com/notes/1808560/E)

S-Userのパスワードをリセットする場合は下記のいずれかでパスワードリセットができるようです。

1. [SAP ID Service](https://accounts.sap.com/ui/protected/profilemanagement)
2. [Forgot My Password](https://accounts.sap.com/ui/createForgottenPasswordMail?spId=55365985e4b07dc3abdfc16c&targetUrl=&sourceUrl=)

1の方法についてですが、下記のように現在のパスワードが必要となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/d0444722-6a7d-ea24-c39c-3358faccedfb.png)

そもそも現在のパスワードがわからなくなっているので、今回は2の方法でパスワードリセットをします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/a811215e-9596-84b9-3983-6d674f6ea999.png)

パスワードを忘れた場合の入力プロンプトに`S-User`を入力すると、メールアドレスにパスワードリセットのメールが届くのでリセットします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/a11eccd1-d112-ee51-ba2b-9dec0e4d82f1.png)

こちらでリセットした後に、`SAP Download Manager`の資格情報にリセット後のパスワードを入力した所、無事接続できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/f4766a00-e0a4-3a69-71c1-bfadb165300d.png)

なおこのリセット方法だと、`S-User`のパスワードだけリセットされて、`SAP Universal ID`のパスワードについては変更されていませんでした。

## 総評

`S-User`から`SAP Universal ID`への移行の過渡期といった感じもしますが。
最終的には`SAP Download Manager`も`SAP Universal ID`に移行するのでしょうか。

あと`SAP Universal ID`と紐づけた際に、個別`S-User`のパスワードは破棄していましたが。
こういった場面では個別`S-User`のパスワードを使う事が出てくるケースがしばらくはありそう？　ですかね。
【rails】ストロングパラメータでmergeメソッドを使う

## RealWorldでエンドポイントを作る
RealWorld という OSS のプロジェクトがある。
RealWorld は実世界と同じ機能を持つプラットフォームを作ることで、学習したいフレームワークの技術を習得することを目的としたプロジェクトのこと。

[RealWorld](https://realworld-docs.netlify.app/docs/specs/backend-specs/api-response-format#single-article )

詳細はリンク先をご覧いただきたいが、
エンドポイントの作成で、次のようなJSONデータを指定URLにPOSTした場合、

`POST /api/articles`

```
{
  "article": {
    "title": "How to train your dragon",
    "description": "Ever wonder how?",
    "body": "You have to believe"
  }
}
```
次のようなJSONデータを返すコードを作成するよう指示されている。
```
{
  "article": {
    "slug": "how-to-train-your-dragon",
    "title": "How to train your dragon",
    "description": "Ever wonder how?",
    "body": "It takes a Jacobian",
    "createdAt": "2016-02-18T03:22:56.637Z",
    "updatedAt": "2016-02-18T03:48:35.824Z"
  }
}
```

"slug"はPOSTするJSONデータにはないため、リクエストを受けたら"slug"の値を作成し、"slug"をマージしてデータを返すようコードを書かなければならない。
## どうしたか？
そこでmergeメソッドを使って、次のコードを作成してみた。
```
params.require(:article).permit(:title, :description, :body).merge(slug: params['article']['title'].gsub(' ', '-'))
```

params['article']['title']　で取得した値（ここで言う、"title": "How to train your dragon" の部分）を置換したものをレコードにマージしている。
【MUI】Accordionコンポーネントの開閉状態を取得する

![header.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219708/03194f19-8276-3bd1-0634-57cd2b46ac46.png)

# 概要

Accordion コンポーネントを使用している UI で、その開閉状態に関わらず全体の `height` を 100vh に合わせる必要がありました。
Accodion の開閉状態を取得する方法で少し調べる必要があったので書き記しておきます。

# 状況

下図のように水色の枠の部分 (TextBox コンポーネント) は Accodion を使用していて、開閉が可能になっています。

<img width="60%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219708/3fa4f27e-0891-e283-9328-09adddcb44a8.png">

各コンポーネントの高さの指定を厳密にするために、100vhから自身以外のコンポーネントの高さを引いた値を設定しています。
Accodion の開閉状態に合わせてピンク色の枠の部分 (Body コンポーネント) の高さを変える必要がありました。
`useState` で状態を取得しようと思いましたが、どこから取れるのかが不明でした。

# 解決

ChatGPTに質問してみたところ `AccordionSummary` の onClick で状態を反転させる方法を提示してくれましたが、こちらは期待する効果が得られませんでした。
公式ドキュメントをよくよく見ていくとどうやら `Accodion` の onChange イベントが `expanded` というプロパティを持っていることが判明し、以下の実装になりました。

``` typescript:Pane.tsx
// 親である Pane コンポーネントで state を定義する
const [isAccordionOpen, setIsAccordionOpen] = useState(false)

// 水色枠 (TextBox) には props として isAccordionOpen, setIsAccordionOpen を渡す
// ピンク色枠 (Body) には props として isAccordionOpen を渡す
```

TextBox コンポーネントでは `Accodion` の onChange イベント内で `expanded` の値で state を更新します。
ちなみにややこしいのですが `Accordion` の開閉時それぞれの height は以下のように設定します。

* 閉じた状態 : `AccordionSummary` の `minHeight`
* 開いた状態 : `AccordionDetails` の `height`

``` typescript:TextBox.tsx
...

return (
    <Accordion
      disableGutters
      onChange={(_event: React.SyntheticEvent, expanded: boolean) =>
        setIsAccordionOpen(expanded)
      }
    >
      <AccordionSummary
        expandIcon={<ExpandMoreIcon fontSize="small" />}
        aria-controls="panel1a-content"
        sx={{ minHeight: 'var(--column-close-input-height)' }}
      ></AccordionSummary>
      <AccordionDetails>
        <Box sx={inputStyle}>
          <FormControl
            variant="outlined"
            sx={{
              width: '100%',
              display: 'flex',
              flexDirection: 'column-reverse',
            }}
          >
            <OutlinedInput
              id="text-input"
              value={messageValue}
              multiline
              fullWidth
              rows={7}
              onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
                setMessageValue(event.target.value)
              }}
              endAdornment={
                <InputAdornment position="end">
                  <IconButton onClick={sending} disabled={messageValue === ''}>
                    <SendIcon fontSize="small" />
                  </IconButton>
                </InputAdornment>
              }
            />
          </FormControl>
        </Box>
      </AccordionDetails>
    </Accordion>
  )
```

Body コンポーネントでは `isAcorrdionOpen` の値に応じて、よしなに `height` を書き換える。

``` typescript:Body.tsx
  const bodyHeight = isAcorrdionOpen
    ? 'calc(100vh - var(--column-header-height) - var(--column-open-input-height))'
    : 'calc(100vh - var(--column-header-height) - var(--column-close-input-height))'
```


# 参考資料

https://mui.com/material-ui/api/accordion/
DiscordBotでメッセージに反応して返信する

身内のサーバーでBotを導入したかったので、自作しようと思い色々やってみたが初歩で詰まったので備忘録

### ChatGPTに頼んだコードでは動かなかった。
下記はChatGpt3.5に書いてもらったコードだが、これだとmessage.Contentが空文字になってしまった。
何度かやりとりしたが、全滅だったため自分で解決策を探した。


```C#
using System;
using System.Threading.Tasks;
using Discord;
using Discord.WebSocket;

class Program
{
    private DiscordSocketClient _client;

    static void Main(string[] args)
        => new Program().MainAsync().GetAwaiter().GetResult();

    public async Task MainAsync()
    {
        _client = new DiscordSocketClient();

        // メッセージ受信時のイベントを設定
        _client.MessageReceived += MessageReceived;

        string token = "ここにあなたのDiscord botのトークンを入力";
        await _client.LoginAsync(TokenType.Bot, token);
        await _client.StartAsync();

        // プログラムが終了しないように待機させる
        await Task.Delay(-1);
    }

    private async Task MessageReceived(SocketMessage message)
    {
        // メッセージがbotのものであれば無視する
        if (message.Author.IsBot) return;

        // メッセージの内容を確認し、「おはよう」なら返信する
        if (message.Content.ToLower() == "おはよう")
        {
            await message.Channel.SendMessageAsync("おはようございます！");
        }
    }
}

```


### Client生成時にconfigを引数にしないとダメだった

日本語文献がでてこなかったので下記を参考にした。
https://stackoverflow.com/questions/73935914/cant-get-any-discord-messages-from-users/73937627#73937627

```C#
        var config = new DiscordSocketConfig
        {
            GatewayIntents = GatewayIntents.AllUnprivileged | GatewayIntents.MessageContent
        };
        _client = new DiscordSocketClient(config);
```

そもそも.NETでbot作ってる人が少ないので情報が少ないような気がする
AIも学習していないのかな・・・？
Ubuntu Server 22.04 を Static IP にする方法

# 設定ファイル
/etc/netplan/50-cloud-init.yaml : 自動生成ファイル。ユーザによる編集は非推奨。
/etc/netplan/99_config.yaml : Ubuntu公式ドキュメント例示ファイル名

# 設定反映
```shell
sudo netplan apply
```

# 設定ファイルの内容
```yaml
network:
    version: 2
    ethernets:
        eth0:
            dhcp4: false
            addresses: [192.168.1.10/24]
            nameservers:
                addresses: [192.168.1.1, 8.8.8.8]
            routes:
              - to: default
                via: 192.168.1.1
```

gateway4は廃止されて、routesでデフォルトゲートウェイを選択するようになった

# 参考記事
https://www.chihayafuru.jp/tech/index.php/archives/5543
Seleniumでpictureタグの現在の画像を取得する方法

# はじめに
HTMLのpictureタグでは、レスポンシブ対応のために画面幅に応じた画像を設定できます。

しかし、単純にSeleniumでpictureタグ直下のsourceタグのsrcset属性の値を取得しても、レスポンシブ対応のために複数の画像URLが取得されてしまいます。

今回は、pictureタグで画面幅に応じて入れ替えられる画像の現在の画像URLを取得する方法を説明します。

# 環境
Python  3.9.13
selenium==4.10.0

# pictureタグとは？
HTMLでレスポンシブに画像を切り替えることができるタグです。
JavaScriptを使用せず、HTMLだけでレスポンシブ対応できる点が特徴ですね。

詳しい解説は以下の記事がわかりやすいです。

https://zero-plus.io/media/html-picture/

簡単に説明しておくと、以下のようにpictureタグ以下にsourceタグを複数書いて、sourceタグを順次評価して現在の画面幅に合う画像のURL（sourceタグのsrcset属性の値）をimgタグのsrc属性の値に置換します。

```picture.html
<picture>
  <!-- sourceに画像のパスを記述-->
  <source srcset="sample.png" media="(min-width: 1024px)" type="image/png"> 
  <source srcset="sample2.png" media="(min-width: 768px)" type="image/png"> 
  <!-- imgに画像のパスを記述 -->
  <img src="sample3.png">
</picture>
```

この例の場合、
- 1024px以上のときはsample.png
- 768px〜1024pxのときはsample2.png
- それ以外の時はsample3.png

を表示します。

# 現在表示されている画像を取得したい
これまでの説明のように、pictureタグを使用するとimgタグのsrcとは別の画像が表示されることがあります。

そのため、単純にimgタグの値を取得してもダメです。

一方で、sourceタグも複数あるので、sourceタグで検索するのもうまくいきません。

こんなときは、以下のように`currentSrc`属性を利用します。
※変数chrome_driverはselenium.webdriver.Chromeオブジェクトです

```sample.py
selector = 'picture > img'　  # pictureタグ以下のimgタグのCSSセレクタ
img = chrome_driver.find_element(By.CSS_SELECTOR, selector) # imgタグを取得
img_src = img.get_attribute('currentSrc') # 現在の画像URLを取得
```

# 参考文献
1. 記事中でも紹介しているpictureタグの説明ページです
https://zero-plus.io/media/html-picture/

2. 今回の解決法を知った出所です
https://stackoverflow.com/questions/74295441/select-first-element-of-srcset-with-python-selenium
React勉強メモ１

Reactの紹介

Reactは、Facebookが開発したユーザーインターフェース（UI）を構築するためのJavaScriptライブラリです。Reactは、コンポーネントベースのアーキテクチャを採用しており、再利用可能なUI部品を作成し、それらを組み合わせてアプリケーションのビューを構築することができます。

Reactの特徴として以下のような点が挙げられます:

仮想DOM（Virtual DOM）: Reactは、仮想DOMと呼ばれる仕組みを使用して、効率的なUIのレンダリングを実現しています。仮想DOMは、変更があった部分のみを実際のDOMに反映することで、パフォーマンスを向上させます。

コンポーネントベース: Reactでは、UIを小さな再利用可能なコンポーネントに分割することができます。これにより、コードの再利用性が高まり、保守性や開発効率が向上します。

単方向データフロー: Reactでは、データの流れが一方向であるというアーキテクチャを採用しています。これにより、データの変更が予測可能で、バグの発生を減らすことができます。

Reactの運用範囲

Reactは、ウェブアプリケーションの開発に広く使用されています。以下のような場面でReactを活用することができます:

シングルページアプリケーション（SPA）: Reactは、SPAの構築に適しています。SPAでは、ページの再読み込みを行わずに、動的なコンテンツの表示やユーザーインタラクションを行います。Reactの仮想DOMの特徴は、SPAのパフォーマンスを向上させます。

モバイルアプリケーション: React NativeというReactの派生ライブラリを使用することで、Reactをベースとしたネイティブアプリケーションの開発が可能です。React Nativeは、JavaScriptを使用してiOSやAndroidのネイティブコンポーネントにアクセスするためのブリッジを提供します。

UIコンポーネントのライブラリ: Reactは、UIコンポーネントの作成にも使用されます。多くのライブラリやフレームワークがReactをベースにしており、これらを使用することで、より高度なUIコンポーネントを簡単に作成できます。

JS各フレームワークの比較

JavaScriptには、React以外にも多くのフレームワークやライブラリが存在します。以下に代表的ないくつかを比較します:

Angular: Angularは、Googleが開発したJavaScriptのフレームワークです。Angularは、フルフィーチャーのフレームワークであり、大規模なアプリケーションの開発に適しています。Angularは、強力なテンプレートエンジンやデータバインディング、依存性注入などの機能を提供しています。

Vue.js: Vue.jsは、Evan Youによって作られたJavaScriptのフレームワークです。Vue.jsは、ReactとAngularの中間に位置すると言われており、学習コストが比較的低く、軽量なアプリケーションや単一のページ内でのUIの一部分の作成に適しています。

Ember.js: Ember.jsは、Ambitious Web Applications（野心的なウェブアプリケーション）の開発に特化したJavaScriptのフレームワークです。Ember.jsは、コンベンションオーバーコンフィギュレーションの原則に基づいており、アプリケーションの構造とフローに関する多くの決定を自動化します。

JS人気フレームワーク

まず結論から言うと、今人気のフレームワークは下記の２つです。

React.js
Vue.js
この結果については、実際にWebエンジニアとしていくつもの開発に携わった中での体感ですので、個人差はあるかと思いますが、このVue.jsとReact.jsは間違いなく多くの開発現場で利用されている人気のフレームワークと言えます。

その理由としては、習得難易度の低さやいかに効率的に開発を進められるか。というところがポイントとなっています。

もちろんそれぞれのフレームワークごとに、良いところ・悪いところや向き不向きがあるので、開発に合わせて最適なフレームワークを選択できるように最低限の知識はつけておいて損はないと思います。

もし、まだ初心者でどれにしたら良いかわからないという方は、自分がどんなものを作っていきたいかを明確にしてからそれに合ったJavascriptフレームワークを選択できるように、準備しておきましょう。そのためには、まずJavascriptでの開発が最低限できることが必須なので、その後から考えても良いかもしれませんね。
【Android】緯度経度から２点の距離を出す【Kotlin】

# 実践
Location.distanceBetweenを利用して２点の距離は出します。



    private fun getDistanceBetween(
        latitude1: Double, longitude1: Double,
        latitude2: Double, longitude2: Double
    ): Float {
        val results = FloatArray(3)
        
        Location.distanceBetween(latitude1, longitude1, latitude2, longitude2, results)

        // 0を指定することで２点の距離を返す
        return results[0]
    }


Location.distanceBetweenの引数を上から順に　第一地点の緯度、経度、第二地点の緯度、経度、2点間の距離を詰めるresultsの順で指定します。


resultsではそれぞれ数字を指定して欲しい情報を取得できます。

|resultsで指定する数字|意味|
|:---|:---|
|0|距離（メートル）|
|1|始点から終点までの方位角|
|2|終点から始点までの方位角|


# 参考
https://developer.android.com/reference/android/location/Location

https://qiita.com/a_nishimura/items/6c2642343c0af832acd4
【Qt】Qt特有の仕組みであるsignal/connect/slotについて概要

最近Qtを触ることがあったので、その際に調べたsignal/connect/slotの覚書。

## 概要
Qt特有のオブジェクト間の通信の仕組み。
Qt以外だとコールバック関数を利用している。


## signal/slot/connect

### signal
なにかしらが発生したことを他のオブジェクトに通知するための関数
ただし、実体がない。

e.g.
- ボタンが押されたときに発生する
- 画面が更新した時に発生させる

### slot
signalに反応して実行される関数。
signalをemitすることで反応する。


e.g.
- ウィジェットを閉じる
- ラベルの文字列を変更する

### connect
slot関数をsignalと結びつけるための関数。

```C++:connect文法
connect(sender, SIGNAL(signal), receiver, SLOT(slot) );
```

## 使用例
```C++:example1.h
signals:
    void SIG_test();
```

```C++:example2.h


public slots:
    void SLOT_test();

```
```C++:example2.cpp

void SLOT_test()
{
	printf("test");
}

connect(m_object1, SIGNAL(SIG_test()),
        this, SLOT(SLOT_test()));

```

## 参考
https://doc.qt.io/qt-6/signalsandslots.html

https://densan-labs.net/tech/qt/chapter3.html
PMP更新方法の概要メモ

■内容
・PMPを更新するためには、3年間でPDUを60ポイント獲得する必要があります。仕事が忙しくて気が付いたらPMPの更新期限が近付いていたり、更新方法忘れたり。。。2022年5月にはトライアングルの内容も更新されましたので、私自身の備忘録として記事を書くことにしました。ご参考になれば幸いです。

■PDUの登録は、以下のカテゴリーごとに登録が必要となる。
・PMP更新に必要なPDU：60PDU（3年間）
　・Education 35PDU以上（最大 60PDUまで可能）
　・Giveback 25PDU以下

■それぞれカテゴリー毎に登録内容を整理する。
・2022年5月に、米国PMI®よりPMP®、CAPM®の資格継続に関する「CCR（資格継続要求）」がアップデートされ、その中で「PMI®タレントトライアングル」が併せて改定されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1041558/878cc1a9-f476-a3bb-2210-ff39feb64408.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1041558/c8dd8307-6914-debd-67c2-2567aa6651f2.png)
■各カテゴリの概念
・Ways of Working（働き方）：
仕事を成し遂げるためのさまざまな方法やスキルに該当します。予測型、アジャイル、デザイン思考、あるいはまだ開発されていない新しい手法など、今日、仕事を成し遂げる方法は1つではなく、プロフェッショナルができるだけ多くの働き方を習得し、適切なタイミングで適切な技術を適用し、成果を上げるために必要な要素になります。

 ・Power Skills（パワースキル）：
協調的リーダーシップ、コミュニケーション、革新的マインドセット、目的志向、共感力などの対人関係スキルに該当します。これらのスキルを身につけることで、チームはさまざまなステークホルダーに対して影響力を維持することができます。これは変化を起こすために不可欠な要素となります。

・Business Acumen（ビジネス感覚）：
組織や業界におけるマクロとミクロの影響力を理解し、適切な意思決定を行うための機能またはドメイン固有の知識を持つことを意味します。あらゆるレベルのプロフェッショナルには、効果的に意思決定を行い、自分たちのプロジェクトが組織全体の戦略やグローバルなトレンドなどの全体像とどのように整合しているかを理解できるスキルが求められています。

・その他
　・Educationについては以下の区分毎に毎に8PDU以上登録する必要がある。
　・Giveback活動については、ポイントの条件は特に無い。
　・各活動についてはエビデンスも要求される（監査のとき）。
　　※つまり、エビデンスは後付けでもOK　まずは登録を！

■Educationの読書とGivevack活動の2種類で申請する
・EducationはRead一択とする（申請が簡単）
　・本は4～5冊で、全て外国の書籍（翻訳版を勉強する）

・Givebackは以下の2つとする
　　①Work as a practitioner（PM実務）
　　②Create content（コンテンツ作成）

■2種類で申請する理由
・EducationとGiveackの2種類でPDUを申請する理由は、
　・全てEducationのReadだけも可能だが、PDUのバランスが悪い
　・2つのカテゴリーに分けて目立たないようにしたい


<参考記事>
https://teinen-atama.com/giveback-pmp159/2198/
https://www.jpsol.co.jp/pmi-talent-triangle/update/
今更ながらslackの通知方法について学んでみた

# はじめに
slackを使い始めて早1年半ぐらい。
業務効率化と対応漏れが多い自分の為にslackの通知方法を学んでみた。

# 記事を書こうと思った背景
通知方法はサイトで調べると載っている。
ただ、過去にslack内で自分が設定した通知設定（/remind……の文章）を覚えていない。確認方法も分からない……そんな、将来忘れてしまうであろう自分の為に書いた記事。

# 定期的な通知の設定方法
- 例
    - 【特定のチャンネル内で自分に向けて毎週火曜10時に「もうすぐ会議がはじまるよ」】と通知設定をする場合
- ①メッセージを入力するテキストボックスに以下を入力。
- 例に記載した通知を設定する場合↓
```
/remind #Qiita channel @todayukihiro もうすぐ会議がはじまるよ every Tuesday at 10:00
```
- テンプレ↓
```
/remind #から始まるチャンネル名 メンションしたい相手 通知したい内容 曜日 at 時間
```
-  ②入力が完了したら、エンターキーを押して設定完了!


### 設定する上での補足情報
- 設定する際は必ず文字と文字の間を **半角スペース**で間隔を空ける
    - 例：【/remind】と【#Qiita channel】の間など
- テキストボックスに **/remind list**と入力し、エンターキーを押すと、これまで設定した通知の一覧が表示されます。
    - 一覧から設定した物を削除することも出来ます!!
- ちなみに【毎月1日の9時に請求書対応が必要】という通知を設定したい場合は以下
```
/remind #から始まるチャンネル名 メンションしたい相手 請求書対応 every month on the 1st at 9:00
```
- 曜日の一覧（英語）
    - 恥ずかしながら、単語がうろ覚え。次回、何かを設定する際、コピペできるよう残しておく
        - 月曜日: Monday
        - 火曜日: Tuesday
        - 水曜日: Wednesday
        - 木曜日: Thursday
        - 金曜日: Friday
        - 土曜日: Saturday
        - 日曜日: Sunday
【Xcode】シュミレーターのタップを可視化する

# はじめに
Kavsoftさんのツイートする動画にはどこをタップしたかわかるような円があったので、
これを自分のシュミレーターでも試してみました！

https://twitter.com/_Kavsoft/status/1670913394634014720?s=20

# やりかた
```:ターミナル
defaults write com.apple.iphonesimulator ShowSingleTouches 1
```

# おわり
これいいですねー

# 参考記事
https://qiita.com/bitpoetics/items/0fee66732f5eab54a851
CPUとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/89812ddc-4d62-6291-a699-6bb8831bff82.png)
１：CPU（Central Processing Unit: 中央処理装置）とは
　コンピュータの頭脳に相当する部分です。CPUは、コンピュータに備わっている機器のコントロールや演算処理を行います。CPUの動作を大まかに捉えると、「メモリから命令やデータを取り出してきて、それを実行し、結果をまたメモリに格納するという動作の繰り返し」であると言えます。

２：コンピュータを構成する５台装置
　コンピュータのハードウェアは、大きく分けて「制御装置」、「演算装置」、「記憶装置」、「入力装置」、「出力装置」から構成されています。CPUは、「制御装置」、「演算装置」で構成されています。

　記憶装置には、主記憶装置と補助記憶装置があります。主記憶装置はメインメモリです。CPUは主記憶装置上のプログラムを実行します。主記憶装置の容量には限りがあるので、ハードディスク装置などの補助記憶装置に、プログラムやデータを格納しておき、必要な時だけ主記憶装置にロード（ロードとは、プログラムやデータを主記憶装置に読み込むこと）するという形をとります。
　

３：各装置の役割
①制御装置：役割は各機器をコントロールする。具体例：CPUの一部
②演算装置：役割は演算を行う。具体例：CPUの一部（ALU）
③記憶装置：役割はプログラム、データを記録する。具体例：メモリ、ハードディスク装置
④入力装置：役割はデータの入力を行う。具体例：：キーボード、マウスなど
⑤出力装置：役割は結果を出力する。具体例：ディスプレイ、プリンターなど
【SwiftUI】TikTok風アニメーションの作り方

# はじめに
SwiftUIでTikTok風のアニメーションを作る方法を紹介します。

# デモ

https://twitter.com/shota_appdev/status/1680543643927445504?s=61&t=NpfVeTBY0mKyz8Vz_Hzmxg

# コード全体

```swift
import SwiftUI

struct ContentView: View {
    // これがtrueのときにTikTok風のエフェクトをかける
    @State private var glitching = false
    
    // 0.1秒ごとにtrue/falseを切り替えるためのタイマー
    private let timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()
    
    private let text = "TikTok"
    
    // テキストの位置をランダムにずらす範囲
    private let offsetRange = -8...8
    
    var body: some View {

        // ZStackで3つのテキストを重ねる
        ZStack {
            Text(text)
                .foregroundStyle(.pink)
                .offset(x: glitching ? CGFloat(Int.random(in: offsetRange)) : 0, y: glitching ? CGFloat(Int.random(in: offsetRange)) : 0)
            
            Text(text)
                .foregroundStyle(.cyan)
                .offset(x: glitching ? CGFloat(Int.random(in: offsetRange)) : 0, y: glitching ? CGFloat(Int.random(in: offsetRange)) : 0)
            
            Text(text)
        }
        .font(.system(size: 128).bold())
        .preferredColorScheme(.dark) // ダークモードにする
        .onReceive(timer) { _ in

            // 0.1秒ごとにtrue/falseを切り替える
            DispatchQueue.main.asyncAfter(deadline: .now() + Double.random(in: 0...0.1)) {
                self.glitching.toggle()
            }
        }
        .onDisappear {

            // 画面が消えたらタイマーをキャンセルする
            timer.upstream.connect().cancel()
        }
    }
}
```

## ポイント
- 色の異なる3つのテキストを重ねる
- 0.1秒ごとにテキストの位置をランダムにずらす

# おわりに
TikTok風アニメーションの作り方を紹介しました。ローディング画面などで使えそうですね。この記事が参考になったという方は、いいね❤️とフォローしていただけると嬉しいです☺️
Win11でtouchコマンドを使えるようにするだけ

# 該当の部分

```
Set-Alias touch New-Item
```

仕組みは簡単でSet-Aliasでコマンドを書き換えてるだけです。

ちなみに
```
Set-Alias <変更後のコマンド> <変更前のコマンド>
```

で好きなコマンドを設定できます

では👋
SwiftUI Stepperの実装方法

普段はAndroidの開発をしているのですが、SwiftUIに興味を持ち色々調べたりしてます。

その中で、StepperというのはAndroidには無い物だったので実装してみました。

Xcode Version 14.2

```StepperSumpleView.swift
struct StepperSumpleView: View {
    @State var count:Int = 0
    var body: some View {
        VStack {
            Stepper(value: $count, in: 0...10, step: 1) {
                Text("\(count)")
            }.frame(width: 250)
        }
    }
}
```

![スクリーンショット 2023-07-16 20.57.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/e30a4f23-147c-2d53-0146-92ad94ad1967.png)

こんな感じの＋を押したら数字が増加して、-押したら数字が減少するUIみたいです。

引数は`value`はIntの増減する対象を設定します。
`in`は増減する幅を指定します。
`step`はボタン押した時に増加する数値です。今回は１なのでプラスを押すと１増加します。

ボタンを好きな見た目にするには自分で作るほうが良いのかもしれないですね。
vue.jsのCI/CD環境を構築してアプリケーション開発に集中する#2

# 目標
前記事はこちら→[vue.jsのCI/CD環境を構築してアプリケーション開発に集中する#1](https://qiita.com/kekkepy/items/8116722c9d7764aaafd8)

GitHub Actionsを用いてVue.jsをS3の静的ウェブサイトホスティングとして公開する
この際AWSマネジメントコンソールでの作業を限りなく0にする
今回使ったGitHubのリポジトリのリンクは[こちら！](https://github.com/keitasato/vuejs-on-s3-oidc)
![pic.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1221536/6d375368-df8f-3b94-4bf1-65f0c66461ad.png)

## 前記事からの修正点
GitHub ActionsからS3へリソースをデプロイするためには、OpenID Connectの設定が必要だが、これをAWSマネジメントコンソールで行った。
この設定もTerraformでコード化する。

## 手順
1. 静的ウェブサイトホスティング用S3バケットを作成(terraform)
1. OpenID Connectの設定(**terraform**)
1. GitHub ActionsでVue.jsをbuild&deploy準備
1. ブラウザからデフォルトページが表示されることを確認

尚、前記事と重複する部分にはついては当記事では記載しない

#### Step.0
前記事で作成したIDプロバイダ、IAM role, IAM PolicyをAWSマネジメントコンソールから削除しておく。

#### Step.1 OpenID Connectの設定(**terraform**)
Terraformで提供されている[モジュール](https://registry.terraform.io/modules/thetestlabs/oidc-with-github-actions/aws/latest#input_iam_role_description)を利用する

```terraform:oidc.tf
module "oidc-with-github-actions" {
  source  = "thetestlabs/oidc-with-github-actions/aws"
  version = "0.1.4"

  github_org = "<アカウント名 or 組織名>"
  github_repositories = [
    "<レポジトリ名>",
  ]

  iam_role_description = "${var.project}-${var.environment} IAM role to enable GitHub OIDC access"
  iam_role_name        = "${var.project}-${var.environment}-GitHubOIDC-Role"
  iam_role_policy      = "AmazonS3FullAccess"
}
```

#### Step.2 GitHub ActionsでVue.jsをbuild&deploy準備
```yaml:frontend.yml
name: frontend CI/CD

on:
  push:
    branches:
      - main
    paths:
      - 'frontend/**'
      - '.github/**'

defaults:
  run:
    working-directory: frontend

permissions:
  id-token: write
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: checkout repository
        uses: actions/checkout@v3

      - name: Use Node.js 18.x
        uses: actions/setup-node@v3
        with:
          node-version: '18.x'

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

      - name: Archive production artifacts
        uses: actions/upload-artifact@v3
        with:
          name: dist
          path: frontend/dist


  deploy:
    needs: build
    if: github.event_name == 'push'
    runs-on: ubuntu-latest
    steps:
      - name: Download production artifacts
        uses: actions/download-artifact@v3
        with:
          name: dist
          path: frontend/dist

      - name: settings deployment role
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: arn:aws:iam::146193870787:role/vuejs-on-s3-oidc-prod-GitHubOIDC-Role
          aws-region: ap-northeast-1
      
      - name: deployment artifact
        run: aws s3 sync ./dist s3://vuejs-on-s3-oidc-prod-static-bucket-mm9r9u --exact-timestamps --region ap-northeast-1
```

#### Step3. ブラウザからデフォルトページが表示されることを確認
無事にデプロイされていることがS3から確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1221536/75c474f3-f611-7009-1382-d8c9722797c8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1221536/fa86dfa2-883b-8883-63c9-ff1ac8e8b8b3.png)
共同開発　model作成　カラム追加

モデルの作成は　先頭大文字の単数形で作成します。
### :shamrock:モデルの作成とカラムの追加

```
【顧客用】
$ rails g devise Customer
【管理者用】
$ rails g devise Admin
```
```
rails db:migrate
```
Deviseというユーザー認証システム用のCustomerモデルが生成されます。モデルファイル、ビューファイル、データベースマイグレーションなど、Deviseを使うために必要なファイルが自動的に作成されます。

:star: cusutomers　(顧客）ファイル
```diff_ruby
 create_table :customers do |t|
      t.string :last_name, null: false
      t.string :first_name, null: false
      t.string :kana_last_name, null: false
      t.string :kana_first_name, null: false
      t.string :phone_number, null: false
      t.string :post_code, null: false
      t.string :address, null: false
      t.booltime :is_deleted, null: false, default: false
      t.datetime :created_at, null: false
      t.datetime :updatad_at, null: false
```
:star:admin （管理者）ファイル
```diff_ruby
 t.datetime :created_at, null: false
 t.datetime :updatad_at, null: false
```
:star:oders  （注文）ファイル
```
rails g model Oder
```
```diff_ruby
  create_table :orders do |t|
      t.integer :customer_id, null: false
      t.integer :payment, null: false
      t.string :name, null: false
      t.string :postcode, null: false
      t.string :address, null: false
      t.integer :order_status, null: false
      t.float :shipping_fee, null: false
     
      t.timestamps
    end
```
:star:order_datails(注文詳細）ファイル
```
rails g model OrderDatail
```
```diff_ruby
 create_table :order_datails do |t|
      t.integer :order_id, null: false
      t.integer :item_id, null: false
      t.integer :quantity, null: false
      t.float :buy_price, null: false
      t.integer :production_status, null: false
      t.timestamps
    end
```
:star: itams(商品）ファイル
```
rails g modal Item
```
```diff_ruby
  create_table :items do |t|
      t.string :name, null: false
      t.text :description, null: false
      t.integer :price, null: false
      t.boolean :is_active, null: false, default: true
      t.timestamps
```
:star:cart_items(カート内商品）ファイル
```
rails g modal CartItems
```
```diff_ruby
  create_table :items do |t|
      t.string :name, null: false
      t.text :description, null: false
      t.integer :price, null: false
      t.boolean :is_active, null: false, default: true
      t.timestamps
    end
```
:star:addresses(配送先）ファイル
```
rails g modal Addresse
```
```diff_ruby
  create_table :addresses do |t|
      t.string :postcode, null: false
      t.string :address, null: false
      t.string :name, null: false
      t.timestamps
    end
```
:star:genres (ジャンル）ファイル
```
rails g modal Genre
```
```diff_ruby
 def change
    create_table :genres do |t|
      t.string :name, null: false
      t.timestamps
    end
```
追加したらmigrateを行う
```
rails db:migrate
```
### 補足

**updated_at** と **updated_at**は、
**t.timestamps**によって自動的に作成されます。
```diff_ruby
 t.datetime "created_at", precision: 6, null: false
 t.datetime "updated_at", precision: 6, null: false
```

**参考**

https://qiita.com/ryouzi/items/2682e7e8a86fd2b1ae47
A5:SQL Mk-2でLinuxサーバのPostgreSQLにSSH接続する

１、「データベースの追加と削除」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180727/afb39d71-4370-fad5-1326-3afeecfd854c.png)

２、「追加」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180727/57548009-3eb5-f90e-6a34-0e388e74ccbc.png)

３、接続タイプを選択
今回はPostgreSQLを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180727/d1fb0c2b-f1c3-0530-5665-f3188dda3fda.png)

４、SSH2トンネルタブを開く。
SSH2ホスト名を入力。
ポート番号を入力。
ユーザーIDを入力。
パスワードを入力。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180727/af3b1704-68d4-296a-4db0-8c5777aa89c5.png)

５、基本タブを開く。
**サーバ名は「localhost」にする。**
**※SSH2ホスト名から見たlocalhostとする。ここをSSH2ホスト名と同じにすると接続できない。**
ポートを入力。
データベース名を入力。
（DBの）ユーザIDを入力。
（DBの）パスワードを入力。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180727/90c2e57a-f79a-6411-6755-48bc904e1f7d.png)

６、「テスト接続」で接続できることを確認する。
【Windowsバッチ】テキストファイルの内容を1行ずつ読み込む方法

■目的
テキストファイルを開きコピペして書き込むのは面倒な場合、自動的に出力できる方法の1つとして「Windowsバッチ」を使う方法をメモとして残します。
なお、主に以下の内容を知りたい方を対象としています。
'-----------------------------------------
・Winodwsバッチファイルでファイル内容を1行ずつ読み込みたい方
・「for」コマンドを使ったファイル内容の読み込み方法をしりたい方
・スペースを含んだファイルから自在に内容を読み込みたい方
'-----------------------------------------

■参考にしたURL
https://jj-blues.com/cms/wantto-readfilelinewithfor/

■前提条件
読み込むファイルは「テキストファイル形式」とします(例, *.txt、*.csvなど)。
そのため、wordやExcelなど上記以外の形式はこの記事の対象ではありません。

■記事に記載する内容
①ファイル内容を1行ずつ読み込む
②スペースを含む場合のファイル内容を読み込み方
~~③任意の列の文字列を読み込み出力する~~
~~④区切り文字を指定する~~


①ファイル内容を1行ずつ読み込む
(1)コードサンプル
```
@echo off
rem ファイルを1行ずつ読み込む
for /f %%[アルファベット1文字] in ([読み込むファイル]) do (

  rem 出力する
  [繰り返したい処理]

  rem 見やすいように区切りを出力する
  echo ---

)
```
このままだと動かないので以下のように変える。
%%[アルファベット1文字]　→　%%a
[読み込むファイル]　→　C:\tmp\4\テスト1_1行ずつ読み込む.txt
[繰り返したい処理]　→　echo %%a

(2)実際に読み込むファイル
C:\tmp\4\テスト1_1行ずつ読み込む.txt
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917622/e36da569-9299-7a9c-b1d5-c8b4b04a0c1f.png)

(3)実行してみる
・(1)のサンプルコードをバッチファイル(read_textfile.bat)として保存する
・コマンドプロンプトを起動しバッチファイルを起動する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917622/66dda26e-1bc4-4a66-ff25-c0e841ebbcea.png)


②スペースを含む場合のファイル内容を読み込み方
(1)コードサンプル
```
@echo off
 
rem スペースを含むテキストファイルを1行ずつ読み込む
for /f "delims=" %%a in ([読み込むファイル]) do (
  rem 出力
  echo %%a
 
  rem 区切りを挿入
  echo ---
)
```
(2)ポイント
「delims」オプションをつけて「”delims=”」とすること
→理由
・スペースがある場合、その位置で一区切りと判断され「%%a」にははじめのスペースまでの文字列しか代入されないため
⇒結果は以下の通り
>・出力結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917622/7764576d-7075-d7f6-008e-4414587084cd.png)
・実行したバッチファイル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917622/1451b4ae-3b10-9606-3940-5cf4e37f4277.png)

・そのため、スペースを区切りとせず一行全体を読み込んで表示させたい場合には、「for」コマンドに「delims」オプションをつける必要がある

(2)実際に読み込むファイル
C:\tmp\4\テスト2_スペースを含むファイルを読み込む.txt
内容はメニューと価格をリスト化したもので、半角スペースで区切っている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917622/e39e2818-b0dc-1bbe-ddf7-8e802efe4e9f.png)

(3)実行してみる
・(1)のサンプルコードをバッチファイル(read_textfile_includeSpace.bat)として保存する
・コマンドプロンプトを起動しバッチファイルを起動する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917622/ff8e2a19-54bb-4ec4-7d24-5ca8b001badf.png)


~~③任意の列の文字列を読み込み出力する~~
~~④区切り文字を指定する~~