OmniAICreator/Qiita-1.07M huggingface dataset:
去年の９月からプログラミングの勉強を始めた文系大学2年生現状報告

# 全ての始まり
流れで言うと高校生の時、プログラミングに惹かれてprogateを使ったりなどして勉強をちょこちょこしていましたが、挫折の繰り返しでした。

大学受験に成功してからの約5ヶ月は何もせずただスマホをしたりゲームをしたり、単位を落としたりなど、ただ時間を潰す日々でした。

## Swift
そして９月に「このままじゃあかんわ。」と思いプログラミングの勉強を再開しました。

最初に手をつけたのは「Swift」です。

自分がMacbookを持っていたこともあり、iosアプリを作ろうと思い勉強を始めました。
自分で情報をひたすら調べて勉強をしていました。

その頃、お世話になったサイトが
https://www.hackingwithswift.com/100/swiftui
この「Hacking with Swift」というサイトです。

とてもわかりやすく初心者である僕にはとても助けられました。

## ReactNative
しばらく「Swift」をメインに勉強していましたが、２月に「ReactNative」の存在を知ります。

「ReactNative」はiosとAndroid両方の同時開発が可能でAmazonなどの大企業に採用されており、凄いとなり勉強を始めました。
ReactNativeCLIで環境構築をしたため大変時間がかかりました。

ですがエラーだったものをクリアする感覚がとても気分良く感じ、へこたれることはありませんでした。

## 進路変更（React,Django）
そこから開発に向けて勉強を進めていましたが、モバイルアプリ開発はリリースに審査が厳しいこともあり、Webアプリ開発に進路を変更します。
そして見つけたフレームワークが「React」と「Django」です。

今までフロントエンド言語だけでバックエンドも解決しようとしており、「Django」の存在を知り、「これが足らんかったんか」と気づきます。

いざ「Django」を勉強してみると、バックエンド処理の山だらけ。僕が必要としていた機能ばかりドキュメントに出てきたのです。

「Django」の勉強は３日前からしています。環境構築で少し手こずりましたが、公式ドキュメントのチュートリアルを勉強して今に至ります。

現在はチュートリアルのはじめてのDjangoアプリ作成③を始めたところです。

何か変更があり次第、ご報告いたします。
【Laravel6 / Vue2】authを使ってログアウト処理

完全honaki用
悪しからず

## コード
```api.php
Auth::routes();
```
```HeaderComponent.vue
<template>
    <div class="container-fluid bg-dark mb-3">
        <div class="container">
            <nav class="navbar navbar-dark">
                <span class="navbar-brand mb-0 h1">Budget Management</span>
                <div>
                    // ⭐️↓ここ
                    <button class="btn btn-danger" @click="logout">ログアウト</button>
                </div>
            </nav>
        </div>
    </div>
</template>
<script>
    export default {
        data: function () {
        },
        methods: {
            // ⭐️↓ここ
            logout(){
                axios.post('/api/logout')
                setTimeout(function () {
                    window.location.href = '/login'
                })
            },
        }
    }
</script>
```

## 補足
```
logout(){
    axios.post('/api/logout')
    //⭐️↓ここ
    setTimeout(function () {
        window.location.href = '/login'
    })
},
```
本来は⭐️の箇所を「this.$router.push」など別の方法で遷移したかったが、
loginに関して一切Vueを使っていないため
下記のログアウト処理後に
```
axios.post('/api/logout')
```
下記の処理で
```
setTimeout(function () {
    window.location.href = '/login'
})
```
loginページへ遷移するようにゴリ押ししました。
ブラウザと更新系API  番号C01

# はじめに　この記事を読んでわかること
サーバAの更新リクエストが、ブラウザトリガーの場合のサーバ間通信のタイムアウトの設計時に考慮すべきことをメモする。

# 正常ケース
#### 正常
更新リクエストがサーバBで正常に処理されて、サーバAがレスポンスを受信。
```plantuml
ブラウザ->サーバA : HTTPリクエスト　　　　　　　　　　　　　
サーバA->サーバB : 更新リクエスト
note right:処理済み
サーバB-->サーバA:OK
note left:状態遷移　初期状態→処理済み
サーバA-->ブラウザ
```

#### 業務エラー
更新リクエストがサーバBで業務エラーと判定された場合。
```plantuml
ブラウザ->サーバA : HTTPリクエスト　　　　　　　　　　　　　
サーバA->サーバB : 更新リクエスト
note right:業務エラーと判定
サーバB-->サーバA:業務エラー
note left:状態遷移　初期状態→業務エラー
サーバA-->ブラウザ:業務エラー
```

# タイムアウト
#### 更新リクエストがタイムアウト
更新リクエストがサーバBで正常に処理されて、サーバAがレスポンスを受信。
```plantuml
ブラウザ->サーバA : HTTPリクエスト　　　　　　　　　　　　　
サーバA->x サーバB : 更新リクエスト RequestID=001
note left:状態遷移　初期状態→不明
サーバA-->ブラウザ:「もう一度やり直してください」
ブラウザ->サーバA : HTTPリクエスト　　　　　　　　　　　　　
サーバA->x サーバB : 更新リクエスト RequestID=002
note left:状態遷移　初期状態→不明
サーバA-->ブラウザ:「もう一度やり直してください」

```

#### 更新レスポンスがタイムアウト
更新リクエストがサーバBで正常に処理されて、サーバAがレスポンスを受信。
```plantuml
ブラウザ->サーバA : HTTPリクエスト　　　　　　　　　　　　　
サーバA->サーバB : 更新リクエスト
note right:処理済み
サーバB-->x サーバA:OK
note left:状態遷移　初期状態→不明
サーバA-->ブラウザ:エラー
```
【Vue】リロードを表現

完全honaki用
悪しからず

## this.$router.push
```
this.$router.push({name: 'top'})
```
→遷移するけどリロードまではしない


## this.$router.go
```
this.$router.go({name: 'top'})
```
→遷移後リロードのような動きをしてくれる

参考
https://qiita.com/CeMoReOn/items/4ce640bee42bf1a0cbd7
【JavaScript】確認メッセージを表示

完全honaki用
悪しからず

```app.blade.php
<form action="{{ route('admin.destroy', ['id' => $user['id']]) }}" method="post">
  @csrf
  //　⭐️↓これ
  <button id="delete" class="btn btn-danger" onClick="return checkDelete()">削除</button>

  <script>
      //　⭐️↓これ
      function checkDelete(){
          var result = confirm('削除しますか？');
          if(result == true){
              return true;
          }else{
              return false;
          }
      }
  </script>
  ```

参考ページ
https://alterbo.jp/blog/riri-210405/
git initってなに？

今回、学習をする中で「git init」の役割についてしっかり理解ができていなかったため調べた内容を簡単にまとめました。

## まずgitとは?
>Gitとはソースコードや変更履歴を管理するために使われる、代表的な分散型バージョン管理システムです。Gitによってファイルのバージョンを管理できるので、仮にほかの誰かにソースコードが上書きされても、簡単に元へ戻すことができます。

