OmniAICreator/Qiita-1.07M huggingface dataset:
Wisteriaに最新のJuliaを入れる方法（＋CUDA.jlも動かしてみる）

普段，某大のWisteriaを使っています．
Wisteriaには一応Juliaが入っていますが，最新ではありません[^1]．
では自分のディレクトリに最新版を入れて使ってしまえ，ということになりますが，思った以上に苦労したので書き残しておきます（~~こんなニッチな記事，誰が見るんでしょう~~）．
インストールには，最近話題の`Juliaup`を使ってみます．

https://github.com/JuliaLang/juliaup


なお，この記事の内容について筆者は責任を負いませんので，実行する場合は自己責任でお願いします．
また，Wisteriaに限った話なので，他のCluster Machine上で動かない可能性大です．

[^1]: 本稿執筆時点で，Juliaの最新版はv1.9.3ですが，Wisteriaにはv1.6.1しか入っていません．


# 手順

## ホームディレクトリの変更

Wisteriaのユーザガイドを読むと，計算ノードからはホームディレクトリ(`/home/ユーザー名`)にアクセスできないことがわかります．Juliaupはファイル群をホームディレクトリに入れようとするので，このままではジョブでJuliaを動かせないと思われます．そこで，ホームディレクトリを計算ノードが認識できるディレクトリに変更するという手順が必要になります．これは，ログインノードで
```shell
$ chhome /work/グループ名/ユーザー名
```
を実行すればOKです．パスワードを聞かれるので，Wisteriaのポータルサイトにログインする時のパスワードを入れます．
変更を反映させるために，一度ログアウトし，再度ログインします．
```
$ echo $HOME
```
を実行して，結果が`/work/グループ名/ユーザー名`となることを確認しておきましょう．

## Juliaのインストール
以下，`/work/グループ名/ユーザー名`で作業しているものとします．
```
$ curl -fsSL https://install.julialang.org | sh
```
でJuliaupのインストールが始まります．
インストール先は〇〇でいいか？などと聞かれるので，もし`/work/グループ名/ユーザー名`以下でない場所にインストールしようとしていたら，`/work/グループ名/ユーザー名`以下にインストールするよう指定します．
インストールが終わると，
```
 . /work/グループ名/ユーザー名/.bashrc
 . /work/グループ名/ユーザー名/.bash_profile
 . /work/グループ名/ユーザー名/.zshrc
```
のいずれかを実行してパスを通すよう言われるので，指示に従います．私は一番上を実行しました．



## Juliaの起動，パッケージの導入
いよいよJuliaを起動します．
```
$ julia
```
とすれば，お馴染みのロゴが表示され，REPLがスタートします．
```
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.9.3 (2023-08-24)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia> 
```

あとは
```
]
```
でパッケージモードに入り，`add hoge`等で必要なパッケージをインストールしてください．


# おまけ
私の目標は，Wisteria上で`CUDA.jl`を使ってみることでした．その結果もここに書いておきます．

まず，パッケージモードで`add CUDA`を実行しインストールを行います．数分で終わります．

さて，`CUDA.jl`を使ってみますが，ログインノードでJuliaを実行して`using CUDA`とかしないように注意しましょう！（ログインノードではGPUが使えないので当然エラーが出ます．私は最初このことに気づかず苦労しました…）
ここでは，GPUを積んでいるAquarius上でのインタラクティブジョブを実行し，`CUDA.jl`がGPUを認識できるか試してみます．

```
$ pjsub --interact -g グループ名 -L rscgrp=interactive-a,node=1
```
でインタラクティブジョブを開始し
```
$ module load aquarius
$ module load cuda/12.1
$ module load cudnn/8.8.1 
```
で必要なCUDAツールキットなどを呼び出します．
バージョンはなんでもいいと思いますが，ここではWisteriaで利用可能な最新のものとしました[^2]．

[^2]: ただしCUDAのバージョンとcuDNNのバージョンは，適切に合わせる必要があります．

続いて
```
$ julia
```
でJuliaをスタートし
```
julia> using CUDA
julia> CUDA.versioninfo()
```
としました．結果はここには出しませんが，
- CUDAやNVIDIAのdriverの情報
- 認識されたデバイスの情報

が表示されましたので，正しく動作しているものと考えています．

最後に

https://cuda.juliagpu.org/stable/usage/overview/#The-CuArray-type

にある例を試してみます．

```
a = CuArray{Int}(undef, 1024)
b = copy(a)
fill!(b, 0)
b == CUDA.zeros(Int, 1024)
```
結果は`true`でした．問題なく動いているようです．




# 終わりに

次は`Flux.jl`で機械学習をしてみたいと思っています．
いつになるかわかりませんが…
使える司令文

ChatGPTに入力するプロンプトを考えてください。

フォーマットは以下の４つとします。

#司令文
ここに普通にやってほしことをかく。壁打ちしたいとかサービス名考えてとか


#目的・ゴール
目的はちゃんと伝えた方がいいです。Twitterでバズらせたいとか、クリックされる広告文が欲しいとか。


#制約条件
ただしXXXなど条件、数量や長さなどの制約、は箇条書きでここへ


#出力
※ここはChatGPTに区切りを教えるためのものなので何も書かない


上記を出力し終わった後に、そのプロンプトの実行結果も出してください。
Ctrl+Spaceで全角／半角切り替える(AutoHotkey v2)

## 概要
AutoHotkeyのv2環境で、Ctr+Spaceで全角／半角を切り替えるスクリプトが探しても見つからなかったので、記録

## スクリプト
``` CtrlSpaceIme.ahk
^Space:: 
{
    send "{vkF3sc029}"   
}
```

## 参考
https://qiita.com/taretmch/items/eedd42c4f2099a9a8542
リセットボタンでJSが走る処理を書いたらうまくいかなかった

## たとえばこんなコード
```HTML
<button type="reset" id="resetButton" name="resetButton" 
            class="btn btn-default">リセット</button>

```
```js
<script>
$('#resetButton').click(function() {

const sampleValue = $("input[name='sampleselected']:checked").val();

    if (sampleselected === '0') {
        $('#sampletextbox').prop('disabled', true);
    } else {
        $('#sampletextbox').prop('disabled', false);
    }
});
</script>
```
リセットボタンがクリックされた時、「sampleselected」のチェック状態の値でテキストボックスの活性状態を制御しています
値をもたせているのは他の画面からの遷移状況でデフォルトの値が変化するからです。
リセットでチェック状態が初期に戻れば付随してテキストボックスの活性状態も変化する想定でしたが、想定通り変化しないパターンが発生しました。なぜ？？？

## 結論
これで直りました
```HTML
<button type="button" id="resetButton" name="resetButton" 
            class="btn btn-default">リセット</button>
```

```js
<script>
$('#resetButton').click(function() {
    $('#Sampleform')[0].reset();

    if ($("input[name='sampleselected']:checked").val() === '0') {
        $('#sampletextbox').prop('disabled', true);
    } else {
        $('##sampletextbox').prop('disabled', false);
    }
});
</script>
```
button typeを"button"へ変更し、フォームにIDを振って[0].reset();としていますが、
button type"reset"と同様フォームをリセットしてくれます。
type=resetをjsのイベントの呼び出しとして使うと処理がぶつかってうまくいかない場合があるようです。

[こちら](https://developer.mozilla.org/ja/docs/Web/HTML/Element/input/reset)にも、「JavaScript を使用してカスタマイズしたいのであれば、 input type="button" またはよりよい button 要素を使用してください。」ときちんと書いてありますね。
PhpStormでFTP(S)経由によるファイル自動アップロード

# `ツール` > `デプロイ` > `構成`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/639d66c9-1e39-b9a9-2b62-b5faca426a48.png)

# `+` > `FTP` or `FTPS`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/4c4e722f-ef33-57d2-c3f6-5cc0525de749.png)

# サーバー名を入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/0f64fd07-3e78-6a4e-321f-d1446696f737.png)

# FTPアカウント情報を入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/9ec5e8c4-4688-01a9-a435-22a7f0716d32.png)

下記、xserverの手順になりますう

### ホスト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/10ca6465-0c5a-cdbd-d13c-ac134ac1fe11.png)

### ユーザー名
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/98bf17e3-46c8-f0b5-09ba-1bd5ca20a3d3.png)

### パスワード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/5eb9f8e1-623c-f53f-b091-dadf7917161e.png)

### `接続のテスト`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/2e38c12f-0231-9d12-2687-95643b0d2cd2.png)

### WebサーバーURL
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/9226d69c-9add-bc18-d89e-5f7cc7fdea81.png)

# `マッピング` > `デプロイパス`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/d4ec1afb-d332-2bc6-e817-832d4834271c.png)

# 自動アップロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/71d08f72-855a-5da0-99da-dbe4ce1d1df7.png)

# アップロード先のフォルダー

`デプロイパス`を変更しましょう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/55e9b148-8d20-a395-0a25-74c76eb4f2b1.png)
Junos(SRX)でDS-Liteを使用してみる ver 2023

