OmniAICreator/Qiita-1.07M huggingface dataset:
UiPath オートメーション デベロッパー プロフェッショナル UiPath-ADPv1_JPN　不合格体験記

# はじめに
Qiita初投稿です。不名誉なタイトルですが反省の意味も込めて赤裸々に記載します。
再受験は未定です。

# 受験概要
- 試験名…UiPath Certified Professional オートメーション デベロッパープロフェッショナル v1.0 (日本語)（UiPath-ADPv1_JPN）
- 合格点…70点
- 受験日…2024年9月23日(月)（日本時間)
- 受験場所…テストセンター
- 結果…不合格 63点

旧バージョンの資格を持っており、半額バウチャーを使って半額で受験しました。
一応模擬テストは90点いくまで勉強したのですが、本番では63点でした。
模擬テストを受けている際、受験範囲に記載されていても模擬テストに出てこない範囲があるとは思いましたが、本番ではそこそこの割合で出てきた印象です。
これから受ける方は模擬テストに出てこない範囲も公式ドキュメントなど読むようにするとよいかもしれません。
自宅で受験もできますが、個人的にテストセンターでの受験が好きなため、テストセンターで受験しました。
Pearson Vueのテストなので、MicrosoftやAWSの試験を受けている方にはおなじみの形式だと思います。

# 筆者の経験値
IT知識を新人教育で多少学んだ後、5年ほどUiPathを触ったり触っていなかったりします。
簡単なロボットを作成したりインストールをすることはできます。
この試験の古いバージョンである「UiPath RPAデベロッパー上級資格試験」を2，3年前に取得済みですが、REFrameworkを実務で使ったことはなく、UiPathの試験体系でいうとアソシエイトくらいの経験値だと思います。

# 勉強内容
今回以下の流れで勉強しました。合計で20時間くらいです。
- 試験範囲確認
- 模擬テストを1回受験（50点）
- UiPath Academy オートメーション デベロッパー プロフェッショナルトレーニング受講（約15H）
- 模擬テスト繰り返し（同じ問題しか出ないが90点になるまで）(5H)

模擬テストを受験し、体系だって勉強する必要を感じたため、UiPath Academyの「オートメーション デベロッパー プロフェッショナルトレーニング受講」コースを受講しました。
このコースを一通り終了し、模擬テストで足りないところを補充すれば7割くらいの試験範囲をおさえられる印象です。
私は今回時間がなかったので、「模擬テストに出てこない範囲」と理解に時間がかかりそうだった「LINQ構文」は勉強しませんでした。
本番でもLINQ構文の問題が3~5問くらい出てきたのでやっておけば合格したかも。。と後の祭りです。

# 模擬テスト・UiPath Academyの上述コース以外に追加学習をおすすめする範囲
この記事を読んでいる時期によっては事情が変わっているかもしれませんが、試験範囲に記載がある以下の範囲は、模擬テストとUiPath Academyaの上述コースだけでは不足すると感じました。

> 1. UiPath Orchestrator
• テナント エンティティ (Webhooks、アラート) とフォルダー エンティティ (トリガー、資格情報ストア) 
• 無人オートメーション機能の活用 (フォルダーとジョブの優先度、バックグラウンドとフォアグラウンド プロセスの分離、マシンごとのライセンス割り当て)
• Orchestrator 監視機能の使用
>2. RPA テスト
• 基本的およびデータ主導の RPA テストの作成と使用
• Test Explorer パネルを使用し、テストをグループ化、デバッグ、アクティビティ カバレッジの分析
• モック テストの使用

前提の「RPA デベロッパー 基礎」を受講したり、追加で公式ドキュメントを読んだり、実際に機能を触ったりすることをおすすめします。
私の時は「UiPath Orchestrator」っぽい問題が5問くらい、「RPAテスト」っぽい問題も5問くらい出ていました。
蛇足で、どこの範囲に含まれるのか不明ですが、Insightsについても2問くらい出てきたと思います。

# おわりに
これから受験されるみなさんの合格を祈ります。受験された際はぜひ役に立った勉強法を公開してみてください。
Windows10のサポート終了について

## 初めに
こんにちは、大野です。
Windows10のサポート終了が近づいてきました。これを読んでいる皆さんはすでに対応を済ませているでしょうか？今回の記事ではWindows10のサポートの時期や気を付けることについて簡単に説明していきます。

## サポート終了時期
肝心のWindows10のサポート終了時期ですが2025年10月14日になります。

## サポート終了するとどうなるのか
まずサポート終了するからと言って、何もできなくなるわけではありません。25年10月14日以降もWindows10のPCを使うことは出来ます。では何が出来なくなるのか？それはOSのセキュリティ更新プログラム（バグ修正や脆弱性のセキュリティ修正）の配布が終了するということになります。

## 対策
対策としては、新しいWindows11を搭載したPCを購入するか、最小要件を満たすPCであれば、Windows10からWindows11に無料でアップグレードする、のいずれかの方法があります。

## 気を付けること
サポート終了直前になると駆け込み需要の発生が予想されます。Windows7のサポート終了月には前の月と比べて2.28倍の需要が発生したそうですから直前の買い替えなんて絶対に避けたほうがいいです。店頭に買い求めやすいPCはなくなり、在庫不足や価格の高騰などが起きておきます。結果自分にとってオーバースペックなPCを購入せざるを得なくなり損をすることになります。

## 最後に
私のお勧めは今年の年末セールで買ってしまうことです。それが一番安く買えるのではないかと予想しています。

読んでいただき、ありがとうございます。以上、大野でした。

## 注意
当記事はとてもWindowsOSに特別詳しい人が書いているわけではありませんので、書ききれていないことがある可能性が大いにあります。当記事で不安を覚えた方は当記事満足せずに自分でも詳しく調べなおすことを推奨します。
access.logをAthenaで分析できる環境を構築してみた話

## 概要
EC2で収集した`access.log`をS3に転送して、S3上のgz形式のログファイルをAthenaで分析できる環境を**作成**しました。

---

## そもそもAthenaってなに？

> Amazon Athena は、オープンソースフレームワーク上に構築されたサーバーレスのインタラクティブな分析サービスで、オープンテーブルとファイル形式をサポートしています。  
> Athena は、ペタバイト規模のデータが存在する場所で分析するための簡素化された柔軟な方法を提供します。Amazon Simple Storage Service (S3) データレイクと 25 以上のデータソース (オンプレミスデータソースや SQL または Python を使用した他のクラウドシステムを含む) からデータを分析したり、アプリケーションを構築したりできます。  
> Athena は、オープンソースの Trino および Presto エンジンと Apache Spark フレームワーク上に構築されており、プロビジョニングや設定は不要です。

要するに **S3にデータを設置すれば、それだけで分析できてしまう** っていうことです！  
なのでサーバーの管理とか、RDSにデータを入れたりする必要は全くないです！

---

## 対応方法

nginxのアクセスログをS3にファイルとして保存するのは、こちらの記事を参照ください！

https://qiita.com/redchili/items/2180c92d0bda53661a57

---

### つまずいたところ

S3に`access.log`は登録されるようになったものの、ユーザーやグループを特定できる情報が含まれていませんでした。  
そこで、こういった情報もログに記録できるように、ログイン処理の中で以下のメソッドを追加しました。

```php
// 省略してわかりやすく書いてます
function nginxNote()
{
    $auth = getAuth();
    header('X-グループのID: ' . $auth['グループのID']);
    header('X-ユーザーのID: ' . $auth['ユーザーのID']);
}
```
https://qiita.com/gusagi/items/820be702d45889c0e27e

これで、アクセスログに`グループのID`や`ユーザーのID`を付加することができました。  
あとでAthenaでログ分析する際に、どのユーザーやグループがどういう操作をしているかが簡単にわかるようになります。

---

## Athena以外の候補

今回はAthenaを選出しましたが、実はこれ以外に2つほど候補がありました。

1. **ログ取得用のスキームを作成する**
    1. **メリット**
        1. 機能に組み込みやすい
        1. 柔軟にログを取得する場所を指定できる
    1. **デメリット**
        1. 今後データがたまった時、取得時に負荷がかかりそう
        1. 新たにRDSを作成して進めようとしていたので、料金や負荷状況の監視など、運用コストが高い

2. **Kibanaを使う**
    1. **メリット**
        1. 表やグラフで視覚的にわかりやすく分析できる
        1. 社内でも実績があり、転用できる（かも？）
    1. **デメリット**
        1. 別途料金がかかる

それぞれのメリット・デメリットを比較して、AWSに乗っているシステムなので工数が抑えられそうなことや、Lambdaなどの拡張性を考慮して、**Athenaでやる**ことに決めました。

---

## 今後の展望
今の段階で達成できている部分もありますが、まだまだ改善の余地があるので、さらに効率化と自動化を目指して以下の点に取り組む予定です。

### 1. nginxの安定運用
現在、`access.log`の書き込みが毎日朝3時に一時停止してしまう問題が発生しています。  
※おそらく、ログローテーションのタイミングでgzに固める際に、権限の問題が起きて新しいログファイルに書き込みできなくなっている模様。

そのため、今は応急処置として、毎朝5時にnginxを再起動するジョブを動かしています。  
ここはログローテーションの設定をしっかり見直して、nginxを安定稼働させる必要があるかなと思っています。

---

### 2. ログ分析の自動化
Athenaで利用状況を抽出できるようになりましたが、今は手動でSQLクエリを実行してデータを取得しています。  
今後はこれを自動化して、もっとラクに分析できるようにする予定です。

- **BIツールの導入**  
  QuickSightを使って、ログデータを視覚的に分析できるように進めています。  
  これが完成すれば、ダッシュボードでリアルタイムのデータが見えるようになり、どれくらい機能が使われているかすぐに把握できるはずです！

- **Lambdaでの自動化**  
  AWS Lambdaを使って、Athenaのデータ抽出を定期的に自動化する計画です。  
  これで、SQLを手動で実行する手間が省けて、定期的にデータを取得する作業も効率化されます。

---

## まとめ
AthenaではMySQLとほぼ同じ構文でデータを取得できて、めちゃ便利です！  
最終的には全自動でデータが取れて、誰でも簡単に抽出できる環境を目指しています。  
これからもAWSや他のツールを駆使して、ログ管理や分析の効率化を進めていきたいです。