[参照：【入門】Gitとは？できることや使い方、GitHubとの違いをわかりやすく解説](https://www.kagoya.jp/howto/it-glossary/develop/git/ "gitの役割ついての記事")

## githubとは?
>GitHubとは、Gitの仕組みを利用したウェブ上のバージョン管理サービスです。Gitの仕組みを採用するサービスはほかにもありますが、GitHubはそのなかでも世界中で最も利用されています。特に開発の現場では、GitHubが必要不可欠な存在になっていることが多いです。
>
>GitHubはGitの仕組みを使っているので、Gitの基本機能を一通りそろえています。また自分のPC内にローカルリポジトリを作成し、GitHubをリモートリポジトリとして利用することも可能です。（多くの開発現場では、実際、そのようにしてGitHubを使っています。）

[参照：【入門】Gitとは？できることや使い方、GitHubとの違いをわかりやすく解説](https://www.kagoya.jp/howto/it-glossary/develop/git/ "gitの役割ついての記事")

## では本題「git init」とは？
git init は、新しいリポジトリの初期セットアップ時に使用するコマンドです。このコマンドを実行すると、現在の作業ディレクトリ内に新しい 「.gitディレクトリ」が作成されます。これによって、新しい main ブランチも作成されます。

これにより、お馴染みの「git branch」や「git add」や「git commit」などのコマンドが使用できるようになります。



## 参考文献
[【入門】Gitとは？できることや使い方、GitHubとの違いをわかりやすく解説](https://www.kagoya.jp/howto/it-glossary/develop/git/ "gitの役割ついての記事")
[Git リポジトリの作成方法 | Atlassian Git Tutorial](https://www.atlassian.com/ja/git/tutorials/setting-up-a-repository#:~:text=git%20init%20%E3%81%AF%E3%80%81%E6%96%B0%E3%81%97%E3%81%84%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA,%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E3%82%82%E4%BD%9C%E6%88%90%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82 "リポジトリのセットアップついての記事")
WindowsAPIのSendMessageで文字列を通信する方法を思いついたのでメモ

[Virtual2D](https://github.com/TNTSuperMan/Virtual2D)の声部分を作る過程で、VOICEVOXの音声ファイルパスを通信する必要があって、テキストを通信する方法を考えていたら思いついたのでメモします。

その方法は、文字を分割して送る方法です。
# 送信側
1. 送る文字列を用意します
1. 今回は1文字ずつで分割します。または一文字ごとに処理できるようにします
1. まず文字列を初期化するように信号を送ります
例
```cpp:初期化信号の例.cpp
SendMessage(hWnd, 0x0EDA, 1, 0);
/*Msgが0xEDA - 文字列信号の種類
  wParamに1が入っていたら文字列の初期化信号
  ということにする
*/
```
4\. 一文字ずる信号を送ります
例
```cpp:一文字ずる送るの例.cpp
for(int i = 0;i < strlen(message);i++){
    SendMessage(hWnd, 0x0EDA, 2, message[i]);
    /* wParamが2だったらlParamの数字を
       文字として受信側が変数に追加する */
}
```
5\. 終了処理をします
初期化と合わせることで必要なくなることもできます
例
```cpp:終了処理の例.cpp
SendMessage(hWnd, 0x0EDA, 3, 0);
//wParamが3だったら終了処理
```
# 受信側
WndProcに色々追加します。
```cpp:WndProcの色々.cpp
string text;
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
    //適当です。
    switch(msg){
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0; break;
    case 0x0EDA: //文字列転送のmsg
        switch(wp){
            case 1: //初期化
                text = new string();
                break;
            case 2: //文字列の追加
                text.append((char)lp);
                break;
            case 3: //終了処理
                MessageBoxA(NULL, text, "テキストの転送", MB_OK);
                //今回はメッセージボックスにする
                break;
        }
        return 0; break;
    }
}
```
wParamとかlParamに文字列ポインタを入れようとしても上手くいかなかったですが、これならうまくいくと思うので書きました。ぜひ参考にしてほしいです。
Voltaを使用していることによるNodeのバージョン変更ができない時の対処法について

## Nodeのバージョン変更ができない時の対処法について

今回Nodeを指定してインストールしたが、バージョンが変わらず沼りかけたので記事にしました。
"Node バージョン　変わらない"　などで検索してみたものの、どの記事の内容を実行しても状況が変わりませんでした。
原因は"Volta"を使用していたことにあります。
その経験を元に対処法を共有できればともいます。

注：
"Volta"については個人で調べてください。
"Volta"を使用しているということはプロジェクトでバージョンを統一している可能性があります。
ですので、プロジェクトに影響がないか等の影響範囲を確認した上でバージョンの変更をするように。



まずNodeを指定してダウンロードしたのに変わらない場合、まずは下記コマンドを実行してください。
"node"コマンドの実行可能ファイルがどの場所にあるかが表示されます。
```.ターミナル

$ which node

```

確認できたらそのファイルに移動し"node -v"を実行すると変更前のバージョンが出てくるはずです。

出たきたら下記コマンドでnodeをインストールしましょう。
今回私は、"v18.17.0"を使用したかったので下記を指定しインストールしました。
```.ターミナル

$ volta install node@18.17.0

```

インストールできたら再度"node -v"を実行すると先ほど指定したバージョンになっているかともいます。
シャットダウンをするバッチファイルで遊ぼう

こんにちは。
友人からいい感じのアイデアを貰い簡単なコーディングをしたので記録したいと思います。

## 要件定義
貰ったアイデア：
**某アイドルの曲の中に、「シャットダウンする？」というセリフがあるので、PCをシャットダウン際に実際にそれを鳴らしたい**

最初に話を聞いた時に軽く調べた時、タスクスケジューラで音声(今回は.wav)を再生するやり方に目を付けていたのですがタスクスケジューラで行う手法にした場合、シャットダウン確定後に「シャットダウンする？」と聞く旨の音声が流れるのは違和感があるなと思っていました。
そんな中、仕事で用いるPCにシャットダウン用のバッチファイルがあったことを思い出し、バッチファイルでの実現を検討しました。
イメージしていることをまとめると、

:::note

1. バッチファイル又はショートカットを起動する
2. ダイアログが起動しシャットダウン有無を確認、同時に音声を再生する
3. ダイアログの回答でシャットダウンを実行するか処理を中断するか決定する
:::
という感じになります。

## 実装
実際に書いたコードに沿って中身を確認していきましょう。
```bat
@echo off

rem 各種パス生成
set path=%~p0
set vbsFile=%path%msgbox.vbs
set wavPath=%path%shutdown.wav

rem 既にvbsが存在した場合に削除する
if exist "%vbsFile%" (
	del /f "%vbsFile%"
)

rem vbs生成
echo Dim answer >> "%vbsFile%"
echo answer = msgbox("シャットダウンする？",vbYesNo + vbInformation,"藤島慈") >> "%vbsFile%"
echo WScript.Quit(answer) >> "%vbsFile%"

rem vbs実行
start /b %wavPath%
"%vbsFile%"

rem vbs実行結果確認
if %ERRORLEVEL% equ 6 (
	start shutdown.exe /s /t 0
)

rem vbs削除
del /f "%vbsFile%"

```

まず、各種パスを生成します。
```bat
rem 各種パス生成
set path=%~p0
set vbsFile=%path%msgbox.vbs
set wavPath=%path%shutdown.wav
```
ここでは、1行目でバッチファイルの存在するフォルダのパスを取得し、2,3行目でダイアログを生成するvbsファイルと流す音声に対応したwavファイル名を定義しています。
パスは直接指定してもいいのですが、今回は友人向けに作成しているので他の環境でも動作することを目指してこのようなコードにしています。ファイルを移動させても正常に動作しますしね。


```bat
if exist "%vbsFile%" (
	del /f "%vbsFile%"
)
```
次のコードでは、同一階層にmsgbox.vbsが既に存在していた場合に削除するようにしています。
スクリプトの最後に削除処理はありますが、念のため実装をしています。



```bat
rem vbs生成
echo Dim answer >> "%vbsFile%"
echo answer = msgbox("シャットダウンする？",vbYesNo + vbInformation,"藤島慈") >> "%vbsFile%"
echo WScript.Quit(answer) >> "%vbsFile%"

rem vbs実行
start /b %wavPath%
"%vbsFile%"
```

さて、いよいよシャットダウンの機構の本体部分になります。
シャットダウンの確認をするダイアログを生成したのち、音声ファイルと一緒に実行しています。

msgboxの後ろの部分にダイアログの内容を記載し、ユーザーからの入力値（今回はY/N）を変数answerで受け取っています。
vbsでコマンドを実行しているため、このままでは戻り値としてanswerを使えないのでWScript.Quit(answer)とすることで%ERRORLEVEL%に実行結果を返しています。

気持ち程度ですが、実行時に音声→vbsとすることでダイアログが上に表示されるので音声を再生するウィンドウが邪魔にならなくていい感じでした。


```bat
rem vbs実行結果確認
if %ERRORLEVEL% equ 6 (
	start shutdown.exe /s /t 0
)

rem vbs削除
del /f "%vbsFile%"
```
最後に、vbs実行後の処理です。
前述しましたが、vbsの実行結果を%ERRORLEVEL%で受け取っています。Y/Nの場合、Yesが6、Noが7を返します。
(参考：https://learn.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/msgbox-constants)
今回はYesだった場合にシャットダウン処理を実行したいため%ERRORLEVEL%が6であるかの判定をしています。
その後、vbsを削除して終了となります。

## 感想等
コマンドの関係上1つのディレクトリに格納する必要があったので、折角だと思ってアイコンも作成したらアプリケーションっぽくなって達成感がありました。
↓こんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253460/7cbf5a95-0907-8549-643c-23ffb502d06e.png)

タイムスタンプからわかる通り、昨年の8月に軽く作成してこの度改めて触ったのですが、shutdown.exeのpathが通っておらず、追加する必要がありました。環境によると思いますが使用者が設定する必要があるので課題点かなと感じました。

今回はいいアイデアを頂けたのでバッチファイルを触りましたが、OSの様々な操作に応用できそうなので今後もいろいろ試してみようと思いました！
最後までお読みいただきありがとうございました。
ブラウザで行う球状黒鉛鋳鉄品の黒鉛球状化率の測定

# はじめに
前回の記事で作成したプログラム

https://qiita.com/_Moony/items/276db838b77e45cf5435

は、ISO法とJIS法のプログラムが別々になっており、また、複数の画像ファイルに対応しておらず、加えてhtmlとjavascriptのファイルが分かれていたため、使いにくいものでした。そこで今回は、複数の画像ファイルを読み込み、ISO法とJIS法の球状化率を同時に求めるプログラムを作成しました。

# 使い方
以下のサイトを立ち上げます。

https://repositoryfiles.github.io/New-Nodularity-WebApp/nodularity_web_app.html

1. Opencv.jsの読み込み中の状態です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/e9fce05d-1268-ad92-ab48-b0920e5ed7f4.png)

2. ブラウザ左上の表示が「準備完了」になれば使用できます。通信環境やパソコンの処理速度により、多少待つ場合があります。画像の幅に値を入力します。この値の設定についてはZIPファイルのREADMEを参照下さい。また、最小黒鉛の長さについてはJISでは10となっているので、変更不要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/9281b43b-3556-85cf-3665-b175984e2d51.png)

3. 「ファイル選択」をクリックして、球状化率を評価する画像ファイルを読み込みます。画像ファイルはダウンロードしたZIPファイル中のサンプル画像を使うことも可能です。画像ファイルは複数選択することも可能です。読み込んだら少し待ちます。
![fig3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/8a39367a-dc26-486f-02d1-ad0c44e2f43c.png)

4. このような表示が出る場合は「許可する」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/23170e9a-8d8f-01c7-6497-0dbbc140cb5a.png)

5. ブラウザにJIS法とISO法の球状化率の結果が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/ccca3502-35e0-ed87-f0e1-8c8f9b01eea7.png)

6. ダウンロードの保存先に指定されているフォルダに画像ファイルが保存されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/e0d3b068-cc34-b522-ea69-6b1f4a10ea59.png)

7. ダウンロードされるファイル名と内容は次のとおりです。
- JIS法
    - ファイル名：元のファイル名+_result(JIS)_球状化率.jpg
    - 内容：JIS法で黒鉛の形状を色分けしたもの