[以前](https://qiita.com/kazubu/items/7356e14d7b284cff7907)、Junos 22.2R1で実装されたIPv4 over IPv6機能を用いてJuniper SRXシリーズでDS-Liteを使う際の設定を紹介しました。

Junos 23.2R1において、さらにFQDNでトンネル接続先アドレスを指定したり、トンネルソースアドレスを指定したインターフェイスから取得する機能をサポートしました([ドキュメント](https://www.juniper.net/documentation/us/en/software/junos/interfaces-encryption/topics/ref/statement/tunnel-edit-interfaces-sv-encryption.html))。

今回はこの機能を使用したDS-Liteの設定例を紹介しようと思います。

# DS-Liteの設定例

主な設定としては[以前](https://qiita.com/kazubu/items/7356e14d7b284cff7907)と同様ですが、`source-interface`および`destination-hostname`を使用することでアドレス変更に自動的に追従することが可能となりました。ホスト名やインターフェイス名からはアドレスファミリーを一意に定めることができないため、`encap-type`でアドレスファミリ(ipv4/ipv6)を明示的に指定する必要があります。
```
set interfaces ge-0/0/0 unit 0 family inet6 address 2001:db8:1000::2/64
set interfaces ip-0/0/0 unit 0 tunnel encap-type ipv6
set interfaces ip-0/0/0 unit 0 tunnel source-interface ge-0/0/0.0
set interfaces ip-0/0/0 unit 0 tunnel destination-hostname aftr.example.net
set interfaces ip-0/0/0 unit 0 family inet
set routing-options rib inet6.0 static route ::/0 next-hop 2001:db8:1000::1
set routing-options static route 0.0.0.0/0 next-hop ip-0/0/0.0
```

RAでアドレスを取得する場合は以下のようになります。


```
set interfaces ge-0/0/0 unit 0 family inet6 dhcpv6-client client-type autoconfig
set interfaces ge-0/0/0 unit 0 family inet6 dhcpv6-client client-ia-type ia-na
set interfaces ge-0/0/0 unit 0 family inet6 dhcpv6-client client-identifier duid-type duid-ll
set interfaces ge-0/0/0 unit 0 family inet6 dhcpv6-client update-server
set interfaces ip-0/0/0 unit 0 tunnel encap-type ipv6
set interfaces ip-0/0/0 unit 0 tunnel source-interface ge-0/0/0.0
set interfaces ip-0/0/0 unit 0 tunnel destination-hostname gw.example.jp
set interfaces ip-0/0/0 unit 0 family inet
set protocols router-advertisement interface ge-0/0/0.0 passive-mode
set routing-options static route 0.0.0.0/0 next-hop ip-0/0/0.0
```

このように、IPv6アドレスの変動やDS-Lite AFTRのアドレス変更等にも追従できるようになり、利用できるシーンが広がりました。

試してはいませんが、似たような設定で固定IPサービスについても対応できると思います。固定IPサービスの場合、`ip-0/0/0.0`に使用するIPアドレスを指定したり、定期的にHTTPリクエストを叩いたりする設定が必要になると思われます。定期的なHTTPリクエストはevent-optionsないしrpmにて構成することが可能です。
troccoを使ってYahoo!広告のレポートをLookerStudioで可視化する


社内エンジニアの方にtroccoの使い方を教えてもらったので触ってみました
troccoのフリープランを開放して頂いて、Yahoo!広告のダミーデータを使用しています

LookerStudioを使ってGoogle広告のデータを可視化したい場合、既存の専用コネクタを用いて簡単に実装できる。一方で、Yahoo!広告は直接繋ぐことができないため、一度BigQuery等に集計データを落としたうえで、可視化する必要があって大変手間。troccoを使えば超簡単。
　
# 実装

下記が完成例。

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319121/d0d68213-2cee-7b0d-3d6e-9d5d50d99315.png)


## troccoの準備をする

troccoのアカウントを準備する。
その上で、`接続情報`から、Yahoo広告とBigQueryに連携。
ポチポチでできた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319121/341d968f-7ce3-1204-e0eb-ce760e281482.png)

`データ転送`の`転送設定`からYahoo!検索広告とBigQueryを指定。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319121/72a6a6d6-d456-1977-c6ab-5dded2204e38.png)

Yahoo!広告 検索広告APIの仕様を確認しながら、使用したい粒度でデータを選ぶ。レポートテンプレートが準備されているので、レファレンスを見なくても大抵のデータは指定できた。IMPシェアなどのデータはデフォルトがdouble型以外になっているので注意。

データ取得期間にはカスタム変数が使えるので「2022年1月から昨日まで」のような指定ができるのが便利だった。また、CTRやCVRなどの計算が必要な指標は、週や月などのディメンションで上手く再集計できなくなるので、ここで指定せずにBIツール上で（Excelの集計フィールドのように）定義した方が良さそう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319121/f634d730-f2dc-d0c9-8714-781d63ade533.png)

転送先のBigQueryも同様に指定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319121/f7c13557-3ee4-2339-4ecb-ff0abf0160aa.png)

プレビューページで、意図通りのテーブルになっているか確認。ここで転送前のフィルタリングや置換、ハッシュ化などの詳細設定もできる。

転送モードで、BigQueryへの追記か洗い替えか選べる。広告データの場合は、後追いCVやIMPシェアデータが遅れて更新されるため、基本的には洗い替え。社内では、ワークフローを使って事前にBQのデータを指定期間分（7日分）削除して、新たに7日分追記しているそう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319121/25b212c5-6e37-633b-344d-db3a2294de21.png)

最後に実行スケジュールを指定したら、完了。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319121/e17f9867-14f5-4485-96a4-efab7b7c30c4.png)

BigQueryにも正しくデータが格納されている。troccoでテーブルを指定する際にテーブル名をYYYYMMDDにしたら、BigQueryの仕様なのか、LookerStudioでデータを使用することができなかったので注意。

## LookerStudioで可視化する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319121/0aa4213d-f170-c6ac-013c-a29cf474b123.png)

LookerStudioで実装する際の注意点として、CTRやCVRなどの集計指標を作る場合は、カスタムフィールドを使用すること。例えば、CTRの場合は`SUM(CLICKS)/SUM(IMPS)`のように集計関数を使うことで、他のディメンションと掛け合わせた際でも正しく加重平均された値になる。

troccoを初めて使ってみましたが、非エンジニアであっても超簡単に扱えた。これで、１枚のダッシュボードでGoogle広告とYahoo!広告のデータを並べて（あるいは結合して）分析できるようになるのは凄く便利。
TinyUSB に自前のデバイスクラスドライバを組み込む

# これは何?