---
Windowsでhead、tailするバッチ例

単発小ネタ　Windowsバッチ

# 20240930_Windowsでhead、tailするバッチ例  
  
## 機能  
- bashのheadやtailのように、Windowsのコマンドプロンプトで対象ファイルの先頭行、末尾行を出力する
- 第一引数　：　対象ファイル　＃必須
- 第二引数　：　希望行数　＃任意。デフォルト5行
- batファイルのディレクトリにPath通せば、headとかtailでコマンド打てるようになります

```head.bat
@echo off
if "%1" == "" GOTO :ERR
if "%2" == "" (set LNUM=5) else (set /a LNUM=%2)

echo.
echo   ** head start ** type head %LNUM% lines **
echo **** **** **** **** 
setlocal enabledelayedexpansion
for /f "tokens=1,2,3 usebackq" %%i in (`find /v /c "" %1`) do set LCTR=%%k

set /a CTR=0

for /f "tokens=1* delims=:" %%i in ('findstr /n "^" %1') do (
if "!CTR!" == "%LNUM%" goto :ENDX
if "%%j" == "" (echo. ) else (echo %%j)
set /a CTR+=1
)

:ENDX
echo **** **** **** **** 
echo   ** head end **
echo   ** cf : %1 has %LCTR% lines.
echo.
exit /b

:ERR
exit /b
```

```tail.bat
@echo off
if "%1" == "" GOTO :ERR
if "%2" == "" (set LNUM=5) else (set /a LNUM=%2)
echo.
echo   ** tail start ** type tail %LNUM% lines **
echo **** **** **** **** 
for /f "tokens=1,2,3 usebackq" %%i in (`find /v /c "" %1`) do set LCTR=%%k
set /a STCTR=%LCTR%-%LNUM%

more +%STCTR% %1

:ENDX
echo **** **** **** **** 
echo   ** tail end **
echo   ** cf : %1 has %LCTR% lines.
echo.
exit /b

:ERR
exit /b
```

## その他
- 付加情報不要なら開始終了のecho削ってください。
- cmderとか導入できれば、或いはwslとか使えれば特に困ることないんですけどね。オフラインのwindows環境もありますよね、ってことで。


:::note info
アプローチを整理してみたので、良ければご確認ください。

https://qiita.com/kubo4ka/items/6f07bddab368329a1836

:::

以上
【備忘録】GAS(Javascript)におけるブーリアン型の判別

久々にGASコード書いたら、はまったので備忘録のメモです。
下記のコードでうまいこと動作せず、悩んでいました。
原因はindexOfの使い方を誤っていたのと、ブーリアン型になるのでおかしくなっていたという
結論です。


誤コード
function test3(){
  const array = ['テレビ','エアコン','洗濯機','冷蔵庫']
  const machine = '乾燥機';
  if(array.indexOf(machine)){

    console.log('yes'+array.indexOf(machine));
  }else{
    console.log('no'+array.indexOf(machine));
  }
}

乾燥機はarrayにないので'no'にいってほしいのですが、'yes'の方にいってしまいます。

結論をいうと//array.indexOf(machine=乾燥機)は-1を返す、-1はブーリアン型
だとtrueということで'yes'になっていたようでした。
0、""（空文字）や null、undefinedはfalseを返すようです。

この上記のコードの場合は
if(array.indexOf(machine))の
箇所が
if(array.indexOf(machine))>=0という事でした。

正コード
function test3(){
  const array = ['テレビ','エアコン','洗濯機','冷蔵庫']
  const machine = '乾燥機';
  if(array.indexOf(machine)>=0){

    console.log('yes'+array.indexOf(machine));
  }else{
    console.log('no'+array.indexOf(machine));
  }
}

indexOfより、includesの方が便利だなと思いました。
RailsでJavaScriptファイルを新しく作ったら動かない


新人エンジニアの私が、入って1ヶ月ほどの時にハマった落とし穴。

### 「RailsでJavaScriptファイルを新しく作ったけど動かない。うまく繋げられない。」

一人で解決するのに相当な時間をかけてしまいましたので、同じ状況で困っている方のお力になれれば幸いです。


## 状況

 Ruby on Railsで、JavaScriptファイル `sample.js` を新しく作りました。
 
 ```sample.js
class Sample {}
```

 この `sample.js` に書いたクラスを、`html.erb` で呼び出します。

```html.erb
<script>

　$(function () {
　　new Sample();
　});

</script>
```


しかし、、、ページを読み込むとコンソールに以下のエラーが出てしまいました。

```
Uncaught ReferenceError: Sample is not defined
```

ReferenceError、、、Sampleなんてのは見つからないと、、、
完全にJavaScriptファイルが読み込まれていません。

そこで気付きました。

*「あ！！ファイルのパス指定してない！！」*

ということで以下のコードを追加します。
```html.erb
<%= javascript_include_tag 'sample' %>
```


しかし、、、またまたエラー。
今度はコンソールエラーではなく画面ごと表示できなくなってしまいました。

```
Sprockets::Rails::Helper::AssetNotPrecompiledError
```


そして私は沼にハマりました。今思えばきちんとエラーの内容を見れば済む話だったのですが、当時はなかなか原因がわからず、、、

格闘すること１時間後、、、

ようやく見つけたのが、、、


### config/initializers/assets.rb


このファイルでした。こいつへの記述が足りていなかったのです。

個別でJavaScriptファイルを使用したい場合は、assets.precompileの指定を行う必要があります。そこで以下をassets.rbに追記します。

```config/initializers/assets.rb
Rails.application.config.assets.precompile += %w (sample.js )
```


これでOK！！！ではありません。

このコードを足しただけでは、ページをリロードしてもまた同じエラーが出てしまいます。



最後に重要なのは、**docker-composeによるコンテナの再構成**。今回のようにファイルを新規追加した場合などには読み込み直す必要があります。

docker-composeをRunして、ようやくJavaScriptファイルが読み込まれました。


## まとめ
この経験から、いろんなファイルへの関心を持つ習慣がつきましたし、エラーの内容をきちんと読解することの大切さも学びました。

今回の内容も、一度知ってしまえばもう二度と繰り返すことはない過ちだとは思いますが、、、

初めてで、かつ初心者だと、「どこのコードが間違っているんだろう？」と、**コードの内容ばかりに思考が傾き**、assets.rbファイルの存在へ辿り着くのに時間がかかることも多いと思います。

少しでも同じ状況で困っている方のお力になれれば幸いです。
Node.js環境構築ではまったこと

# :writing_hand: はじめに

こんにちは。環境構築Lv.1の私です。
今回はTypeScriptで組んだプログラムの動作確認環境が欲しく、以下記事を参考にNode.js環境（バージョン管理には NVM for Windows）を構築しました。