（Ⅰ：赤、Ⅱ：紫、Ⅲ：緑、Ⅳ：水色、Ⅴ：青）
- ISO法
    - ファイル名：元のファイル名+_result(ISO)_球状化率.jpg
    - 内容：ISO法で黒鉛の形状を色分けしたもの
（青：ⅤとⅥ、赤：Ⅰ～Ⅳ）

ソースファイルはこちらにあります。READMEの注意事項を読んでお使いください。

https://github.com/repositoryfiles/New-Nodularity-WebApp

何かの参考になれば幸いです。

# 開発環境

- Windows11
- OpenCV.js 4.9.0
Pythonで「タイムゾーンのインスタンスを生成する」の動作を確認してみた

# 概要

Pythonで「タイムゾーンのインスタンスを生成する」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/python/date/index2.html

# 実装

以下のファイルを作成しました。
```sample.py
import datetime
print(datetime.timezone(datetime.timedelta(hours=9)))
print(datetime.timezone(datetime.timedelta(hours=-4)))
print(datetime.timezone.utc)
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
UTC+09:00
UTC-04:00
UTC
```

# まとめ

何かの役に立てばと。
未経験からエンジニアになった私が1年間で触れた言語

# 未経験から一年
正確には6月配属だったのですが、入社からもうすぐ1年という記念すべき節目。
この1年で触る機会のあった言語を振り返ってみます。

なお、エンジニアになる前は大学の研究で行列の計算をするためにPythonを使用した程度の経験しかありませんでした。

# 研修期間中に多少触れた言語
- R
- HTML・CSS


# 結構使用した言語
- JavaScript
- TypeScript
- ShellScript
- Python
- Java
- SQL 
- Googleスプレッドシート関数/EXCEL関数（言語ではないけども）

以上は何かしら成果物を出した言語たちです。
未経験だったので言語やフレームワークに大したこだわりがなく、振られたタスクに合わせて学んでいったらこうなりました。果たしてこれは多いのか少ないのか、さっぱりですね。

また、実際は挙げた以上に色々な言語に対応した感覚です。
SQLでもAmazon Athenaで使えるクエリとMySQLのクエリは違いますし、GASとAWS SDK for JavaScriptはそれぞれ独自のコマンドが多すぎて文法が似ているだけの全くの別物としてカウントしたいくらいです。

ちなみに初めてがっつり使用したのがTypescriptなので、型定義がないと不安になります。

# たくさん使用した言語
- 日本語
- 英語
- 日本語と英語が入り混じったなにか（つらい）

これらが読めなきゃ始まらない。仕様を独自解釈したり、正しくドキュメントを理解できなかったりしたら大変ですので、ここが一番大事だと思います。
同時に一番自信がないところでもあります。

# 今後触れてみたい言語
- Go
- Rust

GOは各人によるブレが少ないと聞いて気になっています。
Rustは社内でゴリゴリに使っているらしい先輩がいるので影響を受けまして。

他にも猫語を話す先輩がいたりします。


# 感想
意外とC言語,C++,C#を使用していませんでした。
配属されたチームの仕事内容もあるかもしれません。

そして振り返ってみると、どのプログラミング言語もとりあえず目的を達成するために書けるようにした側面が強いように思います。
今後は、各言語の生まれた背景・課題・設計思想・強み・特徴なども意識しながら身につけていきたいです。
そして目的に合わせて相性の良い言語を選択できるようになりたいですね！

つよつよエンジニア目指して頑張ります。
G-codeの基本【3Dプリンタ】

## G-codeとはなんぞや？
皆さん、G-codeというものをご存じでしょうか？

G-codeとは、コンピュータで制御された工作機械 (CNC) や、3Dプリンタの制御に使われているコードになります。

プログラミング言語というよりかは、1行で命令を送るコードであり、機械工作の制御をするもの。
という認識が合っているかと思います。
工業系の方には馴染みあるかもしれません。

近年は3Dプリンタで認知され始めてきたのと、且つ弊社に3Dプリンタが置いてあるので、皆さんにもっと身近に認知してもらおうと記事を書くことにしました。

## G-codeの役割
それでは本題に入ります。
3DプリンタでのG-codeの役割とは、

:::note info
* フィラメントを送り出すエクストルーダーの制御
* 移動命令
* X,Y,Z軸の座標制御
* 速度指定
* 温度制御
* 原点設定
:::

おおよそこれらに分けられます。

:::note warn
**用語説明**
* フィラメント = 3Dプリンターでの造形に使われる材料のこと
（PLA,ABSなどの樹脂素材）
* エクストルーダー = 材料のフィラメントを溶かし、押し出す部品
:::

下記が3DモデルのG-codeになります。
（ほんの一部ですが、実際のコード量はかなり多いです。）
```example.gcode
G21 ; set units to millimeters
M107
M104 S230 ; set temperature
G28 ; home all axes
G1 Z20 F5000 ; lift nozzle
M109 S230 ; wait for temperature to be reached
G90 ; use absolute coordinates
G92 E0
M82 ; use absolute distances for extrusion
G1 F1800.000 E-3.00000
G92 E0
G1 Z0.200 F7800.000
G1 X68.046 Y52.941 F7800.000
G1 E3.00000 F1800.000
G1 X68.993 Y51.791 E3.03788 F910.408
G1 X69.380 Y51.415 E3.05160
G1 X70.862 Y50.335 E3.09823
G1 X71.979 Y49.821 E3.12948
G1 X72.259 Y49.721 E3.13703
G1 X73.800 Y49.373 E3.17720
G1 X74.742 Y49.295 E3.20124
G1 X76.030 Y49.342 E3.23402
G1 X78.756 Y49.701 E3.30391 F910.408
G1 X80.162 Y50.046 E3.34071

～～～～～～～～～～～～～～～

G92 E0
G1 Z30.700 F7800.000
G1 X87.179 Y68.009 F7800.000
G1 E3.00000 F1800.000
G1 X86.748 Y67.847 E3.00797 F600.000
G1 X86.639 Y67.782 E3.01016
G1 X86.425 Y67.531 E3.01586
G1 X86.273 Y67.211 E3.02198
G1 X86.606 Y67.270 E3.02783
G1 X86.742 Y67.330 E3.03039
G1 X86.854 Y67.421 E3.03288
G1 X86.903 Y67.491 E3.03437
G1 X87.151 Y67.956 E3.04346
G1 X86.849 Y67.783 F7800.000
G1 F1800.000 E0.04346
G92 E0
M107
M104 S0 ; turn off temperature
G28 X0  ; home X axis
M84     ; disable motors
```

見てもほとんど分からないとは思いますので、1つずつ見ていきます。

```
G1 X87.151 Y67.956 E3.04346
G1 X86.849 Y67.783 F7800.000
```
移動命令は`G0,G1`の2つがあり、G0は高速移動、G1は直線移動を意味します。
G1に続けて記述されているXとYは、それぞれX軸とY軸の座標を意味します。
Eの値があると思いますが、Eはフィラメントの押出量を意味しています。
Fの値は速度を指定しています。
これを紐解いていくと、`フィラメントを3.04346mm押し出しながら、X軸87.151,Y軸67.956の位置に移動する。`
`7800mm/minの速度で、X軸86.849,Y軸67.783の位置に移動する`
という意味になります。

**原点回帰**

```
G28 ; 全て原点に戻す
X87.151 Y67.956 E3.04346 ; Z軸だけ原点に戻す。 
```
G28というコマンドはX,Y,Z軸を0の位置に戻すコマンドです。
1行目の`G28`のみの記述の場合、全ての軸が0に移動します。
2行目のように値があるものに関しては、記述がない軸のみ0に戻ります。

**コメントアウト**
ほかのプログラミング言語と同様にコメントアウトを記述することが可能です。
；（セミコロン）から続けて記述し、改行までがコメントとして扱われます。

## 最後に
これでG-codeの基本が理解できたと思います。

3DCADソフト等で用いられる3Dモデルは.STLというファイルフォーマットであり、3Dプリンタではこれらをスライサーソフトというものを用いて.gcode形式に変換し、3Dプリンタ側にデータを送信することで造形が開始されます。

もし機会があれば.gcodeファイルを覗いてみてはいかがでしょうか？
PBR Stage EquipmentアセットをURPに対応する

## 概要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418961/1958ef28-5f17-4f37-717a-c9e2ee062658.png)



[PBR Stage Equipment](https://assetstore.unity.com/packages/3d/props/electronics/pbr-stage-equipment-84617) はライブ演出用のミラボールやスポットライト、火炎放射器などが含まれているアセットです。

ライブ演出用アセットなどで検索すると、色々なサイトで紹介されているのですが、どうやらビルトインパイプライン向けのようです。

パイプラインにURPを使用しているシーンで使用したかったのですが、使えるか怪しかったので人柱として購入して実際に使用できることを確かめました。


結論としてはシェーダーをアセットの作者さんが用意してくれている別アセットのものに置き換えるだけでURP対応できたので、とても簡単でした！

### 検証環境
OS : Windows 10
Unity ： 2022.3.10f1

## シェーダーの変更対応
というわけで、PBR Stage EquipmentアセットをURPでも使えるようにします。

[[Released] PBR Stage Equipment](https://forum.unity.com/threads/released-pbr-stage-equipment.499650/)

元々はビルトインレンダーパイプラインのみの対応だったようですが、Froumを見るとURPにも対応してくれているようです。
Froumに記載されている手順通りに修正していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418961/d88ccba0-a914-ec6c-bdb2-cc7598e45cc0.png)

PBR Stage Equipmentアセットをインポートしてサンプルのシーンを開くとシェーダーがエラーを起こしてマテリアルがマゼンタ色になっているので修正していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418961/13275189-a550-b9da-b73c-354fab847bd4.png)