[TinyUSB](https://github.com/hathach/tinyusb) が提供するデバイスクラスドライバを override する方法を紹介します。

# 想定読者

TinyUSB を使って vendor クラスを実装したいんだけど、 TinyUSB のデフォルト実装だとやりたいことが出来ない人

# 結論

[PR385](https://github.com/hathach/tinyusb/pull/385) で追加された
`usbd_app_driver_get_cb` を実装し、自前デバイスクラスドライバの `usbd_class_driver_t` を返しましょう。

実装例は [Raspberry pi Pico の resetデバイス](https://github.com/raspberrypi/pico-sdk/pull/197) があります。

# 補足

[Device Stack](https://github.com/hathach/tinyusb#device-stack) の説明に次のような説明があります。上記結論と同様のことを書いています。

```
If you have a special requirement, usbd_app_driver_get_cb() can be used to write your own class driver without modifying the stack. Here is how the RPi team added their reset interface raspberrypi/pico-sdk#197
```
REST APIについてまとめ

# REST APIとは


REST APIとは、RESTの原則に従ったAPIのことです。
RESTとは設計原則です。設計原則には以下6つの特徴があります。

### クライアント、サーバー
クライアント（画面）とサーバ（データ）を分けて、クライアントがトリガーとなり、サーバ側はレスポンスを返します。サーバ側は基本的には受け身の状態です。

### ステートレス
サーバ側でセッション情報を保持せずにクライアント側で保持します。サーバ側で保持してしまうと、他のサーバとセッション情報を共有しなければいけません。
複数のサーバがある場合、一つのサーバのみにセッション情報があり、他のサーバにはセッション情報がない場合だと、サーバによって、レスポンスが異なってしまうためです。
**クライアント側にセッション情報を保持することで、サーバ側はセッション情報を共有しなくて済むため、サーバ台数を増やしやすいです（スケールアウト）。
デメリットとして、サーバ側で状態を保持しておかないため、やり取りが冗長になってしまいます。一回のリクエストだけで、サーバとクライアントのやり取りを終えるためにリクエストデータが冗長になります。**

### コードオンデマンド
サーバにあるHTMLやJavaScriptなどのプログラムをクライアント側にダウンロードして利用できることです。本番リリース後にサーバ側にあるHTMLやJavaScriptを修正すれば、クライアントは修正後のプログラムを利用できます。

### キャッシュ制御
サーバからレスポンスされたデータをクライアントは保存できます。データをキャッシュすることにより、不要なクライアントとサーバ間の通信がなくなり、**ユーザ体験が向上することやリソースを効率的に使用できます。ただし、古いデータを使用して、信頼を低下する恐れがあります**。

### 統一インターフェイス
クライアントからサーバに対してURIで示したリソースに対して、取得や更新、生成、削除などの操作を行います。その際に、取得はGET、更新はPUT、生成はPOST、削除はDELETEなどのHTTPメソッドに統一することです。
また、サーバからクライアントに返却するデータ形式もJSONやXMLにするかを決めます。JSON形式の方が一般的のようです。

### 階層化システム
複数のWEBサーバ、APサーバ、DBサーバなどの構成のことです。マイクロサービスのように密結合ではなく、疎結合のため、それぞれのサーバを再利用することができるというメリットがあります。

### API

APIとは *Application Programming Interface* の略です。**インターフェイスは何かと何かを繋ぐという意味です。** 例えば、マウスはパソコンとユーザを繋ぐ役割を果たしております。今回の場合はクライアントとサーバを繋ぐ役割のことを指しております。


# REST APIを実践 

movieをリソースとして CRUD操作のURI、HTTPメソッドを定義してみました。

| URI | HTTP method |
|:-:|:-:|
| http://api.example.com/movies  | GET  |
| http://api.example.com/movies/12345  | GET  |
| http://api.example.com/movies  | POST  |
| http://api.example.com/movies/12345  | PUT  |
| http://api.example.com/movies/12345  | DELETE  |
Vimium チートシート

## はじめに
Chrome拡張機能「[Vimium](https://chrome.google.com/webstore/detail/vimium/dbepggeogbaibhgnhhndojpepiihcmeb)」のチートシートです。
よく使う操作を種類ごとにまとめました。
※ここにある以外の操作は`?`で確認できます。
※さらに興味がある方は[公式のwiki](https://github.com/philc/vimium/wiki)をご覧ください。

## コマンド

### 画面スクロール
| 入力 | 動作 |
|:-----------:|:------------|
|j|下にスクロール|
|k|上にスクロール|
|d|下に半画面スクロール|
|u|上に半画面スクロール|
|G|ページ最下部までスクロール|
|gg|ページ最上部までスクロール|

### ページ移動
|     入力     |     動作     |
|:-----------:|:--------------|
|      H      | 前のページに戻る |
|      L      | 次のページに進む |
|      gu     | 1つ上の階層に戻る |
|      gU     |1番上の階層に戻る|

### タブ移動
| 入力 | 動作 |
|:-----------:|:------------|
|J|前(左)のタブに移動|
|K|次(右)のタブに移動|

### タブ操作
| 入力 | 動作 |
|:-----------:|:------------|
|r|再読み込み|
|t|新しいタブを開く|
|x|カレントタブを閉じる|
|X|閉じたタブを開く|
|yt|カレントタブを複製する|
|yy|カレントタブのURLをコピー|
|p|コピーしたURLをカレントタブで開く<br>※`P`で新規タブで開く|

### 検索
| 入力 | 動作 |
|:-----------:|:------------|
|/|ページ内検索<br>※`n` `N`で検索結果を移動|
|o|履歴&ブックマーク検索<br>※`O`で新規タブで開く|
|b|ブックマーク検索<br>※`B`で新規タブで開く|
|T|開いているタブ検索|

### 選択(Visualモード)
| 入力 | 動作 |
|:-----------:|:------------|
|v|Visualモードに入る<br>※`V`で行選択|
|h,j,k,l|選択領域変更<br>※`e` `b`などの(Vim風)操作も使えます|
|o|選択領域の始点と終点を入れ替える|
|c|Caretモードに入る<br>※選択開始位置を変更するモード<br>※Visualモード中に押下する|

### マーク
| 入力 | 動作 |
|:-----------:|:------------|
|m[a-z]|ローカルマークをつける|
|`[a-z]|ローカルマークをつけた場所に移動|

※`[A-Z]`でグローバルマーク
※ローカルマークはページ内でのみ有効
　(ページ内の移動に便利)
※グローバルマークは他ページでも有効
　(タブ間の移動に便利)

### フォーカス
| 入力 | 動作 |
|:-----------:|:------------|
|f|ページ内のクリック可能な要素<br>(リンクやinput要素)をラベリング<br>※ラベルを入力してフォーカス<br>(リンクなら開く)<br>※`F`で新規タブで開く|
|gi|画面に映っている入力要素にフォーカス<br>※複数ある場合は`Tab`で移動|

## さいごに
設定でカスタマイズすることもできるので、気になる方は調べてみてください。<br>(自分の設定についてはまとめる予定です。)
【SwiftUI】絵文字が下からいっぱい出てくるアニメーション

# はじめに
ストーリーに絵文字を送ると下から絵文字が出てくるのをイメージして作ってみました

# こんな感じ
![Simulator Screen Recording - iPhone 14 Pro - 2023-08-30 at 22.58.10.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/2af06169-9571-cda2-fcaa-749e240fc0a6.gif)

# 実装
```swift
import SwiftUI

struct ContentView: View {
    @State private var rotation: Double = 0.0

    @State private var isAnimation = false

    var body: some View {
        GeometryReader { geometryProxy in
            ZStack {
                ForEach(0..<50) { _ in
                    emojiView(emoji: "❤️")
                        .scaleEffect(isAnimation ? .random(in: 1...1.5) : 0)
                        .offset(y: isAnimation ? -geometryProxy.size.height : 0)
                        .opacity(isAnimation ? 0 : 1)
                        .rotationEffect(.degrees(isAnimation ? .random(in: -40...40) : 0))
                        .animation(.easeOut(duration: .random(in: 3...6)).delay(.random(in: 0...10)).repeatForever(autoreverses: false), value: isAnimation)
                }
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom)
            .onAppear {
                isAnimation.toggle()
            }
        }
    }
    
    private func emojiView(emoji: String) -> some View {
        Text(emoji)
            .rotation3DEffect(.degrees(rotation), axis: (x: 0, y: 1, z: 0))
            .font(.system(size: 130))
            .animation(.easeOut(duration: .random(in: 1...2)).repeatForever(autoreverses: false), value: rotation)
            .onAppear { rotation = 360.0 }
    }
}
```

# おわり
インスタの見ながらやったわけじゃなくて完全にイメージだから違うかもw
アジャイル開発におけるプラクティスの罠

## はじめに

これを書いているのはプラクティス集めが趣味で、[「アジャイルプラクティス一覧」](https://qiita.com/kakashi_h5/items/20584998c5ca4594b9ea)なんてものを書いている者です。そんな人間がなぜプラクティスに対して警鐘を鳴らす記事を書いているかというと、かつての自分のようなプラクティス厨を生み出さないようにするためで、自戒を込めて書いております。
１つ１つのプラクティス自体は素晴らしいアイデアの結晶なので、正しい用法で、正しい目的のために活用していただき、プラクティスが作り出す落とし穴にハマらないようにご注意下さい。

## この記事で伝えたいこと

:::note warn
プラクティスの注意点
**・プラクティスはどの現場でも必ず効果があるとは限らない**
**・プラクティスは手段だけど、とても自己目的化しやすい**
**・アジャイル開発で本当に大切なことはプラクティスではない**
:::

上記について、すでに知ってるよ、という方は、本稿は単純にポエムとして楽しんでいただければ幸いです。

## プラクティスの効果が出ない時
詳しくは[別の記事](https://qiita.com/kakashi_h5/items/5c545ee000933293434f)にまとめていますが、そもそもプラクティスは学術的に効果があることが証明されている「方法論」ではありません。ある特定の条件下では効果がある「かもしれない」やり方です。また「プラクティスの目的を理解せずに、他で上手くいったやり方をただ真似しても効果が出ない」とよく言われますが、これは現場の文脈（コンテキスト）に依存する要素があるからです。プラクティスの効果が出ない時は、やり方が良くないか、そもそも文脈が合ってないか、です。（メンバーが目的を理解していない、は論外として）
なのでプラクティスの効果が出なかった時でも「このプラクティスは使えない」ではなく「うちのチームには合わなかった」と表現するのがいいと考えます。

個人的な実感として、プラクティスのやり方を「知っている」と実際に「やったことがある」の差はかなり大きいように感じます。さらに言えば「やったことがある」と「使いこなせる」の間にも距離があります。やってみないと分からない要素が多いのであれば、最初から深く考えすぎずに、色々試してみるというアプローチは間違っていないように思います。ただし留意点として、プラクティスは「始める」よりも「止める」方が難しい気がします。

## ワークショップ症候群
プラクティスは課題解決のための手段です。しかし魅力的なプラクティスを見つけると課題も無いのについやりたくなってしまいます。こういったプラクティスをやること自体が目的となってしまうことをワークショップ症候群と呼ぶらしいですが、僕にも思い当たる節があります。他にもチームで長らく続けているプラクティスが当初の目的を離れ、ただそれをやり続けることが習慣になってしまったり、とか。
プラクティスが自己目的化しやすいのは、実施することが単純に「楽しい」からではないかと思います。無味乾燥な作業もプラクティスで包んであげると楽しいワークに一変したりするので、その魔法が、逆に依存性につながってしまうというのは皮肉な話です。

それを防ぐ手立ては「まず課題⇒その解決手段としてのプラクティス」という順番を守る、この一言に尽きるかと。興味があるプラクティスは心の中にメモっておいて、いつか使う機会が巡ってくることを待ちましょう。

## 大切なことはプラクティスの外にある
アジャイル宣言にも「プロセスやツールよりも個人と対話を」と謳われています。
プラクティスが尊いのは、それを生み出した現場において、関係者で話し合い、創意工夫を重ねる中でたどりついたやり方である、という点です。そういったマインドや関係性を欠いた状態でプロセスだけをコピーしても効果が出ないのは当然といえます。本当に大切なのはプラクティスではなく、マインドセットです。プラクティスはその本当に大切なものを引き出すための手段の１つにすぎません。

課題に出会った時、反射的に「これを解決するプラクティスはどれかな？」と考えてしまう場合は注意が必要かもしれません。その前に一度「これは本当にプラクティスを使わないと解決できない問題なのか？」と自問してみた方がよいでしょう。単純に対話することで解決できる問題も多いはずです。

プラクティスは人目を引くので、初心者はプラクティスをすることがアジャイルだ、と勘違いしてしまうことがあります。そしてこの引力は初心者以外にも作用します。分かっていたはずなのに知らず知らずのうちにプラクティスが中心になってしまっていた、ということがあるかもしれません。そんな時は「Don't Do Agile! Be agile!」という格言を思い出して下さい。

## こぼれ話（心の中のつぶやき）
この記事を書くことで自分の中で免罪符は得たので、これで心置きなくプラクティス収集の道に戻れます。(笑)
プラクティスはゴールではないにせよ、アジャイルへの近道であることは間違いないと思うので、これからも先人の知恵はありがたく活用させていただきます。感謝。

　[アジャイルプラクティス一覧へ戻る](https://qiita.com/kakashi_h5/items/20584998c5ca4594b9ea)
AWS SagemakerでLightGBMの特徴量のインパクトの取得法

# この記事の目的
今回の記事では、AWSのサービスであるSagemakerでLightGBMを用いた機械学習モデルを作成し、特徴量のインパクトを取得しようとしたところ、通常の取得法とは異なりましたので共有します。
調べても出てこなかったので、覚えておくといいかも？

# Sagemakerとは
AWSのサービスの1つであり、機械学習モデルを構築・実装が可能なサービスです（超ざっくり）。
中でも、学習済みのモデルを転移学習させる方法や、組み込みのアルゴリズムを使用した機械学習モデルの作成ができます。
AutoMLも可能ですので、データセットを渡すだけで自動で学習モデルの作成も行ってもらえます。

# 特徴量のインパクトの取得法
本題に入ります。
モデル作成後に以下のプログラムを実行してください。
（Notebookなのでいくつかのセルに分けて確認しながら進めてください。）

```python
!pip install lightgbm

import lightgbm as lgb
import joblib

model_path = 'pickleファイルのパス'
model = joblib.load(model_path)
importance = model.feature_importance()
feature_names = model.feature_name()
for (feature, score) in zip(feature_names, importance):
  print(f'Feature:{feature}, Importance:{score}')
  
gbm_imp = pd.DataFrame(importance, columns=['Importance'])
df = df.drop(columns=['target'])
Features = df.columns
gbm_imp.insert(0,'Features',Features)
sorted_gbm_imp = gbm_imp.sort_values(by='Importance',ascending=False)
```

組み込みのアルゴリズムではlightgbmというライブラリはインストールしていないはずですので、!を頭に付けてインストールします。

pickleファイルのパスを指定していますが、まずは今回作成したモデルのアーティファクト内から取得する必要があります。
以下に手順を示します。

1. 学習したモデルのトレーニングジョブの出力先のS3からアーティファクトをダウンロード
1. ダウンロードしたアーティファクトを解凍
1. 解凍して得られたZIPファイルを解凍
1. 解凍後のフォルダ内から「model.pkl」というファイルのパスを指定

以上です。
簡単ですね。

あとは、テストデータとして使用した特徴量と特徴量のインパクトを対応させて、値を取得するだけです。

その後の作業としては、インパクトを降順で表示し、データとして抽出したかったのでいろいろデータフレーム弄ったりしてる個人的な部分ですのでスルーしてください。
for文までが今回の内容ですね。

# まとめ
AWSのドキュメントや記事を読み漁りましたが、今回の内容は見当たりませんでした。
公式が出してる仕様書？は3500ページ近くあったので、そっと閉じました。
ごめんなさいm(__)m

ですが、その他ではない情報の可能性がありますのでここで共有させていただければと思います！
それでは！！！
Webページとは

webページの成り立ちをまとめます。初記事です。
# そもそもWebページってどんなふうにできてるの？
Webページは、主に以下のものから出来ている。
- HTMLファイル：ページの文字要素や構成をまとめたもの。１ページに一つのHTMLファイルが基本。<br><br>
- CSSファイル　：ページの表示形式・スタイルをまとめたもの。<br> <br>
- 画像や音声のファイル

　　全てのファイルに、それぞれのURLが割り当てられている。

# なぜWebページを表示できるのか
　上記の様に、Webページを構成するHTMLなどの各ファイルには、URLが割り当てられている。

　ここで重要な役割を果たすのがwebブラウザ。URLを参照し、該当ファイルを保管しているwebサーバーに、「ファイルをダウンロードさせて欲しい」とリクエストを出すのである。そして無事ダウンロードされれば、やはりブラウザが、ファイルを処理し画面に表示してくれる。

　**何気なく使ってたwebブラウザの役割！すごい！**
# まとめ
"まとめ"というほど長い記事でもありませんので、感想を。
　**初めての記事でした！緊張！**　でも楽しい！これからwebページの基礎を、学習しつつまとめていきたいと思っています。



参考文献・サイト
　狩野祐東　『Webクリエイター能力認定試験 HTML5対応 エキスパート 公式テキスト』（FOM出版 2019年)
　[Udemyメディア]　https://udemy.benesse.co.jp/design/web-design/what-is-css.html
CSVデータの加工方法

# 列追加、行追加

## csvファイルに行追加
1行
``` 
new_row = {'ts': 0, 'x': 0, 'y': 0}
```
2行

## csvファイルに列追加
```
# 新しい列の計算
norm_data = np.sqrt(df_pdr['x']**2 + df_pdr['y']**2)

# 新しい列をデータフレームに追加
new_column_name = 'norm'  # 新しい列の名前
df_pdr.insert(3, new_column_name, norm_data)  # 4列目に追加
```

## csvファイル列抜き出し
```
# PDRファイルの2列目を抜き出す
add_data = df_sensor.iloc[:, 3]  # 2列目のデータ
```

## 全体コード
```
import pandas as pd
import numpy as np

# CSVファイルを読み込む
csv_filename = 'pbr.csv'  # 読み込むCSVファイルの名前
df_pdr = pd.read_csv(csv_filename)

#----0を行に追加--------
new_row = {'ts': 0, 'x': 0, 'y': 0}

# 新しい行をデータフレームに追加
df_pdr = pd.concat([pd.DataFrame([new_row]), df_pdr], ignore_index=True)

#----ノルム列の追加-------
# 新しい列の計算
norm_data = np.sqrt(df_pdr['x']**2 + df_pdr['y']**2)

# 新しい列をデータフレームに追加
new_column_name = 'norm'  # 新しい列の名前
df_pdr.insert(3, new_column_name, norm_data)  # 4列目に追加

# -----センサーファイルを読み込む-----
sensor_file = 'sensor.csv'  # 読み込むCSVファイルの名前
df_sensor = pd.read_csv(sensor_file)

# PDRファイルの2列目を抜き出す
add_data = df_sensor.iloc[:, 3]  # 2列目のデータ

# 行数を比較して短い方に合わせる
min_rows = min(len(df_pdr), len(df_sensor))
df_sensor = df_sensor[:min_rows]
column_to_merge = add_data[:min_rows]

# 2番目のデータを最初のデータフレームに結合
df_sensor['norm'] = add_data

# 変更をCSVファイルに保存
new_csv_filename = 'added_data.csv'  # 保存先のファイル名
df_sensor.to_csv(new_csv_filename, index=False)

# --------変更をCSVファイルに保存------
new_csv_filename = 'pdr_0.csv'  # 保存先のファイル名
df_sensor.to_csv(new_csv_filename, index=False)

```
## 複数行抜き出して結合するパターン
```
# PDRの2列目と3列目のデータを抜き出す
add_data = df2.iloc[:, [1, 2]]  # 2列目と3列目のデータ

# 行数を比較して短い方に合わせる
min_rows = min(len(df1), len(df2))
df2 = df2[:min_rows]
column_to_merge = add_data[:min_rows]

# 2列目と3列目のデータを最初のデータフレームに結合
df2['new_column_2'] = add_data.iloc[:, 0]
df2['new_column_3'] = add_data.iloc[:, 1]

# 変更をCSVファイルに保存
new_csv_filename = 'add_data2.csv'  # 保存先のファイル名
df2.to_csv(new_csv_filename, index=False)
```

# 縦に結合
```
import pandas as pd

# CSVファイルのリストを作成
csv_filenames = ['sensor.csv', 'sensor2.csv', 'sensor3.csv']  # 読み込むCSVファイルの名前

# 最初のCSVファイルを読み込む
df_list = [pd.read_csv(csv_filenames[0])]

# 2つ目以降のCSVファイルを読み込んで縦に結合
for csv_filename in csv_filenames[1:]:
    df = pd.read_csv(csv_filename)
    df_list.append(df.iloc[0:])  # 2行目以降を追加

# データフレームを縦に結合
combined_df = pd.concat(df_list, ignore_index=True)

# 変更をCSVファイルに保存
new_csv_filename = 'combined_file.csv'  # 保存先のファイル名
combined_df.to_csv(new_csv_filename, index=False)

```
TaigaTakanoのrosbagランド

Xで投稿してたら流れてしまうので。

## VLP-16

https://drive.google.com/file/d/1ZZNQRhtQO8dPpvcHAS8cPAuppkd7CRLr/view?usp=drive_link

https://drive.google.com/file/d/1DzFNZwFYwTqCidyiKVpA1lZfF6U46tGk/view?usp=sharing

## Realsense D455

https://drive.google.com/file/d/1Xvi_muWrJoZ_bqBiUPETogce7eeEt5XI/view?usp=drive_link

https://drive.google.com/file/d/1Jb-mWey06KxqAv1dLq1SFZZuSpVGoZQ8/view?usp=drive_link

## 配布に制限を設けているもの

XでDMにてご連絡ください。
- VLP-16とD455を車に乗せて取ったrosbag
- 市街地をVLP-16を背負って取ったrosbag
インターネットに接続できたら通知【PowerShell】

```powershell
$ToastText01 = [Windows.UI.Notifications.ToastTemplateType, Windows.UI.Notifications, ContentType = WindowsRuntime]::ToastText01
$c = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime]::GetTemplateContent($ToastText01)
$c.SelectSingleNode('//text[@id="1"]').InnerText = 'インターネットが壊れてない'
$i = '{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe'
ping -t 8.8.8.8 | % { echo $_; if ( $_.Contains("からの応答") ) { [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($i).Show($c) } }
```

オフラインでQiita開けないので、上のスクリプトをローカルに保存した方がいいです

実行例

```powershell
PS C:\Users\Admin> ping -t 8.8.8.8 | % { echo $_; if ( $_.Contains("からの応答") ) { [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($i).Show($c) } }

8.8.8.8 に ping を送信しています 32 バイトのデータ:
ping: 転送に失敗しました。一般エラーです。
ping: 転送に失敗しました。一般エラーです。
ping: 転送に失敗しました。一般エラーです。
ping: 転送に失敗しました。一般エラーです。
ping: 転送に失敗しました。一般エラーです。
ping: 転送に失敗しました。一般エラーです。
ping: 転送に失敗しました。一般エラーです。
ping: 転送に失敗しました。一般エラーです。
ping: 転送に失敗しました。一般エラーです。
ping: 転送に失敗しました。一般エラーです。
ping: 転送に失敗しました。一般エラーです。
ping: 転送に失敗しました。一般エラーです。
ping: 転送に失敗しました。一般エラーです。
ping: 転送に失敗しました。一般エラーです。
ping: 転送に失敗しました。一般エラーです。
ping: 転送に失敗しました。一般エラーです。
8.8.8.8 からの応答: バイト数 =32 時間 =8ms TTL=115
8.8.8.8 からの応答: バイト数 =32 時間 =7ms TTL=115
8.8.8.8 からの応答: バイト数 =32 時間 =6ms TTL=115
ping: 転送に失敗しました。一般エラーです。
ping: 転送に失敗しました。一般エラーです。
ping: 転送に失敗しました。一般エラーです。
ping: 転送に失敗しました。一般エラーです。
```

設定から無効有効にして動作確認できます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/b6d20a56-dfc0-2d22-5a30-afbd5eef47f5.png)
カブトムシの幼虫の神秘

8月も終わり。
残暑はあるけれども、「秋風」をにおわせる微風は夏の終わりを感じさせるには強烈な風となって僕に吹いてきます。ここでは、今年の夏も日本の多くの小学生が乱獲したであろう「カブトムシ」をテーマに記事を書いています。特にカブトムシの「卵期」、「幼虫期」、「蛹期」について紹介していきます。
「えー？黒光りした成虫についてじゃないのかよ！(# ﾟДﾟ)」とはならず、ぜひ最後まで見てくだされ。
![カブトムシ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496652/6ee48847-f287-3b0d-5fc9-ccbf1ed9171c.png)

①カブトムシの分布
カブトムシは東南アジア諸国の多くの国々で見ることができます。そんな中で、日本は最北端のカブトムシ生息国となっています。今後、地球温暖化が進むにつれてその生息域は北上する可能性がありますが、日本の北海道でもカブトムシは採取できます。カブトムシは、温暖で湿潤な気候を好みます。日本には、多くのカブトムシが生息しております。私も子供の頃に夜の栗林でカブトムシ採取に熱中した夏があり、鮮明に覚えています。(栗の木におそらく蛾か何かの「成人の前腕サイズの幼虫」がいたことが印象的でした。)また、子供の頃にカブトムシを採取していて気づくこととして、各個体の大きさが異なるということです。虫かごいっぱいにカブトムシを採取してきて大きさが異なるのです。さて、このカブトムシの大きさの差異はなぜ生じるのか。興味深いですな。

②カブトムシの幼虫期に大きさの差異の原因があるらしい
結論から言います。カブトムシの大きさは以下の2つの事柄が大きく影響しています。
　[1]幼虫が住んでいる場所のえさの質
　[2]母親の大きさ(サイズ)

[1]についてですが、カブトムシの幼虫は土の中の微生物を好んで食べます。腐葉土の土の下に幼虫が多くみられるのはそのためです。また、幼虫の驚くべき生体機能として「二酸化炭素の匂いを感知する」があります。二酸化炭素に反応して行動する有名な虫として蚊が知られています。カブトムシの幼虫が二酸化炭素に反応することを裏付ける実験として、透明で四角いプラスチック容器の一か所の角にストローを差しこんでおきます。そのプラスチック容器にカブトムシマットを敷き詰めて、容器の中央部の中に幼虫を入れ実験準備完了。ストローに人間の呼気を吹き付けると、それに反応して中央部にいた幼虫が角っちょに移動していったという実験です。これは、微生物も生きていくうえで呼吸をしており、酸素を吸って二酸化炭素を出しています。このことから、幼虫は二酸化炭素の匂いを感知してその方向に動くことができているのです。当然、この微生物が少ない場所の幼虫は十分な栄養を摂取できず、サイズの小さな成虫になることになります。![カブトムシ2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496652/28feb9f9-df79-5c04-91d9-c136f22ca05e.png)


[2]についてですが、これは哺乳類に顕著にみられる「母性効果」がカブトムシの幼虫前の状態、つまり卵の状態においても影響していることが知られています。(「父性効果」は大きく影響しにくいのが一般的です)この「母性効果」を示す有名な実験として、次のようなものがあります。まず、オスのカブトムシ1匹と様々なサイズのメスカブトムシとを交尾させて産卵させます。その卵のサイズを計測したところ、サイズの大きなメスのカブトムシの卵は大きな卵であり、サイズの小さなメスのカブトムシの卵が小さな卵であることが分かったというのです。最もサイズの大きな個体が生んだ卵の重さは「33mg」、最もサイズの小さな個体が生んだ卵の重さは「43mg」であったのです。カブトムシには母乳はありませんが、ほ乳類では母親が子供に母乳を与える際に、母親の母乳が多いほど子供に栄養がいきわたります。これは、カブトムシにおきかえると卵の中の栄養素の量に置き換えられ、卵のサイズにかかわってきます。生存競争を生き抜くためには、偉大なる母の影響が大きくあることはカブトムシ界においても同じことのようです。

③終わりに
さて、カブトムシの幼虫期、卵期について示してきました。小学生たちの自由研究につながる良いキーワードがたくさん出てきているかと思います。大好きなカブトムシを来年の自由研究につなげるためにも、勝負は始まっています。さあ、秋から冬にかけては幼虫は冬眠をします。その冬眠をしている幼虫を見つけて研究してみてはいかがでしょうか。
他の面白い既存の研究テーマとしては、「同エリア内の幼虫は同時期に蛹になる傾向がある(同調蛹化　現象)」、「幼虫は白色で成虫はなぜ黒いのか」などがあります。

末筆ですが以上になります。(もう少し国語力が必要ですね。。。)
WindowsのVisual Studio 2022とMacを接続できない問題と回避策

こんばんは。

.NET MAUIで開発中のアプリをiOS端末でデバッグしようとAppCenter経由でインストールするため、いつものようにWindows上のVisual Studio 2022の「Macとペアリング」機能を使って接続しようとしたら、エラーが出ました。

このエラーを根本解決しようとしても無理だったので、とりあえず回避策を検討してみました。

# 今回発生した現象

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/f583a128-ff71-ea8c-8822-508e2b060e4e.png)

# 試したこと

## mac側で `sudo dotnet workload install ios`

ターミナルでiosワークロードを再インストールしてみましたが、改善しませんでした。

## mac側で .NET 7 Runtime のセキュリティ修正プログラムをインストールしてみる

SDK 7.0.400をインストールしてみましたが、改善しませんでした。

# 回避策

.NET MAUIで開発中のアプリをiOS端末でデバッグしようとAppCenter経由でインストールするためには2通り方法があります。

* (a) Windows上のVisual Studio 2022のアーカイブマネージャーから発行（アドホック）する
* (b) Mac上のVisual Studio ２０２２ for Macのアーカイブマネージャーから発行（アドホック）する

今回の現象により、(a)にはMacとペアリングが必要なので利用不可ですが、しかし(b)で発行することは可能です。

以下に(b)の方法をおさらいしておきます。

## (b) Mac上のVisual Studio ２０２２ for Macのアーカイブマネージャーから発行（アドホック）する

1. Mac上にソースコードを用意します。（git, SourceTree, forkでクローンしておきます）
1. Visual Studio 2022 for Macを起動し、ソリューションを開きます。
1. MAUIプロジェクトをダブルクリックし、プロジェクトのプロパティを開きます。
1. ビルド＞iOS＞バンドルの署名を開き、署名IDとプロビジョニングプロファイルを適切なものにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/6c27dcff-1032-a4dc-9ea4-89cc6c585e19.png)
1. MAUIプロジェクトを右クリックし、アーカイブの表示をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/c74f0c7c-c4d6-902c-ee69-364100a4492f.png)
1. アーカイブタブが開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/5cd26b79-4488-7427-288e-050f8f319774.png)
1. 最新バージョンがアーカイブされていなければ、ビルド＞公開のためのアーカイブをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/944dd3a7-3e6b-81e6-b16f-f03a28fd172b.png)
1. 最新バージョンを選択してから、署名と配布...をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/8caa0989-0a19-18b8-69b7-f3c7255a0ae6.png)
1. AppCenterにリリースしたい場合は、Adhoc を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/b2f6a474-b593-67c1-8ca2-f27f83ca4cc9.png)
1. 適切なプロビジョニングプロファイルを選択します。（AppCenter用のもの）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/1ac36873-c029-bc77-75e8-1e6d94e7944b.png)
1. 公開ボタンをクリックし、適当な場所に出力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/812c3f0f-c731-31cc-fdcd-61e4fe415b7d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/7e7b9ae9-86e1-3b63-c932-579f1250ca04.png)
1. あとはブラウザでAppCenterを開いて、リリースすれば完了です。

# まとめ

おそらく一時的なバグによるもの？だと思います。
Microsoftによる修正されたバージョンの発表を待つのが嫌な人は、Macを直接操作して発行するといいようです。
正規化前後の相関係数

# はじめに
先日、ビッグデータの解析について記事を書きました。

https://qiita.com/inoshun/items/8510e956b7d38dafce55

そこで、相関係数を算出しましたが
「正規化する前とした後で相関係数に違いってあるのかな？」
ということで試したところ全く変化がありませんでした。

コメントで
「正規化は線形変換の1つであるため、変換後のデータを使って計算される相関係数は変換前のデータでの相関係数と全く同じである」
ということを教えていただきました。

今回は、それを式を使って証明できることを会社の先輩にご教授いただきましたので共有します！

# 証明開始

相関係数は、2つのデータセットの関連性を表す指標であり、以下の式で計算されます。

$$
r = \frac{\sum (x_i - \bar{x})(y_i - \bar{y})}{\sqrt{\sum (x_i - \bar{x})^2 \sum (y_i - \bar{y})^2}}
$$


- $x_i$と$y_i$は、それぞれのデータセットの個々のデータポイント
- $\bar{x}$と$\bar{y}$は、それぞれのデータセットの平均値

正規化は、データをスケーリングして、平均が0、標準偏差が1になるように変換するため、
正規化されたデータポイント$x_i'$と$y_i'$は以下のように計算されます。

$$
x'_i = \frac{x_i - \bar{x}}{s_x} 
$$

$$
y'_i = \frac{y_i - \bar{y}}{s_y}
$$

ここで、$S_x$と$S_y$は、それぞれのデータセットの標準偏差です。

正規化されたデータの相関係数$r'$は以下のようになります。

$$
r' = \frac{\sum (x_i')(y_i')}{\sqrt{\sum (x_i')^2 \sum (y_i')^2}}
$$

この式を使用して、正規化する前と後の相関係数が等しいか示すことができます。

証明は以下のステップに従います。

1. $x'_i$と$y'_i$の式を$r'$の式に代入
1. 簡略化して、$r'$と$r$が等しいことを示す

正規化後の相関係数$r'$は以下の式として得られる。

$$
r' = \frac{\sum \left( \frac{x_i - \bar{x}}{s_x} \right) \left( \frac{y_i - \bar{y}}{s_y} \right)}{\sqrt{\sum \left( \frac{x_i - \bar{x}}{s_x} \right)^2 \sum \left( \frac{y_i - \bar{y}}{s_y} \right)^2}}
$$

この式をさらに簡略化すると、元の相関係数$r$の式と同じになります。

具体的には、分子の部分は$x_i-\bar{x}$と$y_i-\bar{y}$の積の和として表され、分母の部分はそれぞれのデータセットの分散の平方根の積として表されます。
これらの部分は、正規化する前のデータセットの相関係数の式と一致しています。

したがって、正規化前後で相関係数が変わらないことが証明されました。

# まとめ
データ解析を行ううえで統計学なども勉強はしていますが、こういった数学的要素も非常に重要ですね。
今後も評価指標なども数学的要素が絡んできますので、並行して学んでいけたらと思います。
それでは！！！
【再帰SQL】階層構造のレコードから上位、下位のレコードの取得方法

# 階層構造のテーブル

下記のAテーブルはIDをキーにした階層構造のレコード構成を持つテーブルになっている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515728/5c8f62a6-9a55-7013-13c9-671e44111707.png)
Aテーブルの階層構造を分かりやすく表したのが下記の図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515728/8e5ffbf4-c577-784a-adde-ed78d5656775.png)
この図を見れば分かる通り、`社長 > 副社長 > 部長 > 課長 > 社員`とレコードが階層構造になっている。

# 再帰SQL
### Eを主体とした上位のレコードを取得する方法
```sql:
WITH RECURSIVE Parent AS (
  SELECT ID, 値, 親ID
  FROM Aテーブル
  WHERE ID = 'E'
  UNION ALL
  SELECT Aテーブル.ID, Aテーブル.値, Aテーブル.親ID
  FROM Aテーブル
  JOIN Parent ON Aテーブル.ID = Parent.親ID
)
SELECT ID, 値, 親ID
FROM Parent;
```
```:実行結果
| ID | 値     | 親ID  |
|----|--------|-------|
| E  | 社員   | D     |
| D  | 課長   | C     |
| C  | 部長   | B     |
| B  | 副社長 | A     |
| A  | 社長   | NULL  |
```
### Aを主体とした下位のレコードを取得する方法
```sql:
WITH RECURSIVE Child AS (
  SELECT ID, 値, 親ID
  FROM Aテーブル
  WHERE ID = 'A'
  UNION ALL
  SELECT Aテーブル.ID, Aテーブル.値, Aテーブル.親ID
  FROM Aテーブル
  JOIN Child ON Aテーブル.親ID = Child.ID
)
SELECT ID, 値, 親ID
FROM Child;
```
```:実行結果
| ID | 値     | 親ID  |
|----|--------|-------|
| A  | 社長   | NULL  |
| B  | 副社長 | A     |
| C  | 部長   | B     |
| D  | 課長   | C     |
| E  | 社員   | D     |
```
LinuxとWindowsのコマンド比較

# LinuxとWindowsコマンド、同じようで同じじゃない

LinuxとWindowsのコマンドで一緒（もしくはほぼ一緒）のものもあれば、全然違うものもありそうなので、まとめてみました:fist_tone1:

|linux|windows|動作|備考|
|:---|:---|:---|:---|
|cd|cd|ディレクトリを移動する|
|pwd|cd (引数なし)|現在のディレクトリを表示
|ls|dir|ファイル・ディレクトリの一覧を表示する
|mkdir|md|ディレクトリを作成する
|rmdir|del|ディレクトリを削除する
|cat|type|テキストの中身を表示
|less|more|別窓でテキストの中身を表示する
|tail|-|ファイルの末尾を表示する|powershellなら出来るっぽい<br>使い方がイメージできない方は<br>[tail -f の使い方を知るためだけのシェル作成](https://qiita.com/my2k_/items/2124c7dfbf61f560beb0)
|touch|type nul >(txt)|ファイルを作成する
|rm|del|ファイルを削除する
|mv|move|ファイル・ディレクトリを移動する
|mv|rename|ファイル・ディレクトリの名前を変更する|
|cp|copy|ファイル・ディレクトリをコピーする
|ln|mklink /h|ハードリンクを作成する|
|ln -s|mklink /d|シンボリックリンクを作成する
|find|find|ファイルを検索する|
|chmod|icacls /grant|権限を設定する|引数の渡し方はだいぶ違う
|chown|icacls /setowner|ファイルの所有者を変える|引数の渡し方はだいぶ違う
|ps|tasklist|実行中のプロセスを表示する|
|kill|taskkill|プロセスを終了する|
|reboot|shutdown -r|
|grep|findstr|テキストファイルから文字列を検索する||

cdはめっちゃ使いそうなのに知らなかった...
Windowsのコマンドにも慣れておけば、日常的な業務が捗りそうです！

# 参考
[もう怖くないLinuxコマンド。手を動かしながらLinuxコマンドラインを5日間で身に付けよう | Udemy](https://www.udemy.com/course/unscared_linux/)
[Windows のコマンド | Microsoft Learn](https://learn.microsoft.com/ja-jp/windows-server/administration/windows-commands/windows-commands)
Bizrobo Excel APIを用いて住所分割する方法


# 概要
Excel出力の際に住所を分割したい。
今回はBizroboからExcelファイルへデータ入力をExcelAPIを用いて住所の分割をしていきたいと思います。

下記ExcelAPI　URL
https://excelapi.org/docs/post/address-separate/

## API
Application Programming Interfaceの略ですが、
ここではざっくりと第３者が提供している機能を使って、
ほかのアプリケーションを呼び出したり、連携の処理を行ってくれる
便利ツールと考えていただければと思います。

## 使用例
今回はBizroboを用いて、取得した住所データをExcel APIで分割していきます。

![20230830.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291018/4e3de4c0-656c-7977-1023-cc6fdea2fd40.png)



上記の画像ではBizroboのDesign studio上でExcelファイルを開いているのですが、
住所のフルがA列にはいっておりますので、（※架空の住所となります）
ExcelAPIを用いて

住所1には 都道府県
住所2には 市区町村
住所3には 町丁目
住所4には 番地・建物名

という形で分割していきたいと思います。


ちなみにTypeファイルは下記のように作成し、
ロボットファイル側でTypeファイルを読み込むようにします。
![quiita3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291018/f01e1107-3f9d-6d59-c725-7d33d847ecad.png)

次にループ処理で住所を繰り返し
変数の「住所」へ格納をしていきます。

ExcelファイルのA列の住所を繰り返し処理で、変数の「住所」へ格納できたところで、
いよいよAPIの設定へ入ります。

アクションステップを挿入し
下記のアクションを選択してください。（日本語設定の方は「Webサービス呼出」となっているかと思います。）
![quiita6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291018/031d5511-f4b7-bdd5-9c73-9c2f94e2c729.png)

そうすると
URL欄とOutput欄が必須項目となりますので入力していきます。
![quiita7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291018/bbac36a9-9a9e-c18c-9658-321e2b7d6b26.png)

URL欄には
https://api.excelapi.org/post/address-separate
を入力し、
出力先には変数を指定し「住所１」を選択しております。

![quiita8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291018/5b2ad44f-12a9-9701-6c7a-e02daa955358.png)

また、今回APIを利用するにあたって、
partsと
address	が必須項目となりますのでParametersへ設定しておきます。
＋ボタンから設定していきましょう。
![quiita9&10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291018/92594bf9-31a7-9b99-62ba-f25158f1da35.png)

エンドステップへ移動してみると、
県名までが取得できていることが確認できるかと思います。

![quiita11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291018/c2001349-6742-dbb9-99bb-0c95a481a876.png)

この後は、partsを2,3,4へ変えたステップを追加することで、
残りの分割された住所を取得することができます。
parts=2 市区町村
parts=3 町丁目
parts=4 番地・建物名

そのほかにも形式の変更が可能となるようですので、
分割の形式を変更されたい方はExcelAPIのサイトを参照してみてください。


## まとめ

今回はBizroboでWebサービス呼出の機能について記事にしてみました。
APIを使用すると開発の幅が広がるため適宜使用してみてはいかがでしょうか。

最後までご覧いただきありがとうございます。
Git　基本コマンド

##  はじめに
AP開発に参画し、はや1か月が過ぎました。
まだまだなれませんが、残業もないし、難しいこともしていないので辛くありません。

ただ周りは経験年数も多く、仕事も早いため、申し訳ない気持ちがあります。

まあ、そんなこと考えていてもすぐに仕事ができるわけではないので、半年後に1人前になれるように勉強していきます！

本日は、業務でソースコードの改修があり、その際にgitlabを操作したのですが、教えてもらいながらやったが理解が薄いため、周辺知識を含めてまとめていこうと思う

## gitlabの一連操作
以下が基本的なソースコード改修の手順で、それぞれのコマンドを確認していく。
1. ローカルへのクローン作成
1. ソースコード改修
1. ブランチ作成
1. コミット
1. ブランチへpush
1. マージ
1. デプロイ

### ローカルへのクローン作成
#### clone
クローンする前に、ローカルに改修したいファイルと同じ構成のディレクトリを作成し、cdで移動する。
例）sample/src/backendをクローンしたいなら、ローカルにsample/srcディレクトリを作成しsrcディレクトリへ移動し、クローンする

```言語:
git clone "URL"
```
※URL...gitlabの改修したいソースコードのページまで遷移し、"clone"ボタンを押下すると表示される

#### pull
git clone初めてソースを作成する場合に実施するが、その後は使用せず以下のコマンドを使用する。

```言語:
git pull
```
gitlab上からローカルへのソースを持ってくる

他人が作成したブランチをpullする場合は以下
```言語:
git pull origin "ブランチ名"
```

### ブランチ作成
ブランチの作成
```言語:
git branch "branchname"
```
ブランチへの切り替え、作成したブランチはマスターのコピーのようなもの、改修するにはそのブランチに入る必要がある以下で入る
```言語:
$git checkout "branchname"
Switched to branch "branchname"
```
また、ブランチの作成と切り替えを一緒にやりたい場合は以下を実行
```言語:
$git checkout -b "branchname"
Switched to branch "branchname"
```

以下で現在のブランチを確認できる
```言語:
$ git branch
  *"現在のブランチ名"
```
アスタリスクが現在のブランチ

### ソースコードの改修
よしなに

###  コミット
ローカルのファイルを改修したら保存します（ctrl+Sとかで）
保存だけではダメで、コミットをしなければならない。
なぜか、コミットすることでブランチに保存される、また変更履歴にメモを残すことができる

```言語:
 git commit -m "メッセージ"
```
メッセージにはどこを改修したか書きます。


### ブランチへpush
コミットしたら、作成したブランチに改修したソースが保存され、変更履歴が残っているので、それをgitlabにpushします

```言語:
 git push origin "ブランチ名"
```
DBMS(DataBase Management System)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/8b6c6264-b98f-0f84-06b0-1c1748a0953d.png)
１：ロック粒度
　データベース単位、表単位、行単位のように、ロックをかける単位をロック粒度言います。ロック粒度が大きい順に、データベース単位、表単位、行単位です。ロック粒度を大きくすると大きな単位でロックがかかり、複数のトランザクションが同時に動いていた場合、ロック解除待ちのトランザクションが増えることになります。一方で、ロック粒度を大きくすると、作業中に、他トランザクションが先回りしてデータを書き換えてしまうといった事態が発生しづらくなります。したがって、整合性を取りやすくなります。ロック粒度を小さくすると、ロックがかかる単位が小さくなり、ロック解除待ちのトランザクションが少なくなりますが、整合性をとることが困難になりがちです。

　例えば、DB-Xというデータベースがあり、DBーX中に社員表、部署表、売上表があったとします。ここで、DB-X中の社員表にアクセスし、データを更新するトランザクション（TRー１）を実行します。データベース単位でロック粒度を設定すると、DBーXにアクセスできるトランザクションは１つだけとなります。複数のトランザクションが同時にDBーXにアクセスすることができません。つまり、売上表を参照するトランザクション（TRー２）をTRー１と同時に実行したとしても、TRー２はTR-1が終わるまで待たなくてはなりません。TRー１は売上表には一切アクセスしないにも関わらず、TRー２はTR-1が終わるまで待たなくてはなりません。

　このように、ロック粒度を大きくすると、場合によっては無駄にトランザクションを待たせることになります。ロック粒度は、スループットと整合性確保のバランスを見て決めることが大切です。
JAVA×SQL③

# 課題
問題：　JBDCを使用しupdate文を実行せよ
使用ツール：　XAMPP、eclipse

## 回答

~~~~JAVA

package DBA;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;

public class DBA3 {

	public static void main(String[] args)throws SQLException {
		System.out.println("社員ID入力");
		Scanner s=new Scanner(System.in);
		int ID1=s.nextInt();
		System.out.println("部署ID（変更後）入力");
		int ID2=s.nextInt();
		
		String url="jdbc:mysql://localhost/JDBC";
		String user ="root";
		String password ="";
		Connection con = DriverManager.getConnection(url,user,password);
		PreparedStatement pstmt =con.prepareStatement
				("update woker set co_id = ? where id = ?");
			pstmt.setInt(1,ID2);
			pstmt.setInt(2,ID1);
			int rows= pstmt.executeUpdate();
			System.out.println(rows+"件のデータを変更しました");
			}
}

~~~~~~

### 実行結果

~~~~

社員ID入力
1
部署ID（変更後）入力
1
1件のデータを変更しました

~~~~~

本日の気付き：int rows= pstmt.executeUpdate();があることで変更件数がわかります
AWS S3の特定のオブジェクトにのみ取得を許可する

# やりたいこと
S3に保存している特定のオブジェクトのみ参照(取得)できるようにしたい。

# 例
例えば以下のようなとき。

- S3バケット`s3://hoge`に保存している`hoge.txt`のみ取得できるようにしたい。

# 前提条件
- AWSアカウントがあること
- ローカル環境にAWS CLIがインストールされていること

# 方法
1. AWS IAMにから適当なユーザーを作成
1. アクセスキーとアクセスシークレットを控えておく
1. AWS IAMからポリシーを作成する
![スクリーンショット 2023-08-30 19.49.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1583420/224056e5-cfb4-6cb1-b8bc-824ed1fb4c19.png)
1. JSONモードに切り替えて以下のような設定を記述する
![スクリーンショット 2023-08-30 19.51.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1583420/aae85f53-58e4-763e-997e-9307305463dd.png)
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::hoge/hoge.txt" // 取得は特定のファイルに制限する
        },
        {
            "Effect": "Allow",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::hoge"
        }
    ]
}
```

# 検証
1. ローカルのaws cliに作成したIAMロールを設定する。
```sh
$ aws configure
AWS Access Key ID [****************]: XXXXXX
AWS Secret Access Key [****************]: YYYYYY
Default region name [ap-northeast-1]: [使用するリージョン]
Default output format [None]: [空欄で可]
```
1. バケットの中の一覧を取得
```sh
$ aws s3 ls s3://hoge
hoge.txt fuga.txt peta.txt ....
```

1. 手順4で設定した特定のファイルを取得する
```sh
$ aws s3 cp s3://hoge/hoge.txt ./
download: s3://hoge/hoge.txt to ./hoge.txt
```

1. 他のファイルは取得できない
```sh
$ aws s3 cp s3://hoge/fuga.txt ./
fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden
```

# まとめ
Listの許可を与えるところがわからずずっと詰まっていた。
特定のファイル以外はリストすらさせたくない場合はわからないです。
Internet Explorer EOL - ミッションクリティカルなJavaアプリケーションを開く

![My-project-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3486144/ad36e41b-df6d-f9f6-2f6f-174d09ae2bc5.png)
2022年6月、マイクロソフトは長寿ブラウザであるInternet Explorerのメインストリームサポートを終了する意向であり、Windows 11上のIE11デスクトップアプリケーションは使用できなくなる。しかし、一部のアプリケーション、特にJavaアプレットに基づくアプリケーションは、インターネット・エクスプローラーでしか確実に動作しない。

IEの無効化は、これらのアプリケーションへのアクセスを維持する必要がある企業のワークフローに大きな変化をもたらします。

ご覧のように、当社のブラウザベースのソリューションであるCheerpJは、Internet Explorerだけでなく、EMSLとEdge IEモードの必要性も取り除きます。
![1Edge-Java-Infographic-1024x791.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3486144/2045d019-aefe-cecf-64a5-102d0a13cac1.png)
**CheerpJ**
CheerpJは、[ミッションクリティカルなJavaアプリケーションとアプレットへのアクセスをInternet Explorerのサポート終了後も維持し](https://leaningtech.com/cheerpj/)、近代化するエンタープライズグレードのソリューションです。

CheerpJ Applet Runnerは、JavaプラグインやインストールなしでJavaアプレットを実行するための[Chrome](https://chrome.google.com/webstore/detail/cheerpj-applet-runner/bbmolahhldcbngedljfadjlognfaaein?hl=en)と[Edge](https://microsoftedge.microsoft.com/addons/detail/cheerpj-applet-runner/ebfcpaoldmijengghefpohddmfpndmic?hl=en-US)用のブラウザ拡張機能です。これにより、Chrome、Edge、Firefox、Safari、またはその他の最新ブラウザでJavaアプレットにアクセスすることができ、最新のITアーキテクチャで内部またはサードパーティのJavaアプレットインターフェースを使用し続けることができます。

CheerpJ Applet Runnerは、エンタープライズ設定で使用することができ、Microsoftベースのエンタープライズ・アーキテクチャ上のEdgeやChrome上でGlobal Policy Objectsを介してデプロイすることができます。

**❝素晴らしいカスタマーサポートを備えた素晴らしい拡張機能です！私たちは、民間航空機からの自動天気予報を表示する大規模で広範なアプレットを持っています。 CheerpJバージョンは高速です。
– Bill Moniger, NOAA**

[引用元](https://leaningtech.com/internet-explorer-eol-opening-mission-critical-java-applications/)

https://leaningtech.com/legacy-modernisation-jp/
GoでWebアプリケーションを作る（3）ー変数とその定義方法

こんにちは。

今日は「変数とその定義方法」についてです。

変数とその定義方法についての確認と、変数定義に失敗しているソースコードを修正してもらいます。

# 変数の種類

Go言語は、静的型付け言語であるためコンパイル時に変数に紐付いた型の情報に整合性があるか検証されます。 この講義では深く触れませんが、下にGo言語における方の種類について簡単な説明を記載します。 興味のある方は[公式ドキュメント](https://go.dev/ref/spec#Types)を見てみてください。

- 組み込み型
    - 整数
        - int,int8,int16,int32,int64
        - uint,uint8,uint16,uint32,uint64
        - uintptr
        - byte
            - uint8 のエイリアス(別名)です
        - rune
            - int32 のエイリアス(別名)です
    - 浮動小数点
        - float32,float64
    - 複素数
        - complex64,complex128
    - 文字列
        - string
            - stringを構成する文字はruneで構成されます
    - 真偽値
        - bool
    - エラー
        - error
- コンポジット型
0個以上の変数をひとまとまりの集合として表した型です
    - 構造体 (struct)
    - 配列 (array)
    - スライス (slice)
    - マップ (map)
    - チャンネル (channel)
- ユーザー定義型
組み込み型やコンポジット型を元にユーザーが定義した型です
- Interface型
これまで説明した型はデータがメモリ上にどのように表現されているかという観点から区別されていました。 このinterface型は方がどう振る舞うか(型にどんなメソッドが実装されているか)という観点で区別され、0個以上のメソッドから構成されます。 また、[Go1.18からGenericsが追加](https://tip.golang.org/doc/go1.18#generics)されました。これにより、interfaceに型の情報を組み込むことができるようになりました。

# 変数定義方法

Go言語では、変数の定義方法が3つあります。

1. var <変数名> <型>
    例: var Hensu string
    型指定有り。変数初期値の指定無し(stringなので、""になります。)
2. <変数名> := <初期値>
    例: Hensu := "myValue"
    型指定無し。代入元の型を引き継ぐ
3. var <変数名> <型> = <初期値>
    例: var Hensu string = "myValue"
    型指定有り。変数初期値の指定有り

予期せぬ型が変数に定義されないよう、最初のうち（書いている型をイメージできるまで）は、1か3の書き方をお勧めします。
予期せぬ型が変数に定義されうる例として、interface型 があります。
本講義では、interface型 は扱わない為説明は割愛しますが、なんでも型(any) のような使い方ができます。
変数なんでも型が示しているのは、int型だと思っていたらstring型だった。というようなケースもおきえるので、注意が必要です。

Go言語の名前空間は、privateは先頭小文字。Publicが先頭大文字と決まっています。
packageに含める要素（変数や関数、構造体や構造体の要素など）をpackageの外部から参照させたい場合、先頭大文字の変数名とするようご注意ください。

# 不具合箇所は、最高の講師に教えてもらおう

Go言語では、書き方を間違えているととても丁寧に教えてくれる強い味方がいます。
それは、コンパイラ（go build）です。
「うーん、あ、この辺のソースみた？」とだけ返してくる先輩に比べ、「3行目、6文字目。変数定義されていないよ！？」と場所まで指定して教えてくれます。
変数定義方法で、1や3を勧めた理由の1つとして、型が異なる場合にコンパイラに教えてもらえる可能性が高まるためというのもあります。

ちょっと厳しい点があるとすれば、指摘が英語な点でしょうか。
中学生レベルの英語と、単語を調べる力があれば解決できる文章しか出てこないので、ぜひgo build大先生に弟子入りしてみてください。

エラーが多いと、数個のエラーの後にtoo many error....と続き、全てのエラーを教えてくれないことがあります。
しょうがないので、教えてもらっているエラーから対処していきましょう。

## 以下のコマンドを実行して、修正箇所を認識てみよう。

```
:# TERMINAL 0

$ cd /go/src/go_tutorial/3_var/plzfixme/
$ go run main.go
```

### 結果

```
:# TERMINAL 0

$ go run main.go
# command-line-arguments
./main.go:6:2: undefined: WatashiNoHensu
./main.go:7:14: undefined: WatashiNoHensu
```

# 不具合の修正

## ソースコードを修正し、エラーを無くしてみよう。

```
:# TERMINAL 0

$ <お好きなエディタ> main.go
$ go run main.go
```

```main.go
package main

import "fmt"

func main() {
	Watashi_no_Hensu = "GYUDON"       //./main.go:6:2: undefined: Watashi_no_Hensu
	fmt.Println(Watashi_no_Hensu)     //./main.go:7:14: undefined: Watashi_no_Hensu
}
```

### 結果
```
:# TERMINAL 0

$ <お好きなエディタ> main.go
$ go run main.go
GYUDON
```

今日は以上です。
ありがとうございました。

次のPart 4は「関数とその定義方法」です。
よろしくお願いいたします。
Selenium Manager を使っているのに chromedriver がバージョン違いで動かなかった話

## 前提
業務でしばしば自動テストを作成。
OSは Windows 10 Pro を使用。

Chromeがアップデートされる度に、バージョンに合わせたchromedriver.exeを引っ張ってくるのが面倒だった。
しかし、 Selenium をアップロードしてからこの心配がなくなった。

どうやら Selenium 4.6.0 以降で Selenium Manager が同時インストールされるらしい。
使用中の Chrome のバージョンに合わせた chromedriver.exe を自動で用意してくれるらしい。
便利ですね。

起動時の記述も変わってパスの指定が不要になった。

    # アップデート前
    driver = webdriver.Chrome(driverPath)
    
    # アップデート後
    driver = webdriver.Chrome()
パスを指定していることによるエラーが出てちょっと焦った。

## 何が起こってどうしたのか
### 経緯
ちょっとの間使用していなかったが、運用中の自動テストについて改修依頼が来たので動かしてみたらエラーが出た。

    selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 114
    Current browser version is 116.0.5845.141 with binary path C:\Program Files (x86)\Google\Chrome\Application\chrome.exe

はいはい、バージョン違いね。
あれ？
自動で取ってきてくれるんじゃなかったっけ？
まいっか、[取りに行こう](https://chromedriver.chromium.org/downloads)。

### 最新バージョンを取りに行った
さて最新バージョンは、と。
![screenshot-chromedriver.chromium.org-2023.08.30-19_01_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152213/7ceb0b0f-28d3-563a-e6bc-3acfe4b3c859.png)
**116系ないじゃん……**
さて、どうしようかね

### ちょっと調べてみた
[Chrome for Testing](https://googlechromelabs.github.io/chrome-for-testing/)というのがあるのか。
![screenshot-googlechromelabs.github.io-2023.08.30-19_02_19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152213/5aa263b4-7ab4-b9e3-3ca6-e9008e274572.png)
おぉ、116系ありますね。
ありがたやありがたや。

### どこ置きゃ良いんだ？
解凍したは良いものの、設置先が判らない。
Selenium Manager さんに任せきりだったしね。

とりあえず find してみますか。

    find /c/Users/aokym/ -name "chromedriver.exe"
    /c/Users/aokym/.cache/selenium/chromedriver/win32/112.0.5615.49/chromedriver.exe
    /c/Users/aokym/.cache/selenium/chromedriver/win32/114.0.5735.90/chromedriver.exe
出てきましたね。
これに並べりゃ何とかなるっしょ。
知らんけど。

ということでフォルダ作成＆解答したファイルの移動

    mkdir /c/Users/aokym/.cache/selenium/chromedriver/win32/116.0.5845.96
    mv ~/Downloads/chromedriver.exe /c/Users/aokym/.cache/selenium/chromedriver/win32/116.0.5845.96/chromedriver.exe

### 動かしてみる
***It worked.***
エラーも出てないし、雑な思い付きの割には上々な結果でしょう。
Selenium Manager さんは ChromeDriver さんのとこを見てるのかしらね。

時間が経てば解決するものだとは思うけど、同様の事例で参考になると良いな。