- [nvm-windows の導入と簡単な操作をやってみた](https://qiita.com/akipon0821/items/eaeffe79221cfcd4d258)
- [Windows への Node.js（npm）のインストール](https://qiita.com/gahoh/items/8444da99a1f93b6493b4)

基本的には上記記事の手順で大丈夫だと思うのですが、
自分のローカルの都合なのか所々うまくいかず、あれ？となったところがあったので備忘とします。

- nvmがうまくインストールされなかった
（nvm versionコマンドでバージョンが表示されない）
- node, npmがうまくインストールされなかった
（node -v, npm -vコマンドでバージョンが表示されない）


# :writing_hand: nvmがうまくインストールされなかった
 （nvm versionコマンドでバージョンが表示されない）

ダウンロードサイトから落としてきたsetup.exeを管理者実行でセットアップウィザードを完了しても、nvm versionコマンドでバージョンが表示されませんでした。

原因と対処は単純で、セットアップウィザードにてなぜかデフォルトのインストール先指定が変なパスになっていました。
こんなの→ C:\Users\{ユーザ名}\AppData\Roaming\ {ユーザ名}
以下パスにすればうまくインストールできました。
```
C:\Program Files\nvm
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3788032/736454b1-1501-3053-514e-c95d888e4064.png)

セットアップウィザードで自動生成される環境変数もこれに合わせる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3788032/606a49c7-de70-b7f2-bf32-505e7e585fa8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3788032/9aafd0bf-f072-fac1-827e-38f175d73205.png)



# :writing_hand:node, npmがうまくインストールされなかった

原因としては何故かver別のフォルダがnodejsフォルダ直下に保存されていたためだったようです。
（環境変数は上記画像の通りの設定だったのですが・・・）
手動で以下のとおりにフォルダを配置することでうまく認識されるようになりました。

nvmフォルダ直下
(私はわけあって当時最新のv20.17.0に加えてv14.15.4をインストールしています)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3788032/a819b756-52e5-f3d4-6ef6-8e9fbdc529bd.png)

nodejsフォルダ直下

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3788032/e8b957ea-350a-ef16-5129-17ed155fe49c.png)

# :writing_hand:さいごに
もし自分と同じようにはまった方がいればその助けになれたら嬉しいです。
また他でハマったことあっれば今後また構築の際の参考にさせて頂きたいので、ぜひコメントにてお教えください。
【Rails】ArgumentError: The scope body needs to be callable.

## はじめに
Railsのアップデート中にscopeを使用している箇所でエラーが出たので、その対応をまとめます。

## 問題
コード
```ruby
scope :valid, where(:is_valid => true)
```

エラー文
```ruby
ArgumentError: The scope body needs to be callable.
```

## 解決方法
以下のように修正します。
```ruby
scope :valid, -> { where(:is_valid => true) }
```

## 参考
https://stackoverflow.com/questions/28951671/argument-error-the-scope-body-needs-to-be-callable
Vagrantの仮想環境に素早くssh接続するPowershell関数

### 動機
`vagrant ssh`は遅い。`.ssh/config`に登録すると早くて良いけれど、ポート番号が変わるときもある。（僕はprivate_networkを登録してないし、sshの22番ポートのフォワーディングも使ってないです）

でも面倒じゃなく、素早くつなぎたかった。

### 解決策
ということで、VBoxManageをつかって必要な情報を取得して、sshでつなぐPowershellの関数を書いてみました。
* grep、sedの代わりに [ripgrep](https://github.com/BurntSushi/ripgrep) と [sd](https://github.com/chmln/sd) を使ってます。

```posh
function sshvm($vmname) {
  New-Variable -Name vmpath -Value (VBoxManage.exe showvminfo $vmname | rg 'Host path' | sd ".*path: '\\\\\?\\(.*)' .*" '$1')
  New-Variable -Name ip -Value (VBoxManage.exe showvminfo $vmname | rg 'ssh' | sd ".*host ip = ([\d\.]*),.*" '$1')
  New-Variable -Name port -Value (VBoxManage.exe showvminfo $vmname | rg 'ssh' | sd ".*host port = ([\d]*),.*" '$1')
  New-Variable -Name keypath -Value ".vagrant\machines\default\virtualbox\private_key"
  New-variable -Name user -Value 'vagrant'

  echo "ssh $user@$ip -p $port -i $vmpath\$keypath"
  ssh $user@$ip -p $port -i $vmpath\$keypath

  Remove-Variable -Name vmpath
  Remove-Variable -Name keypath
  Remove-Variable -Name ip
  Remove-Variable -Name port
  Remove-Variable -Name user
}
```

これを$profileかなにかに登録しておきます。sshvm <VMの名前>でssh接続できます。

```posh
PS C:\> sshvm manjaro
ssh vagrant@127.0.0.1 -p 2200 -i D:\vagrant\manjaro\.vagrant\machines\default\virtualbox\private_key
Last login: Mon Sep 30 19:50:54 2024 from 10.0.2.2
[vagrant@manjaro ~]$
```
基本情報技術者に向けて　Part.2

# プロトコル
ネットワークを通じてコンピュータ同士がやり取りするための約束事のこと
世界的に使われているプロトコルは**TCP/IP**

# OSI基本参照モデル
様々なプロトコルを７階層に分けたものをOSI基本参照モデルという

### 第７層　アプリケーション層
ユーザーが操作しているアプリケーションが提供する具体的な機能についての仕様や通信手順を定めたもの
各層のうち最も利用者に近い部分で、ファイル転送や電子メールなどの機能が実現されている
代表的なプロトコルとしてはHTTP/HTTPSやFTP、Telnetなどがある

### 第６層　プレゼンテーション層
データの表現形式を定義するもの
文字コードの変換などが含まれる
代表的なプロトコルは、メールの送受信で用いられるSMTPやPOP3、IMAPなどがあげられる

### 第５層　セッション層
通信プロトコル間の開始から終了までの一連の手順（セッション）を定義するもの
接続が切れた場合、接続の回復を試みる際の手順などが含まれる
代表的なプロトコルとして、SSL/TLSなどがある

### 第４層　トランスポート層
通信の品質をコントロールする層
信頼性重視やリアルタイム性重視など、用途に応じてプロトコルを使い分けることができる
代表的なプロトコルとしては、TCPやUDPなどがある

### 第３層　ネットワーク層
ネットワークにおける通信系との選択（ルーティング）や中継を行う
エンドシステム間のデータ伝送を実現するために、ルーティングや中継などを行う
代表的なプロトコルとして、IPやARPなどがある

### 第２層　データリンク層
直接的に接続された機器同士の通信を実現する
隣接ノード間の伝送制御手順（誤り検出、再送制御など）を提供する
代表的なプロトコルとして、イーサネットやPPP、HDLC、アークネットなどがある

:::note warn
※誤り制御とは、コンピュータ間通信の途中で失われた情報や壊れた情報を検知し、適切な状態に修正すること
:::

### 第１層　物理層
ケーブルやコネクターにて接続される
ハードウェアのコネクター形状やピン数といった物理的な接続の規定をプロトコルとして定めている
物理的な通信媒体の特性の差を吸収し、上位の層に透過的な伝送路を提供する
代表的なものとして、イーサネットの物理層を規定するIEEE802.3などがある

# ネットワークの伝送時間の計算方法

**伝送時間(s)　=　データ量（Mbite）x 8(bit)　/　回線速度（Mbps）**
**回線速度（Mbps）　=　伝送速度（Mbps）x　伝送効率（％）**

回線は **伝送速度（実行速度）** に対して、実際に出る速度の割合を **伝達効率** というものがあり、これらの計算により、実際の回線速度が求められる
どうして我々にはLadybirdが必要なのか

インターネットブラウザ自体はたくさんありますが、その本体であるブラウザエンジンは現在3種類しかありません。
すなわちGoogleのChromium、MozillaのGecko、AppleのWebKitです。
かつては独自の実装を持っていたMicrosoftもOperaも、あまりに巨大になったコードベースに自力開発を諦めました。

ブラウザエンジンの減少による弊害は様々なところで論じられているのでここでは省略して、以下は新たに登場した第四のブラウザエンジン[Ladybird](https://ladybird.org/)について、開発者Chris Wanstrathによる紹介記事、[Why we need Ladybird](https://ladybird.org/posts/why-ladybird/)の紹介です。


# Why we need Ladybird

Webは現代の最も重要な発明のひとつす。
インターネットの成長に必要不可欠であり、そして我々の生活、仕事、学習、遊びを大きく変えつつあります。
Webは、それが可能にすること全て、そしてその技術が共同で、オープンに構築されてきた方法のいずれについても、驚異的なものです。
現在のWebは、オープンスタンダードとオープンソースの力の証明です。

Webを2000年の暗黒時代から脱却させたのはオープンソース・オープンスタンダードのFirefoxであり、その影響を色濃く植えたChromeであり、2010年代の主役へはばたいたのです。

現在、主要なブラウザエンジンは全てオープンソースです。
これは素晴らしいことですが、しかし問題がひとつ存在します。
それらには全てGoogleの息がかかっているということです。
Chrome・Edge・Brave・Arc・OperaにはGoogleのChromiumが使われています。
またSafariのデフォルト検索エンジンをGoogleにするためにGoogleはAppleに数十億ドルを支払っており、Firefoxとも同様な契約を結んでいます。

Webはたったひとつの資金源に依存するような構造であるべきではなく、さらにその資金源が広告であるとするならなおさらです。

新しいブラウザを作ることは不可能であり、Google Chromeの座を奪うことなど絶対にできないという人もたくさんいます。
しかし、変化をもたらすためにChromeを打ち負かす必要があるわけではありません。
Firefoxがその証拠です。
Firefoxは決して最も人気のあるブラウザではありませんが、全ての主要ブラウザに大きな影響を与え、Webをより良い場所に導いてきました。

新しいブラウザを開発できるかどうか、それはここにあります。

完全にゼロから開発された新しいブラウザであるLadybirdと、Ladybirdブラウザの開発だけが目的であり寄付金のみで運営される非営利団体Ladybird Browser Initiativeこそが、Webに変化をもたらすことができると信じています。

世界に必要なのは、ユーザを第一に考え、オープンスタンダードに貢献し、そして広告の影響を受けないブラウザです。

これこそが、私がAndreasといっしょにLadybird Browser Initiativeを設立し、開発支援のために100万ドルを寄付した理由です。
私はLadybirdの将来を信じており、Andreasのビジョンを信じています。
皆さまをサポートするオープンで独立したブラウザのために、皆さまのサポートをお願いします。


# 感想

Chris Wanstrathは、[GitHub](https://github.co.jp/)の共同創始者CEOです。
他にもテキストエディタ[ATOM](https://github.blog/news-insights/product-news/sunsetting-atom/)、テンプレートエンジン[mustache](https://mustache.github.io/)、Rubyのジョブキュー[Resque](https://resque.github.io/)など様々なソフトウェアの主要開発者でした。
さらに[Null Games](https://null.com/)というのも作ったみたいですが、こちらはあまり情報が出てこないのでよくわかりません。

とまあ、GitHubだけでも非常に大きな実績のある人物なので、新しいブラウザを作り上げるという途方もないプロジェクトですが、よくあるベーパーウェアにはそうそうならないのではないかと思います。
ただ[GitHubアカウント](https://github.com/defunkt)を見てみると、ソースコード的に活躍していたのは2013年あたりまでなんですよね。
それ以降はマネジメント方面に向かったかんじなのでしょうかね。

また[公式サイトのニュース](https://ladybird.org/#news)が全く更新されておらず、公式サイトだけでは進捗状況やインタビューなどがさっぱりわからないのは困りものです。
公式が静かだと進捗が無いようにも見えてしまうので、もう少し更新はしてほしいですよね。
実際ソースコードは[熱心に更新されている](https://github.com/LadybirdBrowser/ladybird/commits/master/)のですが、これが表からぱっと見てわからないのは惜しいところです。

なお、最初のアルファ版リリースが2026年の予定だそうです。
現代のブラウザはあまりに巨大になりすぎているので仕方のない面もありますが、それにしてもやはり先過ぎますね。
出たころには忘れ去られていそう。
初めてのハッカソン参加してみて

# はじめに
先日、参加しているコミュニティのハッカソンに参加しました。「AIで日常を魔法に」というテーマのもと、2日間でアイデアを出し、アプリを開発しました。

今回は初めてのハッカソン参加だったので、その感想や、どのようなアプリを開発したのかについて紹介したいと思います。

:::note info
今回はチームで参加しました。ただし、私は2日目に体調不良となり、実装にはほとんど関与できませんでした。
:::

# 制作物
![画面収録 2024-09-30 17.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835217/b6e6b37a-fd78-1d25-b582-dce05b9080e8.gif)

+ 概要
朝の気分を入力すると、その日の気分に合わせて、前向きになれるメッセージをAIが届けてくれるアプリです。
+ 使用技術
：React、Gemini API

ユーザーがその日の気分を入力すると、AIがポジティブなメッセージを提供し、さらに音声で読み上げる機能も搭載しています。

# 作ろうと思った理由
メンバーと話し合う中で、私たちはどちらも朝が苦手であることがわかりました。しかし、朝の時間を有効に活用できれば、1日全体をより充実させることができます。私自身、最近朝活を始めてからその効果を実感しています。多くの人にとって、朝に前向きな理由があれば起きやすくなるのではないかと考え、朝の時間をポジティブに過ごす手助けをするアプリを開発しようと決めました。

# 参加してみての感想
今回はチームでの参加となり、普段一人で作業することが多い私にとっては新鮮で貴重な経験でした。一方で、自分自身の課題にも気付きました。特に、具体的な実装のイメージがなかなか浮かばず、手が止まることが多かったです。もっと細かくタスクを分割すれば、実装のイメージがより明確になると感じました。

# 最後に
体調不良により2日目にはほとんど参加できなかったのは残念でしたが、自分の実力や課題が明確になり、とても良い経験になりました。次回もこのような機会があれば、ぜひ挑戦したいと思います。
【Swift】NavigationLinkで画面遷移する

## まえがき
この記事はSwift独学者による備忘録です。
万が一誤った記載がある場合は、コメントでご指摘いただけると幸いですm(_ _)m

## 確認環境
XCode Version 15.4
MacOS Sonoma 14.4.1

## Swiftにおける画面遷移について
Swiftの画面遷移には代表的なものが２つあり、そのうちの一つがプッシュ遷移と呼ばれるNavigationLinkを用いた遷移方法です。
プッシュ遷移では、画面が右から左に切り替わります。

もう一つはモーダル遷移といって、画面が下から現れる遷移方法です。
こちらは今回の記事では割愛します。

## コード例
今回は画面を３つ用意し、NavigationLinkを使用して遷移するようにしました。

```Swift:ContentView.swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {
                Text("TOP画面です")
                    .font(.title)
                    .padding()

                // NavigationLinkを使って画面遷移を行う
                NavigationLink(destination: SecondView()) {
                    Text("次の画面へ移動")
                        .padding()
                        .background(Color.green)
                        .foregroundColor(.white)
                        .cornerRadius(10)
                }
            }
            .navigationTitle("TOP画面")
        }
    }
}