まずは、PBR Stage Equipmentアセットを提供してくれている作者さんによる修正用のシェーダーをインポートします。

シェーダー ： [TG Utility](https://assetstore.unity.com/packages/tools/utilities/tg-utility-131460)

インポートしたら、Standardシェーダーになっている部分をTirgamesSRPに置き換えていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418961/87aa5b9f-fe6b-47bd-45d5-9391ccf4954c.png)

全部置き換えたら修正完了です。
再生して各種演出がちゃんと動くことを確認しましょう。お疲れ様でした！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418961/5c1cf6f2-4d6c-1dde-b97e-293218e75249.png)
VSCodeからSQL Serverへつなぐ時にオートコミットを外す方法

# やりたいこと

- VSCodeの拡張機能(mssql)で、SQL Serverへ接続する際に、オートコミットの設定を切りたい
    - 間違ってSQLを流してしまった際に簡単にロールバックできるようにしておきたい

# やり方

## 前提：拡張機能(mssql)のインストール

https://marketplace.visualstudio.com/items?itemName=ms-mssql.mssql

これです。

使い方についてはこちらの記事が分かりやすかったです。

https://qiita.com/hmsnakr/items/0e9ccc94eeb3eb7f2e08

## オートコミットを外す

`command` + `,`（Windowsなら、`ctrl` + `,`）で、VSCodeの設定を開きます。もしくは、VSCodeのウィンドウ左下からも開けます。

![左下](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518330/8b043506-d910-5ac1-20f7-12a443a95a9f.png)

設定タブを開けたら、「mssql transaction」とでも検索して、「**Implicit Transactions**」のチェックボックスをチェックしてください。（デフォルトだとチェックがついていない状態です。）

![implicit transaction](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518330/86b1184b-1d83-74c7-5b9b-1864e832f43f.jpeg)

## IMPLICIT_TRANSACTIONSとは

https://learn.microsoft.com/ja-jp/sql/t-sql/statements/set-implicit-transactions-transact-sql?view=sql-server-ver16

SQL Serverのドキュメントの解説を見ると、

> ON の場合、システムは "暗黙" トランザクション モードです。 つまり、@@TRANCOUNT = 0 の場合に、次の Transact-SQL ステートメントのいずれかが新しいトランザクションを開始します。 これは、最初に実行される目に見えない BEGIN TRANSACTION と同じです。

とあります。

`BEGIN TRANSACTION`が最初に実行されるというていで考えればよく、SQLの締めでは、`COMMIT`か`ROLLBACK`を明示的に行うことができます。要は、オートコミットを解除しているのとおんなじことですね。

# まとめ

これでオートコミットを外せました。
ポンコツ学生が社会人1年目で劇的に成長できた話

# はじめに
こんにちは！私事ですがあと数日で社会人歴1年となりますので、この1年で学んだこと、主に仕事の進め方ついて書いていき、さらにおすすめのプラクティスを紹介したいと思います！
# 大切だと思ったこと
まず結論から、特に大切だと思ったことは以下の3点です。

- 悪いことほど早く報告する
- あいまいなことを解消する大切さ
- 質問に行くときは整理してからいく

これらについてエピソードを交えて順に書いていきます。

## 悪いことほど早く報告する
「悪いこと」と聞いて何が思い浮かびますか？私は「進捗が遅れているとき」「開発しているアプリに不具合が見つかったとき」などが思い浮かびます。ここでは(こっぴどく怒られて)一番印象に残った「進捗が遅れているとき」について書きます。

社会人、学生よりも「期日」というものは付きまとってきます。
ある日タスクを行っているときに間に合わなさそうだけど頑張れば間に合うかも？と思い報告するよりも先に手を動かそうなどと考えそうしてしまいました。結果締め切り直前でもタスクが完了しておらず、相談することに．．．
「なぜできなさそうと思った時に連絡しなかったのか？」と言われた時何も反論できませんでした。

報告される側からしたら締め切り直前に「間に合いそうにありません...！」など言われてもどうしようもありません。早め早めに相談しておけば期日に間に合わせるようなよい方法を聞けるかもしれません。また、予定の調整もできる可能性が高いです。良いことづくめですね。
根性で頑張るつもりでもまずは報告です！


## あいまいなことを解消する大切さ

ある日新しいタスクが与えられたとき、あいまいなことはありながらこれなら自分でできると最初に何も相談せずに進めてしまっていました。結果手戻りが起きました。

分からないこと、あいまいなことをそのままほっておくのは一番ダメなことだと思います。
私はどちらかというと質問しにいくのが、時間をとって迷惑かなと思って控えることが多かったのですが逆ですね。あいまいなままでタスクを進められた方が圧倒的に迷惑です。

少なくとも新人のうちは、分からないことをたくさん質問することで不快に思われることはないと思います　私の上司も「全然質問しないよりもたくさん質問して解決、吸収して早く戦力になって方が総合的にみてよい」ということもおっしゃってくださっています。


## 質問に行くときは整理してからいく

質問をする際は
- 行いたいこと
- 今できていること
- 今できていないこと


の3点を整理した上でいくことが最低限必要であることを学びました。
以前はこれができておらず質問にいっても？？？という反応をされてしまったのが多かったです。整理されていない状態のものを頭に浮かんだものを次々に話していっても相手は困惑するだけですもんね。しかしこの3点をしっかりしておくだけで相手の反応が劇的に変わりました。


### おすすめのプラクティス

分報です！それぞれのメンバに用意されたSlackの公開チャンネルにて進捗、考えなどをTwitterのように書いていくものです。詳しくはこちらの記事を参照してください。

https://qiita.com/kojimadev/items/ea8825dec1b0d0d2874c

私が所属するチームにおいて活用されているのですが最近じわじわと分報の有効性を感じてきています。

はじめは分報というものに慣れないこともありタスクを進める際コードを書くことを優先してしまっていました。実装自体は進めていけるのですがいざ終わった後「どういう考えでこういう実装にしたの？」と聞かれた際答えられないことが度々ありました。

私が分報に作成しているUI画面や実装を投稿するとそれに対して「ここ違うんじゃない？」「こういう実装ならいけるかも」と返信していただけることが多々ありました。そのおかげで効率的に開発をすすめていけて非常に助かっています。

実際に質問しに行くときにも活用できます。自分の考えをメモしているおかげでそれを順に見せながら説明をすることができます。説明が苦手な人でもこれならうまく説明できますね！

# おわりに
これからも失敗をしてしまうと思います。しかしそこでへこまず、学んだ二度と同じ失敗をしないように失敗そのものよりもその失敗からの学びの方を重視していきたいと思います！ご拝読ありがとうございました！
LeetCode 525. Contiguous Array の解き方メモ

https://leetcode.com/problems/contiguous-array/description

LeetCode 525. Contiguous Array の解き方メモです。難易度はそれほど高くないはずですが、やや苦労したので、思考の過程を残しておきたいと思います。

「0と1からなる配列numsが与えられる。0と1が同数になる部分配列のうち最長のものの長さを求めなさい」という問題です。回答にあたっては、累積和を記録した配列Aと配列Bを用意します。

- A[i] = [0, i)の範囲にある1の数
- B[i] = [0, i)の範囲にある0の数

累積和の性質を考えて、[x, y)の範囲にある1の数はA[y]-A[x]です。同じように、[x, y)の範囲にある0の数はB[y]-B[x]です。今回求めたいのは0と1が同数になる部分配列なので、A[y]-A[x]=B[y]-B[x]。これを整理して、A[x]-B[x]=A[y]-B[y]。これで法則性が見えました。

1. yを[0, n+1)の範囲で動かしていく
2. y未満の範囲で、A[x]-B[x]=A[y]-B[y] となるようなxを探す。より長い部分配列を探すため、xの候補が複数見つかった場合は、より小さいものを採用する。xとA[x]-B[x]の管理にはHashMapを利用する

あとはこれをコードに落とし込みます。全体の計算量はO(n)になるはずです。

```rust
use std::collections::HashMap;

impl Solution {
    pub fn find_max_length(nums: Vec<i32>) -> i32 {
        let n = nums.len();
        let mut a = vec![0; n + 1];
        let mut b = vec![0; n + 1];
        for i in 0..n {
            if nums[i] == 1 {
                a[i+1] = a[i] + 1;
                b[i+1] = b[i];
            } else {
                a[i+1] = a[i];
                b[i+1] = b[i] + 1;
            }
        }

        let mut h = HashMap::new();
        let mut max_len = 0;
        for y in 0..=n {
            let k = a[y] - b[y];
            if let Some(x) = h.get(&k) {
                max_len = max_len.max(y - x);
            } else {
                h.insert(k, y);
            }
        }

        max_len as i32
    }
}
```
AWS Systems Manager Parameter Storeを使ってみた


# AWS Systems Manager Parameter Storeとは？

> 設定データ管理とシークレット管理のための安全な階層型ストレージを提供します。パスワード、データベース文字列、Amazon Machine Image (AMI) ID、ライセンスコードなどのデータをパラメータ値として保存することができます
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-parameter-store.html

ソースコードにパスワードを記載する必要がなくなります
Secrets Managerとは違いローテーション機能がありません

# AWS Systems Manager Parameter Storeの設定

1. AWS Systems Manager のページを開き、左のメニューから`パラメータストア`を選択

2. `パラメータの作成`を選択

3. 格納データを作成
選択できるものは以下の3つがあるようです
- 文字列
- 文字列のリスト
- 安全な文字列(AWS KMS キーを使用して暗号化してテキストを保存することが可能)
![image-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997750/d8a16f1e-6ed8-c9f9-77ed-b153bf77d899.png)



# パラメータ取得

コード
```
import boto3
from botocore.exceptions import ClientError

def get_parameter():

    parameter_name = "" # 2.で設定したパラメータの名前
    region_name = "" # Parameter Storeを作成したリージョン

    session = boto3.session.Session()
    client = session.client(
        aws_access_key_id = '', # アクセスキー
        aws_secret_access_key  = '', # シークレットキー
        service_name='ssm',
        region_name=region_name
    )

    try:
        response = client.get_parameter(
            Name=parameter_name,
        )
    except ClientError as e:
        raise e

    return response['Parameter']['Value']

print(get_parameter())
```

結果
```
test
sample
```

種類を文字列のリストの場合で作成した場合、取得した際に自動でリスト化などしてくれると思ったのですが、普通にカンマ区切りの文字列が返ってきただけでした
種類が文字列をカンマ区切りで登録した場合と種類が文字列のリストで登録した場合の違いがよくわからなかったです
![image-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997750/c1d2c178-d0c2-21de-b1e1-e0acdf965067.png)


結果
```
test,sample
```

# 終わり
種類が文字列のリストと文字列の使い分けがあれば教えてください
AWS Secrets Managerを使ってみた


# AWS Secrets Managerとは？

> データベース認証情報、アプリケーション認証情報、OAuth トークン、API キー、およびその他のシークレットをライフサイクルを通じて管理、取得、ローテーションするのに役立ちます。多くの AWS サービスは、Secrets Manager でシークレットを保存して使用します
https://docs.aws.amazon.com/ja_jp/secretsmanager/latest/userguide/intro.html

ソースコードにパスワードを記載する必要がなくなるので、セキュリティ的にもよく、
ローテーション機能があり定期的にパスワードを更新することができます

# AWS Secrets Managerの設定

1. AWS Secrets Managerのページを開き、`新しいシークレットを保存する`を選択

2. シークレットのタイプを選択
今回はその他のシークレットのタイプにしたので、保存する値も設定します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997750/3c423699-395b-bf6e-044e-acf66cff17a1.png)


3. シークレットの名前を設定
APIで取得する際に使用する名前を設定します
またリージョンで障害が起きた時用に他のリージョンに読み取り専用のデータを保存することもできるようです
![image-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997750/3fbc7c5c-c3c8-cc4b-3021-200abe50a571.png)

4. ローテーションの設定
自動的にローテーションを行いたい場合は設定を行います
![image-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997750/8f4ca733-f22f-77eb-c74f-48429931d2ee.png)


# シークレット取得

Secrets Managerの設定時にpythonのサンプルコードがありました
ローカルで取得するために多少変更を加えて実行し、設定した値が取得できました


コード
```
# Use this code snippet in your app.
# If you need more information about configurations
# or implementing the sample code, visit the AWS docs:
# https://aws.amazon.com/developer/language/python/

import boto3
from botocore.exceptions import ClientError


def get_secret():

    secret_name = "" # 3.で設定したシークレットの名前
    region_name = "" # Secrets Managerを作成したリージョン

    # Create a Secrets Manager client
    session = boto3.session.Session()
    client = session.client(
        aws_access_key_id = '', # アクセスキー
        aws_secret_access_key  = '', # シークレットキー
        service_name='secretsmanager',
        region_name=region_name
    )

    try:
        get_secret_value_response = client.get_secret_value(
            SecretId=secret_name
        )
    except ClientError as e:
        # For a list of exceptions thrown, see
        # https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html
        raise e

    secret = get_secret_value_response['SecretString']

    # Your code goes here.

    return secret

print(get_secret())
```

結果
```
{"test1":"example","test2":"default"}
```
ブラウザ以外からHTTPリクエストを送ってみた時のメモ

タイトル通りです。