struct SecondView: View {
    var body: some View {
        VStack {
            Text("2つ目の画面に遷移しました")
                .font(.title)
                .padding()
        }
        
        NavigationLink(destination: ThirdView()) {
            Text("次の画面へ移動")
                .padding()
                .background(Color.orange)
                .foregroundColor(.white)
                .cornerRadius(10)
        }
    }
}

struct ThirdView: View {
    var body: some View {
        VStack {
            Text("3つ目の画面に遷移しました")
                .font(.title)
                .padding()
        }
        
        NavigationLink(destination: ContentView()) {
            Text("TOPへ戻る")
                .padding()
                .background(Color.pink)
                .foregroundColor(.white)
                .cornerRadius(10)
        }
    }
}

```

それぞれの画面遷移結果は以下です。
| ContentView | SecondView | ThirdView |
| ---- | ---- | ---- |
| <img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3805527/e02137aa-e230-a9b6-407f-ea67ff49cbc7.png"> | <img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3805527/0c022686-afbf-a1aa-758c-0847537da604.png"> | <img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3805527/328ae09c-c308-0750-4106-5eddf33beb97.png"> |

## `.navigationTitle`について
`.navigationTitle`は画面のタイトルとして表示されます。(ContentView参照)

画面遷移すると、左上に表示されるナビゲーションボタン(前画面へ戻るボタン)のテキストとして使用されます。(SecondView参照)

`.navigationTitle`は設定しないことも可能であり、その場合のナビゲーションボタンのテキストは「Back」となります。(ThirdView参照)

## あとがき
簡単にNavigationLinkの使用例をまとめました。
今後も捕捉事項があれば随時更新していきます。
Remix SPA modeでMUIを使用するとビルド時にエラーになる件

# 環境
* pc: MacBookAir 2020 intel model 16gb
*  "vite": "^5.1.0"
*  "remix": "^2.12.1"

参考までに上記はpackage.jsonから抜粋

# ビルド時に発生するエラー原因
viteが自動的に依存関係を最適化する過程で、特定のライブラリを外部化してしまうとエラーが発生するようです。
回避方法はvite.config.tsにnoExternalを追加してエラー原因となるものを明示的に【外部化しない】という指示を追記してあげることで回避できます。

Next.jsではこういったものが必要ありませんでしたが、Remix(vite)を使用していく過程でやはり細かな部分は違いがあるようです。

## MUIとの相性
悪いですね〜。
使うことができないわけではないんですが、こういったエラーの他にSPA modeを使用するとアイコン系でもエラーがでました。
今回はnoExtarnalに追記する方法を記載しましたが、import で各コンポーネントでそのまま@mui/icons-materialを使用するとエラーとなります。
そちらについては下記の記事が参考になりましたので共有いたします。

https://note.com/lizefield/n/na137539931de
## 回避する際の記述
実際に僕が行ったものですとvite.config.tsに下記のssrについての設定でnoExternalを追記しました。
追加した項目はビルドに発生したものです。
ひとまずこちらを追記する形で問題なくビルドできました。

```
export default defineConfig({
  plugins: [
    remix({
      ssr: false,
      future: {
        v3_fetcherPersist: true,
        v3_relativeSplatPath: true,
        v3_throwAbortReason: true,
      },
    }),
    tsconfigPaths(),
  ],
  ssr: {
    noExternal: [
      '@mui/material', 
      '@mui/icons-material',
      '@mui/utils',
      '@mui/system',
      '@mui/styled-engine',
    ]
  }
});

```

## noExternalってなんそれ？
![スクリーンショット 2024-09-30 19.24.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2532739/f93f5df3-d3fd-cc39-0005-0df1bf497679.png)

viteが自動的に特定のモジュールを外部化してバンドルして使うという手法があるのに対し、noExternalを設定することで外部化してバンドルするのを辞めさせることができるという認識

https://ja.vitejs.dev/config/ssr-options

# まとめ
ビルドに発生するMUI系のエラーはnoExternalで防げる
またそれ以外にも外部化しバンドルする挙動でエラーとなるものがある場合はこちらに記載のやり方でvite.config.tsに記載するとよい

以上
汎用性抜群！増減するデータにも対応可能なVLOOKUP関数テンプレート

# はじめに
みなさんはExcelのVLOOKUP関数を利用していて不便を感じた事はございませんか？
この記事ではVLOOKUP関数の引数を工夫して、データが増減しても機能するVLOOKUP関数を紹介します。
※既にVLOOKUP関数の使い方をご存じの方向けの記事となります。
# 作成したVLOOKUP関数
```
=VLOOKUP(検索値,OFFSET($A$1,0,0,COUNTA($A:$A),COUNTA($1:$1)),MATCH("表示させたい列の見出し",$1:$1,0),FALSE)
```
# 使用するエクセルデータサンプル
今回は以下のように1行目に見出しがあり、1列目に検索したい値のあるデータでの利用を紹介します。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2144537/3bf6db85-c7d6-569c-6728-f26d385f2236.png)
# 解説
### VLOOKUP関数の引数について
まずはVLOOKUP関数の引数についてみてみましょう。
```
VLOOKUP(検索値,検索範囲,列数,[検索方法])
```
今回作成したVLOOKUP関数では「検索範囲」と「列数」に「OFFSET関数」、「MATCH関数」を用いてデータの増減に対応できるようにしています。
### 検索範囲について
検索範囲には以下のようにOFFSET関数を用いています。
```
OFFSET($A$1,0,0,COUNTA($A:$A),COUNTA($1:$1))
```
OFFSET関数の引数は以下となります。
```
OFFSET(参照基準, 行数, 列数, [高さ], [幅])
```
参照基準にはVLOOKUP関数で利用する範囲の起点(左上のセル)を指定して、行数、列数は0を指定します。
高さ、幅の値にはCOUNTA関数を用いて、それぞれA:A、1:1と指定することで高さ(値の入っているセルの最大行数)、幅(値の入っているセルの最大列数)が取得できるのでデータが増減しても範囲が狂う事が無くなるようになります。
### 列数について
列数には以下のようにMATCH関数を用いています。
```
MATCH("表示させたい列の見出し",$1:$1,0)
```
※「表示させたい列の見出し」の文言は使用するデータに合わせて変更してみてください

列数にMATCH関数を用いて見出しを検索させる事で視覚的にも表示させたい列が分かりやすくなり、列数が変更された際でも対応した見出しの列数が指定されるため結果が狂う事が無くなるようになります。
# 使用してみた
H列2行目に検索したい値を入力し、I列2行目に関数を入力しました。
尚、出力する値の列(見出し)は「単価」の列としています。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2144537/0905e579-3bcf-4272-92e9-7a96f340a819.png)
### データを追加して正しく出力されるか確認してみた
関数の内容は変更していないが、追加したデータに対する結果が正しく出力されました。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2144537/c9748bad-e12e-d227-815a-73197556520e.png)
# おわりに
いかがだったでしょうか。
今回紹介したVLOOKUP関数をテンプレートとして使用して、少しでもみなさんのお役に立てましたら幸いです。
この記事が良かったと感じたらいいねをお願いします。
Angular入門 ~ zoneless編

## 概要
今回はAngular 14以降導入されたzonelessについてまとめました。zonelessはAngularのZone.jsを使用しないようにするための設定です。zonelessを有効にすると、AngularはZone.jsを使用せずにChange Detectionを実行できます。

:::note info
### Zone.jsとは
AngularのChange Detectionを実行するために使用されるライブラリです。Zone.jsはAngularのコンポーネントが更新されるたびにChange Detectionを実行してコンポーネントのビューを更新します。
Zone.jsの弱点として、特に大規模なアプリケーションでパフォーマンスのオーバーヘッドが問題になることがあります。
:::

:::note warn
プロジェクト全体のソースコードはこちらに置いてあります。
https://github.com/ist-h-i/Angular/tree/main/v-18
:::
## 環境設定
### node -v
v20.17.0

### ng version
Package | Version
— | ---
@angular-devkit/architect | 0.1802.6
@angular-devkit/build-angular | 18.2.6
@angular-devkit/core | 18.2.6 (cli-only)
@angular-devkit/schematics | 18.2.6
@schematics/angular | 18.2.6
rxjs | 7.8.1
typescript | 5.5.4
zone.js | 0.14.10
## 初期構築コマンド
### Angularインストール
npm install -g @angular/cli

### プロジェクト作成
ng new “アプリ名”

### コンポーネント作成
ng g c components/”コンポーネント名”

### node-modulesインストール
npm i

### アプリ起動
npm start
## 実装
上記手順でsignalコンポーネントを作成しています。
### signal.component.html
```html
<input (input)="changeInput($event)">
<p>Signal: {{ signal() }}</p>
```

### forms.component.ts
```typescript
import { Component, NgZone, signal } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';