参考にさせていただいたのは↓
* [エクセルVBAでHTTPリクエストをする最も簡単なプログラム](https://tonari-it.com/excel-vba-http-request/)
* [Invoke-WebRequest (Microsoft.PowerShell.Utility) - PowerShell | Microsoft Learn](https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-7.4)

今回はとりあえずUA情報が取りたかっただけなので、全て[HEAD](https://developer.mozilla.org/ja/docs/Web/HTTP/Methods/HEAD)メソッドを使用。

## Excelの場合(1)
```VBA
Sub onClick()
    Dim httpReq As XMLHTTP60
    Set httpReq = New XMLHTTP60
    Dim uri As String
    uri = "http://localhost:3000/"
    Call httpReq.Open("HEAD", uri, False)
    Call httpReq.Send
    Do While httpReq.readyState < 4
        DoEvents
    Loop
    Set httpReq = Nothing
End Sub
```


## Excelの場合(2)
```VBA
Sub onClick_2()
    Dim winHttp As Object
    Set winHttp = CreateObject("WinHttp.WinHttpRequest.5.1")
    Dim uri As String
    uri = "http://localhost:3000/"

    winHttp.Open "HEAD", uri
    winHttp.Send
End Sub
```

## powershellの場合
```powershell
$uri = 'http://localhost:3000/'
$response = Invoke-WebRequest -Uri $uri -UseBasicParsing -Method HEAD
```

## おわりに
頑張れば負荷テストなどに応用できるかも、と思いつつ、
そこまでの余力はなさそうなのでここまで。
業務からは外れるけどスクレイピングとかも出来たら楽しいかも……

VBAなら一度結構がっつり書いてたことがあるので、やるならVBAかなあ
powershellすらすら書けるようになりたい……
Denodo パフォーマンス向上を目指す

## 初めに
とりあえず確認できるものを羅列しています。
ほぼリンクまとめ

:::note warn
警告
Denodoのマニュアルは「日本語」が選択できますが、最新情報が更新されていないことがあるようです。
（おかしいな）や（こんなのなかったっけ）は英語版マニュアルをまず確認しましょう。
:::

バージョン：V8

## バージョンアップ
まずは使っているDenodoのバージョンが最新かを確認。
古いものを使っている場合、最新バージョンのパフォーマンスに関するアップデートの恩恵が受けられていないかもです。
最新バージョンのリリースノートを確認したりして、最新バージョンに更新できないか確認してみます。

バージョンアップについては以下のマニュアルを参照
・[更新プログラムおよび修正プログラムのインストール](https://community.denodo.com/docs/html/browse/8.0/jp/platform/installation/installing_updates_and_hotfixes/installing_updates_and_hotfixes)

主なアップデートされた機能についてのマニュアルもあります。
例えば20230914であればこれ
・[What Is New in Denodo 8.0u20230914](https://community.denodo.com/docs/html/browse/latest/en/platform/new_features/what_is_new_latest_update)


## Webコンテナの割り当てメモリを増やす
メモリが不足している場合もあります。
不足しているかどうかは別ページ「[DenodoMonitor](https://qiita.com/caffee_mocha/private/08adb8c00f0fbda925ad)」で確認できます。

JVMメモリの設定方法ナレッジベースはこれ
・[JVM MEMORY SETTINGS CONFIGURATION](https://community.denodo.com/kb/en/view/document/JVM%20Memory%20Settings%20Configuration)

ベストプラクティスについての記述はこっち
JVM設定についての記載もあります。
・[Denodo Admin and Development Best Practices](https://community.denodo.com/kb/en/view/document/Denodo%20Admin%20and%20Development%20Best%20Practices#h.b9hulw4bhvja)

:::note warn
警告
ドキュメントにも記載がありますが、設定値の変更後にはサーバの再起動が必要となります。
:::


## キャッシュDBを外部DBにする
そもそもキャッシュ使ってます？
使うといいこと結構あります。
詳しくは
・[キャッシュモジュール](https://community.denodo.com/docs/html/browse/8.0/jp/vdp/administration/cache_module/cache_module)

例えばデフォルトの Apach Derby をそのまま使ってます、というような場合も要注意。
マニュアルに以下の記述があります。
>Apache Derby 組み込みデータベースを使用することは推奨されません。このデータベースは、キャッシュエンジンと小規模なプロジェクトの実行という事例を見せるために提供されています。代わりに、特に本番環境では、外部データベースを使用してください。

さらに、キャッシュはメンテナンスしないとどんどん重くなっていってしまう…………
メンテナンスをするようにしましょう
・[キャッシュメンテナンスタスク](https://community.denodo.com/docs/html/browse/8.0/jp/vdp/administration/cache_module/cache_maintenance_task/cache_maintenance_task)

キャッシュDBとして使うDBによっては気にしなくてはいけないこともあるので、以下を要確認です。
・[キャッシュデータベース固有の情報](
https://community.denodo.com/docs/html/browse/8.0/jp/vdp/administration/cache_module/specific_information_about_cache_databases/specific_information_about_cache_databases)


## 各DSの統計情報（Option>Statistiks>Enable statics）をONにする

どこでクエリを実行するのか（データソースかDenodoか）でもパフォーマンスには違いがありますよね。
それを自動で決めてくれたりする機能もあります。

・[コストベースの最適化](https://community.denodo.com/docs/html/browse/8.0/jp/vdp/administration/optimizing_queries/cost-based_optimization/cost-based_optimization)

・[コストベースの最適化の有効化](https://community.denodo.com/docs/html/browse/8.0/jp/vdp/administration/optimizing_queries/cost-based_optimization/enabling_the_cost-based_optimization#enabling-the-cost-based-optimization)

・[ビューの統計情報の定義](https://community.denodo.com/docs/html/browse/8.0/jp/vdp/vql/defining_the_statistics_of_a_view/defining_the_statistics_of_a_view)
Denodo Monitor？

## 初めに
Denodo、マニュアルを見ているとDenodoのメモリ使用とかクエリの実行情報とか、諸々の情報はDenodo Monitor 起動するとログとして取得できるよ、
なんてあったりしますが、
肝心のDenodo Monitor、なんか2つある？
ってなりましたので簡単に違いを説明。
※正確な違いは製品サポートなりの公式さんに問い合わせください

## まずそれぞれのマニュアル
DenodoMonitorにはSolutionManager版とスタンドアロン版の2種類があります。

・[SolutionManager版のDenodo Monitor](https://community.denodo.com/docs/html/browse/8.0/jp/solution_manager/administration/monitoring/monitoring)

・[スタンドアロン版のDenodo Monitor](https://community.denodo.com/docs/html/browse/8.0/jp/vdp/administration/monitoring_the_virtual_dataport_server/denodo_monitor/denodo_monitor)

## 基本的には
機能としては同じです。
起動方法や設定方法に違いがあります。

## SolutionManager版のDenodo Monitor

#### 基本情報
Solution Manager上の組み込み型Denodo Monitorは、ワンクリックでクラスタや環境を監視することができます。
Administration Tool上でグラフィカルに設定が可能ですし、モニター起動ごとに設定ファイルを自動生成しますので、事前準備がいりません。
起動については、Solution ManagerのAdministration Toolから管理者権限で起動する必要があります。

#### デフォルトのログフォルダ
ログを「<SOLUTION_MANAGER_HOME>/resources/solution-manager-monitor/work」に保存します。
クラスタおよび環境のログは、クラスタまたは環境の名前を持つフォルダに入ります
（例えば、「Production」環境を監視する場合は、ログは「<SOLUTION_MANAGER_HOME>/resources/solution-manager-monitor/work/Production/logs」フォルダに入ります。）

## スタンドアロン版のDenodo Monitor

#### 基本情報
クラスタや環境全体を一括で監視することはできません。
監視を開始する前に手動で設定ファイルを修正し、監視したい要素を追加しておく必要があります。
一方、他のDenodoコンポーネントから切り離されたツールであり、どこからでも独立してこのツールを実行できます。


#### デフォルトのログフォルダ

「<DENODO_MONITOR_HOME>/logs」以下にログを保存し、環境名やクラスタ名を持つフォルダは存在しません。

## まとめ

Solution Manager上のメタデータを利用して、ワンクリックでクラスタや環境の監視を開始したい場合は、Solution Manager上の組み込みDenodo Monitorが適しています。

スタンドアロン型のDenodo Monitorは、監視するサーバーやエレメントを定義するなど、詳細な制御を行いたい場合に適しています。
また、Solution ManagerやVDPサーバーから切り離すために、別のサーバーでDenodo Monitorを動作させたい場合にも使用します。

:::note warn
警告
最新Update等ではSolutionManager版のDenodo Monitorのみが先に変更されたりします。
20230914ではSolutionManager版のみにログの出力する内容が増えたりしてます。
:::
個人的には、よっぽどスタンドアロン版が良い、という理由がなければSolutionManager版をお勧めします。
C#でExcelファイルを読み込む

Excelファイルを扱う場合、そこからデータを読み取ることは一般的な要件です。Excelのデータを読み込むことで、スプレッドシートに含まれる情報にアクセスし、そのデータを他のアプリケーションやプログラミング環境でさらなる処理や分析に使用することができます。

本文は無料ライブラリを使用してC#でExcelデータを読み込む方法を共有します。具体的には、

## 準備：
VSで[Nuget](http://www.nuget.org/packages/FreeSpire.XLS/)経由で無料Excel読み書きライブラリ-[**Free Spire.XLS for .NET**](https://www.e-iceblue.com/Introduce/free-xls-component.html)をインストールします。パッケージをダウンロードして、手動でdllをインポートすることもできます。

## Excelからデータを読み込むには 
1.	Spire.Xls名前空間のインポート
2.	Excelファイルのロード
3.	指定されたワークシートを取得し、その中のデータを含む領域を取得する。
4.	データ領域の行と列を反復します。
5.	**Worksheet.Range.Value**プロパティを使用して、セル内の数値またはテキストを文字列として返すことができます。

## Excelを読み込むためのC#コードの例
```c#
using Spire.Xls;

namespace ReadExcelFile
{
    class Program
    {
        static void Main(string[] args)
        {
            // Excelファイルのロード
            Workbook wb = new Workbook();
            wb.LoadFromFile("Test.xlsx");

            //最初のワークシートを取得する。
            Worksheet sheet = wb.Worksheets[0];

            //ワークシートで使用されている範囲を取得
            CellRange usedRange = sheet.AllocatedRange;
            //指定したセル範囲を取得
            //CellRange Range = sheet.Range["A1:D6"];

            //行を循環する
            for (int i = 0; i < usedRange.Rows.Length; i++)
            {
                //列を循環する
                for (int j = 0; j < usedRange.Rows[i].ColumnCount; j++)
                {
                    //特定のセルのデータを取得
                    Console.Write(usedRange[i + 1, j + 1].Value + "  ");

                }
                Console.WriteLine();
            }
        }
    }
}
```

**出力結果：**
![readExcel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/f1d90e26-2e9b-1c83-a797-ab6ec4f9c1df.png)


> 無料のFree Spire.XLS for .NET ライブラリは、Excel ファイルの生成、変換、編集、印刷を含む様々な機能をサポートしています。その他のデモについては、こちらをクリックしてください：
https://www.e-iceblue.com/Tutorials/Spire.XLS/Spire.XLS-Program-Guide/Spire.XLS-Program-Guide-Content.html
Docker 基本操作：イメージのダウンロード＋破棄

# Dockerイメージダウンロード方法備忘録
自分でコンテナ環境を構築したことがなかったので備忘も兼ねてまとめてみました。

## Dockerhubへアクセス

DockerHubとは・・・Docker用のコンテナイメージがまとめられたレジストリ（＝要はDB）です。
Dockerイメージの公開と共有が行われており、Dockerに触れたことのある方は誰しも１度はアクセスするのではないかと思います。

リンク↓
https://hub.docker.com

今回はubuntuのlatestイメージをダウンロードします。

![スクリーンショット 2024-03-29 17.29.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3511203/d58ebc96-2839-813e-432e-437198fabdad.png)


イメージダウンロードのためのコマンド
```
＃どちらでもOK

docker pull ubuntu
docker image pull ubuntu
```

ターミナル上で実行して以下の出力があれば完了です。

![スクリーンショット 2024-03-29 17.41.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3511203/c5edd0f1-dc43-1e4a-847e-43efd6b6581f.png)

バージョン指定しない場合は上記のコマンドを使用すれば良いのですが、（※デフォルトでは「latest」がダウンロードされます。）
指定したい場合は以下のように書きましょう。
```
# :の後ろにダウンロードしたいイメージのヴァージョンを指定
docker image pull ubuntu:20.04
```

ちなみに便宜上バージョンという言葉を用いて書かせていただきましたが、Dockerhubにおける識別方法として「TAG」というものが使用されています。「最新のもの（安定版）」という意味でlatestだったり、
開発環境やテスト環境での使用を想定した「rolling」というTAGが使用されてたりします。
その辺の使い分け方はリポジトリ毎に異なりますのでご留意ください。

## イメージの削除

```
# rmの後ろに削除するイメージを指定

docker image rm ubuntu

```

すると以下のようになりますね。

![スクリーンショット 2024-03-29 17.53.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3511203/fdc9ef57-b59c-3163-e17f-4148b302e2e4.png)

以上、Dockerイメージのダウンロード＋削除方法でした。
railsアプリで利用されているreCAPTCHA v2からreCAPTCHA Enterpriseに最小工数で切り替える

2024年4月1日からreCAPTCHAの無料制限が100万回から1万回に制限が変更されるというニュースがありました。

https://bytepursuits.com/google-significantly-reduces-recaptcha-free-tier-introduces-new-pricing-models

小さいサイトだと、1万回は問題なさそうですが、ある程度の規模のサイトだと用途によっては簡単に超えてしまいそうです。
v2を継続する場合、1万回を超えると課金ではなく使えなくなるため、今回は既にreCAPTCHA v2を導入しているRailsアプリケーションをreCAPTCHA Enterpriseに切り替える手順を説明します。


## 今回利用した元々の動作環境

- ruby3.1.4
- rails 7.0.8.1
- reCAPTCHA関連の実装は [ambethia/recaptcha](https://github.com/ambethia/recaptcha) の5.12.3 を利用

## Site keyを作成する

Google Cloudでプロジェクトを作成後、reCAPTCHA Enterprise API をまず有効にします。
有効にした後、reCAPTCHA Enterpriseのページでキーを作成というリンクがあるのでそこを押しします。

作成画面に入った後、利用するドメインなど適切に埋めていけばよいですが、`チェックボックスによる本人確認を使用する`をv2から移行する場合オンにしましょう。

![スクリーンショット 2024-03-29 17.15.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359721/ab11f4b7-d922-0ef6-823f-61cfbc3b128d.png)

これによってv2で行われていた画像認証が行われるようになります。
こちらは作成時しか設定できないため、設定を忘れた場合は削除して作り直しましょう。
こちらで作成したキー IDをSite keyとして後ほど利用します。

## API Keyを作成する

続いて、認証情報のページで`認証情報を作成`→APIキーをクリックします。
![スクリーンショット 2024-03-29 17.18.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359721/2ec42489-b570-cbb6-a53e-358467d5381e.png)
APIキーを作成されたら編集画面に飛び、クライアントでAPIをたたくわけではないため、Webサイトの指定はせず、reCAPTCHA Enterprise APIのみに使えるように制限を与えます。

![スクリーンショット 2024-03-29 17.19.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359721/0065be78-074b-7abc-d73e-dd0e8d67c699.png)

これでGoogle Cloudの設定はOKです。


## Railsアプリケーションの対応

先ほど作成したSite keyとAPI keyを使ってRails側の設定をします。
reCAPTCHAの設定をしているファイルを開き、以下のように書き換えます。

```diff_ruby
# 普通直書きしてないと思うので、そこは各アプリケーションの環境変数のお作法に従ってください
Recaptcha.configure do |config|
-   config.site_key = # 過去設定していたSite key  
+   config.site_key = # 先ほど作成したSite key
-   config.secret_key = # 過去設定していたSecret key   
+   config.enterprise = true
+   config.enterprise_api_key = # 先ほど作成したAPI Key
+   config.enterprise_project_id = # Site Keyなどを作成したプロジェクトのID
end

```

ここまで設定すれば、他の面倒な部分はgrecaptcha gemがよしなにやってくれるため必要な対応は完了となります。
フロントエンドをReactなどで記述している場合は別途そちらの対応も必要ですが、[公式のドキュメント](https://cloud.google.com/recaptcha-enterprise/docs/api-ref-checkbox-keys?hl=ja)を参考にすれば問題なく行えると思います。

## まとめ
[ambethia/recaptcha](https://github.com/ambethia/recaptcha)がかなりよしなにやってくれるので、対応は最小限に済みました。
別サービスへの移行も良いですが、直前や4月以降に知ってこの記事を読んでいる方は、ひとまず少ない工数で行えるreCAPTCHA Enterpriseへの移管をするのが良さそうです。
Pythonコードを使用してExcelでウィンドウ枠を固定・解除する方法

Excelの「ウィンドウ枠の固定」機能を使用すると、データセットのサイズに関係なく、特定の行と列をスクロールする際に重要な情報を表示したままにすることができます。ただし、ウィンドウの解除が必要な場合もあります。行と列のウィンドウを解除することで、大規模なデータセットをシームレスにナビゲートし、包括的なデータ分析、編集、書式設定を容易にすることができます。この記事では、Pythonコードを使用して**Excelワークシートでの「ウィンドウ枠の固定・解除」の方法**を紹介します。

- **[Pythonを使用したExcelワークシートでのウィンドウ枠の固定](#pythonを使用したexcelワークシートでのウィンドウ枠の固定)**
- **[Pythonを使用したExcelワークシートでのウィンドウ枠の解除](#pythonを使用したexcelワークシートでのウィンドウ枠の解除)**

この記事で使用する方法には、[Spire.XLS for Python](https://www.e-iceblue.com/Download/Spire-XLS-Python.html)が必要です。これは公式ウェブサイトからダウンロードするか、PyPIを介してインストールできます：`pip install Spire.XLS`。

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

## Pythonを使用したExcelワークシートでのウィンドウ枠の固定
行と列は、**Worksheet.FreezePanes()** メソッドを使用して固定することができます。このメソッドは2つのパラメーター、rowIndex（1から始まる）とcolumnIndex（1から始まる）を取ります。最初のパラメーターは、すべての行が固定される上部の行のインデックスを表します。2番目のパラメーターは、すべての列が固定される左側の列のインデックスを表します。
Excelワークシートでの行と列の固定の詳細な手順は次のとおりです。
1. **Workbook** クラスのインスタンスを作成します。
2. **Workbook.LoadFromFile()** メソッドを使用してExcelファイルを読み込みます。
3. **Workbook.Worksheets[index]** プロパティを使用して特定のワークシートを取得します。
4. **Worksheet.FreezePanes(rowIndex, columnIndex)** メソッドを使用してワークシートで特定の行と/または列を固定します。
5. **Workbook.SaveToFile()** メソッドを使用して結果のExcelファイルを保存します。

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

# Workbookクラスのインスタンスを作成
workbook = Workbook()

# Excelファイルを読み込む
workbook.LoadFromFile("サンプル.xlsx")

# 最初のワークシートを取得
sheet = workbook.Worksheets.get_Item(0)

# 最初の3行と最初の2列を固定する
sheet.FreezePanes(4, 3)

# Excelファイルを保存する
workbook.SaveToFile("output/ウィンドウ枠の固定.xlsx", FileFormat.Version2016)
workbook.Dispose()
```

**結果ファイル**
![Pythonを使用したExcelワークシートでのウィンドウ枠の固定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/4449b77a-c830-1c7f-f618-165d6b2a3561.png)

## Pythonを使用したExcelワークシートでのウィンドウ枠の解除
**Worksheet.RemovePanes()** メソッドを使用してウィンドウ枠の解除を行うことができます。詳細な手順は次のとおりです。
1. **Workbook** クラスのインスタンスを作成します。
2. **Workbook.LoadFromFile()** メソッドを使用してExcelファイルを読み込みます。
3. **Workbook.Worksheets[index]** プロパティを使用して特定のワークシートを取得します。
4. **Worksheet.RemovePanes()** メソッドを使用してワークシートで行と列のウィンドウ枠を解除します。
5. **Workbook.SaveToFile()** メソッドを使用して結果のExcelファイルを保存します。

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

# Workbookクラスのインスタンスを作成
workbook = Workbook()

# Excelファイルを読み込む
workbook.LoadFromFile("output/ウィンドウ枠の固定.xlsx")

# 最初のワークシートを取得
sheet = workbook.Worksheets.get_Item(0)

# ワークシート内の固定を解除する
sheet.RemovePanes()

# Excelファイルを保存する
workbook.SaveToFile("output/ウィンドウ枠の解除.xlsx", FileFormat.Version2016)
workbook.Dispose()
```

この記事では、Pythonを使用してExcelワークシートで行と列を固定・解除する方法を詳細な手順とコードの例を提供して示しています。

Excelファイルの処理に関するさらなるスキルについては、[Spire.XLS for Pythonのチュートリアル]()にアクセスしてください。

本ライブラリを使用して発生した問題については、[Spire.XLSのフォーラム](https://www.e-iceblue.com/forum/spire-xls-f4.html)で技術サポートを受けてください。
初心者でも簡単にプロ顔負けの楽曲が作れる！！（Suno AIが凄すぎた） 

## 初めに
初めまして、私はITの学習を初めて1年程の新米エンジニアです。
最近SNSではよく生成系AIに関して取り上げられています。
私もついこの間X(旧Twitter)にてとある生成系AIに関しての投稿を見ました。
そちらではとある有名な作曲家の方がこのように呟いておりました。

```
話題のSuno AIを試してみたけどヤバイですねコレは...
アレンジやMixがそれっぽくなるのは想定('_')内だったけどメロも70点くらいのを平気でポンポン出してくる。
うーむ('_')
```
プロも唸らせるAI・・・・
ぜひ使いたい！！

## Suno AIとは

### サービス内容
```
Webブラウザ上で歌詞や曲調をプロンプトで指示するだけで、ボーカル付きの音楽を自動生成できるサービス
```

### 開発会社
```
アメリカ・マサチューセッツ州を拠点とする音楽家とAI専門家達からなる「Suno Inc」が開発
```
開発者の中には、米MetaやTikTokを運営する中国byteDanceなどに所属していた人もいるらしい、、
名前聞いたことないけど、実は大きい？？

### 利用方法
```
Discordアカウント、Googleアカウント、Microsoftアカウントのいずれかが必要
```
結構簡単に利用はできるようです

### 商用利用
```
ユーザーは有料プラン加入で、ダウンロードした曲を商用利用することも可能で、YouTubeでの収益化や音楽ストリーミングサービスへのアップロード、広告や映画、ポッドキャストでのライセンス付与などが可能
```
有料プランに加入すれば商用利用しても問題ないそうです！
オリジナル楽曲作り放題？

### 利用制限
```
無料版では1日に10曲まで作成可能
有料プランは500～2000曲で料金が変わる
```
無料版でもそこそこ作れるんですね

### プラン
```
Basic  : 無料 毎日10曲
Pro    : $10  月500曲
Premier: $30  月2000曲
```
Proでも十分そう、、

### 作成方法

```
1 「Suno AI」は、ユーザーからのテキストを受け取る
2  テキストのパターン、リズム、音を分析
3  ディープラーニングの能力を活用して、歌詞の韻律と構造に対応する曲を作曲
```
「Suno AI」は音楽生成のために2つのAIモデルを使用しているようです。
一つは「Bark」で、ボーカルと歌詞に焦点を当てており、
もう一つは「Chirp」で、楽器のトラックに対応しています。
これらのモデルは、ディープラーニングと広範な音楽データを使用しており、これにより音楽の本質を捉えることが可能になっているととのことです。
内部APIに関しては現状まだ公開はされていないようです。

### Bark
こちらはSunoによって生成されたモデルのようです。
笑ったり、ため息をついたり、泣いたりするなどの非言語コミュニケーションを生成することも可能なようです。
凄いですね、、、

### Chirp
こちらはGoogleによる音声認識モデル「Chirp v2」を使用しているようです。

### 作成モード

作成する際にはモードが二つありました！
```
通常モード
曲の説明を書くだけで、メロディーと歌詞を生成してくれる
```
こちらは説明を書くだけで歌詞まで生成してもらえるそうです。。
凄い、

```
カスタムモード
タイトル、歌詞、曲のスタイルはこちらで用意することが可能
```
こちらは自分で考えた歌詞を歌わせることができるモードです。
コーラスなども指示することが出来ました！
凄すぎる、、

## 総括

今回は「Suno AI」について取り上げていきましたが、中々凄いですね、、
今後生成AIが作り出した楽曲が大ヒット、、、
なんてことが現実にあるかもしれませんね。

是非興味がある方は自身の手で触れてみてください！

https://www.suno.ai/
Denodoでちょっと気にするといいこと

## ビュー名の指定には仮想DB名も含めよう （小ネタ1）

バージョン：V8 20220815

カラムの関数としてビュー名を指定するとき、スケジューラでビューを指定するとき、
あらゆる箇所で「ビューの指定」をしようとしたとき、以下の書き方をお勧めします。

**"\<databasename\>".bv_map_test**


ビュー名のみの場合、複数の仮想DB上に同名のビューがあったりすると可読性にも欠けてしまいます。
場合によってはエラー原因にもなったりします。
例えば、View 'bv_map_test' not found なんてエラーが出たら仮想DB名も指定してみるといいかもですね。
※）もちろん他の原因の可能性もあります
Vue勉強 @vue:mounted, @blur

公式ドキュメントのコード読んでて、これどういう意味なのかさっぱり分からんというのが出てきたので調べた。

公式ドキュメントのexamplesのtodoリストのサンプルコード

https://ja.vuejs.org/examples/#todomvc

の一部
```html:html
          <input
            v-if="todo === editedTodo"
            class="edit"
            type="text"
            v-model="todo.title"
            @vue:mounted="({ el }) => el.focus()"
            @blur="doneEdit(todo)"
            @keyup.enter="doneEdit(todo)"
            @keyup.escape="cancelEdit(todo)"
          >
```
ここの `@vue:mounted` とか、 `@blur` ってどういう意味なの？と思って調べた。

  `@keyup.enter`　は、字面的におそらくエンターキー押したら起動かな？と予想（あってた）。

----
  そもそも、  `@hoge` と、に頭に@がつくのは、
  v-onを省略した形だった。（忘れてた）

> v-on:click="handler"、あるいは省略して @click="handler" として使用します。

  https://ja.vuejs.org/guide/essentials/event-handling

## `@blur`


`@blur`はフォーカスを外した時のイベント
対で、`@focus`が、フォーカスした時。
  https://qiita.com/shizen-shin/items/17094a68a0369e126d41

## `@vue:mounted`

`@vue:mounted` については、全く同じ疑問を持ってる人がいた(笑)

https://github.com/vuejs/core/discussions/10133

> not in the official doc but i found it in the migration guide
>
> https://v3-migration.vuejs.org/breaking-changes/vnode-lifecycle-events.html

公式ドキュメントのコードなのに「公式ドキュメント内に（解説）ない」とかコメント付いてる。。

彼がコメントしてくれてる、このマイグレーションドキュメントの中にあった！
https://v3-migration.vuejs.org/breaking-changes/vnode-lifecycle-events.html

（有り難し。イイね👍押しました。）

vue2 と vue3ではライフサイクルイベントの書き方が違っていて、
vue2では、こうやって書いていたけど、
```html:html
<template>
  <child-component @hook:updated="onUpdated">
</template>
```
vue3では、こうやって書くらしい。頭に`@vue:`をつける。
```html:html
<template>
  <child-component @vue:updated="onUpdated">
</template>
```

ライフサイクルは、`mounted`以外にも`updated`、`created`とか色々あるらしい。
`mounted`は、
「インスタンスがDOMにマウントされた後に実行されるフック」とのこと。

https://qiita.com/whopper1962/items/1a99169ba868f94e4c94
リートン で elixir を学ぶ  (その1）掛け算九九の表を作成

こちらで行ったことと同じことを[リートン](https://wrtn.jp/)で行いました。
[ChatGPT で elixir を学ぶ　（その3） 掛け算九九の表を作成](https://qiita.com/ekzemplaro/items/2cb0a1f9eb327095f32b)
[llama-2 で elixir を学ぶ　（その3）掛け算九九の表を作成](https://qiita.com/ekzemplaro/items/93d14f42dd42b9cb6bcc)

## Python のプログラム

```py:multiplation.py
#! /usr/bin/python
#
import sys
#
sys.stderr.write("*** 開始 ***\n")

for it in range(1,10):
	for jt in range(1,10):
		kt = it * jt
		print("%2d" % kt,end = " ")
	print()

sys.stderr.write("*** 終了 ***\n")
```

## リートンで変換した結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/5905808b-823d-dbf1-6d49-678bea70f1c5.png)

```exs:multiplation01.exs
# !/usr/bin/env elixir
#
IO.warn("*** 開始 ***\n")

for it <- 1..9 do
  for jt <- 1..9, into: "" do
    kt = it * jt
    IO.write(String.pad_leading(Integer.to_string(kt), 2) <> " ")
  end
  IO.puts("")
end

IO.warn("*** 終了 ***\n")
```

修正のスクリプト

```text:sed01
s/# !/#! /
s/IO.warn/IO.puts /
s/, into: ""//
```

変換

```bash
sed -f sed01 < multiplation01.exs > multiplation02.exs
```

```exs:multiplation02.exs
#! /usr/bin/env elixir
#
IO.puts ("*** 開始 ***\n")

for it <- 1..9 do
  for jt <- 1..9 do
    kt = it * jt
    IO.write(String.pad_leading(Integer.to_string(kt), 2) <> " ")
  end
  IO.puts("")
end

IO.puts ("*** 終了 ***\n")
```

実行結果

```text
$ ./multiplation02.exs 
*** 開始 ***

 1  2  3  4  5  6  7  8  9 
 2  4  6  8 10 12 14 16 18 
 3  6  9 12 15 18 21 24 27 
 4  8 12 16 20 24 28 32 36 
 5 10 15 20 25 30 35 40 45 
 6 12 18 24 30 36 42 48 54 
 7 14 21 28 35 42 49 56 63 
 8 16 24 32 40 48 56 64 72 
 9 18 27 36 45 54 63 72 81 
*** 終了 ***

```
【SalesforceMarketingCloud】Automationで現在使っているアクティビティの一覧作成（小ネタ）

# はじめに
こちらの記事はSalesforceMarketingCloud（以下SMC）で開発している方向けに自分が実装していて良かった小ネタを紹介する記事です。

# 概要
SMCで開発を行っているとクエリやデータ抽出などのアクティビティを使ってリストを生成したり、何らかの開発を行うと思います。
各アクティビティを試しに使ったものも含めちゃんと管理されていれば問題ないのですが、消し忘れてしまったり、どのオートメーションで使ってるのか分からなくなったりすることもあるのではないでしょうか。

そんな時用に、現在使っているアクティビティの一覧を作成してくと、結構便利だったのでご紹介しようと思います。

# 手順
1\. 使用している一覧を格納するデータエクステンションを作成する
2\. 使用しているアクティビティを抽出するクエリを作成する
3\. Automationを作成し上記1, 2を設定する

# 詳細
### 1\. 使用している一覧を格納するデータエクステンションを作成する

以下で作成（<a href="https://help.salesforce.com/s/articleView?id=sf.mc_as_data_view_automation_activity_instance.htm&type=5">こちら</a>から必要に応じて追加してください）
| 名前 | 型 | 長さ | Null可能 |備考 |
|:-----------|:------------|:------------|:------------|:------------|
| AutomationName       | 文字列        | 400         |いいえ|呼び出しているAutomation名|
| ActivityName     | 文字列      | 400       |いいえ|アクティビティ名|
| ActivityTypeName       | 文字列        | 199         |いいえ|アクティビティタイプ|
| ActivityInstanceStartTime_UTC         | 日付          | -           |はい|アクティビティの実行が開始された時刻|


### 2\. 使用しているアクティビティを抽出するクエリを作成する
以下クエリアクティビティを作成する。
```
SELECT
  AutomationName,
  ActivityName,
  CASE ActivityType
    WHEN 33 THEN 'SMS Activity'
    WHEN 42 THEN 'Send Email'
    WHEN 43 THEN 'Import File'
    WHEN 45 THEN 'Refresh Group'
    WHEN 53 THEN 'File Transfer'
    WHEN 73 THEN 'Data Extract'
    WHEN 84 THEN 'Report Definition'
    WHEN 300 THEN 'SQL Query'
    WHEN 303 THEN 'Filter'
    WHEN 423 THEN 'Script'
    WHEN 425 THEN 'Data Factory Utility Activity'
    WHEN 426 THEN 'Refresh Segment Template'
    WHEN 427 THEN 'Publish Audience'
    WHEN 467 THEN 'Wait'
    WHEN 724 THEN 'Refresh Mobile Filtered List'
    WHEN 725 THEN 'Send SMS'
    WHEN 726 THEN 'Import Mobile Contacts'
    WHEN 733 THEN 'Journey Builder Event Activity'
    WHEN 736 THEN 'Send Push'
    WHEN 749 THEN 'Fire Event'
    WHEN 771 THEN 'Salesforce Email Send'
    WHEN 772 THEN 'Mobile Connect Send Salesforce Sync Subscriber'
    WHEN 783 THEN 'Send GroupConnect'
    WHEN 952 THEN 'Journey Builder Event Activity'
    WHEN 1000 THEN 'Verification'
    WHEN 1010 THEN 'Interaction Studio Data'
    WHEN 1101 THEN 'Interactions'
    WHEN 1701 THEN 'Batch Personalization'
    WHEN 3700 THEN 'Contact to Business Unit Mapping'
    ELSE 'OTHER'
  END AS ActivityTypeName,
  MAX(ActivityInstanceStartTime_UTC) AS ActivityInstanceStartTime_UTC
FROM
  _automationactivityinstance
GROUP BY AutomationName, ActivityName, ActivityType
```
＊ターゲットデータエクステンション：上記1で作成したデータエクステンション
＊データアクション：Update

### 3\. Automationを作成し上記1, 2を設定する
以下のようにAutomationを作成し実行すればOK
![オートメーション設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87351/2b77dd64-9962-ff86-5bf9-8fc2ebc4107f.png)

# 最後に
簡単に作成できるので、もしやっていない方いらっしゃれば設定をお勧めします。
少しでもどなたかのお役に立ててたら嬉しいです。