/**
 * SignalComponent
 *
 * @description
 *  - signalという名前のSignalを生成
 *  - inputイベントが発生した場合、Signalの値を変更
 *  - Signalの値を表示
 *
 * @remarks
 *  - NgZoneをinject
 *  - signalは、UIの更新を伴う
 */
@Component({
  selector: 'app-signal',
  standalone: true,
  imports: [ReactiveFormsModule],
  templateUrl: './signal.component.html',
  styleUrl: './signal.component.scss'
})
export class SignalComponent {
  // signal
  signal = signal('');

  // NgZone（zonelessの場合は不要）
  // private zone: NgZone;

  /**
   * inputイベント
   *
   * @description
   *  - inputイベントが発生した場合、Signalの値を変更
   *  - NgZone.runを使用して、Signalの値を変更
   * @param event inputイベント
   */
  changeInput(event: Event) {
    const inputElement = event.target as HTMLInputElement;

    // NgZone.runを使用して、Signalの値を変更（zonelessの場合は不要）
    // this.zone.run(() => {
      this.signal.set(inputElement.value);
    // })
  }

  // /**
  //  * Constructor
  //  *
  //  * @description
  //  *  - NgZoneをinject（zonelessの場合は不要）
  //  */
  // constructor(zone: NgZone) {
  //   this.zone = zone;
  // }
}
```

### app.config.ts
```typescript
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideClientHydration } from '@angular/platform-browser';

export const appConfig: ApplicationConfig = {
  providers: [
    // zoneless化設定を行う
    provideExperimentalZonelessChangeDetection(),
    provideRouter(routes),
    provideClientHydration()
  ]
};
```
## まとめ
今回はAngular入門第二弾でzonelessへの移行についてまとめました。
zonelessはAngular 18のアップデート目玉のひとつなので使いこなすことができるよう勉強中です。
Standaloneコンポーネント、@forや@ifなどのディレクティブなど近年革新的な更新を続けているAngular、毎回いくつかのメジャーバージョンアップデートを行って苦労している身としては何としても最新バージョンについていきたいところです。
タグベースのマスキングポリシーをdbt-osmosisで伝搬し、dbtで適用する

## やりたいこと

データにタグベースのマスキング
https://docs.snowflake.com/en/user-guide/tag-based-masking-policies
を適用する時、クレンジング以降を毎回手で修正するのはとても辛いので
要件をExcelなどで確定させ、あとはカラムリネージつかって自動で付与したい


```mermaid
graph LR
    RAW --> RAW_SCD
    RAW_SCD --> Cleansing
    Cleansing --> DWH
    DWH --> MART
```

### EXCEL→RAW（YAML）
手間の8割がここ、いい感じにExcel読んでYAMLを更新する

YAMLの処理についてはPyYAMLでは色々問題が出るので

https://pypi.org/project/ruamel.yaml/

を使用し、↓のようにYAMLの定義のカラムにタグを追加で埋め込む
```:xxx.yaml
       columns:
          - name: namae
            description: "なまえ"
            data_type: VARCHAR
            tags:
              - pii_mask_analyst
              - pii_mask_operator
```

読み込みと書き出しについては、以下を指定して引用符とインデントを調整

+ 引用符を保持する
```
yaml.preserve_quotes = True
```

+ インデントの制御

```
yaml.indent(mapping=2, sequence=4, offset=2)
```

詳しくは
https://yaml.readthedocs.io/en/latest/detail/


### RAW/CLEANSING → DWH/MART

+ dbs-osmosis

https://github.com/z3z1ma/dbt-osmosis


```
dbt-osmosis yaml refactor --add-progenitor-to-meta models/cleansing
```
とかで下流に適用していく


### TAGを元にdbt実行時に適用する

+ dbt-tags

https://github.com/infinitelambda/dbt-tags

こちらのパッケージを追加し、post-hookとして適用を行う
今回はTAGは既に作成済みのため、TAGとポリシー作成は割愛

流れとしては
https://dbt-tags.iflambda.com/latest/getting-started.html
ここにある通り

dbt_project.ymlに

+ TAGのスキーマを指定
+ 許可するタグを指定

```yaml
vars:
  dbt_tags__schema: COMMON
  dbt_tags__allowed_tags:
    - pii_mask_analyst
    - pii_mask_operator
```

+ 適用したい範囲で

```
post-hook: {{ dbt_tags.apply_column_tags() }}
```
と追加しておくことでモデル実行後にpost_hookでテーブルにタグが適用できる

## まとめ
流れはとても単純なので、YAMLさえ編集できればとてもサクッと行く

YAMLの読み込みと加工は表記揺れなどでとても泣ける…

## 補足
incrementalやsnapshotのようにテーブルが都度REPLACEされないものについては
unsetするストアドを書いておき

```
post-hook:
    - {{ unset_tags() }}
    - {{ dbt_tags.apply_column_tags() }}
```
のように重ねておく。
1からアプリケーションを作るエンジニアリングマネージャーの姿：要件定義編

## 目的
1. エンジニアリングマネージャーをやっているが、あまりにもエンジニアリングがわかっていない
     - 作業者として実務を行った経験しかなく、0から開発ができない
     - 開発環境の構築とは？
     - アーキテクチャの選定とは？
     - Gitの使い方を忘れている... etc
     - -> これでEMを名乗るのは恥ずかしい
1. 作ってみたいアプリがあるので、それを作って生活をリッチにする
     - ユーザー（私）は人通りが多かったり幅が狭かったりする道が苦手なので、反対に「ここは歩きやすかったぞ！」という道をトレースしたいという要望を持っている



## 要件定義
### 要望ヒアリング
ユーザーはざっくり、以下の機能を求めていた。
1. 地図上の任意の長さの道に対して、色をつけられるようにする
1. 道に点数をつけたい。1~100じゃなくていいので、20点ごとでつけたい
1. 朝、昼、夜でバージョンを変えられるようにする
1. 好きなお店にピンを立てられるようにする

### 動作環境の確認
どんな環境で実行したいかヒアリング
 - 本当はiOSアプリだったら嬉しい
 - でもそれが現状難しいのであれば、一旦Webサイトでいい（モック的に作ってくれたらいい）
 - それが良い感じだったら、おいおいiOSでリリースしてくれたらいい

### ユーザーストーリーマッピング（USP）の作成
ユーザーの要望をもとにUSPを作成し、MVPとNice to Have機能に分割した。
結果は以下の通り、大きく分けて2つの機能を求めていることがわかった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441429/25065e18-bbc5-663a-6aee-1bdf7115bb3d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441429/0182bcb9-84f1-a972-74bf-73c72825e9f1.png)

## インサイト
 - 機能は2つ
 - MVPのPBIは6つだけっぽい
 - 普通に頭から開発していくのがよさそう
     - [Mapが出る] から
PythonでExcelの数式や関数を削除し、データを保持する方法

Excelの表を分析する際、さまざまな数式や関数を使ってデータを計算し、追加の情報を得ることがあります。しかし、分析結果を表示、共有、再利用する際には、数式を含むセルを静的な値に変換して、データを簡略化し、計算結果が変更されないように保護し、データの移植性を向上させたい場合もあります。Pythonを利用すれば、数式や関数を一括で削除しつつ、データを変更せずに保持することが簡単に実現できます。本記事では、**Pythonコードを使用してExcelセル内の数式を一括で削除し、その計算結果を保持する方法**を紹介します。

本記事で使用する方法では、[Spire.XLS for Python](https://jp.e-iceblue.com/introduce/spire-xls-for-python.html)を使用します。PyPIからインストール可能です：`pip install spire.xls`。

## Excelの数式や関数を一括削除し、計算結果を保持する
作業シート内の使用済みの行と列をループ処理し、`Worksheet.Range[]`を使ってセルを取得します。その後、セルに数式や関数が含まれているかどうかを判断し、含まれている場合はそのセルの値を計算結果に設定して、数式や関数を削除する方法をとります。

以下は具体的な手順です：
1. 必要なモジュールをインポートします。
2. `Workbook`オブジェクトを作成し、`Workbook.LoadFromFile()`メソッドを使用してExcelファイルを読み込みます。
3. ワークブック内のワークシートをループ処理し、`Workbook.Worksheets.get_Item()`メソッドを使用してシートを取得します。
4. ワークシート内の行と列をループ処理し、`Worksheet.Range[int: rowIndex, int: colIndex]`プロパティを使用して特定のセルを取得します。
5. セルに数式や関数が含まれているかどうかは、`CellRange.HasFormula`プロパティの値で確認できます。含まれている場合：
    - `CellRange.FormulaValue`プロパティを使用して、数式や関数の計算結果を取得します。
    - `CellRange.Clear(ExcelClearOptions.ClearContent)`メソッドを使用してセルの内容をクリアします。
    - `CellRange.Value`プロパティを使って、取得した計算結果をセルの値として設定します。
6. `Workbook.SaveToFile()`メソッドを使ってワークブックを保存します。
7. リソースを解放します。

**コード例**
```python
from spire.xls import *

# Workbook オブジェクトを作成
workbook = Workbook()

# Excel ワークブックを読み込む
workbook.LoadFromFile("Sample.xlsx")

# すべてのワークシートを繰り返し処理
for sheetIndex in range(workbook.Worksheets.Count):
    # ワークシートを取得
    sheet = workbook.Worksheets.get_Item(sheetIndex)
    # すべてのセルを繰り返し処理
    for rowIndex in range(sheet.Rows.Count):
        for colIndex in range(sheet.Columns.Count):
            # セルを取得
            cell = sheet.Range[rowIndex + 1, colIndex + 1]
            # セルに数式があるかどうか確認
            if cell.HasFormula:
                # 数式の結果を取得
                formulaValue = cell.FormulaValue
                # セルの内容をクリア
                cell.Clear(ExcelClearOptions.ClearContent)
                # セルの値を数式の結果に設定
                cell.Value = formulaValue

# ワークブックを保存
workbook.SaveToFile("output/ClearFormula.xlsx", FileFormat.Version2016)
workbook.Dispose()
```

結果ファイル
![2024-09-30_170504.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/c84a0d7d-9ef8-67c8-a18d-909854374d63.png)

**[無料ライセンスの申請](https://www.e-iceblue.com/TemLicense.html)**

本記事では、Pythonを使用してExcel内の数式や関数を削除し、その計算結果を保持する方法について説明しました。
Midjourney API の様々な使用例

[Midjourney](https://www.midjourney.com/home) は、テキストの説明から驚くべき画像を作成する興奮するAIツールです。公開APIはありませんが、それでも多くのクールなことに非常に役立ちます。Midjourneyを使用している人々の楽しい方法をいくつか見てみましょう：

- ### 創造的なコンテンツ制作
アーティストやデザイナーは、新しいアイデアを生み出すためにMidjourneyを使用しています。彼らは奇抜な概念を入力し、AIが何を生み出すかを見ることができ、しばしば自分では思いつかなかったようなユニークなアートワークやデザインにつながります。デジタルミューズを持っているようなものです！

- ### ソーシャルメディアの楽しみ
人々はMidjourneyの作品をソーシャルメディアで共有することを楽しんでいます。架空の映画ポスターから幻想的な風景まで、ユーザーは多くのいいねやコメントを集める目を引く投稿を作成しています。混雑したフィードの中で目立つ素晴らしい方法です。

- ### 本とゲームのイラスト
著者やゲーム開発者は、彼らの物語に命を吹き込むためにMidjourneyを使用しています。キャラクター、設定、または魔法の生き物の画像を素早く生成し、読者やプレイヤーに想像の世界の視覚的な味わいを提供することができます。

- ### ミーム制作
Midjourneyはミーム制作者の夢です。ユーザーは面白い、奇妙な、または驚くべき画像を生成し、ミームに最適です。インターネットのユーモアに全く新しい次元を加えています。

- ### コンセプトアートとストーリーボード
映画やアニメーションの専門家は、シーンやキャラクターを素早く視覚化するためにMidjourneyを使用しています。これはブレインストーミングのための素晴らしいツールであり、より詳細なアートワークに投資する前にチームが視覚的な方向性に同意するのに役立ちます。

- ### ファッションと製品デザインのインスピレーション
デザイナーは新しいスタイルと製品のアイデアを探求するためにMidjourneyを使用しています。革新的なコンセプトを説明することで、潜在的なデザインを素早くレンダリングして見ることができ、ファッション、家具などで創造性を刺激します。


Midjourneyは、私たちが視覚的なコンテンツを作成し想像する方法を変えています。アートとデザインからソーシャルメディアとストーリーテリングまで、創造性の新しい可能性を開いています。技術が成長するにつれて、さらに多くのエキサイティングな使用法が登場することは間違いありません。AI支援イメージの未来は明るく、驚きに満ちています！APIがあれば完全に活用できると考え、この[Midjourney API](https://www.apiframe.pro/)を作成しました。
【機械学習】パーセプトロンの実装してみた【Python】

## 初めに
この記事は、大学院時代に機械学習や統計を扱う研究室にいた筆者？が、社会人になり使う機会もなく、せっかく学んだことを忘れるのも嫌なので記事数稼ぎもかねて再学習をするというものです。
しばらくは私が大学院時代に使用していた以下の本の内容をやっていこうと思います。

[[第2版]Python 機械学習プログラミング 達人データサイエンティストによる理論と実践](https://www.amazon.co.jp/Python-%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E9%81%94%E4%BA%BA%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B5%E3%82%A4%E3%82%A8%E3%83%B3%E3%83%86%E3%82%A3%E3%82%B9%E3%83%88%E3%81%AB%E3%82%88%E3%82%8B%E7%90%86%E8%AB%96%E3%81%A8%E5%AE%9F%E8%B7%B5-impress-gear/dp/4295003379)

私が使っていたのは第2版ですが、すでに第3版が発行されているので、これから買おうという人は第3版をお勧めします。

## 内容
今回はパーセプトロンの実装をします。

## 理論：パーセプトロンとは
パーセプトロンは、人工知能と機械学習の分野において最も基本的なニューラルネットワークモデルの一つで、Frank Rosenblattによって考案されました。
人間の脳の神経細胞の働きを模倣しており、入力層と出力層からなる単純な構造を持ちます。
数理的には決定関数という関数でできており、入力データに対して重み付けを行い、その総和を計算する関数です。各入力には重みが割り当てられ、これらの重み付き入力の総和が計算されます。この総和が特定のしきい値を超えるかどうかで予測が決まります。

また、パーセプトロンは線形分離可能なデータセットにのみ適用可能ですので注意してください。

## コードの実装
###データセットのロードと加工
今回パーセプトロンのトレーニングに使用するIrisのデータセットをロードし、トレーニング用とテスト用に加工します。
```
from sklearn import datasets
import numpy as np
iris = datasets.load_iris() #Irisデータセットをロード
X = iris.data[:, [2,3]] #3,4列目の特徴量を抽出
y = iris.target #クラスラベルを取得

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=1, stratify=y
) #トレーニングデータとテストデータに分割、全体の30%をテストデータに

from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
sc.fit(X_train) #トレーニングデータの平均と標準偏差を計算
X_train_std = sc.transform(X_train)
X_test_std = sc.transform(X_test)
```

### モデルのインポートと学習データのフィット
パーセプトロンモデルをsklearnからインポートし、データを学習させます。
```
from sklearn.linear_model import Perceptron
ppn = Perceptron(max_iter=40, eta0=0.1,random_state=1) 
ppn.fit(X_train_std, y_train)
```
### 予測
テストデータを使用して予測を行い、誤分類の個数を算出します。
```
from sklearn.linear_model import Perceptron
ppn = Perceptron(max_iter=40, eta0=0.1,random_state=1) #n_iterでなくmax_iter
ppn.fit(X_train_std, y_train)

y_pred = ppn.predict(X_test_std)
print('Misclassified samples: %d' % (y_test != y_pred).sum()) #テストと予測が一致しない＝誤分類の個数を表示

output
ーーーーーーーーーーーーーーーーーーーーーーーーー
Misclassified samples: 1
```
正解率を算出します。
```
from sklearn.metrics import accuracy_score
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))

output
ーーーーーーーーーーーーーーーーーーーーーーーーー
Accuracy: 0.98
```

## 終わりに
こんな感じにパーセプトロンの実装ができました。
[Strategy] 経営分析

# 一覧
|||
|:--|:--|
|ファイブフォース分析|企業を取り巻く環境を分析する<br>``新規参入者の脅威``,``売り手の交渉力``,``買い手の交渉力``,``代替品の脅威``,``競争業者間の敵対関係``|
|PPM|資金を生み出す事業と投資が必要な事業を区別する<br>``花形``,``負け犬``,<br>``問題児``(市場成長率高い=投資必須),<br>``金のなる木(市場占有率高い=資金源)``|
|PEST分析|自社ではコントロールできない、外部環境要因を分析する<br>``Politics``,``Economics``,``Society``,``Technology``|
|3C分析|PEST分析よりも、個別具体的な分析を行う<br>``Customer``,``Competitor``,``Company``|
|SWOT分析|経営資源(内部)と経営環境(外部)から自社の置かれている状況を分析する<br>内部環境: ``Strength``,``Weakness``<br>外部環境: ``Opportunity``,``Threat``|
|アンゾフの成長マトリクス|製品と市場の視点から事業の成長戦略を分析する<br>``市場浸透``,``製品開発``,``市場開拓``,``多角化``|
|バリューチェーン分析|製品やサービスの付加価値(利益)が事業活動のどの部分で生み出されているかを分析する<br>モノの流れに沿う主活動、モノの流れに沿わない（独立した）支援活動|
|CSF分析|重要成功要因を明らかにする手法<br>CSFの抽出にはSWOT分析が使用される|
|バランススコアカード|企業活動を4つの視点で分析し、KGI、CSF、KPI、アクションプランを策定する。<br>`財務`、`顧客`、`内部ビジネス`、`学習と成長`|

# 参考リンク
- [H28A68_アンゾフの成長マトリクス](https://www.ap-siken.com/kakomon/28_aki/q68.html#:~:text=アンゾフの成長マトリクスは,マトリクスとしたものです%E3%80%82)
- [R4S68_アンゾフの成長マトリクス](https://www.ap-siken.com/kakomon/04_haru/q68.html)
- [R5A67_アンゾフの成長マトリクス](https://www.ap-siken.com/kakomon/05_aki/q67.html)
- [R6S68_ファイブフォース分析](https://www.ap-siken.com/kakomon/06_haru/q68.html)
Git操作を楽にするためにやってきたこと

# はじめに

Git操作をいくらかでも楽にしようと、過去にやってみたこと・現在やっていることを紹介します。より快適なGit操作のための参考になれば嬉しいです。

なお自分は普段の開発にMacを使用しており、一部の情報がMac向けに偏っている可能性があります。その点ご容赦ください。

# git-prompt / git-completion

git-promptを導入すると、ブランチ名や未コミットの変更の有無といった情報がターミナルのプロンプトに表示されます。おかげで`git status`や`git branch`を打たずとも、リポジトリの状態を把握できます。

またgit-completionを導入すると、Gitのコマンドやブランチ名にTab補完が効くため、コマンドの入力が楽になります。

設定方法については、こちらの記事にわかりやすくまとまっていました。

https://qiita.com/mikan3rd/items/d41a8ca26523f950ea9d

シェルプロンプトのカスタマイズに[starship](https://github.com/starship/starship)を使えば、自力でgit-prompt・git-completionを導入せずともそれらと同様の機能を得られます。(自分もstarshipを使っています。)

https://github.com/starship/starship

[Warp](https://www.warp.dev/)のように、同様の機能が組み込まれたターミナルを使うのも良いでしょう。

https://www.warp.dev/

# エイリアス

Gitエイリアスを追加することで、コマンド実行に必要な入力を短くすることができます。例えば、以下を実行すると、`git co`と打つだけで`git checkout`と同等のことを行えるようになります。
```shell
git config --global alias.co checkout
```

`git`と打つのも面倒であれば、zshエイリアスを追加しましょう。
```shell:~/.zshrc
alias gco="git checkout"
```
これで`gco`と打てば`git checkout`と同等のことを行えます。

便利なコマンドを作ってエイリアス登録しておくのも良いでしょう。例えば[Gum](https://github.com/charmbracelet/gum)というツールを使うと、「ローカルブランチを選択して一括削除」といったコマンドを簡単に作成できます。
```shell
git branch | cut -c 3- | gum choose --no-limit | xargs git branch -D
```
![スクリーンショット 2024-09-30 17.21.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/777885/6fb30f56-ed59-6abe-d31a-1b765350ade3.png)

これを`~/.zshrc`でエイリアス登録しておけば呼び出しやすくなりますね。

https://github.com/charmbracelet/gum

# GUIツール
VSCodeやJetBrains製品などのエディタには、Git操作のためのGUIが備わっています。これらを使うと、特にファイルの変更差分の把握やコンフリクトの解消なんかがやりやすくなります。[Sourcetree](https://www.sourcetreeapp.com/)のようなGUIツールを使うのも良いですね。

https://www.sourcetreeapp.com/

# Lazygit
[Lazygit](https://github.com/jesseduffield/lazygit)はターミナルUIでGit操作を行うためのツールです。

https://github.com/jesseduffield/lazygit

Lazygitを使うとVimライクな少ないキー操作でGit操作を行えます。またリポジトリに関する情報を画面いっぱいに表示してくれるため、一度に多くの情報を確認できます。

この「操作の楽さ」と「情報量の多さ」が自分にとって非常に使いやすく、現在自分のGit操作の大部分がこのLazygitに支えられています。

# まとめ
Git操作を楽にするためにやってきたこととして、以下の方法・ツールを紹介してきました。

- git-prompt / git-completion
- エイリアス
- GUIツール
- Lazygit

Git操作をより快適にするためのヒントになれば幸いです。
Web技術の基本用語説明

#### 『プロになるためのWeb技術入門』――なぜ，あなたはWebシステムを開発できないのか
この本から学んだことについて自分の言葉でまとめてみる。
尚、わかりにくい場合は具体例をつけてわかりやすく説明する。

### 1. ステートフル
コンピュータやアプリが前のやりとりをした記憶を覚えている状態のこと。
ステートフルはサーバー中心の仕組み

具体例：オンラインショッピングサイトの「カート」機能

説明：たとえば、Amazonで商品をカートに入れると、そのカートの中身を次にサイトにアクセスしたときも覚えてくれます。これがステートフルなシステムの例で、サーバーがあなたの選んだ商品を覚えていて、次回もその状態を維持します。このように「カートの中身」という状態（ステート）をサーバーが保持しているため、「ステートフル」と呼ばれます。

---

### 2. ステートレス
コンピュータやアプリが前のやりとりをした記憶を覚えていないこと。毎回データがリセットされた状態からスタートする。

具体例：Google検索

説明：Googleで何かを検索するたびに、前に何を検索したか覚えていないので、毎回新しいリクエストとして扱われます。これは「ステートレス」なシステムの例で、Googleのサーバーは1つ1つの検索リクエストを独立したものとして処理します。前のリクエストを覚えていないため、過去の検索履歴はその場では使われません。

---

### 3. リクエスト
「リクエスト」は、「これをして！」とお願いすること。たとえば、インターネットで「昨日のサッカーの情報を教えて」って頼むのがリクエスト。

---

### 4. レスポンス
「レスポンス」は、リクエストの返事だよ。「昨日のサッカーの情報を教えて」とリクエストすると、サーバーが「これが昨日のサッカーの情報だよ！」と返してくれる。

---

### 5. クッキー
「クッキー」は、インターネット上であらゆる情報を一時的に覚えておくためのデータのこと。クッキーはブラウザ（ユーザー側）中心の仕組み

具体例：ウェブサイトのログイン状態

説明：たとえば、TwitterやFacebookにログインすると、次回アクセスしたときもログイン状態が維持されていることがあります。これは「クッキー」によって、あなたのログイン情報が一時的に保存されているからです。クッキーのおかげで、毎回ログインし直さなくても、すぐに利用できるようになります。

---

### 6. プロトコル
コンピュータ同士がやりとりするための「ルール」だよ。例えば、手紙を書くときにも「住所を書いてから名前を書く」といった決まりがある。それと同じで、コンピュータもデータをやりとりするときに、どういう順番やルールで送るかが決まっている。

具体例：ウェブサイト閲覧時の「HTTP」や「HTTPS」

説明：たとえば、ウェブサイトにアクセスする際に、ブラウザのURL欄に「http://」や「https://」と表示されることがあります。これが「HTTP」や「HTTPS」というプロトコルで、サーバーとあなたのブラウザがどうやってやりとりするかのルールを決めています。「HTTPS」は特にデータを暗号化して安全に通信するルールです。


---

### 7. ポート番号
「ポート番号」は、コンピュータがインターネットでデータをやりとりするときに使う「入口」や「部屋番号」のようなものだよ。1つのコンピュータにはいろんなプログラムが動いているけど、それぞれがどこにデータを送ればいいかをポート番号で教えている。

具体例：ウェブサーバーのポート番号「80」や「443」

説明：ウェブサイトにアクセスするとき、通常、HTTP通信はポート番号「80」、HTTPS通信はポート番号「443」を使います。たとえば、ウェブブラウザがサーバーにリクエストを送るとき、データはポート番号「80」や「443」を通じてサーバーに届きます。ポート番号によって、どのサービスにリクエストを送るかがわかるようになっています。

---
「就職に有利」というモチベで取得したIT資格は役に立たない

# 記事を書いた経緯
私自身、ベンダー資格（AWS SAP, Security）や基本情報などの資格を持っている。
しかし、現場面談、転職活動などのシーンで大して活きたことはないと感じる。
それは、 __「その資格を取得するための豆知識・小手先の技術」__ は身についたが、
__「その資格を取得して現場で活かせるほどの知識」__ が身についていないからだと思う。

※ただしこれはあくまで開発経験がある人の話で、開発未経験の人が基本情報持っているというのはすごいことだと思う。IT業界ではなめられがちな資格だが、かなりちゃんと勉強しないと取れない資格だと思うので十分やる気のアピールにはなると思う。

# 資格をゴールにするな
AWSの資格持ってます！
じゃああれとあれ使って、こういうの作れる？
・・・。

きっとこうなってしまうのは、資格を取ることを目標として取得してしまっているから。
資格勉強をする上で大事なことは、その資格を取って現場で活かせるだけの実力を身に付けること。
資格は「持ってればいいですよ」というものじゃなくて、
「これに受かるだけの人なんで、これくらいの実力がある人ですよ」の証明だと思う。
なので、それに伴う実力がないのにただ資格を持っているということは足かせにすらなりかねない。
「あぁ、この人は何も考えず資格を取得しているんだな」と。


# 目的を明確にして、必要性を作る
資格を取りたい！という気持ちはすごく大事だと思う。
勉強したい、学びたいという思いは持ち続けて損はない。
でも資格を取るのならモチベーション高く学び、最終的に資格を取得したなりの実力を身に付けて、それを現場で活かせるようにならないといけない。
そのためには **目標を出来る限り明確にすること**が大事だと思う。
いつまでにそれを取って、
どんなことを学んで、
どんなことに役立てて、
その先に何をしたいのか？
どんな自分になるためにそれを取りたいのか？
というのをとにかく**明確**にする。
これ以上ないくらい明確にする。
すると、自分の中にその資格を取る**必要性**が生まれてくる。

必要があると、人は動き出す。
取る必要性あるんだっけ？という負の誘惑に負けることなく、動き続けることが出来る。
**必要なことだけを取捨選択して行うようになる。**

すると、学ぶ内容・学び方が変わってくる。
何故ならそれが今後自分のキャリア・現場作業に必要だと明確に理解しているから。
とりあえず暗記で点取れればいいや！がなくなってくる。

**そもそも資格とる必要ないな、という結論になるかもしれない。**
それでいいと思う。
資格を取るというのは膨大な時間を使う。
それだけ、命を、人生を削っていると思う。
そこまでした対価が「ただ履歴書に無駄な一文を増やすだけ」になってしまっては、時間の無駄だ。
その時間でお金を稼いだり、現場の技術を研究したり、ビジネスを学んだり、友達と遊んでリフレッシュするほうがよほど有意義だ。


# 最悪のモチベーション
「かっこいいから」「転職に有利だから」「みんな持ってるから」「なんとなく学んでみようと思った」「自己研鑽のため」
これらはモチベーションとしては**最悪**だと思う。
何故なら資格を取ること自体がゴールで、
現場で活きる知識・実力が身につかないから。
（勉強習慣は身につくかもしれないが）
こんな気持ちでやるくらいなら、今人生を遊んで楽しむほうが余程いい。

時に「自分の周りの人は立派な資格を持っていて・・・」とか思うかもしれない。
でもそんなのは関係ない。
ただ持ってるだけで何の実力もない可能性はかなりあるし、
そもそも資格を取ったくらいじゃおいつけないほどの実力・モチベーションの差があるかもしれない。

資格を通して得られるその知識が今後の**自分の**やりたいことの実現に**必要だから取る**というのをしていくべきだと思う。

# 最後に
資格を取ろうと思ったその時、まず必要性を考えるべきだと思う。
**資格のその先に何を見据えるか？** がしっかりしていないと「学ぶ意味あるのか？」と揺れる。
ITはあまりに分野が多く学ぶべきことが多いので、ひとつの指針として、とっかかりとして学ぶのはありだと思う。
だが、その先にしっかりと明確に、取る理由を持つべきだ。
でないと時間の無駄になってしまう。
履歴書に一行、無駄な文字列が増えるだけだ。
**そしてその一行が変に期待を増大させ、最終的に自分の首を絞めるかもしれない。**

間違ってもそれを**アピール材料として使えるから** という気持ちでとらないこと。
そういう気持ちでとった資格は何の役にも立たない。

## 余談
資格を持ってると書類選考とかは通りやすい。
けど結局面接でボロが出て落ちる。
めっちゃ美味しいですよ～！って言って出てきた料理がそこまでだった…という気分にさせてしまうのだろう。
それでも資格が欲しいなら、**資格負けしない自分** を作っていくこと、
**資格を取った動機**を明確にすることが大事。
LaTeX Workshop から latexmk を呼び出すまでの流れ

こんにちは。とある大学院生です。

前回、[LaTeX Workshop はどのように TeX ソースをコンパイルしているのか](https://qiita.com/Summer498/items/4a39976c8c1543e8b69c)という記事にて、 LaTeX Workshop が VS Code の `settings.json` をどのように解釈しているのかの記事を書きました（と言っても公式ドキュメントを和訳しただけですが）

その続きとして、更に別のファイルを読み込む必要のある latexmk を呼び出すまでの流れを書いていきます。

# `settings.json`
前回の記事と重複しますが、 まず LaTeX Workshop が `settings.json` を読みに行きます。

`settings` からレシピが読み込まれて、通常一番上にあるものが実行されます。

```settings.json
"latex-workshop.latex.recipes": [
  {
    "name": "latexmk",
    "tools": [
      "latexmk"
    ]
  }
]
```

ここから更に `"tools"` と同じ `"name"` を持つオブジェクトが `latex-workshop.latex.tools` から読み込まれて、そこに記述されたコマンドが実行されます

```settings.json
"latex-workshop.latex.tools": [
  {
    "name": "latexmk",
    "command": "latexmk",
    "args": [
      "-synctex=1",
      "-interaction=nonstopmode",
      "-file-line-error",
      "-pdf",
      "-outdir=%OUTDIR%",
      "%DOC%"
    ],
    "env": {}
  }
]
```

この場合は `latexmk -synctex=1 -interaction=nonstopmode -file-line-error -pdf -outdir=%OUTDIR% %DOC` が実行されています。

なお、この中の `%OUTDIR%` や `%DOC%` は VS Code で利用できる環境変数です (command prompt で環境変数を呼び出す文法と同じなのは開発元が同じ Microsoft だからかしら)

# `.latexmkrc`
`settings.json` から `latexmk` が呼び出された後に、 `%HOME%` ディレクトリにある `.latexmkrc` ファイルが呼び出されます。

- OS の違いについての補足: 
  - Windows で環境変数 `%HOME%` を設定しているとこのような動作をします
  - 設定がない場合は多分 `%USERPROFILE%` と同じ値になっていたと思います
  - UNIX では環境変数 `$HOME` の `.latexmkrc` ファイルを読み込みに行きます

# おわりに
この記事は LaTeX Workshop 内部でどういう流れで処理が行われるのかを記述しているものです。

このため、単体では直接的な問題解決の役に立たないかもしれませんが、処理の流れを知っておくことで、どこで問題が発生しているのかを特定するための見通しをつけやすくなると思います。
【試す】CloudWatchのカスタムメトリクス

# はじめに
EC2からCloudWatchに対してカスタムメトリクスの転送を試します。
閲覧して頂いた方が実際に検証しなくともイメージが沸くことを目指します。

試したいと思い至った理由は、仕事でカスタムメトリクスの利用要件があったのですが、
触ったことが無かったため。

#### ■CloudWatchのカスタムメトリクスとは？
AWS CLIまたはAPIを使用して、独自のメトリクスをCloudWatchに発行できるというもの。
例えば標準メトリクスはメモリ使用率が取得できない為、要件がある場合カスタムメトリクスを利用する。
　※標準メトリクスには何があるのか等は本記事の趣旨から外れるので記載しない。

#### ■費用は？
CloudWatchのカスタムメトリクスについて、以下条件は無期限で無料枠でした。
　※今回のカスタムメトリクス利用範囲では無料でした。

★無料枠の条件
・10個のカスタムメトリクスと10個のアラーム
・100万件のAPIリクエスト
・5GBのログデータの取り込み及び5GBのログデータのアーカイブ
・毎月最大50メトリクスのダッシュボード3個


#### ◼️検証シナリオ
検証内容ですが、シンプルにEC2からVPCEndpoint経由で、
CloudWacthにカスタムメトリクスを転送する。転送結果をCloudWatchから確認する。

★手順
1.EC2用IAMロール作成
2.EC2構築
3.VPCEndpoint作成(CloudWatch用)
4.カスタムメトリクス転送(put-metric-dataを何回か実行)
5.CloudWatchから転送された情報を確認
　※VPCEndpointは作成時から費用かかります。(費用は変動するため、都度確認推奨)


#### ・検証構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852164/f4a9bf03-39c8-3769-8ce8-a718e72ab006.png)

#### 1.EC2用IAMロール作成
適当にEC2用ロールを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852164/faf85375-1f22-36b7-5862-31b26f4f5c73.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852164/f81d89d6-6a1e-473d-2faf-f6bb082bc741.png)

#### 2.EC2構築
EC2は無料枠でAmazonLinuxを構築しました。

作成できたことを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852164/fb848b43-fcb5-da91-d99e-311db1941d0d.png)


#### 3.VPCEndpoint作成(CloudWatch用)
サービスはCloudWatchではなく、monitoringで検索する必要があります。
検索して選択し、エンドポイント作成します。
　※Endpointポリシーはフルアクセスとしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852164/67f49af1-c9c1-72a6-80d5-346f65d4f01d.png)

作成できたことを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852164/e2dc04a6-5c18-5906-9098-1ae8df8d6cfe.png)

#### 4.カスタムメトリクス転送
EC2にログインし、put-metric-dataコマンドを以下引数で実行。

namespace:TestCW
metric-name:Testmemory
dimensions:TestKey=TestValue
value:数字(画像では20としている)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852164/15da0c7e-04fc-11c7-50ef-968b5de6a5b0.png)

#### 5.CloudWatchから転送された情報を確認
MCからCloudWatch確認するとちゃんと送られてますね。(嬉しい)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852164/4a0422e0-a731-d2fd-83e1-ef0e441660c0.png)

グラフも確認できました。(valueは1回目を10、2回目を20としています。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852164/d70fe090-64c9-6acb-d6b6-33a8e2b84c2b.png)

値を変えてもう一回打鍵しました。(valueを3回目30としています。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852164/c717583c-3d08-66ad-63ea-33882e411977.png)

時刻は勝手にCloudWatch側で記録してくれるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852164/33612a8c-be29-568d-c179-95d1fecef5b7.png)

検証は以上になります。

### ■ミスしたところ
しょうもないところで引っかかったのですが、
VPCエンドポイント作成後、EC2からVPCエンドポイント経由で「put-metric-data」コマンドが発行できませんでした。
原因はVPCエンドポイントのセキュリティグループでEC2からの通信を許可してなかったというものでした。。よくあることだと思いますが、気を付けます。

# さいごに
実践向けにはシェルやcronを組み合わせたリ、カスタムメトリクスにアラームを作成したりすることで、運用として利用できるものになると思いますので、まだまだスタートラインに立ったところです。
ただ、今回カスタムメトリクスが実際に転送できたことは自信につながる良い経験になったと思います。
また、閲覧して頂いた方が本記事を通して疑似的に経験し、カスタムメトリクスは簡単に利用できると思っていただければ良いなと思います。
クレジットカードの明細を検索できるサービスをモダンな技術セットで作ってみた

個人開発したアプリの紹介記事です。

## どんなアプリか？

皆さん、毎月クレジットカードの明細は確認していますか？

クレジットカードを使うとき、見慣れない明細を見たとき不安になりませんか？

クレジットの明細を投稿・閲覧できるサイトをGolangとAWSを用いて作成しました。

https://meisaicheck.tech/

## 技術セット
今回は、S3の静的ホスティング機能を使いました。また、独自ドメインを取得して、Cloudfrontを使うことで、hptts通信でアクセスできるようにしました。
ホスティングしているのは、htmlファイルですが、デザインはtailwindCssを使い、jsフレームワークにalpine.jsを使いました。
バックエンドには、lambdaとgolangを用い、DBとしてDynamoDBを採用しました。

自分としては、lambdaのハンズオンを少しやったことがある程度で、golangとDynamoDBは初めて触りました。
それほど難しい操作は実装していませんが、それでも難しかったです。

## 技術的に苦労したことや発見など
今回、S3の静的ホスティング機能を使うため、フロント側のコードを1つのファイルにまとめる必要がありました。そのため、別のコンテンツ（ページ）に遷移するために、新しくファイルを作成することはできません（つまり、俗にいうペライチになる）

※もしかしたら、aタグのリンク先に、S3に配置した別ページのURLを設定しておけば、複数ページのWebサイトを作成することが出来るかもしれません。

ペライチなので、同じURL内で、モーダルなどをうまく活用しながら、投稿フォームや投稿詳細情報などを切り替えて表示していかなくてはいけません。また、CSSやJSの記述も、そのindex.htmlファイル内で行う必要があります。



また、alpine.jsやtailwindなどのパッケージについては、CDNで取得しています。本家のサイトにもありますが、本番環境での構築でCDNを使うことは非推奨です。npmやyarnなどのパッケージマネージャーを使いたい場合は、S3ホスティングはあきらめた方が良いです。



どうしてDynamoDBを使ったのか？
一つ目は私自身の勉強のためです。NoSQLデータベースを勉強したかったからです。スキーマレスであることやコマンド発行の仕方が独特でした。
エイリアスを使って、プレースホルダーで変数をSQLに埋め込む仕組みには馴染み深かったです。


もう一つは、予算の問題です。なるべく低予算で作りたいと思いました。AWSにはありがたいことに、様々なリソースの無料枠があります。MySQLなども使えるRDSも、1年間の無料枠がありますが、コスト的に使いずらいです。一番小さいdb.t3.microでも3,000円ほどかかります。1年後、月々3,000円も支払うのはきついです。1年以内に




このサービスは、ユーザーに投稿してもらうコンテンツの質と量が重要です。いきなりバズることはあり得ないので、少しずつユーザーを増やし、投稿してもらうことが重要です。
そのため、なるべく低価格で運用できることを第一に考えました。



## 技術セット


CloudFront,S3,ApiGateway,Lambda,DyanmoDB



![クレジット明細アプリ.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1851421/cc8bfdbf-3c69-6ad4-83f8-8f3732671fc8.png)